From 0ac264b39d3b9a5eb2da22abefa122e1d2bdaf13 Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Wed, 25 Feb 2026 14:20:06 -0300 Subject: [PATCH] feat(i18n): migrate Settings page batch 1 (7 files, 28+ strings) - Main page.tsx: tab labels, footer - AppearanceTab: dark mode, health check logs - CacheStatsCard: prompt cache stats - ProxyTab: global proxy - SystemPromptTab: global system prompt - ThinkingBudgetTab: mode labels, effort levels - Expanded settings namespace from 63 to 100 keys --- .../settings/components/AppearanceTab.tsx | 14 +++---- .../settings/components/CacheStatsCard.tsx | 16 ++++---- .../settings/components/ProxyTab.tsx | 14 +++---- .../settings/components/SystemPromptTab.tsx | 16 +++++--- .../settings/components/ThinkingBudgetTab.tsx | 22 ++++++----- .../(dashboard)/dashboard/settings/page.tsx | 23 ++++++----- src/i18n/messages/en.json | 39 ++++++++++++++++++- src/i18n/messages/pt-BR.json | 39 ++++++++++++++++++- 8 files changed, 135 insertions(+), 48 deletions(-) diff --git a/src/app/(dashboard)/dashboard/settings/components/AppearanceTab.tsx b/src/app/(dashboard)/dashboard/settings/components/AppearanceTab.tsx index c661e0df64..81dc96d56a 100644 --- a/src/app/(dashboard)/dashboard/settings/components/AppearanceTab.tsx +++ b/src/app/(dashboard)/dashboard/settings/components/AppearanceTab.tsx @@ -4,9 +4,11 @@ import { useState, useEffect } from "react"; import { Card, Toggle } from "@/shared/components"; import { useTheme } from "@/shared/hooks/useTheme"; import { cn } from "@/shared/utils/cn"; +import { useTranslations } from "next-intl"; export default function AppearanceTab() { const { theme, setTheme, isDark } = useTheme(); + const t = useTranslations("settings"); const [settings, setSettings] = useState>({}); const [loading, setLoading] = useState(true); @@ -48,13 +50,13 @@ export default function AppearanceTab() { palette -

Appearance

+

{t("appearance")}

-

Dark Mode

-

Switch between light and dark themes

+

{t("darkMode")}

+

{t("switchThemes")}

setTheme(isDark ? "light" : "dark")} />
@@ -90,10 +92,8 @@ export default function AppearanceTab() {
-

Hide Health Check Logs

-

- When ON, suppress [HealthCheck] messages in server console -

+

{t("hideHealthLogs")}

+

{t("hideHealthLogsDesc")}

{ fetch("/api/cache/stats") @@ -31,40 +33,40 @@ export default function CacheStatsCard() {

cached - Prompt Cache + {t("promptCache")}

{cache ? (
-

Size

+

{t("size")}

{cache.size}/{cache.maxSize}

-

Hit Rate

+

{t("hitRate")}

{cache.hitRate?.toFixed(1) ?? 0}%

-

Hits

+

{t("hits")}

{cache.hits ?? 0}

-

Evictions

+

{t("evictions")}

{cache.evictions ?? 0}

) : ( -

Loading cache stats…

+

{t("loadingCacheStats")}

)} ); diff --git a/src/app/(dashboard)/dashboard/settings/components/ProxyTab.tsx b/src/app/(dashboard)/dashboard/settings/components/ProxyTab.tsx index 56e387ceec..4435a4019b 100644 --- a/src/app/(dashboard)/dashboard/settings/components/ProxyTab.tsx +++ b/src/app/(dashboard)/dashboard/settings/components/ProxyTab.tsx @@ -2,11 +2,14 @@ import { useState, useEffect, useRef } from "react"; import { Card, Button, ProxyConfigModal } from "@/shared/components"; +import { useTranslations } from "next-intl"; export default function ProxyTab() { const [proxyModalOpen, setProxyModalOpen] = useState(false); const [globalProxy, setGlobalProxy] = useState(null); const mountedRef = useRef(true); + const t = useTranslations("settings"); + const tc = useTranslations("common"); const loadGlobalProxy = async () => { try { @@ -44,12 +47,9 @@ export default function ProxyTab() { -

Global Proxy

+

{t("globalProxy")}

-

- Configure a global outbound proxy for all API calls. Individual providers, combos, and - keys can override this. -

+

{t("globalProxyDesc")}

{globalProxy ? (
@@ -58,7 +58,7 @@ export default function ProxyTab() {
) : ( - No global proxy configured + {t("noGlobalProxy")} )}
diff --git a/src/app/(dashboard)/dashboard/settings/components/SystemPromptTab.tsx b/src/app/(dashboard)/dashboard/settings/components/SystemPromptTab.tsx index 0327490276..acc78269f0 100644 --- a/src/app/(dashboard)/dashboard/settings/components/SystemPromptTab.tsx +++ b/src/app/(dashboard)/dashboard/settings/components/SystemPromptTab.tsx @@ -2,12 +2,14 @@ import { useState, useEffect } from "react"; import { Card, Toggle } from "@/shared/components"; +import { useTranslations } from "next-intl"; export default function SystemPromptTab() { const [config, setConfig] = useState({ enabled: false, prompt: "" }); const [loading, setLoading] = useState(true); const [status, setStatus] = useState(""); const [debounceTimer, setDebounceTimer] = useState(null); + const t = useTranslations("settings"); useEffect(() => { fetch("/api/settings/system-prompt") @@ -57,13 +59,14 @@ export default function SystemPromptTab() {
-

Global System Prompt

-

Injected into all requests at proxy level

+

{t("globalSystemPrompt")}

+

{t("systemPromptDesc")}

{status === "saved" && ( - check_circle Saved + check_circle{" "} + {t("saved")} )} handlePromptChange(e.target.value)} - placeholder="Enter system prompt to inject into all requests..." + placeholder={t("systemPromptPlaceholder")} rows={5} className="w-full px-4 py-3 rounded-lg border border-border/50 bg-surface/30 text-sm placeholder:text-text-muted/50 resize-y min-h-[120px] @@ -94,8 +97,9 @@ export default function SystemPromptTab() {

info - This prompt is prepended to the system message of every request. Use for global instructions, - safety guidelines, or response formatting rules. Send _skipSystemPrompt: true in a request to bypass. + {t("systemPromptHint")} Send{" "} + _skipSystemPrompt: true in a + request to bypass.

)} diff --git a/src/app/(dashboard)/dashboard/settings/components/ThinkingBudgetTab.tsx b/src/app/(dashboard)/dashboard/settings/components/ThinkingBudgetTab.tsx index 00734ee7d1..5b8bd14842 100644 --- a/src/app/(dashboard)/dashboard/settings/components/ThinkingBudgetTab.tsx +++ b/src/app/(dashboard)/dashboard/settings/components/ThinkingBudgetTab.tsx @@ -2,6 +2,7 @@ import { useState, useEffect } from "react"; import { Card, Button, Select } from "@/shared/components"; +import { useTranslations } from "next-intl"; const MODES = [ { @@ -46,6 +47,7 @@ export default function ThinkingBudgetTab() { const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [status, setStatus] = useState(""); + const t = useTranslations("settings"); useEffect(() => { fetch("/api/settings/thinking-budget") @@ -90,12 +92,12 @@ export default function ThinkingBudgetTab() {
-

Thinking Budget

-

Control AI reasoning token usage across all requests

+

{t("thinkingBudgetTitle")}

+

{t("thinkingBudgetDesc")}

{status === "saved" && ( - check_circle Saved + check_circle {t("saved")} )} @@ -121,7 +123,9 @@ export default function ThinkingBudgetTab() { {m.icon}
-

+

{m.label}

{m.desc}

@@ -134,9 +138,9 @@ export default function ThinkingBudgetTab() { {config.mode === "custom" && (
-

Token Budget

+

{t("tokenBudget")}

- {config.customBudget.toLocaleString()} tokens + {config.customBudget.toLocaleString()} {t("tokens")}
-

Base Effort Level

-

- Adaptive mode scales from this base level based on message count, tool usage, and prompt length. -

+

{t("baseEffortLevel")}

+

{t("adaptiveHint")}

{EFFORTS.map((e) => ( ))}
{/* Tab contents */} -
t.id === activeTab)?.label}> +
t2.id === activeTab)?.labelKey || "general")} + > {activeTab === "general" && ( <>
@@ -100,7 +105,7 @@ export default function SettingsPage() {

{APP_CONFIG.name} v{APP_CONFIG.version}

-

Local Mode — All data stored on your machine

+

{t("localMode")}

diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 5570a6988d..e311bb6ff8 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -629,7 +629,44 @@ "ipWhitelist": "IP Whitelist", "ipBlacklist": "IP Blacklist", "addIP": "Add IP", - "savedSuccessfully": "Settings saved successfully" + "savedSuccessfully": "Settings saved successfully", + "ai": "AI", + "advanced": "Advanced", + "localMode": "Local Mode — All data stored on your machine", + "switchThemes": "Switch between light and dark themes", + "hideHealthLogs": "Hide Health Check Logs", + "hideHealthLogsDesc": "When ON, suppress [HealthCheck] messages in server console", + "promptCache": "Prompt Cache", + "flushCache": "Flush Cache", + "flushing": "Flushing…", + "size": "Size", + "hits": "Hits", + "evictions": "Evictions", + "loadingCacheStats": "Loading cache stats…", + "globalProxy": "Global Proxy", + "globalProxyDesc": "Configure a global outbound proxy for all API calls. Individual providers, combos, and keys can override this.", + "noGlobalProxy": "No global proxy configured", + "configure": "Configure", + "globalSystemPrompt": "Global System Prompt", + "systemPromptDesc": "Injected into all requests at proxy level", + "saved": "Saved", + "systemPromptPlaceholder": "Enter system prompt to inject into all requests...", + "systemPromptHint": "This prompt is prepended to the system message of every request. Use for global instructions, safety guidelines, or response formatting rules.", + "chars": "{count} chars", + "thinkingBudgetTitle": "Thinking Budget", + "thinkingBudgetDesc": "Control AI reasoning token usage across all requests", + "passthrough": "Passthrough", + "passthroughDesc": "No changes — client controls thinking budget", + "auto": "Auto", + "autoDesc": "Strip all thinking config — let provider decide", + "custom": "Custom", + "customDesc": "Set a fixed token budget for all requests", + "adaptive": "Adaptive", + "adaptiveDesc": "Scale budget based on request complexity", + "tokenBudget": "Token Budget", + "tokens": "tokens", + "baseEffortLevel": "Base Effort Level", + "adaptiveHint": "Adaptive mode scales from this base level based on message count, tool usage, and prompt length." }, "translator": { "title": "Translator", diff --git a/src/i18n/messages/pt-BR.json b/src/i18n/messages/pt-BR.json index 68abd7cd00..f67d532085 100644 --- a/src/i18n/messages/pt-BR.json +++ b/src/i18n/messages/pt-BR.json @@ -629,7 +629,44 @@ "ipWhitelist": "Lista de IPs Permitidos", "ipBlacklist": "Lista de IPs Bloqueados", "addIP": "Adicionar IP", - "savedSuccessfully": "Configurações salvas com sucesso" + "savedSuccessfully": "Configurações salvas com sucesso", + "ai": "IA", + "advanced": "Avançado", + "localMode": "Modo Local — Todos os dados armazenados na sua máquina", + "switchThemes": "Alternar entre temas claro e escuro", + "hideHealthLogs": "Ocultar Logs de Health Check", + "hideHealthLogsDesc": "Quando ATIVADO, suprime mensagens [HealthCheck] no console do servidor", + "promptCache": "Cache de Prompt", + "flushCache": "Limpar Cache", + "flushing": "Limpando…", + "size": "Tamanho", + "hits": "Acertos", + "evictions": "Remoções", + "loadingCacheStats": "Carregando estatísticas do cache…", + "globalProxy": "Proxy Global", + "globalProxyDesc": "Configure um proxy de saída global para todas as chamadas de API. Provedores individuais, combos e chaves podem sobrescrever.", + "noGlobalProxy": "Nenhum proxy global configurado", + "configure": "Configurar", + "globalSystemPrompt": "Prompt de Sistema Global", + "systemPromptDesc": "Injetado em todas as requisições no nível do proxy", + "saved": "Salvo", + "systemPromptPlaceholder": "Digite o prompt de sistema para injetar em todas as requisições...", + "systemPromptHint": "Este prompt é adicionado antes da mensagem de sistema de cada requisição. Use para instruções globais, diretrizes de segurança ou regras de formatação.", + "chars": "{count} caracteres", + "thinkingBudgetTitle": "Orçamento de Raciocínio", + "thinkingBudgetDesc": "Controle o uso de tokens de raciocínio da IA em todas as requisições", + "passthrough": "Passagem Direta", + "passthroughDesc": "Sem alterações — cliente controla orçamento de raciocínio", + "auto": "Automático", + "autoDesc": "Remove toda configuração de raciocínio — provedor decide", + "custom": "Personalizado", + "customDesc": "Define um orçamento fixo de tokens para todas as requisições", + "adaptive": "Adaptativo", + "adaptiveDesc": "Escala orçamento baseado na complexidade da requisição", + "tokenBudget": "Orçamento de Tokens", + "tokens": "tokens", + "baseEffortLevel": "Nível de Esforço Base", + "adaptiveHint": "Modo adaptativo escala a partir deste nível base baseado na quantidade de mensagens, uso de ferramentas e tamanho do prompt." }, "translator": { "title": "Tradutor",