diff --git a/src/app/(dashboard)/dashboard/translator/TranslatorPageClient.tsx b/src/app/(dashboard)/dashboard/translator/TranslatorPageClient.tsx index db8470682c..45adeefcf0 100644 --- a/src/app/(dashboard)/dashboard/translator/TranslatorPageClient.tsx +++ b/src/app/(dashboard)/dashboard/translator/TranslatorPageClient.tsx @@ -1,5 +1,7 @@ "use client"; +import { useTranslations } from "next-intl"; + import { useState } from "react"; import { SegmentedControl } from "@/shared/components"; import PlaygroundMode from "./components/PlaygroundMode"; @@ -7,26 +9,21 @@ import ChatTesterMode from "./components/ChatTesterMode"; import TestBenchMode from "./components/TestBenchMode"; import LiveMonitorMode from "./components/LiveMonitorMode"; -const MODES = [ - { value: "playground", label: "Playground", icon: "code" }, - { value: "chat-tester", label: "Chat Tester", icon: "chat" }, - { value: "test-bench", label: "Test Bench", icon: "science" }, - { value: "live-monitor", label: "Live Monitor", icon: "monitoring" }, -]; - -const MODE_DESCRIPTIONS: Record = { - playground: - "Paste any API request body and see how OmniRoute translates it between provider formats (OpenAI ↔ Claude ↔ Gemini ↔ Responses API)", - "chat-tester": - "Send real chat requests through OmniRoute and see the full round-trip: your input, the translated request, the provider response, and the translated output", - "test-bench": - "Define multiple test cases with different inputs and expected outputs, run them all at once, and compare results across providers and models", - "live-monitor": - "Watch incoming requests in real-time as they flow through OmniRoute — see format translations happening live and identify issues instantly", -}; - export default function TranslatorPageClient() { + const t = useTranslations("translator"); const [mode, setMode] = useState("playground"); + const modes = [ + { value: "playground", label: t("playground"), icon: "code" }, + { value: "chat-tester", label: t("chatTester"), icon: "chat" }, + { value: "test-bench", label: t("testBench"), icon: "science" }, + { value: "live-monitor", label: t("liveMonitor"), icon: "monitoring" }, + ]; + const modeDescriptions: Record = { + playground: t("modeDescriptionPlayground"), + "chat-tester": t("modeDescriptionChatTester"), + "test-bench": t("modeDescriptionTestBench"), + "live-monitor": t("modeDescriptionLiveMonitor"), + }; return (
@@ -35,14 +32,13 @@ export default function TranslatorPageClient() {

translate - Translator Playground + {t("playgroundTitle")}

- {MODE_DESCRIPTIONS[mode] || - "Debug, test, and visualize how OmniRoute translates API requests between providers"} + {modeDescriptions[mode] || t("modeDescriptionFallback")}

- +
{/* Mode Content */} diff --git a/src/app/(dashboard)/dashboard/translator/components/LiveMonitorMode.tsx b/src/app/(dashboard)/dashboard/translator/components/LiveMonitorMode.tsx index d07c105b2a..cb605ac3dc 100644 --- a/src/app/(dashboard)/dashboard/translator/components/LiveMonitorMode.tsx +++ b/src/app/(dashboard)/dashboard/translator/components/LiveMonitorMode.tsx @@ -13,6 +13,7 @@ import { FORMAT_META } from "../exampleTemplates"; */ export default function LiveMonitorMode() { const t = useTranslations("translator"); + const tc = useTranslations("common"); const [events, setEvents] = useState([]); const [loading, setLoading] = useState(true); const [autoRefresh, setAutoRefresh] = useState(true); @@ -60,21 +61,25 @@ export default function LiveMonitorMode() {

{t("realtime")}

- Shows translation events as API calls flow through OmniRoute. Events come from the - in-memory buffer (resets on restart). Use{" "} + {t("liveMonitorDescription")}{" "} {t("chatTester")},{" "} - {t("testBench")}, or external API calls to - generate events. + {t("testBench")}, {t("or")}{" "} + {t("externalApiCalls").toLowerCase()} {t("toGenerateEvents")}

{/* Stats Cards */}
- - - - + + + +
{/* Controls */} @@ -90,7 +95,7 @@ export default function LiveMonitorMode() { onClick={() => setAutoRefresh(!autoRefresh)} className="text-sm text-text-main hover:text-primary transition-colors" > - {autoRefresh ? "Live — Auto-refreshing" : "Paused"} + {autoRefresh ? t("liveAutoRefreshing") : t("paused")} @@ -111,7 +116,7 @@ export default function LiveMonitorMode() { {loading ? (
progress_activity - Loading... + {tc("loading")}
) : events.length === 0 ? (
@@ -120,39 +125,36 @@ export default function LiveMonitorMode() {

{t("noTranslations")}

- Translation events appear here as requests flow through OmniRoute. Use any of these - methods to generate events: + {t("eventsAppearHint")}

- Chat Tester tab + {t("chatTesterTab")} - Test Bench tab + {t("testBenchTab")} - External API calls + {t("externalApiCalls")} - IDE/CLI integrations + {t("ideCliIntegrations")}
-

- Note: Events are stored in-memory and reset when the server restarts. -

+

{t("inMemoryNote")}

) : (
- + - + + + @@ -195,11 +197,11 @@ export default function LiveMonitorMode() { diff --git a/src/app/(dashboard)/dashboard/translator/components/PlaygroundMode.tsx b/src/app/(dashboard)/dashboard/translator/components/PlaygroundMode.tsx index d04d8edeb9..c0ed23c811 100644 --- a/src/app/(dashboard)/dashboard/translator/components/PlaygroundMode.tsx +++ b/src/app/(dashboard)/dashboard/translator/components/PlaygroundMode.tsx @@ -11,6 +11,7 @@ const Editor = dynamic(() => import("@monaco-editor/react"), { ssr: false }); export default function PlaygroundMode() { const t = useTranslations("translator"); + const tc = useTranslations("common"); const [sourceFormat, setSourceFormat] = useState("claude"); const [targetFormat, setTargetFormat] = useState("openai"); const [inputContent, setInputContent] = useState(""); @@ -118,11 +119,7 @@ export default function PlaygroundMode() {

{t("formatConverter")}

-

- Paste or type a JSON request body. The translator will auto-detect the source format and - convert it to the target format. Use this to debug how OmniRoute translates requests - between formats (OpenAI ↔ Claude ↔ Gemini ↔ Responses API). -

+

{t("formatConverterDescription")}

{/* Format Controls Bar */} @@ -131,7 +128,7 @@ export default function PlaygroundMode() { {/* Source Format */}
@@ -148,7 +145,7 @@ export default function PlaygroundMode() { /> {detectedFormat && ( - Auto + {t("auto")} )}
@@ -158,7 +155,7 @@ export default function PlaygroundMode() { @@ -166,7 +163,7 @@ export default function PlaygroundMode() { {/* Target Format */}
@@ -190,7 +187,7 @@ export default function PlaygroundMode() { disabled={!inputContent.trim() || translating} className="whitespace-nowrap" > - Translate + {t("translateAction")}
@@ -204,7 +201,7 @@ export default function PlaygroundMode() {
input -

{t(">input +

{t("input")}

{detectedFormat && ( {FORMAT_META[detectedFormat]?.label || detectedFormat} @@ -220,7 +217,7 @@ export default function PlaygroundMode() { @@ -232,7 +229,7 @@ export default function PlaygroundMode() { setActiveTemplate(null); }} className="p-1.5 rounded hover:bg-black/5 dark:hover:bg-white/5 text-text-muted hover:text-text-main transition-colors" - title="Clear" + title={t("clear")} > delete @@ -253,7 +250,7 @@ export default function PlaygroundMode() { wordWrap: "on", automaticLayout: true, formatOnPaste: true, - placeholder: "Paste a request body here or select a template below...", + placeholder: t("inputPlaceholder"), }} />
@@ -268,7 +265,7 @@ export default function PlaygroundMode() { output -

{t(">output +

{t("output")}

{outputContent && ( {FORMAT_META[targetFormat]?.label || targetFormat} @@ -279,7 +276,7 @@ export default function PlaygroundMode() { @@ -313,8 +310,8 @@ export default function PlaygroundMode() { library_books -

Example Templates

- — Click to load +

{t("exampleTemplates")}

+ {t("exampleTemplatesHint")}
{EXAMPLE_TEMPLATES.map((template) => ( @@ -342,11 +339,9 @@ export default function PlaygroundMode() { {activeTemplate && (
info - Template loads the request in{" "} - - {FORMAT_META[sourceFormat]?.label || sourceFormat} - {" "} - format. Change Source Format to load in a different format. + {t("templateLoadHint", { + format: FORMAT_META[sourceFormat]?.label || sourceFormat, + })}
)}
diff --git a/src/app/(dashboard)/dashboard/translator/page.tsx b/src/app/(dashboard)/dashboard/translator/page.tsx index b7861263a3..f1cd6e2a3e 100644 --- a/src/app/(dashboard)/dashboard/translator/page.tsx +++ b/src/app/(dashboard)/dashboard/translator/page.tsx @@ -1,9 +1,13 @@ import TranslatorPageClient from "./TranslatorPageClient"; +import { getTranslations } from "next-intl/server"; -export const metadata = { - title: "Translator Playground | OmniRoute", - description: "Debug, test, and visualize API format translations between providers", -}; +export async function generateMetadata() { + const t = await getTranslations("translator"); + return { + title: t("metaTitle"), + description: t("metaDescription"), + }; +} export default function TranslatorPage() { return ; diff --git a/src/app/(dashboard)/dashboard/usage/components/BudgetTab.tsx b/src/app/(dashboard)/dashboard/usage/components/BudgetTab.tsx index c93620bda8..d0af6f71db 100644 --- a/src/app/(dashboard)/dashboard/usage/components/BudgetTab.tsx +++ b/src/app/(dashboard)/dashboard/usage/components/BudgetTab.tsx @@ -149,7 +149,7 @@ export default function BudgetTab() {
-
diff --git a/src/app/forgot-password/page.tsx b/src/app/forgot-password/page.tsx index 2e2c2414bd..7aba55439a 100644 --- a/src/app/forgot-password/page.tsx +++ b/src/app/forgot-password/page.tsx @@ -19,7 +19,7 @@ export default function ForgotPasswordPage() {
-

{t(">resetPassword +

{t("resetPassword")}

{t("resetDescription")}

diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 441b3f61cc..b0131d9e4c 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -104,7 +104,7 @@ export default function LoginPage() { rocket_launch
-

{t(">welcome +

{t("welcome")}

Let's get your OmniRoute instance configured

@@ -189,13 +189,13 @@ export default function LoginPage() {
OmniRoute -

{t(">signIn +

{t("signIn")}

{t("enterPassword")}

-
{t(">time - {t(">source + {t("time")}{t("source")} {t(">target - {t(">model - {t(">status - {t(">latency + {t("target")}{t("model")}{t("status")}{t("latency")}
{event.status === "success" ? ( - OK + {t("ok")} ) : ( - {event.statusCode || "ERR"} + {event.statusCode || t("errorShort")} )}
- {t(">session - {t(">age - {t(">requests - {t(">connection