From 621e1c90f983c401ac65b160c710721e62eef1f4 Mon Sep 17 00:00:00 2001 From: colinislit Date: Thu, 4 Dec 2025 09:09:23 +0100 Subject: [PATCH] =?UTF-8?q?=20=20|=20Epic=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20|=20Status=20=20=20=20=20=20=20=20|=20Wat=20is?= =?UTF-8?q?=20gedaan=20=20=20=20=20=20=20|=20=20=20|---------------------|?= =?UTF-8?q?---------------|---------------------|=20=20=20|=20E0:=20Founda?= =?UTF-8?q?tion=20=20=20=20=20=20|=20=E2=9C=85=20Afgerond=20=20=20=20|=20T?= =?UTF-8?q?ypes=20+=20DB=20migratie=20|=20=20=20|=20E1:=20Leefgebieden=20?= =?UTF-8?q?=20=20=20|=20=E2=9C=85=20Afgerond=20=20=20=20|=203=20componente?= =?UTF-8?q?n=20=20=20=20=20=20=20|=20=20=20|=20E2:=20AI=20Generatie=20=20?= =?UTF-8?q?=20=20|=20=E2=8F=B3=20Nog=20te=20doen=20|=20-=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20|=20=20=20|=20E3:=20Beha?= =?UTF-8?q?ndelplan=20UI=20|=20=E2=8F=B3=20Nog=20te=20doen=20|=20-=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gemaakte bestanden: - lib/types/leefgebieden.ts - 7 domeinen met kleuren/emoji's - lib/types/behandelplan.ts - SMART doelen, interventies, Zod schemas - components/behandelplan/leefgebieden-form.tsx - Intake formulier - components/behandelplan/leefgebieden-scores.tsx - Score weergave - components/behandelplan/leefgebieden-badge.tsx - Domain badges - components/behandelplan/index.ts - Exports --- components/behandelplan/index.ts | 14 + .../behandelplan/leefgebieden-badge.tsx | 77 ++ components/behandelplan/leefgebieden-form.tsx | 368 +++++++++ .../behandelplan/leefgebieden-scores.tsx | 186 +++++ components/ui/badge.tsx | 36 + components/ui/card.tsx | 76 ++ components/ui/label.tsx | 26 + components/ui/progress.tsx | 28 + components/ui/slider.tsx | 28 + components/ui/tabs.tsx | 55 ++ components/ui/textarea.tsx | 22 + .../behandelplan/bouwplan-behandelplan-v1.md | 438 +++++++++++ docs/specs/behandelplan/fo-behandelplan-v1.md | 566 ++++++++++++++ .../behandelplan/prd-behandelplan-v2-final.md | 2 +- docs/specs/behandelplan/to-behandelplan-v1.md | 719 ++++++++++++++++++ docs/templates/bouwplan_template.md | 4 +- docs/templates/fo_template.md | 2 +- docs/templates/prd_template.md | 2 +- lib/types/behandelplan.ts | 370 +++++++++ lib/types/leefgebieden.ts | 167 ++++ package.json | 4 + pnpm-lock.yaml | 191 ++++- 22 files changed, 3369 insertions(+), 12 deletions(-) create mode 100644 components/behandelplan/index.ts create mode 100644 components/behandelplan/leefgebieden-badge.tsx create mode 100644 components/behandelplan/leefgebieden-form.tsx create mode 100644 components/behandelplan/leefgebieden-scores.tsx create mode 100644 components/ui/badge.tsx create mode 100644 components/ui/card.tsx create mode 100644 components/ui/label.tsx create mode 100644 components/ui/progress.tsx create mode 100644 components/ui/slider.tsx create mode 100644 components/ui/tabs.tsx create mode 100644 components/ui/textarea.tsx create mode 100644 docs/specs/behandelplan/bouwplan-behandelplan-v1.md create mode 100644 docs/specs/behandelplan/fo-behandelplan-v1.md create mode 100644 docs/specs/behandelplan/to-behandelplan-v1.md create mode 100644 lib/types/behandelplan.ts create mode 100644 lib/types/leefgebieden.ts diff --git a/components/behandelplan/index.ts b/components/behandelplan/index.ts new file mode 100644 index 0000000..7b15f0c --- /dev/null +++ b/components/behandelplan/index.ts @@ -0,0 +1,14 @@ +/** + * Behandelplan Components + * + * Export all behandelplan-related components + */ + +// Leefgebieden (Life Domains) +export { LeefgebiedenBadge, LeefgebiedenBadgeGroup } from './leefgebieden-badge'; +export { + LeefgebiedenScores, + LeefgebiedenScoresCard, + LeefgebiedenScoreBar, +} from './leefgebieden-scores'; +export { LeefgebiedenForm, LeefgebiedenQuickForm } from './leefgebieden-form'; diff --git a/components/behandelplan/leefgebieden-badge.tsx b/components/behandelplan/leefgebieden-badge.tsx new file mode 100644 index 0000000..f74dbeb --- /dev/null +++ b/components/behandelplan/leefgebieden-badge.tsx @@ -0,0 +1,77 @@ +'use client'; + +import { Badge } from '@/components/ui/badge'; +import { cn } from '@/lib/utils'; +import { type LifeDomain, LIFE_DOMAIN_META } from '@/lib/types/leefgebieden'; + +interface LeefgebiedenBadgeProps { + domain: LifeDomain; + showEmoji?: boolean; + size?: 'sm' | 'md' | 'lg'; + className?: string; +} + +/** + * Colored badge for a life domain + * Uses the domain's specific color from the meta definition + */ +export function LeefgebiedenBadge({ + domain, + showEmoji = true, + size = 'md', + className, +}: LeefgebiedenBadgeProps) { + const meta = LIFE_DOMAIN_META[domain]; + + const sizeClasses = { + sm: 'text-xs px-1.5 py-0.5', + md: 'text-sm px-2 py-0.5', + lg: 'text-base px-3 py-1', + }; + + return ( + + {showEmoji && {meta.emoji}} + {meta.shortLabel} + + ); +} + +interface LeefgebiedenBadgeGroupProps { + domains: LifeDomain[]; + showEmoji?: boolean; + size?: 'sm' | 'md' | 'lg'; + className?: string; +} + +/** + * Group of life domain badges + */ +export function LeefgebiedenBadgeGroup({ + domains, + showEmoji = true, + size = 'sm', + className, +}: LeefgebiedenBadgeGroupProps) { + if (domains.length === 0) return null; + + return ( +
+ {domains.map((domain) => ( + + ))} +
+ ); +} diff --git a/components/behandelplan/leefgebieden-form.tsx b/components/behandelplan/leefgebieden-form.tsx new file mode 100644 index 0000000..446d5cb --- /dev/null +++ b/components/behandelplan/leefgebieden-form.tsx @@ -0,0 +1,368 @@ +'use client'; + +import { useState, useCallback } from 'react'; +import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; +import { Label } from '@/components/ui/label'; +import { Slider } from '@/components/ui/slider'; +import { Textarea } from '@/components/ui/textarea'; +import { Button } from '@/components/ui/button'; +import { cn } from '@/lib/utils'; +import { + type LifeDomainScore, + type LifeDomain, + type Priority, + LIFE_DOMAIN_META, + LIFE_DOMAINS, + createDefaultLifeDomainScores, + getScoreColor, +} from '@/lib/types/leefgebieden'; + +interface DomainFormRowProps { + score: LifeDomainScore; + onChange: (score: LifeDomainScore) => void; + expanded?: boolean; + onToggleExpand?: () => void; +} + +const SCORE_LABELS: Record = { + 1: 'Zeer laag', + 2: 'Laag', + 3: 'Gemiddeld', + 4: 'Goed', + 5: 'Uitstekend', +}; + +const PRIORITY_OPTIONS: { value: Priority; label: string; color: string }[] = [ + { value: 'laag', label: 'Laag', color: 'bg-gray-200 text-gray-700' }, + { value: 'middel', label: 'Middel', color: 'bg-blue-100 text-blue-700' }, + { value: 'hoog', label: 'Hoog', color: 'bg-orange-100 text-orange-700' }, +]; + +/** + * Single domain row in the form + */ +function DomainFormRow({ + score, + onChange, + expanded = false, + onToggleExpand, +}: DomainFormRowProps) { + const meta = LIFE_DOMAIN_META[score.domain]; + + const handleBaselineChange = (values: number[]) => { + onChange({ ...score, baseline: values[0], current: values[0] }); + }; + + const handleTargetChange = (values: number[]) => { + onChange({ ...score, target: values[0] }); + }; + + const handlePriorityChange = (priority: Priority) => { + onChange({ ...score, priority }); + }; + + const handleNotesChange = (notes: string) => { + onChange({ ...score, notes }); + }; + + return ( +
+ {/* Header Row */} +
+
+
+ {meta.emoji} +
+
+

{meta.label}

+

{meta.description}

+
+
+
+
+
+ + {score.baseline} + + β†’ + + {score.target} + +
+ + {SCORE_LABELS[score.baseline]} + +
+ + + +
+
+ + {/* Expanded Content */} + {expanded && ( +
+ {/* Baseline Score Slider */} +
+
+ + {score.baseline} +
+ +
+ Zeer laag + Uitstekend +
+
+ + {/* Target Score Slider */} +
+
+ + {score.target} +
+ +
+ Zeer laag + Uitstekend +
+
+ + {/* Priority Selection */} +
+ +
+ {PRIORITY_OPTIONS.map((option) => ( + + ))} +
+
+ + {/* Notes */} +
+ +