feat: maintenance banner, activities log, pinned note, event templates, weekly summary cron

Maintenance mode banner:
- App layout reads SystemConfig maintenance_mode at server render time
- Amber sticky banner for regular users, dimmed indicator for superadmin

Baby activities (3 new event types):
- BATH (Bath icon, sky, timer+duration)
- WALK / Balade (Footprints icon, lime)
- TUMMY_TIME (Baby icon, amber)
- Added to EventType enum, EVENT_CONFIG, event-icon.tsx, dashboard quick-log

Pinned family note:
- Shared across all family members, shown at top of dashboard
- Inline edit with author + timestamp; /api/family/pinned-note GET/PATCH
- pinnedNote + pinnedNoteUpdatedAt + pinnedNoteAuthor fields on Family model

Event templates:
- Named quick-log presets per family (type + label + metadata)
- Dashboard row: tap to open pre-filled EventModal; hover ✕ to delete
- Dropdown to create new template; /api/event-templates GET/POST + /[id] PATCH/DELETE
- EventTemplate model in schema

Weekly summary cron:
- POST /api/cron/weekly-summary — auth via Bearer cron_secret (SystemConfig or env)
- Per family, per baby: feeds count, sleep total+avg, diaper count, latest weight
- Sends Pushover to all family members with pushoverUserKey
- Optional body.familyId to target one family

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 15:08:54 +02:00
parent 020539e2e2
commit 42c580d7e2
10 changed files with 570 additions and 15 deletions
+34 -1
View File
@@ -7,7 +7,10 @@ export type EventType =
| "NAP"
| "NIGHT_SLEEP"
| "MEDICATION"
| "TEMPERATURE";
| "TEMPERATURE"
| "BATH"
| "WALK"
| "TUMMY_TIME";
export const EVENT_CONFIG: Record<
EventType,
@@ -112,6 +115,36 @@ export const EVENT_CONFIG: Record<
hasDuration: false,
hasTimer: false,
},
BATH: {
label: "Bain",
icon: "Bath",
color: "#0284c7",
colorClass: "text-sky-600",
bgClass: "bg-sky-50",
borderClass: "border-sky-200",
hasDuration: true,
hasTimer: true,
},
WALK: {
label: "Balade",
icon: "Footprints",
color: "#65a30d",
colorClass: "text-lime-600",
bgClass: "bg-lime-50",
borderClass: "border-lime-200",
hasDuration: true,
hasTimer: true,
},
TUMMY_TIME: {
label: "Tummy time",
icon: "Baby",
color: "#d97706",
colorClass: "text-amber-600",
bgClass: "bg-amber-50",
borderClass: "border-amber-200",
hasDuration: true,
hasTimer: true,
},
};
export const ALL_EVENT_TYPES = Object.keys(EVENT_CONFIG) as EventType[];