feat(don): add synced checkbox to donate admin
Build and Push Image / build-backend (push) Successful in 23s
Build and Push Image / push (push) Has been cancelled
Build and Push Image / build-frontend (push) Has been cancelled

This commit is contained in:
2026-09-13 20:48:09 +07:00 Unverified
parent f932afe00c
commit 621205435a
3 changed files with 45 additions and 6 deletions
+27 -2
View File
@@ -35,6 +35,8 @@ import { lePalette } from "../../rubgram/admin/[id]/client";
import { th } from "date-fns/locale";
import TruemoneyIcon from "#/assets/tmn.webp";
import Image from "@/components/image";
import { Checkbox } from "@/components/ui/checkbox";
import { toggleCheck } from "@/lib/api";
// directly adapted for date instead of UUID
function colorFor(date: Date) {
@@ -46,7 +48,12 @@ function colorFor(date: Date) {
return lePalette[seed % lePalette.length];
}
const columns: ColumnDef<typeof donations.$inferSelect>[] = [
const columns: ColumnDef<
typeof donations.$inferSelect & {
checked: boolean | null;
artifactSubmissionId: string | null;
}
>[] = [
{
accessorKey: "created",
header: "",
@@ -63,6 +70,21 @@ const columns: ColumnDef<typeof donations.$inferSelect>[] = [
meta: { className: "w-1 p-0 relative" },
},
{ accessorKey: "name", header: "ชื่อ", meta: { className: "w-50 truncate" } },
{
accessorKey: "art_check",
header: "",
meta: { className: "w-6 truncate" },
cell(row) {
const { artifactSubmissionId, checked } = row.row.original;
if (checked === null || !artifactSubmissionId) return;
return (
<Checkbox
checked={checked}
onCheckedChange={() => toggleCheck(artifactSubmissionId)}
/>
);
},
},
{
accessorFn: (row) => `${row.amount}฿`,
header: "จำนวน",
@@ -274,7 +296,10 @@ export function DonateAdminPage({
data,
stats,
}: {
data: (typeof donations.$inferSelect)[];
data: (typeof donations.$inferSelect & {
checked: boolean | null;
artifactSubmissionId: string | null;
})[];
stats: {
total: number;
today: number;
+16 -4
View File
@@ -1,5 +1,6 @@
import { endOfMonth, startOfMonth } from "date-fns";
import { between, desc, getTableColumns, sql, sum } from "drizzle-orm";
import { alias } from "drizzle-orm/pg-core";
import type { Metadata } from "next";
import { redirect } from "next/navigation";
import { adminCheck } from "@/lib/auth";
@@ -12,15 +13,26 @@ export default async function () {
redirect(`/login?next=${encodeURIComponent("/donate/admin")}`);
const now = new Date();
const donation = alias(donations, "donation");
const [data, [stats]] = await Promise.all([
db
.select({
...getTableColumns(donations),
image: sql<Buffer>`${donations.image} IS NOT NULL`,
...getTableColumns(donation),
image: sql<Buffer>`${donation.image} IS NOT NULL`,
checked: sql<boolean | null>`
(SELECT "artifact"."submissions"."checked"
FROM "artifact"."submissions"
WHERE "artifact"."submissions"."uid" = "donation"."uid")
`,
artifactSubmissionId: sql<string | null>`
(SELECT "artifact"."submissions"."id"
FROM "artifact"."submissions"
WHERE "artifact"."submissions"."uid" = "donation"."uid")
`,
})
.from(donations)
.from(donation)
.limit(100)
.orderBy(desc(donations.id)),
.orderBy(desc(donation.id)),
db
.select({
total: sum(donations.amount).mapWith(Number),
+2
View File
@@ -180,8 +180,10 @@ export async function toggleCheck(submissionId: string) {
.where(eq(submissions.id, submissionId));
revalidatePath("/artifact/admin");
revalidatePath("/artifact");
revalidatePath("/donate/admin");
sse.artifact.pub("update", { type: "toggleCheck" });
sse.donate.pub("update", null);
await actionLog(`Toggled an artifact submission check mark`);
}