@burdenoff/microfe-brainyrich 2026.825.1 → 2026.827.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 (29) hide show
  1. package/dist/brainyrich/components/reuse/DocumentsPanel.d.ts +4 -0
  2. package/dist/brainyrich/components/reuse/DocumentsPanel.d.ts.map +1 -1
  3. package/dist/brainyrich/components/reuse/DocumentsPanel.js +150 -99
  4. package/dist/brainyrich/components/reuse/DocumentsPanel.js.map +1 -1
  5. package/dist/brainyrich/hooks/useBrainyRichApi.d.ts +176 -0
  6. package/dist/brainyrich/hooks/useBrainyRichApi.d.ts.map +1 -1
  7. package/dist/brainyrich/hooks/useBrainyRichApi.js +96 -82
  8. package/dist/brainyrich/hooks/useBrainyRichApi.js.map +1 -1
  9. package/dist/brainyrich/pages/AdminFirmPage.d.ts.map +1 -1
  10. package/dist/brainyrich/pages/AdminFirmPage.js +115 -83
  11. package/dist/brainyrich/pages/AdminFirmPage.js.map +1 -1
  12. package/dist/brainyrich/pages/AiAssistantPage.d.ts.map +1 -1
  13. package/dist/brainyrich/pages/AiAssistantPage.js +251 -230
  14. package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
  15. package/dist/brainyrich/pages/FirmPage.d.ts.map +1 -1
  16. package/dist/brainyrich/pages/FirmPage.js +148 -116
  17. package/dist/brainyrich/pages/FirmPage.js.map +1 -1
  18. package/dist/brainyrich/pages/PortfoliosPage.d.ts +14 -0
  19. package/dist/brainyrich/pages/PortfoliosPage.d.ts.map +1 -1
  20. package/dist/brainyrich/pages/PortfoliosPage.js +530 -353
  21. package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
  22. package/dist/brainyrich/pages/RiskPage.d.ts.map +1 -1
  23. package/dist/brainyrich/pages/RiskPage.js +381 -396
  24. package/dist/brainyrich/pages/RiskPage.js.map +1 -1
  25. package/dist/brainyrich/pages/_shared.d.ts +21 -0
  26. package/dist/brainyrich/pages/_shared.d.ts.map +1 -1
  27. package/dist/brainyrich/pages/_shared.js +66 -31
  28. package/dist/brainyrich/pages/_shared.js.map +1 -1
  29. package/package.json +1 -1
@@ -4,27 +4,33 @@ import { Inbox as r, RefreshCw as i, TriangleAlert as a } from "lucide-react";
4
4
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
5
5
  import { Badge as c, Button as l, Skeleton as u } from "@burdenoff/fe-libs/ui";
6
6
  //#region src/brainyrich/pages/_shared.tsx
