@burdenoff/microfe-brainyrich 2026.828.1 → 2026.830.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/brainyrich/BrainyRichRoot.d.ts.map +1 -1
  2. package/dist/brainyrich/BrainyRichRoot.js +59 -59
  3. package/dist/brainyrich/BrainyRichRoot.js.map +1 -1
  4. package/dist/brainyrich/components/viz.d.ts.map +1 -1
  5. package/dist/brainyrich/components/viz.js +149 -148
  6. package/dist/brainyrich/components/viz.js.map +1 -1
  7. package/dist/brainyrich/hooks/useTr.d.ts +17 -0
  8. package/dist/brainyrich/hooks/useTr.d.ts.map +1 -0
  9. package/dist/brainyrich/hooks/useTr.js +14 -0
  10. package/dist/brainyrich/hooks/useTr.js.map +1 -0
  11. package/dist/brainyrich/pages/AiAssistantPage.js +192 -192
  12. package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
  13. package/dist/brainyrich/pages/AnalyticsPage.d.ts.map +1 -1
  14. package/dist/brainyrich/pages/AnalyticsPage.js +253 -252
  15. package/dist/brainyrich/pages/AnalyticsPage.js.map +1 -1
  16. package/dist/brainyrich/pages/DashboardPage.js +115 -115
  17. package/dist/brainyrich/pages/DashboardPage.js.map +1 -1
  18. package/dist/brainyrich/pages/FamilyPage.js +59 -59
  19. package/dist/brainyrich/pages/FamilyPage.js.map +1 -1
  20. package/dist/brainyrich/pages/GoalsPage.js +285 -285
  21. package/dist/brainyrich/pages/GoalsPage.js.map +1 -1
  22. package/dist/brainyrich/pages/InvestmentsPage.js +18 -18
  23. package/dist/brainyrich/pages/InvestmentsPage.js.map +1 -1
  24. package/dist/brainyrich/pages/PortfoliosPage.d.ts.map +1 -1
  25. package/dist/brainyrich/pages/PortfoliosPage.js +477 -471
  26. package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
  27. package/dist/brainyrich/pages/ReportsPage.js +52 -52
  28. package/dist/brainyrich/pages/ReportsPage.js.map +1 -1
  29. package/dist/brainyrich/pages/RiskPage.d.ts.map +1 -1
  30. package/dist/brainyrich/pages/RiskPage.js +272 -271
  31. package/dist/brainyrich/pages/RiskPage.js.map +1 -1
  32. package/dist/brainyrich/pages/TaxPage.d.ts.map +1 -1
  33. package/dist/brainyrich/pages/TaxPage.js +198 -197
  34. package/dist/brainyrich/pages/TaxPage.js.map +1 -1
  35. package/dist/brainyrich/pages/_shared.d.ts.map +1 -1
  36. package/dist/brainyrich/pages/_shared.js +84 -82
  37. package/dist/brainyrich/pages/_shared.js.map +1 -1
  38. package/dist/brainyrich/types/bra.d.ts.map +1 -1
  39. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"GoalsPage.js","names":[],"sources":["../../../src/brainyrich/pages/GoalsPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n AlertTriangle,\n CalendarClock,\n Coins,\n Link2,\n LineChart,\n MoreHorizontal,\n PiggyBank,\n Plus,\n RefreshCw,\n Target,\n Trash2,\n TrendingDown,\n TrendingUp,\n Unlink,\n Wallet,\n} from 'lucide-react';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n ConfirmDialog,\n FadeIn,\n GlassCard,\n LoadMore,\n MiniAreaChart,\n ProgressRing,\n StatTile,\n type AreaDatum,\n type VizTone,\n} from '../components';\nimport { TagField } from '../components/reuse/TagField';\nimport { hapticSuccess, showToast } from '../utils/nativeControls';\nimport { useTrackBrainyRichPageView } from '../hooks/useBrainyRichAnalytics';\nimport {\n useAccounts,\n useArchiveGoal,\n useCreateGoal,\n useGoal,\n useGoalFundings,\n useHouseholds,\n useLinkGoalFunding,\n usePagedGoals,\n useRecalcGoalProjection,\n useUnlinkGoalFunding,\n useUpdateGoal,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraCreateGoalInput,\n BraGoal,\n BraGoalFunding,\n BraGoalProjection,\n BraGoalStatus,\n BraGoalType,\n BraUpdateGoalInput,\n} from '../types/bra';\nimport {\n EmptyState,\n ErrorState,\n LoadingState,\n SectionShell,\n formatCompact,\n formatDate,\n formatMoney,\n formatPct,\n statusBadgeVariant,\n} from './_shared';\n\nconst GOAL_TYPES: BraGoalType[] = [\n 'RETIREMENT',\n 'EDUCATION',\n 'HOME',\n 'EMERGENCY_FUND',\n 'MAJOR_PURCHASE',\n 'WEALTH_GROWTH',\n 'CUSTOM',\n];\n\nconst GOAL_STATUSES: BraGoalStatus[] = ['ACTIVE', 'ACHIEVED', 'ON_HOLD', 'ABANDONED'];\n\ninterface ProjectionMeta {\n icon: typeof TrendingUp;\n tone: string;\n}\n\nfunction projectionMeta(projection: BraGoalProjection): ProjectionMeta {\n switch (projection) {\n case 'AHEAD':\n case 'ON_TRACK':\n return { icon: TrendingUp, tone: 'text-status-success-text' };\n case 'BEHIND':\n return { icon: TrendingDown, tone: 'text-status-warning-text' };\n case 'AT_RISK':\n default:\n return { icon: AlertTriangle, tone: 'text-status-error-text' };\n }\n}\n\nfunction humanize(value: string): string {\n return value\n .toLowerCase()\n .split('_')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n}\n\n/** Sum of the fixed-amount funding links wired to a goal (real backend value). */\nfunction goalFixedFunded(goal: Pick<BraGoal, 'fundings'>): number {\n return goal.fundings.reduce((s, f) => s + (f.fixedAmount ?? 0), 0);\n}\n\n/**\n * Funded-progress percentage for a goal. ACHIEVED goals read 100%; otherwise the\n * sum of fixed funding links over the target — every input is wired backend data,\n * never fabricated.\n */\nfunction fundedPercent(goal: Pick<BraGoal, 'fundings' | 'targetAmount' | 'status'>): number {\n if (goal.status === 'ACHIEVED') return 100;\n if (!(goal.targetAmount > 0)) return 0;\n return Math.max(0, Math.min(100, (goalFixedFunded(goal) / goal.targetAmount) * 100));\n}\n\n/** Ring/accent tone derived from the goal's real status + projection. */\nfunction goalTone(status: BraGoalStatus, projection: BraGoalProjection): VizTone {\n if (status === 'ACHIEVED') return 'success';\n switch (projection) {\n case 'AHEAD':\n case 'ON_TRACK':\n return 'brand';\n case 'BEHIND':\n return 'warning';\n case 'AT_RISK':\n default:\n return 'error';\n }\n}\n\n/**\n * A deterministic contribution trajectory from today to the target date, computed\n * purely from wired fields: starting funded balance + monthly contribution × month.\n * No randomness, no fabricated series — just the arithmetic funding path the user\n * has configured. Returns [] when there is nothing meaningful to chart.\n */\nfunction buildProjectionSeries(\n funded: number,\n monthly: number,\n targetIso?: string | null\n): AreaDatum[] {\n if (!targetIso) return [];\n const target = new Date(targetIso);\n if (Number.isNaN(target.getTime())) return [];\n const now = new Date();\n const totalMonths =\n (target.getFullYear() - now.getFullYear()) * 12 + (target.getMonth() - now.getMonth());\n if (totalMonths <= 0) return [];\n const steps = Math.min(Math.max(totalMonths, 2), 12);\n const fmt = new Intl.DateTimeFormat('en-US', { month: 'short', year: '2-digit' });\n const points: AreaDatum[] = [];\n for (let i = 0; i <= steps; i += 1) {\n const m = Math.round((totalMonths / steps) * i);\n const at = new Date(now.getFullYear(), now.getMonth() + m, 1);\n points.push({ x: fmt.format(at), y: Math.round(funded + monthly * m) });\n }\n return points;\n}\n\n/** yyyy-mm-dd for a date input, guarded against absent/invalid ISO strings. */\nfunction toDateInput(iso?: string | null): string {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toISOString().slice(0, 10);\n}\n\ninterface GoalFormState {\n name: string;\n type: BraGoalType;\n status: BraGoalStatus;\n targetAmount: string;\n targetDate: string;\n monthlyContribution: string;\n priority: string;\n currency: string;\n householdId: string;\n notes: string;\n}\n\nfunction emptyForm(): GoalFormState {\n return {\n name: '',\n type: 'CUSTOM',\n status: 'ACTIVE',\n targetAmount: '',\n targetDate: '',\n monthlyContribution: '',\n priority: '1',\n currency: 'USD',\n householdId: '',\n notes: '',\n };\n}\n\nfunction formFromGoal(goal: BraGoal): GoalFormState {\n return {\n name: goal.name,\n type: goal.type,\n status: goal.status,\n targetAmount: String(goal.targetAmount),\n targetDate: toDateInput(goal.targetDate),\n monthlyContribution: String(goal.monthlyContribution),\n priority: String(goal.priority),\n currency: goal.currency,\n householdId: goal.householdId ?? '',\n notes: goal.notes ?? '',\n };\n}\n\nconst HOUSEHOLD_NONE = '__none__';\n\nexport function GoalsPage() {\n const { t } = useI18n();\n const translate = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n\n useTrackBrainyRichPageView('brainyrich.goals.viewed');\n\n const {\n items: goals,\n hasMore,\n loadMore,\n isFetchingNextPage,\n isLoading,\n isError,\n refetch,\n } = usePagedGoals();\n const { data: households } = useHouseholds();\n\n const createGoal = useCreateGoal();\n const updateGoal = useUpdateGoal();\n const archiveGoal = useArchiveGoal();\n\n const [createOpen, setCreateOpen] = useState(false);\n const [editing, setEditing] = useState<BraGoal | null>(null);\n const [detailId, setDetailId] = useState<string | null>(null);\n const [archiving, setArchiving] = useState<BraGoal | null>(null);\n const [form, setForm] = useState<GoalFormState>(emptyForm);\n\n const setField = <K extends keyof GoalFormState>(key: K, value: GoalFormState[K]) =>\n setForm((prev) => ({ ...prev, [key]: value }));\n\n const totals = useMemo(() => {\n const totalTarget = goals.reduce((s, g) => s + g.targetAmount, 0);\n const totalMonthly = goals.reduce((s, g) => s + g.monthlyContribution, 0);\n const atRisk = goals.filter(\n (g) => g.projection === 'AT_RISK' || g.projection === 'BEHIND'\n ).length;\n return { totalTarget, totalMonthly, atRisk };\n }, [goals]);\n\n const currency = goals[0]?.currency ?? 'USD';\n\n const openCreate = () => {\n setForm(emptyForm());\n setCreateOpen(true);\n };\n\n const openEdit = (goal: BraGoal) => {\n setForm(formFromGoal(goal));\n setEditing(goal);\n };\n\n const formValid =\n form.name.trim().length > 0 && Number(form.targetAmount) > 0 && form.targetDate.length > 0;\n\n const handleCreate = () => {\n if (!formValid) return;\n const input: BraCreateGoalInput = {\n name: form.name.trim(),\n type: form.type,\n targetAmount: Number(form.targetAmount),\n targetDate: new Date(form.targetDate).toISOString(),\n monthlyContribution: Number(form.monthlyContribution) || 0,\n priority: Number(form.priority) || 1,\n currency: form.currency.trim() || 'USD',\n notes: form.notes.trim() || null,\n tags: [],\n ...(form.householdId ? { householdId: form.householdId } : {}),\n };\n createGoal.mutate(input, {\n onSuccess: () => {\n hapticSuccess();\n void showToast(translate('brainyrich.goals.created', 'Goal created'));\n setCreateOpen(false);\n },\n });\n };\n\n const handleUpdate = () => {\n if (!editing || !formValid) return;\n const input: BraUpdateGoalInput = {\n name: form.name.trim(),\n type: form.type,\n status: form.status,\n targetAmount: Number(form.targetAmount),\n targetDate: new Date(form.targetDate).toISOString(),\n monthlyContribution: Number(form.monthlyContribution) || 0,\n priority: Number(form.priority) || 1,\n currency: form.currency.trim() || 'USD',\n notes: form.notes.trim() || null,\n // Legacy `tags` scalar preserved as-is; the canonical tag surface is <TagField>.\n tags: editing.tags,\n };\n updateGoal.mutate(\n { id: editing.id, input },\n {\n onSuccess: () => {\n hapticSuccess();\n void showToast(translate('brainyrich.goals.saved', 'Goal saved'));\n setEditing(null);\n },\n }\n );\n };\n\n const body = () => {\n if (isLoading) return <LoadingState rows={4} />;\n if (isError)\n return (\n <ErrorState\n title={translate('brainyrich.goals.error.title', 'Could not load goals')}\n description={translate(\n 'brainyrich.goals.error.description',\n 'We could not reach the goals service. Please try again.'\n )}\n onRetry={() => refetch()}\n />\n );\n if (goals.length === 0)\n return (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.goals.empty.title', 'No financial goals yet')}\n description={translate(\n 'brainyrich.goals.empty.description',\n 'Create your first goal to start tracking progress toward a milestone.'\n )}\n action={\n <Button size=\"sm\" onClick={openCreate}>\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.createGoal', 'New goal')}\n </Button>\n }\n />\n );\n\n return (\n <>\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <FadeIn index={0}>\n <StatTile\n glow\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.activeGoals', 'Goals')}\n value={String(goals.length)}\n />\n </FadeIn>\n <FadeIn index={1}>\n <StatTile\n icon={<PiggyBank className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.totalTarget', 'Total target')}\n value={formatMoney(totals.totalTarget, currency)}\n />\n </FadeIn>\n <FadeIn index={2}>\n <StatTile\n icon={<Coins className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.monthly', 'Monthly contributions')}\n value={formatMoney(totals.totalMonthly, currency)}\n />\n </FadeIn>\n <FadeIn index={3}>\n <StatTile\n icon={<AlertTriangle className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.atRisk', 'Needs attention')}\n value={String(totals.atRisk)}\n className={totals.atRisk > 0 ? 'ring-1 ring-status-error-text/30' : undefined}\n />\n </FadeIn>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {goals.map((g, i) => {\n const proj = projectionMeta(g.projection);\n const ProjIcon = proj.icon;\n const tone = goalTone(g.status, g.projection);\n const pct = fundedPercent(g);\n const achieved = g.status === 'ACHIEVED';\n return (\n <FadeIn key={g.id} index={i}>\n <Card\n className={`group flex h-full flex-col transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))] ${\n achieved ? 'ring-1 ring-status-success-text/30' : ''\n }`}\n >\n <CardHeader className=\"pb-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Target\n className=\"size-4 shrink-0 text-text-secondary\"\n aria-hidden=\"true\"\n />\n <span className=\"truncate\">{g.name}</span>\n </CardTitle>\n <CardDescription className=\"mt-1 flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\">{humanize(g.type)}</Badge>\n <Badge variant={statusBadgeVariant(g.status)}>{humanize(g.status)}</Badge>\n </CardDescription>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={translate('brainyrich.goals.actions.menu', 'Goal actions')}\n >\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onSelect={() => setDetailId(g.id)}>\n <Link2 className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.manageFunding', 'Manage funding')}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => openEdit(g)}>\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.editGoal', 'Edit goal')}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"text-status-error-text focus:text-status-error-text\"\n onSelect={() => setArchiving(g)}\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.archive', 'Archive goal')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </CardHeader>\n <CardContent className=\"flex flex-1 flex-col gap-4\">\n <div className=\"flex items-center gap-4\">\n <ProgressRing\n value={pct}\n tone={tone}\n size={92}\n strokeWidth={9}\n label={translate('brainyrich.goals.card.funded', 'funded')}\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.target', 'Target amount')}\n </p>\n <p className=\"truncate text-2xl font-semibold text-text-primary\">\n {formatMoney(g.targetAmount, g.currency)}\n </p>\n <span\n className={`mt-1 inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium ${proj.tone}`}\n >\n <ProjIcon className=\"size-3.5\" aria-hidden=\"true\" />\n {humanize(g.projection)}\n </span>\n </div>\n </div>\n\n <dl className=\"grid grid-cols-2 gap-3 rounded-lg bg-bg-sunken p-3 text-sm\">\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.targetDate', 'Target date')}\n </dt>\n <dd className=\"flex items-center gap-1 font-medium text-text-primary\">\n <CalendarClock\n className=\"size-3.5 text-text-secondary\"\n aria-hidden=\"true\"\n />\n {formatDate(g.targetDate)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.monthly', 'Monthly')}\n </dt>\n <dd className=\"font-medium text-text-primary\">\n {formatMoney(g.monthlyContribution, g.currency)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.priority', 'Priority')}\n </dt>\n <dd className=\"font-medium text-text-primary\">{g.priority}</dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.fundings', 'Funding links')}\n </dt>\n <dd className=\"font-medium text-text-primary\">{g.fundings.length}</dd>\n </div>\n </dl>\n\n <div className=\"mt-auto\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => setDetailId(g.id)}\n >\n {translate(\n 'brainyrich.goals.actions.viewDetails',\n 'View details & funding'\n )}\n </Button>\n </div>\n </CardContent>\n </Card>\n </FadeIn>\n );\n })}\n </div>\n\n <LoadMore\n hasMore={hasMore}\n loading={isFetchingNextPage}\n onClick={loadMore}\n label={translate('brainyrich.goals.actions.loadMore', 'Load more goals')}\n loadingLabel={translate('brainyrich.goals.actions.loadingMore', 'Loading…')}\n />\n </>\n );\n };\n\n return (\n <div data-tour=\"brainyrich-page-goals\" className=\"contents\">\n <SectionShell\n title={translate('brainyrich.goals.title', 'Financial Goals')}\n description={translate(\n 'brainyrich.goals.description',\n 'Track progress toward your wealth milestones and life objectives'\n )}\n actionLabel={translate('brainyrich.goals.actions.createGoal', 'New goal')}\n onAction={openCreate}\n >\n {body()}\n </SectionShell>\n\n <GoalFormDialog\n open={createOpen}\n mode=\"create\"\n form={form}\n setField={setField}\n households={households.map((h) => ({ id: h.id, name: h.name }))}\n valid={formValid}\n pending={createGoal.isPending}\n onSubmit={handleCreate}\n onOpenChange={(v) => setCreateOpen(v)}\n translate={translate}\n />\n\n <GoalFormDialog\n open={Boolean(editing)}\n mode=\"edit\"\n goalId={editing?.id}\n form={form}\n setField={setField}\n households={households.map((h) => ({ id: h.id, name: h.name }))}\n valid={formValid}\n pending={updateGoal.isPending}\n onSubmit={handleUpdate}\n onOpenChange={(v) => {\n if (!v) setEditing(null);\n }}\n translate={translate}\n />\n\n <GoalDetailSheet goalId={detailId} onClose={() => setDetailId(null)} translate={translate} />\n\n <ConfirmDialog\n open={Boolean(archiving)}\n onOpenChange={(o) => {\n if (!o) setArchiving(null);\n }}\n title={translate('brainyrich.goals.archive.title', 'Archive goal?')}\n description={translate(\n 'brainyrich.goals.archive.description',\n 'This removes “{name}” from your active goals. You can no longer track its progress.',\n { name: archiving?.name ?? '' }\n )}\n confirmLabel={translate('brainyrich.goals.archive.confirm', 'Archive goal')}\n pendingLabel={translate('brainyrich.goals.archive.pending', 'Archiving…')}\n destructive\n pending={archiveGoal.isPending}\n onConfirm={() => {\n if (!archiving) return;\n archiveGoal.mutate(archiving.id, {\n onSuccess: () => {\n hapticSuccess();\n void showToast(\n translate('brainyrich.goals.archived', 'Goal archived', { name: archiving.name })\n );\n setArchiving(null);\n },\n });\n }}\n />\n </div>\n );\n}\n\ntype Translate = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>\n) => string;\n\ninterface GoalFormDialogProps {\n open: boolean;\n mode: 'create' | 'edit';\n goalId?: string;\n form: GoalFormState;\n setField: <K extends keyof GoalFormState>(key: K, value: GoalFormState[K]) => void;\n households: { id: string; name: string }[];\n valid: boolean;\n pending: boolean;\n onSubmit: () => void;\n onOpenChange: (open: boolean) => void;\n translate: Translate;\n}\n\nfunction GoalFormDialog({\n open,\n mode,\n goalId,\n form,\n setField,\n households,\n valid,\n pending,\n onSubmit,\n onOpenChange,\n translate,\n}: GoalFormDialogProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-h-[90vh] overflow-y-auto sm:max-w-lg\">\n <DialogHeader>\n <DialogTitle>\n {mode === 'create'\n ? translate('brainyrich.goals.form.createTitle', 'New goal')\n : translate('brainyrich.goals.form.editTitle', 'Edit goal')}\n </DialogTitle>\n <DialogDescription>\n {translate(\n 'brainyrich.goals.form.subtitle',\n 'Define the milestone, target and contribution plan.'\n )}\n </DialogDescription>\n </DialogHeader>\n\n <form\n className=\"space-y-4\"\n onSubmit={(e) => {\n e.preventDefault();\n onSubmit();\n }}\n >\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-name\">{translate('brainyrich.goals.form.name', 'Name')}</Label>\n <Input\n id=\"goal-name\"\n value={form.name}\n onChange={(e) => setField('name', e.target.value)}\n placeholder={translate(\n 'brainyrich.goals.form.namePlaceholder',\n 'e.g. Retirement fund'\n )}\n required\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-type\">{translate('brainyrich.goals.form.type', 'Type')}</Label>\n <Select value={form.type} onValueChange={(v) => setField('type', v as BraGoalType)}>\n <SelectTrigger id=\"goal-type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {GOAL_TYPES.map((tpe) => (\n <SelectItem key={tpe} value={tpe}>\n {humanize(tpe)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {mode === 'edit' ? (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-status\">\n {translate('brainyrich.goals.form.status', 'Status')}\n </Label>\n <Select\n value={form.status}\n onValueChange={(v) => setField('status', v as BraGoalStatus)}\n >\n <SelectTrigger id=\"goal-status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {GOAL_STATUSES.map((st) => (\n <SelectItem key={st} value={st}>\n {humanize(st)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-priority\">\n {translate('brainyrich.goals.form.priority', 'Priority')}\n </Label>\n <Input\n id=\"goal-priority\"\n type=\"number\"\n min={1}\n value={form.priority}\n onChange={(e) => setField('priority', e.target.value)}\n />\n </div>\n )}\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-target\">\n {translate('brainyrich.goals.form.targetAmount', 'Target amount')}\n </Label>\n <Input\n id=\"goal-target\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={form.targetAmount}\n onChange={(e) => setField('targetAmount', e.target.value)}\n required\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-date\">\n {translate('brainyrich.goals.form.targetDate', 'Target date')}\n </Label>\n <Input\n id=\"goal-date\"\n type=\"date\"\n value={form.targetDate}\n onChange={(e) => setField('targetDate', e.target.value)}\n required\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-monthly\">\n {translate('brainyrich.goals.form.monthly', 'Monthly contribution')}\n </Label>\n <Input\n id=\"goal-monthly\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={form.monthlyContribution}\n onChange={(e) => setField('monthlyContribution', e.target.value)}\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-currency\">\n {translate('brainyrich.goals.form.currency', 'Currency')}\n </Label>\n <Input\n id=\"goal-currency\"\n value={form.currency}\n onChange={(e) => setField('currency', e.target.value.toUpperCase())}\n maxLength={3}\n />\n </div>\n </div>\n\n {mode === 'edit' ? (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-priority-edit\">\n {translate('brainyrich.goals.form.priority', 'Priority')}\n </Label>\n <Input\n id=\"goal-priority-edit\"\n type=\"number\"\n min={1}\n value={form.priority}\n onChange={(e) => setField('priority', e.target.value)}\n />\n </div>\n ) : null}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-household\">\n {translate('brainyrich.goals.form.household', 'Household (optional)')}\n </Label>\n <Select\n value={form.householdId || HOUSEHOLD_NONE}\n onValueChange={(v) => setField('householdId', v === HOUSEHOLD_NONE ? '' : v)}\n >\n <SelectTrigger id=\"goal-household\">\n <SelectValue\n placeholder={translate('brainyrich.goals.form.householdNone', 'None')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={HOUSEHOLD_NONE}>\n {translate('brainyrich.goals.form.householdNone', 'None')}\n </SelectItem>\n {households.map((h) => (\n <SelectItem key={h.id} value={h.id}>\n {h.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {mode === 'edit' && goalId ? (\n <TagField\n entityType=\"brainyrich-goal\"\n entityId={goalId}\n label={translate('brainyrich.goals.form.tags', 'Tags')}\n />\n ) : (\n <div className=\"space-y-1.5\">\n <Label>{translate('brainyrich.goals.form.tags', 'Tags')}</Label>\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.form.tagsAfterCreate',\n 'You can add tags after creating the goal.'\n )}\n </p>\n </div>\n )}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-notes\">{translate('brainyrich.goals.form.notes', 'Notes')}</Label>\n <Textarea\n id=\"goal-notes\"\n value={form.notes}\n onChange={(e) => setField('notes', e.target.value)}\n rows={3}\n />\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n disabled={pending}\n >\n {translate('brainyrich.goals.form.cancel', 'Cancel')}\n </Button>\n <Button type=\"submit\" disabled={!valid || pending}>\n {pending\n ? translate('brainyrich.goals.form.saving', 'Saving…')\n : mode === 'create'\n ? translate('brainyrich.goals.form.create', 'Create goal')\n : translate('brainyrich.goals.form.save', 'Save changes')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\ntype FundingMode = 'PERCENT' | 'FIXED';\n\ninterface GoalDetailSheetProps {\n goalId: string | null;\n onClose: () => void;\n translate: Translate;\n}\n\nfunction GoalDetailSheet({ goalId, onClose, translate }: GoalDetailSheetProps) {\n const { data: goal, isLoading, isError, refetch } = useGoal(goalId ?? undefined);\n const { data: fundings } = useGoalFundings(goalId ?? undefined);\n const { data: accounts } = useAccounts();\n\n const linkFunding = useLinkGoalFunding();\n const unlinkFunding = useUnlinkGoalFunding();\n const recalc = useRecalcGoalProjection();\n\n const [accountId, setAccountId] = useState('');\n const [fundingMode, setFundingMode] = useState<FundingMode>('PERCENT');\n const [fundingValue, setFundingValue] = useState('');\n const [fundedAmount, setFundedAmount] = useState('');\n const [unlinking, setUnlinking] = useState<BraGoalFunding | null>(null);\n\n const fixedFunded = fundings.reduce((s, f) => s + (f.fixedAmount ?? 0), 0);\n const currency = goal?.currency ?? 'USD';\n const fundedPct = goal ? fundedPercent(goal) : 0;\n const tone: VizTone = goal ? goalTone(goal.status, goal.projection) : 'brand';\n const projectionSeries = goal\n ? buildProjectionSeries(fixedFunded, goal.monthlyContribution, goal.targetDate)\n : [];\n\n const accountName = (id: string) => accounts.find((a) => a.id === id)?.name ?? id;\n\n const handleLink = () => {\n if (!goalId || !accountId) return;\n const numeric = Number(fundingValue);\n if (!Number.isFinite(numeric) || numeric <= 0) return;\n linkFunding.mutate(\n {\n goalId,\n accountId,\n ...(fundingMode === 'PERCENT' ? { allocationPct: numeric } : { fixedAmount: numeric }),\n },\n {\n onSuccess: () => {\n setAccountId('');\n setFundingValue('');\n },\n }\n );\n };\n\n const handleRecalc = () => {\n if (!goalId) return;\n const amount = fundedAmount === '' ? fixedFunded : Number(fundedAmount);\n if (!Number.isFinite(amount)) return;\n recalc.mutate({ id: goalId, fundedAmount: amount });\n };\n\n const linkValid = Boolean(accountId) && Number(fundingValue) > 0;\n\n const unlinkingLabel = unlinking\n ? unlinking.fixedAmount != null\n ? formatMoney(unlinking.fixedAmount, currency)\n : accountName(unlinking.accountId)\n : '';\n\n return (\n <>\n <Sheet\n open={Boolean(goalId)}\n onOpenChange={(v) => {\n if (!v) onClose();\n }}\n >\n <SheetContent className=\"flex w-full flex-col gap-0 overflow-y-auto sm:max-w-xl\">\n <SheetHeader>\n <SheetTitle>\n {goal?.name ?? translate('brainyrich.goals.detail.title', 'Goal')}\n </SheetTitle>\n <SheetDescription>\n {translate(\n 'brainyrich.goals.detail.subtitle',\n 'Manage funding links and projection.'\n )}\n </SheetDescription>\n </SheetHeader>\n\n <div className=\"space-y-6 p-4\">\n {isLoading ? (\n <LoadingState rows={3} />\n ) : isError ? (\n <ErrorState\n title={translate('brainyrich.goals.detail.error', 'Could not load goal')}\n onRetry={() => refetch()}\n />\n ) : !goal ? (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.goals.detail.notFound', 'Goal not found')}\n />\n ) : (\n <>\n {/* Hero: funded progress ring + headline */}\n <GlassCard glow className=\"flex items-center gap-5\">\n <ProgressRing\n value={fundedPct}\n tone={tone}\n size={116}\n strokeWidth={11}\n label={translate('brainyrich.goals.detail.funded', 'funded')}\n />\n <div className=\"min-w-0 flex-1 space-y-1\">\n <Badge variant={statusBadgeVariant(goal.projection)}>\n {humanize(goal.projection)}\n </Badge>\n <p className=\"text-2xl font-semibold text-text-primary\">\n {formatMoney(fixedFunded, currency)}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.detail.ofTarget', 'of {target} target', {\n target: formatCompact(goal.targetAmount, currency),\n })}\n </p>\n </div>\n </GlassCard>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <StatTile\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.target', 'Target')}\n value={formatMoney(goal.targetAmount, currency)}\n />\n <StatTile\n icon={<Wallet className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.funded', 'Funded (fixed)')}\n value={formatMoney(fixedFunded, currency)}\n />\n <StatTile\n icon={<Coins className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.monthly', 'Monthly')}\n value={formatMoney(goal.monthlyContribution, currency)}\n />\n <StatTile\n icon={<CalendarClock className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.targetDate', 'Target date')}\n value={formatDate(goal.targetDate)}\n />\n </div>\n\n {/* Projection trajectory toward the target line */}\n {projectionSeries.length >= 2 ? (\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex items-center gap-2\">\n <LineChart className=\"size-4 text-text-secondary\" aria-hidden=\"true\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate(\n 'brainyrich.goals.detail.projectionChart',\n 'Contribution projection'\n )}\n </h3>\n </div>\n <MiniAreaChart\n data={projectionSeries}\n target={goal.targetAmount}\n tone={tone}\n height={180}\n valueFormatter={(v) => formatCompact(v, currency)}\n />\n <p className=\"text-xs text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.projectionHint',\n 'Starting balance plus {monthly}/mo through {date}.',\n {\n monthly: formatMoney(goal.monthlyContribution, currency),\n date: formatDate(goal.targetDate),\n }\n )}\n </p>\n </section>\n ) : null}\n\n {/* Funding sources table */}\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.fundingLinks', 'Funding sources')}\n </h3>\n {fundings.length === 0 ? (\n <p className=\"rounded-lg border border-dashed border-border-subtle bg-bg-surface px-4 py-6 text-center text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.noFundings',\n 'No accounts linked to fund this goal yet.'\n )}\n </p>\n ) : (\n <div className=\"overflow-x-auto rounded-lg border border-border-subtle\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>\n {translate('brainyrich.goals.detail.account', 'Account')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.goals.detail.allocation', 'Allocation')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.goals.detail.fixedAmount', 'Fixed amount')}\n </TableHead>\n <TableHead className=\"w-10\" />\n </TableRow>\n </TableHeader>\n <TableBody>\n {fundings.map((f) => (\n <TableRow key={f.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {accountName(f.accountId)}\n </TableCell>\n <TableCell className=\"text-right tabular-nums text-text-secondary\">\n {f.fixedAmount == null ? formatPct(f.allocationPct) : '—'}\n </TableCell>\n <TableCell className=\"text-right tabular-nums text-text-secondary\">\n {f.fixedAmount != null ? formatMoney(f.fixedAmount, currency) : '—'}\n </TableCell>\n <TableCell className=\"text-right\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={translate(\n 'brainyrich.goals.detail.unlink',\n 'Unlink funding'\n )}\n onClick={() => setUnlinking(f)}\n >\n <Unlink className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </section>\n\n {/* Link a new funding */}\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.linkTitle', 'Link an account')}\n </h3>\n {accounts.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.noAccounts',\n 'No accounts available to link.'\n )}\n </p>\n ) : (\n <>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-account\">\n {translate('brainyrich.goals.detail.account', 'Account')}\n </Label>\n <Select value={accountId} onValueChange={setAccountId}>\n <SelectTrigger id=\"funding-account\">\n <SelectValue\n placeholder={translate(\n 'brainyrich.goals.detail.selectAccount',\n 'Select account'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n {accounts.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-mode\">\n {translate('brainyrich.goals.detail.mode', 'Method')}\n </Label>\n <Select\n value={fundingMode}\n onValueChange={(v) => setFundingMode(v as FundingMode)}\n >\n <SelectTrigger id=\"funding-mode\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"PERCENT\">\n {translate('brainyrich.goals.detail.percent', 'Percentage')}\n </SelectItem>\n <SelectItem value=\"FIXED\">\n {translate('brainyrich.goals.detail.fixed', 'Fixed amount')}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-value\">\n {fundingMode === 'PERCENT'\n ? translate('brainyrich.goals.detail.pct', 'Percent')\n : translate('brainyrich.goals.detail.amount', 'Amount')}\n </Label>\n <Input\n id=\"funding-value\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={fundingValue}\n onChange={(e) => setFundingValue(e.target.value)}\n />\n </div>\n </div>\n <Button\n size=\"sm\"\n className=\"w-full\"\n disabled={!linkValid || linkFunding.isPending}\n onClick={handleLink}\n >\n <Link2 className=\"size-4\" aria-hidden=\"true\" />\n {linkFunding.isPending\n ? translate('brainyrich.goals.detail.linking', 'Linking…')\n : translate('brainyrich.goals.detail.link', 'Link funding')}\n </Button>\n </>\n )}\n </section>\n\n {/* Tags */}\n <Card>\n <CardContent className=\"p-4\">\n <TagField\n entityType=\"brainyrich-goal\"\n entityId={goal.id}\n label={translate('brainyrich.goals.detail.tags', 'Tags')}\n />\n </CardContent>\n </Card>\n\n {/* Recalc projection */}\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.recalcTitle', 'Recalculate projection')}\n </h3>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"recalc-funded\">\n {translate('brainyrich.goals.detail.fundedAmount', 'Funded amount')}\n </Label>\n <Input\n id=\"recalc-funded\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={fundedAmount}\n placeholder={String(fixedFunded)}\n onChange={(e) => setFundedAmount(e.target.value)}\n />\n <p className=\"text-xs text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.recalcHint',\n 'Defaults to the sum of fixed fundings when left blank.'\n )}\n </p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"w-full\"\n disabled={recalc.isPending}\n onClick={handleRecalc}\n >\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n {recalc.isPending\n ? translate('brainyrich.goals.detail.recalculating', 'Recalculating…')\n : translate('brainyrich.goals.detail.recalc', 'Recalculate')}\n </Button>\n </section>\n </>\n )}\n </div>\n </SheetContent>\n </Sheet>\n\n <ConfirmDialog\n open={Boolean(unlinking)}\n onOpenChange={(o) => {\n if (!o) setUnlinking(null);\n }}\n title={translate('brainyrich.goals.detail.unlinkTitle', 'Unlink funding?')}\n description={translate(\n 'brainyrich.goals.detail.unlinkConfirm',\n 'This removes the “{name}” funding link from this goal.',\n { name: unlinkingLabel }\n )}\n confirmLabel={translate('brainyrich.goals.detail.unlink', 'Unlink funding')}\n pendingLabel={translate('brainyrich.goals.detail.unlinking', 'Unlinking…')}\n destructive\n pending={unlinkFunding.isPending}\n onConfirm={() => {\n if (!unlinking) return;\n unlinkFunding.mutate(unlinking.id, { onSuccess: () => setUnlinking(null) });\n }}\n />\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"GoalsPage.js","names":[],"sources":["../../../src/brainyrich/pages/GoalsPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n AlertTriangle,\n CalendarClock,\n Coins,\n Link2,\n LineChart,\n MoreHorizontal,\n PiggyBank,\n Plus,\n RefreshCw,\n Target,\n Trash2,\n TrendingDown,\n TrendingUp,\n Unlink,\n Wallet,\n} from 'lucide-react';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n ConfirmDialog,\n FadeIn,\n GlassCard,\n LoadMore,\n MiniAreaChart,\n ProgressRing,\n StatTile,\n type AreaDatum,\n type VizTone,\n} from '../components';\nimport { TagField } from '../components/reuse/TagField';\nimport { hapticSuccess, showToast } from '../utils/nativeControls';\nimport { useTrackBrainyRichPageView } from '../hooks/useBrainyRichAnalytics';\nimport {\n useAccounts,\n useArchiveGoal,\n useCreateGoal,\n useGoal,\n useGoalFundings,\n useHouseholds,\n useLinkGoalFunding,\n usePagedGoals,\n useRecalcGoalProjection,\n useUnlinkGoalFunding,\n useUpdateGoal,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraCreateGoalInput,\n BraGoal,\n BraGoalFunding,\n BraGoalProjection,\n BraGoalStatus,\n BraGoalType,\n BraUpdateGoalInput,\n} from '../types/bra';\nimport {\n EmptyState,\n ErrorState,\n LoadingState,\n SectionShell,\n formatCompact,\n formatDate,\n formatMoney,\n formatPct,\n statusBadgeVariant,\n} from './_shared';\n\nconst GOAL_TYPES: BraGoalType[] = [\n 'RETIREMENT',\n 'EDUCATION',\n 'HOME',\n 'EMERGENCY_FUND',\n 'MAJOR_PURCHASE',\n 'WEALTH_GROWTH',\n 'CUSTOM',\n];\n\nconst GOAL_STATUSES: BraGoalStatus[] = ['ACTIVE', 'ACHIEVED', 'ON_HOLD', 'ABANDONED'];\n\ninterface ProjectionMeta {\n icon: typeof TrendingUp;\n tone: string;\n}\n\nfunction projectionMeta(projection: BraGoalProjection): ProjectionMeta {\n switch (projection) {\n case 'AHEAD':\n case 'ON_TRACK':\n return { icon: TrendingUp, tone: 'text-status-success-text' };\n case 'BEHIND':\n return { icon: TrendingDown, tone: 'text-status-warning-text' };\n case 'AT_RISK':\n default:\n return { icon: AlertTriangle, tone: 'text-status-error-text' };\n }\n}\n\nfunction humanize(value: string): string {\n return value\n .toLowerCase()\n .split('_')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n}\n\n/** Sum of the fixed-amount funding links wired to a goal (real backend value). */\nfunction goalFixedFunded(goal: Pick<BraGoal, 'fundings'>): number {\n return goal.fundings.reduce((s, f) => s + (f.fixedAmount ?? 0), 0);\n}\n\n/**\n * Funded-progress percentage for a goal. ACHIEVED goals read 100%; otherwise the\n * sum of fixed funding links over the target — every input is wired backend data,\n * never fabricated.\n */\nfunction fundedPercent(goal: Pick<BraGoal, 'fundings' | 'targetAmount' | 'status'>): number {\n if (goal.status === 'ACHIEVED') return 100;\n if (!(goal.targetAmount > 0)) return 0;\n return Math.max(0, Math.min(100, (goalFixedFunded(goal) / goal.targetAmount) * 100));\n}\n\n/** Ring/accent tone derived from the goal's real status + projection. */\nfunction goalTone(status: BraGoalStatus, projection: BraGoalProjection): VizTone {\n if (status === 'ACHIEVED') return 'success';\n switch (projection) {\n case 'AHEAD':\n case 'ON_TRACK':\n return 'brand';\n case 'BEHIND':\n return 'warning';\n case 'AT_RISK':\n default:\n return 'error';\n }\n}\n\n/**\n * A deterministic contribution trajectory from today to the target date, computed\n * purely from wired fields: starting funded balance + monthly contribution × month.\n * No randomness, no fabricated series — just the arithmetic funding path the user\n * has configured. Returns [] when there is nothing meaningful to chart.\n */\nfunction buildProjectionSeries(\n funded: number,\n monthly: number,\n targetIso?: string | null\n): AreaDatum[] {\n if (!targetIso) return [];\n const target = new Date(targetIso);\n if (Number.isNaN(target.getTime())) return [];\n const now = new Date();\n const totalMonths =\n (target.getFullYear() - now.getFullYear()) * 12 + (target.getMonth() - now.getMonth());\n if (totalMonths <= 0) return [];\n const steps = Math.min(Math.max(totalMonths, 2), 12);\n const fmt = new Intl.DateTimeFormat('en-US', { month: 'short', year: '2-digit' });\n const points: AreaDatum[] = [];\n for (let i = 0; i <= steps; i += 1) {\n const m = Math.round((totalMonths / steps) * i);\n const at = new Date(now.getFullYear(), now.getMonth() + m, 1);\n points.push({ x: fmt.format(at), y: Math.round(funded + monthly * m) });\n }\n return points;\n}\n\n/** yyyy-mm-dd for a date input, guarded against absent/invalid ISO strings. */\nfunction toDateInput(iso?: string | null): string {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toISOString().slice(0, 10);\n}\n\ninterface GoalFormState {\n name: string;\n type: BraGoalType;\n status: BraGoalStatus;\n targetAmount: string;\n targetDate: string;\n monthlyContribution: string;\n priority: string;\n currency: string;\n householdId: string;\n notes: string;\n}\n\nfunction emptyForm(): GoalFormState {\n return {\n name: '',\n type: 'CUSTOM',\n status: 'ACTIVE',\n targetAmount: '',\n targetDate: '',\n monthlyContribution: '',\n priority: '1',\n currency: 'USD',\n householdId: '',\n notes: '',\n };\n}\n\nfunction formFromGoal(goal: BraGoal): GoalFormState {\n return {\n name: goal.name,\n type: goal.type,\n status: goal.status,\n targetAmount: String(goal.targetAmount),\n targetDate: toDateInput(goal.targetDate),\n monthlyContribution: String(goal.monthlyContribution),\n priority: String(goal.priority),\n currency: goal.currency,\n householdId: goal.householdId ?? '',\n notes: goal.notes ?? '',\n };\n}\n\nconst HOUSEHOLD_NONE = '__none__';\n\nexport function GoalsPage() {\n const { t } = useI18n();\n const translate = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n\n useTrackBrainyRichPageView('brainyrich.goals.viewed');\n\n const {\n items: goals,\n hasMore,\n loadMore,\n isFetchingNextPage,\n isLoading,\n isError,\n refetch,\n } = usePagedGoals();\n const { data: households } = useHouseholds();\n\n const createGoal = useCreateGoal();\n const updateGoal = useUpdateGoal();\n const archiveGoal = useArchiveGoal();\n\n const [createOpen, setCreateOpen] = useState(false);\n const [editing, setEditing] = useState<BraGoal | null>(null);\n const [detailId, setDetailId] = useState<string | null>(null);\n const [archiving, setArchiving] = useState<BraGoal | null>(null);\n const [form, setForm] = useState<GoalFormState>(emptyForm);\n\n const setField = <K extends keyof GoalFormState>(key: K, value: GoalFormState[K]) =>\n setForm((prev) => ({ ...prev, [key]: value }));\n\n const totals = useMemo(() => {\n const totalTarget = goals.reduce((s, g) => s + g.targetAmount, 0);\n const totalMonthly = goals.reduce((s, g) => s + g.monthlyContribution, 0);\n const atRisk = goals.filter(\n (g) => g.projection === 'AT_RISK' || g.projection === 'BEHIND'\n ).length;\n return { totalTarget, totalMonthly, atRisk };\n }, [goals]);\n\n const currency = goals[0]?.currency ?? 'USD';\n\n const openCreate = () => {\n setForm(emptyForm());\n setCreateOpen(true);\n };\n\n const openEdit = (goal: BraGoal) => {\n setForm(formFromGoal(goal));\n setEditing(goal);\n };\n\n const formValid =\n form.name.trim().length > 0 && Number(form.targetAmount) > 0 && form.targetDate.length > 0;\n\n const handleCreate = () => {\n if (!formValid) return;\n const input: BraCreateGoalInput = {\n name: form.name.trim(),\n type: form.type,\n targetAmount: Number(form.targetAmount),\n targetDate: new Date(form.targetDate).toISOString(),\n monthlyContribution: Number(form.monthlyContribution) || 0,\n priority: Number(form.priority) || 1,\n currency: form.currency.trim() || 'USD',\n notes: form.notes.trim() || null,\n tags: [],\n ...(form.householdId ? { householdId: form.householdId } : {}),\n };\n createGoal.mutate(input, {\n onSuccess: () => {\n hapticSuccess();\n void showToast(translate('brainyrich.goals.created', 'Goal created'));\n setCreateOpen(false);\n },\n });\n };\n\n const handleUpdate = () => {\n if (!editing || !formValid) return;\n const input: BraUpdateGoalInput = {\n name: form.name.trim(),\n type: form.type,\n status: form.status,\n targetAmount: Number(form.targetAmount),\n targetDate: new Date(form.targetDate).toISOString(),\n monthlyContribution: Number(form.monthlyContribution) || 0,\n priority: Number(form.priority) || 1,\n currency: form.currency.trim() || 'USD',\n notes: form.notes.trim() || null,\n // Legacy `tags` scalar preserved as-is; the canonical tag surface is <TagField>.\n tags: editing.tags,\n };\n updateGoal.mutate(\n { id: editing.id, input },\n {\n onSuccess: () => {\n hapticSuccess();\n void showToast(translate('brainyrich.goals.saved', 'Goal saved'));\n setEditing(null);\n },\n }\n );\n };\n\n const body = () => {\n if (isLoading) return <LoadingState rows={4} />;\n if (isError)\n return (\n <ErrorState\n title={translate('brainyrich.goals.error.title', 'Could not load goals')}\n description={translate(\n 'brainyrich.goals.error.description',\n 'We could not reach the goals service. Please try again.'\n )}\n onRetry={() => refetch()}\n />\n );\n if (goals.length === 0)\n return (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.goals.empty.title', 'No financial goals yet')}\n description={translate(\n 'brainyrich.goals.empty.description',\n 'Create your first goal to start tracking progress toward a milestone.'\n )}\n action={\n <Button size=\"sm\" onClick={openCreate}>\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.createGoal', 'New goal')}\n </Button>\n }\n />\n );\n\n return (\n <>\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <FadeIn index={0}>\n <StatTile\n glow\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.activeGoals', 'Goals')}\n value={String(goals.length)}\n />\n </FadeIn>\n <FadeIn index={1}>\n <StatTile\n icon={<PiggyBank className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.totalTarget', 'Total target')}\n value={formatMoney(totals.totalTarget, currency)}\n />\n </FadeIn>\n <FadeIn index={2}>\n <StatTile\n icon={<Coins className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.monthly', 'Monthly contributions')}\n value={formatMoney(totals.totalMonthly, currency)}\n />\n </FadeIn>\n <FadeIn index={3}>\n <StatTile\n icon={<AlertTriangle className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.atRisk', 'Needs attention')}\n value={String(totals.atRisk)}\n className={totals.atRisk > 0 ? 'ring-1 ring-status-error-text/30' : undefined}\n />\n </FadeIn>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {goals.map((g, i) => {\n const proj = projectionMeta(g.projection);\n const ProjIcon = proj.icon;\n const tone = goalTone(g.status, g.projection);\n const pct = fundedPercent(g);\n const achieved = g.status === 'ACHIEVED';\n return (\n <FadeIn key={g.id} index={i}>\n <Card\n className={`group flex h-full flex-col transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))] ${\n achieved ? 'ring-1 ring-status-success-text/30' : ''\n }`}\n >\n <CardHeader className=\"pb-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Target\n className=\"size-4 shrink-0 text-text-secondary\"\n aria-hidden=\"true\"\n />\n <span className=\"truncate\">{g.name}</span>\n </CardTitle>\n <CardDescription className=\"mt-1 flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\">{humanize(g.type)}</Badge>\n <Badge variant={statusBadgeVariant(g.status)}>{humanize(g.status)}</Badge>\n </CardDescription>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={translate('brainyrich.goals.actions.menu', 'Goal actions')}\n >\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onSelect={() => setDetailId(g.id)}>\n <Link2 className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.manageFunding', 'Manage funding')}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => openEdit(g)}>\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.editGoal', 'Edit goal')}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"text-status-error-text focus:text-status-error-text\"\n onSelect={() => setArchiving(g)}\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.archive', 'Archive goal')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </CardHeader>\n <CardContent className=\"flex flex-1 flex-col gap-4\">\n <div className=\"flex items-center gap-4\">\n <ProgressRing\n value={pct}\n tone={tone}\n size={92}\n strokeWidth={9}\n label={translate('brainyrich.goals.card.funded', 'funded')}\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.target', 'Target amount')}\n </p>\n <p className=\"truncate text-2xl font-semibold text-text-primary\">\n {formatMoney(g.targetAmount, g.currency)}\n </p>\n <span\n className={`mt-1 inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium ${proj.tone}`}\n >\n <ProjIcon className=\"size-3.5\" aria-hidden=\"true\" />\n {humanize(g.projection)}\n </span>\n </div>\n </div>\n\n <dl className=\"grid grid-cols-2 gap-3 rounded-lg bg-bg-sunken p-3 text-sm\">\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.targetDate', 'Target date')}\n </dt>\n <dd className=\"flex items-center gap-1 font-medium text-text-primary\">\n <CalendarClock\n className=\"size-3.5 text-text-secondary\"\n aria-hidden=\"true\"\n />\n {formatDate(g.targetDate)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.monthly', 'Monthly')}\n </dt>\n <dd className=\"font-medium text-text-primary\">\n {formatMoney(g.monthlyContribution, g.currency)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.priority', 'Priority')}\n </dt>\n <dd className=\"font-medium text-text-primary\">{g.priority}</dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.fundings', 'Funding links')}\n </dt>\n <dd className=\"font-medium text-text-primary\">{g.fundings.length}</dd>\n </div>\n </dl>\n\n <div className=\"mt-auto\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => setDetailId(g.id)}\n >\n {translate(\n 'brainyrich.goals.actions.viewDetails',\n 'View details & funding'\n )}\n </Button>\n </div>\n </CardContent>\n </Card>\n </FadeIn>\n );\n })}\n </div>\n\n <LoadMore\n hasMore={hasMore}\n loading={isFetchingNextPage}\n onClick={loadMore}\n label={translate('brainyrich.goals.actions.loadMore', 'Load more goals')}\n loadingLabel={translate('brainyrich.goals.actions.loadingMore', 'Loading…')}\n />\n </>\n );\n };\n\n return (\n <div data-tour=\"brainyrich-page-goals\" className=\"contents\">\n <SectionShell\n title={translate('brainyrich.goals.title', 'Financial Goals')}\n description={translate(\n 'brainyrich.goals.description',\n 'Track progress toward your wealth milestones and life objectives'\n )}\n actionLabel={translate('brainyrich.goals.actions.createGoal', 'New goal')}\n onAction={openCreate}\n >\n {body()}\n </SectionShell>\n\n <GoalFormDialog\n open={createOpen}\n mode=\"create\"\n form={form}\n setField={setField}\n households={households.map((h) => ({ id: h.id, name: h.name }))}\n valid={formValid}\n pending={createGoal.isPending}\n onSubmit={handleCreate}\n onOpenChange={(v) => setCreateOpen(v)}\n translate={translate}\n />\n\n <GoalFormDialog\n open={Boolean(editing)}\n mode=\"edit\"\n goalId={editing?.id}\n form={form}\n setField={setField}\n households={households.map((h) => ({ id: h.id, name: h.name }))}\n valid={formValid}\n pending={updateGoal.isPending}\n onSubmit={handleUpdate}\n onOpenChange={(v) => {\n if (!v) setEditing(null);\n }}\n translate={translate}\n />\n\n <GoalDetailSheet goalId={detailId} onClose={() => setDetailId(null)} translate={translate} />\n\n <ConfirmDialog\n open={Boolean(archiving)}\n onOpenChange={(o) => {\n if (!o) setArchiving(null);\n }}\n title={translate('brainyrich.goals.archive.title', 'Archive goal?')}\n description={translate(\n 'brainyrich.goals.archive.description',\n 'This removes “{name}” from your active goals. You can no longer track its progress.',\n { name: archiving?.name ?? '' }\n )}\n confirmLabel={translate('brainyrich.goals.archive.confirm', 'Archive goal')}\n pendingLabel={translate('brainyrich.goals.archive.pending', 'Archiving…')}\n destructive\n pending={archiveGoal.isPending}\n onConfirm={() => {\n if (!archiving) return;\n archiveGoal.mutate(archiving.id, {\n onSuccess: () => {\n hapticSuccess();\n void showToast(\n translate('brainyrich.goals.archived', 'Goal archived', { name: archiving.name })\n );\n setArchiving(null);\n },\n });\n }}\n />\n </div>\n );\n}\n\ntype Translate = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>\n) => string;\n\ninterface GoalFormDialogProps {\n open: boolean;\n mode: 'create' | 'edit';\n goalId?: string;\n form: GoalFormState;\n setField: <K extends keyof GoalFormState>(key: K, value: GoalFormState[K]) => void;\n households: { id: string; name: string }[];\n valid: boolean;\n pending: boolean;\n onSubmit: () => void;\n onOpenChange: (open: boolean) => void;\n translate: Translate;\n}\n\nfunction GoalFormDialog({\n open,\n mode,\n goalId,\n form,\n setField,\n households,\n valid,\n pending,\n onSubmit,\n onOpenChange,\n translate,\n}: GoalFormDialogProps) {\n return (\n <ResponsiveDialog open={open} onOpenChange={onOpenChange}>\n <ResponsiveDialogContent className=\"max-h-[90vh] overflow-y-auto sm:max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {mode === 'create'\n ? translate('brainyrich.goals.form.createTitle', 'New goal')\n : translate('brainyrich.goals.form.editTitle', 'Edit goal')}\n </ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {translate(\n 'brainyrich.goals.form.subtitle',\n 'Define the milestone, target and contribution plan.'\n )}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <form\n className=\"space-y-4\"\n onSubmit={(e) => {\n e.preventDefault();\n onSubmit();\n }}\n >\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-name\">{translate('brainyrich.goals.form.name', 'Name')}</Label>\n <Input\n id=\"goal-name\"\n value={form.name}\n onChange={(e) => setField('name', e.target.value)}\n placeholder={translate(\n 'brainyrich.goals.form.namePlaceholder',\n 'e.g. Retirement fund'\n )}\n required\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-type\">{translate('brainyrich.goals.form.type', 'Type')}</Label>\n <Select value={form.type} onValueChange={(v) => setField('type', v as BraGoalType)}>\n <SelectTrigger id=\"goal-type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {GOAL_TYPES.map((tpe) => (\n <SelectItem key={tpe} value={tpe}>\n {humanize(tpe)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {mode === 'edit' ? (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-status\">\n {translate('brainyrich.goals.form.status', 'Status')}\n </Label>\n <Select\n value={form.status}\n onValueChange={(v) => setField('status', v as BraGoalStatus)}\n >\n <SelectTrigger id=\"goal-status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {GOAL_STATUSES.map((st) => (\n <SelectItem key={st} value={st}>\n {humanize(st)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-priority\">\n {translate('brainyrich.goals.form.priority', 'Priority')}\n </Label>\n <Input\n id=\"goal-priority\"\n type=\"number\"\n min={1}\n value={form.priority}\n onChange={(e) => setField('priority', e.target.value)}\n />\n </div>\n )}\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-target\">\n {translate('brainyrich.goals.form.targetAmount', 'Target amount')}\n </Label>\n <Input\n id=\"goal-target\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={form.targetAmount}\n onChange={(e) => setField('targetAmount', e.target.value)}\n required\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-date\">\n {translate('brainyrich.goals.form.targetDate', 'Target date')}\n </Label>\n <Input\n id=\"goal-date\"\n type=\"date\"\n value={form.targetDate}\n onChange={(e) => setField('targetDate', e.target.value)}\n required\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-monthly\">\n {translate('brainyrich.goals.form.monthly', 'Monthly contribution')}\n </Label>\n <Input\n id=\"goal-monthly\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={form.monthlyContribution}\n onChange={(e) => setField('monthlyContribution', e.target.value)}\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-currency\">\n {translate('brainyrich.goals.form.currency', 'Currency')}\n </Label>\n <Input\n id=\"goal-currency\"\n value={form.currency}\n onChange={(e) => setField('currency', e.target.value.toUpperCase())}\n maxLength={3}\n />\n </div>\n </div>\n\n {mode === 'edit' ? (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-priority-edit\">\n {translate('brainyrich.goals.form.priority', 'Priority')}\n </Label>\n <Input\n id=\"goal-priority-edit\"\n type=\"number\"\n min={1}\n value={form.priority}\n onChange={(e) => setField('priority', e.target.value)}\n />\n </div>\n ) : null}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-household\">\n {translate('brainyrich.goals.form.household', 'Household (optional)')}\n </Label>\n <Select\n value={form.householdId || HOUSEHOLD_NONE}\n onValueChange={(v) => setField('householdId', v === HOUSEHOLD_NONE ? '' : v)}\n >\n <SelectTrigger id=\"goal-household\">\n <SelectValue\n placeholder={translate('brainyrich.goals.form.householdNone', 'None')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={HOUSEHOLD_NONE}>\n {translate('brainyrich.goals.form.householdNone', 'None')}\n </SelectItem>\n {households.map((h) => (\n <SelectItem key={h.id} value={h.id}>\n {h.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {mode === 'edit' && goalId ? (\n <TagField\n entityType=\"brainyrich-goal\"\n entityId={goalId}\n label={translate('brainyrich.goals.form.tags', 'Tags')}\n />\n ) : (\n <div className=\"space-y-1.5\">\n <Label>{translate('brainyrich.goals.form.tags', 'Tags')}</Label>\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.form.tagsAfterCreate',\n 'You can add tags after creating the goal.'\n )}\n </p>\n </div>\n )}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-notes\">{translate('brainyrich.goals.form.notes', 'Notes')}</Label>\n <Textarea\n id=\"goal-notes\"\n value={form.notes}\n onChange={(e) => setField('notes', e.target.value)}\n rows={3}\n />\n </div>\n\n <ResponsiveDialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n disabled={pending}\n >\n {translate('brainyrich.goals.form.cancel', 'Cancel')}\n </Button>\n <Button type=\"submit\" disabled={!valid || pending}>\n {pending\n ? translate('brainyrich.goals.form.saving', 'Saving…')\n : mode === 'create'\n ? translate('brainyrich.goals.form.create', 'Create goal')\n : translate('brainyrich.goals.form.save', 'Save changes')}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\ntype FundingMode = 'PERCENT' | 'FIXED';\n\ninterface GoalDetailSheetProps {\n goalId: string | null;\n onClose: () => void;\n translate: Translate;\n}\n\nfunction GoalDetailSheet({ goalId, onClose, translate }: GoalDetailSheetProps) {\n const { data: goal, isLoading, isError, refetch } = useGoal(goalId ?? undefined);\n const { data: fundings } = useGoalFundings(goalId ?? undefined);\n const { data: accounts } = useAccounts();\n\n const linkFunding = useLinkGoalFunding();\n const unlinkFunding = useUnlinkGoalFunding();\n const recalc = useRecalcGoalProjection();\n\n const [accountId, setAccountId] = useState('');\n const [fundingMode, setFundingMode] = useState<FundingMode>('PERCENT');\n const [fundingValue, setFundingValue] = useState('');\n const [fundedAmount, setFundedAmount] = useState('');\n const [unlinking, setUnlinking] = useState<BraGoalFunding | null>(null);\n\n const fixedFunded = fundings.reduce((s, f) => s + (f.fixedAmount ?? 0), 0);\n const currency = goal?.currency ?? 'USD';\n const fundedPct = goal ? fundedPercent(goal) : 0;\n const tone: VizTone = goal ? goalTone(goal.status, goal.projection) : 'brand';\n const projectionSeries = goal\n ? buildProjectionSeries(fixedFunded, goal.monthlyContribution, goal.targetDate)\n : [];\n\n const accountName = (id: string) => accounts.find((a) => a.id === id)?.name ?? id;\n\n const handleLink = () => {\n if (!goalId || !accountId) return;\n const numeric = Number(fundingValue);\n if (!Number.isFinite(numeric) || numeric <= 0) return;\n linkFunding.mutate(\n {\n goalId,\n accountId,\n ...(fundingMode === 'PERCENT' ? { allocationPct: numeric } : { fixedAmount: numeric }),\n },\n {\n onSuccess: () => {\n setAccountId('');\n setFundingValue('');\n },\n }\n );\n };\n\n const handleRecalc = () => {\n if (!goalId) return;\n const amount = fundedAmount === '' ? fixedFunded : Number(fundedAmount);\n if (!Number.isFinite(amount)) return;\n recalc.mutate({ id: goalId, fundedAmount: amount });\n };\n\n const linkValid = Boolean(accountId) && Number(fundingValue) > 0;\n\n const unlinkingLabel = unlinking\n ? unlinking.fixedAmount != null\n ? formatMoney(unlinking.fixedAmount, currency)\n : accountName(unlinking.accountId)\n : '';\n\n return (\n <>\n <Sheet\n open={Boolean(goalId)}\n onOpenChange={(v) => {\n if (!v) onClose();\n }}\n >\n <SheetContent className=\"flex w-full flex-col gap-0 overflow-y-auto sm:max-w-xl\">\n <SheetHeader>\n <SheetTitle>\n {goal?.name ?? translate('brainyrich.goals.detail.title', 'Goal')}\n </SheetTitle>\n <SheetDescription>\n {translate(\n 'brainyrich.goals.detail.subtitle',\n 'Manage funding links and projection.'\n )}\n </SheetDescription>\n </SheetHeader>\n\n <div className=\"space-y-6 p-4\">\n {isLoading ? (\n <LoadingState rows={3} />\n ) : isError ? (\n <ErrorState\n title={translate('brainyrich.goals.detail.error', 'Could not load goal')}\n onRetry={() => refetch()}\n />\n ) : !goal ? (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.goals.detail.notFound', 'Goal not found')}\n />\n ) : (\n <>\n {/* Hero: funded progress ring + headline */}\n <GlassCard glow className=\"flex items-center gap-5\">\n <ProgressRing\n value={fundedPct}\n tone={tone}\n size={116}\n strokeWidth={11}\n label={translate('brainyrich.goals.detail.funded', 'funded')}\n />\n <div className=\"min-w-0 flex-1 space-y-1\">\n <Badge variant={statusBadgeVariant(goal.projection)}>\n {humanize(goal.projection)}\n </Badge>\n <p className=\"text-2xl font-semibold text-text-primary\">\n {formatMoney(fixedFunded, currency)}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.detail.ofTarget', 'of {target} target', {\n target: formatCompact(goal.targetAmount, currency),\n })}\n </p>\n </div>\n </GlassCard>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <StatTile\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.target', 'Target')}\n value={formatMoney(goal.targetAmount, currency)}\n />\n <StatTile\n icon={<Wallet className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.funded', 'Funded (fixed)')}\n value={formatMoney(fixedFunded, currency)}\n />\n <StatTile\n icon={<Coins className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.monthly', 'Monthly')}\n value={formatMoney(goal.monthlyContribution, currency)}\n />\n <StatTile\n icon={<CalendarClock className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.targetDate', 'Target date')}\n value={formatDate(goal.targetDate)}\n />\n </div>\n\n {/* Projection trajectory toward the target line */}\n {projectionSeries.length >= 2 ? (\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex items-center gap-2\">\n <LineChart className=\"size-4 text-text-secondary\" aria-hidden=\"true\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate(\n 'brainyrich.goals.detail.projectionChart',\n 'Contribution projection'\n )}\n </h3>\n </div>\n <MiniAreaChart\n data={projectionSeries}\n target={goal.targetAmount}\n tone={tone}\n height={180}\n valueFormatter={(v) => formatCompact(v, currency)}\n />\n <p className=\"text-xs text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.projectionHint',\n 'Starting balance plus {monthly}/mo through {date}.',\n {\n monthly: formatMoney(goal.monthlyContribution, currency),\n date: formatDate(goal.targetDate),\n }\n )}\n </p>\n </section>\n ) : null}\n\n {/* Funding sources table */}\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.fundingLinks', 'Funding sources')}\n </h3>\n {fundings.length === 0 ? (\n <p className=\"rounded-lg border border-dashed border-border-subtle bg-bg-surface px-4 py-6 text-center text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.noFundings',\n 'No accounts linked to fund this goal yet.'\n )}\n </p>\n ) : (\n <div className=\"overflow-x-auto rounded-lg border border-border-subtle\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>\n {translate('brainyrich.goals.detail.account', 'Account')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.goals.detail.allocation', 'Allocation')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.goals.detail.fixedAmount', 'Fixed amount')}\n </TableHead>\n <TableHead className=\"w-10\" />\n </TableRow>\n </TableHeader>\n <TableBody>\n {fundings.map((f) => (\n <TableRow key={f.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {accountName(f.accountId)}\n </TableCell>\n <TableCell className=\"text-right tabular-nums text-text-secondary\">\n {f.fixedAmount == null ? formatPct(f.allocationPct) : '—'}\n </TableCell>\n <TableCell className=\"text-right tabular-nums text-text-secondary\">\n {f.fixedAmount != null ? formatMoney(f.fixedAmount, currency) : '—'}\n </TableCell>\n <TableCell className=\"text-right\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={translate(\n 'brainyrich.goals.detail.unlink',\n 'Unlink funding'\n )}\n onClick={() => setUnlinking(f)}\n >\n <Unlink className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </section>\n\n {/* Link a new funding */}\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.linkTitle', 'Link an account')}\n </h3>\n {accounts.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.noAccounts',\n 'No accounts available to link.'\n )}\n </p>\n ) : (\n <>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-account\">\n {translate('brainyrich.goals.detail.account', 'Account')}\n </Label>\n <Select value={accountId} onValueChange={setAccountId}>\n <SelectTrigger id=\"funding-account\">\n <SelectValue\n placeholder={translate(\n 'brainyrich.goals.detail.selectAccount',\n 'Select account'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n {accounts.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-mode\">\n {translate('brainyrich.goals.detail.mode', 'Method')}\n </Label>\n <Select\n value={fundingMode}\n onValueChange={(v) => setFundingMode(v as FundingMode)}\n >\n <SelectTrigger id=\"funding-mode\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"PERCENT\">\n {translate('brainyrich.goals.detail.percent', 'Percentage')}\n </SelectItem>\n <SelectItem value=\"FIXED\">\n {translate('brainyrich.goals.detail.fixed', 'Fixed amount')}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-value\">\n {fundingMode === 'PERCENT'\n ? translate('brainyrich.goals.detail.pct', 'Percent')\n : translate('brainyrich.goals.detail.amount', 'Amount')}\n </Label>\n <Input\n id=\"funding-value\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={fundingValue}\n onChange={(e) => setFundingValue(e.target.value)}\n />\n </div>\n </div>\n <Button\n size=\"sm\"\n className=\"w-full\"\n disabled={!linkValid || linkFunding.isPending}\n onClick={handleLink}\n >\n <Link2 className=\"size-4\" aria-hidden=\"true\" />\n {linkFunding.isPending\n ? translate('brainyrich.goals.detail.linking', 'Linking…')\n : translate('brainyrich.goals.detail.link', 'Link funding')}\n </Button>\n </>\n )}\n </section>\n\n {/* Tags */}\n <Card>\n <CardContent className=\"p-4\">\n <TagField\n entityType=\"brainyrich-goal\"\n entityId={goal.id}\n label={translate('brainyrich.goals.detail.tags', 'Tags')}\n />\n </CardContent>\n </Card>\n\n {/* Recalc projection */}\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.recalcTitle', 'Recalculate projection')}\n </h3>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"recalc-funded\">\n {translate('brainyrich.goals.detail.fundedAmount', 'Funded amount')}\n </Label>\n <Input\n id=\"recalc-funded\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={fundedAmount}\n placeholder={String(fixedFunded)}\n onChange={(e) => setFundedAmount(e.target.value)}\n />\n <p className=\"text-xs text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.recalcHint',\n 'Defaults to the sum of fixed fundings when left blank.'\n )}\n </p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"w-full\"\n disabled={recalc.isPending}\n onClick={handleRecalc}\n >\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n {recalc.isPending\n ? translate('brainyrich.goals.detail.recalculating', 'Recalculating…')\n : translate('brainyrich.goals.detail.recalc', 'Recalculate')}\n </Button>\n </section>\n </>\n )}\n </div>\n </SheetContent>\n </Sheet>\n\n <ConfirmDialog\n open={Boolean(unlinking)}\n onOpenChange={(o) => {\n if (!o) setUnlinking(null);\n }}\n title={translate('brainyrich.goals.detail.unlinkTitle', 'Unlink funding?')}\n description={translate(\n 'brainyrich.goals.detail.unlinkConfirm',\n 'This removes the “{name}” funding link from this goal.',\n { name: unlinkingLabel }\n )}\n confirmLabel={translate('brainyrich.goals.detail.unlink', 'Unlink funding')}\n pendingLabel={translate('brainyrich.goals.detail.unlinking', 'Unlinking…')}\n destructive\n pending={unlinkFunding.isPending}\n onConfirm={() => {\n if (!unlinking) return;\n unlinkFunding.mutate(unlinking.id, { onSuccess: () => setUnlinking(null) });\n }}\n />\n </>\n );\n}\n"],"mappings":"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"}
@@ -7,7 +7,7 @@ import { useMemo as p, useState as m } from "react";
7
7
  import { CheckCircle2 as h, Gauge as g, Layers as ie, PieChart as _, Plus as v, ShieldCheck as ae, Trash2 as oe, X as y } from "lucide-react";
8
8
  import { useI18n as se } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
9
9
  import { Fragment as ce, jsx as b, jsxs as x } from "react/jsx-runtime";
10
- import { Badge as S, Button as C, Card as le, CardContent as ue, CardDescription as de, CardHeader as fe, CardTitle as pe, Dialog as w, DialogContent as T, DialogDescription as E, DialogFooter as D, DialogHeader as O, DialogTitle as k, Input as A, Label as j, Select as M, SelectContent as N, SelectItem as P, SelectTrigger as F, SelectValue as I, Textarea as me } from "@burdenoff/fe-libs/ui";
10
+ import { Badge as S, Button as C, Card as le, CardContent as ue, CardDescription as de, CardHeader as fe, CardTitle as pe, Input as w, Label as T, ResponsiveDialog as E, ResponsiveDialogContent as D, ResponsiveDialogDescription as O, ResponsiveDialogFooter as k, ResponsiveDialogHeader as A, ResponsiveDialogTitle as j, Select as M, SelectContent as N, SelectItem as P, SelectTrigger as F, SelectValue as I, Textarea as me } from "@burdenoff/fe-libs/ui";
11
11
  //#region src/brainyrich/pages/InvestmentsPage.tsx
12
12
  var he = [
13
13
  "CONSERVATIVE",
@@ -290,24 +290,24 @@ function H() {
290
290
  })
291
291
  })]
