From ec09d6dabbd014f23e967f5ccc9291d38e7fbb00 Mon Sep 17 00:00:00 2001 From: Kaung Myat Shwe <225817956+kaungmyatshwe1397@users.noreply.github.com> Date: Sun, 22 Mar 2026 21:03:42 +0700 Subject: [PATCH 1/3] :sparkles: feat: add static books section --- content/books/sample-book.mdx | 5 ++ contentlayer.config.ts | 16 ++++- messages/en.json | 2 + messages/mm.json | 2 + src/app/books/page.tsx | 88 +++++++++++++++++++++++++ src/components/Common/Footer/Footer.tsx | 23 +++++-- src/components/Common/Navbar/Navbar.tsx | 1 + 7 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 content/books/sample-book.mdx create mode 100644 src/app/books/page.tsx diff --git a/content/books/sample-book.mdx b/content/books/sample-book.mdx new file mode 100644 index 0000000..56a74d0 --- /dev/null +++ b/content/books/sample-book.mdx @@ -0,0 +1,5 @@ +--- +title: "Clean Code" +authorName: "Robert C. Martin" +link: "https://www.oreilly.com/library/view/clean-code-a/9780136083238/" +--- diff --git a/contentlayer.config.ts b/contentlayer.config.ts index a95c9fe..95a5d70 100644 --- a/contentlayer.config.ts +++ b/contentlayer.config.ts @@ -53,9 +53,23 @@ export const Profile = defineDocumentType(() => ({ computedFields: computedFields, })); +const bookFields: FieldDefs = { + title: { type: "string", required: true }, + authorName: { type: "string", required: true }, + link: { type: "string", required: true }, +}; + +export const Book = defineDocumentType(() => ({ + name: "Book", + filePathPattern: `./books/**/*.mdx`, + fields: bookFields, + contentType: "mdx", + computedFields: computedFields, +})); + export default makeSource({ contentDirPath: "./content", - documentTypes: [Blog, Profile], + documentTypes: [Blog, Profile, Book], mdx: { remarkPlugins: [remarkGfm], rehypePlugins: [ diff --git a/messages/en.json b/messages/en.json index f0632a4..0f80aa0 100644 --- a/messages/en.json +++ b/messages/en.json @@ -59,6 +59,7 @@ "nav": { "home": "Home", "profiles": "Profiles", + "books": "Books", "editor": "Editor", "howTo": "How to", "blog": "Blog", @@ -368,6 +369,7 @@ "navigate": "Navigate", "home": "Home", "profiles": "Profiles", + "books": "Books", "profileEditor": "Profile Editor", "blog": "Blog", "contactUs": "Contact Us", diff --git a/messages/mm.json b/messages/mm.json index f466a7e..70bbbff 100644 --- a/messages/mm.json +++ b/messages/mm.json @@ -59,6 +59,7 @@ "nav": { "home": "ပင်မစာမျက်နှာ", "profiles": "ပရိုဖိုင်များ", + "books": "စာအုပ်များ", "editor": "အယ်ဒီတာ", "howTo": "လမ်းညွှန်", "blog": "ဘလော့ဂ်", @@ -368,6 +369,7 @@ "navigate": "လမ်းညွှန်", "home": "ပင်မစာမျက်နှာ", "profiles": "ပရိုဖိုင်များ", + "books": "စာအုပ်များ", "profileEditor": "ပရိုဖိုင် အယ်ဒီတာ", "blog": "ဘလော့ဂ်", "contactUs": "ဆက်သွယ်ရန်", diff --git a/src/app/books/page.tsx b/src/app/books/page.tsx new file mode 100644 index 0000000..c133993 --- /dev/null +++ b/src/app/books/page.tsx @@ -0,0 +1,88 @@ +import PageTransitionWrapper from "@/components/Animate/PageTransitionWrapper/PageTransitionWrapper"; +import Container from "@/components/Common/Container/Container"; +import SpacingDivider from "@/components/Common/SpacingDivider/SpacingDivider"; +import APP_CONFIG from "@/config/config"; +import { allBooks } from "contentlayer/generated"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: `Books | ${APP_CONFIG.title}`, + description: + "Discover recommended tech books and learning resources shared by the MMSWE community.", + openGraph: { + title: `Books | ${APP_CONFIG.title}`, + description: + "Discover recommended tech books and learning resources shared by the MMSWE community.", + images: "https://mmswe.com/images/mmswe-seo.png", + }, +}; + +const BooksPage = async () => { + const books = [...allBooks].sort((a, b) => a.title.localeCompare(b.title)); + + return ( + + +
+
+

+ Community Library +

+

+ Books +

+

+ Recommended tech books and learning resources shared by Myanmar + software engineers. +

+
+ + {books.length === 0 ? ( +
+

+ No books yet +

+

+ Community recommendations will appear here once contributors add + book entries to the repository. +

+
+ ) : ( +
+ {books.map((book) => ( + + ))} +
+ )} +
+ + +
+
+ ); +}; + +export default BooksPage; diff --git a/src/components/Common/Footer/Footer.tsx b/src/components/Common/Footer/Footer.tsx index c002350..dc1ac97 100644 --- a/src/components/Common/Footer/Footer.tsx +++ b/src/components/Common/Footer/Footer.tsx @@ -339,27 +339,36 @@ const Footer = () => { {t("profiles")} - {t("profileEditor")} + {t("books")} + {t("profileEditor")} + + {t("blog")} @@ -368,8 +377,8 @@ const Footer = () => { @@ -378,7 +387,7 @@ const Footer = () => { diff --git a/src/components/Common/Navbar/Navbar.tsx b/src/components/Common/Navbar/Navbar.tsx index 6de5197..a673170 100644 --- a/src/components/Common/Navbar/Navbar.tsx +++ b/src/components/Common/Navbar/Navbar.tsx @@ -17,6 +17,7 @@ import SignInButton from "@/components/Auth/SignInButton"; const linkKeys = [ { key: "home", href: "/" }, { key: "profiles", href: "/profile" }, + { key: "books", href: "/books" }, { key: "editor", href: "/profile/editor" }, { key: "howTo", href: "/how-to" }, { key: "blog", href: "/blog" }, From 9317299abdfeefcde876607639ab765cef31eab9 Mon Sep 17 00:00:00 2001 From: Kaung Myat Shwe <225817956+kaungmyatshwe1397@users.noreply.github.com> Date: Sun, 22 Mar 2026 23:50:57 +0700 Subject: [PATCH 2/3] :sparkles: feat: add optional books fields --- content/books/sample-book.mdx | 3 +++ contentlayer.config.ts | 3 +++ src/app/books/page.tsx | 46 +++++++++++++++++++++++++++++------ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/content/books/sample-book.mdx b/content/books/sample-book.mdx index 56a74d0..9411074 100644 --- a/content/books/sample-book.mdx +++ b/content/books/sample-book.mdx @@ -2,4 +2,7 @@ title: "Clean Code" authorName: "Robert C. Martin" link: "https://www.oreilly.com/library/view/clean-code-a/9780136083238/" +image: "https://m.media-amazon.com/images/I/41xShlnTZTL._SX374_BO1,204,203,200_.jpg" +authorEmail: "unclebob@example.com" +authorLink: "https://blog.cleancoder.com/" --- diff --git a/contentlayer.config.ts b/contentlayer.config.ts index 95a5d70..712ac32 100644 --- a/contentlayer.config.ts +++ b/contentlayer.config.ts @@ -57,6 +57,9 @@ const bookFields: FieldDefs = { title: { type: "string", required: true }, authorName: { type: "string", required: true }, link: { type: "string", required: true }, + image: { type: "string", required: false }, + authorEmail: { type: "string", required: false }, + authorLink: { type: "string", required: false }, }; export const Book = defineDocumentType(() => ({ diff --git a/src/app/books/page.tsx b/src/app/books/page.tsx index c133993..1773caf 100644 --- a/src/app/books/page.tsx +++ b/src/app/books/page.tsx @@ -55,13 +55,45 @@ const BooksPage = async () => { className="rounded-3xl border border-white/10 bg-surface/50 p-6 transition-colors hover:border-white/20" >
-
-

- {book.title} -

-

- by {book.authorName} -

+
+ {book.image && ( + {`${book.title} + )} + +
+

+ {book.title} +

+

+ by {book.authorName} +

+ {(book.authorEmail || book.authorLink) && ( +
+ {book.authorEmail && ( + + {book.authorEmail} + + )} + {book.authorLink && ( + + {book.authorLink} + + )} +
+ )} +
Date: Mon, 23 Mar 2026 10:41:51 +0700 Subject: [PATCH 3/3] :bug: fix: restore books build --- content/books/sample-book.mdx | 2 ++ src/components/Common/Navbar/Navbar.tsx | 1 + 2 files changed, 3 insertions(+) diff --git a/content/books/sample-book.mdx b/content/books/sample-book.mdx index 9411074..b0a0fd6 100644 --- a/content/books/sample-book.mdx +++ b/content/books/sample-book.mdx @@ -6,3 +6,5 @@ image: "https://m.media-amazon.com/images/I/41xShlnTZTL._SX374_BO1,204,203,200_. authorEmail: "unclebob@example.com" authorLink: "https://blog.cleancoder.com/" --- + +Recommended software craftsmanship reading. diff --git a/src/components/Common/Navbar/Navbar.tsx b/src/components/Common/Navbar/Navbar.tsx index adc8a75..72a3c60 100644 --- a/src/components/Common/Navbar/Navbar.tsx +++ b/src/components/Common/Navbar/Navbar.tsx @@ -27,6 +27,7 @@ const linkKeys = [ const desktopNavWidthByKey: Record<(typeof linkKeys)[number]["key"], string> = { home: "w-[7rem]", profiles: "w-[6rem]", + books: "w-[5.5rem]", editor: "w-[5.5rem]", howTo: "w-[5.25rem]", blog: "w-[4.5rem]",