feat: per-baby breastfeeding and pump feature toggles

Add isBreastfed and hasPump flags to Baby model. When disabled,
hide breastfeeding/pump options from quick-add FAB, dashboard
counters and quick-log groups, and the milk stock nav link.
Settings page gains toggle UI to configure per baby.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-19 11:51:41 +02:00
parent 319d70c3a4
commit f2cc181ece
8 changed files with 67 additions and 28 deletions
+22 -22
View File
@@ -12,24 +12,21 @@ import { fr } from "date-fns/locale";
import { AlertTriangle, Clock, CheckCircle2, Pin, PinOff, Pencil, Check, X, Plus, FileText, ImageIcon } from "lucide-react";
import { useSession } from "next-auth/react";
const QUICK_LOG_GROUPS: { label: string; types: EventType[] }[] = [
{
label: "Alimentation & Soins",
types: ["BREASTFEED", "BOTTLE", "PUMP", "DIAPER_WET", "DIAPER_STOOL"],
},
{
label: "Sommeil & Activités",
types: ["NAP", "NIGHT_SLEEP", "BATH", "WALK", "TUMMY_TIME"],
},
{
label: "Santé",
types: ["TEMPERATURE", "MEDICATION", "SYMPTOM"],
},
{
label: "Autre",
types: ["OTHER"],
},
];
function buildQuickLogGroups(isBreastfed: boolean, hasPump: boolean): { label: string; types: EventType[] }[] {
const feedTypes: EventType[] = [
...(isBreastfed ? (["BREASTFEED"] as EventType[]) : []),
"BOTTLE",
...(hasPump ? (["PUMP"] as EventType[]) : []),
"DIAPER_WET",
"DIAPER_STOOL",
];
return [
{ label: "Alimentation & Soins", types: feedTypes },
{ label: "Sommeil & Activis", types: ["NAP", "NIGHT_SLEEP", "BATH", "WALK", "TUMMY_TIME"] },
{ label: "Santé", types: ["TEMPERATURE", "MEDICATION", "SYMPTOM"] },
{ label: "Autre", types: ["OTHER"] },
];
}
interface Event {
id: string;
@@ -434,7 +431,7 @@ export default function DashboardPage() {
queryKey: ["events-feeds", selectedBaby?.id],
queryFn: () =>
fetch(`/api/events?babyId=${selectedBaby!.id}&limit=100&type=BREASTFEED`).then((r) => r.json()),
enabled: !!selectedBaby?.id,
enabled: !!selectedBaby?.id && (selectedBaby?.isBreastfed ?? true),
staleTime: 60_000,
});
const { data: bottleData } = useQuery({
@@ -577,8 +574,11 @@ export default function DashboardPage() {
</div>
{/* Today's summary counters */}
<div className="grid grid-cols-4 gap-3 mb-6">
{(["BREASTFEED", "BOTTLE", "DIAPER_WET", "DIAPER_STOOL"] as EventType[]).map((t) => {
<div className={`grid gap-3 mb-6 ${selectedBaby.isBreastfed ? "grid-cols-4" : "grid-cols-3"}`}>
{(["BREASTFEED", "BOTTLE", "DIAPER_WET", "DIAPER_STOOL"] as EventType[]).filter((t) => {
if (t === "BREASTFEED" && !selectedBaby.isBreastfed) return false;
return true;
}).map((t) => {
const cfg = EVENT_CONFIG[t];
return (
<div key={t} className="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl p-3 text-center">
@@ -673,7 +673,7 @@ export default function DashboardPage() {
{/* Quick log */}
<div className="space-y-4">
{QUICK_LOG_GROUPS.map((group) => (
{buildQuickLogGroups(selectedBaby.isBreastfed, selectedBaby.hasPump).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 sm:grid-cols-6 gap-2">