fix(i18n): add Chinese translations for account settings page (#2712)
The account settings page had all user-facing strings (profile labels, password form placeholders, validation messages, button text) hardcoded in English. Replace them with i18n translation keys so the page renders correctly when the locale is set to Chinese. Fixed #2710
This commit is contained in:
@@ -8,11 +8,13 @@ import { Input } from "@/components/ui/input";
|
||||
import { fetch, getCsrfHeaders } from "@/core/api/fetcher";
|
||||
import { useAuth } from "@/core/auth/AuthProvider";
|
||||
import { parseAuthError } from "@/core/auth/types";
|
||||
import { useI18n } from "@/core/i18n/hooks";
|
||||
|
||||
import { SettingsSection } from "./settings-section";
|
||||
|
||||
export function AccountSettingsPage() {
|
||||
const { user, logout } = useAuth();
|
||||
const { t } = useI18n();
|
||||
const [currentPassword, setCurrentPassword] = useState("");
|
||||
const [newPassword, setNewPassword] = useState("");
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
@@ -26,11 +28,11 @@ export function AccountSettingsPage() {
|
||||
setMessage("");
|
||||
|
||||
if (newPassword !== confirmPassword) {
|
||||
setError("New passwords do not match");
|
||||
setError(t.settings.account.passwordMismatch);
|
||||
return;
|
||||
}
|
||||
if (newPassword.length < 8) {
|
||||
setError("Password must be at least 8 characters");
|
||||
setError(t.settings.account.passwordTooShort);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -55,12 +57,12 @@ export function AccountSettingsPage() {
|
||||
return;
|
||||
}
|
||||
|
||||
setMessage("Password changed successfully");
|
||||
setMessage(t.settings.account.passwordChangedSuccess);
|
||||
setCurrentPassword("");
|
||||
setNewPassword("");
|
||||
setConfirmPassword("");
|
||||
} catch {
|
||||
setError("Network error. Please try again.");
|
||||
setError(t.settings.account.networkError);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -68,12 +70,16 @@ export function AccountSettingsPage() {
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<SettingsSection title="Profile">
|
||||
<SettingsSection title={t.settings.account.profileTitle}>
|
||||
<div className="space-y-2">
|
||||
<div className="grid grid-cols-[max-content_max-content] items-center gap-4">
|
||||
<span className="text-muted-foreground text-sm">Email</span>
|
||||
<span className="text-muted-foreground text-sm">
|
||||
{t.settings.account.email}
|
||||
</span>
|
||||
<span className="text-sm font-medium">{user?.email ?? "—"}</span>
|
||||
<span className="text-muted-foreground text-sm">Role</span>
|
||||
<span className="text-muted-foreground text-sm">
|
||||
{t.settings.account.role}
|
||||
</span>
|
||||
<span className="text-sm font-medium capitalize">
|
||||
{user?.system_role ?? "—"}
|
||||
</span>
|
||||
@@ -82,20 +88,20 @@ export function AccountSettingsPage() {
|
||||
</SettingsSection>
|
||||
|
||||
<SettingsSection
|
||||
title="Change Password"
|
||||
description="Update your account password."
|
||||
title={t.settings.account.changePasswordTitle}
|
||||
description={t.settings.account.changePasswordDescription}
|
||||
>
|
||||
<form onSubmit={handleChangePassword} className="max-w-sm space-y-3">
|
||||
<Input
|
||||
type="password"
|
||||
placeholder="Current password"
|
||||
placeholder={t.settings.account.currentPassword}
|
||||
value={currentPassword}
|
||||
onChange={(e) => setCurrentPassword(e.target.value)}
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
type="password"
|
||||
placeholder="New password"
|
||||
placeholder={t.settings.account.newPassword}
|
||||
value={newPassword}
|
||||
onChange={(e) => setNewPassword(e.target.value)}
|
||||
required
|
||||
@@ -103,7 +109,7 @@ export function AccountSettingsPage() {
|
||||
/>
|
||||
<Input
|
||||
type="password"
|
||||
placeholder="Confirm new password"
|
||||
placeholder={t.settings.account.confirmNewPassword}
|
||||
value={confirmPassword}
|
||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
||||
required
|
||||
@@ -112,7 +118,9 @@ export function AccountSettingsPage() {
|
||||
{error && <p className="text-sm text-red-500">{error}</p>}
|
||||
{message && <p className="text-sm text-green-500">{message}</p>}
|
||||
<Button type="submit" variant="outline" size="sm" disabled={loading}>
|
||||
{loading ? "Updating..." : "Update Password"}
|
||||
{loading
|
||||
? t.settings.account.updating
|
||||
: t.settings.account.updatePassword}
|
||||
</Button>
|
||||
</form>
|
||||
</SettingsSection>
|
||||
@@ -125,7 +133,7 @@ export function AccountSettingsPage() {
|
||||
className="gap-2"
|
||||
>
|
||||
<LogOutIcon className="size-4" />
|
||||
Sign Out
|
||||
{t.settings.account.signOut}
|
||||
</Button>
|
||||
</SettingsSection>
|
||||
</div>
|
||||
|
||||
@@ -478,6 +478,23 @@ export const enUS: Translations = {
|
||||
notSupported: "Your browser does not support notifications.",
|
||||
disableNotification: "Disable notification",
|
||||
},
|
||||
account: {
|
||||
profileTitle: "Profile",
|
||||
email: "Email",
|
||||
role: "Role",
|
||||
changePasswordTitle: "Change Password",
|
||||
changePasswordDescription: "Update your account password.",
|
||||
currentPassword: "Current password",
|
||||
newPassword: "New password",
|
||||
confirmNewPassword: "Confirm new password",
|
||||
passwordMismatch: "New passwords do not match",
|
||||
passwordTooShort: "Password must be at least 8 characters",
|
||||
passwordChangedSuccess: "Password changed successfully",
|
||||
networkError: "Network error. Please try again.",
|
||||
updating: "Updating...",
|
||||
updatePassword: "Update Password",
|
||||
signOut: "Sign Out",
|
||||
},
|
||||
acknowledge: {
|
||||
emptyTitle: "Acknowledgements",
|
||||
emptyDescription: "Credits and acknowledgements will show here.",
|
||||
|
||||
@@ -394,6 +394,23 @@ export interface Translations {
|
||||
notSupported: string;
|
||||
disableNotification: string;
|
||||
};
|
||||
account: {
|
||||
profileTitle: string;
|
||||
email: string;
|
||||
role: string;
|
||||
changePasswordTitle: string;
|
||||
changePasswordDescription: string;
|
||||
currentPassword: string;
|
||||
newPassword: string;
|
||||
confirmNewPassword: string;
|
||||
passwordMismatch: string;
|
||||
passwordTooShort: string;
|
||||
passwordChangedSuccess: string;
|
||||
networkError: string;
|
||||
updating: string;
|
||||
updatePassword: string;
|
||||
signOut: string;
|
||||
};
|
||||
acknowledge: {
|
||||
emptyTitle: string;
|
||||
emptyDescription: string;
|
||||
|
||||
@@ -458,6 +458,23 @@ export const zhCN: Translations = {
|
||||
notSupported: "当前浏览器不支持通知功能。",
|
||||
disableNotification: "关闭通知",
|
||||
},
|
||||
account: {
|
||||
profileTitle: "个人信息",
|
||||
email: "邮箱",
|
||||
role: "角色",
|
||||
changePasswordTitle: "修改密码",
|
||||
changePasswordDescription: "更新你的账号密码。",
|
||||
currentPassword: "当前密码",
|
||||
newPassword: "新密码",
|
||||
confirmNewPassword: "确认新密码",
|
||||
passwordMismatch: "两次输入的新密码不一致",
|
||||
passwordTooShort: "密码长度至少为 8 个字符",
|
||||
passwordChangedSuccess: "密码修改成功",
|
||||
networkError: "网络错误,请重试。",
|
||||
updating: "更新中...",
|
||||
updatePassword: "修改密码",
|
||||
signOut: "退出登录",
|
||||
},
|
||||
acknowledge: {
|
||||
emptyTitle: "致谢",
|
||||
emptyDescription: "相关的致谢信息会展示在这里。",
|
||||
|
||||
Reference in New Issue
Block a user