import { useState, useEffect, useCallback, useRef } from 'react' import { ChevronLeft, ChevronRight, X } from 'lucide-react' interface LightboxPhoto { id: string src: string caption?: string | null provider?: string asset_id?: string | null owner_id?: number | null } interface Props { photos: LightboxPhoto[] startIndex?: number onClose: () => void } export default function PhotoLightbox({ photos, startIndex = 0, onClose }: Props) { const [idx, setIdx] = useState(startIndex) const touchStart = useRef<{ x: number; y: number } | null>(null) const photo = photos[idx] const hasPrev = idx > 0 const hasNext = idx < photos.length - 1 const prev = useCallback(() => { if (hasPrev) setIdx(i => i - 1) }, [hasPrev]) const next = useCallback(() => { if (hasNext) setIdx(i => i + 1) }, [hasNext]) useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose() if (e.key === 'ArrowLeft') prev() if (e.key === 'ArrowRight') next() } window.addEventListener('keydown', onKey) return () => window.removeEventListener('keydown', onKey) }, [prev, next, onClose]) const onTouchStart = (e: React.TouchEvent) => { const t = e.touches[0] touchStart.current = { x: t.clientX, y: t.clientY } } const onTouchEnd = (e: React.TouchEvent) => { if (!touchStart.current) return const t = e.changedTouches[0] const dx = t.clientX - touchStart.current.x const dy = t.clientY - touchStart.current.y // swipe down to close if (dy > 80 && Math.abs(dx) < 60) { onClose() return } // horizontal swipe if (Math.abs(dx) > 50 && Math.abs(dy) < 80) { if (dx < 0) next() else prev() } touchStart.current = null } if (!photo) return null return (
{photo.caption}