"use client"; import { useState, useEffect } from "react"; import { useParams, useRouter } from "next/navigation"; import Link from "next/link"; import Image from "next/image"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { TaskList } from "@/components/tasks/TaskList"; import { Separator } from "@/components/ui/separator"; import { getInitials } from "@/lib/utils"; import { cn } from "@/lib/utils"; import { Film, ArrowLeft, Clock, AlertCircle, CheckCircle2, Settings, ListTodo, Video, Copy, } from "lucide-react"; import type { ShotWithDetails } from "@/types"; import { ShotSettingsTab } from "@/components/shots/ShotSettingsTab"; import { FootageViewer } from "@/components/shots/FootageViewer"; import { duplicateShot } from "@/actions/shots"; const STATUS_CONFIG: Record< string, { label: string; className: string; Icon: React.ElementType } > = { WAITING: { label: "Waiting", className: "bg-zinc-500/10 text-zinc-400 border-zinc-500/20", Icon: Clock }, IN_PROGRESS: { label: "In Progress", className: "bg-blue-500/10 text-blue-400 border-blue-500/20", Icon: Film }, IN_REVIEW: { label: "In Review", className: "bg-amber-500/10 text-amber-400 border-amber-500/20", Icon: AlertCircle }, REVISIONS: { label: "Revisions", className: "bg-orange-500/10 text-orange-400 border-orange-500/20", Icon: AlertCircle }, COMPLETE: { label: "Complete", className: "bg-emerald-500/10 text-emerald-400 border-emerald-500/20", Icon: CheckCircle2 }, }; const PRIORITY_CONFIG: Record = { LOW: { label: "Low", dot: "bg-zinc-400" }, NORMAL: { label: "Normal", dot: "bg-blue-400" }, HIGH: { label: "High", dot: "bg-amber-400" }, CRITICAL: { label: "Critical", dot: "bg-red-500" }, }; import { useToast } from "@/components/ui/use-toast"; export default function ShotDetailPage() { const params = useParams<{ id: string; shotId: string }>(); const router = useRouter(); const { toast } = useToast(); const [shot, setShot] = useState(null); const [projectName, setProjectName] = useState(""); const [loading, setLoading] = useState(true); const [canApprove, setCanApprove] = useState(false); const [tasks, setTasks] = useState([]); const [artists, setArtists] = useState([]); const [canManage, setCanManage] = useState(false); const [isDuplicating, setIsDuplicating] = useState(false); const [activeTab, setActiveTab] = useState<"tasks" | "footage" | "settings">("tasks"); const fetchShot = async () => { try { const res = await fetch(`/api/shots/${params.shotId}?projectId=${params.id}`); if (res.status === 404) { router.push("/projects"); return; } const data = await res.json(); setShot(data.shot); setProjectName(data.projectName ?? ""); setCanApprove(data.canApprove ?? false); setTasks(data.tasks ?? []); setArtists(data.artists ?? []); setCanManage(data.canApprove ?? false); } catch { router.push("/projects"); } finally { setLoading(false); } }; useEffect(() => { fetchShot(); }, [params.shotId]); const handleDuplicate = async () => { if (!shot) return; setIsDuplicating(true); try { const { shot: newShot } = await duplicateShot(shot.id); toast({ title: "Shot duplicated", description: `Created ${newShot.shotCode}` }); router.push(`/projects/${params.id}/shots/${newShot.id}`); } catch (e) { toast({ title: "Duplicate failed", description: e instanceof Error ? e.message : undefined, variant: "destructive" }); } finally { setIsDuplicating(false); } }; if (loading) { return (
); } if (!shot) return null; const statusCfg = STATUS_CONFIG[shot.status] ?? STATUS_CONFIG.WAITING; const priorityCfg = PRIORITY_CONFIG[shot.priority] ?? PRIORITY_CONFIG.NORMAL; const { Icon: StatusIcon } = statusCfg; return (
{/* Breadcrumb */}
Projects / {projectName} / {shot.shotCode}
{/* Header */}
{/* Thumbnail – cinema scope 2.39:1 */} {shot.thumbnailUrl && (
{shot.shotCode}
)}

{shot.shotCode}

{shot.sequence && ( Seq: {shot.sequence} )}
{shot.description && (

{shot.description}

)}
{statusCfg.label}
{priorityCfg.label} Priority
{shot.fps} fps {shot.artist && (
{getInitials(shot.artist.name ?? shot.artist.email)} {shot.artist.name ?? shot.artist.email}
)}
{canManage && (
)}
{/* Tabs */}
{canManage && ( )}
{activeTab === "tasks" && ( )} {activeTab === "footage" && ( )} {activeTab === "settings" && canManage && ( )}
); }