Initial CMPP frontend prototype

This commit is contained in:
hectorzhao
2026-06-30 16:09:46 +08:00
commit 2f3c274a30
98 changed files with 25255 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
import { useMemo, useState } from 'react';
import { Check, X } from 'lucide-react';
import { Button, Table, Tag, type TableColumn } from '@/components/ui';
import { adminService } from '@/mock';
import type { AuditItem, AuditStatus } from '@/mock';
const applicationMap: Record<string, string> = {
'AUD-2401': '验证码服务',
'AUD-2403': '营销推广平台',
};
const auditStatusLabelMap: Record<AuditStatus, string> = {
pending: '待审核',
approved: '已通过',
rejected: '已驳回',
};
export function AdminTemplateAuditPage() {
const [audits, setAudits] = useState(() => adminService.getAudits());
const columns = useMemo<Array<TableColumn<AuditItem>>>(
() => [
{ key: 'id', title: '审核编号', render: (record) => record.id },
{ key: 'customer', title: '客户', render: (record) => record.customer },
{ key: 'application', title: '短信应用', render: (record) => applicationMap[record.id] ?? '客户通知服务' },
{ key: 'content', title: '短信模板内容', render: (record) => record.content },
{ key: 'submittedAt', title: '提交时间', render: (record) => record.submittedAt },
{
key: 'status',
title: '状态',
render: (record) => (
<Tag tone={record.status === 'approved' ? 'success' : record.status === 'rejected' ? 'danger' : 'info'}>
{auditStatusLabelMap[record.status]}
</Tag>
),
},
{
key: 'actions',
title: '操作',
align: 'right',
render: (record) => (
<div className="table-actions">
<Button
disabled={record.status !== 'pending'}
icon={<Check size={15} />}
onClick={() => setAudits(adminService.updateAuditStatus(record.id, 'approved'))}
size="sm"
variant="secondary"
>
</Button>
<Button
disabled={record.status !== 'pending'}
icon={<X size={15} />}
onClick={() => setAudits(adminService.updateAuditStatus(record.id, 'rejected'))}
size="sm"
variant="ghost"
>
</Button>
</div>
),
},
],
[],
);
const templateAudits = audits.filter((item) => item.type === '模板');
return (
<section className="page-stack">
<div className="page-heading">
<div>
<p className="eyebrow"></p>
<h1></h1>
</div>
</div>
<div className="surface">
<Table columns={columns} data={templateAudits} rowKey="id" />
</div>
</section>
);
}