refactor(energy): 电能整体页面对齐氢能:每日 / 总览 子 tab 切换
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

- ElectricView 改为受控组件接收 sub prop(与 HydrogenView 对齐)
- EnergyModule sticky 头部统一显示 sub-tabs:氢能、电能都给 每日 / 总览
  ETC 仍不显示子 tab(建设中页)
- 共享 sub state 抽 helper:activeTab 切换时自动用对应的 sub
- 龙王路停车场充电站信息条移入 ElectricOverview 顶部(同氢能"数据自...")

进入电能默认显示「每日」(与氢能一致),切换「总览」看 KPI + 柱图

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-04-30 15:22:02 +08:00
parent c3b463d9ca
commit fe70ec389b
3 changed files with 25 additions and 19 deletions

View File

@@ -40,6 +40,9 @@ export default function ElectricOverview() {
return ( return (
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
<div className="bg-white rounded-xl border border-slate-100 px-3 py-1.5 text-[11px] text-slate-400">
2025-01-01
</div>
{/* 横向 mini KPI 头 */} {/* 横向 mini KPI 头 */}
<div className="grid grid-cols-2 gap-2 md:gap-3"> <div className="grid grid-cols-2 gap-2 md:gap-3">
<div className="bg-white rounded-2xl border border-slate-100 shadow-sm p-3 md:p-4"> <div className="bg-white rounded-2xl border border-slate-100 shadow-sm p-3 md:p-4">

View File

@@ -1,14 +1,12 @@
import ElectricOverview from './ElectricOverview'; import ElectricOverview from './ElectricOverview';
import ElectricDaily from './ElectricDaily'; import ElectricDaily from './ElectricDaily';
export default function ElectricView() { export type ElectricSubTab = 'daily' | 'overview';
return (
<> interface Props {
<div className="bg-white rounded-xl border border-slate-100 px-3 py-1.5 text-[11px] text-slate-400"> sub: ElectricSubTab;
2025-01-01 }
</div>
<ElectricOverview /> export default function ElectricView({ sub }: Props) {
<ElectricDaily /> return sub === 'overview' ? <ElectricOverview /> : <ElectricDaily />;
</>
);
} }

View File

@@ -2,10 +2,11 @@ import { useState } from 'react';
import { Fuel, BatteryCharging, Receipt, LayoutDashboard, CalendarDays } from 'lucide-react'; import { Fuel, BatteryCharging, Receipt, LayoutDashboard, CalendarDays } from 'lucide-react';
import { motion } from 'motion/react'; import { motion } from 'motion/react';
import HydrogenView, { type HydrogenSubTab } from './HydrogenView'; import HydrogenView, { type HydrogenSubTab } from './HydrogenView';
import ElectricView from './ElectricView'; import ElectricView, { type ElectricSubTab } from './ElectricView';
import ETCView from './ETCView'; import ETCView from './ETCView';
type TopTab = 'hydrogen' | 'electric' | 'etc'; type TopTab = 'hydrogen' | 'electric' | 'etc';
type SubTabId = HydrogenSubTab | ElectricSubTab; // 'daily' | 'overview'
const TABS: { key: TopTab; label: string; icon: typeof Fuel }[] = [ const TABS: { key: TopTab; label: string; icon: typeof Fuel }[] = [
{ key: 'hydrogen', label: '氢能', icon: Fuel }, { key: 'hydrogen', label: '氢能', icon: Fuel },
@@ -13,7 +14,7 @@ const TABS: { key: TopTab; label: string; icon: typeof Fuel }[] = [
{ key: 'etc', label: 'ETC', icon: Receipt }, { key: 'etc', label: 'ETC', icon: Receipt },
]; ];
const HYDROGEN_SUB_TABS: { id: HydrogenSubTab; label: string; icon: typeof LayoutDashboard }[] = [ const SUB_TABS: { id: SubTabId; label: string; icon: typeof LayoutDashboard }[] = [
{ id: 'daily', label: '每日', icon: CalendarDays }, { id: 'daily', label: '每日', icon: CalendarDays },
{ id: 'overview', label: '总览', icon: LayoutDashboard }, { id: 'overview', label: '总览', icon: LayoutDashboard },
]; ];
@@ -21,6 +22,10 @@ const HYDROGEN_SUB_TABS: { id: HydrogenSubTab; label: string; icon: typeof Layou
export default function EnergyModule() { export default function EnergyModule() {
const [activeTab, setActiveTab] = useState<TopTab>('hydrogen'); const [activeTab, setActiveTab] = useState<TopTab>('hydrogen');
const [hydroSub, setHydroSub] = useState<HydrogenSubTab>('daily'); const [hydroSub, setHydroSub] = useState<HydrogenSubTab>('daily');
const [electricSub, setElectricSub] = useState<ElectricSubTab>('daily');
const showSubTabs = activeTab === 'hydrogen' || activeTab === 'electric';
const currentSub: SubTabId = activeTab === 'electric' ? electricSub : hydroSub;
const setSub = (id: SubTabId) => activeTab === 'electric' ? setElectricSub(id) : setHydroSub(id);
return ( return (
<div className="min-h-screen bg-[#F8F9FB] text-gray-800 font-sans p-3 md:p-6 relative" style={{ overflowX: 'clip' }}> <div className="min-h-screen bg-[#F8F9FB] text-gray-800 font-sans p-3 md:p-6 relative" style={{ overflowX: 'clip' }}>
<div className="max-w-6xl mx-auto flex flex-col gap-3 pb-16 landscape:pb-0 landscape:h-full landscape:flex-1 landscape:overflow-hidden"> <div className="max-w-6xl mx-auto flex flex-col gap-3 pb-16 landscape:pb-0 landscape:h-full landscape:flex-1 landscape:overflow-hidden">
@@ -29,7 +34,7 @@ export default function EnergyModule() {
<div className="sticky top-0 z-30 -mx-3 md:-mx-6 px-3 md:px-6 -mt-3 md:-mt-6 pt-3 md:pt-6 pb-2 bg-[#F8F9FB]/85 backdrop-blur-md"> <div className="sticky top-0 z-30 -mx-3 md:-mx-6 px-3 md:px-6 -mt-3 md:-mt-6 pt-3 md:pt-6 pb-2 bg-[#F8F9FB]/85 backdrop-blur-md">
<div className="bg-white rounded-2xl border border-slate-100 shadow-sm overflow-hidden"> <div className="bg-white rounded-2xl border border-slate-100 shadow-sm overflow-hidden">
{/* 顶部 tab氢能 / 电能 / ETC */} {/* 顶部 tab氢能 / 电能 / ETC */}
<div className={`px-4 py-2 flex items-center gap-6 ${activeTab === 'hydrogen' ? 'border-b border-slate-50' : ''}`}> <div className={`px-4 py-2 flex items-center gap-6 ${showSubTabs ? 'border-b border-slate-50' : ''}`}>
{TABS.map(tab => { {TABS.map(tab => {
const Icon = tab.icon; const Icon = tab.icon;
const active = activeTab === tab.key; const active = activeTab === tab.key;
@@ -48,15 +53,15 @@ export default function EnergyModule() {
); );
})} })}
</div> </div>
{/* 子 tab氢能时显示 */} {/* 子 tab氢能 / 电能 都显示 每日 / 总览 */}
{activeTab === 'hydrogen' && ( {showSubTabs && (
<div className="p-1 flex gap-1"> <div className="p-1 flex gap-1">
{HYDROGEN_SUB_TABS.map(({ id, label, icon: Icon }) => { {SUB_TABS.map(({ id, label, icon: Icon }) => {
const active = hydroSub === id; const active = currentSub === id;
return ( return (
<button <button
key={id} key={id}
onClick={() => setHydroSub(id)} onClick={() => setSub(id)}
className={`flex-1 flex items-center justify-center gap-1.5 rounded-xl py-1.5 text-[12px] font-bold transition-all ${ className={`flex-1 flex items-center justify-center gap-1.5 rounded-xl py-1.5 text-[12px] font-bold transition-all ${
active ? 'bg-blue-50 text-blue-600' : 'text-slate-400 hover:bg-slate-50' active ? 'bg-blue-50 text-blue-600' : 'text-slate-400 hover:bg-slate-50'
}`} }`}
@@ -72,7 +77,7 @@ export default function EnergyModule() {
</div> </div>
{activeTab === 'hydrogen' && <HydrogenView sub={hydroSub} />} {activeTab === 'hydrogen' && <HydrogenView sub={hydroSub} />}
{activeTab === 'electric' && <ElectricView />} {activeTab === 'electric' && <ElectricView sub={electricSub} />}
{activeTab === 'etc' && <ETCView />} {activeTab === 'etc' && <ETCView />}
</div> </div>
</div> </div>