fix: UX audit — code-review findings
- Photo client-side limit: 5MB → 30MB (matches server) - OTHER event shows notes preview in dashboard + timeline summaries - Stats: add "Activités par jour" chart (Bain/Balade/Plat ventre/Autre) - Combined diaper (wet→stool): show color/amount pickers, pass metadata - Quick-add FAB: 4-col → 5-col grid (14 types in 3 rows instead of 4) - Stool color buttons: force dark text, readable on light bg in dark mode - Reminders: mark taken (✓) sets lastSentAt, ↺ clears it; shows elapsed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,9 @@
|
||||
import { useState } from "react";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { useBaby } from "@/contexts/baby-context";
|
||||
import { Plus, Trash2, Bell, BellOff, Clock } from "lucide-react";
|
||||
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;
|
||||
@@ -72,6 +74,24 @@ export default function RemindersPage() {
|
||||
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" });
|
||||
@@ -175,8 +195,31 @@ export default function RemindersPage() {
|
||||
<span className="text-xs text-indigo-600 dark:text-indigo-400 ml-2">{nextDueLabel(r)}</span>
|
||||
)}
|
||||
</div>
|
||||
{r.lastSentAt && (
|
||||
<p className="text-xs text-green-600 dark:text-green-400 mt-0.5 flex items-center gap-1">
|
||||
<CheckCircle2 className="w-3 h-3" />
|
||||
Pris {formatDistanceToNow(new Date(r.lastSentAt), { locale: fr, addSuffix: true })}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-1.5 flex-shrink-0">
|
||||
{r.lastSentAt ? (
|
||||
<button
|
||||
onClick={() => unmarkTaken(r.id)}
|
||||
title="Annuler la prise"
|
||||
className="w-8 h-8 flex items-center justify-center rounded-lg text-green-500 hover:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-800 transition"
|
||||
>
|
||||
<RotateCcw className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
onClick={() => markTaken(r.id)}
|
||||
title="Marquer comme pris"
|
||||
className="w-8 h-8 flex items-center justify-center rounded-lg text-slate-400 hover:text-green-600 hover:bg-green-50 dark:hover:bg-green-950 transition"
|
||||
>
|
||||
<CheckCircle2 className="w-4 h-4" />
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={() => toggleEnabled(r.id, r.enabled)}
|
||||
className={`w-9 h-5 rounded-full transition relative overflow-hidden ${r.enabled ? "bg-green-500" : "bg-slate-200 dark:bg-slate-700"}`}
|
||||
|
||||
Reference in New Issue
Block a user