Split customer management modules

This commit is contained in:
hectorzhao
2026-06-30 17:24:12 +08:00
parent 2f3c274a30
commit b2e42ebd82
7 changed files with 1587 additions and 8 deletions
+62 -7
View File
@@ -1,22 +1,52 @@
import { useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Building2, DollarSign, Plus, TrendingDown, TrendingUp } from 'lucide-react';
import { Button, Input, Select, Table, Tag, type TableColumn } from '@/components/ui';
import { Building2, DollarSign, Plus, Trash2, TrendingDown, TrendingUp } from 'lucide-react';
import { Button, Input, Modal, Select, Table, Tag, type TableColumn } from '@/components/ui';
import {
formatCurrency,
getEnterpriseRecords,
saveEnterpriseRecords,
statusOptions,
toggleEnterpriseStatus,
type EnterpriseRecord,
} from './adminEnterpriseMock';
export function AdminCustomersPage() {
type AdminCustomersPageProps = {
basePath?: string;
};
function ConfirmModal({ message, onCancel, onConfirm }: { message: string; onCancel: () => void; onConfirm: () => void }) {
return (
<Modal
footer={(
<>
<Button onClick={onCancel} variant="ghost"></Button>
<Button onClick={onConfirm}></Button>
</>
)}
onClose={onCancel}
open
title="操作确认"
>
<p className="admin-confirm-text">{message}</p>
</Modal>
);
}
export function AdminCustomersPage({ basePath = '/admin/customers' }: AdminCustomersPageProps) {
const navigate = useNavigate();
const [records, setRecords] = useState<EnterpriseRecord[]>(() => getEnterpriseRecords());
const [queryId, setQueryId] = useState('');
const [queryName, setQueryName] = useState('');
const [queryStatus, setQueryStatus] = useState('all');
const [filters, setFilters] = useState({ id: '', name: '', status: 'all' });
const [confirmAction, setConfirmAction] = useState<{ type: 'toggle' | 'delete'; record: EnterpriseRecord } | null>(null);
function deleteEnterprise(id: string) {
const nextRecords = records.filter((record) => record.id !== id);
saveEnterpriseRecords(nextRecords);
setRecords(nextRecords);
}
const filteredRecords = useMemo(() => records.filter((record) => {
const matchId = filters.id ? record.id.includes(filters.id) : true;
@@ -61,26 +91,34 @@ export function AdminCustomersPage() {
render: (record) => (
<div className="table-actions">
<Button
onClick={() => navigate(`/admin/customers/${record.id}`)}
onClick={() => navigate(`${basePath}/${record.id}`)}
size="sm"
variant="ghost"
>
</Button>
<Button
onClick={() => navigate(`/admin/customers/${record.id}/edit`)}
onClick={() => navigate(`${basePath}/${record.id}/edit`)}
size="sm"
variant="ghost"
>
</Button>
<Button
onClick={() => setRecords(toggleEnterpriseStatus(record.id))}
onClick={() => setConfirmAction({ type: 'toggle', record })}
size="sm"
variant={record.status === 'active' ? 'danger' : 'secondary'}
>
{record.status === 'active' ? '禁用' : '启用'}
</Button>
<Button
icon={<Trash2 size={15} />}
onClick={() => setConfirmAction({ type: 'delete', record })}
size="sm"
variant="danger"
>
</Button>
</div>
),
},
@@ -93,7 +131,7 @@ export function AdminCustomersPage() {
<p className="eyebrow"></p>
<h1></h1>
</div>
<Button icon={<Plus size={16} />} onClick={() => navigate('/admin/customers/new')}>
<Button icon={<Plus size={16} />} onClick={() => navigate(`${basePath}/new`)}>
</Button>
</div>
@@ -186,6 +224,23 @@ export function AdminCustomersPage() {
</div>
<Table columns={columns} data={filteredRecords} rowKey="id" />
</div>
{confirmAction ? (
<ConfirmModal
message={confirmAction.type === 'delete'
? `确认删除企业“${confirmAction.record.name}”吗?`
: `确认${confirmAction.record.status === 'active' ? '禁用' : '启用'}企业“${confirmAction.record.name}”吗?`}
onCancel={() => setConfirmAction(null)}
onConfirm={() => {
if (confirmAction.type === 'delete') {
deleteEnterprise(confirmAction.record.id);
} else {
setRecords(toggleEnterpriseStatus(confirmAction.record.id));
}
setConfirmAction(null);
}}
/>
) : null}
</section>
);
}