"use client"; import { useState } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { useBaby } from "@/contexts/baby-context"; import { Plus, Trash2, Bell, BellOff, Clock, CheckCircle2, RotateCcw } from "lucide-react"; import { formatDistanceToNow } from "date-fns"; import { fr } from "date-fns/locale"; interface Reminder { id: string; name: string; dose: string | null; unit: string | null; intervalHours: number; startAt: string; enabled: boolean; lastSentAt: string | null; } 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 dark:text-slate-100"; function localNowString() { const now = new Date(); return new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString().slice(0, 16); } function nextDueLabel(reminder: Reminder): string { const intervalMs = reminder.intervalHours * 60 * 60 * 1000; const base = reminder.lastSentAt ?? reminder.startAt; const next = new Date(new Date(base).getTime() + intervalMs); const now = new Date(); const diff = next.getTime() - now.getTime(); if (diff <= 0) return "En attente d'envoi"; const h = Math.floor(diff / 3600000); const m = Math.floor((diff % 3600000) / 60000); return h > 0 ? `Dans ${h}h${m.toString().padStart(2, "0")}` : `Dans ${m} min`; } export default function RemindersPage() { const qc = useQueryClient(); const { selectedBaby } = useBaby(); const [showForm, setShowForm] = useState(false); const [form, setForm] = useState({ name: "", dose: "", unit: "mL", intervalHours: "8", startAt: localNowString() }); const [saving, setSaving] = useState(false); const { data: reminders = [], isLoading } = useQuery({ queryKey: ["reminders", selectedBaby?.id], queryFn: () => fetch(`/api/reminders?babyId=${selectedBaby!.id}`).then((r) => r.json()), enabled: !!selectedBaby?.id, }); async function handleCreate(e: React.FormEvent) { e.preventDefault(); if (!selectedBaby) return; setSaving(true); await fetch("/api/reminders", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ babyId: selectedBaby.id, ...form, intervalHours: parseFloat(form.intervalHours) }), }); qc.invalidateQueries({ queryKey: ["reminders"] }); setForm({ name: "", dose: "", unit: "mL", intervalHours: "8", startAt: localNowString() }); setShowForm(false); setSaving(false); } async function toggleEnabled(id: string, enabled: boolean) { await fetch(`/api/reminders/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ enabled: !enabled }), }); qc.invalidateQueries({ queryKey: ["reminders"] }); } async function markTaken(id: string) { await fetch(`/api/reminders/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ lastSentAt: new Date().toISOString() }), }); qc.invalidateQueries({ queryKey: ["reminders"] }); } async function unmarkTaken(id: string) { await fetch(`/api/reminders/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ lastSentAt: null }), }); qc.invalidateQueries({ queryKey: ["reminders"] }); } async function deleteReminder(id: string) { if (!confirm("Supprimer ce rappel ?")) return; await fetch(`/api/reminders/${id}`, { method: "DELETE" }); qc.invalidateQueries({ queryKey: ["reminders"] }); } return (

Rappels médicaments

{selectedBaby &&

{selectedBaby.name}

}
{showForm && (

Nouveau rappel

setForm((f) => ({ ...f, name: e.target.value }))} required className={inputCls} placeholder="Doliprane" />
setForm((f) => ({ ...f, dose: e.target.value }))} className={inputCls} placeholder="2.4" />
setForm((f) => ({ ...f, startAt: e.target.value }))} required className={inputCls} />
)} {isLoading && (
)} {!isLoading && reminders.length === 0 && !showForm && (

Aucun rappel configuré

)}
{reminders.map((r) => (
{r.enabled ? : }

{r.name}

{(r.dose || r.unit) && (

{[r.dose, r.unit].filter(Boolean).join(" ")}

)}
Toutes les {r.intervalHours}h {r.enabled && ( {nextDueLabel(r)} )}
{r.lastSentAt && (

Pris {formatDistanceToNow(new Date(r.lastSentAt), { locale: fr, addSuffix: true })}

)}
{r.lastSentAt ? ( ) : ( )}
))}
{reminders.length > 0 && (

Appelez /api/reminders/check régulièrement (cron) pour envoyer les rappels via Pushover.

)}
); }