import { Check, ChevronLeft, ChevronRight, Copy, Download, ExternalLink, X } from 'lucide-react' import { useEffect, useState } from 'react' import { createPortal } from 'react-dom' import { useFocusTrap } from '../hooks/useFocusTrap' import { useToast } from '../store/toast' interface Props { kind: 'html' | 'image' | 'video' src: string title: string subtitle?: string onClose: () => void onPrevious?: () => void onNext?: () => void } export default function AssetPreviewModal({ kind, src, title, subtitle, onClose, onPrevious, onNext, }: Props) { const dialogRef = useFocusTrap(true) const [copyState, setCopyState] = useState<'idle' | 'copying' | 'ok'>('idle') const toast = useToast() useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose() if (kind === 'image' && e.key === 'ArrowLeft') onPrevious?.() if (kind === 'image' && e.key === 'ArrowRight') onNext?.() } window.addEventListener('keydown', onKey) const prev = document.body.style.overflow document.body.style.overflow = 'hidden' return () => { window.removeEventListener('keydown', onKey) document.body.style.overflow = prev } }, [kind, onClose, onNext, onPrevious]) const onCopyHtml = async () => { if (kind !== 'html') return setCopyState('copying') try { const res = await fetch(src) if (!res.ok) throw new Error(`HTTP ${res.status}`) const text = await res.text() await navigator.clipboard.writeText(text) setCopyState('ok') toast.push({ variant: 'success', message: 'HTML copied to clipboard.' }) window.setTimeout(() => setCopyState('idle'), 1500) } catch (e) { setCopyState('idle') toast.push({ variant: 'error', title: 'Copy failed', message: e instanceof Error ? e.message : String(e), }) } } const downloadName = title.split('/').pop() ?? title return createPortal(
{title}
{subtitle && (
{subtitle}
)}
{kind === 'image' && onPrevious && ( )} {kind === 'image' && onNext && ( )} {kind === 'html' && ( )} Download Open
{kind === 'html' ? (