"use client"; import { useState, useTransition } from "react"; import { useRouter } from "next/navigation"; import { FormField, FormLabel, FormInput } from "./ui/Form"; interface EditSeriesFormProps { libraryId: string; seriesName: string; currentAuthors: string[]; currentPublishers: string[]; currentBookAuthor: string | null; currentBookLanguage: string | null; currentDescription: string | null; currentStartYear: number | null; } export function EditSeriesForm({ libraryId, seriesName, currentAuthors, currentPublishers, currentBookAuthor, currentBookLanguage, currentDescription, currentStartYear, }: EditSeriesFormProps) { const router = useRouter(); const [isPending, startTransition] = useTransition(); const [isEditing, setIsEditing] = useState(false); const [error, setError] = useState(null); // Champs propres à la série const [newName, setNewName] = useState(seriesName === "unclassified" ? "" : seriesName); const [authors, setAuthors] = useState(currentAuthors); const [authorInput, setAuthorInput] = useState(""); const [authorInputEl, setAuthorInputEl] = useState(null); const [publishers, setPublishers] = useState(currentPublishers); const [publisherInput, setPublisherInput] = useState(""); const [publisherInputEl, setPublisherInputEl] = useState(null); const [description, setDescription] = useState(currentDescription ?? ""); const [startYear, setStartYear] = useState(currentStartYear?.toString() ?? ""); // Propagation aux livres — opt-in via bouton const [bookAuthor, setBookAuthor] = useState(currentBookAuthor ?? ""); const [bookLanguage, setBookLanguage] = useState(currentBookLanguage ?? ""); const [showApplyToBooks, setShowApplyToBooks] = useState(false); 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 addPublisher = () => { const v = publisherInput.trim(); if (v && !publishers.includes(v)) { setPublishers([...publishers, v]); } setPublisherInput(""); publisherInputEl?.focus(); }; const removePublisher = (idx: number) => { setPublishers(publishers.filter((_, i) => i !== idx)); }; const handlePublisherKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter") { e.preventDefault(); addPublisher(); } }; const handleCancel = () => { setNewName(seriesName === "unclassified" ? "" : seriesName); setAuthors(currentAuthors); setAuthorInput(""); setPublishers(currentPublishers); setPublisherInput(""); setDescription(currentDescription ?? ""); setStartYear(currentStartYear?.toString() ?? ""); setShowApplyToBooks(false); setBookAuthor(currentBookAuthor ?? ""); setBookLanguage(currentBookLanguage ?? ""); setError(null); setIsEditing(false); }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!newName.trim() && seriesName !== "unclassified") return; setError(null); const finalAuthors = authorInput.trim() ? [...new Set([...authors, authorInput.trim()])] : authors; const finalPublishers = publisherInput.trim() ? [...new Set([...publishers, publisherInput.trim()])] : publishers; startTransition(async () => { try { const effectiveName = newName.trim() || "unclassified"; const body: Record = { new_name: effectiveName, authors: finalAuthors, publishers: finalPublishers, description: description.trim() || null, start_year: startYear.trim() ? parseInt(startYear.trim(), 10) : null, }; if (showApplyToBooks) { body.author = bookAuthor.trim() || null; body.language = bookLanguage.trim() || null; } const res = await fetch( `/api/libraries/${libraryId}/series/${encodeURIComponent(seriesName)}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), } ); if (!res.ok) { const data = await res.json(); setError(data.error ?? "Erreur lors de la sauvegarde"); return; } setIsEditing(false); if (effectiveName !== seriesName) { router.push(`/libraries/${libraryId}/series/${encodeURIComponent(effectiveName)}` as any); } else { router.refresh(); } } catch { setError("Erreur réseau"); } }); }; if (!isEditing) { return ( ); } return (

Modifier les métadonnées de la série

Nom setNewName(e.target.value)} disabled={isPending} placeholder="Nom de la série" /> Année de début setStartYear(e.target.value)} disabled={isPending} placeholder="ex : 1990" /> {/* 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" />
{showApplyToBooks && (
Auteur (livres) setBookAuthor(e.target.value)} disabled={isPending} placeholder="Écrase le champ auteur de chaque livre" /> Langue (livres) setBookLanguage(e.target.value)} disabled={isPending} placeholder="ex : fr, en, jp" />
)} {/* Éditeurs — multi-valeur */} Éditeur(s)
{publishers.length > 0 && (
{publishers.map((p, i) => ( {p} ))}
)}
setPublisherInput(e.target.value)} onKeyDown={handlePublisherKeyDown} disabled={isPending} placeholder="Ajouter un éditeur (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" />
Description