Files
smart-crop-ui/crop-x/src/app/(app)/central-config/message/send/components/MessageSendTable.tsx

154 lines
5.3 KiB
TypeScript

import { Card } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import {
Send,
Clock,
Users,
Eye,
Trash2,
CheckCircle2,
XCircle,
Timer
} from 'lucide-react';
import { format } from 'date-fns';
import { zhCN } from 'date-fns/locale';
import { MessageSendRecord } from '@/types/message';
interface MessageSendTableProps {
sendRecords: MessageSendRecord[];
onPreview: (record: MessageSendRecord) => void;
onCancel: (id: string) => void;
onDelete: (id: string) => void;
getTypeIcon: (type: string) => JSX.Element;
getTypeLabel: (type: string) => string;
getTypeBadge: (type: string) => string;
getStatusBadge: (status: string) => JSX.Element;
}
export function MessageSendTable({
sendRecords,
onPreview,
onCancel,
onDelete,
getTypeIcon,
getTypeLabel,
getTypeBadge,
getStatusBadge
}: MessageSendTableProps) {
return (
<Card>
<Table>
<TableHeader>
<TableRow>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{sendRecords.length === 0 ? (
<TableRow>
<TableCell colSpan={7} className="text-center text-muted-foreground py-8">
</TableCell>
</TableRow>
) : (
sendRecords.map((record) => (
<TableRow key={record.id}>
<TableCell>
<div>{record.templateName}</div>
{record.subject && (
<p className="text-xs text-muted-foreground">{record.subject}</p>
)}
</TableCell>
<TableCell>
<Badge className={getTypeBadge(record.type)}>
<span className="flex items-center gap-1">
{getTypeIcon(record.type)}
{getTypeLabel(record.type)}
</span>
</Badge>
</TableCell>
<TableCell>
<div className="flex items-center gap-1">
<Users className="w-4 h-4 text-muted-foreground" />
<span>{record.recipientCount}</span>
</div>
</TableCell>
<TableCell>
{record.sendType === 'immediate' ? (
<Badge variant="outline">
<Send className="w-3 h-3 mr-1" />
</Badge>
) : (
<div>
<Badge variant="outline">
<Clock className="w-3 h-3 mr-1" />
</Badge>
{record.scheduledTime && (
<p className="text-xs text-muted-foreground mt-1">
{format(new Date(record.scheduledTime), 'MM-dd HH:mm', { locale: zhCN })}
</p>
)}
</div>
)}
</TableCell>
<TableCell>
{getStatusBadge(record.status)}
{record.status === 'sent' && (
<p className="text-xs text-muted-foreground mt-1">
{record.sentCount}/{record.recipientCount}
</p>
)}
</TableCell>
<TableCell className="text-sm text-muted-foreground">
{format(new Date(record.createdAt), 'MM-dd HH:mm', { locale: zhCN })}
</TableCell>
<TableCell>
<div className="flex gap-1">
<Button
variant="ghost"
size="sm"
onClick={() => onPreview(record)}
title="查看详情"
>
<Eye className="w-4 h-4" />
</Button>
{record.status === 'pending' && (
<Button
variant="ghost"
size="sm"
onClick={() => onCancel(record.id)}
title="取消发送"
>
<XCircle className="w-4 h-4 text-orange-600" />
</Button>
)}
{(record.status === 'sent' || record.status === 'cancelled') && (
<Button
variant="ghost"
size="sm"
onClick={() => onDelete(record.id)}
title="删除记录"
>
<Trash2 className="w-4 h-4 text-destructive" />
</Button>
)}
</div>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</Card>
);
}