import { NextRequest, NextResponse } from "next/server"; import { auth } from "@/auth"; import { db } from "@/lib/db"; const IMAGE_EXTS = new Set(["jpg", "jpeg", "png", "webp", "tiff", "tif", "avif"]); export interface ThumbnailPreviewItem { fileName: string; stemName: string; shotCode: string | null; shotId: string | null; status: "match" | "no-match"; currentThumbnailUrl: string | null; } function stem(fileName: string): string { const dot = fileName.lastIndexOf("."); return (dot > 0 ? fileName.slice(0, dot) : fileName).toLowerCase(); } /** * POST /api/batch-upload/thumbnails * Body: { projectId: string; fileNames: string[] } */ export async function POST(req: NextRequest) { const session = await auth(); if (!session?.user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); let body: { projectId?: string; fileNames?: string[] }; try { body = await req.json(); } catch { return NextResponse.json({ error: "Invalid JSON" }, { status: 400 }); } const { projectId, fileNames } = body; if (!projectId || !Array.isArray(fileNames)) { return NextResponse.json({ error: "projectId and fileNames are required" }, { status: 400 }); } // Only image files const imageFiles = fileNames.filter((f) => { const ext = f.split(".").pop()?.toLowerCase() ?? ""; return IMAGE_EXTS.has(ext); }); const shots = await db.shot.findMany({ where: { projectId }, select: { id: true, shotCode: true, thumbnailUrl: true }, }); // Build a lowercase map for case-insensitive matching const shotMap = new Map(shots.map((s) => [s.shotCode.toLowerCase(), s])); const items: ThumbnailPreviewItem[] = fileNames.map((fileName) => { const ext = fileName.split(".").pop()?.toLowerCase() ?? ""; if (!IMAGE_EXTS.has(ext)) { return { fileName, stemName: stem(fileName), shotCode: null, shotId: null, status: "no-match" as const, currentThumbnailUrl: null }; } const s = stem(fileName); const shot = shotMap.get(s) ?? null; return { fileName, stemName: s, shotCode: shot?.shotCode ?? null, shotId: shot?.id ?? null, status: shot ? "match" : "no-match", currentThumbnailUrl: shot?.thumbnailUrl ?? null, }; }); return NextResponse.json({ items }); }