96 lines
2.8 KiB
TypeScript
96 lines
2.8 KiB
TypeScript
import { useState, useEffect } from 'react'
|
|
import { Row, Col, Card, Statistic, Typography, Table, Tag, Space } from 'antd'
|
|
import { VideoCameraOutlined, EyeOutlined, SignalFilled } from '@ant-design/icons'
|
|
import { fetchStreams, type StreamInfo } from '../../api/streams'
|
|
|
|
const { Title } = Typography
|
|
|
|
export default function Dashboard() {
|
|
const [streams, setStreams] = useState<StreamInfo[]>([])
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
useEffect(() => {
|
|
loadData()
|
|
const timer = setInterval(loadData, 10000)
|
|
return () => clearInterval(timer)
|
|
}, [])
|
|
|
|
async function loadData() {
|
|
try {
|
|
const data = await fetchStreams()
|
|
setStreams(data)
|
|
} catch { /* ignore */ }
|
|
setLoading(false)
|
|
}
|
|
|
|
const liveCount = streams.filter((s) => s.status === 'live').length
|
|
const pendingCount = streams.filter((s) => s.status === 'pending').length
|
|
|
|
const statusMap: Record<string, { color: string; label: string }> = {
|
|
pending: { color: 'blue', label: '待开播' },
|
|
live: { color: 'green', label: '直播中' },
|
|
ended: { color: 'default', label: '已结束' },
|
|
cancelled: { color: 'red', label: '已取消' },
|
|
}
|
|
|
|
const recentColumns = [
|
|
{ title: '标题', dataIndex: 'title', key: 'title', ellipsis: true },
|
|
{
|
|
title: '状态', dataIndex: 'status', key: 'status',
|
|
render: (status: string) => {
|
|
const s = statusMap[status] || { color: 'default', label: status }
|
|
return <Tag color={s.color}>{s.label}</Tag>
|
|
},
|
|
},
|
|
{ title: '创建时间', dataIndex: 'created_at', key: 'created_at', render: (v: string) => v?.slice(0, 16) },
|
|
]
|
|
|
|
return (
|
|
<div>
|
|
<Title level={3} style={{ marginBottom: 24 }}>概览</Title>
|
|
<Row gutter={[24, 24]}>
|
|
<Col xs={24} sm={8}>
|
|
<Card>
|
|
<Statistic
|
|
title="直播中"
|
|
value={liveCount}
|
|
prefix={<SignalFilled style={{ color: '#52c41a' }} />}
|
|
loading={loading}
|
|
/>
|
|
</Card>
|
|
</Col>
|
|
<Col xs={24} sm={8}>
|
|
<Card>
|
|
<Statistic
|
|
title="待开播"
|
|
value={pendingCount}
|
|
prefix={<VideoCameraOutlined style={{ color: '#1677ff' }} />}
|
|
loading={loading}
|
|
/>
|
|
</Card>
|
|
</Col>
|
|
<Col xs={24} sm={8}>
|
|
<Card>
|
|
<Statistic
|
|
title="直播总数"
|
|
value={streams.length}
|
|
prefix={<EyeOutlined />}
|
|
loading={loading}
|
|
/>
|
|
</Card>
|
|
</Col>
|
|
</Row>
|
|
<Card title="最近直播" style={{ marginTop: 24 }}>
|
|
<Table
|
|
dataSource={streams.slice(0, 10)}
|
|
columns={recentColumns}
|
|
rowKey="id"
|
|
loading={loading}
|
|
pagination={false}
|
|
size="middle"
|
|
/>
|
|
</Card>
|
|
</div>
|
|
)
|
|
}
|