终端顶栏新增中英文语言切换按钮

KoyfinWeatherTerminal 顶栏右侧添加 EN/中文 切换组件,样式与落地页一致。
Refresh 按钮文字同步支持国际化。

Tested: npm run build 通过
This commit is contained in:
2569718930@qq.com
2026-05-25 01:26:03 +08:00
parent 0574b0cc20
commit bdb314d1a7
@@ -325,20 +325,24 @@ function MarketTable({
function KoyfinWeatherTerminal({ function KoyfinWeatherTerminal({
generatedText, generatedText,
isEn, isEn,
locale,
onRefresh, onRefresh,
refreshing, refreshing,
rows, rows,
selectedRow, selectedRow,
setSelectedRow, setSelectedRow,
toggleLocale,
userLocalTime, userLocalTime,
}: { }: {
generatedText: string; generatedText: string;
isEn: boolean; isEn: boolean;
locale: "zh-CN" | "en-US";
onRefresh: () => void; onRefresh: () => void;
refreshing: boolean; refreshing: boolean;
rows: ScanOpportunityRow[]; rows: ScanOpportunityRow[];
selectedRow: ScanOpportunityRow | null; selectedRow: ScanOpportunityRow | null;
setSelectedRow: (row: ScanOpportunityRow) => void; setSelectedRow: (row: ScanOpportunityRow) => void;
toggleLocale: () => void;
userLocalTime: string; userLocalTime: string;
}) { }) {
const topRows = rows.slice(0, 18); const topRows = rows.slice(0, 18);
@@ -404,6 +408,35 @@ function KoyfinWeatherTerminal({
</div> </div>
<div className="flex items-center gap-3 text-sm text-slate-300"> <div className="flex items-center gap-3 text-sm text-slate-300">
<span className="hidden font-mono md:inline">{userLocalTime}</span> <span className="hidden font-mono md:inline">{userLocalTime}</span>
{/* Language toggle — matches landing page style */}
<button
type="button"
aria-label={isEn ? "Switch to Chinese" : "切换到英文"}
title={isEn ? "Switch to Chinese" : "切换到英文"}
onClick={toggleLocale}
className="inline-flex h-9 items-center gap-0.5 rounded border border-slate-600 bg-[#29323d] p-1 text-xs font-bold text-slate-400 hover:border-slate-400"
>
<span
className={clsx(
"rounded px-2 py-1 transition-colors",
locale === "zh-CN"
? "bg-blue-600 text-white"
: "hover:text-slate-200",
)}
>
</span>
<span
className={clsx(
"rounded px-2 py-1 transition-colors",
locale === "en-US"
? "bg-blue-600 text-white"
: "hover:text-slate-200",
)}
>
EN
</span>
</button>
<button <button
type="button" type="button"
onClick={onRefresh} onClick={onRefresh}
@@ -411,7 +444,7 @@ function KoyfinWeatherTerminal({
className="inline-flex h-9 items-center gap-2 rounded border border-slate-600 bg-[#29323d] px-3 font-bold hover:bg-[#323c49] disabled:opacity-60" className="inline-flex h-9 items-center gap-2 rounded border border-slate-600 bg-[#29323d] px-3 font-bold hover:bg-[#323c49] disabled:opacity-60"
> >
<RefreshCw size={15} className={refreshing ? "animate-spin" : ""} /> <RefreshCw size={15} className={refreshing ? "animate-spin" : ""} />
Refresh {isEn ? "Refresh" : "刷新"}
</button> </button>
<Link <Link
href="/account" href="/account"
@@ -839,6 +872,8 @@ function ScanTerminalScreen() {
); );
const [locale, setLocale] = useState<"zh-CN" | "en-US">("zh-CN"); const [locale, setLocale] = useState<"zh-CN" | "en-US">("zh-CN");
const isEn = locale === "en-US"; const isEn = locale === "en-US";
const toggleLocale = () =>
setLocale((prev) => (prev === "zh-CN" ? "en-US" : "zh-CN"));
const [hydrated, setHydrated] = useState(false); const [hydrated, setHydrated] = useState(false);
const [localFullAccess, setLocalFullAccess] = useState(false); const [localFullAccess, setLocalFullAccess] = useState(false);
const canUseLocalFullAccess = hydrated && localFullAccess; const canUseLocalFullAccess = hydrated && localFullAccess;
@@ -957,11 +992,13 @@ function ScanTerminalScreen() {
<KoyfinWeatherTerminal <KoyfinWeatherTerminal
generatedText={generatedText || ""} generatedText={generatedText || ""}
isEn={isEn} isEn={isEn}
locale={locale}
onRefresh={refreshScanTerminalManually} onRefresh={refreshScanTerminalManually}
refreshing={scanLoading} refreshing={scanLoading}
rows={rows} rows={rows}
selectedRow={selectedRow} selectedRow={selectedRow}
setSelectedRow={(row) => setSelectedId(row.id)} setSelectedRow={(row) => setSelectedId(row.id)}
toggleLocale={toggleLocale}
userLocalTime={userLocalTime} userLocalTime={userLocalTime}
/> />
); );