Files
live-hub-py/web/frontend/src/pages/DashboardPage.tsx
T

134 lines
3.9 KiB
TypeScript

import { Card, Col, Row, Space, Statistic, Tag, Typography, theme } from 'antd';
import { useEffect, useMemo, useState } from 'react';
import { dashboardApi } from '../api/modules';
const { Title, Text } = Typography;
interface PlatformStats {
accounts: number;
tasks: number;
success: number;
failed: number;
}
interface DashboardStats {
douyu: PlatformStats & {
cookies: number;
};
huya: PlatformStats & {
goods: number;
rechargeGoods: number;
};
}
const EMPTY_STATS: DashboardStats = {
douyu: {
accounts: 0,
tasks: 0,
success: 0,
failed: 0,
cookies: 0,
},
huya: {
accounts: 0,
tasks: 0,
success: 0,
failed: 0,
goods: 0,
rechargeGoods: 0,
},
};
function StatCard({
title,
value,
color,
loading,
}: {
title: string;
value: number;
color?: string;
loading?: boolean;
}) {
return (
<Col xs={24} sm={12} lg={6}>
<Card size="small" loading={loading}>
<Statistic title={title} value={value} styles={{ content: color ? { color } : undefined }} />
</Card>
</Col>
);
}
export default function DashboardPage() {
const { token } = theme.useToken();
const [loading, setLoading] = useState(true);
const [stats, setStats] = useState<DashboardStats>(EMPTY_STATS);
useEffect(() => {
let ignore = false;
async function loadDashboard() {
setLoading(true);
try {
const data = await dashboardApi.summary();
if (!ignore) setStats(data);
} finally {
if (!ignore) setLoading(false);
}
}
void loadDashboard();
return () => {
ignore = true;
};
}, []);
const totalStats = useMemo(() => ({
accounts: stats.douyu.accounts + stats.huya.accounts,
tasks: stats.douyu.tasks + stats.huya.tasks,
success: stats.douyu.success + stats.huya.success,
failed: stats.douyu.failed + stats.huya.failed,
}), [stats]);
return (
<div>
<div style={{ marginBottom: 16 }}>
<Space align="center" wrap>
<Title level={2} style={{ margin: 0 }}>概览</Title>
<Tag color="blue">斗鱼</Tag>
<Tag color="orange">虎牙</Tag>
</Space>
</div>
<Row gutter={[12, 12]} style={{ marginBottom: 20 }}>
<StatCard title="账号总数" value={totalStats.accounts} loading={loading} />
<StatCard title="任务总数" value={totalStats.tasks} loading={loading} />
<StatCard title="成功任务" value={totalStats.success} color={token.colorSuccess} loading={loading} />
<StatCard title="失败任务" value={totalStats.failed} color={token.colorError} loading={loading} />
</Row>
<div style={{ marginBottom: 10 }}>
<Title level={4} style={{ margin: 0 }}>斗鱼</Title>
<Text type="secondary">账号登录、Cookie 产出和批量登录任务</Text>
</div>
<Row gutter={[12, 12]} style={{ marginBottom: 20 }}>
<StatCard title="斗鱼账号" value={stats.douyu.accounts} loading={loading} />
<StatCard title="登录任务" value={stats.douyu.tasks} loading={loading} />
<StatCard title="成功 Cookie" value={stats.douyu.cookies} color={token.colorSuccess} loading={loading} />
<StatCard title="失败/异常" value={stats.douyu.failed} color={token.colorError} loading={loading} />
</Row>
<div style={{ marginBottom: 10 }}>
<Title level={4} style={{ margin: 0 }}>虎牙</Title>
<Text type="secondary">账号 Cookie、活动任务、兑换商品和充值商品</Text>
</div>
<Row gutter={[12, 12]}>
<StatCard title="虎牙账号" value={stats.huya.accounts} loading={loading} />
<StatCard title="虎牙任务" value={stats.huya.tasks} loading={loading} />
<StatCard title="兑换商品" value={stats.huya.goods} loading={loading} />
<StatCard title="充值商品" value={stats.huya.rechargeGoods} loading={loading} />
</Row>
</div>
);
}