feat(settings): 设置与个人信息模块审计重构 — i18n + 服务注入解耦 + Error Boundary + 流式渲染
- 新增 SettingsService 接口 + Context 注入,组件层不再直接 import users/messaging actions - 新增 resolveRoleSettingsConfig 配置驱动角色路由,删除 parent/student/teacher-settings-view 冗余文件 - 新增 SettingsSectionErrorBoundary,每个 TabsContent + profile 角色概览区块均包裹 - 新增 ProfileStudentOverview/ProfileTeacherOverview 异步 Server Component + 骨架屏,支持流式渲染 - 抽取 buildStudentOverviewData 等纯函数到 lib/student-overview-data.ts,便于单元测试 - 新增 settings.json 翻译文件(zh-CN + en),所有组件改用 useTranslations/getTranslations - 重构 profile/page.tsx:i18n 适配 + Suspense 分区加载 + 业务逻辑抽离 - 同步更新架构图 004/005
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
import { redirect } from "next/navigation"
|
||||
import { getTranslations } from "next-intl/server"
|
||||
|
||||
import { requireAuth } from "@/shared/lib/auth-guard"
|
||||
import { SettingsView } from "@/modules/settings/components/settings-view"
|
||||
import { StudentSettingsView } from "@/modules/settings/components/student-settings-view"
|
||||
import { TeacherSettingsView } from "@/modules/settings/components/teacher-settings-view"
|
||||
import { ParentSettingsView } from "@/modules/settings/components/parent-settings-view"
|
||||
import { SettingsServiceProvider } from "@/modules/settings/components/settings-service-context"
|
||||
import { resolveRoleSettingsConfig } from "@/modules/settings/config/role-settings-config"
|
||||
import type { SettingsService } from "@/modules/settings/types"
|
||||
import { getUserProfile } from "@/modules/users/data-access"
|
||||
import { updateUserProfile } from "@/modules/users/actions"
|
||||
import { getNotificationPreferences } from "@/modules/notifications/preferences"
|
||||
import { updateNotificationPreferencesAction } from "@/modules/messaging/actions"
|
||||
import type { UpdateNotificationPreferencesInput } from "@/modules/notifications/types"
|
||||
|
||||
export const dynamic = "force-dynamic"
|
||||
|
||||
@@ -14,6 +18,32 @@ export const metadata = {
|
||||
title: "Settings",
|
||||
}
|
||||
|
||||
/**
|
||||
* 将通知偏好输入对象转换为 FormData,适配 updateNotificationPreferencesAction 的签名。
|
||||
* Action 内部通过 formData.get(key) === "on" 解析布尔值。
|
||||
*/
|
||||
function buildNotificationFormData(input: UpdateNotificationPreferencesInput): FormData {
|
||||
const formData = new FormData()
|
||||
const booleanFields: Array<keyof UpdateNotificationPreferencesInput> = [
|
||||
"emailEnabled",
|
||||
"smsEnabled",
|
||||
"pushEnabled",
|
||||
"homeworkNotifications",
|
||||
"gradeNotifications",
|
||||
"announcementNotifications",
|
||||
"messageNotifications",
|
||||
"attendanceNotifications",
|
||||
"quietHoursEnabled",
|
||||
]
|
||||
for (const field of booleanFields) {
|
||||
const value = input[field]
|
||||
if (value === true) formData.set(field, "on")
|
||||
}
|
||||
if (input.quietHoursStart) formData.set("quietHoursStart", input.quietHoursStart)
|
||||
if (input.quietHoursEnd) formData.set("quietHoursEnd", input.quietHoursEnd)
|
||||
return formData
|
||||
}
|
||||
|
||||
export default async function SettingsPage() {
|
||||
const ctx = await requireAuth()
|
||||
|
||||
@@ -24,22 +54,36 @@ export default async function SettingsPage() {
|
||||
|
||||
const roles = ctx.roles
|
||||
const notificationPrefs = await getNotificationPreferences(userId)
|
||||
const t = await getTranslations("settings")
|
||||
|
||||
if (roles.includes("admin")) {
|
||||
return (
|
||||
const config = resolveRoleSettingsConfig(roles)
|
||||
const description = t(config?.descriptionKey ?? "title")
|
||||
const backHref = config?.backHref ?? "/dashboard"
|
||||
const generalExtra = config?.generalExtra
|
||||
|
||||
// 构建 SettingsService 实现,注入到 SettingsServiceProvider
|
||||
// 组件层通过 useSettingsService() 消费,不直接 import users/messaging actions
|
||||
const service: SettingsService = {
|
||||
profile: {
|
||||
getProfile: async () => getUserProfile(userId),
|
||||
updateProfile: async (input) => updateUserProfile(input),
|
||||
},
|
||||
notifications: {
|
||||
getPreferences: async () => getNotificationPreferences(userId),
|
||||
updatePreferences: async (input) =>
|
||||
updateNotificationPreferencesAction(null, buildNotificationFormData(input)),
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsServiceProvider service={service}>
|
||||
<SettingsView
|
||||
description="Manage your admin preferences and account access."
|
||||
backHref="/admin/dashboard"
|
||||
description={description}
|
||||
backHref={backHref}
|
||||
user={userProfile}
|
||||
notificationPreferences={notificationPrefs}
|
||||
generalExtra={generalExtra}
|
||||
/>
|
||||
)
|
||||
}
|
||||
if (roles.includes("student")) {
|
||||
return <StudentSettingsView user={userProfile} notificationPreferences={notificationPrefs} />
|
||||
}
|
||||
if (roles.includes("parent")) {
|
||||
return <ParentSettingsView user={userProfile} notificationPreferences={notificationPrefs} />
|
||||
}
|
||||
return <TeacherSettingsView user={userProfile} notificationPreferences={notificationPrefs} />
|
||||
</SettingsServiceProvider>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user