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