import { Gift } from "lucide-react"; import { createVoucher, deleteVoucher } from "@/actions/admin-vouchers"; import { StatusCard } from "@/components/admin/dashboard"; import { prisma } from "@/lib/prisma"; export const dynamic = "force-dynamic"; type VoucherRow = { id: bigint; code: string; amount: number; maxUses: number; useCount: number; expiresAt: Date | null; createdAt: Date | null; }; function fmtDate(d: Date | null): string { if (!d) return "—"; return d.toISOString().slice(0, 16).replace("T", " "); } export default async function AdminVouchers() { const now = Date.now(); let vouchers: VoucherRow[] = []; try { vouchers = await prisma.websiteShopVouchers.findMany({ select: { id: true, code: true, amount: true, maxUses: true, useCount: true, expiresAt: true, createdAt: true, }, orderBy: { id: "desc" }, take: 200, }); } catch { vouchers = []; } const active = vouchers.filter((v) => { const expired = v.expiresAt ? v.expiresAt.getTime() <= now : false; const usedUp = v.maxUses > 0 && v.useCount >= v.maxUses; return !expired && !usedUp; }).length; const expiredCount = vouchers.filter( (v) => v.expiresAt && v.expiresAt.getTime() <= now, ).length; const usedUpCount = vouchers.filter( (v) => v.maxUses > 0 && v.useCount >= v.maxUses, ).length; return (

Shop Vouchers

Codes redeemable on the website shop for a balance top-up. Each user can use a given voucher once, up to its max uses.

0 ? "ok" : "neutral"} icon="✅" /> 0 ? "warn" : "neutral"} icon="📉" /> 0 ? "danger" : "neutral"} icon="⏰" />

New voucher

Vouchers ({vouchers.length})

{vouchers.map((v) => { const expired = v.expiresAt ? v.expiresAt.getTime() <= now : false; const usedUp = v.maxUses > 0 && v.useCount >= v.maxUses; return ( ); })}
Code Amount Uses Status Expires Created
{v.code} {v.amount} {v.useCount} / {v.maxUses} {expired ? ( Expired ) : usedUp ? ( Used up ) : ( Active )} {fmtDate(v.expiresAt)} {fmtDate(v.createdAt)}
{vouchers.length === 0 ?
No vouchers yet.
: null}
); }