终端顶栏新增中英文语言切换按钮
KoyfinWeatherTerminal 顶栏右侧添加 EN/中文 切换组件,样式与落地页一致。 Refresh 按钮文字同步支持国际化。 Tested: npm run build 通过
This commit is contained in:
@@ -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}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user