Add complete i18n infrastructure using next-intl (cookie-driven, without i18n routing) with zh-CN/en dictionary files, locale switcher, and NextIntlClientProvider in root layout. Add class invitation code system with new class_invitation_codes table, data-access layer (generate/validate/consume/revoke), server actions with permission checks, rate limiting, and audit logging. Add class-invitation-manager UI component. Refactor onboarding stepper to use i18n translations and accept new invitation code format (6-char alphanumeric) with backward compatibility for legacy 6-digit codes.
44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
/**
|
||
* 项目 i18n 配置(without i18n routing 模式)。
|
||
*
|
||
* 设计决策(v3 引入完整 i18n 体系):
|
||
* - 采用 next-intl 4.x,官方推荐的 Next.js App Router 方案
|
||
* - 不使用 `[locale]` 路由段,避免破坏现有 (auth)/(dashboard)/(onboarding) 路由组结构
|
||
* - locale 通过 cookie 持久化,SSR 时从 cookie 读取
|
||
* - 字典放在 shared/i18n/messages/,符合三层架构约束
|
||
*
|
||
* 支持的 locale:
|
||
* - zh-CN(默认):简体中文
|
||
* - en:英文
|
||
*/
|
||
|
||
export const LOCALES = ["zh-CN", "en"] as const;
|
||
export type Locale = (typeof LOCALES)[number];
|
||
|
||
export const DEFAULT_LOCALE: Locale = "zh-CN";
|
||
|
||
/** Cookie 名称,与 proxy.ts / request.ts 保持一致 */
|
||
export const LOCALE_COOKIE = "NEXT_LOCALE";
|
||
|
||
/** Cookie 属性:1 年有效期,全站可读 */
|
||
export const LOCALE_COOKIE_OPTIONS = {
|
||
maxAge: 60 * 60 * 24 * 365,
|
||
path: "/",
|
||
sameSite: "lax" as const,
|
||
};
|
||
|
||
/**
|
||
* 校验字符串是否为受支持的 locale。
|
||
* 用于从 cookie/header 读取后的容错处理。
|
||
*/
|
||
export function isLocale(value: string | null | undefined): value is Locale {
|
||
return typeof value === "string" && (LOCALES as readonly string[]).includes(value);
|
||
}
|
||
|
||
/**
|
||
* 将任意字符串归一化为合法 locale,非法值回退到默认。
|
||
*/
|
||
export function normalizeLocale(value: string | null | undefined): Locale {
|
||
return isLocale(value) ? value : DEFAULT_LOCALE;
|
||
}
|