Files
admin/src/app/(root)/articles/page.tsx
2026-06-09 16:37:40 +08:00

106 lines
3.0 KiB
TypeScript

"use client"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { Suspense, useCallback } from "react"
import { toast } from "sonner"
import { getArticlePage, removeArticle } from "@/actions/article"
import { DataTable, useDataTable } from "@/components/data-table"
import { Page } from "@/components/page"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import type { Article } from "@/models/article"
import { formatDate } from "@/models/formatDate"
export default function ArticleListPage() {
const router = useRouter()
const fetchFn = useCallback(
(page: number, size: number) => getArticlePage({ page, size }),
[],
)
const table = useDataTable(fetchFn)
console.log(table, "tabletabletable")
const handleDelete = useCallback(
async (id: number, title: string) => {
if (!confirm(`确定要删除文章《${title}》吗?此操作不可恢复!`)) return
try {
const resp = await removeArticle(id)
console.log(resp, "resprespresp")
if (resp.success) {
toast.success("文章已删除")
table.refresh()
router.refresh()
} else {
toast.error(resp.message || "删除失败")
}
} catch (error) {
toast.error("删除失败")
console.error(error)
}
},
[table, router],
)
return (
<Page>
<div className="flex items-center justify-between">
<h1 className="text-2xl font-bold"></h1>
<Link href="/articles/new">
<Button></Button>
</Link>
</div>
<Suspense>
<DataTable<Article>
{...table}
columns={[
{ header: "标题", accessorKey: "title" },
{
header: "状态",
accessorKey: "status",
cell: ({ row }) => (
<Badge
variant={row.original.status === 1 ? "default" : "secondary"}
>
{row.original.status === 1 ? "已发布" : "草稿"}
</Badge>
),
},
{
header: "更新时间",
accessorKey: "updated_at",
cell: ({ row }) => formatDate(row.original.updated_at),
},
{
header: "操作",
id: "actions",
cell: ({ row }) => (
<div className="flex gap-2">
<Link
href={`/articles/${row.original.id}`}
className="text-primary hover:underline"
>
</Link>
<button
onClick={() =>
handleDelete(row.original.id, row.original.title)
}
className="text-destructive hover:underline"
>
</button>
</div>
),
},
]}
/>
</Suspense>
</Page>
)
}