"use client"; import { useState } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { useSession } from "next-auth/react"; import { useBaby } from "@/contexts/baby-context"; import { format } from "date-fns"; import { fr } from "date-fns/locale"; import { Plus, Pencil, Trash2, ChevronDown, ChevronUp, CheckSquare, Square, AlertCircle } from "lucide-react"; interface Vaccination { id: string; babyId: string; name: string; date: string | null; dueDate: string | null; notes: string | null; done: boolean; createdAt: string; } const PRESET_VACCINES = [ "BCG", "Hépatite B", "DTPolio", "Pentavalent", "Pneumocoque", "Méningocoque C", "ROR", "Varicelle", "Hépatite A", ]; const inputCls = "w-full px-3 py-2.5 rounded-lg border border-slate-200 dark:border-slate-700 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-400 bg-white dark:bg-slate-800 text-slate-900 dark:text-slate-100"; const emptyForm = { name: "", dueDate: "", date: "", notes: "" }; function formatDate(dateStr: string) { return format(new Date(dateStr), "d MMM yyyy", { locale: fr }); } function isOverdue(v: Vaccination): boolean { if (v.done || !v.dueDate) return false; return new Date(v.dueDate) < new Date(new Date().toDateString()); } export default function VaccinationsPage() { const qc = useQueryClient(); const { selectedBaby: baby } = useBaby(); const { data: session } = useSession(); const isReadonly = (session?.user as { role?: string } | undefined)?.role === "READONLY"; const [showForm, setShowForm] = useState(false); const [form, setForm] = useState(emptyForm); const [saving, setSaving] = useState(false); const [editingId, setEditingId] = useState(null); const [editForm, setEditForm] = useState(emptyForm); const [editSaving, setEditSaving] = useState(false); const [showDone, setShowDone] = useState(false); const [togglingId, setTogglingId] = useState(null); const { data: vaccinations = [] } = useQuery({ queryKey: ["vaccinations", baby?.id], queryFn: () => fetch(`/api/vaccinations?babyId=${baby!.id}`).then((r) => r.json()), enabled: !!baby?.id, }); const upcoming = vaccinations.filter((v) => !v.done); const done = vaccinations.filter((v) => v.done); async function handleSave(e: React.FormEvent) { e.preventDefault(); if (!baby) return; setSaving(true); await fetch("/api/vaccinations", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ babyId: baby.id, name: form.name, dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null, date: form.date ? new Date(form.date).toISOString() : null, notes: form.notes || null, }), }); qc.invalidateQueries({ queryKey: ["vaccinations", baby.id] }); setSaving(false); setShowForm(false); setForm(emptyForm); } function startEdit(v: Vaccination) { setEditingId(v.id); setEditForm({ name: v.name, dueDate: v.dueDate ? format(new Date(v.dueDate), "yyyy-MM-dd") : "", date: v.date ? format(new Date(v.date), "yyyy-MM-dd") : "", notes: v.notes ?? "", }); } async function handleEditSave(e: React.FormEvent, id: string) { e.preventDefault(); if (!baby) return; setEditSaving(true); await fetch(`/api/vaccinations/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: editForm.name, dueDate: editForm.dueDate ? new Date(editForm.dueDate).toISOString() : null, date: editForm.date ? new Date(editForm.date).toISOString() : null, notes: editForm.notes || null, }), }); qc.invalidateQueries({ queryKey: ["vaccinations", baby.id] }); setEditSaving(false); setEditingId(null); } async function handleDelete(id: string) { if (!baby) return; if (!confirm("Supprimer ce vaccin ?")) return; await fetch(`/api/vaccinations/${id}`, { method: "DELETE" }); qc.invalidateQueries({ queryKey: ["vaccinations", baby.id] }); } async function handleToggleDone(v: Vaccination) { if (!baby || isReadonly) return; setTogglingId(v.id); const nowDone = !v.done; await fetch(`/api/vaccinations/${v.id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ done: nowDone, date: nowDone && !v.date ? new Date().toISOString() : v.date ?? undefined, }), }); qc.invalidateQueries({ queryKey: ["vaccinations", baby.id] }); setTogglingId(null); } function VaccinCard({ v }: { v: Vaccination }) { const overdue = isOverdue(v); const toggling = togglingId === v.id; if (editingId === v.id) { return (
handleEditSave(e, v.id)} className="space-y-3"> {/* Preset chips */}
{PRESET_VACCINES.map((preset) => ( ))}
setEditForm((f) => ({ ...f, name: e.target.value }))} required placeholder="Nom du vaccin" className={inputCls} />
setEditForm((f) => ({ ...f, dueDate: e.target.value }))} className={inputCls} />
setEditForm((f) => ({ ...f, date: e.target.value }))} className={inputCls} />