feat: finish all UI/UX improvements from backlog

- nav: aria-label on baby switcher select
- dashboard: active timers show baby name
- growth: PDF export includes percentile band per weight row
- settings: invite link note (permanent, reset if compromised)
- timeline: select mode toggle shows "Annuler" when active
- photos: delete photo from lightbox (PATCHes event metadata)
- notes: invisible date input overlay for date-jump via calendar picker
- IMPROVEMENTS.md: updated checkboxes, 8 remaining → 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-15 20:58:57 +02:00
parent 8f68eebeb0
commit b40694d691
8 changed files with 102 additions and 42 deletions
+27 -5
View File
@@ -1,12 +1,12 @@
"use client";
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useBaby } from "@/contexts/baby-context";
import { EVENT_CONFIG, EventType } from "@/lib/event-config";
import { format, isToday, isYesterday } from "date-fns";
import { fr } from "date-fns/locale";
import { X, ChevronLeft, ChevronRight, Camera } from "lucide-react";
import { X, ChevronLeft, ChevronRight, Camera, Trash2 } from "lucide-react";
import Image from "next/image";
interface PhotoEvent {
@@ -27,6 +27,7 @@ function dayLabel(key: string): string {
export default function PhotosPage() {
const { selectedBaby } = useBaby();
const qc = useQueryClient();
const [lightbox, setLightbox] = useState<{ events: PhotoEvent[]; index: number } | null>(null);
const { data, isLoading } = useQuery({
@@ -67,6 +68,19 @@ export default function PhotosPage() {
const current = lightbox ? lightbox.events[lightbox.index] : null;
async function deletePhoto(eventId: string) {
const res = await fetch(`/api/events/${eventId}`);
const ev = await res.json();
const existingMeta = ev.metadata ?? {};
await fetch(`/api/events/${eventId}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ metadata: { ...existingMeta, photo: null } }),
});
qc.invalidateQueries({ queryKey: ["photo-events", selectedBaby?.id] });
setLightbox(null);
}
return (
<div className="p-4 md:p-8 pb-24 md:pb-8">
<h1 className="text-2xl font-bold text-slate-900 dark:text-slate-100 mb-6">
@@ -134,9 +148,17 @@ export default function PhotosPage() {
</p>
{current.notes && <p className="text-white/80 text-xs mt-0.5 italic">{current.notes}</p>}
</div>
<button onClick={() => setLightbox(null)} className="w-9 h-9 flex items-center justify-center rounded-full bg-white/10 hover:bg-white/20 transition">
<X className="w-5 h-5 text-white" />
</button>
<div className="flex items-center gap-2">
<button
onClick={() => { if (confirm("Supprimer cette photo ?")) deletePhoto(current.id); }}
className="w-9 h-9 flex items-center justify-center rounded-full bg-black/50 hover:bg-red-600/80 transition"
>
<Trash2 className="w-5 h-5 text-white" />
</button>
<button onClick={() => setLightbox(null)} className="w-9 h-9 flex items-center justify-center rounded-full bg-white/10 hover:bg-white/20 transition">
<X className="w-5 h-5 text-white" />
</button>
</div>
</div>
{/* Image */}