import type { ColumnsType } from "antd/es/table"; import { DeleteOutlined, EditOutlined, InboxOutlined, LoginOutlined, RedoOutlined } from "@ant-design/icons"; import { App as AntApp, Button, Popconfirm, Space, Table, Tag } from "antd"; import { useNavigate } from "react-router"; import type { Project, ProjectListResponse } from "../../../../shared/api"; interface ProjectTableProps { data: ProjectListResponse | undefined; loading: boolean; onArchive: (id: string) => Promise; onDelete: (id: string) => Promise; onEdit: (project: Project) => void; onPageChange: (page: number, pageSize: number) => void; onRestore: (id: string) => Promise; page: number; pageSize: number; } const COLUMNS: ColumnsType = [ { dataIndex: "name", ellipsis: true, title: "项目名称", width: 160 }, { dataIndex: "description", ellipsis: true, title: "项目描述" }, { align: "center", dataIndex: "status", render: (_value, record: Project) => { if (record.status === "archived") { return 已归档; } return 进行中; }, title: "状态", width: 100, }, { align: "center", dataIndex: "createdAt", render: (_value, record: Project) => formatDatetime(record.createdAt), title: "创建时间", width: 185, }, { align: "center", dataIndex: "updatedAt", render: (_value, record: Project) => formatDatetime(record.updatedAt), title: "更新时间", width: 185, }, ]; export function ProjectTable({ data, loading, onArchive, onDelete, onEdit, onPageChange, onRestore, page, pageSize, }: ProjectTableProps) { const { message } = AntApp.useApp(); const navigate = useNavigate(); const handleArchive = async (id: string) => { try { await onArchive(id); message.success("项目已归档"); } catch (err) { message.error((err as Error).message); } }; const handleRestore = async (id: string) => { try { await onRestore(id); message.success("项目已恢复"); } catch (err) { message.error((err as Error).message); } }; const handleDelete = async (id: string) => { try { await onDelete(id); message.success("项目已永久删除"); } catch (err) { message.error((err as Error).message); } }; const operationColumn: ColumnsType[number] = { dataIndex: "op", fixed: "right", render: (_value, record: Project) => { if (record.status === "active") { return ( void handleArchive(record.id)} title="确认归档此项目?" > ); } return ( void handleRestore(record.id)} title="确认恢复此项目?"> void handleDelete(record.id)} title="确认永久删除此项目?" > ); }, title: "操作", width: 280, }; return ( ); } function formatDatetime(dateStr: string): string { const d = new Date(dateStr); const pad = (n: number) => String(n).padStart(2, "0"); return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`; }