Files
admin/src/app/(root)/coupon/page.tsx

149 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { format } from "date-fns"
import { Suspense, useState } from "react"
import { toast } from "sonner"
import { deleteCoupon, getPagCoupon } from "@/actions/coupon"
import { DataTable, useDataTable } from "@/components/data-table"
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
import { Button } from "@/components/ui/button"
import type { Coupon } from "@/models/coupon"
import { CreateDiscount } from "./create"
import { UpdateCoupon } from "./update"
export default function CouponPage() {
const table = useDataTable((page, size) => getPagCoupon({ page, size }))
return (
<div className="flex flex-col gap-3">
<div className="flex justify-between items-stretch">
<div className="flex gap-3">
<CreateDiscount onSuccess={table.refresh} />
</div>
</div>
<Suspense>
<DataTable<Coupon>
{...table}
columns={[
{ header: "ID", accessorKey: "id" },
{ header: "所属用户", accessorKey: "user_id" },
{ header: "代码", accessorKey: "code" },
{ header: "备注", accessorKey: "remark" },
{ header: "金额", accessorKey: "amount" },
{ header: "最低消费金额", accessorKey: "min_amount" },
{
header: "状态",
accessorKey: "status",
cell: ({ row }) => {
const status = row.original.status
if (status === 0) {
return <span className="text-yellow-600">使</span>
}
if (status === 1) {
return <span className="text-green-600">使</span>
}
return <span>-</span>
},
},
{
header: "过期时间",
accessorKey: "expire_at",
cell: ({ row }) =>
format(new Date(row.original.created_at), "yyyy-MM-dd HH:mm"),
},
{
header: "创建时间",
accessorKey: "created_at",
cell: ({ row }) =>
format(new Date(row.original.created_at), "yyyy-MM-dd HH:mm"),
},
{
header: "更新时间",
accessorKey: "updated_at",
cell: ({ row }) =>
format(new Date(row.original.updated_at), "yyyy-MM-dd HH:mm"),
},
{
header: "操作",
cell: ({ row }) => (
<div className="flex gap-2">
<UpdateCoupon
coupon={row.original}
onSuccess={table.refresh}
/>
<DeleteCoupon
coupon={row.original}
onSuccess={table.refresh}
/>
</div>
),
},
]}
/>
</Suspense>
</div>
)
}
function DeleteCoupon({
coupon,
onSuccess,
}: {
coupon: Coupon
onSuccess?: () => void
}) {
const [loading, setLoading] = useState(false)
const handleConfirm = async () => {
setLoading(true)
try {
const resp = await deleteCoupon(coupon.id)
if (resp.success) {
toast.success("删除成功")
onSuccess?.()
} else {
toast.error(resp.message ?? "删除失败")
}
} catch (error) {
const message = error instanceof Error ? error.message : error
toast.error(`接口请求错误: ${message}`)
} finally {
setLoading(false)
}
}
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button size="sm" variant="destructive" disabled={loading}>
</Button>
</AlertDialogTrigger>
<AlertDialogContent size="sm">
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription>
{coupon.code}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction variant="destructive" onClick={handleConfirm}>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)
}