From be2fb25b809d00c663c31804cc97a3767f97700b Mon Sep 17 00:00:00 2001 From: oratis Date: Tue, 16 Jun 2026 11:21:05 +0800 Subject: [PATCH] fix(i18n): shorten language switcher + localize scenario badges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The switcher showed the active locale's full native name (e.g. "Bahasa Indonesia"), making the header pill very wide. Render a compact uppercase code (EN/ZH/…) with a transparent native is overlaid on top: it keeps full keyboard and + * screen-reader accessibility and renders the OS-native option list with the + * full native language names, so discoverability isn't lost. * - * The current query is read from `window.location` at click time rather than - * via `useSearchParams()` to avoid forcing a Suspense boundary on the layout. + * Switching preserves the current path and query string via next-intl's + * locale-aware router (the default locale stays unprefixed). The current query + * is read from `window.location` at change time rather than via + * `useSearchParams()` to avoid forcing a Suspense boundary on the layout. */ export default function LocaleSwitcher({ className = "" }: { className?: string }) { const locale = useLocale(); @@ -31,14 +36,30 @@ export default function LocaleSwitcher({ className = "" }: { className?: string } return ( -
- +
+ + {/* Visible label — just the short code, keeps the chip narrow. */} + {locale} + + + + {/* Transparent native onSelect(e.target.value)} disabled={isPending} aria-label={t("label")} - className="appearance-none rounded-full border border-gray-300 bg-gray-50 py-1.5 ps-8 pe-7 text-sm text-gray-700 outline-none transition-colors hover:border-purple-300 focus:border-purple-400 focus:ring-2 focus:ring-purple-100 disabled:opacity-60" + className="absolute inset-0 h-full w-full cursor-pointer appearance-none opacity-0 outline-none disabled:cursor-default" > {routing.locales.map((l) => ( ))} - - -
); } diff --git a/src/components/ui/AgentCard.tsx b/src/components/ui/AgentCard.tsx index 8ef6eab4..b4b8eb5e 100644 --- a/src/components/ui/AgentCard.tsx +++ b/src/components/ui/AgentCard.tsx @@ -1,7 +1,7 @@ import { getTranslations } from "next-intl/server"; import { Link } from "@/i18n/navigation"; import { Zap, Layers, Star, GitFork } from "lucide-react"; -import { findScenario, scenarioLabel } from "@/lib/scenarios"; +import { findScenario } from "@/lib/scenarios"; // Minimal translator shape so priceLabel can be called with or without i18n. type Translator = (key: string, values?: Record) => string; @@ -57,6 +57,7 @@ function formatStars(n: number): string { export default async function AgentCard({ agent }: { agent: AgentCardData }) { const t = await getTranslations("Components"); + const tScenario = await getTranslations("Scenarios"); const isProject = agent.kind === "PROJECT"; return ( { const sc = findScenario(slug); if (!sc) return null; + const label = tScenario(slug); return ( {sc.emoji} - {sc.nameZh} + {label} ); })}