'use client'; import { useEffect, useState } from 'react'; import useSWR from 'swr'; import { CheckCircle2, CheckCheck, Loader2, Trash2 } from 'lucide-react'; import { AdminHeader } from '@/components/admin/AdminHeader'; import { PaginationTable, type Column } from '@/components/admin/PaginationTable'; import { TableToolbar } from '@/components/admin/TableToolbar'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Badge } from '@/components/ui/badge'; import { adminApi } from '@/lib/admin-services'; import { useAdminStore } from '@/store/adminStore'; import { formatDate } from '@/lib/utils'; import type { Message } from '@/lib/types'; export default function MessageAdminPage() { const [hydrated, setHydrated] = useState(false); const [page, setPage] = useState(1); const [isRead, setIsRead] = useState(); const [keyword, setKeyword] = useState(''); const [searchKw, setSearchKw] = useState(''); const [markingAll, setMarkingAll] = useState(false); const isSuperAdmin = useAdminStore((s) => s.admin?.role) === 'super_admin'; useEffect(() => setHydrated(true), []); const { data, isLoading, mutate } = useSWR( hydrated ? ['/admin/message', page, isRead, searchKw] : null, () => adminApi.messagePaginate({ page, pageSize: 10, isRead, keyword: searchKw || undefined, }), ); const onMarkRead = async (id: number) => { try { await adminApi.messageMarkRead(id); await mutate(); } catch (e) { alert((e as Error).message); } }; const onDelete = async (id: number) => { if (!confirm('确认删除该留言?')) return; try { await adminApi.messageDelete(id); await mutate(); } catch (e) { alert((e as Error).message); } }; const onMarkAllRead = async () => { setMarkingAll(true); try { // 拉取全部未读(跨页) const unread = await adminApi.messagePaginate({ isRead: 0, page: 1, pageSize: 999, }); // 串行标记,单个失败即中断 for (const m of unread.list) { await adminApi.messageMarkRead(m.id); } await mutate(); } catch (e) { alert((e as Error).message); } finally { setMarkingAll(false); } }; const hasUnread = (data?.list ?? []).some((m) => m.isRead === 0); const columns: Column[] = [ { key: 'id', title: 'ID', width: 60 }, { key: 'name', title: '姓名', width: 120 }, { key: 'phone', title: '电话', width: 140 }, { key: 'email', title: '邮箱', width: 180 }, { key: 'content', title: '留言内容', render: (r) => ( {r.content} ), }, { key: 'createdAt', title: '提交时间', width: 160, render: (r) => formatDate(r.createdAt, 'YYYY-MM-DD HH:mm'), }, { key: 'isRead', title: '状态', width: 90, render: (r) => r.isRead === 1 ? ( 已读 ) : ( 未读 ), }, { key: '_op', title: '操作', width: 150, render: (r) => (
{r.isRead === 0 && ( )} {isSuperAdmin && ( )}
), }, ]; return (
setKeyword(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { setSearchKw(keyword); setPage(1); } }} className="max-w-xs" /> } right={ } /> columns={columns} rows={data?.list ?? []} total={data?.total ?? 0} page={page} pageSize={10} loading={isLoading} onPageChange={setPage} rowKey={(r) => String(r.id)} />
); }