feat: Implement the PolyWeather dashboard including frontend components, data collection, analysis, and API endpoints.
This commit is contained in:
@@ -2,38 +2,62 @@
|
||||
|
||||
import clsx from "clsx";
|
||||
import { useDashboardStore } from "@/hooks/useDashboardStore";
|
||||
import { useI18n } from "@/hooks/useI18n";
|
||||
|
||||
export function HeaderBar() {
|
||||
const store = useDashboardStore();
|
||||
const { locale, setLocale, t } = useI18n();
|
||||
|
||||
return (
|
||||
<header className="header">
|
||||
<div className="brand">
|
||||
<h1>PolyWeather</h1>
|
||||
<span className="subtitle">天气衍生品智能分析</span>
|
||||
<span className="subtitle">{t("header.subtitle")}</span>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="info-btn"
|
||||
title="查看系统技术说明"
|
||||
aria-label="查看系统技术说明"
|
||||
onClick={store.openGuide}
|
||||
>
|
||||
技术说明
|
||||
</button>
|
||||
<div className="live-badge" id="liveBadge">
|
||||
<span className="pulse-dot" />
|
||||
<span>实时</span>
|
||||
|
||||
<div className="header-right">
|
||||
<div className="lang-switch" role="group" aria-label={t("header.langAria")}>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx("lang-btn", locale === "zh-CN" && "active")}
|
||||
onClick={() => setLocale("zh-CN")}
|
||||
>
|
||||
{t("header.langZh")}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx("lang-btn", locale === "en-US" && "active")}
|
||||
onClick={() => setLocale("en-US")}
|
||||
>
|
||||
{t("header.langEn")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="info-btn"
|
||||
title={t("header.infoAria")}
|
||||
aria-label={t("header.infoAria")}
|
||||
onClick={store.openGuide}
|
||||
>
|
||||
{t("header.info")}
|
||||
</button>
|
||||
|
||||
<div className="live-badge" id="liveBadge">
|
||||
<span className="pulse-dot" />
|
||||
<span>{t("header.live")}</span>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className={clsx("refresh-btn", store.loadingState.refresh && "spinning")}
|
||||
title={t("header.refreshAria")}
|
||||
aria-label={t("header.refreshAria")}
|
||||
onClick={() => void store.refreshAll()}
|
||||
>
|
||||
↻
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx("refresh-btn", store.loadingState.refresh && "spinning")}
|
||||
title="刷新所有数据"
|
||||
aria-label="刷新所有数据"
|
||||
onClick={() => void store.refreshAll()}
|
||||
>
|
||||
↻
|
||||
</button>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user