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 */} +
+ +