"use client"; import { useState, useTransition, useEffect, useCallback } from "react"; import { createPortal } from "react-dom"; import { useRouter } from "next/navigation"; import { BookDto } from "@/lib/api"; import { FormField, FormLabel, FormInput } from "./ui/Form"; interface EditBookFormProps { book: BookDto; } export function EditBookForm({ book }: EditBookFormProps) { const router = useRouter(); const [isPending, startTransition] = useTransition(); const [isOpen, setIsOpen] = useState(false); const [error, setError] = useState(null); const [title, setTitle] = useState(book.title); const [authors, setAuthors] = useState(book.authors ?? []); const [authorInput, setAuthorInput] = useState(""); const [authorInputEl, setAuthorInputEl] = useState(null); const [series, setSeries] = useState(book.series ?? ""); const [volume, setVolume] = useState(book.volume?.toString() ?? ""); const [language, setLanguage] = useState(book.language ?? ""); const addAuthor = () => { const v = authorInput.trim(); if (v && !authors.includes(v)) { setAuthors([...authors, v]); } setAuthorInput(""); authorInputEl?.focus(); }; const removeAuthor = (idx: number) => { setAuthors(authors.filter((_, i) => i !== idx)); }; const handleAuthorKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter") { e.preventDefault(); addAuthor(); } }; const handleClose = useCallback(() => { setTitle(book.title); setAuthors(book.authors ?? []); setAuthorInput(""); setSeries(book.series ?? ""); setVolume(book.volume?.toString() ?? ""); setLanguage(book.language ?? ""); setError(null); setIsOpen(false); }, [book]); useEffect(() => { if (!isOpen) return; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape" && !isPending) handleClose(); }; document.addEventListener("keydown", handleKeyDown); return () => document.removeEventListener("keydown", handleKeyDown); }, [isOpen, isPending, handleClose]); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!title.trim()) return; setError(null); const finalAuthors = authorInput.trim() ? [...new Set([...authors, authorInput.trim()])] : authors; startTransition(async () => { try { const res = await fetch(`/api/books/${book.id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title: title.trim(), author: finalAuthors[0] ?? null, authors: finalAuthors, series: series.trim() || null, volume: volume.trim() ? parseInt(volume.trim(), 10) : null, language: language.trim() || null, }), }); if (!res.ok) { const data = await res.json(); setError(data.error ?? "Erreur lors de la sauvegarde"); return; } setIsOpen(false); router.refresh(); } catch { setError("Erreur réseau"); } }); }; const modal = isOpen ? createPortal( <> {/* Backdrop */}
!isPending && handleClose()} /> {/* Modal */}
{/* Header */}

Modifier les métadonnées

{/* Body */}
Titre setTitle(e.target.value)} disabled={isPending} placeholder="Titre du livre" /> {/* Auteurs — multi-valeur */} Auteur(s)
{authors.length > 0 && (
{authors.map((a, i) => ( {a} ))}
)}
setAuthorInput(e.target.value)} onKeyDown={handleAuthorKeyDown} disabled={isPending} placeholder="Ajouter un auteur (Entrée pour valider)" className="flex h-10 flex-1 rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50" />
Langue setLanguage(e.target.value)} disabled={isPending} placeholder="ex : fr, en, jp" /> Série setSeries(e.target.value)} disabled={isPending} placeholder="Nom de la série" /> Volume setVolume(e.target.value)} disabled={isPending} placeholder="Numéro de volume" />
{error && (

{error}

)} {/* Footer */}
, document.body ) : null; return ( <> {modal} ); }