@burdenoff/microfe-brainyrich 2026.819.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.
- package/dist/_virtual/_rolldown/runtime.js +1 -1
- package/dist/brainyrich/BrainyRichRoot.d.ts +0 -1
- package/dist/brainyrich/BrainyRichRoot.js.map +1 -1
- package/dist/brainyrich/BrainyRichRoutes.js.map +1 -1
- package/dist/brainyrich/components/ActorName.js.map +1 -1
- package/dist/brainyrich/components/ConfirmDialog.d.ts +0 -1
- package/dist/brainyrich/components/ConfirmDialog.js.map +1 -1
- package/dist/brainyrich/components/LoadMore.js.map +1 -1
- package/dist/brainyrich/components/notify.js.map +1 -1
- package/dist/brainyrich/components/pickers.js.map +1 -1
- package/dist/brainyrich/components/reuse/CommentThread.js.map +1 -1
- package/dist/brainyrich/components/reuse/DocumentsPanel.d.ts +4 -0
- package/dist/brainyrich/components/reuse/DocumentsPanel.d.ts.map +1 -1
- package/dist/brainyrich/components/reuse/DocumentsPanel.js +150 -99
- package/dist/brainyrich/components/reuse/DocumentsPanel.js.map +1 -1
- package/dist/brainyrich/components/reuse/TagField.js.map +1 -1
- package/dist/brainyrich/components/reuse/transport.js.map +1 -1
- package/dist/brainyrich/components/viz.d.ts +0 -1
- package/dist/brainyrich/components/viz.js.map +1 -1
- package/dist/brainyrich/hooks/useBrainyRichAnalytics.js.map +1 -1
- package/dist/brainyrich/hooks/useBrainyRichApi.d.ts +176 -1
- package/dist/brainyrich/hooks/useBrainyRichApi.d.ts.map +1 -1
- package/dist/brainyrich/hooks/useBrainyRichApi.js +96 -82
- package/dist/brainyrich/hooks/useBrainyRichApi.js.map +1 -1
- package/dist/brainyrich/pages/AccountsPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/AccountsPage.js +367 -363
- package/dist/brainyrich/pages/AccountsPage.js.map +1 -1
- package/dist/brainyrich/pages/AdminFirmPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/AdminFirmPage.js +115 -83
- package/dist/brainyrich/pages/AdminFirmPage.js.map +1 -1
- package/dist/brainyrich/pages/AiAssistantPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/AiAssistantPage.js +251 -230
- package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
- package/dist/brainyrich/pages/AnalyticsPage.js.map +1 -1
- package/dist/brainyrich/pages/DashboardPage.js.map +1 -1
- package/dist/brainyrich/pages/FamilyPage.js.map +1 -1
- package/dist/brainyrich/pages/FirmPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/FirmPage.js +148 -116
- package/dist/brainyrich/pages/FirmPage.js.map +1 -1
- package/dist/brainyrich/pages/GoalsPage.js.map +1 -1
- package/dist/brainyrich/pages/InvestmentsPage.js.map +1 -1
- package/dist/brainyrich/pages/PortfoliosPage.d.ts +14 -0
- package/dist/brainyrich/pages/PortfoliosPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/PortfoliosPage.js +530 -353
- package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
- package/dist/brainyrich/pages/ReportsPage.js.map +1 -1
- package/dist/brainyrich/pages/RiskPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/RiskPage.js +381 -396
- package/dist/brainyrich/pages/RiskPage.js.map +1 -1
- package/dist/brainyrich/pages/TaxPage.js.map +1 -1
- package/dist/brainyrich/pages/_shared.d.ts +21 -1
- package/dist/brainyrich/pages/_shared.d.ts.map +1 -1
- package/dist/brainyrich/pages/_shared.js +66 -31
- package/dist/brainyrich/pages/_shared.js.map +1 -1
- package/dist/brainyrich/providers/BrainyRichProvider.d.ts +0 -1
- package/dist/brainyrich/providers/BrainyRichProvider.js.map +1 -1
- package/dist/brainyrich/services/createSandboxAssistantTransport.js.map +1 -1
- package/dist/brainyrich/types/bra.d.ts.map +1 -1
- package/dist/brainyrich/types/index.d.ts +0 -1
- package/dist/brainyrich/utils/cn.d.ts +0 -1
- package/dist/brainyrich/utils/i18n.d.ts +0 -1
- package/dist/brainyrich/utils/i18n.js.map +1 -1
- package/dist/brainyrich/utils/nativeControls.d.ts +0 -1
- package/dist/brainyrich/utils/nativeControls.js.map +1 -1
- package/dist/brainyrich/utils/navigation.js.map +1 -1
- package/dist/brainyrich/utils/pageContext.js.map +1 -1
- package/dist/dev/main.d.ts +0 -1
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -1
- package/dist/node_modules/d3-array/src/ascending.js.map +1 -1
- package/dist/node_modules/d3-array/src/bisect.js.map +1 -1
- package/dist/node_modules/d3-array/src/bisector.js.map +1 -1
- package/dist/node_modules/d3-array/src/descending.js.map +1 -1
- package/dist/node_modules/d3-array/src/max.js.map +1 -1
- package/dist/node_modules/d3-array/src/min.js.map +1 -1
- package/dist/node_modules/d3-array/src/number.js.map +1 -1
- package/dist/node_modules/d3-array/src/quantile.js.map +1 -1
- package/dist/node_modules/d3-array/src/quickselect.js.map +1 -1
- package/dist/node_modules/d3-array/src/range.js.map +1 -1
- package/dist/node_modules/d3-array/src/sort.js.map +1 -1
- package/dist/node_modules/d3-array/src/ticks.js.map +1 -1
- package/dist/node_modules/d3-color/src/color.js.map +1 -1
- package/dist/node_modules/d3-color/src/define.js.map +1 -1
- package/dist/node_modules/d3-format/src/defaultLocale.js.map +1 -1
- package/dist/node_modules/d3-format/src/exponent.js.map +1 -1
- package/dist/node_modules/d3-format/src/formatDecimal.js.map +1 -1
- package/dist/node_modules/d3-format/src/formatGroup.js.map +1 -1
- package/dist/node_modules/d3-format/src/formatNumerals.js.map +1 -1
- package/dist/node_modules/d3-format/src/formatPrefixAuto.js.map +1 -1
- package/dist/node_modules/d3-format/src/formatRounded.js.map +1 -1
- package/dist/node_modules/d3-format/src/formatSpecifier.js.map +1 -1
- package/dist/node_modules/d3-format/src/formatTrim.js.map +1 -1
- package/dist/node_modules/d3-format/src/formatTypes.js.map +1 -1
- package/dist/node_modules/d3-format/src/identity.js.map +1 -1
- package/dist/node_modules/d3-format/src/locale.js.map +1 -1
- package/dist/node_modules/d3-format/src/precisionFixed.js.map +1 -1
- package/dist/node_modules/d3-format/src/precisionPrefix.js.map +1 -1
- package/dist/node_modules/d3-format/src/precisionRound.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/array.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/basis.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/basisClosed.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/color.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/date.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/number.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/numberArray.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/object.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/piecewise.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/rgb.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/round.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/string.js.map +1 -1
- package/dist/node_modules/d3-interpolate/src/value.js.map +1 -1
- package/dist/node_modules/d3-path/src/path.js.map +1 -1
- package/dist/node_modules/d3-scale/src/band.js.map +1 -1
- package/dist/node_modules/d3-scale/src/constant.js.map +1 -1
- package/dist/node_modules/d3-scale/src/continuous.js.map +1 -1
- package/dist/node_modules/d3-scale/src/diverging.js.map +1 -1
- package/dist/node_modules/d3-scale/src/identity.js.map +1 -1
- package/dist/node_modules/d3-scale/src/init.js.map +1 -1
- package/dist/node_modules/d3-scale/src/linear.js.map +1 -1
- package/dist/node_modules/d3-scale/src/log.js.map +1 -1
- package/dist/node_modules/d3-scale/src/nice.js.map +1 -1
- package/dist/node_modules/d3-scale/src/number.js.map +1 -1
- package/dist/node_modules/d3-scale/src/ordinal.js.map +1 -1
- package/dist/node_modules/d3-scale/src/pow.js.map +1 -1
- package/dist/node_modules/d3-scale/src/quantile.js.map +1 -1
- package/dist/node_modules/d3-scale/src/quantize.js.map +1 -1
- package/dist/node_modules/d3-scale/src/radial.js.map +1 -1
- package/dist/node_modules/d3-scale/src/sequential.js.map +1 -1
- package/dist/node_modules/d3-scale/src/sequentialQuantile.js.map +1 -1
- package/dist/node_modules/d3-scale/src/symlog.js.map +1 -1
- package/dist/node_modules/d3-scale/src/threshold.js.map +1 -1
- package/dist/node_modules/d3-scale/src/tickFormat.js.map +1 -1
- package/dist/node_modules/d3-scale/src/time.js.map +1 -1
- package/dist/node_modules/d3-scale/src/utcTime.js.map +1 -1
- package/dist/node_modules/d3-shape/src/area.js.map +1 -1
- package/dist/node_modules/d3-shape/src/array.js.map +1 -1
- package/dist/node_modules/d3-shape/src/constant.js.map +1 -1
- package/dist/node_modules/d3-shape/src/curve/basis.js.map +1 -1
- package/dist/node_modules/d3-shape/src/curve/basisClosed.js.map +1 -1
- package/dist/node_modules/d3-shape/src/curve/basisOpen.js.map +1 -1
- package/dist/node_modules/d3-shape/src/curve/bump.js.map +1 -1
- package/dist/node_modules/d3-shape/src/curve/linear.js.map +1 -1
- package/dist/node_modules/d3-shape/src/curve/linearClosed.js.map +1 -1
- package/dist/node_modules/d3-shape/src/curve/monotone.js.map +1 -1
- package/dist/node_modules/d3-shape/src/curve/natural.js.map +1 -1
- package/dist/node_modules/d3-shape/src/curve/step.js.map +1 -1
- package/dist/node_modules/d3-shape/src/line.js.map +1 -1
- package/dist/node_modules/d3-shape/src/noop.js.map +1 -1
- package/dist/node_modules/d3-shape/src/offset/expand.js.map +1 -1
- package/dist/node_modules/d3-shape/src/offset/none.js.map +1 -1
- package/dist/node_modules/d3-shape/src/offset/silhouette.js.map +1 -1
- package/dist/node_modules/d3-shape/src/offset/wiggle.js.map +1 -1
- package/dist/node_modules/d3-shape/src/order/none.js.map +1 -1
- package/dist/node_modules/d3-shape/src/path.js.map +1 -1
- package/dist/node_modules/d3-shape/src/point.js.map +1 -1
- package/dist/node_modules/d3-shape/src/stack.js.map +1 -1
- package/dist/node_modules/d3-shape/src/symbol/circle.js.map +1 -1
- package/dist/node_modules/d3-shape/src/symbol/cross.js.map +1 -1
- package/dist/node_modules/d3-shape/src/symbol/diamond.js.map +1 -1
- package/dist/node_modules/d3-shape/src/symbol/square.js.map +1 -1
- package/dist/node_modules/d3-shape/src/symbol/star.js.map +1 -1
- package/dist/node_modules/d3-shape/src/symbol/triangle.js.map +1 -1
- package/dist/node_modules/d3-shape/src/symbol/wye.js.map +1 -1
- package/dist/node_modules/d3-shape/src/symbol.js.map +1 -1
- package/dist/node_modules/d3-time/src/day.js.map +1 -1
- package/dist/node_modules/d3-time/src/hour.js.map +1 -1
- package/dist/node_modules/d3-time/src/interval.js.map +1 -1
- package/dist/node_modules/d3-time/src/millisecond.js.map +1 -1
- package/dist/node_modules/d3-time/src/minute.js.map +1 -1
- package/dist/node_modules/d3-time/src/month.js.map +1 -1
- package/dist/node_modules/d3-time/src/second.js.map +1 -1
- package/dist/node_modules/d3-time/src/ticks.js.map +1 -1
- package/dist/node_modules/d3-time/src/week.js.map +1 -1
- package/dist/node_modules/d3-time/src/year.js.map +1 -1
- package/dist/node_modules/d3-time-format/src/defaultLocale.js.map +1 -1
- package/dist/node_modules/d3-time-format/src/locale.js.map +1 -1
- package/dist/node_modules/decimal.js-light/decimal.js.map +1 -1
- package/dist/node_modules/eventemitter3/index.js.map +1 -1
- package/dist/node_modules/fast-equals/dist/es/index.js.map +1 -1
- package/dist/node_modules/internmap/src/index.js.map +1 -1
- package/dist/node_modules/lodash/_DataView.js.map +1 -1
- package/dist/node_modules/lodash/_Hash.js.map +1 -1
- package/dist/node_modules/lodash/_ListCache.js.map +1 -1
- package/dist/node_modules/lodash/_Map.js.map +1 -1
- package/dist/node_modules/lodash/_MapCache.js.map +1 -1
- package/dist/node_modules/lodash/_Promise.js.map +1 -1
- package/dist/node_modules/lodash/_Set.js.map +1 -1
- package/dist/node_modules/lodash/_SetCache.js.map +1 -1
- package/dist/node_modules/lodash/_Stack.js +2 -1
- package/dist/node_modules/lodash/_Stack.js.map +1 -1
- package/dist/node_modules/lodash/_Symbol.js.map +1 -1
- package/dist/node_modules/lodash/_Uint8Array.js.map +1 -1
- package/dist/node_modules/lodash/_WeakMap.js.map +1 -1
- package/dist/node_modules/lodash/_apply.js.map +1 -1
- package/dist/node_modules/lodash/_arrayEvery.js.map +1 -1
- package/dist/node_modules/lodash/_arrayFilter.js.map +1 -1
- package/dist/node_modules/lodash/_arrayIncludes.js.map +1 -1
- package/dist/node_modules/lodash/_arrayIncludesWith.js.map +1 -1
- package/dist/node_modules/lodash/_arrayLikeKeys.js.map +1 -1
- package/dist/node_modules/lodash/_arrayMap.js.map +1 -1
- package/dist/node_modules/lodash/_arrayPush.js.map +1 -1
- package/dist/node_modules/lodash/_arraySome.js.map +1 -1
- package/dist/node_modules/lodash/_asciiToArray.js.map +1 -1
- package/dist/node_modules/lodash/_assocIndexOf.js.map +1 -1
- package/dist/node_modules/lodash/_baseAssignValue.js.map +1 -1
- package/dist/node_modules/lodash/_baseEach.js.map +1 -1
- package/dist/node_modules/lodash/_baseEvery.js.map +1 -1
- package/dist/node_modules/lodash/_baseExtremum.js.map +1 -1
- package/dist/node_modules/lodash/_baseFindIndex.js.map +1 -1
- package/dist/node_modules/lodash/_baseFlatten.js.map +1 -1
- package/dist/node_modules/lodash/_baseFor.js.map +1 -1
- package/dist/node_modules/lodash/_baseForOwn.js.map +1 -1
- package/dist/node_modules/lodash/_baseGet.js.map +1 -1
- package/dist/node_modules/lodash/_baseGetAllKeys.js.map +1 -1
- package/dist/node_modules/lodash/_baseGetTag.js.map +1 -1
- package/dist/node_modules/lodash/_baseGt.js.map +1 -1
- package/dist/node_modules/lodash/_baseHasIn.js.map +1 -1
- package/dist/node_modules/lodash/_baseIndexOf.js.map +1 -1
- package/dist/node_modules/lodash/_baseIsArguments.js.map +1 -1
- package/dist/node_modules/lodash/_baseIsEqual.js.map +1 -1
- package/dist/node_modules/lodash/_baseIsEqualDeep.js.map +1 -1
- package/dist/node_modules/lodash/_baseIsMatch.js.map +1 -1
- package/dist/node_modules/lodash/_baseIsNaN.js.map +1 -1
- package/dist/node_modules/lodash/_baseIsNative.js.map +1 -1
- package/dist/node_modules/lodash/_baseIsTypedArray.js.map +1 -1
- package/dist/node_modules/lodash/_baseIteratee.js.map +1 -1
- package/dist/node_modules/lodash/_baseKeys.js.map +1 -1
- package/dist/node_modules/lodash/_baseLt.js.map +1 -1
- package/dist/node_modules/lodash/_baseMap.js.map +1 -1
- package/dist/node_modules/lodash/_baseMatches.js.map +1 -1
- package/dist/node_modules/lodash/_baseMatchesProperty.js.map +1 -1
- package/dist/node_modules/lodash/_baseOrderBy.js.map +1 -1
- package/dist/node_modules/lodash/_baseProperty.js.map +1 -1
- package/dist/node_modules/lodash/_basePropertyDeep.js.map +1 -1
- package/dist/node_modules/lodash/_baseRange.js.map +1 -1
- package/dist/node_modules/lodash/_baseRest.js.map +1 -1
- package/dist/node_modules/lodash/_baseSetToString.js.map +1 -1
- package/dist/node_modules/lodash/_baseSlice.js.map +1 -1
- package/dist/node_modules/lodash/_baseSome.js.map +1 -1
- package/dist/node_modules/lodash/_baseSortBy.js.map +1 -1
- package/dist/node_modules/lodash/_baseTimes.js.map +1 -1
- package/dist/node_modules/lodash/_baseToString.js.map +1 -1
- package/dist/node_modules/lodash/_baseTrim.js.map +1 -1
- package/dist/node_modules/lodash/_baseUnary.js.map +1 -1
- package/dist/node_modules/lodash/_baseUniq.js.map +1 -1
- package/dist/node_modules/lodash/_cacheHas.js.map +1 -1
- package/dist/node_modules/lodash/_castPath.js.map +1 -1
- package/dist/node_modules/lodash/_castSlice.js.map +1 -1
- package/dist/node_modules/lodash/_compareAscending.js.map +1 -1
- package/dist/node_modules/lodash/_compareMultiple.js.map +1 -1
- package/dist/node_modules/lodash/_coreJsData.js.map +1 -1
- package/dist/node_modules/lodash/_createBaseEach.js.map +1 -1
- package/dist/node_modules/lodash/_createBaseFor.js.map +1 -1
- package/dist/node_modules/lodash/_createCaseFirst.js.map +1 -1
- package/dist/node_modules/lodash/_createFind.js.map +1 -1
- package/dist/node_modules/lodash/_createRange.js.map +1 -1
- package/dist/node_modules/lodash/_createSet.js.map +1 -1
- package/dist/node_modules/lodash/_defineProperty.js.map +1 -1
- package/dist/node_modules/lodash/_equalArrays.js.map +1 -1
- package/dist/node_modules/lodash/_equalByTag.js.map +1 -1
- package/dist/node_modules/lodash/_equalObjects.js.map +1 -1
- package/dist/node_modules/lodash/_freeGlobal.js.map +1 -1
- package/dist/node_modules/lodash/_getAllKeys.js.map +1 -1
- package/dist/node_modules/lodash/_getMapData.js.map +1 -1
- package/dist/node_modules/lodash/_getMatchData.js.map +1 -1
- package/dist/node_modules/lodash/_getNative.js.map +1 -1
- package/dist/node_modules/lodash/_getPrototype.js.map +1 -1
- package/dist/node_modules/lodash/_getRawTag.js.map +1 -1
- package/dist/node_modules/lodash/_getSymbols.js.map +1 -1
- package/dist/node_modules/lodash/_getTag.js.map +1 -1
- package/dist/node_modules/lodash/_getValue.js.map +1 -1
- package/dist/node_modules/lodash/_hasPath.js.map +1 -1
- package/dist/node_modules/lodash/_hasUnicode.js.map +1 -1
- package/dist/node_modules/lodash/_hashClear.js.map +1 -1
- package/dist/node_modules/lodash/_hashDelete.js.map +1 -1
- package/dist/node_modules/lodash/_hashGet.js.map +1 -1
- package/dist/node_modules/lodash/_hashHas.js.map +1 -1
- package/dist/node_modules/lodash/_hashSet.js.map +1 -1
- package/dist/node_modules/lodash/_isFlattenable.js.map +1 -1
- package/dist/node_modules/lodash/_isIndex.js.map +1 -1
- package/dist/node_modules/lodash/_isIterateeCall.js.map +1 -1
- package/dist/node_modules/lodash/_isKey.js.map +1 -1
- package/dist/node_modules/lodash/_isKeyable.js.map +1 -1
- package/dist/node_modules/lodash/_isMasked.js.map +1 -1
- package/dist/node_modules/lodash/_isPrototype.js.map +1 -1
- package/dist/node_modules/lodash/_isStrictComparable.js.map +1 -1
- package/dist/node_modules/lodash/_listCacheClear.js.map +1 -1
- package/dist/node_modules/lodash/_listCacheDelete.js.map +1 -1
- package/dist/node_modules/lodash/_listCacheGet.js.map +1 -1
- package/dist/node_modules/lodash/_listCacheHas.js.map +1 -1
- package/dist/node_modules/lodash/_listCacheSet.js.map +1 -1
- package/dist/node_modules/lodash/_mapCacheClear.js.map +1 -1
- package/dist/node_modules/lodash/_mapCacheDelete.js.map +1 -1
- package/dist/node_modules/lodash/_mapCacheGet.js.map +1 -1
- package/dist/node_modules/lodash/_mapCacheHas.js.map +1 -1
- package/dist/node_modules/lodash/_mapCacheSet.js.map +1 -1
- package/dist/node_modules/lodash/_mapToArray.js.map +1 -1
- package/dist/node_modules/lodash/_matchesStrictComparable.js.map +1 -1
- package/dist/node_modules/lodash/_memoizeCapped.js.map +1 -1
- package/dist/node_modules/lodash/_nativeCreate.js.map +1 -1
- package/dist/node_modules/lodash/_nativeKeys.js.map +1 -1
- package/dist/node_modules/lodash/_nodeUtil.js.map +1 -1
- package/dist/node_modules/lodash/_objectToString.js.map +1 -1
- package/dist/node_modules/lodash/_overArg.js.map +1 -1
- package/dist/node_modules/lodash/_overRest.js.map +1 -1
- package/dist/node_modules/lodash/_root.js.map +1 -1
- package/dist/node_modules/lodash/_setCacheAdd.js.map +1 -1
- package/dist/node_modules/lodash/_setCacheHas.js.map +1 -1
- package/dist/node_modules/lodash/_setToArray.js.map +1 -1
- package/dist/node_modules/lodash/_setToString.js.map +1 -1
- package/dist/node_modules/lodash/_shortOut.js.map +1 -1
- package/dist/node_modules/lodash/_stackClear.js.map +1 -1
- package/dist/node_modules/lodash/_stackDelete.js.map +1 -1
- package/dist/node_modules/lodash/_stackGet.js.map +1 -1
- package/dist/node_modules/lodash/_stackHas.js.map +1 -1
- package/dist/node_modules/lodash/_stackSet.js.map +1 -1
- package/dist/node_modules/lodash/_strictIndexOf.js.map +1 -1
- package/dist/node_modules/lodash/_stringToArray.js.map +1 -1
- package/dist/node_modules/lodash/_stringToPath.js.map +1 -1
- package/dist/node_modules/lodash/_toKey.js.map +1 -1
- package/dist/node_modules/lodash/_toSource.js.map +1 -1
- package/dist/node_modules/lodash/_trimmedEndIndex.js.map +1 -1
- package/dist/node_modules/lodash/_unicodeToArray.js.map +1 -1
- package/dist/node_modules/lodash/constant.js.map +1 -1
- package/dist/node_modules/lodash/debounce.js.map +1 -1
- package/dist/node_modules/lodash/eq.js.map +1 -1
- package/dist/node_modules/lodash/every.js.map +1 -1
- package/dist/node_modules/lodash/find.js.map +1 -1
- package/dist/node_modules/lodash/findIndex.js.map +1 -1
- package/dist/node_modules/lodash/flatMap.js.map +1 -1
- package/dist/node_modules/lodash/get.js.map +1 -1
- package/dist/node_modules/lodash/hasIn.js.map +1 -1
- package/dist/node_modules/lodash/identity.js.map +1 -1
- package/dist/node_modules/lodash/isArguments.js.map +1 -1
- package/dist/node_modules/lodash/isArray.js.map +1 -1
- package/dist/node_modules/lodash/isArrayLike.js.map +1 -1
- package/dist/node_modules/lodash/isBoolean.js.map +1 -1
- package/dist/node_modules/lodash/isBuffer.js.map +1 -1
- package/dist/node_modules/lodash/isEqual.js.map +1 -1
- package/dist/node_modules/lodash/isFunction.js.map +1 -1
- package/dist/node_modules/lodash/isLength.js.map +1 -1
- package/dist/node_modules/lodash/isNaN.js.map +1 -1
- package/dist/node_modules/lodash/isNil.js.map +1 -1
- package/dist/node_modules/lodash/isNumber.js.map +1 -1
- package/dist/node_modules/lodash/isObject.js.map +1 -1
- package/dist/node_modules/lodash/isObjectLike.js.map +1 -1
- package/dist/node_modules/lodash/isPlainObject.js.map +1 -1
- package/dist/node_modules/lodash/isString.js.map +1 -1
- package/dist/node_modules/lodash/isSymbol.js.map +1 -1
- package/dist/node_modules/lodash/isTypedArray.js.map +1 -1
- package/dist/node_modules/lodash/keys.js.map +1 -1
- package/dist/node_modules/lodash/last.js.map +1 -1
- package/dist/node_modules/lodash/map.js.map +1 -1
- package/dist/node_modules/lodash/mapValues.js.map +1 -1
- package/dist/node_modules/lodash/max.js.map +1 -1
- package/dist/node_modules/lodash/maxBy.js.map +1 -1
- package/dist/node_modules/lodash/memoize.js.map +1 -1
- package/dist/node_modules/lodash/min.js.map +1 -1
- package/dist/node_modules/lodash/minBy.js.map +1 -1
- package/dist/node_modules/lodash/noop.js.map +1 -1
- package/dist/node_modules/lodash/now.js.map +1 -1
- package/dist/node_modules/lodash/property.js.map +1 -1
- package/dist/node_modules/lodash/range.js.map +1 -1
- package/dist/node_modules/lodash/some.js.map +1 -1
- package/dist/node_modules/lodash/sortBy.js.map +1 -1
- package/dist/node_modules/lodash/stubArray.js.map +1 -1
- package/dist/node_modules/lodash/stubFalse.js.map +1 -1
- package/dist/node_modules/lodash/throttle.js.map +1 -1
- package/dist/node_modules/lodash/toFinite.js.map +1 -1
- package/dist/node_modules/lodash/toInteger.js.map +1 -1
- package/dist/node_modules/lodash/toNumber.js.map +1 -1
- package/dist/node_modules/lodash/toString.js.map +1 -1
- package/dist/node_modules/lodash/uniqBy.js.map +1 -1
- package/dist/node_modules/lodash/upperFirst.js.map +1 -1
- package/dist/node_modules/object-assign/index.js.map +1 -1
- package/dist/node_modules/prop-types/checkPropTypes.js.map +1 -1
- package/dist/node_modules/prop-types/factoryWithThrowingShims.js.map +1 -1
- package/dist/node_modules/prop-types/factoryWithTypeCheckers.js.map +1 -1
- package/dist/node_modules/prop-types/index.js.map +1 -1
- package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js.map +1 -1
- package/dist/node_modules/prop-types/lib/has.js.map +1 -1
- package/dist/node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js.map +1 -1
- package/dist/node_modules/prop-types/node_modules/react-is/cjs/react-is.production.min.js.map +1 -1
- package/dist/node_modules/prop-types/node_modules/react-is/index.js.map +1 -1
- package/dist/node_modules/react-is/cjs/react-is.development.js.map +1 -1
- package/dist/node_modules/react-is/cjs/react-is.production.min.js.map +1 -1
- package/dist/node_modules/react-is/index.js.map +1 -1
- package/dist/node_modules/react-smooth/es6/Animate.js +2 -2
- package/dist/node_modules/react-smooth/es6/Animate.js.map +1 -1
- package/dist/node_modules/react-smooth/es6/AnimateManager.js.map +1 -1
- package/dist/node_modules/react-smooth/es6/configUpdate.js.map +1 -1
- package/dist/node_modules/react-smooth/es6/easing.js.map +1 -1
- package/dist/node_modules/react-smooth/es6/setRafTimeout.js.map +1 -1
- package/dist/node_modules/react-smooth/es6/util.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/Area.js +13 -13
- package/dist/node_modules/recharts/es6/cartesian/Area.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/Bar.js +9 -9
- package/dist/node_modules/recharts/es6/cartesian/Bar.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/Brush.js +12 -12
- package/dist/node_modules/recharts/es6/cartesian/Brush.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/CartesianAxis.js +7 -7
- package/dist/node_modules/recharts/es6/cartesian/CartesianAxis.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/ErrorBar.js +4 -4
- package/dist/node_modules/recharts/es6/cartesian/ErrorBar.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/ReferenceArea.js +3 -3
- package/dist/node_modules/recharts/es6/cartesian/ReferenceArea.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/ReferenceDot.js +3 -3
- package/dist/node_modules/recharts/es6/cartesian/ReferenceDot.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/ReferenceLine.js +4 -4
- package/dist/node_modules/recharts/es6/cartesian/ReferenceLine.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/XAxis.js +3 -3
- package/dist/node_modules/recharts/es6/cartesian/XAxis.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/YAxis.js +3 -3
- package/dist/node_modules/recharts/es6/cartesian/YAxis.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/getEquidistantTicks.js.map +1 -1
- package/dist/node_modules/recharts/es6/cartesian/getTicks.js.map +1 -1
- package/dist/node_modules/recharts/es6/chart/AccessibilityManager.js +1 -1
- package/dist/node_modules/recharts/es6/chart/AccessibilityManager.js.map +1 -1
- package/dist/node_modules/recharts/es6/chart/AreaChart.js.map +1 -1
- package/dist/node_modules/recharts/es6/chart/BarChart.js.map +1 -1
- package/dist/node_modules/recharts/es6/chart/PieChart.js.map +1 -1
- package/dist/node_modules/recharts/es6/chart/generateCategoricalChart.js +22 -22
- package/dist/node_modules/recharts/es6/chart/generateCategoricalChart.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/Cell.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/Cursor.js +1 -1
- package/dist/node_modules/recharts/es6/component/Cursor.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/DefaultLegendContent.js +11 -11
- package/dist/node_modules/recharts/es6/component/DefaultLegendContent.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/DefaultTooltipContent.js +6 -6
- package/dist/node_modules/recharts/es6/component/DefaultTooltipContent.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/Label.js +14 -14
- package/dist/node_modules/recharts/es6/component/Label.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/LabelList.js +6 -6
- package/dist/node_modules/recharts/es6/component/LabelList.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/Legend.js +5 -5
- package/dist/node_modules/recharts/es6/component/Legend.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/ResponsiveContainer.js +3 -3
- package/dist/node_modules/recharts/es6/component/ResponsiveContainer.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/Text.js +2 -2
- package/dist/node_modules/recharts/es6/component/Text.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/Tooltip.js +3 -3
- package/dist/node_modules/recharts/es6/component/Tooltip.js.map +1 -1
- package/dist/node_modules/recharts/es6/component/TooltipBoundingBox.js +2 -2
- package/dist/node_modules/recharts/es6/component/TooltipBoundingBox.js.map +1 -1
- package/dist/node_modules/recharts/es6/container/Layer.js +2 -2
- package/dist/node_modules/recharts/es6/container/Layer.js.map +1 -1
- package/dist/node_modules/recharts/es6/container/Surface.js +2 -2
- package/dist/node_modules/recharts/es6/container/Surface.js.map +1 -1
- package/dist/node_modules/recharts/es6/context/chartLayoutContext.js +2 -2
- package/dist/node_modules/recharts/es6/context/chartLayoutContext.js.map +1 -1
- package/dist/node_modules/recharts/es6/polar/Pie.js +13 -13
- package/dist/node_modules/recharts/es6/polar/Pie.js.map +1 -1
- package/dist/node_modules/recharts/es6/polar/PolarAngleAxis.js +8 -8
- package/dist/node_modules/recharts/es6/polar/PolarAngleAxis.js.map +1 -1
- package/dist/node_modules/recharts/es6/polar/PolarRadiusAxis.js +6 -6
- package/dist/node_modules/recharts/es6/polar/PolarRadiusAxis.js.map +1 -1
- package/dist/node_modules/recharts/es6/shape/Cross.js +1 -1
- package/dist/node_modules/recharts/es6/shape/Cross.js.map +1 -1
- package/dist/node_modules/recharts/es6/shape/Curve.js +1 -1
- package/dist/node_modules/recharts/es6/shape/Curve.js.map +1 -1
- package/dist/node_modules/recharts/es6/shape/Dot.js +1 -1
- package/dist/node_modules/recharts/es6/shape/Dot.js.map +1 -1
- package/dist/node_modules/recharts/es6/shape/Polygon.js +4 -4
- package/dist/node_modules/recharts/es6/shape/Polygon.js.map +1 -1
- package/dist/node_modules/recharts/es6/shape/Rectangle.js +4 -4
- package/dist/node_modules/recharts/es6/shape/Rectangle.js.map +1 -1
- package/dist/node_modules/recharts/es6/shape/Sector.js +1 -1
- package/dist/node_modules/recharts/es6/shape/Sector.js.map +1 -1
- package/dist/node_modules/recharts/es6/shape/Symbols.js +1 -1
- package/dist/node_modules/recharts/es6/shape/Symbols.js.map +1 -1
- package/dist/node_modules/recharts/es6/shape/Trapezoid.js +4 -4
- package/dist/node_modules/recharts/es6/shape/Trapezoid.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/ActiveShapeUtils.js +9 -9
- package/dist/node_modules/recharts/es6/util/ActiveShapeUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/BarUtils.js +1 -1
- package/dist/node_modules/recharts/es6/util/BarUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/CartesianUtils.js +1 -1
- package/dist/node_modules/recharts/es6/util/CartesianUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/ChartUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/CssPrefixUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/DOMUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/DataUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/DetectReferenceElementsDomain.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/Events.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/Global.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/IfOverflowMatches.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/LogUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/PolarUtils.js +1 -1
- package/dist/node_modules/recharts/es6/util/PolarUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/ReactUtils.js +1 -1
- package/dist/node_modules/recharts/es6/util/ReactUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/ReduceCSSCalc.js +1 -1
- package/dist/node_modules/recharts/es6/util/ReduceCSSCalc.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/ShallowEqual.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/TickUtils.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/calculateViewBox.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/cursor/getCursorPoints.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/cursor/getCursorRectangle.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/cursor/getRadialCursorPoints.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/getEveryNthWithCondition.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/getLegendProps.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/isDomainSpecifiedByUser.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/payload/getUniqPayload.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/tooltip/translate.js.map +1 -1
- package/dist/node_modules/recharts/es6/util/types.js +1 -1
- package/dist/node_modules/recharts/es6/util/types.js.map +1 -1
- package/dist/node_modules/recharts-scale/es6/getNiceTickValues.js.map +1 -1
- package/dist/node_modules/recharts-scale/es6/util/arithmetic.js.map +1 -1
- package/dist/node_modules/recharts-scale/es6/util/utils.js.map +1 -1
- package/dist/node_modules/sonner/dist/index.js.map +1 -1
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1 -1
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -1
- package/dist/node_modules/tiny-invariant/dist/esm/tiny-invariant.js.map +1 -1
- package/dist/stories/LoadMore.stories.d.ts +0 -1
- package/package.json +15 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/brainyrich/pages/DashboardPage.tsx"],"sourcesContent":["import { useMemo, useState, type FormEvent, type ReactNode } from 'react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CardDescription,\n Button,\n Badge,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Target,\n Bell,\n Briefcase,\n Wallet,\n PlusCircle,\n MoreHorizontal,\n Check,\n X,\n CircleCheck,\n TrendingUp,\n Coins,\n Landmark,\n TriangleAlert,\n Info,\n ShieldAlert,\n} from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n useNetWorthSummary,\n usePortfolios,\n useGoals,\n useInsights,\n useCreateAccount,\n useAcknowledgeInsight,\n useDismissInsight,\n useResolveInsight,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraAccountType,\n BraAssetClass,\n BraCreateAccountInput,\n BraInsight,\n BraInsightSeverity,\n} from '../types/bra';\nimport {\n HouseholdPicker,\n ConfirmDialog,\n DonutChart,\n StatTile,\n GlassCard,\n FadeIn,\n type VizTone,\n type DonutDatum,\n} from '../components';\nimport {\n SectionShell,\n EmptyState,\n LoadingState,\n ErrorState,\n formatMoney,\n formatCompact,\n formatDate,\n statusBadgeVariant,\n} from './_shared';\nimport { hapticSuccess, showToast } from '../utils/nativeControls';\nimport { useTrackBrainyRichPageView } from '../hooks/useBrainyRichAnalytics';\n\nconst ACCOUNT_TYPES: BraAccountType[] = [\n 'BANK',\n 'BROKERAGE',\n 'RETIREMENT',\n 'CASH',\n 'CRYPTO',\n 'REAL_ESTATE',\n 'ALTERNATIVE',\n 'LIABILITY',\n];\n\n/** Distinct, semantic tone per asset class so the donut stays legible + on-brand. */\nconst ASSET_TONE: Record<BraAssetClass, VizTone> = {\n EQUITY: 'brand',\n FIXED_INCOME: 'blue',\n CASH: 'teal',\n REAL_ESTATE: 'indigo',\n COMMODITY: 'warning',\n CRYPTO: 'purple',\n ALTERNATIVE: 'info',\n};\n\n/** Title-case an enum member: FIXED_INCOME → \"Fixed income\". */\nfunction prettyLabel(value: string): string {\n const spaced = value.replace(/_/g, ' ').toLowerCase();\n return spaced.charAt(0).toUpperCase() + spaced.slice(1);\n}\n\nexport function DashboardPage() {\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.dashboard.viewed');\n\n const summaryQuery = useNetWorthSummary();\n const portfoliosQuery = usePortfolios();\n const goalsQuery = useGoals();\n const insightsQuery = useInsights({ status: 'OPEN' });\n\n const summary = summaryQuery.data;\n const currency = summary?.currency ?? 'USD';\n\n const kpis: HeroStat[] = summary\n ? [\n {\n label: translate('brainyrich.dashboard.metrics.netWorth', 'Net Worth'),\n value: formatCompact(summary.totalNetWorth, currency),\n icon: <Wallet className=\"size-4\" aria-hidden=\"true\" />,\n glow: true,\n },\n {\n label: translate('brainyrich.dashboard.metrics.investedAssets', 'Invested Assets'),\n value: formatCompact(summary.totalMarketValue, currency),\n icon: <TrendingUp className=\"size-4\" aria-hidden=\"true\" />,\n },\n {\n label: translate('brainyrich.dashboard.metrics.liquidity', 'Cash & Liquidity'),\n value: formatCompact(summary.totalCash, currency),\n icon: <Coins className=\"size-4\" aria-hidden=\"true\" />,\n },\n {\n label: translate('brainyrich.dashboard.metrics.accounts', 'Linked Accounts'),\n value: String(summary.accountCount),\n icon: <Landmark className=\"size-4\" aria-hidden=\"true\" />,\n },\n ]\n : [];\n\n const donutData: DonutDatum[] = useMemo(() => {\n if (!summary) return [];\n return summary.byAssetClass\n .filter((row) => Number.isFinite(row.marketValue) && row.marketValue > 0)\n .slice()\n .sort((a, b) => b.marketValue - a.marketValue)\n .map((row) => ({\n label: prettyLabel(row.assetClass),\n value: row.marketValue,\n tone: ASSET_TONE[row.assetClass],\n }));\n }, [summary]);\n\n const topPortfolios = portfoliosQuery.data.slice(0, 5);\n const topGoals = goalsQuery.data.slice(0, 5);\n const openInsights = insightsQuery.data.slice(0, 6);\n\n return (\n <div data-tour=\"brainyrich-page-dashboard\" className=\"contents\">\n <SectionShell\n title={translate('brainyrich.dashboard.title', 'Wealth Dashboard')}\n description={translate(\n 'brainyrich.dashboard.description',\n 'Your consolidated financial overview at a glance'\n )}\n actions={<NewAccountDialog translate={translate} />}\n >\n {/* Hero KPI row — net-worth overview */}\n {summaryQuery.isLoading ? (\n <LoadingState rows={1} />\n ) : summaryQuery.isError ? (\n <ErrorState\n title={translate('brainyrich.dashboard.netWorthError', 'Could not load net worth')}\n onRetry={() => summaryQuery.refetch()}\n />\n ) : summary ? (\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n {kpis.map((kpi, i) => (\n <FadeIn key={kpi.label} index={i}>\n <StatTile\n label={kpi.label}\n value={kpi.value}\n icon={kpi.icon}\n glow={kpi.glow}\n className=\"h-full\"\n />\n </FadeIn>\n ))}\n </div>\n ) : (\n <EmptyState\n icon={<Wallet className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.dashboard.noSummary', 'No financial data yet')}\n description={translate(\n 'brainyrich.dashboard.noSummaryDesc',\n 'Link your first account to see your net worth here.'\n )}\n />\n )}\n\n <div className=\"grid gap-6 lg:grid-cols-3\">\n {/* Net worth by asset class — donut hero */}\n <FadeIn index={0} className=\"lg:col-span-2\">\n <GlassCard className=\"h-full\">\n <div className=\"mb-4 space-y-1\">\n <h2 className=\"flex items-center gap-2 text-base font-semibold text-text-primary\">\n <Briefcase className=\"size-5\" aria-hidden=\"true\" />\n {translate(\n 'brainyrich.dashboard.sections.assetAllocation',\n 'Net worth by asset class'\n )}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.dashboard.sections.assetAllocationDescription',\n 'Market value distributed across asset classes'\n )}\n </p>\n </div>\n {summaryQuery.isLoading ? (\n <LoadingState rows={3} />\n ) : summaryQuery.isError ? (\n <ErrorState onRetry={() => summaryQuery.refetch()} />\n ) : donutData.length > 0 ? (\n <DonutChart\n data={donutData}\n height={260}\n centerValue={formatCompact(summary?.totalMarketValue ?? 0, currency)}\n centerLabel={translate('brainyrich.dashboard.metrics.investedAssets', 'Invested')}\n valueFormatter={(v) => formatMoney(v, currency)}\n />\n ) : (\n <EmptyState\n icon={<Briefcase className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.dashboard.noAllocation', 'No holdings to allocate')}\n description={translate(\n 'brainyrich.dashboard.noAllocationDesc',\n 'Add holdings to your accounts to see how your wealth is allocated.'\n )}\n />\n )}\n </GlassCard>\n </FadeIn>\n\n {/* Right rail — needs attention + goals */}\n <div className=\"space-y-6\">\n {/* Needs attention — open insights */}\n <FadeIn index={1}>\n <Card className=\"motion-safe:transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <CardHeader className=\"pb-3\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Bell className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.sections.needsAttention', 'Needs attention')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2.5\">\n {insightsQuery.isLoading ? (\n <LoadingState rows={2} />\n ) : insightsQuery.isError ? (\n <ErrorState onRetry={() => insightsQuery.refetch()} />\n ) : openInsights.length > 0 ? (\n openInsights.map((insight) => (\n <InsightRow key={insight.id} insight={insight} translate={translate} />\n ))\n ) : (\n <EmptyState\n icon={<CircleCheck className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.dashboard.noInsights', 'All clear')}\n description={translate(\n 'brainyrich.dashboard.noInsightsDesc',\n 'There are no open insights that need your attention.'\n )}\n />\n )}\n </CardContent>\n </Card>\n </FadeIn>\n\n {/* Goals on track */}\n <FadeIn index={2}>\n <Card className=\"motion-safe:transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <CardHeader className=\"pb-3\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Target className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.sections.goals', 'Goals on track')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2.5\">\n {goalsQuery.isLoading ? (\n <LoadingState rows={3} />\n ) : goalsQuery.isError ? (\n <ErrorState onRetry={() => goalsQuery.refetch()} />\n ) : topGoals.length > 0 ? (\n topGoals.map((goal) => (\n <div\n key={goal.id}\n className=\"flex items-start justify-between gap-2 rounded-lg border border-border-subtle p-3 motion-safe:transition-colors hover:border-[var(--color-action-primary-border)]/50 hover:bg-bg-elevated\"\n >\n <div className=\"min-w-0 space-y-0.5\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {goal.name}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {formatMoney(goal.targetAmount, goal.currency)}\n {' · '}\n {formatDate(goal.targetDate)}\n </p>\n </div>\n <Badge variant={statusBadgeVariant(goal.projection)} className=\"shrink-0\">\n {prettyLabel(goal.projection)}\n </Badge>\n </div>\n ))\n ) : (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.dashboard.noGoals', 'No goals yet')}\n description={translate(\n 'brainyrich.dashboard.noGoalsDesc',\n 'Set a financial goal to start tracking progress.'\n )}\n />\n )}\n </CardContent>\n </Card>\n </FadeIn>\n </div>\n </div>\n\n {/* Portfolios mini-list */}\n <FadeIn index={3}>\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Wallet className=\"size-5\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.sections.portfolios', 'Portfolios')}\n </CardTitle>\n <CardDescription>\n {translate(\n 'brainyrich.dashboard.sections.portfoliosDescription',\n 'Your active investment strategies'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent>\n {portfoliosQuery.isLoading ? (\n <LoadingState rows={3} />\n ) : portfoliosQuery.isError ? (\n <ErrorState onRetry={() => portfoliosQuery.refetch()} />\n ) : topPortfolios.length > 0 ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {topPortfolios.map((portfolio) => (\n <div\n key={portfolio.id}\n className=\"flex items-start justify-between gap-2 rounded-lg border border-border-subtle p-3 motion-safe:transition-colors hover:border-[var(--color-action-primary-border)]/50 hover:bg-bg-elevated\"\n >\n <div className=\"min-w-0 space-y-0.5\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {portfolio.name}\n </p>\n {portfolio.description ? (\n <p className=\"truncate text-xs text-text-secondary\">\n {portfolio.description}\n </p>\n ) : (\n <p className=\"text-xs text-text-secondary\">{portfolio.baseCurrency}</p>\n )}\n </div>\n <Badge variant={statusBadgeVariant(portfolio.status)} className=\"shrink-0\">\n {portfolio.status}\n </Badge>\n </div>\n ))}\n </div>\n ) : (\n <EmptyState\n icon={<Wallet className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.dashboard.noPortfolios', 'No portfolios yet')}\n description={translate(\n 'brainyrich.dashboard.noPortfoliosDesc',\n 'Create a portfolio to organize your investment strategy.'\n )}\n />\n )}\n </CardContent>\n </Card>\n </FadeIn>\n </SectionShell>\n </div>\n );\n}\n\ninterface HeroStat {\n label: string;\n value: string;\n icon: ReactNode;\n glow?: boolean;\n}\n\ntype Translate = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>\n) => string;\n\n// ============================================================================\n// Severity chip — tinted, icon + label (colour is never the only signal)\n// ============================================================================\n\nconst SEVERITY_STYLE: Record<BraInsightSeverity, { chip: string; rail: string; icon: ReactNode }> =\n {\n CRITICAL: {\n chip: 'text-status-error-text bg-status-error-bg',\n rail: 'bg-status-error',\n icon: <ShieldAlert className=\"size-3\" aria-hidden=\"true\" />,\n },\n HIGH: {\n chip: 'text-status-error-text bg-status-error-bg',\n rail: 'bg-status-error',\n icon: <TriangleAlert className=\"size-3\" aria-hidden=\"true\" />,\n },\n MEDIUM: {\n chip: 'text-status-warning-text bg-status-warning-bg',\n rail: 'bg-status-warning',\n icon: <TriangleAlert className=\"size-3\" aria-hidden=\"true\" />,\n },\n LOW: {\n chip: 'text-status-info-text bg-status-info-bg',\n rail: 'bg-status-info',\n icon: <Info className=\"size-3\" aria-hidden=\"true\" />,\n },\n INFO: {\n chip: 'text-status-info-text bg-status-info-bg',\n rail: 'bg-status-info',\n icon: <Info className=\"size-3\" aria-hidden=\"true\" />,\n },\n };\n\nfunction SeverityChip({ severity }: { severity: BraInsightSeverity }) {\n const style = SEVERITY_STYLE[severity] ?? SEVERITY_STYLE.INFO;\n return (\n <span\n className={`inline-flex shrink-0 items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${style.chip}`}\n >\n {style.icon}\n {severity}\n </span>\n );\n}\n\n// ============================================================================\n// Insight row with acknowledge / dismiss / resolve actions\n// ============================================================================\n\nfunction InsightRow({ insight, translate }: { insight: BraInsight; translate: Translate }) {\n const acknowledge = useAcknowledgeInsight();\n const dismiss = useDismissInsight();\n const resolve = useResolveInsight();\n const [confirmDismiss, setConfirmDismiss] = useState(false);\n const pending = acknowledge.isPending || dismiss.isPending || resolve.isPending;\n const rail = (SEVERITY_STYLE[insight.severity] ?? SEVERITY_STYLE.INFO).rail;\n\n return (\n <div className=\"relative flex items-start justify-between gap-3 overflow-hidden rounded-lg border border-border-subtle p-3 pl-4 motion-safe:transition-colors hover:border-[var(--color-action-primary-border)]/50 hover:bg-bg-elevated\">\n <span aria-hidden=\"true\" className={`absolute inset-y-0 left-0 w-1 ${rail}`} />\n <div className=\"min-w-0 space-y-1\">\n <div className=\"flex items-center gap-2\">\n <SeverityChip severity={insight.severity} />\n <span className=\"truncate text-xs text-text-secondary\">{prettyLabel(insight.type)}</span>\n </div>\n <p className=\"text-sm font-medium text-text-primary\">{insight.title}</p>\n {insight.detail ? <p className=\"text-xs text-text-secondary\">{insight.detail}</p> : null}\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"shrink-0\"\n disabled={pending}\n aria-label={translate('brainyrich.dashboard.insightActions', 'Insight actions')}\n >\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onSelect={() => acknowledge.mutate(insight.id)}>\n <Check className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.insight.acknowledge', 'Acknowledge')}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => resolve.mutate(insight.id)}>\n <CircleCheck className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.insight.resolve', 'Resolve')}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => setConfirmDismiss(true)}>\n <X className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.insight.dismiss', 'Dismiss')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n\n <ConfirmDialog\n open={confirmDismiss}\n onOpenChange={setConfirmDismiss}\n title={translate('brainyrich.dashboard.insight.dismissTitle', 'Dismiss this insight?')}\n description={translate(\n 'brainyrich.dashboard.insight.dismissDescription',\n 'It will be removed from Needs Attention. You can still find it in the full insights list.'\n )}\n confirmLabel={translate('brainyrich.dashboard.insight.dismiss', 'Dismiss')}\n pendingLabel={translate('brainyrich.dashboard.insight.dismissing', 'Dismissing…')}\n destructive\n pending={dismiss.isPending}\n onConfirm={() =>\n dismiss.mutate(insight.id, {\n onSuccess: () => setConfirmDismiss(false),\n })\n }\n />\n </div>\n );\n}\n\n// ============================================================================\n// New account dialog — primary create action\n// ============================================================================\n\nfunction NewAccountDialog({ translate }: { translate: Translate }) {\n const [open, setOpen] = useState(false);\n const [name, setName] = useState('');\n const [type, setType] = useState<BraAccountType>('BROKERAGE');\n const [institution, setInstitution] = useState('');\n const [cashBalance, setCashBalance] = useState('');\n const [currency, setCurrency] = useState('USD');\n const [householdId, setHouseholdId] = useState<string | null>(null);\n\n const createAccount = useCreateAccount();\n const trimmedName = name.trim();\n const canSubmit = trimmedName.length > 0 && !createAccount.isPending;\n\n const reset = () => {\n setName('');\n setType('BROKERAGE');\n setInstitution('');\n setCashBalance('');\n setCurrency('USD');\n setHouseholdId(null);\n createAccount.reset();\n };\n\n const handleSubmit = (event: FormEvent) => {\n event.preventDefault();\n if (!canSubmit) return;\n const parsedCash = Number.parseFloat(cashBalance);\n const input: BraCreateAccountInput = {\n name: trimmedName,\n type,\n currency: currency.trim() || 'USD',\n isManual: true,\n ...(institution.trim() ? { institution: institution.trim() } : {}),\n ...(Number.isFinite(parsedCash) ? { cashBalance: parsedCash } : {}),\n ...(householdId ? { householdId } : {}),\n };\n createAccount.mutate(input, {\n onSuccess: () => {\n hapticSuccess();\n void showToast(translate('brainyrich.dashboard.newAccount.success', 'Account created'));\n reset();\n setOpen(false);\n },\n });\n };\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) reset();\n }}\n >\n <Button size=\"sm\" onClick={() => setOpen(true)}>\n <PlusCircle className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.actions.newAccount', 'New Account')}\n </Button>\n <DialogContent>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <DialogHeader>\n <DialogTitle>\n {translate('brainyrich.dashboard.newAccount.title', 'New Account')}\n </DialogTitle>\n <DialogDescription>\n {translate(\n 'brainyrich.dashboard.newAccount.description',\n 'Add a manual account to track alongside your linked institutions.'\n )}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-account-name\">\n {translate('brainyrich.dashboard.newAccount.name', 'Account name')}\n </Label>\n <Input\n id=\"bra-account-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={translate(\n 'brainyrich.dashboard.newAccount.namePlaceholder',\n 'e.g. Fidelity Brokerage'\n )}\n required\n autoFocus\n />\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-account-type\">\n {translate('brainyrich.dashboard.newAccount.type', 'Type')}\n </Label>\n <Select value={type} onValueChange={(value) => setType(value as BraAccountType)}>\n <SelectTrigger id=\"bra-account-type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ACCOUNT_TYPES.map((accountType) => (\n <SelectItem key={accountType} value={accountType}>\n {accountType.replace(/_/g, ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-account-currency\">\n {translate('brainyrich.dashboard.newAccount.currency', 'Currency')}\n </Label>\n <Input\n id=\"bra-account-currency\"\n value={currency}\n onChange={(e) => setCurrency(e.target.value.toUpperCase())}\n maxLength={3}\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-account-institution\">\n {translate('brainyrich.dashboard.newAccount.institution', 'Institution (optional)')}\n </Label>\n <Input\n id=\"bra-account-institution\"\n value={institution}\n onChange={(e) => setInstitution(e.target.value)}\n placeholder={translate(\n 'brainyrich.dashboard.newAccount.institutionPlaceholder',\n 'e.g. Fidelity'\n )}\n />\n </div>\n\n <HouseholdPicker\n id=\"bra-account-household\"\n value={householdId}\n onChange={setHouseholdId}\n label={translate('brainyrich.dashboard.newAccount.household', 'Household (optional)')}\n noneLabel={translate('brainyrich.dashboard.newAccount.noHousehold', 'No household')}\n disabled={createAccount.isPending}\n />\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-account-cash\">\n {translate('brainyrich.dashboard.newAccount.cash', 'Cash balance (optional)')}\n </Label>\n <Input\n id=\"bra-account-cash\"\n type=\"number\"\n inputMode=\"decimal\"\n step=\"0.01\"\n value={cashBalance}\n onChange={(e) => setCashBalance(e.target.value)}\n placeholder=\"0.00\"\n />\n </div>\n\n {createAccount.isError ? (\n <p className=\"text-sm text-status-error-text\">\n {createAccount.error instanceof Error\n ? createAccount.error.message\n : translate('brainyrich.dashboard.newAccount.error', 'Could not create account.')}\n </p>\n ) : null}\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n disabled={createAccount.isPending}\n >\n {translate('brainyrich.common.cancel', 'Cancel')}\n </Button>\n <Button type=\"submit\" disabled={!canSubmit}>\n {createAccount.isPending\n ? translate('brainyrich.dashboard.newAccount.creating', 'Creating…')\n : translate('brainyrich.dashboard.newAccount.create', 'Create account')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/brainyrich/pages/DashboardPage.tsx"],"sourcesContent":["import { useMemo, useState, type FormEvent, type ReactNode } from 'react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CardDescription,\n Button,\n Badge,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Target,\n Bell,\n Briefcase,\n Wallet,\n PlusCircle,\n MoreHorizontal,\n Check,\n X,\n CircleCheck,\n TrendingUp,\n Coins,\n Landmark,\n TriangleAlert,\n Info,\n ShieldAlert,\n} from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n useNetWorthSummary,\n usePortfolios,\n useGoals,\n useInsights,\n useCreateAccount,\n useAcknowledgeInsight,\n useDismissInsight,\n useResolveInsight,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraAccountType,\n BraAssetClass,\n BraCreateAccountInput,\n BraInsight,\n BraInsightSeverity,\n} from '../types/bra';\nimport {\n HouseholdPicker,\n ConfirmDialog,\n DonutChart,\n StatTile,\n GlassCard,\n FadeIn,\n type VizTone,\n type DonutDatum,\n} from '../components';\nimport {\n SectionShell,\n EmptyState,\n LoadingState,\n ErrorState,\n formatMoney,\n formatCompact,\n formatDate,\n statusBadgeVariant,\n} from './_shared';\nimport { hapticSuccess, showToast } from '../utils/nativeControls';\nimport { useTrackBrainyRichPageView } from '../hooks/useBrainyRichAnalytics';\n\nconst ACCOUNT_TYPES: BraAccountType[] = [\n 'BANK',\n 'BROKERAGE',\n 'RETIREMENT',\n 'CASH',\n 'CRYPTO',\n 'REAL_ESTATE',\n 'ALTERNATIVE',\n 'LIABILITY',\n];\n\n/** Distinct, semantic tone per asset class so the donut stays legible + on-brand. */\nconst ASSET_TONE: Record<BraAssetClass, VizTone> = {\n EQUITY: 'brand',\n FIXED_INCOME: 'blue',\n CASH: 'teal',\n REAL_ESTATE: 'indigo',\n COMMODITY: 'warning',\n CRYPTO: 'purple',\n ALTERNATIVE: 'info',\n};\n\n/** Title-case an enum member: FIXED_INCOME → \"Fixed income\". */\nfunction prettyLabel(value: string): string {\n const spaced = value.replace(/_/g, ' ').toLowerCase();\n return spaced.charAt(0).toUpperCase() + spaced.slice(1);\n}\n\nexport function DashboardPage() {\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.dashboard.viewed');\n\n const summaryQuery = useNetWorthSummary();\n const portfoliosQuery = usePortfolios();\n const goalsQuery = useGoals();\n const insightsQuery = useInsights({ status: 'OPEN' });\n\n const summary = summaryQuery.data;\n const currency = summary?.currency ?? 'USD';\n\n const kpis: HeroStat[] = summary\n ? [\n {\n label: translate('brainyrich.dashboard.metrics.netWorth', 'Net Worth'),\n value: formatCompact(summary.totalNetWorth, currency),\n icon: <Wallet className=\"size-4\" aria-hidden=\"true\" />,\n glow: true,\n },\n {\n label: translate('brainyrich.dashboard.metrics.investedAssets', 'Invested Assets'),\n value: formatCompact(summary.totalMarketValue, currency),\n icon: <TrendingUp className=\"size-4\" aria-hidden=\"true\" />,\n },\n {\n label: translate('brainyrich.dashboard.metrics.liquidity', 'Cash & Liquidity'),\n value: formatCompact(summary.totalCash, currency),\n icon: <Coins className=\"size-4\" aria-hidden=\"true\" />,\n },\n {\n label: translate('brainyrich.dashboard.metrics.accounts', 'Linked Accounts'),\n value: String(summary.accountCount),\n icon: <Landmark className=\"size-4\" aria-hidden=\"true\" />,\n },\n ]\n : [];\n\n const donutData: DonutDatum[] = useMemo(() => {\n if (!summary) return [];\n return summary.byAssetClass\n .filter((row) => Number.isFinite(row.marketValue) && row.marketValue > 0)\n .slice()\n .sort((a, b) => b.marketValue - a.marketValue)\n .map((row) => ({\n label: prettyLabel(row.assetClass),\n value: row.marketValue,\n tone: ASSET_TONE[row.assetClass],\n }));\n }, [summary]);\n\n const topPortfolios = portfoliosQuery.data.slice(0, 5);\n const topGoals = goalsQuery.data.slice(0, 5);\n const openInsights = insightsQuery.data.slice(0, 6);\n\n return (\n <div data-tour=\"brainyrich-page-dashboard\" className=\"contents\">\n <SectionShell\n title={translate('brainyrich.dashboard.title', 'Wealth Dashboard')}\n description={translate(\n 'brainyrich.dashboard.description',\n 'Your consolidated financial overview at a glance'\n )}\n actions={<NewAccountDialog translate={translate} />}\n >\n {/* Hero KPI row — net-worth overview */}\n {summaryQuery.isLoading ? (\n <LoadingState rows={1} />\n ) : summaryQuery.isError ? (\n <ErrorState\n title={translate('brainyrich.dashboard.netWorthError', 'Could not load net worth')}\n onRetry={() => summaryQuery.refetch()}\n />\n ) : summary ? (\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n {kpis.map((kpi, i) => (\n <FadeIn key={kpi.label} index={i}>\n <StatTile\n label={kpi.label}\n value={kpi.value}\n icon={kpi.icon}\n glow={kpi.glow}\n className=\"h-full\"\n />\n </FadeIn>\n ))}\n </div>\n ) : (\n <EmptyState\n icon={<Wallet className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.dashboard.noSummary', 'No financial data yet')}\n description={translate(\n 'brainyrich.dashboard.noSummaryDesc',\n 'Link your first account to see your net worth here.'\n )}\n />\n )}\n\n <div className=\"grid gap-6 lg:grid-cols-3\">\n {/* Net worth by asset class — donut hero */}\n <FadeIn index={0} className=\"lg:col-span-2\">\n <GlassCard className=\"h-full\">\n <div className=\"mb-4 space-y-1\">\n <h2 className=\"flex items-center gap-2 text-base font-semibold text-text-primary\">\n <Briefcase className=\"size-5\" aria-hidden=\"true\" />\n {translate(\n 'brainyrich.dashboard.sections.assetAllocation',\n 'Net worth by asset class'\n )}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.dashboard.sections.assetAllocationDescription',\n 'Market value distributed across asset classes'\n )}\n </p>\n </div>\n {summaryQuery.isLoading ? (\n <LoadingState rows={3} />\n ) : summaryQuery.isError ? (\n <ErrorState onRetry={() => summaryQuery.refetch()} />\n ) : donutData.length > 0 ? (\n <DonutChart\n data={donutData}\n height={260}\n centerValue={formatCompact(summary?.totalMarketValue ?? 0, currency)}\n centerLabel={translate('brainyrich.dashboard.metrics.investedAssets', 'Invested')}\n valueFormatter={(v) => formatMoney(v, currency)}\n />\n ) : (\n <EmptyState\n icon={<Briefcase className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.dashboard.noAllocation', 'No holdings to allocate')}\n description={translate(\n 'brainyrich.dashboard.noAllocationDesc',\n 'Add holdings to your accounts to see how your wealth is allocated.'\n )}\n />\n )}\n </GlassCard>\n </FadeIn>\n\n {/* Right rail — needs attention + goals */}\n <div className=\"space-y-6\">\n {/* Needs attention — open insights */}\n <FadeIn index={1}>\n <Card className=\"motion-safe:transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <CardHeader className=\"pb-3\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Bell className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.sections.needsAttention', 'Needs attention')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2.5\">\n {insightsQuery.isLoading ? (\n <LoadingState rows={2} />\n ) : insightsQuery.isError ? (\n <ErrorState onRetry={() => insightsQuery.refetch()} />\n ) : openInsights.length > 0 ? (\n openInsights.map((insight) => (\n <InsightRow key={insight.id} insight={insight} translate={translate} />\n ))\n ) : (\n <EmptyState\n icon={<CircleCheck className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.dashboard.noInsights', 'All clear')}\n description={translate(\n 'brainyrich.dashboard.noInsightsDesc',\n 'There are no open insights that need your attention.'\n )}\n />\n )}\n </CardContent>\n </Card>\n </FadeIn>\n\n {/* Goals on track */}\n <FadeIn index={2}>\n <Card className=\"motion-safe:transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <CardHeader className=\"pb-3\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Target className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.sections.goals', 'Goals on track')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2.5\">\n {goalsQuery.isLoading ? (\n <LoadingState rows={3} />\n ) : goalsQuery.isError ? (\n <ErrorState onRetry={() => goalsQuery.refetch()} />\n ) : topGoals.length > 0 ? (\n topGoals.map((goal) => (\n <div\n key={goal.id}\n className=\"flex items-start justify-between gap-2 rounded-lg border border-border-subtle p-3 motion-safe:transition-colors hover:border-[var(--color-action-primary-border)]/50 hover:bg-bg-elevated\"\n >\n <div className=\"min-w-0 space-y-0.5\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {goal.name}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {formatMoney(goal.targetAmount, goal.currency)}\n {' · '}\n {formatDate(goal.targetDate)}\n </p>\n </div>\n <Badge variant={statusBadgeVariant(goal.projection)} className=\"shrink-0\">\n {prettyLabel(goal.projection)}\n </Badge>\n </div>\n ))\n ) : (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.dashboard.noGoals', 'No goals yet')}\n description={translate(\n 'brainyrich.dashboard.noGoalsDesc',\n 'Set a financial goal to start tracking progress.'\n )}\n />\n )}\n </CardContent>\n </Card>\n </FadeIn>\n </div>\n </div>\n\n {/* Portfolios mini-list */}\n <FadeIn index={3}>\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Wallet className=\"size-5\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.sections.portfolios', 'Portfolios')}\n </CardTitle>\n <CardDescription>\n {translate(\n 'brainyrich.dashboard.sections.portfoliosDescription',\n 'Your active investment strategies'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent>\n {portfoliosQuery.isLoading ? (\n <LoadingState rows={3} />\n ) : portfoliosQuery.isError ? (\n <ErrorState onRetry={() => portfoliosQuery.refetch()} />\n ) : topPortfolios.length > 0 ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {topPortfolios.map((portfolio) => (\n <div\n key={portfolio.id}\n className=\"flex items-start justify-between gap-2 rounded-lg border border-border-subtle p-3 motion-safe:transition-colors hover:border-[var(--color-action-primary-border)]/50 hover:bg-bg-elevated\"\n >\n <div className=\"min-w-0 space-y-0.5\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {portfolio.name}\n </p>\n {portfolio.description ? (\n <p className=\"truncate text-xs text-text-secondary\">\n {portfolio.description}\n </p>\n ) : (\n <p className=\"text-xs text-text-secondary\">{portfolio.baseCurrency}</p>\n )}\n </div>\n <Badge variant={statusBadgeVariant(portfolio.status)} className=\"shrink-0\">\n {portfolio.status}\n </Badge>\n </div>\n ))}\n </div>\n ) : (\n <EmptyState\n icon={<Wallet className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.dashboard.noPortfolios', 'No portfolios yet')}\n description={translate(\n 'brainyrich.dashboard.noPortfoliosDesc',\n 'Create a portfolio to organize your investment strategy.'\n )}\n />\n )}\n </CardContent>\n </Card>\n </FadeIn>\n </SectionShell>\n </div>\n );\n}\n\ninterface HeroStat {\n label: string;\n value: string;\n icon: ReactNode;\n glow?: boolean;\n}\n\ntype Translate = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>\n) => string;\n\n// ============================================================================\n// Severity chip — tinted, icon + label (colour is never the only signal)\n// ============================================================================\n\nconst SEVERITY_STYLE: Record<BraInsightSeverity, { chip: string; rail: string; icon: ReactNode }> =\n {\n CRITICAL: {\n chip: 'text-status-error-text bg-status-error-bg',\n rail: 'bg-status-error',\n icon: <ShieldAlert className=\"size-3\" aria-hidden=\"true\" />,\n },\n HIGH: {\n chip: 'text-status-error-text bg-status-error-bg',\n rail: 'bg-status-error',\n icon: <TriangleAlert className=\"size-3\" aria-hidden=\"true\" />,\n },\n MEDIUM: {\n chip: 'text-status-warning-text bg-status-warning-bg',\n rail: 'bg-status-warning',\n icon: <TriangleAlert className=\"size-3\" aria-hidden=\"true\" />,\n },\n LOW: {\n chip: 'text-status-info-text bg-status-info-bg',\n rail: 'bg-status-info',\n icon: <Info className=\"size-3\" aria-hidden=\"true\" />,\n },\n INFO: {\n chip: 'text-status-info-text bg-status-info-bg',\n rail: 'bg-status-info',\n icon: <Info className=\"size-3\" aria-hidden=\"true\" />,\n },\n };\n\nfunction SeverityChip({ severity }: { severity: BraInsightSeverity }) {\n const style = SEVERITY_STYLE[severity] ?? SEVERITY_STYLE.INFO;\n return (\n <span\n className={`inline-flex shrink-0 items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${style.chip}`}\n >\n {style.icon}\n {severity}\n </span>\n );\n}\n\n// ============================================================================\n// Insight row with acknowledge / dismiss / resolve actions\n// ============================================================================\n\nfunction InsightRow({ insight, translate }: { insight: BraInsight; translate: Translate }) {\n const acknowledge = useAcknowledgeInsight();\n const dismiss = useDismissInsight();\n const resolve = useResolveInsight();\n const [confirmDismiss, setConfirmDismiss] = useState(false);\n const pending = acknowledge.isPending || dismiss.isPending || resolve.isPending;\n const rail = (SEVERITY_STYLE[insight.severity] ?? SEVERITY_STYLE.INFO).rail;\n\n return (\n <div className=\"relative flex items-start justify-between gap-3 overflow-hidden rounded-lg border border-border-subtle p-3 pl-4 motion-safe:transition-colors hover:border-[var(--color-action-primary-border)]/50 hover:bg-bg-elevated\">\n <span aria-hidden=\"true\" className={`absolute inset-y-0 left-0 w-1 ${rail}`} />\n <div className=\"min-w-0 space-y-1\">\n <div className=\"flex items-center gap-2\">\n <SeverityChip severity={insight.severity} />\n <span className=\"truncate text-xs text-text-secondary\">{prettyLabel(insight.type)}</span>\n </div>\n <p className=\"text-sm font-medium text-text-primary\">{insight.title}</p>\n {insight.detail ? <p className=\"text-xs text-text-secondary\">{insight.detail}</p> : null}\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"shrink-0\"\n disabled={pending}\n aria-label={translate('brainyrich.dashboard.insightActions', 'Insight actions')}\n >\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onSelect={() => acknowledge.mutate(insight.id)}>\n <Check className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.insight.acknowledge', 'Acknowledge')}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => resolve.mutate(insight.id)}>\n <CircleCheck className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.insight.resolve', 'Resolve')}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => setConfirmDismiss(true)}>\n <X className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.insight.dismiss', 'Dismiss')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n\n <ConfirmDialog\n open={confirmDismiss}\n onOpenChange={setConfirmDismiss}\n title={translate('brainyrich.dashboard.insight.dismissTitle', 'Dismiss this insight?')}\n description={translate(\n 'brainyrich.dashboard.insight.dismissDescription',\n 'It will be removed from Needs Attention. You can still find it in the full insights list.'\n )}\n confirmLabel={translate('brainyrich.dashboard.insight.dismiss', 'Dismiss')}\n pendingLabel={translate('brainyrich.dashboard.insight.dismissing', 'Dismissing…')}\n destructive\n pending={dismiss.isPending}\n onConfirm={() =>\n dismiss.mutate(insight.id, {\n onSuccess: () => setConfirmDismiss(false),\n })\n }\n />\n </div>\n );\n}\n\n// ============================================================================\n// New account dialog — primary create action\n// ============================================================================\n\nfunction NewAccountDialog({ translate }: { translate: Translate }) {\n const [open, setOpen] = useState(false);\n const [name, setName] = useState('');\n const [type, setType] = useState<BraAccountType>('BROKERAGE');\n const [institution, setInstitution] = useState('');\n const [cashBalance, setCashBalance] = useState('');\n const [currency, setCurrency] = useState('USD');\n const [householdId, setHouseholdId] = useState<string | null>(null);\n\n const createAccount = useCreateAccount();\n const trimmedName = name.trim();\n const canSubmit = trimmedName.length > 0 && !createAccount.isPending;\n\n const reset = () => {\n setName('');\n setType('BROKERAGE');\n setInstitution('');\n setCashBalance('');\n setCurrency('USD');\n setHouseholdId(null);\n createAccount.reset();\n };\n\n const handleSubmit = (event: FormEvent) => {\n event.preventDefault();\n if (!canSubmit) return;\n const parsedCash = Number.parseFloat(cashBalance);\n const input: BraCreateAccountInput = {\n name: trimmedName,\n type,\n currency: currency.trim() || 'USD',\n isManual: true,\n ...(institution.trim() ? { institution: institution.trim() } : {}),\n ...(Number.isFinite(parsedCash) ? { cashBalance: parsedCash } : {}),\n ...(householdId ? { householdId } : {}),\n };\n createAccount.mutate(input, {\n onSuccess: () => {\n hapticSuccess();\n void showToast(translate('brainyrich.dashboard.newAccount.success', 'Account created'));\n reset();\n setOpen(false);\n },\n });\n };\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) reset();\n }}\n >\n <Button size=\"sm\" onClick={() => setOpen(true)}>\n <PlusCircle className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.dashboard.actions.newAccount', 'New Account')}\n </Button>\n <DialogContent>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <DialogHeader>\n <DialogTitle>\n {translate('brainyrich.dashboard.newAccount.title', 'New Account')}\n </DialogTitle>\n <DialogDescription>\n {translate(\n 'brainyrich.dashboard.newAccount.description',\n 'Add a manual account to track alongside your linked institutions.'\n )}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-account-name\">\n {translate('brainyrich.dashboard.newAccount.name', 'Account name')}\n </Label>\n <Input\n id=\"bra-account-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={translate(\n 'brainyrich.dashboard.newAccount.namePlaceholder',\n 'e.g. Fidelity Brokerage'\n )}\n required\n autoFocus\n />\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-account-type\">\n {translate('brainyrich.dashboard.newAccount.type', 'Type')}\n </Label>\n <Select value={type} onValueChange={(value) => setType(value as BraAccountType)}>\n <SelectTrigger id=\"bra-account-type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ACCOUNT_TYPES.map((accountType) => (\n <SelectItem key={accountType} value={accountType}>\n {accountType.replace(/_/g, ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-account-currency\">\n {translate('brainyrich.dashboard.newAccount.currency', 'Currency')}\n </Label>\n <Input\n id=\"bra-account-currency\"\n value={currency}\n onChange={(e) => setCurrency(e.target.value.toUpperCase())}\n maxLength={3}\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-account-institution\">\n {translate('brainyrich.dashboard.newAccount.institution', 'Institution (optional)')}\n </Label>\n <Input\n id=\"bra-account-institution\"\n value={institution}\n onChange={(e) => setInstitution(e.target.value)}\n placeholder={translate(\n 'brainyrich.dashboard.newAccount.institutionPlaceholder',\n 'e.g. Fidelity'\n )}\n />\n </div>\n\n <HouseholdPicker\n id=\"bra-account-household\"\n value={householdId}\n onChange={setHouseholdId}\n label={translate('brainyrich.dashboard.newAccount.household', 'Household (optional)')}\n noneLabel={translate('brainyrich.dashboard.newAccount.noHousehold', 'No household')}\n disabled={createAccount.isPending}\n />\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-account-cash\">\n {translate('brainyrich.dashboard.newAccount.cash', 'Cash balance (optional)')}\n </Label>\n <Input\n id=\"bra-account-cash\"\n type=\"number\"\n inputMode=\"decimal\"\n step=\"0.01\"\n value={cashBalance}\n onChange={(e) => setCashBalance(e.target.value)}\n placeholder=\"0.00\"\n />\n </div>\n\n {createAccount.isError ? (\n <p className=\"text-sm text-status-error-text\">\n {createAccount.error instanceof Error\n ? createAccount.error.message\n : translate('brainyrich.dashboard.newAccount.error', 'Could not create account.')}\n </p>\n ) : null}\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n disabled={createAccount.isPending}\n >\n {translate('brainyrich.common.cancel', 'Cancel')}\n </Button>\n <Button type=\"submit\" disabled={!canSubmit}>\n {createAccount.isPending\n ? translate('brainyrich.dashboard.newAccount.creating', 'Creating…')\n : translate('brainyrich.dashboard.newAccount.create', 'Create account')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FamilyPage.js","names":[],"sources":["../../../src/brainyrich/pages/FamilyPage.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n Dialog,\n DialogClose,\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 Separator,\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Users,\n MoreHorizontal,\n Pencil,\n Archive,\n Eye,\n Mail,\n Wallet,\n Target,\n Briefcase,\n Building2,\n TrendingUp,\n UserCircle2,\n} from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n usePagedHouseholds,\n useHousehold,\n useCreateHousehold,\n useUpdateHousehold,\n useArchiveHousehold,\n useAccounts,\n usePortfolios,\n useGoals,\n} from '../hooks/useBrainyRichApi';\nimport {\n ConfirmDialog,\n LoadMore,\n ActorName,\n StatTile,\n GlassCard,\n FadeIn,\n DonutChart,\n type DonutDatum,\n} from '../components';\nimport { TagField } from '../components/reuse/TagField';\nimport { DocumentsPanel } from '../components/reuse/DocumentsPanel';\nimport { hapticSuccess, showToast } from '../utils/nativeControls';\nimport { useTrackBrainyRichPageView } from '../hooks/useBrainyRichAnalytics';\nimport { CommentThread } from '../components/reuse/CommentThread';\nimport type {\n BraHousehold,\n BraHouseholdStatus,\n BraRiskProfile,\n BraCreateHouseholdInput,\n BraUpdateHouseholdInput,\n BraAccount,\n BraGoal,\n} from '../types/bra';\nimport {\n SectionShell,\n EmptyState,\n LoadingState,\n ErrorState,\n formatMoney,\n formatCompact,\n formatDate,\n statusBadgeVariant,\n} from './_shared';\n\nconst STATUS_OPTIONS: BraHouseholdStatus[] = ['PROSPECT', 'ONBOARDING', 'ACTIVE', 'INACTIVE'];\nconst RISK_OPTIONS: BraRiskProfile[] = [\n 'CONSERVATIVE',\n 'MODERATE',\n 'BALANCED',\n 'GROWTH',\n 'AGGRESSIVE',\n];\nconst CURRENCY_OPTIONS = ['USD', 'EUR', 'GBP', 'INR', 'AED', 'SGD'];\n\n/** Per-status donut tone (semantic — colour is never the only signal). */\nconst STATUS_TONE: Record<BraHouseholdStatus, DonutDatum['tone']> = {\n ACTIVE: 'brand',\n ONBOARDING: 'info',\n PROSPECT: 'warning',\n INACTIVE: 'neutral',\n};\n\ninterface HouseholdFormState {\n name: string;\n status: BraHouseholdStatus;\n riskProfile: BraRiskProfile;\n currency: string;\n advisorId: string;\n primaryContactName: string;\n primaryContactEmail: string;\n notes: string;\n tags: string;\n}\n\nconst emptyForm: HouseholdFormState = {\n name: '',\n status: 'PROSPECT',\n riskProfile: 'BALANCED',\n currency: 'USD',\n advisorId: '',\n primaryContactName: '',\n primaryContactEmail: '',\n notes: '',\n tags: '',\n};\n\nfunction toTags(raw: string): string[] {\n return raw\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n}\n\n/** Real market value of an account: settled cash + marked-to-market holdings. */\nfunction accountValue(a: BraAccount): number {\n const holdings = (a.holdings ?? []).reduce(\n (sum, h) => sum + (Number.isFinite(h.marketValue) ? h.marketValue : 0),\n 0\n );\n const cash = Number.isFinite(a.cashBalance) ? a.cashBalance : 0;\n return cash + holdings;\n}\n\nexport function FamilyPage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n\n useTrackBrainyRichPageView('brainyrich.family.viewed');\n\n const {\n items: households,\n hasMore,\n loadMore,\n isLoading,\n isFetchingNextPage,\n isError,\n refetch,\n } = usePagedHouseholds();\n\n const createHousehold = useCreateHousehold();\n const updateHousehold = useUpdateHousehold();\n const archiveHousehold = useArchiveHousehold();\n\n const [formOpen, setFormOpen] = useState(false);\n const [editing, setEditing] = useState<BraHousehold | null>(null);\n const [form, setForm] = useState<HouseholdFormState>(emptyForm);\n const [detailId, setDetailId] = useState<string | undefined>(undefined);\n const [archiveTarget, setArchiveTarget] = useState<BraHousehold | null>(null);\n\n const setField = <K extends keyof HouseholdFormState>(key: K, value: HouseholdFormState[K]) =>\n setForm((prev) => ({ ...prev, [key]: value }));\n\n const openCreate = () => {\n setEditing(null);\n setForm(emptyForm);\n setFormOpen(true);\n };\n\n const openEdit = (h: BraHousehold) => {\n setEditing(h);\n setForm({\n name: h.name,\n status: h.status,\n riskProfile: h.riskProfile,\n currency: h.currency,\n advisorId: h.advisorId ?? '',\n primaryContactName: h.primaryContactName ?? '',\n primaryContactEmail: h.primaryContactEmail ?? '',\n notes: h.notes ?? '',\n tags: h.tags.join(', '),\n });\n setFormOpen(true);\n };\n\n const firm = useMemo(() => {\n const currency = households[0]?.currency ?? 'USD';\n const total = households.length;\n const active = households.filter((h) => h.status === 'ACTIVE').length;\n const prospects = households.filter((h) => h.status === 'PROSPECT').length;\n const onboarding = households.filter((h) => h.status === 'ONBOARDING').length;\n const aum = households.reduce((sum, h) => sum + (Number.isFinite(h.aum) ? h.aum : 0), 0);\n\n // AUM grouped by advisor (empty advisorId → unassigned bucket).\n const byAdvisor = new Map<string, number>();\n for (const h of households) {\n const key = h.advisorId?.trim() || '';\n byAdvisor.set(key, (byAdvisor.get(key) ?? 0) + (Number.isFinite(h.aum) ? h.aum : 0));\n }\n const advisors = Array.from(byAdvisor.entries())\n .map(([advisorId, value]) => ({ advisorId, value }))\n .sort((a, b) => b.value - a.value);\n const advisorCount = advisors.filter((a) => a.advisorId).length;\n const advisorMax = advisors.reduce((m, a) => Math.max(m, a.value), 0);\n\n // Book mix by status → donut.\n const statusMix: DonutDatum[] = (STATUS_OPTIONS as BraHouseholdStatus[])\n .map((s) => ({\n label: s.charAt(0) + s.slice(1).toLowerCase(),\n value: households.filter((h) => h.status === s).length,\n tone: STATUS_TONE[s],\n }))\n .filter((d) => d.value > 0);\n\n return {\n currency,\n total,\n active,\n prospects,\n onboarding,\n aum,\n advisors,\n advisorCount,\n advisorMax,\n statusMix,\n };\n }, [households]);\n\n const submitting = createHousehold.isPending || updateHousehold.isPending;\n const canSubmit = form.name.trim().length > 0 && !submitting;\n\n const handleSubmit = () => {\n if (!canSubmit) return;\n if (editing) {\n const input: BraUpdateHouseholdInput = {\n name: form.name.trim(),\n status: form.status,\n riskProfile: form.riskProfile,\n currency: form.currency,\n primaryContactName: form.primaryContactName.trim() || null,\n primaryContactEmail: form.primaryContactEmail.trim() || null,\n notes: form.notes.trim() || null,\n tags: toTags(form.tags),\n };\n updateHousehold.mutate(\n { id: editing.id, input },\n {\n onSuccess: () => {\n hapticSuccess();\n void showToast(tr('brainyrich.households.saved', 'Household saved'));\n setFormOpen(false);\n },\n }\n );\n } else {\n const input: BraCreateHouseholdInput = {\n name: form.name.trim(),\n status: form.status,\n riskProfile: form.riskProfile,\n currency: form.currency,\n primaryContactName: form.primaryContactName.trim() || null,\n primaryContactEmail: form.primaryContactEmail.trim() || null,\n notes: form.notes.trim() || null,\n tags: toTags(form.tags),\n };\n if (form.advisorId.trim()) input.advisorId = form.advisorId.trim();\n createHousehold.mutate(input, {\n onSuccess: () => {\n hapticSuccess();\n void showToast(tr('brainyrich.households.created', 'Household created'));\n setFormOpen(false);\n },\n });\n }\n };\n\n const showFirm = !isLoading && !isError && households.length > 0;\n\n return (\n <div data-tour=\"brainyrich-page-households\" className=\"contents\">\n <SectionShell\n title={tr('brainyrich.households.title', 'Households')}\n description={tr(\n 'brainyrich.households.description',\n 'Client households and family units under advisement'\n )}\n badges={\n households.length\n ? [\n tr('brainyrich.households.count', '{count} households', {\n count: households.length,\n }),\n ]\n : []\n }\n actionLabel={tr('brainyrich.households.new', 'New household')}\n onAction={openCreate}\n >\n {showFirm ? (\n <FirmOverview firm={firm} tr={tr} />\n ) : (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <StatTile label={tr('brainyrich.households.kpi.aum', 'Total AUM')} value=\"—\" glow />\n <StatTile label={tr('brainyrich.households.kpi.total', 'Households')} value=\"—\" />\n <StatTile label={tr('brainyrich.households.kpi.active', 'Active')} value=\"—\" />\n <StatTile label={tr('brainyrich.households.kpi.prospects', 'Prospects')} value=\"—\" />\n </div>\n )}\n\n {isLoading ? (\n <LoadingState rows={5} />\n ) : isError ? (\n <ErrorState\n title={tr('brainyrich.households.error.title', 'Could not load households')}\n onRetry={() => refetch()}\n />\n ) : households.length === 0 ? (\n <EmptyState\n icon={<Users className=\"size-6\" aria-hidden=\"true\" />}\n title={tr('brainyrich.households.empty.title', 'No households yet')}\n description={tr(\n 'brainyrich.households.empty.description',\n 'Create your first client household to start organizing accounts, portfolios and goals.'\n )}\n action={\n <Button size=\"sm\" onClick={openCreate}>\n {tr('brainyrich.households.new', 'New household')}\n </Button>\n }\n />\n ) : (\n <FadeIn as=\"section\">\n <Card className=\"overflow-hidden\">\n <CardContent className=\"p-0\">\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead>{tr('brainyrich.households.col.name', 'Household')}</TableHead>\n <TableHead>{tr('brainyrich.households.col.status', 'Status')}</TableHead>\n <TableHead className=\"hidden md:table-cell\">\n {tr('brainyrich.households.col.risk', 'Risk profile')}\n </TableHead>\n <TableHead className=\"hidden lg:table-cell\">\n {tr('brainyrich.households.col.contact', 'Primary contact')}\n </TableHead>\n <TableHead className=\"hidden sm:table-cell\">\n {tr('brainyrich.households.col.advisor', 'Advisor')}\n </TableHead>\n <TableHead className=\"text-right\">\n {tr('brainyrich.households.col.aum', 'AUM')}\n </TableHead>\n <TableHead className=\"w-12 text-right\">\n <span className=\"sr-only\">\n {tr('brainyrich.households.col.actions', 'Actions')}\n </span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {households.map((h) => {\n const share = firm.aum > 0 ? Math.min(100, (h.aum / firm.aum) * 100) : 0;\n return (\n <TableRow\n key={h.id}\n className=\"group cursor-pointer transition-colors\"\n onClick={() => setDetailId(h.id)}\n >\n <TableCell>\n <span className=\"font-medium text-text-primary transition-colors group-hover:text-[var(--color-action-primary-text)]\">\n {h.name}\n </span>\n {h.tags.length > 0 ? (\n <div className=\"mt-1 flex flex-wrap gap-1\">\n {h.tags.slice(0, 3).map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n {h.tags.length > 3 ? (\n <Badge variant=\"outline\" className=\"text-xs\">\n +{h.tags.length - 3}\n </Badge>\n ) : null}\n </div>\n ) : null}\n </TableCell>\n <TableCell>\n <Badge variant={statusBadgeVariant(h.status)}>{h.status}</Badge>\n </TableCell>\n <TableCell className=\"hidden md:table-cell\">\n <Badge variant=\"secondary\">{h.riskProfile}</Badge>\n </TableCell>\n <TableCell className=\"hidden lg:table-cell\">\n {h.primaryContactName ? (\n <div className=\"space-y-0.5\">\n <p className=\"text-sm text-text-primary\">\n {h.primaryContactName}\n </p>\n {h.primaryContactEmail ? (\n <p className=\"flex items-center gap-1 text-xs text-text-secondary\">\n <Mail className=\"size-3\" aria-hidden=\"true\" />\n {h.primaryContactEmail}\n </p>\n ) : null}\n </div>\n ) : (\n <span className=\"text-sm text-text-muted\">—</span>\n )}\n </TableCell>\n <TableCell className=\"hidden sm:table-cell\">\n {h.advisorId ? (\n <span className=\"flex items-center gap-1.5 text-sm text-text-secondary\">\n <UserCircle2 className=\"size-3.5\" aria-hidden=\"true\" />\n <ActorName id={h.advisorId} />\n </span>\n ) : (\n <span className=\"text-sm text-text-muted\">\n {tr('brainyrich.common.unassigned', 'Unassigned')}\n </span>\n )}\n </TableCell>\n <TableCell className=\"text-right\">\n <div className=\"flex flex-col items-end gap-1\">\n <span className=\"font-medium tabular-nums text-text-primary\">\n {formatMoney(h.aum, h.currency)}\n </span>\n <span\n className=\"h-1 w-16 overflow-hidden rounded-full bg-bg-sunken\"\n aria-hidden=\"true\"\n >\n <span\n className=\"block h-full rounded-full bg-[var(--color-action-primary-bg)]\"\n style={{ width: `${share}%` }}\n />\n </span>\n </div>\n </TableCell>\n <TableCell className=\"text-right\" onClick={(e) => e.stopPropagation()}>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={tr(\n 'brainyrich.households.rowMenu',\n 'Household actions'\n )}\n >\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setDetailId(h.id)}>\n <Eye className=\"size-4\" aria-hidden=\"true\" />\n {tr('brainyrich.households.action.view', 'View details')}\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => openEdit(h)}>\n <Pencil className=\"size-4\" aria-hidden=\"true\" />\n {tr('brainyrich.households.action.edit', 'Edit')}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"text-status-error-text focus:text-status-error-text\"\n onClick={() => setArchiveTarget(h)}\n >\n <Archive className=\"size-4\" aria-hidden=\"true\" />\n {tr('brainyrich.households.action.archive', 'Archive')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n </CardContent>\n </Card>\n </FadeIn>\n )}\n\n {!isLoading && !isError && households.length > 0 ? (\n <LoadMore\n hasMore={hasMore}\n onClick={loadMore}\n loading={isFetchingNextPage}\n label={tr('brainyrich.households.loadMore', 'Load more households')}\n />\n ) : null}\n\n <HouseholdFormDialog\n open={formOpen}\n onOpenChange={setFormOpen}\n editing={editing}\n form={form}\n setField={setField}\n onSubmit={handleSubmit}\n canSubmit={canSubmit}\n submitting={submitting}\n tr={tr}\n />\n\n <HouseholdDetailSheet\n householdId={detailId}\n onClose={() => setDetailId(undefined)}\n onEdit={(h) => {\n setDetailId(undefined);\n openEdit(h);\n }}\n tr={tr}\n />\n\n <ConfirmDialog\n open={Boolean(archiveTarget)}\n onOpenChange={(o) => (!o ? setArchiveTarget(null) : undefined)}\n title={tr('brainyrich.households.archive.title', 'Archive household?')}\n description={tr(\n 'brainyrich.households.archive.description',\n 'Archiving “{name}” removes it from the active list. You can still access its records, but it will no longer appear here.',\n { name: archiveTarget?.name ?? '' }\n )}\n confirmLabel={tr('brainyrich.households.action.archive', 'Archive')}\n pendingLabel={tr('brainyrich.households.archive.pending', 'Archiving…')}\n destructive\n pending={archiveHousehold.isPending}\n onConfirm={() => {\n if (!archiveTarget) return;\n archiveHousehold.mutate(archiveTarget.id, {\n onSuccess: () => {\n hapticSuccess();\n void showToast(\n tr('brainyrich.households.archived', 'Household archived', {\n name: archiveTarget.name,\n })\n );\n setArchiveTarget(null);\n },\n });\n }}\n />\n </SectionShell>\n </div>\n );\n}\n\n// ============================================================================\n// Firm overview — practice-wide KPIs + AUM-by-advisor + book mix\n// ============================================================================\n\ninterface FirmData {\n currency: string;\n total: number;\n active: number;\n prospects: number;\n onboarding: number;\n aum: number;\n advisors: { advisorId: string; value: number }[];\n advisorCount: number;\n advisorMax: number;\n statusMix: DonutDatum[];\n}\n\nfunction FirmOverview({\n firm,\n tr,\n}: {\n firm: FirmData;\n tr: (key: string, fallback: string, params?: Record<string, string | number>) => string;\n}) {\n return (\n <FadeIn as=\"section\" className=\"space-y-4\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <StatTile\n label={tr('brainyrich.households.kpi.aum', 'Total AUM')}\n value={formatMoney(firm.aum, firm.currency)}\n glow\n icon={<Wallet className=\"size-4\" aria-hidden=\"true\" />}\n />\n <StatTile\n label={tr('brainyrich.households.kpi.total', 'Households')}\n value={String(firm.total)}\n icon={<Users className=\"size-4\" aria-hidden=\"true\" />}\n />\n <StatTile\n label={tr('brainyrich.households.kpi.active', 'Active')}\n value={String(firm.active)}\n icon={<TrendingUp className=\"size-4\" aria-hidden=\"true\" />}\n />\n <StatTile\n label={tr('brainyrich.households.kpi.prospects', 'Prospects')}\n value={String(firm.prospects)}\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n />\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-3\">\n <GlassCard className=\"lg:col-span-2\">\n <div className=\"mb-4 flex items-center justify-between gap-2\">\n <div>\n <h2 className=\"text-sm font-semibold text-text-primary\">\n {tr('brainyrich.households.firm.byAdvisor', 'AUM by advisor')}\n </h2>\n <p className=\"text-xs text-text-secondary\">\n {tr('brainyrich.households.firm.advisorCount', '{count} advisors', {\n count: firm.advisorCount,\n })}\n </p>\n </div>\n <Building2 className=\"size-4 text-text-secondary\" aria-hidden=\"true\" />\n </div>\n <ul\n className=\"space-y-3.5\"\n aria-label={tr('brainyrich.households.firm.byAdvisor', 'AUM by advisor')}\n >\n {firm.advisors.map((a) => {\n const width =\n firm.advisorMax > 0 ? Math.max(2, (a.value / firm.advisorMax) * 100) : 0;\n return (\n <li key={a.advisorId || 'unassigned'} className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between gap-3 text-xs\">\n <span className=\"flex items-center gap-1.5 truncate font-medium text-text-primary\">\n <UserCircle2\n className=\"size-3.5 shrink-0 text-text-secondary\"\n aria-hidden=\"true\"\n />\n {a.advisorId ? (\n <ActorName id={a.advisorId} />\n ) : (\n tr('brainyrich.common.unassigned', 'Unassigned')\n )}\n </span>\n <span className=\"shrink-0 tabular-nums text-text-secondary\">\n {formatCompact(a.value, firm.currency)}\n </span>\n </div>\n <div\n className=\"h-2 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={a.advisorId || 'Unassigned'}\n >\n <div\n className=\"h-full rounded-full bg-[var(--color-action-primary-bg)] transition-[width] duration-500 ease-out\"\n style={{ width: `${width}%` }}\n />\n </div>\n </li>\n );\n })}\n </ul>\n </GlassCard>\n\n <GlassCard>\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <h2 className=\"text-sm font-semibold text-text-primary\">\n {tr('brainyrich.households.firm.bookMix', 'Book by status')}\n </h2>\n </div>\n {firm.statusMix.length > 0 ? (\n <DonutChart\n data={firm.statusMix}\n centerValue={String(firm.total)}\n centerLabel={tr('brainyrich.households.kpi.total', 'Households')}\n legend\n height={200}\n valueFormatter={(v) => String(v)}\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr('brainyrich.households.firm.noMix', 'No households to chart yet.')}\n </p>\n )}\n </GlassCard>\n </div>\n </FadeIn>\n );\n}\n\n// ============================================================================\n// Create / edit dialog\n// ============================================================================\n\ninterface HouseholdFormDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n editing: BraHousehold | null;\n form: HouseholdFormState;\n setField: <K extends keyof HouseholdFormState>(key: K, value: HouseholdFormState[K]) => void;\n onSubmit: () => void;\n canSubmit: boolean;\n submitting: boolean;\n tr: (key: string, fallback: string, params?: Record<string, string | number>) => string;\n}\n\nfunction HouseholdFormDialog({\n open,\n onOpenChange,\n editing,\n form,\n setField,\n onSubmit,\n canSubmit,\n submitting,\n tr,\n}: HouseholdFormDialogProps) {\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 {editing\n ? tr('brainyrich.households.form.editTitle', 'Edit household')\n : tr('brainyrich.households.form.createTitle', 'New household')}\n </DialogTitle>\n <DialogDescription>\n {tr(\n 'brainyrich.households.form.subtitle',\n 'A household groups a client family’s accounts, portfolios and goals.'\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-2\">\n <Label htmlFor=\"hh-name\">{tr('brainyrich.households.form.name', 'Name')} *</Label>\n <Input\n id=\"hh-name\"\n value={form.name}\n onChange={(e) => setField('name', e.target.value)}\n placeholder={tr('brainyrich.households.form.namePh', 'e.g. The Raghavan Family')}\n required\n />\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label>{tr('brainyrich.households.form.status', 'Status')}</Label>\n <Select\n value={form.status}\n onValueChange={(v) => setField('status', v as BraHouseholdStatus)}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STATUS_OPTIONS.map((s) => (\n <SelectItem key={s} value={s}>\n {s}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-2\">\n <Label>{tr('brainyrich.households.form.risk', 'Risk profile')}</Label>\n <Select\n value={form.riskProfile}\n onValueChange={(v) => setField('riskProfile', v as BraRiskProfile)}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {RISK_OPTIONS.map((r) => (\n <SelectItem key={r} value={r}>\n {r}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"hh-contact-name\">\n {tr('brainyrich.households.form.contactName', 'Primary contact')}\n </Label>\n <Input\n id=\"hh-contact-name\"\n value={form.primaryContactName}\n onChange={(e) => setField('primaryContactName', e.target.value)}\n placeholder={tr('brainyrich.households.form.contactNamePh', 'Full name')}\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"hh-contact-email\">\n {tr('brainyrich.households.form.contactEmail', 'Contact email')}\n </Label>\n <Input\n id=\"hh-contact-email\"\n type=\"email\"\n value={form.primaryContactEmail}\n onChange={(e) => setField('primaryContactEmail', e.target.value)}\n placeholder=\"name@example.com\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label>{tr('brainyrich.households.form.currency', 'Currency')}</Label>\n <Select value={form.currency} onValueChange={(v) => setField('currency', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {CURRENCY_OPTIONS.map((c) => (\n <SelectItem key={c} value={c}>\n {c}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {!editing ? (\n <div className=\"space-y-2\">\n <Label htmlFor=\"hh-advisor\">\n {tr('brainyrich.households.form.advisor', 'Advisor ID')}\n </Label>\n <Input\n id=\"hh-advisor\"\n value={form.advisorId}\n onChange={(e) => setField('advisorId', e.target.value)}\n placeholder={tr('brainyrich.households.form.advisorPh', 'Optional')}\n />\n </div>\n ) : null}\n </div>\n\n {editing ? (\n <TagField\n entityType=\"brainyrich-household\"\n entityId={editing.id}\n label={tr('brainyrich.households.form.tags', 'Tags')}\n />\n ) : (\n <div className=\"space-y-2\">\n <Label htmlFor=\"hh-tags\">{tr('brainyrich.households.form.tags', 'Tags')}</Label>\n <Input\n id=\"hh-tags\"\n value={form.tags}\n onChange={(e) => setField('tags', e.target.value)}\n placeholder={tr('brainyrich.households.form.tagsPh', 'Comma-separated')}\n />\n </div>\n )}\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"hh-notes\">{tr('brainyrich.households.form.notes', 'Notes')}</Label>\n <Textarea\n id=\"hh-notes\"\n value={form.notes}\n onChange={(e) => setField('notes', e.target.value)}\n rows={3}\n />\n </div>\n\n <DialogFooter>\n <DialogClose asChild>\n <Button type=\"button\" variant=\"outline\">\n {tr('brainyrich.common.cancel', 'Cancel')}\n </Button>\n </DialogClose>\n <Button type=\"submit\" disabled={!canSubmit}>\n {submitting\n ? tr('brainyrich.common.saving', 'Saving…')\n : editing\n ? tr('brainyrich.common.save', 'Save changes')\n : tr('brainyrich.households.form.create', 'Create household')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\n// ============================================================================\n// Detail sheet\n// ============================================================================\n\ninterface HouseholdDetailSheetProps {\n householdId: string | undefined;\n onClose: () => void;\n onEdit: (h: BraHousehold) => void;\n tr: (key: string, fallback: string, params?: Record<string, string | number>) => string;\n}\n\nfunction HouseholdDetailSheet({ householdId, onClose, onEdit, tr }: HouseholdDetailSheetProps) {\n const { data: household, isLoading, isError, refetch } = useHousehold(householdId);\n const { data: accounts } = useAccounts(householdId ? { householdId } : {});\n const { data: portfolios } = usePortfolios(householdId ? { householdId } : {});\n const { data: goals } = useGoals(householdId ? { householdId } : {});\n\n const open = Boolean(householdId);\n\n const accountRows = useMemo(\n () =>\n [...accounts]\n .map((a) => ({ account: a, value: accountValue(a) }))\n .sort((x, y) => y.value - x.value),\n [accounts]\n );\n const invested = accountRows.reduce((s, r) => s + r.value, 0);\n const allocDonut: DonutDatum[] = accountRows\n .filter((r) => r.value > 0)\n .slice(0, 6)\n .map((r) => ({ label: r.account.name, value: r.value }));\n\n return (\n <Sheet open={open} onOpenChange={(o) => (!o ? onClose() : undefined)}>\n <SheetContent className=\"flex w-full flex-col gap-0 overflow-y-auto p-0 sm:max-w-xl\">\n {isLoading ? (\n <div className=\"p-6\">\n <LoadingState rows={4} />\n </div>\n ) : isError ? (\n <div className=\"p-6\">\n <ErrorState\n title={tr('brainyrich.households.detail.error', 'Could not load household')}\n onRetry={() => refetch()}\n />\n </div>\n ) : !household ? (\n <div className=\"p-6\">\n <EmptyState\n icon={<Users className=\"size-6\" aria-hidden=\"true\" />}\n title={tr('brainyrich.households.detail.missing', 'Household not found')}\n />\n </div>\n ) : (\n <div className=\"space-y-5 p-6\">\n <SheetHeader className=\"space-y-2 p-0 text-left\">\n <SheetTitle className=\"text-xl\">{household.name}</SheetTitle>\n <SheetDescription className=\"sr-only\">\n {tr('brainyrich.households.detail.subtitle', 'Household overview')}\n </SheetDescription>\n <div className=\"flex flex-wrap items-center gap-2 pt-1\">\n <Badge variant={statusBadgeVariant(household.status)}>{household.status}</Badge>\n <Badge variant=\"secondary\">{household.riskProfile}</Badge>\n </div>\n </SheetHeader>\n\n {/* Hero — AUM + primary contact on a glass surface with emerald glow */}\n <GlassCard glow>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">\n {tr('brainyrich.households.detail.aum', 'AUM')}\n </p>\n <p className=\"mt-1 text-3xl font-semibold tracking-tight text-text-primary\">\n {formatMoney(household.aum, household.currency)}\n </p>\n <p className=\"mt-1 text-xs text-text-secondary\">{household.currency}</p>\n </div>\n <div className=\"sm:text-right\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">\n {tr('brainyrich.households.detail.contact', 'Primary contact')}\n </p>\n <p className=\"mt-1 text-base font-medium text-text-primary\">\n {household.primaryContactName ?? '—'}\n </p>\n {household.primaryContactEmail ? (\n <a\n href={`mailto:${household.primaryContactEmail}`}\n className=\"mt-0.5 inline-flex items-center gap-1 text-xs text-text-secondary hover:text-[var(--color-action-primary-text)] sm:justify-end\"\n >\n <Mail className=\"size-3\" aria-hidden=\"true\" />\n {household.primaryContactEmail}\n </a>\n ) : null}\n </div>\n </div>\n </GlassCard>\n\n {/* Portfolio counts */}\n <div className=\"grid grid-cols-3 gap-3\">\n <SummaryTile\n icon={<Wallet className=\"size-4\" aria-hidden=\"true\" />}\n label={tr('brainyrich.households.detail.accounts', 'Accounts')}\n value={String(accounts.length)}\n />\n <SummaryTile\n icon={<Briefcase className=\"size-4\" aria-hidden=\"true\" />}\n label={tr('brainyrich.households.detail.portfolios', 'Portfolios')}\n value={String(portfolios.length)}\n />\n <SummaryTile\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n label={tr('brainyrich.households.detail.goals', 'Goals')}\n value={String(goals.length)}\n />\n </div>\n\n {household.tags.length > 0 ? (\n <div className=\"flex flex-wrap gap-1\">\n {household.tags.map((tag) => (\n <Badge key={tag} variant=\"outline\">\n {tag}\n </Badge>\n ))}\n </div>\n ) : null}\n\n <Tabs defaultValue=\"overview\" className=\"w-full\">\n <TabsList className=\"w-full justify-start overflow-x-auto\">\n <TabsTrigger value=\"overview\">\n {tr('brainyrich.households.tab.overview', 'Overview')}\n </TabsTrigger>\n <TabsTrigger value=\"accounts\">\n {tr('brainyrich.households.detail.accounts', 'Accounts')}\n </TabsTrigger>\n <TabsTrigger value=\"goals\">\n {tr('brainyrich.households.detail.goals', 'Goals')}\n </TabsTrigger>\n <TabsTrigger value=\"documents\">\n {tr('brainyrich.households.detail.documents', 'Documents')}\n </TabsTrigger>\n <TabsTrigger value=\"discussion\">\n {tr('brainyrich.households.detail.discussion', 'Discussion')}\n </TabsTrigger>\n </TabsList>\n\n {/* Overview */}\n <TabsContent value=\"overview\" className=\"mt-4 space-y-4\">\n {allocDonut.length > 0 ? (\n <Card>\n <CardContent className=\"p-4\">\n <h3 className=\"mb-3 text-sm font-medium text-text-primary\">\n {tr('brainyrich.households.detail.allocation', 'Where assets sit')}\n </h3>\n <DonutChart\n data={allocDonut}\n centerValue={formatCompact(invested, household.currency)}\n centerLabel={tr('brainyrich.households.detail.invested', 'Invested')}\n height={200}\n valueFormatter={(v) => formatMoney(v, household.currency)}\n />\n </CardContent>\n </Card>\n ) : null}\n\n <Card>\n <CardContent className=\"space-y-3 p-4 text-sm\">\n <div className=\"flex items-center justify-between gap-4\">\n <span className=\"text-text-secondary\">\n {tr('brainyrich.households.detail.advisor', 'Advisor')}\n </span>\n <span className=\"text-right font-medium text-text-primary\">\n {household.advisorId ? (\n <ActorName id={household.advisorId} />\n ) : (\n tr('brainyrich.common.unassigned', 'Unassigned')\n )}\n </span>\n </div>\n <Separator />\n <DetailRow\n label={tr('brainyrich.households.detail.created', 'Created')}\n value={formatDate(household.createdAt)}\n />\n <DetailRow\n label={tr('brainyrich.households.detail.updated', 'Last updated')}\n value={formatDate(household.updatedAt)}\n />\n </CardContent>\n </Card>\n\n {household.notes ? (\n <Card>\n <CardContent className=\"space-y-1 p-4\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {tr('brainyrich.households.detail.summary', 'Summary')}\n </p>\n <p className=\"text-sm text-text-primary\">{household.notes}</p>\n </CardContent>\n </Card>\n ) : null}\n\n <Card>\n <CardContent className=\"p-4\">\n <TagField entityType=\"brainyrich-household\" entityId={household.id} />\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Accounts */}\n <TabsContent value=\"accounts\" className=\"mt-4 space-y-2\">\n {accountRows.length === 0 ? (\n <EmptyState\n icon={<Wallet className=\"size-6\" aria-hidden=\"true\" />}\n title={tr('brainyrich.households.detail.noAccounts', 'No accounts linked')}\n />\n ) : (\n accountRows.map(({ account, value }) => (\n <div\n key={account.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-subtle bg-bg-surface p-3 transition-colors hover:border-[var(--color-action-primary-border)]\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {account.name}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {account.institution ?? account.type}\n {account.accountMask ? ` ·••${account.accountMask}` : ''}\n </p>\n </div>\n <span className=\"shrink-0 text-sm font-semibold tabular-nums text-status-success-text\">\n {formatMoney(value, account.currency)}\n </span>\n </div>\n ))\n )}\n </TabsContent>\n\n {/* Goals */}\n <TabsContent value=\"goals\" className=\"mt-4 space-y-2\">\n {goals.length === 0 ? (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={tr('brainyrich.households.detail.noGoals', 'No goals set')}\n />\n ) : (\n goals.map((g: BraGoal) => (\n <div\n key={g.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-subtle bg-bg-surface p-3\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{g.name}</p>\n <p className=\"text-xs text-text-secondary\">\n {tr('brainyrich.households.detail.goalTarget', 'Target')}{' '}\n {formatMoney(g.targetAmount, g.currency)} · {formatDate(g.targetDate)}\n </p>\n </div>\n <Badge variant={statusBadgeVariant(g.projection)} className=\"shrink-0\">\n {g.projection.replace(/_/g, ' ')}\n </Badge>\n </div>\n ))\n )}\n </TabsContent>\n\n {/* Documents */}\n <TabsContent value=\"documents\" className=\"mt-4\">\n <DocumentsPanel\n entityType=\"brainyrich-household\"\n entityId={household.id}\n heading={tr('brainyrich.households.detail.documents', 'Documents')}\n />\n </TabsContent>\n\n {/* Discussion */}\n <TabsContent value=\"discussion\" className=\"mt-4\">\n <CommentThread\n entityType=\"brainyrich-household\"\n entityId={household.id}\n heading={tr('brainyrich.households.detail.discussion', 'Discussion')}\n />\n </TabsContent>\n </Tabs>\n\n <Button variant=\"outline\" className=\"w-full\" onClick={() => onEdit(household)}>\n <Pencil className=\"size-4\" aria-hidden=\"true\" />\n {tr('brainyrich.households.action.edit', 'Edit')}\n </Button>\n </div>\n )}\n </SheetContent>\n </Sheet>\n );\n}\n\nfunction SummaryTile({ icon, label, value }: { icon: ReactNode; label: string; value: string }) {\n return (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-3 text-center transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <div className=\"mx-auto mb-1 flex size-8 items-center justify-center rounded-full bg-bg-sunken text-text-secondary\">\n {icon}\n </div>\n <p className=\"text-lg font-semibold text-text-primary\">{value}</p>\n <p className=\"text-xs text-text-secondary\">{label}</p>\n </div>\n );\n}\n\nfunction DetailRow({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-center justify-between gap-4\">\n <span className=\"text-text-secondary\">{label}</span>\n <span className=\"text-right font-medium text-text-primary\">{value}</span>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FamilyPage.js","names":[],"sources":["../../../src/brainyrich/pages/FamilyPage.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n Dialog,\n DialogClose,\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 Separator,\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Users,\n MoreHorizontal,\n Pencil,\n Archive,\n Eye,\n Mail,\n Wallet,\n Target,\n Briefcase,\n Building2,\n TrendingUp,\n UserCircle2,\n} from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n usePagedHouseholds,\n useHousehold,\n useCreateHousehold,\n useUpdateHousehold,\n useArchiveHousehold,\n useAccounts,\n usePortfolios,\n useGoals,\n} from '../hooks/useBrainyRichApi';\nimport {\n ConfirmDialog,\n LoadMore,\n ActorName,\n StatTile,\n GlassCard,\n FadeIn,\n DonutChart,\n type DonutDatum,\n} from '../components';\nimport { TagField } from '../components/reuse/TagField';\nimport { DocumentsPanel } from '../components/reuse/DocumentsPanel';\nimport { hapticSuccess, showToast } from '../utils/nativeControls';\nimport { useTrackBrainyRichPageView } from '../hooks/useBrainyRichAnalytics';\nimport { CommentThread } from '../components/reuse/CommentThread';\nimport type {\n BraHousehold,\n BraHouseholdStatus,\n BraRiskProfile,\n BraCreateHouseholdInput,\n BraUpdateHouseholdInput,\n BraAccount,\n BraGoal,\n} from '../types/bra';\nimport {\n SectionShell,\n EmptyState,\n LoadingState,\n ErrorState,\n formatMoney,\n formatCompact,\n formatDate,\n statusBadgeVariant,\n} from './_shared';\n\nconst STATUS_OPTIONS: BraHouseholdStatus[] = ['PROSPECT', 'ONBOARDING', 'ACTIVE', 'INACTIVE'];\nconst RISK_OPTIONS: BraRiskProfile[] = [\n 'CONSERVATIVE',\n 'MODERATE',\n 'BALANCED',\n 'GROWTH',\n 'AGGRESSIVE',\n];\nconst CURRENCY_OPTIONS = ['USD', 'EUR', 'GBP', 'INR', 'AED', 'SGD'];\n\n/** Per-status donut tone (semantic — colour is never the only signal). */\nconst STATUS_TONE: Record<BraHouseholdStatus, DonutDatum['tone']> = {\n ACTIVE: 'brand',\n ONBOARDING: 'info',\n PROSPECT: 'warning',\n INACTIVE: 'neutral',\n};\n\ninterface HouseholdFormState {\n name: string;\n status: BraHouseholdStatus;\n riskProfile: BraRiskProfile;\n currency: string;\n advisorId: string;\n primaryContactName: string;\n primaryContactEmail: string;\n notes: string;\n tags: string;\n}\n\nconst emptyForm: HouseholdFormState = {\n name: '',\n status: 'PROSPECT',\n riskProfile: 'BALANCED',\n currency: 'USD',\n advisorId: '',\n primaryContactName: '',\n primaryContactEmail: '',\n notes: '',\n tags: '',\n};\n\nfunction toTags(raw: string): string[] {\n return raw\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n}\n\n/** Real market value of an account: settled cash + marked-to-market holdings. */\nfunction accountValue(a: BraAccount): number {\n const holdings = (a.holdings ?? []).reduce(\n (sum, h) => sum + (Number.isFinite(h.marketValue) ? h.marketValue : 0),\n 0\n );\n const cash = Number.isFinite(a.cashBalance) ? a.cashBalance : 0;\n return cash + holdings;\n}\n\nexport function FamilyPage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n\n useTrackBrainyRichPageView('brainyrich.family.viewed');\n\n const {\n items: households,\n hasMore,\n loadMore,\n isLoading,\n isFetchingNextPage,\n isError,\n refetch,\n } = usePagedHouseholds();\n\n const createHousehold = useCreateHousehold();\n const updateHousehold = useUpdateHousehold();\n const archiveHousehold = useArchiveHousehold();\n\n const [formOpen, setFormOpen] = useState(false);\n const [editing, setEditing] = useState<BraHousehold | null>(null);\n const [form, setForm] = useState<HouseholdFormState>(emptyForm);\n const [detailId, setDetailId] = useState<string | undefined>(undefined);\n const [archiveTarget, setArchiveTarget] = useState<BraHousehold | null>(null);\n\n const setField = <K extends keyof HouseholdFormState>(key: K, value: HouseholdFormState[K]) =>\n setForm((prev) => ({ ...prev, [key]: value }));\n\n const openCreate = () => {\n setEditing(null);\n setForm(emptyForm);\n setFormOpen(true);\n };\n\n const openEdit = (h: BraHousehold) => {\n setEditing(h);\n setForm({\n name: h.name,\n status: h.status,\n riskProfile: h.riskProfile,\n currency: h.currency,\n advisorId: h.advisorId ?? '',\n primaryContactName: h.primaryContactName ?? '',\n primaryContactEmail: h.primaryContactEmail ?? '',\n notes: h.notes ?? '',\n tags: h.tags.join(', '),\n });\n setFormOpen(true);\n };\n\n const firm = useMemo(() => {\n const currency = households[0]?.currency ?? 'USD';\n const total = households.length;\n const active = households.filter((h) => h.status === 'ACTIVE').length;\n const prospects = households.filter((h) => h.status === 'PROSPECT').length;\n const onboarding = households.filter((h) => h.status === 'ONBOARDING').length;\n const aum = households.reduce((sum, h) => sum + (Number.isFinite(h.aum) ? h.aum : 0), 0);\n\n // AUM grouped by advisor (empty advisorId → unassigned bucket).\n const byAdvisor = new Map<string, number>();\n for (const h of households) {\n const key = h.advisorId?.trim() || '';\n byAdvisor.set(key, (byAdvisor.get(key) ?? 0) + (Number.isFinite(h.aum) ? h.aum : 0));\n }\n const advisors = Array.from(byAdvisor.entries())\n .map(([advisorId, value]) => ({ advisorId, value }))\n .sort((a, b) => b.value - a.value);\n const advisorCount = advisors.filter((a) => a.advisorId).length;\n const advisorMax = advisors.reduce((m, a) => Math.max(m, a.value), 0);\n\n // Book mix by status → donut.\n const statusMix: DonutDatum[] = (STATUS_OPTIONS as BraHouseholdStatus[])\n .map((s) => ({\n label: s.charAt(0) + s.slice(1).toLowerCase(),\n value: households.filter((h) => h.status === s).length,\n tone: STATUS_TONE[s],\n }))\n .filter((d) => d.value > 0);\n\n return {\n currency,\n total,\n active,\n prospects,\n onboarding,\n aum,\n advisors,\n advisorCount,\n advisorMax,\n statusMix,\n };\n }, [households]);\n\n const submitting = createHousehold.isPending || updateHousehold.isPending;\n const canSubmit = form.name.trim().length > 0 && !submitting;\n\n const handleSubmit = () => {\n if (!canSubmit) return;\n if (editing) {\n const input: BraUpdateHouseholdInput = {\n name: form.name.trim(),\n status: form.status,\n riskProfile: form.riskProfile,\n currency: form.currency,\n primaryContactName: form.primaryContactName.trim() || null,\n primaryContactEmail: form.primaryContactEmail.trim() || null,\n notes: form.notes.trim() || null,\n tags: toTags(form.tags),\n };\n updateHousehold.mutate(\n { id: editing.id, input },\n {\n onSuccess: () => {\n hapticSuccess();\n void showToast(tr('brainyrich.households.saved', 'Household saved'));\n setFormOpen(false);\n },\n }\n );\n } else {\n const input: BraCreateHouseholdInput = {\n name: form.name.trim(),\n status: form.status,\n riskProfile: form.riskProfile,\n currency: form.currency,\n primaryContactName: form.primaryContactName.trim() || null,\n primaryContactEmail: form.primaryContactEmail.trim() || null,\n notes: form.notes.trim() || null,\n tags: toTags(form.tags),\n };\n if (form.advisorId.trim()) input.advisorId = form.advisorId.trim();\n createHousehold.mutate(input, {\n onSuccess: () => {\n hapticSuccess();\n void showToast(tr('brainyrich.households.created', 'Household created'));\n setFormOpen(false);\n },\n });\n }\n };\n\n const showFirm = !isLoading && !isError && households.length > 0;\n\n return (\n <div data-tour=\"brainyrich-page-households\" className=\"contents\">\n <SectionShell\n title={tr('brainyrich.households.title', 'Households')}\n description={tr(\n 'brainyrich.households.description',\n 'Client households and family units under advisement'\n )}\n badges={\n households.length\n ? [\n tr('brainyrich.households.count', '{count} households', {\n count: households.length,\n }),\n ]\n : []\n }\n actionLabel={tr('brainyrich.households.new', 'New household')}\n onAction={openCreate}\n >\n {showFirm ? (\n <FirmOverview firm={firm} tr={tr} />\n ) : (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <StatTile label={tr('brainyrich.households.kpi.aum', 'Total AUM')} value=\"—\" glow />\n <StatTile label={tr('brainyrich.households.kpi.total', 'Households')} value=\"—\" />\n <StatTile label={tr('brainyrich.households.kpi.active', 'Active')} value=\"—\" />\n <StatTile label={tr('brainyrich.households.kpi.prospects', 'Prospects')} value=\"—\" />\n </div>\n )}\n\n {isLoading ? (\n <LoadingState rows={5} />\n ) : isError ? (\n <ErrorState\n title={tr('brainyrich.households.error.title', 'Could not load households')}\n onRetry={() => refetch()}\n />\n ) : households.length === 0 ? (\n <EmptyState\n icon={<Users className=\"size-6\" aria-hidden=\"true\" />}\n title={tr('brainyrich.households.empty.title', 'No households yet')}\n description={tr(\n 'brainyrich.households.empty.description',\n 'Create your first client household to start organizing accounts, portfolios and goals.'\n )}\n action={\n <Button size=\"sm\" onClick={openCreate}>\n {tr('brainyrich.households.new', 'New household')}\n </Button>\n }\n />\n ) : (\n <FadeIn as=\"section\">\n <Card className=\"overflow-hidden\">\n <CardContent className=\"p-0\">\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead>{tr('brainyrich.households.col.name', 'Household')}</TableHead>\n <TableHead>{tr('brainyrich.households.col.status', 'Status')}</TableHead>\n <TableHead className=\"hidden md:table-cell\">\n {tr('brainyrich.households.col.risk', 'Risk profile')}\n </TableHead>\n <TableHead className=\"hidden lg:table-cell\">\n {tr('brainyrich.households.col.contact', 'Primary contact')}\n </TableHead>\n <TableHead className=\"hidden sm:table-cell\">\n {tr('brainyrich.households.col.advisor', 'Advisor')}\n </TableHead>\n <TableHead className=\"text-right\">\n {tr('brainyrich.households.col.aum', 'AUM')}\n </TableHead>\n <TableHead className=\"w-12 text-right\">\n <span className=\"sr-only\">\n {tr('brainyrich.households.col.actions', 'Actions')}\n </span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {households.map((h) => {\n const share = firm.aum > 0 ? Math.min(100, (h.aum / firm.aum) * 100) : 0;\n return (\n <TableRow\n key={h.id}\n className=\"group cursor-pointer transition-colors\"\n onClick={() => setDetailId(h.id)}\n >\n <TableCell>\n <span className=\"font-medium text-text-primary transition-colors group-hover:text-[var(--color-action-primary-text)]\">\n {h.name}\n </span>\n {h.tags.length > 0 ? (\n <div className=\"mt-1 flex flex-wrap gap-1\">\n {h.tags.slice(0, 3).map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n {h.tags.length > 3 ? (\n <Badge variant=\"outline\" className=\"text-xs\">\n +{h.tags.length - 3}\n </Badge>\n ) : null}\n </div>\n ) : null}\n </TableCell>\n <TableCell>\n <Badge variant={statusBadgeVariant(h.status)}>{h.status}</Badge>\n </TableCell>\n <TableCell className=\"hidden md:table-cell\">\n <Badge variant=\"secondary\">{h.riskProfile}</Badge>\n </TableCell>\n <TableCell className=\"hidden lg:table-cell\">\n {h.primaryContactName ? (\n <div className=\"space-y-0.5\">\n <p className=\"text-sm text-text-primary\">\n {h.primaryContactName}\n </p>\n {h.primaryContactEmail ? (\n <p className=\"flex items-center gap-1 text-xs text-text-secondary\">\n <Mail className=\"size-3\" aria-hidden=\"true\" />\n {h.primaryContactEmail}\n </p>\n ) : null}\n </div>\n ) : (\n <span className=\"text-sm text-text-muted\">—</span>\n )}\n </TableCell>\n <TableCell className=\"hidden sm:table-cell\">\n {h.advisorId ? (\n <span className=\"flex items-center gap-1.5 text-sm text-text-secondary\">\n <UserCircle2 className=\"size-3.5\" aria-hidden=\"true\" />\n <ActorName id={h.advisorId} />\n </span>\n ) : (\n <span className=\"text-sm text-text-muted\">\n {tr('brainyrich.common.unassigned', 'Unassigned')}\n </span>\n )}\n </TableCell>\n <TableCell className=\"text-right\">\n <div className=\"flex flex-col items-end gap-1\">\n <span className=\"font-medium tabular-nums text-text-primary\">\n {formatMoney(h.aum, h.currency)}\n </span>\n <span\n className=\"h-1 w-16 overflow-hidden rounded-full bg-bg-sunken\"\n aria-hidden=\"true\"\n >\n <span\n className=\"block h-full rounded-full bg-[var(--color-action-primary-bg)]\"\n style={{ width: `${share}%` }}\n />\n </span>\n </div>\n </TableCell>\n <TableCell className=\"text-right\" onClick={(e) => e.stopPropagation()}>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={tr(\n 'brainyrich.households.rowMenu',\n 'Household actions'\n )}\n >\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setDetailId(h.id)}>\n <Eye className=\"size-4\" aria-hidden=\"true\" />\n {tr('brainyrich.households.action.view', 'View details')}\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => openEdit(h)}>\n <Pencil className=\"size-4\" aria-hidden=\"true\" />\n {tr('brainyrich.households.action.edit', 'Edit')}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"text-status-error-text focus:text-status-error-text\"\n onClick={() => setArchiveTarget(h)}\n >\n <Archive className=\"size-4\" aria-hidden=\"true\" />\n {tr('brainyrich.households.action.archive', 'Archive')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n </CardContent>\n </Card>\n </FadeIn>\n )}\n\n {!isLoading && !isError && households.length > 0 ? (\n <LoadMore\n hasMore={hasMore}\n onClick={loadMore}\n loading={isFetchingNextPage}\n label={tr('brainyrich.households.loadMore', 'Load more households')}\n />\n ) : null}\n\n <HouseholdFormDialog\n open={formOpen}\n onOpenChange={setFormOpen}\n editing={editing}\n form={form}\n setField={setField}\n onSubmit={handleSubmit}\n canSubmit={canSubmit}\n submitting={submitting}\n tr={tr}\n />\n\n <HouseholdDetailSheet\n householdId={detailId}\n onClose={() => setDetailId(undefined)}\n onEdit={(h) => {\n setDetailId(undefined);\n openEdit(h);\n }}\n tr={tr}\n />\n\n <ConfirmDialog\n open={Boolean(archiveTarget)}\n onOpenChange={(o) => (!o ? setArchiveTarget(null) : undefined)}\n title={tr('brainyrich.households.archive.title', 'Archive household?')}\n description={tr(\n 'brainyrich.households.archive.description',\n 'Archiving “{name}” removes it from the active list. You can still access its records, but it will no longer appear here.',\n { name: archiveTarget?.name ?? '' }\n )}\n confirmLabel={tr('brainyrich.households.action.archive', 'Archive')}\n pendingLabel={tr('brainyrich.households.archive.pending', 'Archiving…')}\n destructive\n pending={archiveHousehold.isPending}\n onConfirm={() => {\n if (!archiveTarget) return;\n archiveHousehold.mutate(archiveTarget.id, {\n onSuccess: () => {\n hapticSuccess();\n void showToast(\n tr('brainyrich.households.archived', 'Household archived', {\n name: archiveTarget.name,\n })\n );\n setArchiveTarget(null);\n },\n });\n }}\n />\n </SectionShell>\n </div>\n );\n}\n\n// ============================================================================\n// Firm overview — practice-wide KPIs + AUM-by-advisor + book mix\n// ============================================================================\n\ninterface FirmData {\n currency: string;\n total: number;\n active: number;\n prospects: number;\n onboarding: number;\n aum: number;\n advisors: { advisorId: string; value: number }[];\n advisorCount: number;\n advisorMax: number;\n statusMix: DonutDatum[];\n}\n\nfunction FirmOverview({\n firm,\n tr,\n}: {\n firm: FirmData;\n tr: (key: string, fallback: string, params?: Record<string, string | number>) => string;\n}) {\n return (\n <FadeIn as=\"section\" className=\"space-y-4\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <StatTile\n label={tr('brainyrich.households.kpi.aum', 'Total AUM')}\n value={formatMoney(firm.aum, firm.currency)}\n glow\n icon={<Wallet className=\"size-4\" aria-hidden=\"true\" />}\n />\n <StatTile\n label={tr('brainyrich.households.kpi.total', 'Households')}\n value={String(firm.total)}\n icon={<Users className=\"size-4\" aria-hidden=\"true\" />}\n />\n <StatTile\n label={tr('brainyrich.households.kpi.active', 'Active')}\n value={String(firm.active)}\n icon={<TrendingUp className=\"size-4\" aria-hidden=\"true\" />}\n />\n <StatTile\n label={tr('brainyrich.households.kpi.prospects', 'Prospects')}\n value={String(firm.prospects)}\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n />\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-3\">\n <GlassCard className=\"lg:col-span-2\">\n <div className=\"mb-4 flex items-center justify-between gap-2\">\n <div>\n <h2 className=\"text-sm font-semibold text-text-primary\">\n {tr('brainyrich.households.firm.byAdvisor', 'AUM by advisor')}\n </h2>\n <p className=\"text-xs text-text-secondary\">\n {tr('brainyrich.households.firm.advisorCount', '{count} advisors', {\n count: firm.advisorCount,\n })}\n </p>\n </div>\n <Building2 className=\"size-4 text-text-secondary\" aria-hidden=\"true\" />\n </div>\n <ul\n className=\"space-y-3.5\"\n aria-label={tr('brainyrich.households.firm.byAdvisor', 'AUM by advisor')}\n >\n {firm.advisors.map((a) => {\n const width =\n firm.advisorMax > 0 ? Math.max(2, (a.value / firm.advisorMax) * 100) : 0;\n return (\n <li key={a.advisorId || 'unassigned'} className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between gap-3 text-xs\">\n <span className=\"flex items-center gap-1.5 truncate font-medium text-text-primary\">\n <UserCircle2\n className=\"size-3.5 shrink-0 text-text-secondary\"\n aria-hidden=\"true\"\n />\n {a.advisorId ? (\n <ActorName id={a.advisorId} />\n ) : (\n tr('brainyrich.common.unassigned', 'Unassigned')\n )}\n </span>\n <span className=\"shrink-0 tabular-nums text-text-secondary\">\n {formatCompact(a.value, firm.currency)}\n </span>\n </div>\n <div\n className=\"h-2 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={a.advisorId || 'Unassigned'}\n >\n <div\n className=\"h-full rounded-full bg-[var(--color-action-primary-bg)] transition-[width] duration-500 ease-out\"\n style={{ width: `${width}%` }}\n />\n </div>\n </li>\n );\n })}\n </ul>\n </GlassCard>\n\n <GlassCard>\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <h2 className=\"text-sm font-semibold text-text-primary\">\n {tr('brainyrich.households.firm.bookMix', 'Book by status')}\n </h2>\n </div>\n {firm.statusMix.length > 0 ? (\n <DonutChart\n data={firm.statusMix}\n centerValue={String(firm.total)}\n centerLabel={tr('brainyrich.households.kpi.total', 'Households')}\n legend\n height={200}\n valueFormatter={(v) => String(v)}\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr('brainyrich.households.firm.noMix', 'No households to chart yet.')}\n </p>\n )}\n </GlassCard>\n </div>\n </FadeIn>\n );\n}\n\n// ============================================================================\n// Create / edit dialog\n// ============================================================================\n\ninterface HouseholdFormDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n editing: BraHousehold | null;\n form: HouseholdFormState;\n setField: <K extends keyof HouseholdFormState>(key: K, value: HouseholdFormState[K]) => void;\n onSubmit: () => void;\n canSubmit: boolean;\n submitting: boolean;\n tr: (key: string, fallback: string, params?: Record<string, string | number>) => string;\n}\n\nfunction HouseholdFormDialog({\n open,\n onOpenChange,\n editing,\n form,\n setField,\n onSubmit,\n canSubmit,\n submitting,\n tr,\n}: HouseholdFormDialogProps) {\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 {editing\n ? tr('brainyrich.households.form.editTitle', 'Edit household')\n : tr('brainyrich.households.form.createTitle', 'New household')}\n </DialogTitle>\n <DialogDescription>\n {tr(\n 'brainyrich.households.form.subtitle',\n 'A household groups a client family’s accounts, portfolios and goals.'\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-2\">\n <Label htmlFor=\"hh-name\">{tr('brainyrich.households.form.name', 'Name')} *</Label>\n <Input\n id=\"hh-name\"\n value={form.name}\n onChange={(e) => setField('name', e.target.value)}\n placeholder={tr('brainyrich.households.form.namePh', 'e.g. The Raghavan Family')}\n required\n />\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label>{tr('brainyrich.households.form.status', 'Status')}</Label>\n <Select\n value={form.status}\n onValueChange={(v) => setField('status', v as BraHouseholdStatus)}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STATUS_OPTIONS.map((s) => (\n <SelectItem key={s} value={s}>\n {s}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-2\">\n <Label>{tr('brainyrich.households.form.risk', 'Risk profile')}</Label>\n <Select\n value={form.riskProfile}\n onValueChange={(v) => setField('riskProfile', v as BraRiskProfile)}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {RISK_OPTIONS.map((r) => (\n <SelectItem key={r} value={r}>\n {r}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"hh-contact-name\">\n {tr('brainyrich.households.form.contactName', 'Primary contact')}\n </Label>\n <Input\n id=\"hh-contact-name\"\n value={form.primaryContactName}\n onChange={(e) => setField('primaryContactName', e.target.value)}\n placeholder={tr('brainyrich.households.form.contactNamePh', 'Full name')}\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"hh-contact-email\">\n {tr('brainyrich.households.form.contactEmail', 'Contact email')}\n </Label>\n <Input\n id=\"hh-contact-email\"\n type=\"email\"\n value={form.primaryContactEmail}\n onChange={(e) => setField('primaryContactEmail', e.target.value)}\n placeholder=\"name@example.com\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label>{tr('brainyrich.households.form.currency', 'Currency')}</Label>\n <Select value={form.currency} onValueChange={(v) => setField('currency', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {CURRENCY_OPTIONS.map((c) => (\n <SelectItem key={c} value={c}>\n {c}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {!editing ? (\n <div className=\"space-y-2\">\n <Label htmlFor=\"hh-advisor\">\n {tr('brainyrich.households.form.advisor', 'Advisor ID')}\n </Label>\n <Input\n id=\"hh-advisor\"\n value={form.advisorId}\n onChange={(e) => setField('advisorId', e.target.value)}\n placeholder={tr('brainyrich.households.form.advisorPh', 'Optional')}\n />\n </div>\n ) : null}\n </div>\n\n {editing ? (\n <TagField\n entityType=\"brainyrich-household\"\n entityId={editing.id}\n label={tr('brainyrich.households.form.tags', 'Tags')}\n />\n ) : (\n <div className=\"space-y-2\">\n <Label htmlFor=\"hh-tags\">{tr('brainyrich.households.form.tags', 'Tags')}</Label>\n <Input\n id=\"hh-tags\"\n value={form.tags}\n onChange={(e) => setField('tags', e.target.value)}\n placeholder={tr('brainyrich.households.form.tagsPh', 'Comma-separated')}\n />\n </div>\n )}\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"hh-notes\">{tr('brainyrich.households.form.notes', 'Notes')}</Label>\n <Textarea\n id=\"hh-notes\"\n value={form.notes}\n onChange={(e) => setField('notes', e.target.value)}\n rows={3}\n />\n </div>\n\n <DialogFooter>\n <DialogClose asChild>\n <Button type=\"button\" variant=\"outline\">\n {tr('brainyrich.common.cancel', 'Cancel')}\n </Button>\n </DialogClose>\n <Button type=\"submit\" disabled={!canSubmit}>\n {submitting\n ? tr('brainyrich.common.saving', 'Saving…')\n : editing\n ? tr('brainyrich.common.save', 'Save changes')\n : tr('brainyrich.households.form.create', 'Create household')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\n// ============================================================================\n// Detail sheet\n// ============================================================================\n\ninterface HouseholdDetailSheetProps {\n householdId: string | undefined;\n onClose: () => void;\n onEdit: (h: BraHousehold) => void;\n tr: (key: string, fallback: string, params?: Record<string, string | number>) => string;\n}\n\nfunction HouseholdDetailSheet({ householdId, onClose, onEdit, tr }: HouseholdDetailSheetProps) {\n const { data: household, isLoading, isError, refetch } = useHousehold(householdId);\n const { data: accounts } = useAccounts(householdId ? { householdId } : {});\n const { data: portfolios } = usePortfolios(householdId ? { householdId } : {});\n const { data: goals } = useGoals(householdId ? { householdId } : {});\n\n const open = Boolean(householdId);\n\n const accountRows = useMemo(\n () =>\n [...accounts]\n .map((a) => ({ account: a, value: accountValue(a) }))\n .sort((x, y) => y.value - x.value),\n [accounts]\n );\n const invested = accountRows.reduce((s, r) => s + r.value, 0);\n const allocDonut: DonutDatum[] = accountRows\n .filter((r) => r.value > 0)\n .slice(0, 6)\n .map((r) => ({ label: r.account.name, value: r.value }));\n\n return (\n <Sheet open={open} onOpenChange={(o) => (!o ? onClose() : undefined)}>\n <SheetContent className=\"flex w-full flex-col gap-0 overflow-y-auto p-0 sm:max-w-xl\">\n {isLoading ? (\n <div className=\"p-6\">\n <LoadingState rows={4} />\n </div>\n ) : isError ? (\n <div className=\"p-6\">\n <ErrorState\n title={tr('brainyrich.households.detail.error', 'Could not load household')}\n onRetry={() => refetch()}\n />\n </div>\n ) : !household ? (\n <div className=\"p-6\">\n <EmptyState\n icon={<Users className=\"size-6\" aria-hidden=\"true\" />}\n title={tr('brainyrich.households.detail.missing', 'Household not found')}\n />\n </div>\n ) : (\n <div className=\"space-y-5 p-6\">\n <SheetHeader className=\"space-y-2 p-0 text-left\">\n <SheetTitle className=\"text-xl\">{household.name}</SheetTitle>\n <SheetDescription className=\"sr-only\">\n {tr('brainyrich.households.detail.subtitle', 'Household overview')}\n </SheetDescription>\n <div className=\"flex flex-wrap items-center gap-2 pt-1\">\n <Badge variant={statusBadgeVariant(household.status)}>{household.status}</Badge>\n <Badge variant=\"secondary\">{household.riskProfile}</Badge>\n </div>\n </SheetHeader>\n\n {/* Hero — AUM + primary contact on a glass surface with emerald glow */}\n <GlassCard glow>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">\n {tr('brainyrich.households.detail.aum', 'AUM')}\n </p>\n <p className=\"mt-1 text-3xl font-semibold tracking-tight text-text-primary\">\n {formatMoney(household.aum, household.currency)}\n </p>\n <p className=\"mt-1 text-xs text-text-secondary\">{household.currency}</p>\n </div>\n <div className=\"sm:text-right\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">\n {tr('brainyrich.households.detail.contact', 'Primary contact')}\n </p>\n <p className=\"mt-1 text-base font-medium text-text-primary\">\n {household.primaryContactName ?? '—'}\n </p>\n {household.primaryContactEmail ? (\n <a\n href={`mailto:${household.primaryContactEmail}`}\n className=\"mt-0.5 inline-flex items-center gap-1 text-xs text-text-secondary hover:text-[var(--color-action-primary-text)] sm:justify-end\"\n >\n <Mail className=\"size-3\" aria-hidden=\"true\" />\n {household.primaryContactEmail}\n </a>\n ) : null}\n </div>\n </div>\n </GlassCard>\n\n {/* Portfolio counts */}\n <div className=\"grid grid-cols-3 gap-3\">\n <SummaryTile\n icon={<Wallet className=\"size-4\" aria-hidden=\"true\" />}\n label={tr('brainyrich.households.detail.accounts', 'Accounts')}\n value={String(accounts.length)}\n />\n <SummaryTile\n icon={<Briefcase className=\"size-4\" aria-hidden=\"true\" />}\n label={tr('brainyrich.households.detail.portfolios', 'Portfolios')}\n value={String(portfolios.length)}\n />\n <SummaryTile\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n label={tr('brainyrich.households.detail.goals', 'Goals')}\n value={String(goals.length)}\n />\n </div>\n\n {household.tags.length > 0 ? (\n <div className=\"flex flex-wrap gap-1\">\n {household.tags.map((tag) => (\n <Badge key={tag} variant=\"outline\">\n {tag}\n </Badge>\n ))}\n </div>\n ) : null}\n\n <Tabs defaultValue=\"overview\" className=\"w-full\">\n <TabsList className=\"w-full justify-start overflow-x-auto\">\n <TabsTrigger value=\"overview\">\n {tr('brainyrich.households.tab.overview', 'Overview')}\n </TabsTrigger>\n <TabsTrigger value=\"accounts\">\n {tr('brainyrich.households.detail.accounts', 'Accounts')}\n </TabsTrigger>\n <TabsTrigger value=\"goals\">\n {tr('brainyrich.households.detail.goals', 'Goals')}\n </TabsTrigger>\n <TabsTrigger value=\"documents\">\n {tr('brainyrich.households.detail.documents', 'Documents')}\n </TabsTrigger>\n <TabsTrigger value=\"discussion\">\n {tr('brainyrich.households.detail.discussion', 'Discussion')}\n </TabsTrigger>\n </TabsList>\n\n {/* Overview */}\n <TabsContent value=\"overview\" className=\"mt-4 space-y-4\">\n {allocDonut.length > 0 ? (\n <Card>\n <CardContent className=\"p-4\">\n <h3 className=\"mb-3 text-sm font-medium text-text-primary\">\n {tr('brainyrich.households.detail.allocation', 'Where assets sit')}\n </h3>\n <DonutChart\n data={allocDonut}\n centerValue={formatCompact(invested, household.currency)}\n centerLabel={tr('brainyrich.households.detail.invested', 'Invested')}\n height={200}\n valueFormatter={(v) => formatMoney(v, household.currency)}\n />\n </CardContent>\n </Card>\n ) : null}\n\n <Card>\n <CardContent className=\"space-y-3 p-4 text-sm\">\n <div className=\"flex items-center justify-between gap-4\">\n <span className=\"text-text-secondary\">\n {tr('brainyrich.households.detail.advisor', 'Advisor')}\n </span>\n <span className=\"text-right font-medium text-text-primary\">\n {household.advisorId ? (\n <ActorName id={household.advisorId} />\n ) : (\n tr('brainyrich.common.unassigned', 'Unassigned')\n )}\n </span>\n </div>\n <Separator />\n <DetailRow\n label={tr('brainyrich.households.detail.created', 'Created')}\n value={formatDate(household.createdAt)}\n />\n <DetailRow\n label={tr('brainyrich.households.detail.updated', 'Last updated')}\n value={formatDate(household.updatedAt)}\n />\n </CardContent>\n </Card>\n\n {household.notes ? (\n <Card>\n <CardContent className=\"space-y-1 p-4\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {tr('brainyrich.households.detail.summary', 'Summary')}\n </p>\n <p className=\"text-sm text-text-primary\">{household.notes}</p>\n </CardContent>\n </Card>\n ) : null}\n\n <Card>\n <CardContent className=\"p-4\">\n <TagField entityType=\"brainyrich-household\" entityId={household.id} />\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Accounts */}\n <TabsContent value=\"accounts\" className=\"mt-4 space-y-2\">\n {accountRows.length === 0 ? (\n <EmptyState\n icon={<Wallet className=\"size-6\" aria-hidden=\"true\" />}\n title={tr('brainyrich.households.detail.noAccounts', 'No accounts linked')}\n />\n ) : (\n accountRows.map(({ account, value }) => (\n <div\n key={account.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-subtle bg-bg-surface p-3 transition-colors hover:border-[var(--color-action-primary-border)]\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {account.name}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {account.institution ?? account.type}\n {account.accountMask ? ` ·••${account.accountMask}` : ''}\n </p>\n </div>\n <span className=\"shrink-0 text-sm font-semibold tabular-nums text-status-success-text\">\n {formatMoney(value, account.currency)}\n </span>\n </div>\n ))\n )}\n </TabsContent>\n\n {/* Goals */}\n <TabsContent value=\"goals\" className=\"mt-4 space-y-2\">\n {goals.length === 0 ? (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={tr('brainyrich.households.detail.noGoals', 'No goals set')}\n />\n ) : (\n goals.map((g: BraGoal) => (\n <div\n key={g.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-subtle bg-bg-surface p-3\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{g.name}</p>\n <p className=\"text-xs text-text-secondary\">\n {tr('brainyrich.households.detail.goalTarget', 'Target')}{' '}\n {formatMoney(g.targetAmount, g.currency)} · {formatDate(g.targetDate)}\n </p>\n </div>\n <Badge variant={statusBadgeVariant(g.projection)} className=\"shrink-0\">\n {g.projection.replace(/_/g, ' ')}\n </Badge>\n </div>\n ))\n )}\n </TabsContent>\n\n {/* Documents */}\n <TabsContent value=\"documents\" className=\"mt-4\">\n <DocumentsPanel\n entityType=\"brainyrich-household\"\n entityId={household.id}\n heading={tr('brainyrich.households.detail.documents', 'Documents')}\n />\n </TabsContent>\n\n {/* Discussion */}\n <TabsContent value=\"discussion\" className=\"mt-4\">\n <CommentThread\n entityType=\"brainyrich-household\"\n entityId={household.id}\n heading={tr('brainyrich.households.detail.discussion', 'Discussion')}\n />\n </TabsContent>\n </Tabs>\n\n <Button variant=\"outline\" className=\"w-full\" onClick={() => onEdit(household)}>\n <Pencil className=\"size-4\" aria-hidden=\"true\" />\n {tr('brainyrich.households.action.edit', 'Edit')}\n </Button>\n </div>\n )}\n </SheetContent>\n </Sheet>\n );\n}\n\nfunction SummaryTile({ icon, label, value }: { icon: ReactNode; label: string; value: string }) {\n return (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-3 text-center transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <div className=\"mx-auto mb-1 flex size-8 items-center justify-center rounded-full bg-bg-sunken text-text-secondary\">\n {icon}\n </div>\n <p className=\"text-lg font-semibold text-text-primary\">{value}</p>\n <p className=\"text-xs text-text-secondary\">{label}</p>\n </div>\n );\n}\n\nfunction DetailRow({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-center justify-between gap-4\">\n <span className=\"text-text-secondary\">{label}</span>\n <span className=\"text-right font-medium text-text-primary\">{value}</span>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmPage.d.ts","sourceRoot":"","sources":["../../../src/brainyrich/pages/FirmPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FirmPage.d.ts","sourceRoot":"","sources":["../../../src/brainyrich/pages/FirmPage.tsx"],"names":[],"mappings":"AA4FA,wBAAgB,QAAQ,4CAiIvB"}
|