"use client"; import { useState, useTransition } from "react"; import { Save, Pencil, X, Check, Trash2, Star, Eye, EyeOff, FileJson } from "lucide-react"; import { useRouter } from "next/navigation"; import { saveCoverMeta } from "@/app/actions/coverMeta"; import { deleteImage } from "@/app/actions/bulk"; import { useUndoDeleteToast } from "@/components/select/UndoDeleteToast"; import { useSettings } from "@/components/settings/SettingsProvider"; import { ChipInput, type ChipSuggestion } from "./ChipInput"; import { NfoImportDialog } from "./NfoImportDialog"; import type { NfoMetadata } from "@/lib/jav/nfoParser"; import { cn } from "@/lib/utils"; export interface CoverEditorInitial { imageId: number; code: string | null; title: string | null; releaseDate: string | null; runtimeMin: number | null; director: string | null; studio: string | null; label: string | null; series: string | null; rating: number | null; watched: boolean; notes: string | null; actresses: string[]; genres: string[]; } export function CoverEditor({ initial, actressSuggestions, genreSuggestions, }: { initial: CoverEditorInitial; actressSuggestions?: ChipSuggestion[]; genreSuggestions?: ChipSuggestion[]; }) { const empty = !initial.code && !initial.title && initial.actresses.length === 0; const [editing, setEditing] = useState(empty); const [code, setCode] = useState(initial.code ?? ""); const [title, setTitle] = useState(initial.title ?? ""); const [releaseDate, setReleaseDate] = useState(initial.releaseDate ?? ""); const [runtime, setRuntime] = useState(initial.runtimeMin?.toString() ?? ""); const [director, setDirector] = useState(initial.director ?? ""); const [studio, setStudio] = useState(initial.studio ?? ""); const [label, setLabel] = useState(initial.label ?? ""); const [series, setSeries] = useState(initial.series ?? ""); const [rating, setRating] = useState(initial.rating); const [watched, setWatched] = useState(initial.watched); const [notes, setNotes] = useState(initial.notes ?? ""); const [actresses, setActresses] = useState(initial.actresses); const [genres, setGenres] = useState(initial.genres); const [saved, setSaved] = useState(false); const [importing, setImporting] = useState(false); const [pending, start] = useTransition(); const router = useRouter(); const applyImported = (m: NfoMetadata) => { if (m.code) setCode(m.code); if (m.title) setTitle(m.title); if (m.releaseDate) setReleaseDate(m.releaseDate); if (m.runtimeMin != null) setRuntime(String(m.runtimeMin)); if (m.director) setDirector(m.director); if (m.studio) setStudio(m.studio); if (m.series) setSeries(m.series); if (m.actresses && m.actresses.length) setActresses(Array.from(new Set([...actresses, ...m.actresses]))); if (m.genres && m.genres.length) setGenres(Array.from(new Set([...genres, ...m.genres]))); if (m.notes) setNotes(m.notes); setEditing(true); }; const { settings } = useSettings(); const { show: showUndo } = useUndoDeleteToast(); const save = () => { start(async () => { await saveCoverMeta({ imageId: initial.imageId, code: code || null, title: title || null, releaseDate: releaseDate || null, runtimeMin: runtime ? Number(runtime) : null, director: director || null, studio: studio || null, label: label || null, series: series || null, rating, watched, notes: notes || null, actresses, genres, }); router.refresh(); setSaved(true); setEditing(false); setTimeout(() => setSaved(false), 1600); }); }; const cancel = () => { setCode(initial.code ?? ""); setTitle(initial.title ?? ""); setReleaseDate(initial.releaseDate ?? ""); setRuntime(initial.runtimeMin?.toString() ?? ""); setDirector(initial.director ?? ""); setStudio(initial.studio ?? ""); setLabel(initial.label ?? ""); setSeries(initial.series ?? ""); setRating(initial.rating); setWatched(initial.watched); setNotes(initial.notes ?? ""); setActresses(initial.actresses); setGenres(initial.genres); setEditing(false); }; const onDelete = (e: React.MouseEvent) => { const permanent = e.shiftKey || !settings.useRecycleBin; if (permanent && !confirm("Permanently delete this cover? Cannot be undone.")) return; start(async () => { await deleteImage(initial.imageId, permanent ? { permanent: true } : undefined); if (!permanent) showUndo([initial.imageId]); router.push("/"); }); }; if (!editing) { return ( <>
{/* Status row: fixed height so the toast/hint never reflows the buttons above. Empty placeholder retains the line so the transition between states stays CLS-free. */}
{saved ? ( Saved ) : empty ? ( No metadata yet — click Edit to fill in details ) : (   )}
{importing && setImporting(false)} onApply={applyImported} />} ); } return (

{empty ? "Add Metadata" : "Edit Metadata"}

{!empty && ( )}