65 lines
2.7 KiB
TypeScript
65 lines
2.7 KiB
TypeScript
import { useState } from 'react';
|
|||
|
|
import { Layout, Nav, Tag, Spin } from '@douyinfe/semi-ui';
|
||
|
|
import { IconMonitorStroked, IconSaveStroked, IconAlertCircle, IconGridView } from '@douyinfe/semi-icons';
|
||
|
|
import { useDashboardData } from '@bj_power_dashboard/hooks/useDashboardData';
|
||
|
|
import { ProductionBoard } from '@bj_power_dashboard/pages/ProductionBoard';
|
||
|
|
import { WarehouseBoard } from '@bj_power_dashboard/pages/WarehouseBoard';
|
||
|
|
import { AlarmBoard } from '@bj_power_dashboard/pages/AlarmBoard';
|
||
|
|
import { LineModel } from '@bj_power_dashboard/pages/LineModel';
|
||
|
|
import { ErrorRetry } from '@bj_power_dashboard/components/ErrorRetry';
|
||
|
|
|
||
|
|
type PageKey = 'production' | 'warehouse' | 'alarms' | 'model';
|
||
|
|
|
||
|
|
export function App() {
|
||
|
|
const [page, setPage] = useState<PageKey>('production');
|
||
|
|
const { data: dashboard, mode, error, retry } = useDashboardData();
|
||
|
|
const loading = !dashboard && !error;
|
||
|
|
|
||
|
|
const navItems = [
|
||
|
|
{ itemKey: 'production', text: '生产数据看板', icon: <IconMonitorStroked /> },
|
||
|
|
{ itemKey: 'warehouse', text: '仓储数据看板', icon: <IconSaveStroked /> },
|
||
|
|
{ itemKey: 'alarms', text: '异常报警', icon: <IconAlertCircle /> },
|
||
|
|
{ itemKey: 'model', text: '产线模型', icon: <IconGridView /> },
|
||
|
|
];
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Layout className="app-shell">
|
||
|
|
<Layout.Header className="app-header">
|
||
|
|
<div className="app-title">北京电力智能产线 · 生产看板</div>
|
||
|
|
<div className="app-meta">
|
||
|
|
{mode === 'sse' ? (
|
||
|
|
<Tag color="green">SSE 实时</Tag>
|
||
|
|
) : mode === 'polling' ? (
|
||
|
|
<Tag color="blue">HTTP 轮询 10s</Tag>
|
||
|
|
) : (
|
||
|
|
<Tag color="grey">连接中</Tag>
|
||
|
|
)}
|
||
|
|
<span className="clock">{new Date().toLocaleTimeString('zh-CN')}</span>
|
||
|
|
</div>
|
||
|
|
</Layout.Header>
|
||
|
|
|
||
|
|
<Layout.Sider style={{ background: 'transparent' }}>
|
||
|
|
<Nav
|
||
|
|
selectedKeys={[page]}
|
||
|
|
onSelect={(k) => setPage(k.itemKey as PageKey)}
|
||
|
|
items={navItems}
|
||
|
|
/>
|
||
|
|
</Layout.Sider>
|
||
|
|
|
||
|
|
<Layout.Content className="app-content">
|
||
|
|
{loading ? (
|
||
|
|
<div style={{ display: 'flex', justifyContent: 'center', padding: 80 }}>
|
||
|
|
<Spin size="large" tip="数据加载中…" />
|
||
|
|
</div>
|
||
|
|
) : (
|
||
|
|
<ErrorRetry error={error} mode={mode} loading={loading} onRetry={retry}>
|
||
|
|
{dashboard && page === 'production' && <ProductionBoard data={dashboard} />}
|
||
|
|
{dashboard && page === 'warehouse' && <WarehouseBoard data={dashboard} />}
|
||
|
|
{dashboard && page === 'alarms' && <AlarmBoard data={dashboard} />}
|
||
|
|
{dashboard && page === 'model' && <LineModel data={dashboard} />}
|
||
|
|
</ErrorRetry>
|
||
|
|
)}
|
||
|
|
</Layout.Content>
|
||
|
|
</Layout>
|
||
|
|
);
|
||
|
|
}
|