fix: dark mode event colors, sidebar height, calendar default, photo badge

- event-config: all bgClass/borderClass get dark:bg-*-950/50 + dark:border-*-800 variants — fixes bright pastel backgrounds in dark mode
- nav: h-screen → h-[100dvh] — fixes sidebar bottom buttons hidden behind mobile browser chrome
- calendar: selectedDay defaults to today, never null — events shown immediately on load
- timeline + dashboard: photo indicator (ImageIcon) on events with metadata.photo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-15 22:22:32 +02:00
parent cd3efa98fc
commit c28fa8188f
5 changed files with 47 additions and 41 deletions
+11 -11
View File
@@ -45,19 +45,21 @@ export default function CalendarPage() {
const days = eachDayOfInterval({ start: calStart, end: calEnd });
const [selectedDay, setSelectedDay] = useState<Date | null>(null);
const [selectedDay, setSelectedDay] = useState<Date>(() => new Date());
const dayEvents = (day: Date) => events.filter((e) => isSameDay(new Date(e.startedAt), day));
const selectedDayEvents = selectedDay ? dayEvents(selectedDay) : [];
const selectedDayEvents = dayEvents(selectedDay);
function prevMonth() {
setCursor(new Date(cursor.getFullYear(), cursor.getMonth() - 1, 1));
setSelectedDay(null);
const first = new Date(cursor.getFullYear(), cursor.getMonth() - 1, 1);
setCursor(first);
setSelectedDay(first);
}
function nextMonth() {
setCursor(new Date(cursor.getFullYear(), cursor.getMonth() + 1, 1));
setSelectedDay(null);
const first = new Date(cursor.getFullYear(), cursor.getMonth() + 1, 1);
setCursor(first);
setSelectedDay(first);
}
return (
@@ -75,7 +77,7 @@ export default function CalendarPage() {
className="w-9 h-9 rounded-lg flex items-center justify-center text-slate-500 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-800 transition">
<ChevronLeft className="w-5 h-5" />
</button>
<button onClick={() => { setCursor(new Date()); setSelectedDay(null); }}
<button onClick={() => { setCursor(new Date()); setSelectedDay(new Date()); }}
className="px-3 py-1.5 text-xs font-medium text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg transition">
Aujourd&apos;hui
</button>
@@ -102,13 +104,13 @@ export default function CalendarPage() {
{days.map((day, i) => {
const inMonth = day.getMonth() === cursor.getMonth();
const evs = dayEvents(day);
const isSelected = selectedDay ? isSameDay(day, selectedDay) : false;
const isSelected = isSameDay(day, selectedDay);
const today = isToday(day);
return (
<button
key={i}
onClick={() => setSelectedDay(isSameDay(day, selectedDay ?? new Date(0)) ? null : day)}
onClick={() => setSelectedDay(day)}
className={`min-h-[52px] sm:min-h-[64px] p-1 sm:p-1.5 text-left border-b border-r border-slate-100 dark:border-slate-800 last:border-r-0 transition ${
isSelected
? "bg-indigo-50 dark:bg-indigo-950"
@@ -146,7 +148,6 @@ export default function CalendarPage() {
</div>
{/* Selected day detail */}
{selectedDay && (
<div className="mt-4">
<div className="flex items-baseline justify-between mb-3">
<h2 className="text-sm font-semibold text-slate-700 dark:text-slate-200 capitalize">
@@ -189,7 +190,6 @@ export default function CalendarPage() {
</div>
)}
</div>
)}
{!selectedBaby && (
<div className="text-center py-16 text-slate-400 dark:text-slate-500">
+4 -1
View File
@@ -9,7 +9,7 @@ import { useBaby } from "@/contexts/baby-context";
import { checkFeedAlert, getThresholds } from "@/lib/notifications";
import { format, isToday } from "date-fns";
import { fr } from "date-fns/locale";
import { AlertTriangle, Clock, CheckCircle2, Pin, PinOff, Pencil, Check, X, Plus, Trash2, FileText } from "lucide-react";
import { AlertTriangle, Clock, CheckCircle2, Pin, PinOff, Pencil, Check, X, Plus, Trash2, FileText, ImageIcon } from "lucide-react";
import { useSession } from "next-auth/react";
const QUICK_LOG_GROUPS: { label: string; types: EventType[] }[] = [
@@ -790,6 +790,9 @@ export default function DashboardPage() {
<span className="text-xs text-slate-400 dark:text-slate-500 ml-2">{getEventSummary(ev)}</span>
)}
</div>
{typeof ev.metadata?.photo === "string" && ev.metadata.photo && (
<ImageIcon className="w-3.5 h-3.5 text-slate-400 dark:text-slate-500 flex-shrink-0" />
)}
<span className="text-xs text-slate-400 dark:text-slate-500 flex-shrink-0 font-mono">
{format(new Date(ev.startedAt), "HH:mm")}
</span>
+4 -1
View File
@@ -8,7 +8,7 @@ import { EventIcon } from "@/components/event-icon";
import { useBaby } from "@/contexts/baby-context";
import { format, isToday, isYesterday } from "date-fns";
import { fr } from "date-fns/locale";
import { Trash2, StickyNote, Pencil, CheckSquare, Square, XCircle } from "lucide-react";
import { Trash2, StickyNote, Pencil, CheckSquare, Square, XCircle, ImageIcon } from "lucide-react";
import Image from "next/image";
import { EventModal } from "@/components/event-modal";
@@ -271,6 +271,9 @@ export default function TimelinePage() {
{summary && <span className="text-xs text-slate-400 dark:text-slate-500 ml-2">{summary}</span>}
{ev.notes && <p className="text-xs text-slate-400 dark:text-slate-500 truncate mt-0.5 italic">{ev.notes}</p>}
</div>
{typeof ev.metadata?.photo === "string" && ev.metadata.photo && (
<ImageIcon className="w-3.5 h-3.5 text-slate-400 dark:text-slate-500 flex-shrink-0" />
)}
<span className="text-xs text-slate-400 dark:text-slate-500 flex-shrink-0 font-mono">
{format(new Date(ev.startedAt), "HH:mm")}
</span>
+1 -1
View File
@@ -117,7 +117,7 @@ export function SidebarNav() {
const { babies, selectedBaby, setSelectedBabyId } = useBaby();
return (
<aside className="hidden md:flex flex-col w-[220px] border-r border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 fixed left-0 top-0 h-screen z-20">
<aside className="hidden md:flex flex-col w-[220px] border-r border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 fixed left-0 top-0 h-[100dvh] z-20">
{/* Brand */}
<div className="px-5 py-4 border-b border-slate-100 dark:border-slate-700">
<div className="flex items-center gap-2">
+26 -26
View File
@@ -32,8 +32,8 @@ export const EVENT_CONFIG: Record<
icon: "Heart",
color: "#f43f5e",
colorClass: "text-rose-500",
bgClass: "bg-rose-50",
borderClass: "border-rose-200",
bgClass: "bg-rose-50 dark:bg-rose-950/50",
borderClass: "border-rose-200 dark:border-rose-800",
hasDuration: true,
hasTimer: true,
defaultDurationMin: 15,
@@ -43,8 +43,8 @@ export const EVENT_CONFIG: Record<
icon: "GlassWater",
color: "#3b82f6",
colorClass: "text-blue-500",
bgClass: "bg-blue-50",
borderClass: "border-blue-200",
bgClass: "bg-blue-50 dark:bg-blue-950/50",
borderClass: "border-blue-200 dark:border-blue-800",
hasDuration: false,
hasTimer: false,
},
@@ -53,8 +53,8 @@ export const EVENT_CONFIG: Record<
icon: "Milk",
color: "#0891b2",
colorClass: "text-cyan-600",
bgClass: "bg-cyan-50",
borderClass: "border-cyan-200",
bgClass: "bg-cyan-50 dark:bg-cyan-950/50",
borderClass: "border-cyan-200 dark:border-cyan-800",
hasDuration: true,
hasTimer: true,
defaultDurationMin: 15,
@@ -64,8 +64,8 @@ export const EVENT_CONFIG: Record<
icon: "Droplets",
color: "#06b6d4",
colorClass: "text-cyan-500",
bgClass: "bg-cyan-50",
borderClass: "border-cyan-200",
bgClass: "bg-cyan-50 dark:bg-cyan-950/50",
borderClass: "border-cyan-200 dark:border-cyan-800",
hasDuration: false,
hasTimer: false,
},
@@ -74,8 +74,8 @@ export const EVENT_CONFIG: Record<
icon: "CircleDot",
color: "#d97706",
colorClass: "text-amber-600",
bgClass: "bg-amber-50",
borderClass: "border-amber-200",
bgClass: "bg-amber-50 dark:bg-amber-950/50",
borderClass: "border-amber-200 dark:border-amber-800",
hasDuration: false,
hasTimer: false,
},
@@ -84,8 +84,8 @@ export const EVENT_CONFIG: Record<
icon: "Sunset",
color: "#7c3aed",
colorClass: "text-violet-600",
bgClass: "bg-violet-50",
borderClass: "border-violet-200",
bgClass: "bg-violet-50 dark:bg-violet-950/50",
borderClass: "border-violet-200 dark:border-violet-800",
hasDuration: true,
hasTimer: true,
defaultDurationMin: 45,
@@ -95,8 +95,8 @@ export const EVENT_CONFIG: Record<
icon: "Moon",
color: "#4338ca",
colorClass: "text-indigo-700",
bgClass: "bg-indigo-50",
borderClass: "border-indigo-200",
bgClass: "bg-indigo-50 dark:bg-indigo-950/50",
borderClass: "border-indigo-200 dark:border-indigo-800",
hasDuration: true,
hasTimer: true,
defaultDurationMin: 480,
@@ -106,8 +106,8 @@ export const EVENT_CONFIG: Record<
icon: "Pill",
color: "#16a34a",
colorClass: "text-green-600",
bgClass: "bg-green-50",
borderClass: "border-green-200",
bgClass: "bg-green-50 dark:bg-green-950/50",
borderClass: "border-green-200 dark:border-green-800",
hasDuration: false,
hasTimer: false,
},
@@ -116,8 +116,8 @@ export const EVENT_CONFIG: Record<
icon: "Thermometer",
color: "#dc2626",
colorClass: "text-red-600",
bgClass: "bg-red-50",
borderClass: "border-red-200",
bgClass: "bg-red-50 dark:bg-red-950/50",
borderClass: "border-red-200 dark:border-red-800",
hasDuration: false,
hasTimer: false,
},
@@ -126,8 +126,8 @@ export const EVENT_CONFIG: Record<
icon: "Bath",
color: "#0284c7",
colorClass: "text-sky-600",
bgClass: "bg-sky-50",
borderClass: "border-sky-200",
bgClass: "bg-sky-50 dark:bg-sky-950/50",
borderClass: "border-sky-200 dark:border-sky-800",
hasDuration: true,
hasTimer: true,
defaultDurationMin: 10,
@@ -137,8 +137,8 @@ export const EVENT_CONFIG: Record<
icon: "Footprints",
color: "#65a30d",
colorClass: "text-lime-600",
bgClass: "bg-lime-50",
borderClass: "border-lime-200",
bgClass: "bg-lime-50 dark:bg-lime-950/50",
borderClass: "border-lime-200 dark:border-lime-800",
hasDuration: true,
hasTimer: true,
defaultDurationMin: 30,
@@ -148,8 +148,8 @@ export const EVENT_CONFIG: Record<
icon: "Baby",
color: "#d97706",
colorClass: "text-amber-600",
bgClass: "bg-amber-50",
borderClass: "border-amber-200",
bgClass: "bg-amber-50 dark:bg-amber-950/50",
borderClass: "border-amber-200 dark:border-amber-800",
hasDuration: true,
hasTimer: true,
defaultDurationMin: 5,
@@ -159,8 +159,8 @@ export const EVENT_CONFIG: Record<
icon: "Activity",
color: "#dc2626",
colorClass: "text-red-600",
bgClass: "bg-red-50",
borderClass: "border-red-200",
bgClass: "bg-red-50 dark:bg-red-950/50",
borderClass: "border-red-200 dark:border-red-800",
hasDuration: false,
hasTimer: false,
},