From 3ebcc0ec55c742c7d84dae244a7a2a01350b47de Mon Sep 17 00:00:00 2001 From: miyaliu666 Date: Mon, 22 Dec 2025 03:43:52 +0800 Subject: [PATCH] feat(curriculum): release A1 Chinese (#64764) Co-authored-by: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com> --- client/i18n/locales/english/intro.json | 40 ++++++++----------- client/i18n/locales/english/translations.json | 1 + client/src/components/Map/index.tsx | 1 + .../build-external-curricula-data-v1.test.ts | 3 +- .../build-external-curricula-data-v2.test.ts | 1 + .../build-external-curricula-data-v2.ts | 9 +++++ ...h-a1-learn-certification-introduction.json | 2 +- .../blocks/zh-a1-learn-compound-finals.json | 2 +- .../blocks/zh-a1-learn-initials.json | 2 +- .../blocks/zh-a1-learn-nasal-finals.json | 2 +- .../blocks/zh-a1-learn-simple-finals.json | 2 +- .../zh-a1-learn-special-spelling-rules.json | 2 +- ...rstanding-greetings-and-introductions.json | 2 +- ...n-understanding-questions-and-answers.json | 2 +- ...practice-exchanging-basic-information.json | 2 +- .../zh-a1-practice-introducing-yourself.json | 2 +- .../blocks/zh-a1-practice-pinyin.json | 2 +- ...h-a1-quiz-greetings-and-introductions.json | 2 +- .../zh-a1-quiz-introduction-questions.json | 2 +- ...a1-review-greetings-and-introductions.json | 2 +- .../zh-a1-review-introduction-questions.json | 2 +- ...zh-a1-warm-up-greeting-new-colleagues.json | 2 +- .../zh-a1-warm-up-meeting-new-teammates.json | 2 +- .../superblocks/a1-professional-chinese.json | 6 +++ e2e/landing.spec.ts | 1 + e2e/map.spec.ts | 6 ++- shared/config/curriculum.ts | 4 +- 27 files changed, 62 insertions(+), 44 deletions(-) diff --git a/client/i18n/locales/english/intro.json b/client/i18n/locales/english/intro.json index 08ff5909cc6..0924f55394a 100644 --- a/client/i18n/locales/english/intro.json +++ b/client/i18n/locales/english/intro.json @@ -8767,37 +8767,29 @@ "zh-a1-module-discussing-team-skills": "Discussing Team Skills" }, "module-intros": { - "zh-a1-module-introduction-and-certification-overview": { - "note": "Coming Winter 2025", - "intro": ["PLACEHOLDER: Write the module intro here."] - }, - "zh-a1-module-initials-and-finals": { - "note": "Coming Winter 2025", - "intro": ["PLACEHOLDER: Write the module intro here."] - }, - "zh-a1-module-greetings-and-basic-introductions": { - "note": "Coming Winter 2025", - "intro": ["PLACEHOLDER: Write the module intro here."] - }, - "zh-a1-module-asking-and-giving-basic-information": { - "note": "Coming Winter 2025", - "intro": ["PLACEHOLDER: Write the module intro here."] - }, "zh-a1-module-introducing-others": { - "note": "Coming Winter 2025", - "intro": ["PLACEHOLDER: Write the module intro here."] + "note": "Coming 2026", + "intro": [ + "In this module, you will practice understanding short monologues that introduce information about other people, such as name, role, nationality, and age." + ] }, "zh-a1-module-getting-to-know-the-team": { - "note": "Coming Winter 2025", - "intro": ["PLACEHOLDER: Write the module intro here."] + "note": "Coming 2026", + "intro": [ + "In this module, you will practice understanding a short conversation that asks and answers simple questions about colleagues." + ] }, "zh-a1-module-talking-about-personal-skills": { - "note": "Coming Winter 2025", - "intro": ["PLACEHOLDER: Write the module intro here."] + "note": "Coming 2026", + "intro": [ + "In this module, you will practice understanding short monologues about what people can and cannot do, such as languages and work skills." + ] }, "zh-a1-module-discussing-team-skills": { - "note": "Coming Winter 2025", - "intro": ["PLACEHOLDER: Write the module intro here."] + "note": "Coming 2026", + "intro": [ + "In this module, you will practice understanding a short conversation about who can do which tasks on a team and how a project starts." + ] } }, "blocks": { diff --git a/client/i18n/locales/english/translations.json b/client/i18n/locales/english/translations.json index a8667c7face..b689fca0d7d 100644 --- a/client/i18n/locales/english/translations.json +++ b/client/i18n/locales/english/translations.json @@ -208,6 +208,7 @@ "core-certs-heading": "Recommended curriculum (still in beta):", "learn-english-heading": "Learn English for Developers:", "learn-spanish-heading": "Learn Professional Spanish:", + "learn-chinese-heading": "Learn Professional Chinese:", "professional-certs-heading": "Professional certifications:", "interview-prep-heading": "Prepare for the developer interview job search:", "legacy-curriculum-heading": "Our archived coursework:", diff --git a/client/src/components/Map/index.tsx b/client/src/components/Map/index.tsx index 2348b984dc5..62d43b009fd 100644 --- a/client/src/components/Map/index.tsx +++ b/client/src/components/Map/index.tsx @@ -32,6 +32,7 @@ const superBlockHeadings: { [key in SuperBlockStage]: string } = { [SuperBlockStage.Core]: 'landing.core-certs-heading', [SuperBlockStage.English]: 'landing.learn-english-heading', [SuperBlockStage.Spanish]: 'landing.learn-spanish-heading', + [SuperBlockStage.Chinese]: 'landing.learn-chinese-heading', [SuperBlockStage.Professional]: 'landing.professional-certs-heading', [SuperBlockStage.Extra]: 'landing.interview-prep-heading', [SuperBlockStage.Legacy]: 'landing.legacy-curriculum-heading', diff --git a/client/tools/external-curriculum/build-external-curricula-data-v1.test.ts b/client/tools/external-curriculum/build-external-curricula-data-v1.test.ts index 7dea187fda6..1e3b8859410 100644 --- a/client/tools/external-curriculum/build-external-curricula-data-v1.test.ts +++ b/client/tools/external-curriculum/build-external-curricula-data-v1.test.ts @@ -147,7 +147,8 @@ describe('external curriculum data build', () => { stage !== SuperBlockStage.Upcoming && stage !== SuperBlockStage.Catalog && stage !== SuperBlockStage.Core && - stage !== SuperBlockStage.Spanish + stage !== SuperBlockStage.Spanish && + stage !== SuperBlockStage.Chinese ); }) .flatMap(([, superBlocks]) => superBlocks); diff --git a/client/tools/external-curriculum/build-external-curricula-data-v2.test.ts b/client/tools/external-curriculum/build-external-curricula-data-v2.test.ts index a08d4cecd82..1e34a74b299 100644 --- a/client/tools/external-curriculum/build-external-curricula-data-v2.test.ts +++ b/client/tools/external-curriculum/build-external-curricula-data-v2.test.ts @@ -270,6 +270,7 @@ describe('external curriculum data build', () => { core: SuperBlockStage.Core, english: SuperBlockStage.English, spanish: SuperBlockStage.Spanish, + chinese: SuperBlockStage.Chinese, professional: SuperBlockStage.Professional, extra: SuperBlockStage.Extra, legacy: SuperBlockStage.Legacy, diff --git a/client/tools/external-curriculum/build-external-curricula-data-v2.ts b/client/tools/external-curriculum/build-external-curricula-data-v2.ts index 6d549da5a10..d3a0b9186f0 100644 --- a/client/tools/external-curriculum/build-external-curricula-data-v2.ts +++ b/client/tools/external-curriculum/build-external-curricula-data-v2.ts @@ -93,6 +93,7 @@ enum SuperBlockStage { Core = 'core', English = 'english', Spanish = 'spanish', + Chinese = 'chinese', Professional = 'professional', Extra = 'extra', Legacy = 'legacy' @@ -175,6 +176,14 @@ export const orderedSuperBlockInfo: OrderedSuperBlocks = { } ], + [SuperBlockStage.Chinese]: [ + { + dashedName: SuperBlocks.A1Chinese, + public: false, + title: intros[SuperBlocks.A1Chinese].title + } + ], + [SuperBlockStage.Extra]: [ { dashedName: SuperBlocks.TheOdinProject, diff --git a/curriculum/structure/blocks/zh-a1-learn-certification-introduction.json b/curriculum/structure/blocks/zh-a1-learn-certification-introduction.json index 9b511286857..266dc022865 100644 --- a/curriculum/structure/blocks/zh-a1-learn-certification-introduction.json +++ b/curriculum/structure/blocks/zh-a1-learn-certification-introduction.json @@ -1,6 +1,6 @@ { "name": "Certification Introduction", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-learn-certification-introduction", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-list", diff --git a/curriculum/structure/blocks/zh-a1-learn-compound-finals.json b/curriculum/structure/blocks/zh-a1-learn-compound-finals.json index a51ae1f16d8..2160435edd1 100644 --- a/curriculum/structure/blocks/zh-a1-learn-compound-finals.json +++ b/curriculum/structure/blocks/zh-a1-learn-compound-finals.json @@ -1,6 +1,6 @@ { "name": "Compound Finals", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-learn-compound-finals", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-learn-initials.json b/curriculum/structure/blocks/zh-a1-learn-initials.json index 9744e26f189..3c2c1f6dd5e 100644 --- a/curriculum/structure/blocks/zh-a1-learn-initials.json +++ b/curriculum/structure/blocks/zh-a1-learn-initials.json @@ -1,6 +1,6 @@ { "name": "Initials", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-learn-initials", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-learn-nasal-finals.json b/curriculum/structure/blocks/zh-a1-learn-nasal-finals.json index 4cfc4e8199d..39150f5d4a5 100644 --- a/curriculum/structure/blocks/zh-a1-learn-nasal-finals.json +++ b/curriculum/structure/blocks/zh-a1-learn-nasal-finals.json @@ -1,6 +1,6 @@ { "name": "Nasal Finals", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-learn-nasal-finals", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-learn-simple-finals.json b/curriculum/structure/blocks/zh-a1-learn-simple-finals.json index 47b5b712db3..c21bad2fb50 100644 --- a/curriculum/structure/blocks/zh-a1-learn-simple-finals.json +++ b/curriculum/structure/blocks/zh-a1-learn-simple-finals.json @@ -1,6 +1,6 @@ { "name": "Simple Finals", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-learn-simple-finals", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-learn-special-spelling-rules.json b/curriculum/structure/blocks/zh-a1-learn-special-spelling-rules.json index 92a07953c12..7000346548a 100644 --- a/curriculum/structure/blocks/zh-a1-learn-special-spelling-rules.json +++ b/curriculum/structure/blocks/zh-a1-learn-special-spelling-rules.json @@ -1,6 +1,6 @@ { "name": "Special Spelling Rules", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-learn-special-spelling-rules", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-learn-understanding-greetings-and-introductions.json b/curriculum/structure/blocks/zh-a1-learn-understanding-greetings-and-introductions.json index 31c9b48e3e0..1e26bca3396 100644 --- a/curriculum/structure/blocks/zh-a1-learn-understanding-greetings-and-introductions.json +++ b/curriculum/structure/blocks/zh-a1-learn-understanding-greetings-and-introductions.json @@ -1,6 +1,6 @@ { "name": "Understanding the Greetings and Introductions", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-learn-understanding-greetings-and-introductions", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-learn-understanding-questions-and-answers.json b/curriculum/structure/blocks/zh-a1-learn-understanding-questions-and-answers.json index 6ef2548382f..67bb63051ee 100644 --- a/curriculum/structure/blocks/zh-a1-learn-understanding-questions-and-answers.json +++ b/curriculum/structure/blocks/zh-a1-learn-understanding-questions-and-answers.json @@ -1,6 +1,6 @@ { "name": "Understanding the Questions and Answers", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-learn-understanding-questions-and-answers", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-practice-exchanging-basic-information.json b/curriculum/structure/blocks/zh-a1-practice-exchanging-basic-information.json index 312c00e566f..505e2ccfc5f 100644 --- a/curriculum/structure/blocks/zh-a1-practice-exchanging-basic-information.json +++ b/curriculum/structure/blocks/zh-a1-practice-exchanging-basic-information.json @@ -1,6 +1,6 @@ { "name": "Exchanging Basic Information", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-practice-exchanging-basic-information", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-practice-introducing-yourself.json b/curriculum/structure/blocks/zh-a1-practice-introducing-yourself.json index f1616d47b01..0521a5db65d 100644 --- a/curriculum/structure/blocks/zh-a1-practice-introducing-yourself.json +++ b/curriculum/structure/blocks/zh-a1-practice-introducing-yourself.json @@ -1,6 +1,6 @@ { "name": "​Building Your Self-Introduction", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-practice-introducing-yourself", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-practice-pinyin.json b/curriculum/structure/blocks/zh-a1-practice-pinyin.json index 857687d0436..5f85ff51b4c 100644 --- a/curriculum/structure/blocks/zh-a1-practice-pinyin.json +++ b/curriculum/structure/blocks/zh-a1-practice-pinyin.json @@ -1,6 +1,6 @@ { "name": "Pinyin Practice", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-practice-pinyin", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-quiz-greetings-and-introductions.json b/curriculum/structure/blocks/zh-a1-quiz-greetings-and-introductions.json index 764a138bc06..423d5bbdc6f 100644 --- a/curriculum/structure/blocks/zh-a1-quiz-greetings-and-introductions.json +++ b/curriculum/structure/blocks/zh-a1-quiz-greetings-and-introductions.json @@ -1,6 +1,6 @@ { "name": "Greetings and Introductions Quiz", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-quiz-greetings-and-introductions", "helpCategory": "Chinese Curriculum", "blockLayout": "link", diff --git a/curriculum/structure/blocks/zh-a1-quiz-introduction-questions.json b/curriculum/structure/blocks/zh-a1-quiz-introduction-questions.json index 74419d0fd24..0ed98f936c3 100644 --- a/curriculum/structure/blocks/zh-a1-quiz-introduction-questions.json +++ b/curriculum/structure/blocks/zh-a1-quiz-introduction-questions.json @@ -1,6 +1,6 @@ { "name": "Introduction Questions Quiz", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-quiz-introduction-questions", "helpCategory": "Chinese Curriculum", "blockLayout": "link", diff --git a/curriculum/structure/blocks/zh-a1-review-greetings-and-introductions.json b/curriculum/structure/blocks/zh-a1-review-greetings-and-introductions.json index 1232684b7b1..b4008f35283 100644 --- a/curriculum/structure/blocks/zh-a1-review-greetings-and-introductions.json +++ b/curriculum/structure/blocks/zh-a1-review-greetings-and-introductions.json @@ -1,6 +1,6 @@ { "name": "Greetings and Introductions Review", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-review-greetings-and-introductions", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-list", diff --git a/curriculum/structure/blocks/zh-a1-review-introduction-questions.json b/curriculum/structure/blocks/zh-a1-review-introduction-questions.json index 848068fb4e3..aaca0ff37ba 100644 --- a/curriculum/structure/blocks/zh-a1-review-introduction-questions.json +++ b/curriculum/structure/blocks/zh-a1-review-introduction-questions.json @@ -1,6 +1,6 @@ { "name": "Introduction Questions Review", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-review-introduction-questions", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-list", diff --git a/curriculum/structure/blocks/zh-a1-warm-up-greeting-new-colleagues.json b/curriculum/structure/blocks/zh-a1-warm-up-greeting-new-colleagues.json index e140b92fa1c..433363c3b1a 100644 --- a/curriculum/structure/blocks/zh-a1-warm-up-greeting-new-colleagues.json +++ b/curriculum/structure/blocks/zh-a1-warm-up-greeting-new-colleagues.json @@ -1,6 +1,6 @@ { "name": "Greeting New Colleagues", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-warm-up-greeting-new-colleagues", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/blocks/zh-a1-warm-up-meeting-new-teammates.json b/curriculum/structure/blocks/zh-a1-warm-up-meeting-new-teammates.json index e11b950e2a3..13a3bcf79a9 100644 --- a/curriculum/structure/blocks/zh-a1-warm-up-meeting-new-teammates.json +++ b/curriculum/structure/blocks/zh-a1-warm-up-meeting-new-teammates.json @@ -1,6 +1,6 @@ { "name": "Meeting New Teammates", - "isUpcomingChange": true, + "isUpcomingChange": false, "dashedName": "zh-a1-warm-up-meeting-new-teammates", "helpCategory": "Chinese Curriculum", "blockLayout": "challenge-grid", diff --git a/curriculum/structure/superblocks/a1-professional-chinese.json b/curriculum/structure/superblocks/a1-professional-chinese.json index 2cdbc9f8507..f62722e3bf8 100644 --- a/curriculum/structure/superblocks/a1-professional-chinese.json +++ b/curriculum/structure/superblocks/a1-professional-chinese.json @@ -52,9 +52,11 @@ }, { "dashedName": "zh-a1-chapter-introducing-colleagues-and-family", + "comingSoon": true, "modules": [ { "dashedName": "zh-a1-module-introducing-others", + "comingSoon": true, "blocks": [ "zh-a1-warm-up-introducing-others-basics", "zh-a1-learn-meeting-the-team", @@ -67,6 +69,7 @@ }, { "dashedName": "zh-a1-module-getting-to-know-the-team", + "comingSoon": true, "blocks": [ "zh-a1-warm-up-knowing-the-team-basics", "zh-a1-learn-asking-about-the-team", @@ -79,9 +82,11 @@ }, { "dashedName": "zh-a1-chapter-expressing-what-you-can-and-cant-do", + "comingSoon": true, "modules": [ { "dashedName": "zh-a1-module-talking-about-personal-skills", + "comingSoon": true, "blocks": [ "zh-a1-warm-up-personal-skills-basics", "zh-a1-learn-can-or-cannot", @@ -92,6 +97,7 @@ }, { "dashedName": "zh-a1-module-discussing-team-skills", + "comingSoon": true, "blocks": [ "zh-a1-warm-up-team-skills-basics", "zh-a1-learn-who-can-do-what-on-the-team", diff --git a/e2e/landing.spec.ts b/e2e/landing.spec.ts index 32ff2ebd8f4..9793ecf902f 100644 --- a/e2e/landing.spec.ts +++ b/e2e/landing.spec.ts @@ -28,6 +28,7 @@ const nonArchivedSuperBlocks = [ intro[SuperBlocks.A2English].title, intro[SuperBlocks.B1English].title, intro[SuperBlocks.A1Spanish].title, + intro[SuperBlocks.A1Chinese].title, intro[SuperBlocks.TheOdinProject].title, intro[SuperBlocks.CodingInterviewPrep].title, intro[SuperBlocks.ProjectEuler].title, diff --git a/e2e/map.spec.ts b/e2e/map.spec.ts index 786a623661d..464544b39ab 100644 --- a/e2e/map.spec.ts +++ b/e2e/map.spec.ts @@ -46,6 +46,10 @@ const LANDING_PAGE_LINKS = [ slug: 'a1-professional-spanish', name: 'A1 Professional Spanish Certification (Beta)' }, + { + slug: 'a1-professional-chinese', + name: 'A1 Professional Chinese Certification (Beta)' + }, { slug: 'foundational-c-sharp-with-microsoft', name: 'Free Foundational C# with Microsoft Certification' @@ -68,7 +72,7 @@ test.describe('Map Component', () => { page.getByText(translations.landing['interview-prep-heading']) ).toBeVisible(); const curriculumBtns = page.getByTestId('curriculum-map-button'); - await expect(curriculumBtns).toHaveCount(15); + await expect(curriculumBtns).toHaveCount(16); for (const { name, slug } of LANDING_PAGE_LINKS) { const superblockLink = page.getByRole('link', { diff --git a/shared/config/curriculum.ts b/shared/config/curriculum.ts index 2ee727bef7a..5daac8bde62 100644 --- a/shared/config/curriculum.ts +++ b/shared/config/curriculum.ts @@ -83,6 +83,7 @@ export enum SuperBlockStage { Core, English, Spanish, + Chinese, Professional, Extra, Legacy, @@ -95,6 +96,7 @@ const defaultStageOrder = [ SuperBlockStage.Core, SuperBlockStage.English, SuperBlockStage.Spanish, + SuperBlockStage.Chinese, SuperBlockStage.Extra, SuperBlockStage.Legacy, SuperBlockStage.Professional, @@ -129,6 +131,7 @@ export const superBlockStages: StageMap = { ], [SuperBlockStage.English]: [SuperBlocks.A2English, SuperBlocks.B1English], [SuperBlockStage.Spanish]: [SuperBlocks.A1Spanish], + [SuperBlockStage.Chinese]: [SuperBlocks.A1Chinese], [SuperBlockStage.Professional]: [SuperBlocks.FoundationalCSharp], [SuperBlockStage.Extra]: [ SuperBlocks.TheOdinProject, @@ -158,7 +161,6 @@ export const superBlockStages: StageMap = { SuperBlocks.FullStackOpen, SuperBlocks.A2Spanish, SuperBlocks.A2Chinese, - SuperBlocks.A1Chinese, SuperBlocks.DevPlayground, SuperBlocks.FullStackDeveloper ],