feat: implement HeaderBar and ScanTerminal UI layout components for dashboard navigation and decision workspace

This commit is contained in:
2569718930@qq.com
2026-05-24 22:38:43 +08:00
parent 4832678d72
commit 32a3ba0ea4
5 changed files with 67 additions and 179 deletions
@@ -10,8 +10,6 @@ import {
RotateCw,
BookOpen,
MoreHorizontal,
Moon,
Sun,
} from "lucide-react";
import { useEffect, useState } from "react";
import { useDashboardStore, useProAccess } from "@/hooks/useDashboardStore";
@@ -42,7 +40,6 @@ export function HeaderBar({
const { proAccess } = useProAccess();
const { locale, t, toggleLocale } = useI18n();
const pathname = usePathname();
const [theme, setTheme] = useState<"dark" | "light">("dark");
const isAuthenticated = proAccess.authenticated;
const docsHref = "/docs/intro";
const docsActive = pathname?.startsWith("/docs");
@@ -94,24 +91,6 @@ export function HeaderBar({
? `Pro ${Math.max(expiryInfo?.daysLeft || 0, 0)}d left`
: `Pro 还剩 ${Math.max(expiryInfo?.daysLeft || 0, 0)}`;
useEffect(() => {
const savedTheme =
typeof window !== "undefined"
? window.localStorage.getItem("polyweather_theme")
: null;
const nextTheme = savedTheme === "light" ? "light" : "dark";
setTheme(nextTheme);
document.documentElement.classList.toggle("dark", nextTheme === "dark");
document.documentElement.classList.toggle("light", nextTheme === "light");
}, []);
const toggleTheme = () => {
const nextTheme = theme === "dark" ? "light" : "dark";
setTheme(nextTheme);
document.documentElement.classList.toggle("dark", nextTheme === "dark");
document.documentElement.classList.toggle("light", nextTheme === "light");
window.localStorage.setItem("polyweather_theme", nextTheme);
};
return (
<header className="header">
@@ -165,19 +144,6 @@ export function HeaderBar({
<RotateCw size={16} strokeWidth={2} />
</button>
<button
type="button"
className="header-utility-btn"
aria-label={theme === "dark" ? "切换到明亮模式" : "切换到暗黑模式"}
title={theme === "dark" ? "明亮模式" : "暗黑模式"}
onClick={toggleTheme}
>
{theme === "dark" ? (
<Sun size={15} strokeWidth={2} />
) : (
<Moon size={15} strokeWidth={2} />
)}
</button>
<Link
href={docsHref}
@@ -122,19 +122,7 @@ export function ScanTerminalTopBar({
{isEn ? "Sign in" : "登录"}
</Link>
)}
<button
type="button"
className="scan-theme-button"
aria-label={
themeMode === "light" ? "切换到暗色模式" : "切换到明亮模式"
}
title={themeMode === "light" ? "切换到暗色模式" : "切换到明亮模式"}
onClick={() =>
setThemeMode((current) => (current === "light" ? "dark" : "light"))
}
>
{themeMode === "light" ? <Moon size={15} /> : <Sun size={15} />}
</button>
{isAuthenticated ? (
<Link
href={accountHref}
@@ -20,30 +20,13 @@ export function useUserLocalClock() {
}
export function useScanTerminalTheme() {
const [themeMode, setThemeMode] = useState<ThemeMode>("dark");
const [themeMode] = useState<ThemeMode>("light");
useEffect(() => {
const root = document.documentElement;
const hadLight = root.classList.contains("light");
const hadDark = root.classList.contains("dark");
root.classList.toggle("light", themeMode === "light");
root.classList.toggle("dark", themeMode === "dark");
return () => {
root.classList.toggle("light", hadLight);
root.classList.toggle("dark", hadDark);
};
}, [themeMode]);
useEffect(() => {
const stored = window.localStorage.getItem("polyweather_scan_theme");
if (stored === "light") {
setThemeMode("light");
}
root.classList.add("light");
root.classList.remove("dark");
}, []);
useEffect(() => {
window.localStorage.setItem("polyweather_scan_theme", themeMode);
}, [themeMode]);
return { setThemeMode, themeMode };
return { setThemeMode: () => {}, themeMode };
}