diff --git a/content/classes/sample-python-fundamentals.mdx b/content/classes/sample-python-fundamentals.mdx new file mode 100644 index 0000000..39eef79 --- /dev/null +++ b/content/classes/sample-python-fundamentals.mdx @@ -0,0 +1,28 @@ +--- +title: Myanmar Python Fundamentals (Sample) +description: >- + An introductory class covering Python syntax, problem-solving basics, + data structures, and scripting practice for students transitioning into + software development. +instructorName: Community Python Mentor Group +classLink: https://example.com/classes/python-fundamentals +tags: + - Python + - Programming Basics + - Backend +classType: In-Person +status: incoming +proofOfAssociation: >- + Submitter is a currently enrolled student and shared enrollment confirmation + plus class orientation details in the pull request for manual verification. +--- + +### Trust Context + +- Submitter role: Attending student (learning side). +- Class legitimacy: This entry demonstrates the required credibility narrative for a moderated listing. + +### Notes + +- Schedule and venue details are managed through the official class link. +- Listing appears only after maintainer approval. diff --git a/content/classes/sample-react-bootcamp.mdx b/content/classes/sample-react-bootcamp.mdx new file mode 100644 index 0000000..2f761ef --- /dev/null +++ b/content/classes/sample-react-bootcamp.mdx @@ -0,0 +1,29 @@ +--- +title: MMSWE React Bootcamp (Sample) +description: >- + A structured React bootcamp focused on modern frontend fundamentals: + component architecture, state management, routing, API integration, and + deployment workflow for beginner-to-intermediate learners. +instructorName: MMSWE Education Team +classLink: https://example.com/classes/react-bootcamp +tags: + - React + - TypeScript + - Frontend +classType: online +status: active +proofOfAssociation: >- + Submitter is a teaching assistant in the class and provided internal schedule + screenshots plus mentor confirmation to maintainers during PR review. +--- + +### Trust Context + +- Submitter role: Teaching assistant (teaching side). +- Class legitimacy: This entry represents a sample verified listing format for the curated Classes registry. + +### What learners can expect + +- Weekly live sessions with guided coding exercises. +- Practical mini-projects with mentor feedback. +- Community discussion and Q&A support. diff --git a/contentlayer.config.ts b/contentlayer.config.ts index 712ac32..791611a 100644 --- a/contentlayer.config.ts +++ b/contentlayer.config.ts @@ -62,6 +62,30 @@ const bookFields: FieldDefs = { authorLink: { type: "string", required: false }, }; +const classFields: FieldDefs = { + title: { type: "string", required: true }, + description: { type: "string", required: true }, + instructorName: { type: "string", required: true }, + classLink: { type: "string", required: true }, + tags: { + type: "list", + of: { type: "string" }, + required: true, + }, + classType: { + type: "enum", + options: ["online", "In-Person"], + required: true, + }, + status: { + type: "enum", + options: ["active", "completed", "incoming"], + required: true, + }, + proofOfAssociation: { type: "string", required: true }, + image: { type: "string", required: false }, +}; + export const Book = defineDocumentType(() => ({ name: "Book", filePathPattern: `./books/**/*.mdx`, @@ -70,9 +94,17 @@ export const Book = defineDocumentType(() => ({ computedFields: computedFields, })); +export const Class = defineDocumentType(() => ({ + name: "Class", + filePathPattern: `./classes/**/*.mdx`, + fields: classFields, + contentType: "mdx", + computedFields: computedFields, +})); + export default makeSource({ contentDirPath: "./content", - documentTypes: [Blog, Profile, Book], + documentTypes: [Blog, Profile, Book, Class], mdx: { remarkPlugins: [remarkGfm], rehypePlugins: [ diff --git a/messages/en.json b/messages/en.json index 0f80aa0..2e4b633 100644 --- a/messages/en.json +++ b/messages/en.json @@ -59,6 +59,7 @@ "nav": { "home": "Home", "profiles": "Profiles", + "classes": "Classes", "books": "Books", "editor": "Editor", "howTo": "How to", @@ -369,6 +370,7 @@ "navigate": "Navigate", "home": "Home", "profiles": "Profiles", + "classes": "Classes", "books": "Books", "profileEditor": "Profile Editor", "blog": "Blog", diff --git a/messages/mm.json b/messages/mm.json index 70bbbff..96b2a2a 100644 --- a/messages/mm.json +++ b/messages/mm.json @@ -59,6 +59,7 @@ "nav": { "home": "ပင်မစာမျက်နှာ", "profiles": "ပရိုဖိုင်များ", + "classes": "သင်တန်းများ", "books": "စာအုပ်များ", "editor": "အယ်ဒီတာ", "howTo": "လမ်းညွှန်", @@ -369,6 +370,7 @@ "navigate": "လမ်းညွှန်", "home": "ပင်မစာမျက်နှာ", "profiles": "ပရိုဖိုင်များ", + "classes": "သင်တန်းများ", "books": "စာအုပ်များ", "profileEditor": "ပရိုဖိုင် အယ်ဒီတာ", "blog": "ဘလော့ဂ်", diff --git a/src/app/classes/page.tsx b/src/app/classes/page.tsx new file mode 100644 index 0000000..3fbe2f3 --- /dev/null +++ b/src/app/classes/page.tsx @@ -0,0 +1,114 @@ +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 { allClasses } from "contentlayer/generated"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: `Classes | ${APP_CONFIG.title}`, + description: + "Explore verified tech classes in Myanmar curated by the MMSWE community.", + openGraph: { + title: `Classes | ${APP_CONFIG.title}`, + description: + "Explore verified tech classes in Myanmar curated by the MMSWE community.", + images: "https://mmswe.com/images/mmswe-seo.png", + }, +}; + +const ClassesPage = async () => { + const classes = [...allClasses].sort((a, b) => a.title.localeCompare(b.title)); + + return ( + + +
+
+

