ux: dashboard grouping, responsive grids, grouped nav drawer, modal polish

Dashboard:
- Split 12-item quick-log into two labeled groups (Alimentation & Soins / Sommeil & Activités)
- "Voir tout →" link on today's timeline when events present
- Quick-log button: hover highlight indigo instead of grey for clearer affordance

Event modal:
- Timer: text-3xl on mobile, text-4xl on sm+ (prevents overflow on narrow screens)
- Date/time inputs: CalendarDays + Clock icons inline in each field for clarity

Stats:
- Today summary 3-col: gap-2 md:gap-3, p-3 md:p-4, text-xl md:text-2xl (no text clipping on mobile)
- Sleep/feeding summary grids: gap-2 md:gap-4

Calendar:
- Cell min-height: 52px mobile, 64px sm+ (reduces grid height on small screens)
- Day detail: events sorted by time, duration shown as HH:mm → HH:mm for ranged events
- Empty day state uses card container instead of bare text

Medications:
- Empty state: Pill icon + subtitle copy, centred card

Milk:
- Used/archived section: "… et N lots de plus" indicator when > 20 items

Nav drawer (mobile):
- Grouped secondary links: Suivi / Santé / Vie du bébé sections with section headers
- Medications: correct Pill icon (was duplicating Bell/Stethoscope)
- Ungrouped items fall through to a full-width list row

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 15:36:54 +02:00
parent 42c580d7e2
commit 63effbf85b
7 changed files with 168 additions and 88 deletions
+42 -37
View File
@@ -11,19 +11,15 @@ import { format, isToday } from "date-fns";
import { fr } from "date-fns/locale";
import { AlertTriangle, Clock, CheckCircle2, Pin, PinOff, Pencil, Check, X, Plus, Trash2 } from "lucide-react";
const QUICK_LOG_TYPES: EventType[] = [
"BREASTFEED",
"BOTTLE",
"PUMP",
"DIAPER_WET",
"DIAPER_STOOL",
"NAP",
"NIGHT_SLEEP",
"MEDICATION",
"TEMPERATURE",
"BATH",
"WALK",
"TUMMY_TIME",
const QUICK_LOG_GROUPS: { label: string; types: EventType[] }[] = [
{
label: "Alimentation & Soins",
types: ["BREASTFEED", "BOTTLE", "PUMP", "DIAPER_WET", "DIAPER_STOOL", "MEDICATION", "TEMPERATURE"],
},
{
label: "Sommeil & Activités",
types: ["NAP", "NIGHT_SLEEP", "BATH", "WALK", "TUMMY_TIME"],
},
];
interface Event {
@@ -405,27 +401,31 @@ export default function DashboardPage() {
</div>
{/* Quick log */}
<div>
<h2 className="text-xs font-semibold text-slate-400 dark:text-slate-500 uppercase tracking-wider mb-3">Enregistrer</h2>
<div className="grid grid-cols-4 md:grid-cols-4 gap-2">
{QUICK_LOG_TYPES.map((type) => {
const cfg = EVENT_CONFIG[type];
return (
<button
key={type}
onClick={() => setActiveModal(type)}
className="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 hover:border-slate-300 hover:shadow-sm rounded-xl p-3 flex flex-col items-center gap-2 transition active:scale-95"
>
<div className={`w-9 h-9 rounded-lg ${cfg.bgClass} flex items-center justify-center`}>
<EventIcon name={cfg.icon} className={`w-5 h-5 ${cfg.colorClass}`} />
</div>
<span className="text-[10px] font-medium text-slate-600 dark:text-slate-300 text-center leading-tight">
{cfg.label}
</span>
</button>
);
})}
</div>
<div className="space-y-4">
{QUICK_LOG_GROUPS.map((group) => (
<div key={group.label}>
<h2 className="text-xs font-semibold text-slate-400 dark:text-slate-500 uppercase tracking-wider mb-2">{group.label}</h2>
<div className="grid grid-cols-4 gap-2">
{group.types.map((type) => {
const cfg = EVENT_CONFIG[type];
return (
<button
key={type}
onClick={() => setActiveModal(type)}
className="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 hover:border-indigo-200 dark:hover:border-indigo-700 hover:shadow-sm rounded-xl p-2.5 flex flex-col items-center gap-1.5 transition active:scale-95"
>
<div className={`w-9 h-9 rounded-lg ${cfg.bgClass} flex items-center justify-center`}>
<EventIcon name={cfg.icon} className={`w-5 h-5 ${cfg.colorClass}`} />
</div>
<span className="text-[10px] font-medium text-slate-600 dark:text-slate-300 text-center leading-tight">
{cfg.label}
</span>
</button>
);
})}
</div>
</div>
))}
</div>
</div>
@@ -483,9 +483,14 @@ export default function DashboardPage() {
{/* Today's timeline */}
{todayEvents.length > 0 && (
<div className="mt-6">
<h2 className="text-xs font-semibold text-slate-400 dark:text-slate-500 uppercase tracking-wider mb-3">
Aujourd&apos;hui · {todayEvents.length} événement{todayEvents.length > 1 ? "s" : ""}
</h2>
<div className="flex items-center justify-between mb-3">
<h2 className="text-xs font-semibold text-slate-400 dark:text-slate-500 uppercase tracking-wider">
Aujourd&apos;hui · {todayEvents.length} événement{todayEvents.length > 1 ? "s" : ""}
</h2>
<a href="/timeline" className="text-xs text-indigo-600 dark:text-indigo-400 hover:underline">
Voir tout
</a>
</div>
<div className="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden divide-y divide-slate-100 dark:divide-slate-700">
{todayEvents.slice(0, 10).map((ev) => {
const cfg = EVENT_CONFIG[ev.type];