Files
Bing Free d5a25d7438 MUL-7608 feat(mobile): add Simplified Chinese localization (#8702)
Add a standalone Simplified Chinese UI to the mobile app, with a
Settings → Language picker (Follow system / English / 简体中文) whose
manual choice persists across restarts. Mobile keeps its own i18next
resources rather than reusing web/desktop copy, following the
conventions.mdx glossary: issue statuses and categories stay lowercase
English identifiers, Squad is 小队.

- Failure reasons: REASONS now mirrors web's REASON_LABEL, and a drift
  test pins it to the en/zh-Hans failure_reason keys.
- Production env: .env.production stays committed with the public
  multica.ai defaults; the *:prod scripts layer a gitignored
  .env.production.local on top for self-hosting or a custom bundle ID.
- Duplicate-mark activity rows from #8741 are localized too.
2026-09-24 13:07:10 +08:00

26 lines
1.1 KiB
TypeScript

/**
* Map backend auth errors to user-facing strings. The backend returns raw
* English messages that are fine for logs but should not surface as-is —
* we map the known shapes to friendlier copy and fall back to the caller's
* default for anything unrecognised.
*/
type Translate = (key: string) => string;
export function mapAuthError(err: unknown, fallback: string, t?: Translate): string {
if (!(err instanceof Error)) return fallback;
const msg = err.message.toLowerCase();
if (/invalid|incorrect|wrong/.test(msg)) {
return t ? t("verify.mismatch") : "That code didn't match. Double-check and try again.";
}
if (/expired/.test(msg)) {
return t ? t("verify.expired") : "That code has expired. Tap resend to get a new one.";
}
if (/rate.?limit|too many|throttle/.test(msg)) {
return t ? t("verify.rate_limited") : "Too many attempts. Wait a moment and try again.";
}
if (/network|fetch|timeout|unreachable/.test(msg)) {
return t ? t("verify.network") : "Can't reach Multica. Check your connection and retry.";
}
return fallback;
}