'use client'; import { ProTable, ProTableActions } from '@/components/pro-table'; import { getBatchSendEmailTaskList, stopBatchSendEmailTask } from '@/services/admin/marketing'; import { formatDate } from '@/utils/common'; import { Badge } from '@workspace/ui/components/badge'; import { Button } from '@workspace/ui/components/button'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, } from '@workspace/ui/components/dialog'; import { ScrollArea } from '@workspace/ui/components/scroll-area'; import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger, } from '@workspace/ui/components/sheet'; import { Icon } from '@workspace/ui/custom-components/icon'; import { useTranslations } from 'next-intl'; import { useRef, useState } from 'react'; import { toast } from 'sonner'; export default function EmailTaskManager() { const t = useTranslations('marketing'); const ref = useRef(null); const [selectedTask, setSelectedTask] = useState(null); const [open, setOpen] = useState(false); const stopTask = async (taskId: number) => { try { await stopBatchSendEmailTask({ id: taskId, }); toast.success(t('taskStoppedSuccessfully')); ref.current?.refresh(); } catch (error) { console.error('Failed to stop task:', error); toast.error(t('failedToStopTask')); } }; const getStatusBadge = (status: number) => { const statusConfig = { 0: { label: t('notStarted'), variant: 'secondary' as const }, 1: { label: t('inProgress'), variant: 'default' as const }, 2: { label: t('completed'), variant: 'default' as const }, }; const config = statusConfig[status as keyof typeof statusConfig] || { label: `${t('status')} ${status}`, variant: 'secondary' as const, }; return {config.label}; }; return (

{t('emailTaskManager')}

{t('viewAndManageEmailBroadcastTasks')}

{t('emailBroadcastTasks')}
action={ref} columns={[ { accessorKey: 'subject', header: t('subject'), cell: ({ row }) => (
{row.getValue('subject') as string}
), }, { accessorKey: 'scope', header: t('recipientType'), cell: ({ row }) => { const scope = row.original.scope; const scopeLabels = { 1: t('allUsers'), // ScopeAll 2: t('subscribedUsers'), // ScopeActive 3: t('expiredUsers'), // ScopeExpired 4: t('nonSubscribers'), // ScopeNone 5: t('specificUsers'), // ScopeSkip }; return ( scopeLabels[scope as keyof typeof scopeLabels] || `${t('scope')} ${scope}` ); }, }, { accessorKey: 'status', header: t('status'), cell: ({ row }) => getStatusBadge(row.getValue('status') as number), }, { accessorKey: 'progress', header: t('progress'), cell: ({ row }) => { const task = row.original as API.BatchSendEmailTask; const progress = task.total > 0 ? (task.current / task.total) * 100 : 0; return (
{task.current} / {task.total} {progress.toFixed(1)}%
); }, }, { accessorKey: 'scheduled', header: t('sendTime'), cell: ({ row }) => { const scheduled = row.getValue('scheduled') as number; return scheduled && scheduled > 0 ? formatDate(scheduled) : '--'; }, }, { accessorKey: 'created_at', header: t('createdAt'), cell: ({ row }) => { const createdAt = row.getValue('created_at') as number; return formatDate(createdAt); }, }, ]} request={async (pagination, filters) => { const response = await getBatchSendEmailTaskList({ ...filters, page: pagination.page, size: pagination.size, }); return { list: response.data?.data?.list || [], total: response.data?.data?.total || 0, }; }} params={[ { key: 'status', placeholder: t('status'), options: [ { label: t('notStarted'), value: '0' }, { label: t('inProgress'), value: '1' }, { label: t('completed'), value: '2' }, ], }, { key: 'scope', placeholder: t('sendScope'), options: [ { label: t('allUsers'), value: '1' }, { label: t('subscribedUsers'), value: '2' }, { label: t('expiredUsers'), value: '3' }, { label: t('nonSubscribers'), value: '4' }, { label: t('specificUsers'), value: '5' }, ], }, ]} actions={{ render: (row) => { return [ {t('emailContent')} {selectedTask && (

{t('subject')}

{selectedTask.subject}

{t('content')}

{selectedTask.additional && (

{t('additionalRecipients')}

{selectedTask.additional}

)}
)}
, ...([0, 1].includes(row.status) ? [ , ] : []), ]; }, }} />
); }