Skip to content

Commit 8f3d07a

Browse files
✨ feat: add static books section (#263)
* ✨ feat: add static books section * ✨ feat: add optional books fields * 🐛 fix: restore books build
1 parent 8c72e21 commit 8f3d07a

7 files changed

Lines changed: 170 additions & 8 deletions

File tree

content/books/sample-book.mdx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: "Clean Code"
3+
authorName: "Robert C. Martin"
4+
link: "https://www.oreilly.com/library/view/clean-code-a/9780136083238/"
5+
image: "https://m.media-amazon.com/images/I/41xShlnTZTL._SX374_BO1,204,203,200_.jpg"
6+
authorEmail: "unclebob@example.com"
7+
authorLink: "https://blog.cleancoder.com/"
8+
---
9+
10+
Recommended software craftsmanship reading.

contentlayer.config.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,26 @@ export const Profile = defineDocumentType(() => ({
5353
computedFields: computedFields,
5454
}));
5555

56+
const bookFields: FieldDefs = {
57+
title: { type: "string", required: true },
58+
authorName: { type: "string", required: true },
59+
link: { type: "string", required: true },
60+
image: { type: "string", required: false },
61+
authorEmail: { type: "string", required: false },
62+
authorLink: { type: "string", required: false },
63+
};
64+
65+
export const Book = defineDocumentType(() => ({
66+
name: "Book",
67+
filePathPattern: `./books/**/*.mdx`,
68+
fields: bookFields,
69+
contentType: "mdx",
70+
computedFields: computedFields,
71+
}));
72+
5673
export default makeSource({
5774
contentDirPath: "./content",
58-
documentTypes: [Blog, Profile],
75+
documentTypes: [Blog, Profile, Book],
5976
mdx: {
6077
remarkPlugins: [remarkGfm],
6178
rehypePlugins: [

messages/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"nav": {
6060
"home": "Home",
6161
"profiles": "Profiles",
62+
"books": "Books",
6263
"editor": "Editor",
6364
"howTo": "How to",
6465
"blog": "Blog",
@@ -368,6 +369,7 @@
368369
"navigate": "Navigate",
369370
"home": "Home",
370371
"profiles": "Profiles",
372+
"books": "Books",
371373
"profileEditor": "Profile Editor",
372374
"blog": "Blog",
373375
"contactUs": "Contact Us",

messages/mm.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"nav": {
6060
"home": "ပင်မစာမျက်နှာ",
6161
"profiles": "ပရိုဖိုင်များ",
62+
"books": "စာအုပ်များ",
6263
"editor": "အယ်ဒီတာ",
6364
"howTo": "လမ်းညွှန်",
6465
"blog": "ဘလော့ဂ်",
@@ -368,6 +369,7 @@
368369
"navigate": "လမ်းညွှန်",
369370
"home": "ပင်မစာမျက်နှာ",
370371
"profiles": "ပရိုဖိုင်များ",
372+
"books": "စာအုပ်များ",
371373
"profileEditor": "ပရိုဖိုင် အယ်ဒီတာ",
372374
"blog": "ဘလော့ဂ်",
373375
"contactUs": "ဆက်သွယ်ရန်",

src/app/books/page.tsx

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import PageTransitionWrapper from "@/components/Animate/PageTransitionWrapper/PageTransitionWrapper";
2+
import Container from "@/components/Common/Container/Container";
3+
import SpacingDivider from "@/components/Common/SpacingDivider/SpacingDivider";
4+
import APP_CONFIG from "@/config/config";
5+
import { allBooks } from "contentlayer/generated";
6+
import { Metadata } from "next";
7+
8+
export const metadata: Metadata = {
9+
title: `Books | ${APP_CONFIG.title}`,
10+
description:
11+
"Discover recommended tech books and learning resources shared by the MMSWE community.",
12+
openGraph: {
13+
title: `Books | ${APP_CONFIG.title}`,
14+
description:
15+
"Discover recommended tech books and learning resources shared by the MMSWE community.",
16+
images: "https://mmswe.com/images/mmswe-seo.png",
17+
},
18+
};
19+
20+
const BooksPage = async () => {
21+
const books = [...allBooks].sort((a, b) => a.title.localeCompare(b.title));
22+
23+
return (
24+
<PageTransitionWrapper>
25+
<Container>
26+
<section className="py-16">
27+
<div className="max-w-3xl">
28+
<p className="font-mono text-xs uppercase tracking-[0.25em] text-zinc-500">
29+
Community Library
30+
</p>
31+
<h1 className="mt-4 font-display text-4xl font-bold text-zinc-100 sm:text-5xl">
32+
Books
33+
</h1>
34+
<p className="mt-4 max-w-2xl text-base leading-7 text-zinc-400">
35+
Recommended tech books and learning resources shared by Myanmar
36+
software engineers.
37+
</p>
38+
</div>
39+
40+
{books.length === 0 ? (
41+
<div className="mt-12 rounded-3xl border border-white/10 bg-surface/50 p-8 text-zinc-300">
42+
<h2 className="font-display text-2xl font-semibold text-zinc-100">
43+
No books yet
44+
</h2>
45+
<p className="mt-3 max-w-2xl text-sm leading-6 text-zinc-400">
46+
Community recommendations will appear here once contributors add
47+
book entries to the repository.
48+
</p>
49+
</div>
50+
) : (
51+
<div className="mt-12 grid gap-4">
52+
{books.map((book) => (
53+
<article
54+
key={book._id}
55+
className="rounded-3xl border border-white/10 bg-surface/50 p-6 transition-colors hover:border-white/20"
56+
>
57+
<div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
58+
<div className="flex flex-col gap-4 sm:flex-row sm:items-start">
59+
{book.image && (
60+
<img
61+
src={book.image}
62+
alt={`${book.title} cover`}
63+
className="h-32 w-24 rounded-xl border border-white/10 object-cover"
64+
/>
65+
)}
66+
67+
<div>
68+
<h2 className="font-display text-2xl font-semibold text-zinc-100">
69+
{book.title}
70+
</h2>
71+
<p className="mt-2 text-sm text-zinc-400">
72+
by {book.authorName}
73+
</p>
74+
{(book.authorEmail || book.authorLink) && (
75+
<div className="mt-3 flex flex-col gap-2 text-sm">
76+
{book.authorEmail && (
77+
<a
78+
href={`mailto:${book.authorEmail}`}
79+
className="text-zinc-400 transition-colors hover:text-prism-cyan"
80+
>
81+
{book.authorEmail}
82+
</a>
83+
)}
84+
{book.authorLink && (
85+
<a
86+
href={book.authorLink}
87+
target="_blank"
88+
rel="noopener noreferrer"
89+
className="text-zinc-400 transition-colors hover:text-prism-cyan"
90+
>
91+
{book.authorLink}
92+
</a>
93+
)}
94+
</div>
95+
)}
96+
</div>
97+
</div>
98+
99+
<a
100+
href={book.link}
101+
target="_blank"
102+
rel="noopener noreferrer"
103+
className="inline-flex items-center justify-center rounded-full border border-prism-cyan/40 px-4 py-2 text-sm font-medium text-prism-cyan transition-colors hover:border-prism-cyan hover:bg-prism-cyan/10"
104+
>
105+
Open Resource
106+
</a>
107+
</div>
108+
</article>
109+
))}
110+
</div>
111+
)}
112+
</section>
113+
114+
<SpacingDivider size="lg" />
115+
</Container>
116+
</PageTransitionWrapper>
117+
);
118+
};
119+
120+
export default BooksPage;

src/components/Common/Footer/Footer.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -339,27 +339,36 @@ const Footer = () => {
339339
{t("profiles")}
340340
</FooterLink>
341341
<FooterLink
342-
href="/profile/editor"
342+
href="/books"
343343
color="#22d3ee"
344344
index={2}
345345
isInView={isInView}
346346
mmFont={mmFont}
347347
>
348-
{t("profileEditor")}
348+
{t("books")}
349349
</FooterLink>
350350
<FooterLink
351-
href="/blog"
351+
href="/profile/editor"
352352
color="#fb7185"
353353
index={3}
354354
isInView={isInView}
355355
mmFont={mmFont}
356+
>
357+
{t("profileEditor")}
358+
</FooterLink>
359+
<FooterLink
360+
href="/blog"
361+
color="#fbbf24"
362+
index={4}
363+
isInView={isInView}
364+
mmFont={mmFont}
356365
>
357366
{t("blog")}
358367
</FooterLink>
359368
<FooterLink
360369
href="/contact-us"
361370
color="#fbbf24"
362-
index={4}
371+
index={5}
363372
isInView={isInView}
364373
mmFont={mmFont}
365374
>
@@ -368,8 +377,8 @@ const Footer = () => {
368377

369378
<FooterLink
370379
href="/jobs"
371-
color="#fbbf24"
372-
index={4}
380+
color="#fb7185"
381+
index={6}
373382
isInView={isInView}
374383
mmFont={mmFont}
375384
>
@@ -378,7 +387,7 @@ const Footer = () => {
378387
<FooterLink
379388
href="/how-to-develop-setup"
380389
color="#fb7185"
381-
index={5}
390+
index={7}
382391
isInView={isInView}
383392
mmFont={mmFont}
384393
>

src/components/Common/Navbar/Navbar.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import SignInButton from "@/components/Auth/SignInButton";
1717
const linkKeys = [
1818
{ key: "home", href: "/" },
1919
{ key: "profiles", href: "/profile" },
20+
{ key: "books", href: "/books" },
2021
{ key: "editor", href: "/profile/editor" },
2122
{ key: "howTo", href: "/how-to" },
2223
{ key: "blog", href: "/blog" },
@@ -26,6 +27,7 @@ const linkKeys = [
2627
const desktopNavWidthByKey: Record<(typeof linkKeys)[number]["key"], string> = {
2728
home: "w-[7rem]",
2829
profiles: "w-[6rem]",
30+
books: "w-[5.5rem]",
2931
editor: "w-[5.5rem]",
3032
howTo: "w-[5.25rem]",
3133
blog: "w-[4.5rem]",

0 commit comments

Comments
 (0)