Files
Raul Lugo 5ff287a911
Deploy On Server / Prepare Repository Remotely (push) Successful in 9s
Deploy On Server / Docker Compose Up (push) Successful in 17s
Deploy On Server / Prune Images (push) Successful in 2s
Deploy On Server / Remove .env File (push) Successful in 3s
feat: dasboard stats
2026-08-11 22:56:32 +02:00

84 lines
2.6 KiB
TypeScript

import { db } from "@/lib/db/client"
export interface AdminDashboardMetrics {
totalInvitations: number
totalMembers: number
attendingMembers: number
declinedMembers: number
pendingMembers: number
submittedInvitations: number
pendingInvitations: number
uploadedPhotos: number
pendingToastRequests: number
}
function toNumber(value: string | number | bigint | null | undefined) {
return Number(value ?? 0)
}
export async function getAdminDashboardMetrics(): Promise<AdminDashboardMetrics> {
const [
totalInvitations,
totalMembers,
attendingMembers,
declinedMembers,
pendingMembers,
submittedInvitations,
uploadedPhotos,
pendingToastRequests,
] = await Promise.all([
db
.selectFrom("invitations")
.select((eb) => eb.fn.countAll<string>().as("count"))
.executeTakeFirstOrThrow(),
db
.selectFrom("invitation_members")
.select((eb) => eb.fn.countAll<string>().as("count"))
.executeTakeFirstOrThrow(),
db
.selectFrom("invitation_members")
.select((eb) => eb.fn.countAll<string>().as("count"))
.where("attending", "=", true)
.executeTakeFirstOrThrow(),
db
.selectFrom("invitation_members")
.select((eb) => eb.fn.countAll<string>().as("count"))
.where("attending", "=", false)
.executeTakeFirstOrThrow(),
db
.selectFrom("invitation_members")
.select((eb) => eb.fn.countAll<string>().as("count"))
.where("attending", "is", null)
.executeTakeFirstOrThrow(),
db
.selectFrom("invitation_responses")
.select((eb) => eb.fn.countAll<string>().as("count"))
.where("submitted_at", "is not", null)
.executeTakeFirstOrThrow(),
db
.selectFrom("photo_uploads")
.select((eb) => eb.fn.countAll<string>().as("count"))
.executeTakeFirstOrThrow(),
db
.selectFrom("toast_requests")
.select((eb) => eb.fn.countAll<string>().as("count"))
.where("status", "=", "pending")
.executeTakeFirstOrThrow(),
])
const invitationsCount = toNumber(totalInvitations.count)
const submittedInvitationsCount = toNumber(submittedInvitations.count)
return {
totalInvitations: invitationsCount,
totalMembers: toNumber(totalMembers.count),
attendingMembers: toNumber(attendingMembers.count),
declinedMembers: toNumber(declinedMembers.count),
pendingMembers: toNumber(pendingMembers.count),
submittedInvitations: submittedInvitationsCount,
pendingInvitations: Math.max(invitationsCount - submittedInvitationsCount, 0),
uploadedPhotos: toNumber(uploadedPhotos.count),
pendingToastRequests: toNumber(pendingToastRequests.count),
}
}