204 lines
8.2 KiB
TypeScript
204 lines
8.2 KiB
TypeScript
import React, { useState } from 'react';
|
|
|
|
/**
|
|
* D2. 发行方管理
|
|
*
|
|
* 入驻审核列表、发行方详情、券审核列表
|
|
*/
|
|
|
|
interface Issuer {
|
|
id: string;
|
|
name: string;
|
|
creditRating: string;
|
|
status: 'pending' | 'approved' | 'rejected';
|
|
submittedAt: string;
|
|
couponCount: number;
|
|
totalVolume: string;
|
|
}
|
|
|
|
const mockIssuers: Issuer[] = [
|
|
{ id: 'ISS-001', name: 'Starbucks Inc.', creditRating: 'AAA', status: 'approved', submittedAt: '2026-01-15', couponCount: 12, totalVolume: '$128,450' },
|
|
{ id: 'ISS-002', name: 'Amazon Corp.', creditRating: 'AA', status: 'approved', submittedAt: '2026-01-20', couponCount: 8, totalVolume: '$456,000' },
|
|
{ id: 'ISS-003', name: 'NewBrand LLC', creditRating: '-', status: 'pending', submittedAt: '2026-02-09', couponCount: 0, totalVolume: '-' },
|
|
{ id: 'ISS-004', name: 'Target Corp.', creditRating: 'A', status: 'approved', submittedAt: '2026-01-25', couponCount: 5, totalVolume: '$67,200' },
|
|
{ id: 'ISS-005', name: 'FakeStore Inc.', creditRating: '-', status: 'rejected', submittedAt: '2026-02-05', couponCount: 0, totalVolume: '-' },
|
|
];
|
|
|
|
export const IssuerManagementPage: React.FC = () => {
|
|
const [tab, setTab] = useState<'all' | 'pending' | 'approved' | 'rejected'>('all');
|
|
|
|
const filtered = tab === 'all' ? mockIssuers : mockIssuers.filter(i => i.status === tab);
|
|
|
|
const creditColor = (rating: string) => {
|
|
const map: Record<string, string> = {
|
|
'AAA': 'var(--color-credit-aaa)',
|
|
'AA': 'var(--color-credit-aa)',
|
|
'A': 'var(--color-credit-a)',
|
|
'BBB': 'var(--color-credit-bbb)',
|
|
};
|
|
return map[rating] || 'var(--color-text-tertiary)';
|
|
};
|
|
|
|
const statusStyle = (status: string) => {
|
|
const map: Record<string, { bg: string; color: string }> = {
|
|
pending: { bg: 'var(--color-warning-light)', color: 'var(--color-warning)' },
|
|
approved: { bg: 'var(--color-success-light)', color: 'var(--color-success)' },
|
|
rejected: { bg: 'var(--color-error-light)', color: 'var(--color-error)' },
|
|
};
|
|
return map[status] || { bg: 'var(--color-gray-100)', color: 'var(--color-text-tertiary)' };
|
|
};
|
|
|
|
const statusLabel = (status: string) => {
|
|
const map: Record<string, string> = { pending: '待审核', approved: '已通过', rejected: '已驳回' };
|
|
return map[status] || status;
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
|
|
<h1 style={{ font: 'var(--text-h1)' }}>发行方管理</h1>
|
|
<div style={{ display: 'flex', gap: 8 }}>
|
|
<button style={{
|
|
padding: '6px 16px',
|
|
border: '1px solid var(--color-primary)',
|
|
borderRadius: 'var(--radius-full)',
|
|
background: 'var(--color-primary-surface)',
|
|
color: 'var(--color-primary)',
|
|
cursor: 'pointer',
|
|
font: 'var(--text-label-sm)',
|
|
}}>
|
|
✨ AI 预审
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Tabs */}
|
|
<div style={{ display: 'flex', gap: 4, marginBottom: 20 }}>
|
|
{(['all', 'pending', 'approved', 'rejected'] as const).map(t => (
|
|
<button
|
|
key={t}
|
|
onClick={() => setTab(t)}
|
|
style={{
|
|
padding: '8px 16px',
|
|
border: 'none',
|
|
borderRadius: 'var(--radius-full)',
|
|
background: tab === t ? 'var(--color-primary)' : 'var(--color-gray-50)',
|
|
color: tab === t ? 'white' : 'var(--color-text-secondary)',
|
|
cursor: 'pointer',
|
|
font: 'var(--text-label-sm)',
|
|
}}
|
|
>
|
|
{t === 'all' ? '全部' : statusLabel(t)}
|
|
{t === 'pending' && (
|
|
<span style={{
|
|
marginLeft: 4, padding: '0 5px',
|
|
background: 'var(--color-error)',
|
|
color: 'white',
|
|
borderRadius: 'var(--radius-full)',
|
|
fontSize: 10,
|
|
}}>
|
|
{mockIssuers.filter(i => i.status === 'pending').length}
|
|
</span>
|
|
)}
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
{/* Table */}
|
|
<div style={{
|
|
background: 'var(--color-surface)',
|
|
borderRadius: 'var(--radius-md)',
|
|
border: '1px solid var(--color-border-light)',
|
|
overflow: 'hidden',
|
|
}}>
|
|
<table style={{ width: '100%', borderCollapse: 'collapse' }}>
|
|
<thead>
|
|
<tr style={{ background: 'var(--color-gray-50)', borderBottom: '1px solid var(--color-border)' }}>
|
|
{['ID', '企业名称', '信用评级', '状态', '提交时间', '券数量', '总发行额', '操作'].map(h => (
|
|
<th key={h} style={{
|
|
font: 'var(--text-label-sm)',
|
|
color: 'var(--color-text-tertiary)',
|
|
padding: '12px 16px',
|
|
textAlign: 'left',
|
|
}}>{h}</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{filtered.map(issuer => {
|
|
const ss = statusStyle(issuer.status);
|
|
return (
|
|
<tr key={issuer.id} style={{ borderBottom: '1px solid var(--color-border-light)' }}>
|
|
<td style={{ font: 'var(--text-body-sm)', fontFamily: 'var(--font-family-mono)', padding: '12px 16px', color: 'var(--color-text-tertiary)' }}>
|
|
{issuer.id}
|
|
</td>
|
|
<td style={{ font: 'var(--text-label)', padding: '12px 16px' }}>{issuer.name}</td>
|
|
<td style={{ padding: '12px 16px' }}>
|
|
<span style={{
|
|
padding: '2px 8px',
|
|
borderRadius: 'var(--radius-full)',
|
|
border: `1px solid ${creditColor(issuer.creditRating)}33`,
|
|
background: `${creditColor(issuer.creditRating)}11`,
|
|
color: creditColor(issuer.creditRating),
|
|
font: 'var(--text-label-sm)',
|
|
fontWeight: 700,
|
|
}}>
|
|
{issuer.creditRating}
|
|
</span>
|
|
</td>
|
|
<td style={{ padding: '12px 16px' }}>
|
|
<span style={{
|
|
padding: '2px 10px',
|
|
borderRadius: 'var(--radius-full)',
|
|
background: ss.bg,
|
|
color: ss.color,
|
|
font: 'var(--text-caption)',
|
|
fontWeight: 500,
|
|
}}>
|
|
{statusLabel(issuer.status)}
|
|
</span>
|
|
</td>
|
|
<td style={{ font: 'var(--text-body-sm)', color: 'var(--color-text-tertiary)', padding: '12px 16px' }}>
|
|
{issuer.submittedAt}
|
|
</td>
|
|
<td style={{ font: 'var(--text-body-sm)', padding: '12px 16px' }}>{issuer.couponCount}</td>
|
|
<td style={{ font: 'var(--text-label-sm)', color: 'var(--color-primary)', padding: '12px 16px' }}>
|
|
{issuer.totalVolume}
|
|
</td>
|
|
<td style={{ padding: '12px 16px' }}>
|
|
<button style={{
|
|
padding: '4px 12px',
|
|
border: '1px solid var(--color-border)',
|
|
borderRadius: 'var(--radius-sm)',
|
|
background: 'none',
|
|
cursor: 'pointer',
|
|
font: 'var(--text-caption)',
|
|
color: 'var(--color-primary)',
|
|
}}>
|
|
详情
|
|
</button>
|
|
{issuer.status === 'pending' && (
|
|
<button style={{
|
|
marginLeft: 8,
|
|
padding: '4px 12px',
|
|
border: 'none',
|
|
borderRadius: 'var(--radius-sm)',
|
|
background: 'var(--color-primary)',
|
|
cursor: 'pointer',
|
|
font: 'var(--text-caption)',
|
|
color: 'white',
|
|
}}>
|
|
审核
|
|
</button>
|
|
)}
|
|
</td>
|
|
</tr>
|
|
);
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|