diff --git a/components/shoot-log/TakeEditorPanel.tsx b/components/shoot-log/TakeEditorPanel.tsx index e28076d..98ec018 100644 --- a/components/shoot-log/TakeEditorPanel.tsx +++ b/components/shoot-log/TakeEditorPanel.tsx @@ -213,7 +213,88 @@ interface LinkedShot { references: { id: string; fileUrl: string; fileName: string; label: string | null }[]; } +interface LightboxItem { + url: string; + label: string; +} + +function ShotLightbox({ + items, + index, + onClose, +}: { + items: LightboxItem[]; + index: number; + onClose: () => void; +}) { + const [current, setCurrent] = useState(index); + const item = items[current]; + + // Keyboard navigation + useEffect(() => { + function onKey(e: KeyboardEvent) { + if (e.key === "Escape") onClose(); + if (e.key === "ArrowLeft") setCurrent((c) => Math.max(0, c - 1)); + if (e.key === "ArrowRight") setCurrent((c) => Math.min(items.length - 1, c + 1)); + } + window.addEventListener("keydown", onKey); + return () => window.removeEventListener("keydown", onKey); + }, [items.length, onClose]); + + return ( +
+ + +
e.stopPropagation()} + > + {/* eslint-disable-next-line @next/next/no-img-element */} + {item.label} +
+ +

{item.label}

+ + {items.length > 1 && ( +
e.stopPropagation()}> + + + {current + 1} / {items.length} + + +
+ )} +
+ ); +} + function LinkedShotPanel({ shotId }: { shotId: string }) { + const [lightboxIndex, setLightboxIndex] = useState(null); + const { data, isLoading } = useQuery<{ shot: LinkedShot }>({ queryKey: ["linked-shot", shotId], queryFn: async () => { @@ -239,46 +320,80 @@ function LinkedShotPanel({ shotId }: { shotId: string }) { const hasContent = shot.thumbnailUrl || shot.references.length > 0; if (!hasContent) return null; + // Build a flat list of lightbox items: thumbnail first, then references + const lightboxItems: LightboxItem[] = [ + ...(shot.thumbnailUrl + ? [{ url: shot.thumbnailUrl, label: `${shot.shotCode} — Thumbnail` }] + : []), + ...shot.references.map((ref) => ({ + url: ref.fileUrl, + label: ref.label ?? ref.fileName, + })), + ]; + + // Index offsets: thumbnail is 0 (if present), refs start at offset + const thumbLightboxIndex = shot.thumbnailUrl ? 0 : null; + const refLightboxOffset = shot.thumbnailUrl ? 1 : 0; + return ( -
-
- - Shot Reference — {shot.shotCode} + <> +
+
+ + Shot Reference — {shot.shotCode} +
+ + {shot.thumbnailUrl && ( +
setLightboxIndex(thumbLightboxIndex!)} + > + {shot.shotCode} +
+
+ )} + + {shot.references.length > 0 && ( +
+ {shot.references.map((ref, i) => ( +
setLightboxIndex(refLightboxOffset + i)} + > + {ref.label +
+ {ref.label && ( +
+ {ref.label} +
+ )} +
+ ))} +
+ )}
- {shot.thumbnailUrl && ( -
- {shot.shotCode} -
+ {lightboxIndex !== null && ( + setLightboxIndex(null)} + /> )} - - {shot.references.length > 0 && ( -
- {shot.references.map((ref) => ( -
- {ref.label - {ref.label && ( -
- {ref.label} -
- )} -
- ))} -
- )} -
+ ); }