7
- function d(e, t = "USD") {
8
- return Number.isFinite(e) ? new Intl.NumberFormat("en-US", {
9
- style: "currency",
10
- currency: t,
11
- maximumFractionDigits: 0
12
- }).format(e) : "—";
13
- }
14
- function f(e, t) {
15
- return Number.isFinite(e) ? new Intl.NumberFormat("en-US", {
7
+ function d(e, t, n) {
8
+ try {
9
+ return new Intl.NumberFormat("en-US", {
10
+ ...n,
11
+ ...t ? {
12
+ style: "currency",
13
+ currency: t
14
+ } : {}
15
+ }).format(e);
16
+ } catch {
17
+ let r = new Intl.NumberFormat("en-US", n).format(e);
18
+ return t ? `${r} ${t}` : r;
19
+ }
20
+ }
21
+ function f(e, t = "USD") {
22
+ return Number.isFinite(e) ? d(e, t, { maximumFractionDigits: 0 }) : "—";
23
+ }
24
+ function p(e, t) {
25
+ return Number.isFinite(e) ? d(e, t, {
16
26
  notation: "compact",
17
- maximumFractionDigits: 1,
18
- ...t ? {
19
- style: "currency",
20
- currency: t
21
- } : {}
22
- }).format(e) : "—";
23
- }
24
- function p(e, t = 1) {
27
+ maximumFractionDigits: 1
28
+ }) : "—";
29
+ }
30
+ function m(e, t = 1) {
25
31
  return e == null || !Number.isFinite(e) ? "—" : `${e.toFixed(t)}%`;
26
32
  }
27
- function m(e) {
33
+ function h(e) {
28
34
  if (!e) return "—";
29
35
  let t = new Date(e);
30
36
  return Number.isNaN(t.getTime()) ? "—" : new Intl.DateTimeFormat("en-US", {
@@ -33,7 +39,7 @@ function m(e) {
33
39
  day: "numeric"
34
40
  }).format(t);
35
41
  }
36
- function h(e) {
42
+ function g(e) {
37
43
  let t = e.toUpperCase();
38
44
  return [
39
45
  "ACTIVE",
@@ -62,10 +68,10 @@ function h(e) {
62
68
  "LOW"
63
69
  ].includes(t) ? "secondary" : "outline";
64
70
  }
65
- function g(e) {
71
+ function _(e) {
66
72
  return e > 0 ? "text-status-success-text" : e < 0 ? "text-status-error-text" : "text-text-secondary";
67
73
  }
68
- function _({ title: e, description: t, actionLabel: n, onAction: r, actions: i, badges: a = [], children: u }) {
74
+ function v({ title: e, description: t, actionLabel: n, onAction: r, actions: i, badges: a = [], children: u }) {
69
75
  return /* @__PURE__ */ s("div", {
70
76
  className: "space-y-6 p-6",
71
77
  children: [/* @__PURE__ */ s("div", {
@@ -94,14 +100,14 @@ function _({ title: e, description: t, actionLabel: n, onAction: r, actions: i,
94
100
  }), u]
95
101
  });
96
102
  }
97
- var v = {
103
+ var y = {
98
104
  default: "bg-primary",
99
105
  positive: "bg-status-success-bg",
100
106
  negative: "bg-status-error-bg",
101
107
  warning: "bg-status-warning-bg",
102
108
  accent: "bg-accent-teal"
103
109
  };
104
- function y({ width: r, className: i }) {
110
+ function b({ width: r, className: i }) {
105
111
  let a = e(), [s, c] = n(a ? r : 0);
106
112
  return t(() => {
107
113
  let e = requestAnimationFrame(() => c(r));
@@ -114,7 +120,7 @@ function y({ width: r, className: i }) {
114
120
  }
115
121
  });
116
122
  }
117
- function b({ data: e }) {
123
+ function x({ data: e }) {
118
124
  let t = e.filter((e) => Number.isFinite(e.value));
119
125
  return t.length === 0 ? /* @__PURE__ */ o("p", {
120
126
  className: "text-sm text-text-secondary",
@@ -132,7 +138,7 @@ function b({ data: e }) {
132
138
  children: e.label
133
139
  }), /* @__PURE__ */ o("span", {
134
140
  className: "tabular-nums text-text-secondary",
135
- children: e.caption ?? p(e.value)
141
+ children: e.caption ?? m(e.value)
136
142
  })]
137
143
  }), /* @__PURE__ */ o("div", {
138
144
  className: "h-2.5 w-full overflow-hidden rounded-full bg-bg-sunken",
@@ -141,16 +147,45 @@ function b({ data: e }) {
141
147
  "aria-valuemin": 0,
142
148
  "aria-valuemax": 100,
143
149
  "aria-label": e.label,
144
- children: /* @__PURE__ */ o(y, {
150
+ children: /* @__PURE__ */ o(b, {
145
151
  width: t,
146
- className: `h-full rounded-full ${v[e.tone ?? "default"]}`
152
+ className: `h-full rounded-full ${y[e.tone ?? "default"]}`
147
153
  })
148
154
  })]
149
155
  }, e.label);
150
156
  })
151
157
  });
152
158
  }
153
- function x({ icon: e, title: t, description: n, action: i }) {
159
+ function S(e) {
160
+ return e == null ? "—" : typeof e == "number" ? Number.isInteger(e) ? e.toLocaleString() : e.toLocaleString(void 0, { maximumFractionDigits: 2 }) : typeof e == "boolean" ? e ? "Yes" : "No" : typeof e == "string" ? e : JSON.stringify(e);
161
+ }
162
+ function C(e) {
163
+ if (!e || typeof e != "object" || Array.isArray(e)) return null;
164
+ let t = Object.entries(e);
165
+ if (t.length === 0) return null;
166
+ let n = e.formula;
167
+ return {
168
+ formula: typeof n == "string" ? n : null,
169
+ entries: t.filter(([e]) => e !== "formula")
170
+ };
171
+ }
172
+ function w({ entries: e }) {
173
+ return e.length === 0 ? null : /* @__PURE__ */ o("dl", {
174
+ className: "grid grid-cols-2 gap-x-4 gap-y-1 sm:grid-cols-3 lg:grid-cols-4",
175
+ children: e.map(([e, t]) => /* @__PURE__ */ s("div", {
176
+ className: "min-w-0",
177
+ children: [/* @__PURE__ */ o("dt", {
178
+ className: "truncate text-[11px] uppercase tracking-wide text-text-muted",
179
+ children: e.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/_/g, " ").replace(/^./, (e) => e.toUpperCase())
180
+ }), /* @__PURE__ */ o("dd", {
181
+ className: "truncate text-sm font-medium tabular-nums text-text-primary",
182
+ title: S(t),
183
+ children: S(t)
184
+ })]
185
+ }, e))
186
+ });
187
+ }
188
+ function T({ icon: e, title: t, description: n, action: i }) {
154
189
  return /* @__PURE__ */ s("div", {
155
190
  className: "flex flex-col items-center justify-center rounded-lg border border-dashed border-border-subtle bg-bg-surface px-6 py-12 text-center",
156
191
  children: [
@@ -176,7 +211,7 @@ function x({ icon: e, title: t, description: n, action: i }) {
176
211
  ]
177
212
  });
178
213
  }
179
- function S({ rows: e = 4 }) {
214
+ function E({ rows: e = 4 }) {
180
215
  return /* @__PURE__ */ o("div", {
181
216
  className: "space-y-3",
182
217
  "aria-busy": "true",
@@ -194,7 +229,7 @@ function S({ rows: e = 4 }) {
194
229
  }, t))
195
230
  });
196
231
  }
197
- function C({ title: e = "Something went wrong", description: t = "We could not load this data. Please try again.", onRetry: n }) {
232
+ function D({ title: e = "Something went wrong", description: t = "We could not load this data. Please try again.", onRetry: n }) {
198
233
  return /* @__PURE__ */ s("div", {
199
234
  className: "flex flex-col items-center justify-center rounded-lg border border-status-error-text/40 bg-status-error-bg px-6 py-12 text-center",
200
235
  children: [
@@ -227,6 +262,6 @@ function C({ title: e = "Something went wrong", description: t = "We could not l
227
262
  });
228
263
  }
229
264
  //#endregion
230
- export { b as AllocationBars, x as EmptyState, C as ErrorState, S as LoadingState, _ as SectionShell, g as deltaToneClass, f as formatCompact, m as formatDate, d as formatMoney, p as formatPct, h as statusBadgeVariant };
265
+ export { x as AllocationBars, T as EmptyState, D as ErrorState, E as LoadingState, w as MetricGrid, v as SectionShell, _ as deltaToneClass, p as formatCompact, h as formatDate, f as formatMoney, m as formatPct, C as readEngineMetrics, g as statusBadgeVariant };
231
266
 
232
267
  //# sourceMappingURL=_shared.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_shared.js","names":[],"sources":["../../../src/brainyrich/pages/_shared.tsx"],"sourcesContent":["import { useEffect, useState, type ReactNode } from 'react';\nimport { ArrowDownRight, ArrowUpRight, Inbox, Minus, RefreshCw, TriangleAlert } from 'lucide-react';\nimport { Badge, Button, Card, CardContent, Skeleton } from '@burdenoff/fe-libs/ui';\nimport { FadeIn, useReducedMotion } from '../components/viz';\n\n// ============================================================================\n// Formatters\n// ============================================================================\n\n/** USD currency, no cents. Pass a currency code to override. */\nexport function formatMoney(value: number, currency = 'USD'): string {\n if (!Number.isFinite(value)) return '—';\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency,\n maximumFractionDigits: 0,\n }).format(value);\n}\n\n/** Compact money/number, e.g. 1.2M, 950K. */\nexport function formatCompact(value: number, currency?: string): string {\n if (!Number.isFinite(value)) return '—';\n return new Intl.NumberFormat('en-US', {\n notation: 'compact',\n maximumFractionDigits: 1,\n ...(currency ? { style: 'currency', currency } : {}),\n }).format(value);\n}\n\n/** Percentage from a whole-number percent (e.g. 12.5 → \"12.5%\"). */\nexport function formatPct(value: number | null | undefined, fractionDigits = 1): string {\n if (value === null || value === undefined || !Number.isFinite(value)) return '—';\n return `${value.toFixed(fractionDigits)}%`;\n}\n\n/**\n * Guarded date formatter. Only wraps a present ISO string in `new Date()` at\n * render time — never calls `.getTime()` on a raw scalar and never `new Date(0)`.\n * Returns an em-dash for absent/invalid values.\n */\nexport function formatDate(iso?: string | null): string {\n if (!iso) return '—';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '—';\n return new Intl.DateTimeFormat('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n }).format(d);\n}\n\n// ============================================================================\n// Status → badge variant (semantic, no raw colors)\n// ============================================================================\n\n/**\n * Map a domain status/severity string to a shadcn Badge variant. Accepts the\n * Bra* enum members (ACTIVE, AT_RISK, HIGH, …) case-insensitively so pages can\n * pass raw enum values.\n */\nexport function statusBadgeVariant(\n status: string\n): 'default' | 'secondary' | 'destructive' | 'outline' {\n const s = status.toUpperCase();\n if (['ACTIVE', 'ACHIEVED', 'ON_TRACK', 'AHEAD', 'RESOLVED', 'EXECUTED', 'APPROVED'].includes(s))\n return 'default';\n if (['AT_RISK', 'HIGH', 'CRITICAL', 'ABANDONED', 'REJECTED', 'CANCELLED', 'CLOSED'].includes(s))\n return 'destructive';\n if (\n ['ONBOARDING', 'PROSPECT', 'ON_HOLD', 'BEHIND', 'DRAFT', 'PROPOSED', 'MEDIUM', 'LOW'].includes(\n s\n )\n )\n return 'secondary';\n return 'outline';\n}\n\n/** Semantic text-color token for a signed delta (color is never the only signal). */\nexport function deltaToneClass(value: number): string {\n if (value > 0) return 'text-status-success-text';\n if (value < 0) return 'text-status-error-text';\n return 'text-text-secondary';\n}\n\n// ============================================================================\n// Section shell + KPIs\n// ============================================================================\n\ninterface SectionShellProps {\n title: string;\n description: string;\n actionLabel?: string;\n onAction?: () => void;\n actions?: ReactNode;\n badges?: string[];\n children: ReactNode;\n}\n\nexport function SectionShell({\n title,\n description,\n actionLabel,\n onAction,\n actions,\n badges = [],\n children,\n}: SectionShellProps) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold text-text-primary\">{title}</h1>\n <p className=\"text-sm text-text-secondary\">{description}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n {badges.map((badge) => (\n <Badge key={badge} variant=\"secondary\">\n {badge}\n </Badge>\n ))}\n {actions}\n {actionLabel ? (\n <Button size=\"sm\" onClick={onAction}>\n {actionLabel}\n </Button>\n ) : null}\n </div>\n </div>\n {children}\n </div>\n );\n}\n\nexport interface KpiItem {\n label: string;\n value: string;\n /** Optional signed delta rendered as a DeltaBadge (icon + sign + color). */\n delta?: number;\n /** Optional free-text trend line (neutral tone unless deltaTone provided). */\n trend?: string;\n deltaTone?: 'positive' | 'negative' | 'neutral';\n}\n\nexport function KpiGrid({ items }: { items: KpiItem[] }) {\n return (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {items.map((item, i) => (\n <FadeIn key={item.label} index={i}>\n <Card className=\"h-full transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <CardContent className=\"space-y-1.5 p-4\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {item.label}\n </p>\n <p className=\"text-2xl font-semibold tracking-tight text-text-primary\">\n {item.value}\n </p>\n {item.delta !== undefined ? (\n <DeltaBadge value={item.delta} />\n ) : item.trend ? (\n <p\n className={\n item.deltaTone === 'positive'\n ? 'text-xs text-status-success-text'\n : item.deltaTone === 'negative'\n ? 'text-xs text-status-error-text'\n : 'text-xs text-text-secondary'\n }\n >\n {item.trend}\n </p>\n ) : null}\n </CardContent>\n </Card>\n </FadeIn>\n ))}\n </div>\n );\n}\n\n// ============================================================================\n// Delta badge — icon + sign + semantic color (color never the only signal)\n// ============================================================================\n\nexport function DeltaBadge({\n value,\n suffix = '%',\n className = '',\n}: {\n value: number;\n suffix?: string;\n className?: string;\n}) {\n const positive = value > 0;\n const negative = value < 0;\n const Icon = positive ? ArrowUpRight : negative ? ArrowDownRight : Minus;\n const tone = positive\n ? 'text-status-success-text bg-status-success-bg'\n : negative\n ? 'text-status-error-text bg-status-error-bg'\n : 'text-text-secondary bg-bg-sunken';\n const sign = positive ? '+' : '';\n return (\n <span\n className={`inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-medium ${tone} ${className}`}\n >\n <Icon className=\"size-3\" aria-hidden=\"true\" />\n {sign}\n {Number.isFinite(value) ? value.toFixed(1) : '—'}\n {suffix}\n </span>\n );\n}\n\n// ============================================================================\n// Allocation bars — tokenized horizontal bar primitive\n// ============================================================================\n\nexport type AllocationTone = 'default' | 'positive' | 'negative' | 'warning' | 'accent';\n\nconst TONE_FILL: Record<AllocationTone, string> = {\n default: 'bg-primary',\n positive: 'bg-status-success-bg',\n negative: 'bg-status-error-bg',\n warning: 'bg-status-warning-bg',\n accent: 'bg-accent-teal',\n};\n\nexport interface AllocationDatum {\n label: string;\n /** Percentage 0–100 for the bar width. */\n value: number;\n tone?: AllocationTone;\n /** Optional right-aligned caption (e.g. formatted money). Defaults to the %. */\n caption?: string;\n}\n\n/**\n * Single allocation bar fill. Starts at 0 width and grows to `width`% after\n * mount via a CSS transition; instant (no transition) under reduced motion.\n */\nfunction AllocationFill({ width, className }: { width: number; className: string }) {\n const reduce = useReducedMotion();\n // Reduced motion starts at the final width (instant); otherwise start at 0 and\n // grow on the next frame via the CSS width transition.\n const [w, setW] = useState(reduce ? width : 0);\n\n useEffect(() => {\n const id = requestAnimationFrame(() => setW(width));\n return () => cancelAnimationFrame(id);\n }, [width]);\n\n return (\n <div\n className={className}\n style={{ width: `${w}%`, transition: reduce ? 'none' : 'width 500ms ease' }}\n />\n );\n}\n\nexport function AllocationBars({ data }: { data: AllocationDatum[] }) {\n const rows = data.filter((d) => Number.isFinite(d.value));\n if (rows.length === 0) {\n return <p className=\"text-sm text-text-secondary\">No allocation data.</p>;\n }\n return (\n <div className=\"space-y-3.5\">\n {rows.map((d) => {\n const width = Math.max(0, Math.min(100, d.value));\n return (\n <div key={d.label} className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"font-medium text-text-primary\">{d.label}</span>\n <span className=\"tabular-nums text-text-secondary\">\n {d.caption ?? formatPct(d.value)}\n </span>\n </div>\n <div\n className=\"h-2.5 w-full overflow-hidden rounded-full bg-bg-sunken\"\n role=\"progressbar\"\n aria-valuenow={Math.round(width)}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={d.label}\n >\n <AllocationFill\n width={width}\n className={`h-full rounded-full ${TONE_FILL[d.tone ?? 'default']}`}\n />\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\n// ============================================================================\n// Empty / Loading / Error states (designed, shared)\n// ============================================================================\n\nexport function EmptyState({\n icon,\n title,\n description,\n action,\n}: {\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n}) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-dashed border-border-subtle bg-bg-surface px-6 py-12 text-center\">\n <div className=\"mb-4 flex size-12 items-center justify-center rounded-full bg-bg-sunken text-text-secondary\">\n {icon ?? <Inbox className=\"size-6\" aria-hidden=\"true\" />}\n </div>\n <h3 className=\"text-base font-semibold text-text-primary\">{title}</h3>\n {description ? (\n <p className=\"mt-1 max-w-md text-sm text-text-secondary\">{description}</p>\n ) : null}\n {action ? <div className=\"mt-4\">{action}</div> : null}\n </div>\n );\n}\n\nexport function LoadingState({ rows = 4 }: { rows?: number }) {\n return (\n <div className=\"space-y-3\" aria-busy=\"true\" aria-live=\"polite\">\n {Array.from({ length: rows }).map((_, i) => (\n <div\n key={i}\n className=\"flex items-center gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4\"\n >\n <Skeleton className=\"size-10 rounded-full\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-1/3\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n <Skeleton className=\"h-4 w-16\" />\n </div>\n ))}\n </div>\n );\n}\n\nexport function ErrorState({\n title = 'Something went wrong',\n description = 'We could not load this data. Please try again.',\n onRetry,\n}: {\n title?: string;\n description?: string;\n onRetry?: () => void;\n}) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-status-error-text/40 bg-status-error-bg px-6 py-12 text-center\">\n <div className=\"mb-4 flex size-12 items-center justify-center rounded-full bg-bg-surface text-status-error-text\">\n <TriangleAlert className=\"size-6\" aria-hidden=\"true\" />\n </div>\n <h3 className=\"text-base font-semibold text-text-primary\">{title}</h3>\n <p className=\"mt-1 max-w-md text-sm text-text-secondary\">{description}</p>\n {onRetry ? (\n <Button variant=\"outline\" size=\"sm\" className=\"mt-4\" onClick={onRetry}>\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n Retry\n </Button>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"_shared.js","names":[],"sources":["../../../src/brainyrich/pages/_shared.tsx"],"sourcesContent":["import { useEffect, useState, type ReactNode } from 'react';\nimport { ArrowDownRight, ArrowUpRight, Inbox, Minus, RefreshCw, TriangleAlert } from 'lucide-react';\nimport { Badge, Button, Card, CardContent, Skeleton } from '@burdenoff/fe-libs/ui';\nimport { FadeIn, useReducedMotion } from '../components/viz';\n\n// ============================================================================\n// Formatters\n// ============================================================================\n\n/**\n * `Intl.NumberFormat` throws `RangeError` on a currency code that is not three\n * ASCII letters, and `BraPortfolio.baseCurrency` / `BraHolding.currency` are\n * free-text `String!` columns — a single row saved as \"US\" would otherwise take\n * down every list that formats it. Fall back to the number plus the raw code.\n */\nfunction formatCurrencySafely(\n value: number,\n currency: string | undefined,\n options: Intl.NumberFormatOptions\n): string {\n try {\n return new Intl.NumberFormat('en-US', {\n ...options,\n ...(currency ? { style: 'currency', currency } : {}),\n }).format(value);\n } catch {\n const plain = new Intl.NumberFormat('en-US', options).format(value);\n return currency ? `${plain} ${currency}` : plain;\n }\n}\n\n/** USD currency, no cents. Pass a currency code to override. */\nexport function formatMoney(value: number, currency = 'USD'): string {\n if (!Number.isFinite(value)) return '—';\n return formatCurrencySafely(value, currency, { maximumFractionDigits: 0 });\n}\n\n/** Compact money/number, e.g. 1.2M, 950K. */\nexport function formatCompact(value: number, currency?: string): string {\n if (!Number.isFinite(value)) return '—';\n return formatCurrencySafely(value, currency, {\n notation: 'compact',\n maximumFractionDigits: 1,\n });\n}\n\n/** Percentage from a whole-number percent (e.g. 12.5 → \"12.5%\"). */\nexport function formatPct(value: number | null | undefined, fractionDigits = 1): string {\n if (value === null || value === undefined || !Number.isFinite(value)) return '—';\n return `${value.toFixed(fractionDigits)}%`;\n}\n\n/**\n * Guarded date formatter. Only wraps a present ISO string in `new Date()` at\n * render time — never calls `.getTime()` on a raw scalar and never `new Date(0)`.\n * Returns an em-dash for absent/invalid values.\n */\nexport function formatDate(iso?: string | null): string {\n if (!iso) return '—';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '—';\n return new Intl.DateTimeFormat('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n }).format(d);\n}\n\n// ============================================================================\n// Status → badge variant (semantic, no raw colors)\n// ============================================================================\n\n/**\n * Map a domain status/severity string to a shadcn Badge variant. Accepts the\n * Bra* enum members (ACTIVE, AT_RISK, HIGH, …) case-insensitively so pages can\n * pass raw enum values.\n */\nexport function statusBadgeVariant(\n status: string\n): 'default' | 'secondary' | 'destructive' | 'outline' {\n const s = status.toUpperCase();\n if (['ACTIVE', 'ACHIEVED', 'ON_TRACK', 'AHEAD', 'RESOLVED', 'EXECUTED', 'APPROVED'].includes(s))\n return 'default';\n if (['AT_RISK', 'HIGH', 'CRITICAL', 'ABANDONED', 'REJECTED', 'CANCELLED', 'CLOSED'].includes(s))\n return 'destructive';\n if (\n ['ONBOARDING', 'PROSPECT', 'ON_HOLD', 'BEHIND', 'DRAFT', 'PROPOSED', 'MEDIUM', 'LOW'].includes(\n s\n )\n )\n return 'secondary';\n return 'outline';\n}\n\n/** Semantic text-color token for a signed delta (color is never the only signal). */\nexport function deltaToneClass(value: number): string {\n if (value > 0) return 'text-status-success-text';\n if (value < 0) return 'text-status-error-text';\n return 'text-text-secondary';\n}\n\n// ============================================================================\n// Section shell + KPIs\n// ============================================================================\n\ninterface SectionShellProps {\n title: string;\n description: string;\n actionLabel?: string;\n onAction?: () => void;\n actions?: ReactNode;\n badges?: string[];\n children: ReactNode;\n}\n\nexport function SectionShell({\n title,\n description,\n actionLabel,\n onAction,\n actions,\n badges = [],\n children,\n}: SectionShellProps) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold text-text-primary\">{title}</h1>\n <p className=\"text-sm text-text-secondary\">{description}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n {badges.map((badge) => (\n <Badge key={badge} variant=\"secondary\">\n {badge}\n </Badge>\n ))}\n {actions}\n {actionLabel ? (\n <Button size=\"sm\" onClick={onAction}>\n {actionLabel}\n </Button>\n ) : null}\n </div>\n </div>\n {children}\n </div>\n );\n}\n\nexport interface KpiItem {\n label: string;\n value: string;\n /** Optional signed delta rendered as a DeltaBadge (icon + sign + color). */\n delta?: number;\n /** Optional free-text trend line (neutral tone unless deltaTone provided). */\n trend?: string;\n deltaTone?: 'positive' | 'negative' | 'neutral';\n}\n\nexport function KpiGrid({ items }: { items: KpiItem[] }) {\n return (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {items.map((item, i) => (\n <FadeIn key={item.label} index={i}>\n <Card className=\"h-full transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <CardContent className=\"space-y-1.5 p-4\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {item.label}\n </p>\n <p className=\"text-2xl font-semibold tracking-tight text-text-primary\">\n {item.value}\n </p>\n {item.delta !== undefined ? (\n <DeltaBadge value={item.delta} />\n ) : item.trend ? (\n <p\n className={\n item.deltaTone === 'positive'\n ? 'text-xs text-status-success-text'\n : item.deltaTone === 'negative'\n ? 'text-xs text-status-error-text'\n : 'text-xs text-text-secondary'\n }\n >\n {item.trend}\n </p>\n ) : null}\n </CardContent>\n </Card>\n </FadeIn>\n ))}\n </div>\n );\n}\n\n// ============================================================================\n// Delta badge — icon + sign + semantic color (color never the only signal)\n// ============================================================================\n\nexport function DeltaBadge({\n value,\n suffix = '%',\n className = '',\n}: {\n value: number;\n suffix?: string;\n className?: string;\n}) {\n const positive = value > 0;\n const negative = value < 0;\n const Icon = positive ? ArrowUpRight : negative ? ArrowDownRight : Minus;\n const tone = positive\n ? 'text-status-success-text bg-status-success-bg'\n : negative\n ? 'text-status-error-text bg-status-error-bg'\n : 'text-text-secondary bg-bg-sunken';\n const sign = positive ? '+' : '';\n return (\n <span\n className={`inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-medium ${tone} ${className}`}\n >\n <Icon className=\"size-3\" aria-hidden=\"true\" />\n {sign}\n {Number.isFinite(value) ? value.toFixed(1) : '—'}\n {suffix}\n </span>\n );\n}\n\n// ============================================================================\n// Allocation bars — tokenized horizontal bar primitive\n// ============================================================================\n\nexport type AllocationTone = 'default' | 'positive' | 'negative' | 'warning' | 'accent';\n\nconst TONE_FILL: Record<AllocationTone, string> = {\n default: 'bg-primary',\n positive: 'bg-status-success-bg',\n negative: 'bg-status-error-bg',\n warning: 'bg-status-warning-bg',\n accent: 'bg-accent-teal',\n};\n\nexport interface AllocationDatum {\n label: string;\n /** Percentage 0–100 for the bar width. */\n value: number;\n tone?: AllocationTone;\n /** Optional right-aligned caption (e.g. formatted money). Defaults to the %. */\n caption?: string;\n}\n\n/**\n * Single allocation bar fill. Starts at 0 width and grows to `width`% after\n * mount via a CSS transition; instant (no transition) under reduced motion.\n */\nfunction AllocationFill({ width, className }: { width: number; className: string }) {\n const reduce = useReducedMotion();\n // Reduced motion starts at the final width (instant); otherwise start at 0 and\n // grow on the next frame via the CSS width transition.\n const [w, setW] = useState(reduce ? width : 0);\n\n useEffect(() => {\n const id = requestAnimationFrame(() => setW(width));\n return () => cancelAnimationFrame(id);\n }, [width]);\n\n return (\n <div\n className={className}\n style={{ width: `${w}%`, transition: reduce ? 'none' : 'width 500ms ease' }}\n />\n );\n}\n\nexport function AllocationBars({ data }: { data: AllocationDatum[] }) {\n const rows = data.filter((d) => Number.isFinite(d.value));\n if (rows.length === 0) {\n return <p className=\"text-sm text-text-secondary\">No allocation data.</p>;\n }\n return (\n <div className=\"space-y-3.5\">\n {rows.map((d) => {\n const width = Math.max(0, Math.min(100, d.value));\n return (\n <div key={d.label} className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"font-medium text-text-primary\">{d.label}</span>\n <span className=\"tabular-nums text-text-secondary\">\n {d.caption ?? formatPct(d.value)}\n </span>\n </div>\n <div\n className=\"h-2.5 w-full overflow-hidden rounded-full bg-bg-sunken\"\n role=\"progressbar\"\n aria-valuenow={Math.round(width)}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={d.label}\n >\n <AllocationFill\n width={width}\n className={`h-full rounded-full ${TONE_FILL[d.tone ?? 'default']}`}\n />\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\n// ============================================================================\n// Deterministic-engine metrics (BraRiskSignal.metrics / BraInsight.metrics)\n// ============================================================================\n\n/**\n * Render one entry of a deterministic-engine `metrics` object without inventing\n * formatting rules per-key: numbers render as plain locale numbers (2dp when\n * fractional), booleans as Yes/No, everything else as-is. This is the ONLY way\n * the engine's real inputs and formula reach the screen — never replaced by a\n * derived or opaque display value.\n */\nexport function formatMetricValue(value: unknown): string {\n if (value === null || value === undefined) return '—';\n if (typeof value === 'number') {\n return Number.isInteger(value)\n ? value.toLocaleString()\n : value.toLocaleString(undefined, { maximumFractionDigits: 2 });\n }\n if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n}\n\n/**\n * A `metrics` JSON scalar split into the engine's own `formula` string (when it\n * set one) and the remaining measured entries. Returns `null` when there is\n * nothing to show, so callers render no empty rationale block.\n */\nexport function readEngineMetrics(\n metrics: unknown\n): { formula: string | null; entries: Array<[string, unknown]> } | null {\n if (!metrics || typeof metrics !== 'object' || Array.isArray(metrics)) return null;\n const all = Object.entries(metrics as Record<string, unknown>);\n if (all.length === 0) return null;\n const formulaValue = (metrics as Record<string, unknown>).formula;\n return {\n formula: typeof formulaValue === 'string' ? formulaValue : null,\n entries: all.filter(([key]) => key !== 'formula'),\n };\n}\n\n/** Key/value grid for engine metric entries — matches the risk-signal rows. */\nexport function MetricGrid({ entries }: { entries: Array<[string, unknown]> }) {\n if (entries.length === 0) return null;\n return (\n <dl className=\"grid grid-cols-2 gap-x-4 gap-y-1 sm:grid-cols-3 lg:grid-cols-4\">\n {entries.map(([key, value]) => (\n <div key={key} className=\"min-w-0\">\n <dt className=\"truncate text-[11px] uppercase tracking-wide text-text-muted\">\n {key\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/_/g, ' ')\n .replace(/^./, (c) => c.toUpperCase())}\n </dt>\n <dd\n className=\"truncate text-sm font-medium tabular-nums text-text-primary\"\n title={formatMetricValue(value)}\n >\n {formatMetricValue(value)}\n </dd>\n </div>\n ))}\n </dl>\n );\n}\n\n// ============================================================================\n// Empty / Loading / Error states (designed, shared)\n// ============================================================================\n\nexport function EmptyState({\n icon,\n title,\n description,\n action,\n}: {\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n}) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-dashed border-border-subtle bg-bg-surface px-6 py-12 text-center\">\n <div className=\"mb-4 flex size-12 items-center justify-center rounded-full bg-bg-sunken text-text-secondary\">\n {icon ?? <Inbox className=\"size-6\" aria-hidden=\"true\" />}\n </div>\n <h3 className=\"text-base font-semibold text-text-primary\">{title}</h3>\n {description ? (\n <p className=\"mt-1 max-w-md text-sm text-text-secondary\">{description}</p>\n ) : null}\n {action ? <div className=\"mt-4\">{action}</div> : null}\n </div>\n );\n}\n\nexport function LoadingState({ rows = 4 }: { rows?: number }) {\n return (\n <div className=\"space-y-3\" aria-busy=\"true\" aria-live=\"polite\">\n {Array.from({ length: rows }).map((_, i) => (\n <div\n key={i}\n className=\"flex items-center gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4\"\n >\n <Skeleton className=\"size-10 rounded-full\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-1/3\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n <Skeleton className=\"h-4 w-16\" />\n </div>\n ))}\n </div>\n );\n}\n\nexport function ErrorState({\n title = 'Something went wrong',\n description = 'We could not load this data. Please try again.',\n onRetry,\n}: {\n title?: string;\n description?: string;\n onRetry?: () => void;\n}) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-status-error-text/40 bg-status-error-bg px-6 py-12 text-center\">\n <div className=\"mb-4 flex size-12 items-center justify-center rounded-full bg-bg-surface text-status-error-text\">\n <TriangleAlert className=\"size-6\" aria-hidden=\"true\" />\n </div>\n <h3 className=\"text-base font-semibold text-text-primary\">{title}</h3>\n <p className=\"mt-1 max-w-md text-sm text-text-secondary\">{description}</p>\n {onRetry ? (\n <Button variant=\"outline\" size=\"sm\" className=\"mt-4\" onClick={onRetry}>\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n Retry\n </Button>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-brainyrich",
3
- "version": "2026.825.1",
3
+ "version": "2026.827.1",
4
4
  "description": "Burdenoff BrainyRich Microfrontend",
5
5
  "type": "module",
6
6
  "files": [