import { auth } from "@/lib/auth"; import { createSupabaseServiceRoleClient } from "@/lib/supabase/service-role"; import { updateGalleryPhotoPickStatus } from "@/server/admin/gallery-pick"; import { NextResponse, type NextRequest } from "next/server"; import { z } from "zod"; export const runtime = "nodejs"; export const dynamic = "force-dynamic"; const galleryPhotoSelect = "id,unsplash_id,slug,description,alt_description,width,height,color,color_family,likes,urls,user_info,photo_created_at,is_picked,picked_at,picked_by,oss_url,oss_object_key,oss_synced_at,oss_sync_error"; const patchSchema = z.object({ unsplashId: z.string().min(1), isPicked: z.boolean(), }); async function requireAdminSession() { const session = await auth(); if (!session) { return null; } return session; } export async function GET(request: NextRequest) { try { const session = await requireAdminSession(); if (!session) { return NextResponse.json( { ok: false, error: "Unauthorized." }, { status: 401 }, ); } const { searchParams } = new URL(request.url); const page = parseInt(searchParams.get("page") || "1", 10); const perPage = parseInt(searchParams.get("per_page") || "24", 10); const picked = searchParams.get("picked"); const colorFamily = searchParams.get("color_family"); if (page < 1 || perPage < 1 || perPage > 100) { return NextResponse.json( { ok: false, error: "Invalid pagination parameters." }, { status: 400 }, ); } const supabase = createSupabaseServiceRoleClient(); let query = supabase .from("wg_gallery_photos") .select(galleryPhotoSelect, { count: "exact" }); if (picked === "true") { query = query.eq("is_picked", true); } else if (picked === "false") { query = query.eq("is_picked", false); } if (colorFamily && colorFamily !== "all") { query = query.eq("color_family", colorFamily); } const { data, error, count } = await query .order("picked_at", { ascending: false, nullsFirst: false }) .order("photo_created_at", { ascending: false }) .range((page - 1) * perPage, page * perPage - 1); if (error) { throw error; } return NextResponse.json({ ok: true, data: data ?? [], pagination: { page, perPage, total: count ?? 0, hasMore: (count ?? 0) > page * perPage, }, }); } catch (error) { const message = error instanceof Error ? error.message : "Unknown error."; console.error("[api/admin/gallery-photos] PATCH failed", error); return NextResponse.json( { ok: false, error: message }, { status: 500 }, ); } } export async function PATCH(request: NextRequest) { try { const session = await requireAdminSession(); if (!session) { return NextResponse.json( { ok: false, error: "Unauthorized." }, { status: 401 }, ); } const parsed = patchSchema.safeParse(await request.json()); if (!parsed.success) { return NextResponse.json( { ok: false, error: "Invalid request body." }, { status: 400 }, ); } const data = await updateGalleryPhotoPickStatus({ isPicked: parsed.data.isPicked, pickedBy: session.user?.email ?? session.user?.id ?? "wallora-admin", unsplashId: parsed.data.unsplashId, }); return NextResponse.json({ ok: true, data, }); } catch (error) { const message = error instanceof Error ? error.message : "Unknown error."; return NextResponse.json( { ok: false, error: message }, { status: 500 }, ); } }