292
292
  }),
293
- /* @__PURE__ */ b(w, {
293
+ /* @__PURE__ */ b(E, {
294
294
  open: ye,
295
295
  onOpenChange: (e) => {
296
296
  U(e), e || Y();
297
297
  },
298
- children: /* @__PURE__ */ x(T, {
298
+ children: /* @__PURE__ */ x(D, {
299
299
  className: "max-h-[90vh] overflow-y-auto sm:max-w-lg",
300
300
  children: [
301
- /* @__PURE__ */ x(O, { children: [/* @__PURE__ */ b(k, { children: $ }), /* @__PURE__ */ b(E, { children: c("brainyrich.investments.form.subtitle", "Define a target allocation. Targets should sum to about 100%.") })] }),
301
+ /* @__PURE__ */ x(A, { children: [/* @__PURE__ */ b(j, { children: $ }), /* @__PURE__ */ b(O, { children: c("brainyrich.investments.form.subtitle", "Define a target allocation. Targets should sum to about 100%.") })] }),
302
302
  /* @__PURE__ */ x("div", {
303
303
  className: "space-y-4 py-2",
304
304
  children: [
305
305
  /* @__PURE__ */ x("div", {
306
306
  className: "space-y-2",
307
- children: [/* @__PURE__ */ b(j, {
307
+ children: [/* @__PURE__ */ b(T, {
308
308
  htmlFor: "bra-model-name",
309
309
  children: c("brainyrich.investments.form.name", "Name")
310
- }), /* @__PURE__ */ b(A, {
310
+ }), /* @__PURE__ */ b(w, {
311
311
  id: "bra-model-name",
312
312
  value: W,
313
313
  onChange: (e) => Se(e.target.value),
@@ -318,7 +318,7 @@ function H() {
318
318
  className: "grid gap-4 sm:grid-cols-2",
319
319
  children: [/* @__PURE__ */ x("div", {
320
320
  className: "space-y-2",
321
- children: [/* @__PURE__ */ b(j, {
321
+ children: [/* @__PURE__ */ b(T, {
322
322
  htmlFor: "bra-model-risk",
323
323
  children: c("brainyrich.investments.form.risk", "Risk profile")
324
324
  }), /* @__PURE__ */ x(M, {
@@ -334,10 +334,10 @@ function H() {
334
334
  })]
335
335
  }), /* @__PURE__ */ x("div", {
336
336
  className: "space-y-2",
337
- children: [/* @__PURE__ */ b(j, {
337
+ children: [/* @__PURE__ */ b(T, {
338
338
  htmlFor: "bra-model-currency",
339
339
  children: c("brainyrich.investments.form.currency", "Base currency")
340
- }), /* @__PURE__ */ b(A, {
340
+ }), /* @__PURE__ */ b(w, {
341
341
  id: "bra-model-currency",
342
342
  value: Te,
343
343
  onChange: (e) => Ee(e.target.value.toUpperCase().slice(0, 3)),
@@ -347,7 +347,7 @@ function H() {
347
347
  }),
348
348
  /* @__PURE__ */ x("div", {
349
349
  className: "space-y-2",
350
- children: [/* @__PURE__ */ b(j, {
350
+ children: [/* @__PURE__ */ b(T, {
351
351
  htmlFor: "bra-model-desc",
352
352
  children: c("brainyrich.investments.form.description", "Description")
353
353
  }), /* @__PURE__ */ b(me, {
@@ -363,7 +363,7 @@ function H() {
363
363
  children: [
364
364
  /* @__PURE__ */ x("div", {
365
365
  className: "flex items-center justify-between",
366
- children: [/* @__PURE__ */ b(j, { children: c("brainyrich.investments.form.allocations", "Target allocations") }), /* @__PURE__ */ x("span", {
366
+ children: [/* @__PURE__ */ b(T, { children: c("brainyrich.investments.form.allocations", "Target allocations") }), /* @__PURE__ */ x("span", {
367
367
  className: `inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium ${Z ? "bg-status-success-bg text-status-success-text" : "bg-status-warning-bg text-status-warning-text"}`,
368
368
  children: [Z ? /* @__PURE__ */ b(h, {
369
369
  className: "size-3",
@@ -408,7 +408,7 @@ function H() {
408
408
  children: L(e)
409
409
  }, e)) })]
410
410
  }),
411
- /* @__PURE__ */ b(A, {
411
+ /* @__PURE__ */ b(w, {
412
412
  type: "number",
413
413
  inputMode: "decimal",
414
414
  min: 0,
@@ -454,7 +454,7 @@ function H() {
454
454
  }) : null
455
455
  ]
456
456
  }),
457
- /* @__PURE__ */ x(D, { children: [/* @__PURE__ */ b(C, {
457
+ /* @__PURE__ */ x(k, { children: [/* @__PURE__ */ b(C, {
458
458
  variant: "outline",
459
459
  onClick: () => {
460
460
  U(!1), Y();
@@ -482,16 +482,16 @@ function ve({ id: e, onClose: t, translate: r }) {
482
482
  value: e.targetPct,
483
483
  tone: R[t % R.length]
484
484
  })), p = B(a?.allocations ?? []), m = [...a?.allocations ?? []].sort((e, t) => t.targetPct - e.targetPct)[0];
485
- return /* @__PURE__ */ b(w, {
485
+ return /* @__PURE__ */ b(E, {
486
486
  open: !!e,
487
487
  onOpenChange: (e) => e ? void 0 : t(),
488
- children: /* @__PURE__ */ x(T, {
488
+ children: /* @__PURE__ */ x(D, {
489
489
  className: "max-h-[90vh] overflow-y-auto sm:max-w-lg",
490
490
  children: [
491
- /* @__PURE__ */ x(O, { children: [/* @__PURE__ */ b(k, {
491
+ /* @__PURE__ */ x(A, { children: [/* @__PURE__ */ b(j, {
492
492
  className: "flex items-center justify-between gap-2 pr-6",
493
493
  children: a?.name ?? r("brainyrich.investments.detail.title", "Model portfolio")
494
- }), a?.description ? /* @__PURE__ */ b(E, { children: a.description }) : null] }),
494
+ }), a?.description ? /* @__PURE__ */ b(O, { children: a.description }) : null] }),
495
495
  o ? /* @__PURE__ */ b(l, { rows: 3 }) : ee ? /* @__PURE__ */ b(ne, {
496
496
  title: r("brainyrich.investments.detail.error", "Could not load this model"),
497
497
  onRetry: () => s()
@@ -558,7 +558,7 @@ function ve({ id: e, onClose: t, translate: r }) {
558
558
  }),
559
559
  title: r("brainyrich.investments.detail.notFound", "Model not found")
560
560
  }),
561
- /* @__PURE__ */ b(D, { children: /* @__PURE__ */ b(C, {
561
+ /* @__PURE__ */ b(k, { children: /* @__PURE__ */ b(C, {
562
562
  variant: "outline",
563
563
  onClick: t,
564
564
  children: r("brainyrich.investments.detail.close", "Close")