import type { SQL } from "drizzle-orm"; import { asc, desc, max, ne, sql, sum } from "drizzle-orm"; import type { Metadata } from "next"; import { Suspense } from "react"; import { Skeleton } from "@/components/ui/skeleton"; import { db } from "@/lib/db"; import { donations } from "@/lib/db/schema"; import { fileToDataUrl } from "@/lib/utils"; import { Podium } from "./podium"; import { TopDonateTable } from "./table"; type NumberString = `${number}`; type NumberLike = number | NumberString; export const metadata: Metadata = { title: "โดเนทขึ้นจอ", description: "ท็อป 10 อันดับคนโดเนท", }; export default function Page() { return ( }> ); } function PageSkeleton() { return (
); } async function Content() { const list = await db .select({ i: sql`ROW_NUMBER() OVER (ORDER BY ${desc(sum(donations.amount))}, ${asc(max(donations.id))})`, name: donations.name, amount: sum(donations.amount) as unknown as SQL, }) .from(donations) .where(ne(donations.name, "Anonymous")) .offset(3) .limit(7) .groupBy(donations.name) .orderBy(desc(sum(donations.amount)), asc(max(donations.id))); const podium = await db .select({ name: donations.name, amount: sum(donations.amount).as("amount"), image: sql` ( array_agg(${donations.image} ORDER BY ${donations.id} DESC ) )[1] `, }) .from(donations) .where(ne(donations.name, "Anonymous")) .groupBy(donations.name) .orderBy(desc(sum(donations.amount)), asc(max(donations.id))) .limit(3) .then((r) => Promise.all( r.map(async (d) => ({ ...d, image: d.image ? await fileToDataUrl(new File([Buffer.from(d.image)], "image.jpg")) : undefined, })), ), ); return (
); } export const dynamic = "force-dynamic";