diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 5e43440..8d28ed4 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -14,6 +14,7 @@ import { } from "lucide-react"; import type { Conversation, User } from "../lib/types.ts"; import { api } from "../lib/api.ts"; +import { useT } from "../lib/i18n.ts"; import { Avatar, Button, ContextMenu, FlowerMark, IconButton } from "./ui.tsx"; import { cn } from "../lib/cn.ts"; @@ -58,6 +59,7 @@ export function Sidebar({ mobileOpen: boolean; onCloseMobile: () => void; }) { + const { t } = useT(); const [menu, setMenu] = useState(null); const [query, setQuery] = useState(""); const [results, setResults] = useState<(Conversation & { snippet: string | null; snippetRole: string | null })[] | null>(null); @@ -132,12 +134,12 @@ export function Sidebar({
- + - +
@@ -146,13 +148,13 @@ export function Sidebar({ setQuery(e.target.value)} - placeholder="Search chats…" - aria-label="Search conversations" + placeholder={t("sidebar.searchPh")} + aria-label={t("sidebar.searchAria")} className="w-full rounded-2xl border border-stone-200/70 bg-stone-100 py-2 pl-9 pr-8 text-sm outline-none transition placeholder:text-stone-400 focus:border-accent-500/60 focus:bg-white dark:border-zinc-800 dark:bg-zinc-800/60 dark:placeholder:text-zinc-500 dark:focus:bg-zinc-900" /> {query && (
-

Two-factor (TOTP)

- {totpOn === null &&

Checking…

} +

{t("sec.totp")}

+ {totpOn === null &&

{t("sec.totpChecking")}

} {totpOn === false && !secret && ( <> -

Add a 6-digit code from your authenticator app on top of your access key.

- +

{t("sec.totpAddHint")}

+ )} {secret && (
-

Add this secret to your authenticator app (or open the otpauth link), then enter a code to confirm:

+

{t("sec.totpSecretHint")}

{secret} @@ -834,30 +834,30 @@ function SecuritySection({ onKeyRotated }: { onKeyRotated?: () => void }) { value={code} onChange={(e) => setCode(e.target.value.replace(/\D/g, "").slice(0, 6))} placeholder="000000" - aria-label="Authenticator code" + aria-label={t("login.totpAria")} inputMode="numeric" className="text-center tracking-[0.4em]" /> - +
)} {totpOn === true && (
- + setCode(e.target.value.replace(/\D/g, "").slice(0, 6))} placeholder="000000" - aria-label="Current authenticator code" + aria-label={t("login.totpAria")} inputMode="numeric" className="text-center tracking-[0.4em]" />
-
)} @@ -866,31 +866,31 @@ function SecuritySection({ onKeyRotated }: { onKeyRotated?: () => void }) {
- Passkeys (soon) - WebAuthn / platform authenticators — needs a server RP setup. + {t("sec.passkeys")} {t("feat.soon")} + {t("sec.passkeysHint")}

- Danger zone + {t("sec.danger")}

-

Permanently delete your account with all chats, shares and sessions. Cannot be undone.

-
{error &&

{error}

} - {}} title="New access key" icon={KeyRound}> + {}} title={t("sec.newKeyTitle")} icon={KeyRound}>
-

Copy it now — it won't be shown again. Your old sessions are revoked.

+

{t("sec.newKeyHint")}

{rotatedKey} {rotatedKey && }
- +
@@ -898,9 +898,9 @@ function SecuritySection({ onKeyRotated }: { onKeyRotated?: () => void }) { open={confirmDelete} onClose={() => setConfirmDelete(false)} onConfirm={removeAccount} - title="Delete your account?" - message="This permanently removes your account with all conversations, shares and sessions. This cannot be undone." - confirmLabel="Delete forever" + title={t("sec.deleteTitle")} + message={t("sec.deleteMsg")} + confirmLabel={t("sec.deleteForever")} />
);