Ship product gaps: register/vote pages, friend add/accept/decline/remove, email verify TTL, captcha on login/forgot, soft-fail user actions, SSE abort/shared client, Commando Centrum error toasts, admin delete for events/polls, and IT/NL i18n fills. Co-authored-by: Cursor <[email protected]>
64 lines
1.6 KiB
TypeScript
64 lines
1.6 KiB
TypeScript
import { redirect } from "next/navigation";
|
|
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
|
|
import { prisma } from "@/lib/prisma";
|
|
import { VouchersClient, type VoucherRow } from "./vouchers-client";
|
|
|
|
export default async function AdminVouchers() {
|
|
const { session, permissions } = await getAdminContext();
|
|
if (!canAccess(permissions, PERMS.SHOP_VIEW, session.user.rank)) {
|
|
redirect("/admin");
|
|
}
|
|
|
|
const canEdit = canAccess(permissions, PERMS.SHOP_EDIT, session.user.rank);
|
|
const now = Date.now();
|
|
|
|
let rows: VoucherRow[] = [];
|
|
try {
|
|
const 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,
|
|
});
|
|
rows = vouchers.map((v) => {
|
|
const expired = v.expiresAt ? v.expiresAt.getTime() <= now : false;
|
|
const usedUp = v.maxUses > 0 && v.useCount >= v.maxUses;
|
|
const status: VoucherRow["status"] = expired
|
|
? "expired"
|
|
: usedUp
|
|
? "usedUp"
|
|
: "active";
|
|
return {
|
|
id: String(v.id),
|
|
code: v.code,
|
|
amount: v.amount,
|
|
maxUses: v.maxUses,
|
|
useCount: v.useCount,
|
|
expiresAt: v.expiresAt?.toISOString() ?? null,
|
|
createdAt: v.createdAt?.toISOString() ?? null,
|
|
status,
|
|
};
|
|
});
|
|
} catch {
|
|
rows = [];
|
|
}
|
|
|
|
const stats = {
|
|
total: rows.length,
|
|
active: rows.filter((v) => v.status === "active").length,
|
|
usedUp: rows.filter((v) => v.status === "usedUp").length,
|
|
expired: rows.filter((v) => v.status === "expired").length,
|
|
};
|
|
|
|
return (
|
|
<VouchersClient vouchers={rows} canEdit={canEdit} stats={stats} />
|
|
);
|
|
}
|