- Remove .prettierrc (dead config, Biome replaces Prettier) - Rename lighthouserc.json to lighthouserc.cjs with module.exports for ESM compat - Add logger.warn to empty catch blocks in auth, register, site-settings, prisma-cache, redis, security, rate-limit - Unify ActionResult type: action-helper.ts uses 'ok' consistent with safe-action-shared.ts - Add noUnusedLocals + noUnusedParameters to tsconfig + fix 25 pre-existing unused vars - Replace barrel export src/types/index.ts with direct @/types/common imports - Make trustHost conditional (development only) in auth.ts - Add pre-flight URL validation to update-Nitrov3.sh to catch image.library.url misconfigurations - Improve NITRO_IMAGE_LIBRARY_URL content validation in pre-flight & post-compute checks
62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
import { redirect } from "next/navigation";
|
|
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
|
|
import { prisma } from "@/lib/prisma";
|
|
import { type VoucherRow, VouchersClient } 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} />;
|
|
}
|