feat(portal-shell): integrate next-intl + merge messages from teacher-portal (P1-4)

- Add next-intl v4.13.2 with cookie-based locale (no i18n routing)
- Create src/i18n/request.ts reading NEXT_LOCALE cookie
- Merge zh-CN/en messages from teacher-portal + add shell.dev.templates namespace
- Wrap next.config.js with withNextIntl plugin (Turbopack resolveAlias)
- Refactor RootLayout to async + NextIntlClientProvider + getLocale/getMessages
- Replace ThemeI18nProvider with ThemeProvider (theme-only, i18n removed)
- Remove locale/setLocale from PluginStore
- Rework locale-switcher to useLocale/useTranslations + router.refresh
- Update dev/templates page to use getTranslations (Server Component)
- Fix WorkbenchPageShell test (loading prop + center instead of children)

Verified: locale switch via NEXT_LOCALE cookie changes <html lang> and messages
zh-CN: 保存/取消/切换侧栏 | en: Save/Cancel/Toggle sidebar
typecheck 0 errors | lint 0 errors 2 warnings (generated) | vitest 231 passed
This commit is contained in:
SpecialX
2026-07-22 13:40:44 +08:00
parent 994441c2dc
commit da05c9107a
17 changed files with 1040 additions and 158 deletions

View File

@@ -0,0 +1,214 @@
{
"common": {
"brand": "Edu",
"button": {
"save": "Save",
"cancel": "Cancel",
"edit": "Edit",
"export": "Export",
"search": "Search",
"delete": "Delete",
"retry": "Retry",
"back": "Back"
},
"label": {
"search": "Search",
"loading": "Loading...",
"student": "Student",
"studentNo": "Student No.",
"score": "Score",
"feedback": "Feedback",
"class": "Class",
"subject": "Subject",
"name": "Name",
"email": "Email",
"roles": "Roles"
},
"status": {
"loading": "Loading...",
"saved": "Saved"
},
"error": {
"loadFailed": "Failed to load: {message}",
"pageError": "Something went wrong"
},
"nav": {
"empty": "No viewports available",
"loadError": "Navigation failed to load: {message}",
"logout": "Log out",
"noRoles": "No roles"
},
"locale": {
"label": "Language",
"zhCN": "简体中文",
"en": "English"
},
"empty": {
"title": "No data",
"description": "Adjust filters and retry, or create your first record"
},
"navLabel": {
"dashboard": "Dashboard",
"classes": "Classes",
"exams": "Exams",
"homework": "Homework",
"grades": "Grades",
"analytics": "Analytics",
"knowledgeGraph": "Knowledge Graph",
"notifications": "Notifications",
"aiAssist": "AI Assist",
"aiLessonPlan": "AI Lesson Plan",
"aiReport": "AI Report",
"attendance": "Attendance",
"questions": "Questions",
"textbooks": "Textbooks",
"lessonPlans": "Lesson Plans",
"coursePlans": "Course Plans",
"diagnostic": "Diagnostic",
"errorBook": "Error Book",
"practice": "Practice",
"elective": "Elective",
"leave": "Leave Requests",
"scheduleChanges": "Schedule Changes",
"settings": "Settings",
"students": "Students"
}
},
"shell": {
"toggleSidebar": "Toggle sidebar",
"layout": "Layout",
"empty": "No visible plugins",
"dev": {
"templates": {
"title": "Page Templates Quartet",
"description": "P1-3 preview pages (dev only, 404 in production)",
"list": "List Page Template",
"listDescription": "PageHeader + FilterBar + DataTable + Pagination + 3 states",
"detail": "Detail Page Template",
"detailDescription": "PageHeader + info area + Tabs/sections + related list",
"form": "Form Page Template",
"formDescription": "PageHeader + form + submit/cancel + error summary",
"workbench": "Workbench Page Template",
"workbenchDescription": "Three-column (tree/canvas/properties) composite",
"listExample": {
"title": "Exam Management",
"subtitle": "List page template example",
"searchPlaceholder": "Search exam name...",
"newExam": "New Exam"
},
"detailExample": {
"title": "2026 Spring Final Exam",
"subtitle": "Detail page template example"
},
"formExample": {
"title": "New Exam",
"subtitle": "Form page template example"
},
"workbenchExample": {
"title": "Lesson Plan Editor",
"subtitle": "Workbench page template example"
}
}
}
},
"auth": {
"title": "Login"
},
"dashboard": {
"title": "Welcome",
"greeting": "Welcome, {name}",
"subtitle": "{email} · Roles: {roles} · Data scope: {dataScope}",
"subtitleNoRoles": "None",
"error": {
"loadFailed": "Dashboard failed to load: {message}"
},
"empty": {
"title": "No data",
"description": "Dashboard data is not ready yet"
},
"stats": {
"classes": "Total Classes",
"exams": "Total Exams",
"pendingGrading": "Pending Grading"
},
"classes": {
"title": "My Classes",
"count": "{count} total",
"viewAll": "View all",
"emptyTitle": "No classes",
"emptyDescription": "Please contact the administrator to assign classes",
"grade": "Grade: {gradeId}",
"studentCount": "{count} students",
"viewStudents": "View students"
}
},
"classes": {
"title": "Classes"
},
"exams": {
"title": "Exams"
},
"homework": {
"title": "Homework"
},
"grades": {
"title": "Grades"
},
"analytics": {
"title": "Analytics"
},
"knowledgeGraph": {
"title": "Knowledge Graph"
},
"notifications": {
"title": "Notifications"
},
"aiAssist": {
"title": "AI Assist"
},
"aiLessonPlan": {
"title": "AI Lesson Plan"
},
"aiReport": {
"title": "AI Report"
},
"attendance": {
"title": "Attendance"
},
"questions": {
"title": "Questions"
},
"textbooks": {
"title": "Textbooks"
},
"lessonPlans": {
"title": "Lesson Plans"
},
"coursePlans": {
"title": "Course Plans"
},
"diagnostic": {
"title": "Diagnostic"
},
"errorBook": {
"title": "Error Book"
},
"practice": {
"title": "Practice"
},
"elective": {
"title": "Elective"
},
"leave": {
"title": "Leave Requests"
},
"scheduleChanges": {
"title": "Schedule Changes"
},
"settings": {
"title": "Settings"
},
"students": {
"title": "Students"
}
}

