import { count, desc, inArray } from "drizzle-orm"; import { Camera } from "lucide-react"; import Link from "next/link"; import { redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import { deletePhoto } from "@/actions/admin-photos"; import { AdminPageShell } from "@/components/admin/admin-page-shell"; import { StatusCard } from "@/components/admin/dashboard"; import { Button } from "@/components/ui/button"; import { calcPagination, parseListParams } from "@/lib/admin-helpers"; import { CameraWeb, db, User } from "@/lib/db"; import { canAccess, getAdminContext, PERMS } from "@/lib/permissions"; // TODO: Cache Components adoption. Refactor this route so this opt-out can be removed. // See: https://nextjs.org/docs/app/guides/migrating-to-cache-components export const instant = false; export default async function AdminPhotos({ searchParams, }: { searchParams: Promise>; }) { const { session, permissions } = await getAdminContext(); if (!canAccess(permissions, PERMS.PAGES_VIEW, session.user.rank)) { redirect("/admin"); } const t = await getTranslations("pages.admin.photos"); const parsed = parseListParams(new URLSearchParams(await searchParams)); const [totalRow] = await db .select({ total: count() }) .from(CameraWeb) .catch(() => [{ total: 0 }]); const total = Number(totalRow?.total ?? 0); const pagination = calcPagination(total, parsed.page, parsed.perPage || 24); let photos: (typeof CameraWeb.$inferSelect)[] = []; try { photos = await db .select() .from(CameraWeb) .orderBy(desc(CameraWeb.timestamp)) .limit(pagination.perPage) .offset(pagination.offset); } catch { photos = []; } const userIds = [...new Set(photos.map((p) => p.userId))]; const users = userIds.length > 0 ? await db .select({ id: User.id, username: User.username }) .from(User) .where(inArray(User.id, userIds)) .catch(() => []) : []; const usernameById = new Map(users.map((u) => [u.id, u.username])); const uniqueRooms = new Set(photos.map((p) => p.roomId)).size; const uniqueUsers = new Set(photos.map((p) => p.userId)).size; const canEdit = canAccess(permissions, PERMS.PAGES_EDIT, session.user.rank); return (

{t("purgeHint")}

{t("recentPhotos")}

{photos.length === 0 ? (
{t("noPhotos")}
) : (
{photos.map((p) => { const username = usernameById.get(p.userId) ?? `#${p.userId}`; return (
{/* eslint-disable-next-line @next/next/no-img-element */} {t("photoAlt",
#{String(p.id)} {t("colRoom")} {p.roomId}

{t("byUser", { username })} {" "} ยท{" "} {new Date(p.timestamp * 1000) .toISOString() .slice(0, 16) .replace("T", " ")}

{canEdit ? (
) : null}
); })}
)} {pagination.lastPage > 1 ? (

{t("pageOf", { page: pagination.page, last: pagination.lastPage, total, })}

) : null}
); }