+ Verified Registry +

+

+ Classes +

+

+ A trust-first, community-curated directory of tech classes in + Myanmar. Listings are reviewed before publication. +

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

+ No classes yet +

+

+ Verified class listings will appear here after maintainers review + and approve class submissions. +

+
+ ) : ( +
+ {classes.map((classItem) => ( +
+
+
+
+

+ {classItem.title} +

+ + {classItem.status} + + + {classItem.classType} + +
+ +

+ {classItem.description} +

+ +

+ Instructor: {classItem.instructorName} +

+ +
+ {classItem.tags.map((tag) => ( + + {tag} + + ))} +
+
+ + +
+
+ ))} +
+ )} +
+ + +
+
+ ); +}; + +export default ClassesPage; diff --git a/src/components/Common/Footer/Footer.tsx b/src/components/Common/Footer/Footer.tsx index dc1ac97..d3cb247 100644 --- a/src/components/Common/Footer/Footer.tsx +++ b/src/components/Common/Footer/Footer.tsx @@ -120,7 +120,10 @@ const FooterLink = ({ {children} @@ -130,7 +133,9 @@ const FooterLink = ({ {/* Underline reveal on hover */} @@ -180,7 +185,12 @@ const SocialLink = ({ - + {label} @@ -271,7 +281,10 @@ const Footer = () => { {/* Tagline */} { transition={{ duration: 0.5, delay: 0.15 }} > {t("tagline.prefix")} - {t("tagline.innovate")},{" "} - {t("tagline.collaborate")},{" "} - {t("tagline.build")} + {t("tagline.innovate")} + ,{" "} + + {t("tagline.collaborate")} + + , {t("tagline.build")} {t("tagline.suffix")} @@ -306,9 +322,18 @@ const Footer = () => { "0 0 4px rgba(52,211,153,0.6)", ], }} - transition={{ duration: 2, repeat: Infinity, ease: "easeInOut" }} + transition={{ + duration: 2, + repeat: Infinity, + ease: "easeInOut", + }} /> - + {t("openSource")} @@ -318,7 +343,10 @@ const Footer = () => { {/* Navigation column */}
{ {t("navigate")}