View File

@@ -0,0 +1,214 @@
{
"common": {
"brand": "Edu",
"button": {
"save": "保存",
"cancel": "取消",
"edit": "编辑",
"export": "导出",
"search": "搜索",
"delete": "删除",
"retry": "重试",
"back": "返回"
},
"label": {
"search": "搜索",
"loading": "加载中...",
"student": "学生",
"studentNo": "学号",
"score": "分数",
"feedback": "反馈",
"class": "班级",
"subject": "学科",
"name": "姓名",
"email": "邮箱",
"roles": "角色"
},
"status": {
"loading": "加载中...",
"saved": "已保存"
},
"error": {
"loadFailed": "加载失败:{message}",
"pageError": "页面出错了"
},
"nav": {
"empty": "暂无可用视口",
"loadError": "导航加载失败:{message}",
"logout": "退出登录",
"noRoles": "无角色"
},
"locale": {
"label": "语言",
"zhCN": "简体中文",
"en": "English"
},
"empty": {
"title": "暂无数据",
"description": "调整筛选条件后重试,或新建第一条记录"
},
"navLabel": {
"dashboard": "仪表盘",
"classes": "班级管理",
"exams": "考试管理",
"homework": "作业管理",
"grades": "成绩查询",
"analytics": "学情分析",
"knowledgeGraph": "知识图谱",
"notifications": "通知中心",
"aiAssist": "AI 辅助",
"aiLessonPlan": "AI 教案",
"aiReport": "AI 学情报告",
"attendance": "考勤管理",
"questions": "题库",
"textbooks": "教材",
"lessonPlans": "备课",
"coursePlans": "课程计划",
"diagnostic": "诊断报告",
"errorBook": "错题本",
"practice": "练习分析",
"elective": "选修课",
"leave": "请假审批",
"scheduleChanges": "调课申请",
"settings": "个人设置",
"students": "学生"
}
},
"shell": {
"toggleSidebar": "切换侧栏",
"layout": "布局",
"empty": "暂无可见插件",
"dev": {
"templates": {
"title": "页面模板四件套",
"description": "P1-3 验收用示例页(仅 dev 可见,生产环境 404",
"list": "列表页模板",
"listDescription": "PageHeader + FilterBar + DataTable + Pagination + 三态",
"detail": "详情页模板",
"detailDescription": "PageHeader + 信息区 + Tabs/分区 + 关联列表",
"form": "表单页模板",
"formDescription": "PageHeader + 表单 + 提交/取消 + 错误摘要",
"workbench": "工作台页模板",
"workbenchDescription": "三栏(树/画布/属性)复合组件",
"listExample": {
"title": "考试管理",
"subtitle": "列表页模板示例",
"searchPlaceholder": "搜索考试名称...",
"newExam": "新建考试"
},
"detailExample": {
"title": "2026 春季期末考试",
"subtitle": "详情页模板示例"
},
"formExample": {
"title": "新建考试",
"subtitle": "表单页模板示例"
},
"workbenchExample": {
"title": "教案编辑器",
"subtitle": "工作台页模板示例"
}
}
}
},
"auth": {
"title": "登录"
},
"dashboard": {
"title": "欢迎",
"greeting": "欢迎,{name}",
"subtitle": "{email} · 角色:{roles} · 数据范围:{dataScope}",
"subtitleNoRoles": "无",
"error": {
"loadFailed": "仪表盘加载失败:{message}"
},
"empty": {
"title": "暂无数据",
"description": "仪表盘数据尚未就绪"
},
"stats": {
"classes": "班级总数",
"exams": "考试总数",
"pendingGrading": "待批改"
},
"classes": {
"title": "我的班级",
"count": "{count} 个",
"viewAll": "查看全部",
"emptyTitle": "暂无班级",
"emptyDescription": "请联系管理员分配班级",
"grade": "年级:{gradeId}",
"studentCount": "{count} 名学生",
"viewStudents": "查看学生"
}
},
"classes": {
"title": "班级管理"
},
"exams": {
"title": "考试管理"
},
"homework": {
"title": "作业管理"
},
"grades": {
"title": "成绩查询"
},
"analytics": {
"title": "学情分析"
},
"knowledgeGraph": {
"title": "知识图谱"
},
"notifications": {
"title": "通知中心"
},
"aiAssist": {
"title": "AI 辅助"
},
"aiLessonPlan": {
"title": "AI 教案"
},
"aiReport": {
"title": "AI 学情报告"
},
"attendance": {
"title": "考勤管理"
},
"questions": {
"title": "题库"
},
"textbooks": {
"title": "教材"
},
"lessonPlans": {
"title": "备课"
},
"coursePlans": {
"title": "课程计划"
},
"diagnostic": {
"title": "诊断报告"
},
"errorBook": {
"title": "错题本"
},
"practice": {
"title": "练习分析"
},
"elective": {
"title": "选修课"
},
"leave": {
"title": "请假审批"
},
"scheduleChanges": {
"title": "调课申请"
},
"settings": {
"title": "个人设置"
},
"students": {
"title": "学生"
}
}