"use client"; import { useState, useCallback, useRef, useEffect } from "react"; import { useQuery } from "@tanstack/react-query"; import { format } from "date-fns"; import { Plus, ChevronDown, ChevronRight, Image, MessageSquare, Loader2, Clapperboard } from "lucide-react"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import type { TakeQuality } from "@prisma/client"; // ─── Types ─────────────────────────────────────────────────────────────────── export interface TakeSummary { id: string; takeNumber: number; clipName: string | null; quality: TakeQuality; supervisorNotes: string | null; continuityNotes: string | null; vfxRequirements: string | null; _count: { attachments: number }; } export interface SetupWithTakes { id: string; name: string; description: string | null; sortOrder: number; takes: TakeSummary[]; } export interface ShootDayWithSetups { id: string; date: string; unit: string; label: string | null; setups: SetupWithTakes[]; } // ─── Quality helpers ────────────────────────────────────────────────────────── const QUALITY_DOT: Record = { HERO: "bg-green-400", GOOD: "bg-blue-400", PRINT: "bg-amber-400", NO_GOOD: "bg-red-500", FALSE_START: "bg-zinc-500", }; const QUALITY_LABEL: Record = { HERO: "Hero", GOOD: "Good", PRINT: "Print", NO_GOOD: "NG", FALSE_START: "FS", }; // ─── Component ─────────────────────────────────────────────────────────────── interface Props { projectId: string; selectedTakeId: string | null; onSelectTake: (takeId: string, setupId: string) => void; onNewDay: () => void; onNewSetup: (dayId: string) => void; onNewTake: (setupId: string) => void; /** When set, auto-expands this day ID (e.g. after creation) */ expandDayId?: string | null; } export function TakeListPanel({ projectId, selectedTakeId, onSelectTake, onNewDay, onNewSetup, onNewTake, expandDayId, }: Props) { const [expandedDays, setExpandedDays] = useState>(new Set()); const [expandedSetups, setExpandedSetups] = useState>(new Set()); const autoExpandedRef = useRef(false); const { data, isLoading } = useQuery<{ days: ShootDayWithSetups[] }>({ queryKey: ["shoot-log-days", projectId], queryFn: async () => { const res = await fetch(`/api/shoot-log/days?projectId=${projectId}`); if (!res.ok) throw new Error("Failed to load days"); return res.json(); }, enabled: !!projectId, staleTime: 0, }); const days = data?.days ?? []; const toggleDay = useCallback((id: string) => { setExpandedDays((prev) => { const next = new Set(prev); next.has(id) ? next.delete(id) : next.add(id); return next; }); }, []); const toggleSetup = useCallback((id: string) => { setExpandedSetups((prev) => { const next = new Set(prev); next.has(id) ? next.delete(id) : next.add(id); return next; }); }, []); // Auto-expand the first day/setup on first load useEffect(() => { if (!autoExpandedRef.current && days.length > 0) { autoExpandedRef.current = true; const firstDay = days[0]; setExpandedDays(new Set([firstDay.id])); if (firstDay.setups.length > 0) { setExpandedSetups(new Set([firstDay.setups[0].id])); } } }, [days]); // Expand a specific day when requested (e.g. after creation) useEffect(() => { if (!expandDayId) return; setExpandedDays((prev) => new Set([...prev, expandDayId])); // Also expand the first setup within that day if present const day = days.find((d) => d.id === expandDayId); if (day?.setups[0]) { setExpandedSetups((prev) => new Set([...prev, day.setups[0].id])); } }, [expandDayId]); // eslint-disable-line react-hooks/exhaustive-deps const hasNotes = (take: TakeSummary) => !!(take.supervisorNotes || take.continuityNotes || take.vfxRequirements); return (
{/* Header */}
Shoot Days
{/* List */}
{isLoading ? (
) : days.length === 0 ? (

No shoot days yet.

) : (
{days.map((day) => { const dayOpen = expandedDays.has(day.id); const takeCount = day.setups.reduce((s, set) => s + set.takes.length, 0); return (
{/* Day row */} {/* Setups */} {dayOpen && (
{day.setups.length === 0 ? (
) : ( day.setups.map((setup) => { const setupOpen = expandedSetups.has(setup.id); return (
{/* Setup row */} {/* Takes */} {setupOpen && (
{setup.takes.map((take) => ( ))} {/* Add take button */}
)}
); }) )}
)}
); })}
)}
); }