diff --git a/src/app/blog/[blogId]/MoreBlogs.tsx b/src/app/blog/[blogId]/MoreBlogs.tsx
new file mode 100644
index 000000000..972084839
--- /dev/null
+++ b/src/app/blog/[blogId]/MoreBlogs.tsx
@@ -0,0 +1,52 @@
+import { Pagination } from "swiper/modules"
+import { Swiper, SwiperSlide } from "swiper/react"
+
+import { Box, Stack, Typography } from "@mui/material"
+
+import ArticleCard from "@/components/ArticleCard"
+
+const MoreBlogs = props => {
+ const { blogs, title, ...restProps } = props
+
+ return (
+
+
+ {title}
+
+
+
+ {props.blogs.map(blog => (
+
+
+
+
+
+ ))}
+
+
+ )
+}
+
+export default MoreBlogs
diff --git a/src/app/blog/[blogId]/actions.ts b/src/app/blog/[blogId]/actions.ts
new file mode 100644
index 000000000..65e05e043
--- /dev/null
+++ b/src/app/blog/[blogId]/actions.ts
@@ -0,0 +1,17 @@
+"use server"
+
+import { fetchBlogDetailURL } from "@/apis/blog"
+
+export const fetchBlogContent = async (blogId: string) => {
+ const response = await fetch(fetchBlogDetailURL(blogId))
+
+ if (response.ok) {
+ const blogContent = await response.text()
+ if (!blogContent) {
+ throw new Error("Not found")
+ }
+ return blogContent
+ } else {
+ throw new Error("Failed to fetch blog content")
+ }
+}
diff --git a/src/app/blog/[blogId]/articles.tsx b/src/app/blog/[blogId]/articles.tsx
deleted file mode 100644
index 60a57b456..000000000
--- a/src/app/blog/[blogId]/articles.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Pagination } from "swiper/modules"
-import { Swiper, SwiperSlide } from "swiper/react"
-
-import { Box } from "@mui/material"
-import { styled } from "@mui/system"
-
-import ArticleCard from "@/components/ArticleCard"
-import useCheckViewport from "@/hooks/useCheckViewport"
-
-const ArticleBox = styled(Box)(
- ({ theme }) => `
- display: flex;
- justify-content: space-between;
- ${theme.breakpoints.down("md")} {
- justify-content: center;
- };
- `,
-) as typeof Box
-
-const Articles = props => {
- const { isPortrait, isTabletLandscape } = useCheckViewport()
- let slidesPerView = 3
- if (isTabletLandscape) {
- slidesPerView = 2
- } else if (isPortrait) {
- slidesPerView = 1
- }
- return (
-
- {props.blogs.map(blog => (
-
-
-
-
-
- ))}
-
- )
-}
-
-export default Articles
diff --git a/src/app/blog/[blogId]/detail.tsx b/src/app/blog/[blogId]/detail.tsx
index ba95e849e..7531243ca 100644
--- a/src/app/blog/[blogId]/detail.tsx
+++ b/src/app/blog/[blogId]/detail.tsx
@@ -9,10 +9,9 @@ import rehypeRaw from "rehype-raw"
import remarkGfm from "remark-gfm"
import remarkMath from "remark-math"
-import { Box, Typography } from "@mui/material"
+import { Box } from "@mui/material"
import { styled } from "@mui/system"
-import { fetchBlogDetailURL } from "@/apis/blog"
import blogSource from "@/assets/blog/main.data.json"
import LoadingPage from "@/components/LoadingPage"
import { LANGUAGE_MAP } from "@/constants"
@@ -20,7 +19,8 @@ import useCheckViewport from "@/hooks/useCheckViewport"
import useUserLanguage from "@/hooks/useUserLanguage"
import { filterBlogsByLanguage } from "@/utils"
-import Articles from "./articles"
+import MoreBlogs from "./MoreBlogs"
+import { fetchBlogContent } from "./actions"
import TOC from "./components/tableOfContents"
const BlogContainer = styled(Box)(
@@ -61,36 +61,37 @@ const BlogDetail = props => {
const blogsWithLang = useMemo(() => filterBlogsByLanguage(blogSource, language), [blogSource, language])
useEffect(() => {
- const regex = /([^_]*?)_lang_[^_]+/g
- const blogIdMatch = blogId?.match(regex)
-
- const blogItemWithLang = blogSource.find(item => item.id === `${blogId}_lang_${language}`)
-
- if ((!blogIdMatch && language === "en") || (blogIdMatch && language !== "en") || (!blogIdMatch && language !== "en" && !blogItemWithLang)) {
- let anchors = [...document.querySelectorAll("a")]
- anchors.map(anchor => {
- if (anchor.href.includes("/Content/")) {
- anchor.setAttribute("target", "")
+ async function fetchCurrentBlog() {
+ const regex = /([^_]*?)_lang_[^_]+/g
+ const blogIdMatch = blogId?.match(regex)
+
+ const blogItemWithLang = blogSource.find(item => item.id === `${blogId}_lang_${language}`)
+
+ if ((!blogIdMatch && language === "en") || (blogIdMatch && language !== "en") || (!blogIdMatch && language !== "en" && !blogItemWithLang)) {
+ let anchors = [...document.querySelectorAll("a")]
+ anchors.map(anchor => {
+ if (anchor.href.includes("/Content/")) {
+ anchor.setAttribute("target", "")
+ }
+ return anchor
+ })
+ try {
+ setLoading(true)
+ const text = await fetchBlogContent(blogId)
+ setBlogContent(text)
+ } catch (_error) {
+ router.push("/404")
+ } finally {
+ setLoading(false)
}
- return anchor
- })
- try {
- setLoading(true)
- fetch(fetchBlogDetailURL(blogId))
- .then(response => response.text())
- .then(text => {
- setLoading(false)
- setBlogContent(text)
- })
- } catch (_error) {
- router.push("/404")
+ } else if (blogIdMatch && language === "en") {
+ const nextBlogId = blogId.replace(regex, "$1")
+ router.push(`/blog/${nextBlogId}`)
+ } else if (blogItemWithLang) {
+ router.push(`/blog/${blogId}_lang_${language}`)
}
- } else if (blogIdMatch && language === "en") {
- const nextBlogId = blogId.replace(regex, "$1")
- router.push(`/blog/${nextBlogId}`)
- } else if (blogItemWithLang) {
- router.push(`/blog/${blogId}_lang_${language}`)
}
+ fetchCurrentBlog()
}, [blogId, language])
useEffect(() => {
@@ -119,21 +120,8 @@ const BlogDetail = props => {
className="markdown-body"
/>
- {isPortrait ? (
-
-
- {LANGUAGE_MAP[language].more_articles}
-
-
-
- ) : null}
+
+ {!!isPortrait && }
)}