@burdenoff/microfe-brainyrich 2026.706.2 → 2026.706.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (543) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +5 -5
  2. package/dist/brainyrich/components/viz.js +155 -156
  3. package/dist/brainyrich/components/viz.js.map +1 -1
  4. package/dist/brainyrich/pages/AccountsPage.js.map +1 -1
  5. package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
  6. package/dist/brainyrich/pages/AnalyticsPage.js.map +1 -1
  7. package/dist/brainyrich/pages/DashboardPage.js.map +1 -1
  8. package/dist/brainyrich/pages/FamilyPage.js.map +1 -1
  9. package/dist/brainyrich/pages/GoalsPage.js.map +1 -1
  10. package/dist/brainyrich/pages/InvestmentsPage.js.map +1 -1
  11. package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
  12. package/dist/brainyrich/pages/ReportsPage.js +2 -1
  13. package/dist/brainyrich/pages/ReportsPage.js.map +1 -1
  14. package/dist/brainyrich/pages/RiskPage.js.map +1 -1
  15. package/dist/brainyrich/pages/_shared.js +76 -68
  16. package/dist/brainyrich/pages/_shared.js.map +1 -1
  17. package/package.json +3 -4
  18. package/dist/_virtual/__vite-optional-peer-dep_@emotion/is-prop-valid_framer-motion.js +0 -10
  19. package/dist/_virtual/__vite-optional-peer-dep_@emotion/is-prop-valid_framer-motion.js.map +0 -1
  20. package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.js +0 -22
  21. package/dist/node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.js.map +0 -1
  22. package/dist/node_modules/framer-motion/dist/es/context/LayoutGroupContext.js +0 -8
  23. package/dist/node_modules/framer-motion/dist/es/context/LayoutGroupContext.js.map +0 -1
  24. package/dist/node_modules/framer-motion/dist/es/context/LazyContext.js +0 -8
  25. package/dist/node_modules/framer-motion/dist/es/context/LazyContext.js.map +0 -1
  26. package/dist/node_modules/framer-motion/dist/es/context/MotionConfigContext.js +0 -12
  27. package/dist/node_modules/framer-motion/dist/es/context/MotionConfigContext.js.map +0 -1
  28. package/dist/node_modules/framer-motion/dist/es/context/MotionContext/create.js +0 -19
  29. package/dist/node_modules/framer-motion/dist/es/context/MotionContext/create.js.map +0 -1
  30. package/dist/node_modules/framer-motion/dist/es/context/MotionContext/index.js +0 -8
  31. package/dist/node_modules/framer-motion/dist/es/context/MotionContext/index.js.map +0 -1
  32. package/dist/node_modules/framer-motion/dist/es/context/MotionContext/utils.js +0 -17
  33. package/dist/node_modules/framer-motion/dist/es/context/MotionContext/utils.js.map +0 -1
  34. package/dist/node_modules/framer-motion/dist/es/context/PresenceContext.js +0 -8
  35. package/dist/node_modules/framer-motion/dist/es/context/PresenceContext.js.map +0 -1
  36. package/dist/node_modules/framer-motion/dist/es/context/SwitchLayoutGroupContext.js +0 -8
  37. package/dist/node_modules/framer-motion/dist/es/context/SwitchLayoutGroupContext.js.map +0 -1
  38. package/dist/node_modules/framer-motion/dist/es/events/add-pointer-event.js +0 -10
  39. package/dist/node_modules/framer-motion/dist/es/events/add-pointer-event.js.map +0 -1
  40. package/dist/node_modules/framer-motion/dist/es/events/event-info.js +0 -13
  41. package/dist/node_modules/framer-motion/dist/es/events/event-info.js.map +0 -1
  42. package/dist/node_modules/framer-motion/dist/es/gestures/drag/VisualElementDragControls.js +0 -259
  43. package/dist/node_modules/framer-motion/dist/es/gestures/drag/VisualElementDragControls.js.map +0 -1
  44. package/dist/node_modules/framer-motion/dist/es/gestures/drag/index.js +0 -24
  45. package/dist/node_modules/framer-motion/dist/es/gestures/drag/index.js.map +0 -1
  46. package/dist/node_modules/framer-motion/dist/es/gestures/drag/utils/constraints.js +0 -61
  47. package/dist/node_modules/framer-motion/dist/es/gestures/drag/utils/constraints.js.map +0 -1
  48. package/dist/node_modules/framer-motion/dist/es/gestures/focus.js +0 -29
  49. package/dist/node_modules/framer-motion/dist/es/gestures/focus.js.map +0 -1
  50. package/dist/node_modules/framer-motion/dist/es/gestures/hover.js +0 -22
  51. package/dist/node_modules/framer-motion/dist/es/gestures/hover.js.map +0 -1
  52. package/dist/node_modules/framer-motion/dist/es/gestures/pan/PanSession.js +0 -135
  53. package/dist/node_modules/framer-motion/dist/es/gestures/pan/PanSession.js.map +0 -1
  54. package/dist/node_modules/framer-motion/dist/es/gestures/pan/index.js +0 -44
  55. package/dist/node_modules/framer-motion/dist/es/gestures/pan/index.js.map +0 -1
  56. package/dist/node_modules/framer-motion/dist/es/gestures/press.js +0 -28
  57. package/dist/node_modules/framer-motion/dist/es/gestures/press.js.map +0 -1
  58. package/dist/node_modules/framer-motion/dist/es/motion/features/animation/exit.js +0 -41
  59. package/dist/node_modules/framer-motion/dist/es/motion/features/animation/exit.js.map +0 -1
  60. package/dist/node_modules/framer-motion/dist/es/motion/features/animation/index.js +0 -27
  61. package/dist/node_modules/framer-motion/dist/es/motion/features/animation/index.js.map +0 -1
  62. package/dist/node_modules/framer-motion/dist/es/motion/features/animations.js +0 -11
  63. package/dist/node_modules/framer-motion/dist/es/motion/features/animations.js.map +0 -1
  64. package/dist/node_modules/framer-motion/dist/es/motion/features/definitions.js +0 -53
  65. package/dist/node_modules/framer-motion/dist/es/motion/features/definitions.js.map +0 -1
  66. package/dist/node_modules/framer-motion/dist/es/motion/features/drag.js +0 -17
  67. package/dist/node_modules/framer-motion/dist/es/motion/features/drag.js.map +0 -1
  68. package/dist/node_modules/framer-motion/dist/es/motion/features/gestures.js +0 -15
  69. package/dist/node_modules/framer-motion/dist/es/motion/features/gestures.js.map +0 -1
  70. package/dist/node_modules/framer-motion/dist/es/motion/features/layout/MeasureLayout.js +0 -63
  71. package/dist/node_modules/framer-motion/dist/es/motion/features/layout/MeasureLayout.js.map +0 -1
  72. package/dist/node_modules/framer-motion/dist/es/motion/features/layout.js +0 -11
  73. package/dist/node_modules/framer-motion/dist/es/motion/features/layout.js.map +0 -1
  74. package/dist/node_modules/framer-motion/dist/es/motion/features/load-features.js +0 -15
  75. package/dist/node_modules/framer-motion/dist/es/motion/features/load-features.js.map +0 -1
  76. package/dist/node_modules/framer-motion/dist/es/motion/features/viewport/index.js +0 -48
  77. package/dist/node_modules/framer-motion/dist/es/motion/features/viewport/index.js.map +0 -1
  78. package/dist/node_modules/framer-motion/dist/es/motion/features/viewport/observers.js +0 -26
  79. package/dist/node_modules/framer-motion/dist/es/motion/features/viewport/observers.js.map +0 -1
  80. package/dist/node_modules/framer-motion/dist/es/motion/index.js +0 -72
  81. package/dist/node_modules/framer-motion/dist/es/motion/index.js.map +0 -1
  82. package/dist/node_modules/framer-motion/dist/es/motion/utils/symbol.js +0 -6
  83. package/dist/node_modules/framer-motion/dist/es/motion/utils/symbol.js.map +0 -1
  84. package/dist/node_modules/framer-motion/dist/es/motion/utils/use-motion-ref.js +0 -24
  85. package/dist/node_modules/framer-motion/dist/es/motion/utils/use-motion-ref.js.map +0 -1
  86. package/dist/node_modules/framer-motion/dist/es/motion/utils/use-visual-element.js +0 -60
  87. package/dist/node_modules/framer-motion/dist/es/motion/utils/use-visual-element.js.map +0 -1
  88. package/dist/node_modules/framer-motion/dist/es/motion/utils/use-visual-state.js +0 -52
  89. package/dist/node_modules/framer-motion/dist/es/motion/utils/use-visual-state.js.map +0 -1
  90. package/dist/node_modules/framer-motion/dist/es/motion/utils/valid-prop.js +0 -9
  91. package/dist/node_modules/framer-motion/dist/es/motion/utils/valid-prop.js.map +0 -1
  92. package/dist/node_modules/framer-motion/dist/es/render/components/create-proxy.js +0 -12
  93. package/dist/node_modules/framer-motion/dist/es/render/components/create-proxy.js.map +0 -1
  94. package/dist/node_modules/framer-motion/dist/es/render/components/motion/feature-bundle.js +0 -15
  95. package/dist/node_modules/framer-motion/dist/es/render/components/motion/feature-bundle.js.map +0 -1
  96. package/dist/node_modules/framer-motion/dist/es/render/components/motion/proxy.js +0 -9
  97. package/dist/node_modules/framer-motion/dist/es/render/components/motion/proxy.js.map +0 -1
  98. package/dist/node_modules/framer-motion/dist/es/render/dom/create-visual-element.js +0 -10
  99. package/dist/node_modules/framer-motion/dist/es/render/dom/create-visual-element.js.map +0 -1
  100. package/dist/node_modules/framer-motion/dist/es/render/dom/use-render.js +0 -23
  101. package/dist/node_modules/framer-motion/dist/es/render/dom/use-render.js.map +0 -1
  102. package/dist/node_modules/framer-motion/dist/es/render/dom/utils/filter-props.js +0 -21
  103. package/dist/node_modules/framer-motion/dist/es/render/dom/utils/filter-props.js.map +0 -1
  104. package/dist/node_modules/framer-motion/dist/es/render/dom/utils/is-svg-component.js +0 -9
  105. package/dist/node_modules/framer-motion/dist/es/render/dom/utils/is-svg-component.js.map +0 -1
  106. package/dist/node_modules/framer-motion/dist/es/render/html/use-html-visual-state.js +0 -13
  107. package/dist/node_modules/framer-motion/dist/es/render/html/use-html-visual-state.js.map +0 -1
  108. package/dist/node_modules/framer-motion/dist/es/render/html/use-props.js +0 -28
  109. package/dist/node_modules/framer-motion/dist/es/render/html/use-props.js.map +0 -1
  110. package/dist/node_modules/framer-motion/dist/es/render/html/utils/create-render-state.js +0 -11
  111. package/dist/node_modules/framer-motion/dist/es/render/html/utils/create-render-state.js.map +0 -1
  112. package/dist/node_modules/framer-motion/dist/es/render/svg/lowercase-elements.js +0 -32
  113. package/dist/node_modules/framer-motion/dist/es/render/svg/lowercase-elements.js.map +0 -1
  114. package/dist/node_modules/framer-motion/dist/es/render/svg/use-props.js +0 -28
  115. package/dist/node_modules/framer-motion/dist/es/render/svg/use-props.js.map +0 -1
  116. package/dist/node_modules/framer-motion/dist/es/render/svg/use-svg-visual-state.js +0 -13
  117. package/dist/node_modules/framer-motion/dist/es/render/svg/use-svg-visual-state.js.map +0 -1
  118. package/dist/node_modules/framer-motion/dist/es/render/svg/utils/create-render-state.js +0 -10
  119. package/dist/node_modules/framer-motion/dist/es/render/svg/utils/create-render-state.js.map +0 -1
  120. package/dist/node_modules/framer-motion/dist/es/utils/distance.js +0 -10
  121. package/dist/node_modules/framer-motion/dist/es/utils/distance.js.map +0 -1
  122. package/dist/node_modules/framer-motion/dist/es/utils/get-context-window.js +0 -6
  123. package/dist/node_modules/framer-motion/dist/es/utils/get-context-window.js.map +0 -1
  124. package/dist/node_modules/framer-motion/dist/es/utils/is-browser.js +0 -6
  125. package/dist/node_modules/framer-motion/dist/es/utils/is-browser.js.map +0 -1
  126. package/dist/node_modules/framer-motion/dist/es/utils/is-ref-object.js +0 -8
  127. package/dist/node_modules/framer-motion/dist/es/utils/is-ref-object.js.map +0 -1
  128. package/dist/node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js +0 -15
  129. package/dist/node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js.map +0 -1
  130. package/dist/node_modules/framer-motion/dist/es/utils/use-constant.js +0 -11
  131. package/dist/node_modules/framer-motion/dist/es/utils/use-constant.js.map +0 -1
  132. package/dist/node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.js +0 -9
  133. package/dist/node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.js.map +0 -1
  134. package/dist/node_modules/motion-dom/dist/es/animation/AsyncMotionValueAnimation.js +0 -109
  135. package/dist/node_modules/motion-dom/dist/es/animation/AsyncMotionValueAnimation.js.map +0 -1
  136. package/dist/node_modules/motion-dom/dist/es/animation/JSAnimation.js +0 -132
  137. package/dist/node_modules/motion-dom/dist/es/animation/JSAnimation.js.map +0 -1
  138. package/dist/node_modules/motion-dom/dist/es/animation/NativeAnimation.js +0 -86
  139. package/dist/node_modules/motion-dom/dist/es/animation/NativeAnimation.js.map +0 -1
  140. package/dist/node_modules/motion-dom/dist/es/animation/NativeAnimationExtended.js +0 -30
  141. package/dist/node_modules/motion-dom/dist/es/animation/NativeAnimationExtended.js.map +0 -1
  142. package/dist/node_modules/motion-dom/dist/es/animation/animate/single-value.js +0 -12
  143. package/dist/node_modules/motion-dom/dist/es/animation/animate/single-value.js.map +0 -1
  144. package/dist/node_modules/motion-dom/dist/es/animation/drivers/frame.js +0 -15
  145. package/dist/node_modules/motion-dom/dist/es/animation/drivers/frame.js.map +0 -1
  146. package/dist/node_modules/motion-dom/dist/es/animation/generators/inertia.js +0 -34
  147. package/dist/node_modules/motion-dom/dist/es/animation/generators/inertia.js.map +0 -1
  148. package/dist/node_modules/motion-dom/dist/es/animation/generators/keyframes.js +0 -24
  149. package/dist/node_modules/motion-dom/dist/es/animation/generators/keyframes.js.map +0 -1
  150. package/dist/node_modules/motion-dom/dist/es/animation/generators/spring.js +0 -168
  151. package/dist/node_modules/motion-dom/dist/es/animation/generators/spring.js.map +0 -1
  152. package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/calc-duration.js +0 -11
  153. package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/calc-duration.js.map +0 -1
  154. package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/create-generator-easing.js +0 -18
  155. package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/create-generator-easing.js.map +0 -1
  156. package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/is-generator.js +0 -8
  157. package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/is-generator.js.map +0 -1
  158. package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/velocity.js +0 -11
  159. package/dist/node_modules/motion-dom/dist/es/animation/generators/utils/velocity.js.map +0 -1
  160. package/dist/node_modules/motion-dom/dist/es/animation/interfaces/motion-value.js +0 -47
  161. package/dist/node_modules/motion-dom/dist/es/animation/interfaces/motion-value.js.map +0 -1
  162. package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element-target.js +0 -56
  163. package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element-target.js.map +0 -1
  164. package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element-variant.js +0 -28
  165. package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element-variant.js.map +0 -1
  166. package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element.js +0 -23
  167. package/dist/node_modules/motion-dom/dist/es/animation/interfaces/visual-element.js.map +0 -1
  168. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/DOMKeyframesResolver.js +0 -63
  169. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/DOMKeyframesResolver.js.map +0 -1
  170. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/KeyframesResolver.js +0 -69
  171. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/KeyframesResolver.js.map +0 -1
  172. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/get-final.js +0 -10
  173. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/get-final.js.map +0 -1
  174. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/default.js +0 -10
  175. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/default.js.map +0 -1
  176. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/fill.js +0 -14
  177. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/fill.js.map +0 -1
  178. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/time.js +0 -8
  179. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/offsets/time.js.map +0 -1
  180. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/fill-wildcards.js +0 -8
  181. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/fill-wildcards.js.map +0 -1
  182. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/is-none.js +0 -9
  183. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/is-none.js.map +0 -1
  184. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/make-none-animatable.js +0 -20
  185. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/make-none-animatable.js.map +0 -1
  186. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/unit-conversion.js +0 -38
  187. package/dist/node_modules/motion-dom/dist/es/animation/keyframes/utils/unit-conversion.js.map +0 -1
  188. package/dist/node_modules/motion-dom/dist/es/animation/optimized-appear/data-id.js +0 -6
  189. package/dist/node_modules/motion-dom/dist/es/animation/optimized-appear/data-id.js.map +0 -1
  190. package/dist/node_modules/motion-dom/dist/es/animation/optimized-appear/get-appear-id.js +0 -9
  191. package/dist/node_modules/motion-dom/dist/es/animation/optimized-appear/get-appear-id.js.map +0 -1
  192. package/dist/node_modules/motion-dom/dist/es/animation/utils/WithPromise.js +0 -24
  193. package/dist/node_modules/motion-dom/dist/es/animation/utils/WithPromise.js.map +0 -1
  194. package/dist/node_modules/motion-dom/dist/es/animation/utils/calc-child-stagger.js +0 -9
  195. package/dist/node_modules/motion-dom/dist/es/animation/utils/calc-child-stagger.js.map +0 -1
  196. package/dist/node_modules/motion-dom/dist/es/animation/utils/can-animate.js +0 -20
  197. package/dist/node_modules/motion-dom/dist/es/animation/utils/can-animate.js.map +0 -1
  198. package/dist/node_modules/motion-dom/dist/es/animation/utils/css-variables-conversion.js +0 -27
  199. package/dist/node_modules/motion-dom/dist/es/animation/utils/css-variables-conversion.js.map +0 -1
  200. package/dist/node_modules/motion-dom/dist/es/animation/utils/default-transitions.js +0 -29
  201. package/dist/node_modules/motion-dom/dist/es/animation/utils/default-transitions.js.map +0 -1
  202. package/dist/node_modules/motion-dom/dist/es/animation/utils/get-value-transition.js +0 -10
  203. package/dist/node_modules/motion-dom/dist/es/animation/utils/get-value-transition.js.map +0 -1
  204. package/dist/node_modules/motion-dom/dist/es/animation/utils/is-animatable.js +0 -7
  205. package/dist/node_modules/motion-dom/dist/es/animation/utils/is-animatable.js.map +0 -1
  206. package/dist/node_modules/motion-dom/dist/es/animation/utils/is-css-variable.js +0 -9
  207. package/dist/node_modules/motion-dom/dist/es/animation/utils/is-css-variable.js.map +0 -1
  208. package/dist/node_modules/motion-dom/dist/es/animation/utils/is-transition-defined.js +0 -21
  209. package/dist/node_modules/motion-dom/dist/es/animation/utils/is-transition-defined.js.map +0 -1
  210. package/dist/node_modules/motion-dom/dist/es/animation/utils/make-animation-instant.js +0 -8
  211. package/dist/node_modules/motion-dom/dist/es/animation/utils/make-animation-instant.js.map +0 -1
  212. package/dist/node_modules/motion-dom/dist/es/animation/utils/replace-transition-type.js +0 -18
  213. package/dist/node_modules/motion-dom/dist/es/animation/utils/replace-transition-type.js.map +0 -1
  214. package/dist/node_modules/motion-dom/dist/es/animation/utils/resolve-transition.js +0 -15
  215. package/dist/node_modules/motion-dom/dist/es/animation/utils/resolve-transition.js.map +0 -1
  216. package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/cubic-bezier.js +0 -6
  217. package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/cubic-bezier.js.map +0 -1
  218. package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/map-easing.js +0 -13
  219. package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/map-easing.js.map +0 -1
  220. package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/supported.js +0 -37
  221. package/dist/node_modules/motion-dom/dist/es/animation/waapi/easing/supported.js.map +0 -1
  222. package/dist/node_modules/motion-dom/dist/es/animation/waapi/start-waapi-animation.js +0 -27
  223. package/dist/node_modules/motion-dom/dist/es/animation/waapi/start-waapi-animation.js.map +0 -1
  224. package/dist/node_modules/motion-dom/dist/es/animation/waapi/supports/waapi.js +0 -26
  225. package/dist/node_modules/motion-dom/dist/es/animation/waapi/supports/waapi.js.map +0 -1
  226. package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/accelerated-values.js +0 -11
  227. package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/accelerated-values.js.map +0 -1
  228. package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/apply-generator.js +0 -10
  229. package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/apply-generator.js.map +0 -1
  230. package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/is-browser-color.js +0 -10
  231. package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/is-browser-color.js.map +0 -1
  232. package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/linear.js +0 -10
  233. package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/linear.js.map +0 -1
  234. package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/unsupported-easing.js +0 -19
  235. package/dist/node_modules/motion-dom/dist/es/animation/waapi/utils/unsupported-easing.js.map +0 -1
  236. package/dist/node_modules/motion-dom/dist/es/events/add-dom-event.js +0 -8
  237. package/dist/node_modules/motion-dom/dist/es/events/add-dom-event.js.map +0 -1
  238. package/dist/node_modules/motion-dom/dist/es/frameloop/batcher.js +0 -32
  239. package/dist/node_modules/motion-dom/dist/es/frameloop/batcher.js.map +0 -1
  240. package/dist/node_modules/motion-dom/dist/es/frameloop/frame.js +0 -8
  241. package/dist/node_modules/motion-dom/dist/es/frameloop/frame.js.map +0 -1
  242. package/dist/node_modules/motion-dom/dist/es/frameloop/microtask.js +0 -7
  243. package/dist/node_modules/motion-dom/dist/es/frameloop/microtask.js.map +0 -1
  244. package/dist/node_modules/motion-dom/dist/es/frameloop/order.js +0 -15
  245. package/dist/node_modules/motion-dom/dist/es/frameloop/order.js.map +0 -1
  246. package/dist/node_modules/motion-dom/dist/es/frameloop/render-step.js +0 -35
  247. package/dist/node_modules/motion-dom/dist/es/frameloop/render-step.js.map +0 -1
  248. package/dist/node_modules/motion-dom/dist/es/frameloop/sync-time.js +0 -17
  249. package/dist/node_modules/motion-dom/dist/es/frameloop/sync-time.js.map +0 -1
  250. package/dist/node_modules/motion-dom/dist/es/gestures/drag/state/is-active.js +0 -12
  251. package/dist/node_modules/motion-dom/dist/es/gestures/drag/state/is-active.js.map +0 -1
  252. package/dist/node_modules/motion-dom/dist/es/gestures/drag/state/set-active.js +0 -13
  253. package/dist/node_modules/motion-dom/dist/es/gestures/drag/state/set-active.js.map +0 -1
  254. package/dist/node_modules/motion-dom/dist/es/gestures/hover.js +0 -38
  255. package/dist/node_modules/motion-dom/dist/es/gestures/hover.js.map +0 -1
  256. package/dist/node_modules/motion-dom/dist/es/gestures/press/index.js +0 -35
  257. package/dist/node_modules/motion-dom/dist/es/gestures/press/index.js.map +0 -1
  258. package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/is-keyboard-accessible.js +0 -23
  259. package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/is-keyboard-accessible.js.map +0 -1
  260. package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/keyboard.js +0 -30
  261. package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/keyboard.js.map +0 -1
  262. package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/state.js +0 -6
  263. package/dist/node_modules/motion-dom/dist/es/gestures/press/utils/state.js.map +0 -1
  264. package/dist/node_modules/motion-dom/dist/es/gestures/utils/is-node-or-child.js +0 -6
  265. package/dist/node_modules/motion-dom/dist/es/gestures/utils/is-node-or-child.js.map +0 -1
  266. package/dist/node_modules/motion-dom/dist/es/gestures/utils/is-primary-pointer.js +0 -6
  267. package/dist/node_modules/motion-dom/dist/es/gestures/utils/is-primary-pointer.js.map +0 -1
  268. package/dist/node_modules/motion-dom/dist/es/gestures/utils/setup.js +0 -18
  269. package/dist/node_modules/motion-dom/dist/es/gestures/utils/setup.js.map +0 -1
  270. package/dist/node_modules/motion-dom/dist/es/projection/animation/mix-values.js +0 -31
  271. package/dist/node_modules/motion-dom/dist/es/projection/animation/mix-values.js.map +0 -1
  272. package/dist/node_modules/motion-dom/dist/es/projection/geometry/conversion.js +0 -41
  273. package/dist/node_modules/motion-dom/dist/es/projection/geometry/conversion.js.map +0 -1
  274. package/dist/node_modules/motion-dom/dist/es/projection/geometry/copy.js +0 -14
  275. package/dist/node_modules/motion-dom/dist/es/projection/geometry/copy.js.map +0 -1
  276. package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-apply.js +0 -45
  277. package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-apply.js.map +0 -1
  278. package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-calc.js +0 -32
  279. package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-calc.js.map +0 -1
  280. package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-remove.js +0 -31
  281. package/dist/node_modules/motion-dom/dist/es/projection/geometry/delta-remove.js.map +0 -1
  282. package/dist/node_modules/motion-dom/dist/es/projection/geometry/models.js +0 -20
  283. package/dist/node_modules/motion-dom/dist/es/projection/geometry/models.js.map +0 -1
  284. package/dist/node_modules/motion-dom/dist/es/projection/geometry/utils.js +0 -30
  285. package/dist/node_modules/motion-dom/dist/es/projection/geometry/utils.js.map +0 -1
  286. package/dist/node_modules/motion-dom/dist/es/projection/node/DocumentProjectionNode.js +0 -15
  287. package/dist/node_modules/motion-dom/dist/es/projection/node/DocumentProjectionNode.js.map +0 -1
  288. package/dist/node_modules/motion-dom/dist/es/projection/node/HTMLProjectionNode.js +0 -24
  289. package/dist/node_modules/motion-dom/dist/es/projection/node/HTMLProjectionNode.js.map +0 -1
  290. package/dist/node_modules/motion-dom/dist/es/projection/node/create-projection-node.js +0 -590
  291. package/dist/node_modules/motion-dom/dist/es/projection/node/create-projection-node.js.map +0 -1
  292. package/dist/node_modules/motion-dom/dist/es/projection/node/state.js +0 -9
  293. package/dist/node_modules/motion-dom/dist/es/projection/node/state.js.map +0 -1
  294. package/dist/node_modules/motion-dom/dist/es/projection/shared/stack.js +0 -53
  295. package/dist/node_modules/motion-dom/dist/es/projection/shared/stack.js.map +0 -1
  296. package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-border-radius.js +0 -15
  297. package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-border-radius.js.map +0 -1
  298. package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-box-shadow.js +0 -15
  299. package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-box-shadow.js.map +0 -1
  300. package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-correction.js +0 -23
  301. package/dist/node_modules/motion-dom/dist/es/projection/styles/scale-correction.js.map +0 -1
  302. package/dist/node_modules/motion-dom/dist/es/projection/styles/transform.js +0 -14
  303. package/dist/node_modules/motion-dom/dist/es/projection/styles/transform.js.map +0 -1
  304. package/dist/node_modules/motion-dom/dist/es/projection/utils/compare-by-depth.js +0 -6
  305. package/dist/node_modules/motion-dom/dist/es/projection/utils/compare-by-depth.js.map +0 -1
  306. package/dist/node_modules/motion-dom/dist/es/projection/utils/each-axis.js +0 -8
  307. package/dist/node_modules/motion-dom/dist/es/projection/utils/each-axis.js.map +0 -1
  308. package/dist/node_modules/motion-dom/dist/es/projection/utils/flat-tree.js +0 -21
  309. package/dist/node_modules/motion-dom/dist/es/projection/utils/flat-tree.js.map +0 -1
  310. package/dist/node_modules/motion-dom/dist/es/projection/utils/has-transform.js +0 -20
  311. package/dist/node_modules/motion-dom/dist/es/projection/utils/has-transform.js.map +0 -1
  312. package/dist/node_modules/motion-dom/dist/es/projection/utils/measure.js +0 -14
  313. package/dist/node_modules/motion-dom/dist/es/projection/utils/measure.js.map +0 -1
  314. package/dist/node_modules/motion-dom/dist/es/render/Feature.js +0 -11
  315. package/dist/node_modules/motion-dom/dist/es/render/Feature.js.map +0 -1
  316. package/dist/node_modules/motion-dom/dist/es/render/VisualElement.js +0 -206
  317. package/dist/node_modules/motion-dom/dist/es/render/VisualElement.js.map +0 -1
  318. package/dist/node_modules/motion-dom/dist/es/render/dom/DOMVisualElement.js +0 -30
  319. package/dist/node_modules/motion-dom/dist/es/render/dom/DOMVisualElement.js.map +0 -1
  320. package/dist/node_modules/motion-dom/dist/es/render/dom/is-css-var.js +0 -6
  321. package/dist/node_modules/motion-dom/dist/es/render/dom/is-css-var.js.map +0 -1
  322. package/dist/node_modules/motion-dom/dist/es/render/dom/parse-transform.js +0 -58
  323. package/dist/node_modules/motion-dom/dist/es/render/dom/parse-transform.js.map +0 -1
  324. package/dist/node_modules/motion-dom/dist/es/render/dom/style-set.js +0 -9
  325. package/dist/node_modules/motion-dom/dist/es/render/dom/style-set.js.map +0 -1
  326. package/dist/node_modules/motion-dom/dist/es/render/dom/utils/camel-to-dash.js +0 -8
  327. package/dist/node_modules/motion-dom/dist/es/render/dom/utils/camel-to-dash.js.map +0 -1
  328. package/dist/node_modules/motion-dom/dist/es/render/html/HTMLVisualElement.js +0 -37
  329. package/dist/node_modules/motion-dom/dist/es/render/html/HTMLVisualElement.js.map +0 -1
  330. package/dist/node_modules/motion-dom/dist/es/render/html/utils/build-styles.js +0 -30
  331. package/dist/node_modules/motion-dom/dist/es/render/html/utils/build-styles.js.map +0 -1
  332. package/dist/node_modules/motion-dom/dist/es/render/html/utils/build-transform.js +0 -37
  333. package/dist/node_modules/motion-dom/dist/es/render/html/utils/build-transform.js.map +0 -1
  334. package/dist/node_modules/motion-dom/dist/es/render/html/utils/render.js +0 -10
  335. package/dist/node_modules/motion-dom/dist/es/render/html/utils/render.js.map +0 -1
  336. package/dist/node_modules/motion-dom/dist/es/render/html/utils/scrape-motion-values.js +0 -13
  337. package/dist/node_modules/motion-dom/dist/es/render/html/utils/scrape-motion-values.js.map +0 -1
  338. package/dist/node_modules/motion-dom/dist/es/render/store.js +0 -6
  339. package/dist/node_modules/motion-dom/dist/es/render/store.js.map +0 -1
  340. package/dist/node_modules/motion-dom/dist/es/render/svg/SVGVisualElement.js +0 -42
  341. package/dist/node_modules/motion-dom/dist/es/render/svg/SVGVisualElement.js.map +0 -1
  342. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/build-attrs.js +0 -24
  343. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/build-attrs.js.map +0 -1
  344. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/camel-case-attrs.js +0 -30
  345. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/camel-case-attrs.js.map +0 -1
  346. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/is-svg-tag.js +0 -6
  347. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/is-svg-tag.js.map +0 -1
  348. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/path.js +0 -17
  349. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/path.js.map +0 -1
  350. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/render.js +0 -12
  351. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/render.js.map +0 -1
  352. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/scrape-motion-values.js +0 -16
  353. package/dist/node_modules/motion-dom/dist/es/render/svg/utils/scrape-motion-values.js.map +0 -1
  354. package/dist/node_modules/motion-dom/dist/es/render/utils/animation-state.js +0 -137
  355. package/dist/node_modules/motion-dom/dist/es/render/utils/animation-state.js.map +0 -1
  356. package/dist/node_modules/motion-dom/dist/es/render/utils/get-variant-context.js +0 -21
  357. package/dist/node_modules/motion-dom/dist/es/render/utils/get-variant-context.js.map +0 -1
  358. package/dist/node_modules/motion-dom/dist/es/render/utils/is-animation-controls.js +0 -8
  359. package/dist/node_modules/motion-dom/dist/es/render/utils/is-animation-controls.js.map +0 -1
  360. package/dist/node_modules/motion-dom/dist/es/render/utils/is-controlling-variants.js +0 -14
  361. package/dist/node_modules/motion-dom/dist/es/render/utils/is-controlling-variants.js.map +0 -1
  362. package/dist/node_modules/motion-dom/dist/es/render/utils/is-forced-motion-value.js +0 -10
  363. package/dist/node_modules/motion-dom/dist/es/render/utils/is-forced-motion-value.js.map +0 -1
  364. package/dist/node_modules/motion-dom/dist/es/render/utils/is-keyframes-target.js +0 -6
  365. package/dist/node_modules/motion-dom/dist/es/render/utils/is-keyframes-target.js.map +0 -1
  366. package/dist/node_modules/motion-dom/dist/es/render/utils/is-variant-label.js +0 -8
  367. package/dist/node_modules/motion-dom/dist/es/render/utils/is-variant-label.js.map +0 -1
  368. package/dist/node_modules/motion-dom/dist/es/render/utils/keys-position.js +0 -15
  369. package/dist/node_modules/motion-dom/dist/es/render/utils/keys-position.js.map +0 -1
  370. package/dist/node_modules/motion-dom/dist/es/render/utils/keys-transform.js +0 -24
  371. package/dist/node_modules/motion-dom/dist/es/render/utils/keys-transform.js.map +0 -1
  372. package/dist/node_modules/motion-dom/dist/es/render/utils/motion-values.js +0 -23
  373. package/dist/node_modules/motion-dom/dist/es/render/utils/motion-values.js.map +0 -1
  374. package/dist/node_modules/motion-dom/dist/es/render/utils/reduced-motion/index.js +0 -13
  375. package/dist/node_modules/motion-dom/dist/es/render/utils/reduced-motion/index.js.map +0 -1
  376. package/dist/node_modules/motion-dom/dist/es/render/utils/reduced-motion/state.js +0 -6
  377. package/dist/node_modules/motion-dom/dist/es/render/utils/reduced-motion/state.js.map +0 -1
  378. package/dist/node_modules/motion-dom/dist/es/render/utils/resolve-dynamic-variants.js +0 -10
  379. package/dist/node_modules/motion-dom/dist/es/render/utils/resolve-dynamic-variants.js.map +0 -1
  380. package/dist/node_modules/motion-dom/dist/es/render/utils/resolve-variants.js +0 -22
  381. package/dist/node_modules/motion-dom/dist/es/render/utils/resolve-variants.js.map +0 -1
  382. package/dist/node_modules/motion-dom/dist/es/render/utils/setters.js +0 -22
  383. package/dist/node_modules/motion-dom/dist/es/render/utils/setters.js.map +0 -1
  384. package/dist/node_modules/motion-dom/dist/es/render/utils/shallow-compare.js +0 -12
  385. package/dist/node_modules/motion-dom/dist/es/render/utils/shallow-compare.js.map +0 -1
  386. package/dist/node_modules/motion-dom/dist/es/render/utils/variant-props.js +0 -14
  387. package/dist/node_modules/motion-dom/dist/es/render/utils/variant-props.js.map +0 -1
  388. package/dist/node_modules/motion-dom/dist/es/resize/handle-element.js +0 -39
  389. package/dist/node_modules/motion-dom/dist/es/resize/handle-element.js.map +0 -1
  390. package/dist/node_modules/motion-dom/dist/es/resize/handle-window.js +0 -24
  391. package/dist/node_modules/motion-dom/dist/es/resize/handle-window.js.map +0 -1
  392. package/dist/node_modules/motion-dom/dist/es/resize/index.js +0 -10
  393. package/dist/node_modules/motion-dom/dist/es/resize/index.js.map +0 -1
  394. package/dist/node_modules/motion-dom/dist/es/stats/animation-count.js +0 -10
  395. package/dist/node_modules/motion-dom/dist/es/stats/animation-count.js.map +0 -1
  396. package/dist/node_modules/motion-dom/dist/es/stats/buffer.js +0 -9
  397. package/dist/node_modules/motion-dom/dist/es/stats/buffer.js.map +0 -1
  398. package/dist/node_modules/motion-dom/dist/es/utils/delay.js +0 -14
  399. package/dist/node_modules/motion-dom/dist/es/utils/delay.js.map +0 -1
  400. package/dist/node_modules/motion-dom/dist/es/utils/interpolate.js +0 -35
  401. package/dist/node_modules/motion-dom/dist/es/utils/interpolate.js.map +0 -1
  402. package/dist/node_modules/motion-dom/dist/es/utils/is-html-element.js +0 -9
  403. package/dist/node_modules/motion-dom/dist/es/utils/is-html-element.js.map +0 -1
  404. package/dist/node_modules/motion-dom/dist/es/utils/is-svg-element.js +0 -9
  405. package/dist/node_modules/motion-dom/dist/es/utils/is-svg-element.js.map +0 -1
  406. package/dist/node_modules/motion-dom/dist/es/utils/is-svg-svg-element.js +0 -9
  407. package/dist/node_modules/motion-dom/dist/es/utils/is-svg-svg-element.js.map +0 -1
  408. package/dist/node_modules/motion-dom/dist/es/utils/mix/color.js +0 -32
  409. package/dist/node_modules/motion-dom/dist/es/utils/mix/color.js.map +0 -1
  410. package/dist/node_modules/motion-dom/dist/es/utils/mix/complex.js +0 -54
  411. package/dist/node_modules/motion-dom/dist/es/utils/mix/complex.js.map +0 -1
  412. package/dist/node_modules/motion-dom/dist/es/utils/mix/immediate.js +0 -8
  413. package/dist/node_modules/motion-dom/dist/es/utils/mix/immediate.js.map +0 -1
  414. package/dist/node_modules/motion-dom/dist/es/utils/mix/index.js +0 -10
  415. package/dist/node_modules/motion-dom/dist/es/utils/mix/index.js.map +0 -1
  416. package/dist/node_modules/motion-dom/dist/es/utils/mix/number.js +0 -6
  417. package/dist/node_modules/motion-dom/dist/es/utils/mix/number.js.map +0 -1
  418. package/dist/node_modules/motion-dom/dist/es/utils/mix/visibility.js +0 -9
  419. package/dist/node_modules/motion-dom/dist/es/utils/mix/visibility.js.map +0 -1
  420. package/dist/node_modules/motion-dom/dist/es/utils/resolve-elements.js +0 -16
  421. package/dist/node_modules/motion-dom/dist/es/utils/resolve-elements.js.map +0 -1
  422. package/dist/node_modules/motion-dom/dist/es/utils/supports/flags.js +0 -6
  423. package/dist/node_modules/motion-dom/dist/es/utils/supports/flags.js.map +0 -1
  424. package/dist/node_modules/motion-dom/dist/es/utils/supports/linear-easing.js +0 -14
  425. package/dist/node_modules/motion-dom/dist/es/utils/supports/linear-easing.js.map +0 -1
  426. package/dist/node_modules/motion-dom/dist/es/utils/supports/memo.js +0 -11
  427. package/dist/node_modules/motion-dom/dist/es/utils/supports/memo.js.map +0 -1
  428. package/dist/node_modules/motion-dom/dist/es/utils/supports/scroll-timeline.js +0 -7
  429. package/dist/node_modules/motion-dom/dist/es/utils/supports/scroll-timeline.js.map +0 -1
  430. package/dist/node_modules/motion-dom/dist/es/value/index.js +0 -94
  431. package/dist/node_modules/motion-dom/dist/es/value/index.js.map +0 -1
  432. package/dist/node_modules/motion-dom/dist/es/value/types/auto.js +0 -9
  433. package/dist/node_modules/motion-dom/dist/es/value/types/auto.js.map +0 -1
  434. package/dist/node_modules/motion-dom/dist/es/value/types/color/hex.js +0 -21
  435. package/dist/node_modules/motion-dom/dist/es/value/types/color/hex.js.map +0 -1
  436. package/dist/node_modules/motion-dom/dist/es/value/types/color/hsla-to-rgba.js +0 -23
  437. package/dist/node_modules/motion-dom/dist/es/value/types/color/hsla-to-rgba.js.map +0 -1
  438. package/dist/node_modules/motion-dom/dist/es/value/types/color/hsla.js +0 -14
  439. package/dist/node_modules/motion-dom/dist/es/value/types/color/hsla.js.map +0 -1
  440. package/dist/node_modules/motion-dom/dist/es/value/types/color/index.js +0 -17
  441. package/dist/node_modules/motion-dom/dist/es/value/types/color/index.js.map +0 -1
  442. package/dist/node_modules/motion-dom/dist/es/value/types/color/rgba.js +0 -17
  443. package/dist/node_modules/motion-dom/dist/es/value/types/color/rgba.js.map +0 -1
  444. package/dist/node_modules/motion-dom/dist/es/value/types/color/utils.js +0 -18
  445. package/dist/node_modules/motion-dom/dist/es/value/types/color/utils.js.map +0 -1
  446. package/dist/node_modules/motion-dom/dist/es/value/types/complex/filter.js +0 -28
  447. package/dist/node_modules/motion-dom/dist/es/value/types/complex/filter.js.map +0 -1
  448. package/dist/node_modules/motion-dom/dist/es/value/types/complex/index.js +0 -54
  449. package/dist/node_modules/motion-dom/dist/es/value/types/complex/index.js.map +0 -1
  450. package/dist/node_modules/motion-dom/dist/es/value/types/complex/mask.js +0 -16
  451. package/dist/node_modules/motion-dom/dist/es/value/types/complex/mask.js.map +0 -1
  452. package/dist/node_modules/motion-dom/dist/es/value/types/dimensions.js +0 -18
  453. package/dist/node_modules/motion-dom/dist/es/value/types/dimensions.js.map +0 -1
  454. package/dist/node_modules/motion-dom/dist/es/value/types/int.js +0 -10
  455. package/dist/node_modules/motion-dom/dist/es/value/types/int.js.map +0 -1
  456. package/dist/node_modules/motion-dom/dist/es/value/types/maps/defaults.js +0 -26
  457. package/dist/node_modules/motion-dom/dist/es/value/types/maps/defaults.js.map +0 -1
  458. package/dist/node_modules/motion-dom/dist/es/value/types/maps/number.js +0 -66
  459. package/dist/node_modules/motion-dom/dist/es/value/types/maps/number.js.map +0 -1
  460. package/dist/node_modules/motion-dom/dist/es/value/types/maps/transform.js +0 -33
  461. package/dist/node_modules/motion-dom/dist/es/value/types/maps/transform.js.map +0 -1
  462. package/dist/node_modules/motion-dom/dist/es/value/types/numbers/index.js +0 -17
  463. package/dist/node_modules/motion-dom/dist/es/value/types/numbers/index.js.map +0 -1
  464. package/dist/node_modules/motion-dom/dist/es/value/types/numbers/units.js +0 -14
  465. package/dist/node_modules/motion-dom/dist/es/value/types/numbers/units.js.map +0 -1
  466. package/dist/node_modules/motion-dom/dist/es/value/types/test.js +0 -6
  467. package/dist/node_modules/motion-dom/dist/es/value/types/test.js.map +0 -1
  468. package/dist/node_modules/motion-dom/dist/es/value/types/utils/animatable-none.js +0 -14
  469. package/dist/node_modules/motion-dom/dist/es/value/types/utils/animatable-none.js.map +0 -1
  470. package/dist/node_modules/motion-dom/dist/es/value/types/utils/color-regex.js +0 -6
  471. package/dist/node_modules/motion-dom/dist/es/value/types/utils/color-regex.js.map +0 -1
  472. package/dist/node_modules/motion-dom/dist/es/value/types/utils/find.js +0 -14
  473. package/dist/node_modules/motion-dom/dist/es/value/types/utils/find.js.map +0 -1
  474. package/dist/node_modules/motion-dom/dist/es/value/types/utils/float-regex.js +0 -6
  475. package/dist/node_modules/motion-dom/dist/es/value/types/utils/float-regex.js.map +0 -1
  476. package/dist/node_modules/motion-dom/dist/es/value/types/utils/get-as-type.js +0 -6
  477. package/dist/node_modules/motion-dom/dist/es/value/types/utils/get-as-type.js.map +0 -1
  478. package/dist/node_modules/motion-dom/dist/es/value/types/utils/is-nullish.js +0 -8
  479. package/dist/node_modules/motion-dom/dist/es/value/types/utils/is-nullish.js.map +0 -1
  480. package/dist/node_modules/motion-dom/dist/es/value/types/utils/sanitize.js +0 -6
  481. package/dist/node_modules/motion-dom/dist/es/value/types/utils/sanitize.js.map +0 -1
  482. package/dist/node_modules/motion-dom/dist/es/value/types/utils/single-color-regex.js +0 -6
  483. package/dist/node_modules/motion-dom/dist/es/value/types/utils/single-color-regex.js.map +0 -1
  484. package/dist/node_modules/motion-dom/dist/es/value/utils/is-motion-value.js +0 -6
  485. package/dist/node_modules/motion-dom/dist/es/value/utils/is-motion-value.js.map +0 -1
  486. package/dist/node_modules/motion-dom/dist/es/value/utils/resolve-motion-value.js +0 -9
  487. package/dist/node_modules/motion-dom/dist/es/value/utils/resolve-motion-value.js.map +0 -1
  488. package/dist/node_modules/motion-dom/dist/es/value/will-change/add-will-change.js +0 -15
  489. package/dist/node_modules/motion-dom/dist/es/value/will-change/add-will-change.js.map +0 -1
  490. package/dist/node_modules/motion-dom/dist/es/value/will-change/is.js +0 -9
  491. package/dist/node_modules/motion-dom/dist/es/value/will-change/is.js.map +0 -1
  492. package/dist/node_modules/motion-utils/dist/es/array.js +0 -12
  493. package/dist/node_modules/motion-utils/dist/es/array.js.map +0 -1
  494. package/dist/node_modules/motion-utils/dist/es/clamp.js +0 -6
  495. package/dist/node_modules/motion-utils/dist/es/clamp.js.map +0 -1
  496. package/dist/node_modules/motion-utils/dist/es/easing/anticipate.js +0 -7
  497. package/dist/node_modules/motion-utils/dist/es/easing/anticipate.js.map +0 -1
  498. package/dist/node_modules/motion-utils/dist/es/easing/back.js +0 -9
  499. package/dist/node_modules/motion-utils/dist/es/easing/back.js.map +0 -1
  500. package/dist/node_modules/motion-utils/dist/es/easing/circ.js +0 -8
  501. package/dist/node_modules/motion-utils/dist/es/easing/circ.js.map +0 -1
  502. package/dist/node_modules/motion-utils/dist/es/easing/cubic-bezier.js +0 -19
  503. package/dist/node_modules/motion-utils/dist/es/easing/cubic-bezier.js.map +0 -1
  504. package/dist/node_modules/motion-utils/dist/es/easing/ease.js +0 -7
  505. package/dist/node_modules/motion-utils/dist/es/easing/ease.js.map +0 -1
  506. package/dist/node_modules/motion-utils/dist/es/easing/modifiers/mirror.js +0 -6
  507. package/dist/node_modules/motion-utils/dist/es/easing/modifiers/mirror.js.map +0 -1
  508. package/dist/node_modules/motion-utils/dist/es/easing/modifiers/reverse.js +0 -6
  509. package/dist/node_modules/motion-utils/dist/es/easing/modifiers/reverse.js.map +0 -1
  510. package/dist/node_modules/motion-utils/dist/es/easing/utils/is-bezier-definition.js +0 -6
  511. package/dist/node_modules/motion-utils/dist/es/easing/utils/is-bezier-definition.js.map +0 -1
  512. package/dist/node_modules/motion-utils/dist/es/easing/utils/is-easing-array.js +0 -6
  513. package/dist/node_modules/motion-utils/dist/es/easing/utils/is-easing-array.js.map +0 -1
  514. package/dist/node_modules/motion-utils/dist/es/easing/utils/map.js +0 -33
  515. package/dist/node_modules/motion-utils/dist/es/easing/utils/map.js.map +0 -1
  516. package/dist/node_modules/motion-utils/dist/es/errors.js +0 -12
  517. package/dist/node_modules/motion-utils/dist/es/errors.js.map +0 -1
  518. package/dist/node_modules/motion-utils/dist/es/format-error-message.js +0 -8
  519. package/dist/node_modules/motion-utils/dist/es/format-error-message.js.map +0 -1
  520. package/dist/node_modules/motion-utils/dist/es/global-config.js +0 -6
  521. package/dist/node_modules/motion-utils/dist/es/global-config.js.map +0 -1
  522. package/dist/node_modules/motion-utils/dist/es/is-numerical-string.js +0 -6
  523. package/dist/node_modules/motion-utils/dist/es/is-numerical-string.js.map +0 -1
  524. package/dist/node_modules/motion-utils/dist/es/is-object.js +0 -8
  525. package/dist/node_modules/motion-utils/dist/es/is-object.js.map +0 -1
  526. package/dist/node_modules/motion-utils/dist/es/is-zero-value-string.js +0 -6
  527. package/dist/node_modules/motion-utils/dist/es/is-zero-value-string.js.map +0 -1
  528. package/dist/node_modules/motion-utils/dist/es/memo.js +0 -10
  529. package/dist/node_modules/motion-utils/dist/es/memo.js.map +0 -1
  530. package/dist/node_modules/motion-utils/dist/es/noop.js +0 -6
  531. package/dist/node_modules/motion-utils/dist/es/noop.js.map +0 -1
  532. package/dist/node_modules/motion-utils/dist/es/pipe.js +0 -6
  533. package/dist/node_modules/motion-utils/dist/es/pipe.js.map +0 -1
  534. package/dist/node_modules/motion-utils/dist/es/progress.js +0 -9
  535. package/dist/node_modules/motion-utils/dist/es/progress.js.map +0 -1
  536. package/dist/node_modules/motion-utils/dist/es/subscription-manager.js +0 -28
  537. package/dist/node_modules/motion-utils/dist/es/subscription-manager.js.map +0 -1
  538. package/dist/node_modules/motion-utils/dist/es/time-conversion.js +0 -6
  539. package/dist/node_modules/motion-utils/dist/es/time-conversion.js.map +0 -1
  540. package/dist/node_modules/motion-utils/dist/es/velocity-per-second.js +0 -8
  541. package/dist/node_modules/motion-utils/dist/es/velocity-per-second.js.map +0 -1
  542. package/dist/node_modules/motion-utils/dist/es/warn-once.js +0 -10
  543. package/dist/node_modules/motion-utils/dist/es/warn-once.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"GoalsPage.js","names":[],"sources":["../../../src/brainyrich/pages/GoalsPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n AlertTriangle,\n CalendarClock,\n Coins,\n Link2,\n LineChart,\n MoreHorizontal,\n PiggyBank,\n Plus,\n RefreshCw,\n Target,\n Trash2,\n TrendingDown,\n TrendingUp,\n Unlink,\n Wallet,\n} from 'lucide-react';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n ConfirmDialog,\n FadeIn,\n GlassCard,\n LoadMore,\n MiniAreaChart,\n ProgressRing,\n StatTile,\n type AreaDatum,\n type VizTone,\n} from '../components';\nimport { TagField } from '../components/reuse/TagField';\nimport {\n useAccounts,\n useArchiveGoal,\n useCreateGoal,\n useGoal,\n useGoalFundings,\n useHouseholds,\n useLinkGoalFunding,\n usePagedGoals,\n useRecalcGoalProjection,\n useUnlinkGoalFunding,\n useUpdateGoal,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraCreateGoalInput,\n BraGoal,\n BraGoalFunding,\n BraGoalProjection,\n BraGoalStatus,\n BraGoalType,\n BraUpdateGoalInput,\n} from '../types/bra';\nimport {\n EmptyState,\n ErrorState,\n LoadingState,\n SectionShell,\n formatCompact,\n formatDate,\n formatMoney,\n formatPct,\n statusBadgeVariant,\n} from './_shared';\n\nconst GOAL_TYPES: BraGoalType[] = [\n 'RETIREMENT',\n 'EDUCATION',\n 'HOME',\n 'EMERGENCY_FUND',\n 'MAJOR_PURCHASE',\n 'WEALTH_GROWTH',\n 'CUSTOM',\n];\n\nconst GOAL_STATUSES: BraGoalStatus[] = ['ACTIVE', 'ACHIEVED', 'ON_HOLD', 'ABANDONED'];\n\ninterface ProjectionMeta {\n icon: typeof TrendingUp;\n tone: string;\n}\n\nfunction projectionMeta(projection: BraGoalProjection): ProjectionMeta {\n switch (projection) {\n case 'AHEAD':\n case 'ON_TRACK':\n return { icon: TrendingUp, tone: 'text-status-success-text' };\n case 'BEHIND':\n return { icon: TrendingDown, tone: 'text-status-warning-text' };\n case 'AT_RISK':\n default:\n return { icon: AlertTriangle, tone: 'text-status-error-text' };\n }\n}\n\nfunction humanize(value: string): string {\n return value\n .toLowerCase()\n .split('_')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n}\n\n/** Sum of the fixed-amount funding links wired to a goal (real backend value). */\nfunction goalFixedFunded(goal: Pick<BraGoal, 'fundings'>): number {\n return goal.fundings.reduce((s, f) => s + (f.fixedAmount ?? 0), 0);\n}\n\n/**\n * Funded-progress percentage for a goal. ACHIEVED goals read 100%; otherwise the\n * sum of fixed funding links over the target — every input is wired backend data,\n * never fabricated.\n */\nfunction fundedPercent(goal: Pick<BraGoal, 'fundings' | 'targetAmount' | 'status'>): number {\n if (goal.status === 'ACHIEVED') return 100;\n if (!(goal.targetAmount > 0)) return 0;\n return Math.max(0, Math.min(100, (goalFixedFunded(goal) / goal.targetAmount) * 100));\n}\n\n/** Ring/accent tone derived from the goal's real status + projection. */\nfunction goalTone(status: BraGoalStatus, projection: BraGoalProjection): VizTone {\n if (status === 'ACHIEVED') return 'success';\n switch (projection) {\n case 'AHEAD':\n case 'ON_TRACK':\n return 'brand';\n case 'BEHIND':\n return 'warning';\n case 'AT_RISK':\n default:\n return 'error';\n }\n}\n\n/**\n * A deterministic contribution trajectory from today to the target date, computed\n * purely from wired fields: starting funded balance + monthly contribution × month.\n * No randomness, no fabricated series — just the arithmetic funding path the user\n * has configured. Returns [] when there is nothing meaningful to chart.\n */\nfunction buildProjectionSeries(\n funded: number,\n monthly: number,\n targetIso?: string | null\n): AreaDatum[] {\n if (!targetIso) return [];\n const target = new Date(targetIso);\n if (Number.isNaN(target.getTime())) return [];\n const now = new Date();\n const totalMonths =\n (target.getFullYear() - now.getFullYear()) * 12 + (target.getMonth() - now.getMonth());\n if (totalMonths <= 0) return [];\n const steps = Math.min(Math.max(totalMonths, 2), 12);\n const fmt = new Intl.DateTimeFormat('en-US', { month: 'short', year: '2-digit' });\n const points: AreaDatum[] = [];\n for (let i = 0; i <= steps; i += 1) {\n const m = Math.round((totalMonths / steps) * i);\n const at = new Date(now.getFullYear(), now.getMonth() + m, 1);\n points.push({ x: fmt.format(at), y: Math.round(funded + monthly * m) });\n }\n return points;\n}\n\n/** yyyy-mm-dd for a date input, guarded against absent/invalid ISO strings. */\nfunction toDateInput(iso?: string | null): string {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toISOString().slice(0, 10);\n}\n\ninterface GoalFormState {\n name: string;\n type: BraGoalType;\n status: BraGoalStatus;\n targetAmount: string;\n targetDate: string;\n monthlyContribution: string;\n priority: string;\n currency: string;\n householdId: string;\n notes: string;\n}\n\nfunction emptyForm(): GoalFormState {\n return {\n name: '',\n type: 'CUSTOM',\n status: 'ACTIVE',\n targetAmount: '',\n targetDate: '',\n monthlyContribution: '',\n priority: '1',\n currency: 'USD',\n householdId: '',\n notes: '',\n };\n}\n\nfunction formFromGoal(goal: BraGoal): GoalFormState {\n return {\n name: goal.name,\n type: goal.type,\n status: goal.status,\n targetAmount: String(goal.targetAmount),\n targetDate: toDateInput(goal.targetDate),\n monthlyContribution: String(goal.monthlyContribution),\n priority: String(goal.priority),\n currency: goal.currency,\n householdId: goal.householdId ?? '',\n notes: goal.notes ?? '',\n };\n}\n\nconst HOUSEHOLD_NONE = '__none__';\n\nexport function GoalsPage() {\n const { t } = useI18n();\n const translate = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n\n const {\n items: goals,\n hasMore,\n loadMore,\n isFetchingNextPage,\n isLoading,\n isError,\n refetch,\n } = usePagedGoals();\n const { data: households } = useHouseholds();\n\n const createGoal = useCreateGoal();\n const updateGoal = useUpdateGoal();\n const archiveGoal = useArchiveGoal();\n\n const [createOpen, setCreateOpen] = useState(false);\n const [editing, setEditing] = useState<BraGoal | null>(null);\n const [detailId, setDetailId] = useState<string | null>(null);\n const [archiving, setArchiving] = useState<BraGoal | null>(null);\n const [form, setForm] = useState<GoalFormState>(emptyForm);\n\n const setField = <K extends keyof GoalFormState>(key: K, value: GoalFormState[K]) =>\n setForm((prev) => ({ ...prev, [key]: value }));\n\n const totals = useMemo(() => {\n const totalTarget = goals.reduce((s, g) => s + g.targetAmount, 0);\n const totalMonthly = goals.reduce((s, g) => s + g.monthlyContribution, 0);\n const atRisk = goals.filter(\n (g) => g.projection === 'AT_RISK' || g.projection === 'BEHIND'\n ).length;\n return { totalTarget, totalMonthly, atRisk };\n }, [goals]);\n\n const currency = goals[0]?.currency ?? 'USD';\n\n const openCreate = () => {\n setForm(emptyForm());\n setCreateOpen(true);\n };\n\n const openEdit = (goal: BraGoal) => {\n setForm(formFromGoal(goal));\n setEditing(goal);\n };\n\n const formValid =\n form.name.trim().length > 0 && Number(form.targetAmount) > 0 && form.targetDate.length > 0;\n\n const handleCreate = () => {\n if (!formValid) return;\n const input: BraCreateGoalInput = {\n name: form.name.trim(),\n type: form.type,\n targetAmount: Number(form.targetAmount),\n targetDate: new Date(form.targetDate).toISOString(),\n monthlyContribution: Number(form.monthlyContribution) || 0,\n priority: Number(form.priority) || 1,\n currency: form.currency.trim() || 'USD',\n notes: form.notes.trim() || null,\n tags: [],\n ...(form.householdId ? { householdId: form.householdId } : {}),\n };\n createGoal.mutate(input, { onSuccess: () => setCreateOpen(false) });\n };\n\n const handleUpdate = () => {\n if (!editing || !formValid) return;\n const input: BraUpdateGoalInput = {\n name: form.name.trim(),\n type: form.type,\n status: form.status,\n targetAmount: Number(form.targetAmount),\n targetDate: new Date(form.targetDate).toISOString(),\n monthlyContribution: Number(form.monthlyContribution) || 0,\n priority: Number(form.priority) || 1,\n currency: form.currency.trim() || 'USD',\n notes: form.notes.trim() || null,\n // Legacy `tags` scalar preserved as-is; the canonical tag surface is <TagField>.\n tags: editing.tags,\n };\n updateGoal.mutate({ id: editing.id, input }, { onSuccess: () => setEditing(null) });\n };\n\n const body = () => {\n if (isLoading) return <LoadingState rows={4} />;\n if (isError)\n return (\n <ErrorState\n title={translate('brainyrich.goals.error.title', 'Could not load goals')}\n description={translate(\n 'brainyrich.goals.error.description',\n 'We could not reach the goals service. Please try again.'\n )}\n onRetry={() => refetch()}\n />\n );\n if (goals.length === 0)\n return (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.goals.empty.title', 'No financial goals yet')}\n description={translate(\n 'brainyrich.goals.empty.description',\n 'Create your first goal to start tracking progress toward a milestone.'\n )}\n action={\n <Button size=\"sm\" onClick={openCreate}>\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.createGoal', 'New goal')}\n </Button>\n }\n />\n );\n\n return (\n <>\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <FadeIn index={0}>\n <StatTile\n glow\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.activeGoals', 'Goals')}\n value={String(goals.length)}\n />\n </FadeIn>\n <FadeIn index={1}>\n <StatTile\n icon={<PiggyBank className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.totalTarget', 'Total target')}\n value={formatMoney(totals.totalTarget, currency)}\n />\n </FadeIn>\n <FadeIn index={2}>\n <StatTile\n icon={<Coins className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.monthly', 'Monthly contributions')}\n value={formatMoney(totals.totalMonthly, currency)}\n />\n </FadeIn>\n <FadeIn index={3}>\n <StatTile\n icon={<AlertTriangle className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.atRisk', 'Needs attention')}\n value={String(totals.atRisk)}\n className={\n totals.atRisk > 0\n ? 'ring-1 ring-status-error-text/30'\n : undefined\n }\n />\n </FadeIn>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {goals.map((g, i) => {\n const proj = projectionMeta(g.projection);\n const ProjIcon = proj.icon;\n const tone = goalTone(g.status, g.projection);\n const pct = fundedPercent(g);\n const achieved = g.status === 'ACHIEVED';\n return (\n <FadeIn key={g.id} index={i}>\n <Card\n className={`group flex h-full flex-col transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))] ${\n achieved ? 'ring-1 ring-status-success-text/30' : ''\n }`}\n >\n <CardHeader className=\"pb-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Target\n className=\"size-4 shrink-0 text-text-secondary\"\n aria-hidden=\"true\"\n />\n <span className=\"truncate\">{g.name}</span>\n </CardTitle>\n <CardDescription className=\"mt-1 flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\">{humanize(g.type)}</Badge>\n <Badge variant={statusBadgeVariant(g.status)}>{humanize(g.status)}</Badge>\n </CardDescription>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={translate('brainyrich.goals.actions.menu', 'Goal actions')}\n >\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onSelect={() => setDetailId(g.id)}>\n <Link2 className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.manageFunding', 'Manage funding')}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => openEdit(g)}>\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.editGoal', 'Edit goal')}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"text-status-error-text focus:text-status-error-text\"\n onSelect={() => setArchiving(g)}\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.archive', 'Archive goal')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </CardHeader>\n <CardContent className=\"flex flex-1 flex-col gap-4\">\n <div className=\"flex items-center gap-4\">\n <ProgressRing\n value={pct}\n tone={tone}\n size={92}\n strokeWidth={9}\n label={translate('brainyrich.goals.card.funded', 'funded')}\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.target', 'Target amount')}\n </p>\n <p className=\"truncate text-2xl font-semibold text-text-primary\">\n {formatMoney(g.targetAmount, g.currency)}\n </p>\n <span\n className={`mt-1 inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium ${proj.tone}`}\n >\n <ProjIcon className=\"size-3.5\" aria-hidden=\"true\" />\n {humanize(g.projection)}\n </span>\n </div>\n </div>\n\n <dl className=\"grid grid-cols-2 gap-3 rounded-lg bg-bg-sunken p-3 text-sm\">\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.targetDate', 'Target date')}\n </dt>\n <dd className=\"flex items-center gap-1 font-medium text-text-primary\">\n <CalendarClock\n className=\"size-3.5 text-text-secondary\"\n aria-hidden=\"true\"\n />\n {formatDate(g.targetDate)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.monthly', 'Monthly')}\n </dt>\n <dd className=\"font-medium text-text-primary\">\n {formatMoney(g.monthlyContribution, g.currency)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.priority', 'Priority')}\n </dt>\n <dd className=\"font-medium text-text-primary\">{g.priority}</dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.fundings', 'Funding links')}\n </dt>\n <dd className=\"font-medium text-text-primary\">{g.fundings.length}</dd>\n </div>\n </dl>\n\n <div className=\"mt-auto\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => setDetailId(g.id)}\n >\n {translate('brainyrich.goals.actions.viewDetails', 'View details & funding')}\n </Button>\n </div>\n </CardContent>\n </Card>\n </FadeIn>\n );\n })}\n </div>\n\n <LoadMore\n hasMore={hasMore}\n loading={isFetchingNextPage}\n onClick={loadMore}\n label={translate('brainyrich.goals.actions.loadMore', 'Load more goals')}\n loadingLabel={translate('brainyrich.goals.actions.loadingMore', 'Loading…')}\n />\n </>\n );\n };\n\n return (\n <>\n <SectionShell\n title={translate('brainyrich.goals.title', 'Financial Goals')}\n description={translate(\n 'brainyrich.goals.description',\n 'Track progress toward your wealth milestones and life objectives'\n )}\n actionLabel={translate('brainyrich.goals.actions.createGoal', 'New goal')}\n onAction={openCreate}\n >\n {body()}\n </SectionShell>\n\n <GoalFormDialog\n open={createOpen}\n mode=\"create\"\n form={form}\n setField={setField}\n households={households.map((h) => ({ id: h.id, name: h.name }))}\n valid={formValid}\n pending={createGoal.isPending}\n onSubmit={handleCreate}\n onOpenChange={(v) => setCreateOpen(v)}\n translate={translate}\n />\n\n <GoalFormDialog\n open={Boolean(editing)}\n mode=\"edit\"\n goalId={editing?.id}\n form={form}\n setField={setField}\n households={households.map((h) => ({ id: h.id, name: h.name }))}\n valid={formValid}\n pending={updateGoal.isPending}\n onSubmit={handleUpdate}\n onOpenChange={(v) => {\n if (!v) setEditing(null);\n }}\n translate={translate}\n />\n\n <GoalDetailSheet goalId={detailId} onClose={() => setDetailId(null)} translate={translate} />\n\n <ConfirmDialog\n open={Boolean(archiving)}\n onOpenChange={(o) => {\n if (!o) setArchiving(null);\n }}\n title={translate('brainyrich.goals.archive.title', 'Archive goal?')}\n description={translate(\n 'brainyrich.goals.archive.description',\n 'This removes “{name}” from your active goals. You can no longer track its progress.',\n { name: archiving?.name ?? '' }\n )}\n confirmLabel={translate('brainyrich.goals.archive.confirm', 'Archive goal')}\n pendingLabel={translate('brainyrich.goals.archive.pending', 'Archiving…')}\n destructive\n pending={archiveGoal.isPending}\n onConfirm={() => {\n if (!archiving) return;\n archiveGoal.mutate(archiving.id, { onSuccess: () => setArchiving(null) });\n }}\n />\n </>\n );\n}\n\ntype Translate = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>\n) => string;\n\ninterface GoalFormDialogProps {\n open: boolean;\n mode: 'create' | 'edit';\n goalId?: string;\n form: GoalFormState;\n setField: <K extends keyof GoalFormState>(key: K, value: GoalFormState[K]) => void;\n households: { id: string; name: string }[];\n valid: boolean;\n pending: boolean;\n onSubmit: () => void;\n onOpenChange: (open: boolean) => void;\n translate: Translate;\n}\n\nfunction GoalFormDialog({\n open,\n mode,\n goalId,\n form,\n setField,\n households,\n valid,\n pending,\n onSubmit,\n onOpenChange,\n translate,\n}: GoalFormDialogProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-h-[90vh] overflow-y-auto sm:max-w-lg\">\n <DialogHeader>\n <DialogTitle>\n {mode === 'create'\n ? translate('brainyrich.goals.form.createTitle', 'New goal')\n : translate('brainyrich.goals.form.editTitle', 'Edit goal')}\n </DialogTitle>\n <DialogDescription>\n {translate(\n 'brainyrich.goals.form.subtitle',\n 'Define the milestone, target and contribution plan.'\n )}\n </DialogDescription>\n </DialogHeader>\n\n <form\n className=\"space-y-4\"\n onSubmit={(e) => {\n e.preventDefault();\n onSubmit();\n }}\n >\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-name\">{translate('brainyrich.goals.form.name', 'Name')}</Label>\n <Input\n id=\"goal-name\"\n value={form.name}\n onChange={(e) => setField('name', e.target.value)}\n placeholder={translate(\n 'brainyrich.goals.form.namePlaceholder',\n 'e.g. Retirement fund'\n )}\n required\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-type\">{translate('brainyrich.goals.form.type', 'Type')}</Label>\n <Select value={form.type} onValueChange={(v) => setField('type', v as BraGoalType)}>\n <SelectTrigger id=\"goal-type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {GOAL_TYPES.map((tpe) => (\n <SelectItem key={tpe} value={tpe}>\n {humanize(tpe)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {mode === 'edit' ? (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-status\">\n {translate('brainyrich.goals.form.status', 'Status')}\n </Label>\n <Select\n value={form.status}\n onValueChange={(v) => setField('status', v as BraGoalStatus)}\n >\n <SelectTrigger id=\"goal-status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {GOAL_STATUSES.map((st) => (\n <SelectItem key={st} value={st}>\n {humanize(st)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-priority\">\n {translate('brainyrich.goals.form.priority', 'Priority')}\n </Label>\n <Input\n id=\"goal-priority\"\n type=\"number\"\n min={1}\n value={form.priority}\n onChange={(e) => setField('priority', e.target.value)}\n />\n </div>\n )}\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-target\">\n {translate('brainyrich.goals.form.targetAmount', 'Target amount')}\n </Label>\n <Input\n id=\"goal-target\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={form.targetAmount}\n onChange={(e) => setField('targetAmount', e.target.value)}\n required\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-date\">\n {translate('brainyrich.goals.form.targetDate', 'Target date')}\n </Label>\n <Input\n id=\"goal-date\"\n type=\"date\"\n value={form.targetDate}\n onChange={(e) => setField('targetDate', e.target.value)}\n required\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-monthly\">\n {translate('brainyrich.goals.form.monthly', 'Monthly contribution')}\n </Label>\n <Input\n id=\"goal-monthly\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={form.monthlyContribution}\n onChange={(e) => setField('monthlyContribution', e.target.value)}\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-currency\">\n {translate('brainyrich.goals.form.currency', 'Currency')}\n </Label>\n <Input\n id=\"goal-currency\"\n value={form.currency}\n onChange={(e) => setField('currency', e.target.value.toUpperCase())}\n maxLength={3}\n />\n </div>\n </div>\n\n {mode === 'edit' ? (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-priority-edit\">\n {translate('brainyrich.goals.form.priority', 'Priority')}\n </Label>\n <Input\n id=\"goal-priority-edit\"\n type=\"number\"\n min={1}\n value={form.priority}\n onChange={(e) => setField('priority', e.target.value)}\n />\n </div>\n ) : null}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-household\">\n {translate('brainyrich.goals.form.household', 'Household (optional)')}\n </Label>\n <Select\n value={form.householdId || HOUSEHOLD_NONE}\n onValueChange={(v) => setField('householdId', v === HOUSEHOLD_NONE ? '' : v)}\n >\n <SelectTrigger id=\"goal-household\">\n <SelectValue\n placeholder={translate('brainyrich.goals.form.householdNone', 'None')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={HOUSEHOLD_NONE}>\n {translate('brainyrich.goals.form.householdNone', 'None')}\n </SelectItem>\n {households.map((h) => (\n <SelectItem key={h.id} value={h.id}>\n {h.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {mode === 'edit' && goalId ? (\n <TagField\n entityType=\"brainyrich-goal\"\n entityId={goalId}\n label={translate('brainyrich.goals.form.tags', 'Tags')}\n />\n ) : (\n <div className=\"space-y-1.5\">\n <Label>{translate('brainyrich.goals.form.tags', 'Tags')}</Label>\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.form.tagsAfterCreate',\n 'You can add tags after creating the goal.'\n )}\n </p>\n </div>\n )}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-notes\">{translate('brainyrich.goals.form.notes', 'Notes')}</Label>\n <Textarea\n id=\"goal-notes\"\n value={form.notes}\n onChange={(e) => setField('notes', e.target.value)}\n rows={3}\n />\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n disabled={pending}\n >\n {translate('brainyrich.goals.form.cancel', 'Cancel')}\n </Button>\n <Button type=\"submit\" disabled={!valid || pending}>\n {pending\n ? translate('brainyrich.goals.form.saving', 'Saving…')\n : mode === 'create'\n ? translate('brainyrich.goals.form.create', 'Create goal')\n : translate('brainyrich.goals.form.save', 'Save changes')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\ntype FundingMode = 'PERCENT' | 'FIXED';\n\ninterface GoalDetailSheetProps {\n goalId: string | null;\n onClose: () => void;\n translate: Translate;\n}\n\nfunction GoalDetailSheet({ goalId, onClose, translate }: GoalDetailSheetProps) {\n const { data: goal, isLoading, isError, refetch } = useGoal(goalId ?? undefined);\n const { data: fundings } = useGoalFundings(goalId ?? undefined);\n const { data: accounts } = useAccounts();\n\n const linkFunding = useLinkGoalFunding();\n const unlinkFunding = useUnlinkGoalFunding();\n const recalc = useRecalcGoalProjection();\n\n const [accountId, setAccountId] = useState('');\n const [fundingMode, setFundingMode] = useState<FundingMode>('PERCENT');\n const [fundingValue, setFundingValue] = useState('');\n const [fundedAmount, setFundedAmount] = useState('');\n const [unlinking, setUnlinking] = useState<BraGoalFunding | null>(null);\n\n const fixedFunded = fundings.reduce((s, f) => s + (f.fixedAmount ?? 0), 0);\n const currency = goal?.currency ?? 'USD';\n const fundedPct = goal ? fundedPercent(goal) : 0;\n const tone: VizTone = goal ? goalTone(goal.status, goal.projection) : 'brand';\n const projectionSeries = goal\n ? buildProjectionSeries(fixedFunded, goal.monthlyContribution, goal.targetDate)\n : [];\n\n const accountName = (id: string) => accounts.find((a) => a.id === id)?.name ?? id;\n\n const handleLink = () => {\n if (!goalId || !accountId) return;\n const numeric = Number(fundingValue);\n if (!Number.isFinite(numeric) || numeric <= 0) return;\n linkFunding.mutate(\n {\n goalId,\n accountId,\n ...(fundingMode === 'PERCENT' ? { allocationPct: numeric } : { fixedAmount: numeric }),\n },\n {\n onSuccess: () => {\n setAccountId('');\n setFundingValue('');\n },\n }\n );\n };\n\n const handleRecalc = () => {\n if (!goalId) return;\n const amount = fundedAmount === '' ? fixedFunded : Number(fundedAmount);\n if (!Number.isFinite(amount)) return;\n recalc.mutate({ id: goalId, fundedAmount: amount });\n };\n\n const linkValid = Boolean(accountId) && Number(fundingValue) > 0;\n\n const unlinkingLabel = unlinking\n ? unlinking.fixedAmount != null\n ? formatMoney(unlinking.fixedAmount, currency)\n : accountName(unlinking.accountId)\n : '';\n\n return (\n <>\n <Sheet\n open={Boolean(goalId)}\n onOpenChange={(v) => {\n if (!v) onClose();\n }}\n >\n <SheetContent className=\"flex w-full flex-col gap-0 overflow-y-auto sm:max-w-xl\">\n <SheetHeader>\n <SheetTitle>\n {goal?.name ?? translate('brainyrich.goals.detail.title', 'Goal')}\n </SheetTitle>\n <SheetDescription>\n {translate('brainyrich.goals.detail.subtitle', 'Manage funding links and projection.')}\n </SheetDescription>\n </SheetHeader>\n\n <div className=\"space-y-6 p-4\">\n {isLoading ? (\n <LoadingState rows={3} />\n ) : isError ? (\n <ErrorState\n title={translate('brainyrich.goals.detail.error', 'Could not load goal')}\n onRetry={() => refetch()}\n />\n ) : !goal ? (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.goals.detail.notFound', 'Goal not found')}\n />\n ) : (\n <>\n {/* Hero: funded progress ring + headline */}\n <GlassCard glow className=\"flex items-center gap-5\">\n <ProgressRing\n value={fundedPct}\n tone={tone}\n size={116}\n strokeWidth={11}\n label={translate('brainyrich.goals.detail.funded', 'funded')}\n />\n <div className=\"min-w-0 flex-1 space-y-1\">\n <Badge variant={statusBadgeVariant(goal.projection)}>\n {humanize(goal.projection)}\n </Badge>\n <p className=\"text-2xl font-semibold text-text-primary\">\n {formatMoney(fixedFunded, currency)}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.detail.ofTarget', 'of {target} target', {\n target: formatCompact(goal.targetAmount, currency),\n })}\n </p>\n </div>\n </GlassCard>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <StatTile\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.target', 'Target')}\n value={formatMoney(goal.targetAmount, currency)}\n />\n <StatTile\n icon={<Wallet className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.funded', 'Funded (fixed)')}\n value={formatMoney(fixedFunded, currency)}\n />\n <StatTile\n icon={<Coins className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.monthly', 'Monthly')}\n value={formatMoney(goal.monthlyContribution, currency)}\n />\n <StatTile\n icon={<CalendarClock className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.targetDate', 'Target date')}\n value={formatDate(goal.targetDate)}\n />\n </div>\n\n {/* Projection trajectory toward the target line */}\n {projectionSeries.length >= 2 ? (\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex items-center gap-2\">\n <LineChart className=\"size-4 text-text-secondary\" aria-hidden=\"true\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.projectionChart', 'Contribution projection')}\n </h3>\n </div>\n <MiniAreaChart\n data={projectionSeries}\n target={goal.targetAmount}\n tone={tone}\n height={180}\n valueFormatter={(v) => formatCompact(v, currency)}\n />\n <p className=\"text-xs text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.projectionHint',\n 'Starting balance plus {monthly}/mo through {date}.',\n {\n monthly: formatMoney(goal.monthlyContribution, currency),\n date: formatDate(goal.targetDate),\n }\n )}\n </p>\n </section>\n ) : null}\n\n {/* Funding sources table */}\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.fundingLinks', 'Funding sources')}\n </h3>\n {fundings.length === 0 ? (\n <p className=\"rounded-lg border border-dashed border-border-subtle bg-bg-surface px-4 py-6 text-center text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.noFundings',\n 'No accounts linked to fund this goal yet.'\n )}\n </p>\n ) : (\n <div className=\"overflow-x-auto rounded-lg border border-border-subtle\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>\n {translate('brainyrich.goals.detail.account', 'Account')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.goals.detail.allocation', 'Allocation')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.goals.detail.fixedAmount', 'Fixed amount')}\n </TableHead>\n <TableHead className=\"w-10\" />\n </TableRow>\n </TableHeader>\n <TableBody>\n {fundings.map((f) => (\n <TableRow key={f.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {accountName(f.accountId)}\n </TableCell>\n <TableCell className=\"text-right tabular-nums text-text-secondary\">\n {f.fixedAmount == null ? formatPct(f.allocationPct) : '—'}\n </TableCell>\n <TableCell className=\"text-right tabular-nums text-text-secondary\">\n {f.fixedAmount != null ? formatMoney(f.fixedAmount, currency) : '—'}\n </TableCell>\n <TableCell className=\"text-right\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={translate(\n 'brainyrich.goals.detail.unlink',\n 'Unlink funding'\n )}\n onClick={() => setUnlinking(f)}\n >\n <Unlink className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </section>\n\n {/* Link a new funding */}\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.linkTitle', 'Link an account')}\n </h3>\n {accounts.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.noAccounts',\n 'No accounts available to link.'\n )}\n </p>\n ) : (\n <>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-account\">\n {translate('brainyrich.goals.detail.account', 'Account')}\n </Label>\n <Select value={accountId} onValueChange={setAccountId}>\n <SelectTrigger id=\"funding-account\">\n <SelectValue\n placeholder={translate(\n 'brainyrich.goals.detail.selectAccount',\n 'Select account'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n {accounts.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-mode\">\n {translate('brainyrich.goals.detail.mode', 'Method')}\n </Label>\n <Select\n value={fundingMode}\n onValueChange={(v) => setFundingMode(v as FundingMode)}\n >\n <SelectTrigger id=\"funding-mode\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"PERCENT\">\n {translate('brainyrich.goals.detail.percent', 'Percentage')}\n </SelectItem>\n <SelectItem value=\"FIXED\">\n {translate('brainyrich.goals.detail.fixed', 'Fixed amount')}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-value\">\n {fundingMode === 'PERCENT'\n ? translate('brainyrich.goals.detail.pct', 'Percent')\n : translate('brainyrich.goals.detail.amount', 'Amount')}\n </Label>\n <Input\n id=\"funding-value\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={fundingValue}\n onChange={(e) => setFundingValue(e.target.value)}\n />\n </div>\n </div>\n <Button\n size=\"sm\"\n className=\"w-full\"\n disabled={!linkValid || linkFunding.isPending}\n onClick={handleLink}\n >\n <Link2 className=\"size-4\" aria-hidden=\"true\" />\n {linkFunding.isPending\n ? translate('brainyrich.goals.detail.linking', 'Linking…')\n : translate('brainyrich.goals.detail.link', 'Link funding')}\n </Button>\n </>\n )}\n </section>\n\n {/* Recalc projection */}\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.recalcTitle', 'Recalculate projection')}\n </h3>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"recalc-funded\">\n {translate('brainyrich.goals.detail.fundedAmount', 'Funded amount')}\n </Label>\n <Input\n id=\"recalc-funded\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={fundedAmount}\n placeholder={String(fixedFunded)}\n onChange={(e) => setFundedAmount(e.target.value)}\n />\n <p className=\"text-xs text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.recalcHint',\n 'Defaults to the sum of fixed fundings when left blank.'\n )}\n </p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"w-full\"\n disabled={recalc.isPending}\n onClick={handleRecalc}\n >\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n {recalc.isPending\n ? translate('brainyrich.goals.detail.recalculating', 'Recalculating…')\n : translate('brainyrich.goals.detail.recalc', 'Recalculate')}\n </Button>\n </section>\n </>\n )}\n </div>\n </SheetContent>\n </Sheet>\n\n <ConfirmDialog\n open={Boolean(unlinking)}\n onOpenChange={(o) => {\n if (!o) setUnlinking(null);\n }}\n title={translate('brainyrich.goals.detail.unlinkTitle', 'Unlink funding?')}\n description={translate(\n 'brainyrich.goals.detail.unlinkConfirm',\n 'This removes the “{name}” funding link from this goal.',\n { name: unlinkingLabel }\n )}\n confirmLabel={translate('brainyrich.goals.detail.unlink', 'Unlink funding')}\n pendingLabel={translate('brainyrich.goals.detail.unlinking', 'Unlinking…')}\n destructive\n pending={unlinkFunding.isPending}\n onConfirm={() => {\n if (!unlinking) return;\n unlinkFunding.mutate(unlinking.id, { onSuccess: () => setUnlinking(null) });\n }}\n />\n </>\n );\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"GoalsPage.js","names":[],"sources":["../../../src/brainyrich/pages/GoalsPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n AlertTriangle,\n CalendarClock,\n Coins,\n Link2,\n LineChart,\n MoreHorizontal,\n PiggyBank,\n Plus,\n RefreshCw,\n Target,\n Trash2,\n TrendingDown,\n TrendingUp,\n Unlink,\n Wallet,\n} from 'lucide-react';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n ConfirmDialog,\n FadeIn,\n GlassCard,\n LoadMore,\n MiniAreaChart,\n ProgressRing,\n StatTile,\n type AreaDatum,\n type VizTone,\n} from '../components';\nimport { TagField } from '../components/reuse/TagField';\nimport {\n useAccounts,\n useArchiveGoal,\n useCreateGoal,\n useGoal,\n useGoalFundings,\n useHouseholds,\n useLinkGoalFunding,\n usePagedGoals,\n useRecalcGoalProjection,\n useUnlinkGoalFunding,\n useUpdateGoal,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraCreateGoalInput,\n BraGoal,\n BraGoalFunding,\n BraGoalProjection,\n BraGoalStatus,\n BraGoalType,\n BraUpdateGoalInput,\n} from '../types/bra';\nimport {\n EmptyState,\n ErrorState,\n LoadingState,\n SectionShell,\n formatCompact,\n formatDate,\n formatMoney,\n formatPct,\n statusBadgeVariant,\n} from './_shared';\n\nconst GOAL_TYPES: BraGoalType[] = [\n 'RETIREMENT',\n 'EDUCATION',\n 'HOME',\n 'EMERGENCY_FUND',\n 'MAJOR_PURCHASE',\n 'WEALTH_GROWTH',\n 'CUSTOM',\n];\n\nconst GOAL_STATUSES: BraGoalStatus[] = ['ACTIVE', 'ACHIEVED', 'ON_HOLD', 'ABANDONED'];\n\ninterface ProjectionMeta {\n icon: typeof TrendingUp;\n tone: string;\n}\n\nfunction projectionMeta(projection: BraGoalProjection): ProjectionMeta {\n switch (projection) {\n case 'AHEAD':\n case 'ON_TRACK':\n return { icon: TrendingUp, tone: 'text-status-success-text' };\n case 'BEHIND':\n return { icon: TrendingDown, tone: 'text-status-warning-text' };\n case 'AT_RISK':\n default:\n return { icon: AlertTriangle, tone: 'text-status-error-text' };\n }\n}\n\nfunction humanize(value: string): string {\n return value\n .toLowerCase()\n .split('_')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n}\n\n/** Sum of the fixed-amount funding links wired to a goal (real backend value). */\nfunction goalFixedFunded(goal: Pick<BraGoal, 'fundings'>): number {\n return goal.fundings.reduce((s, f) => s + (f.fixedAmount ?? 0), 0);\n}\n\n/**\n * Funded-progress percentage for a goal. ACHIEVED goals read 100%; otherwise the\n * sum of fixed funding links over the target — every input is wired backend data,\n * never fabricated.\n */\nfunction fundedPercent(goal: Pick<BraGoal, 'fundings' | 'targetAmount' | 'status'>): number {\n if (goal.status === 'ACHIEVED') return 100;\n if (!(goal.targetAmount > 0)) return 0;\n return Math.max(0, Math.min(100, (goalFixedFunded(goal) / goal.targetAmount) * 100));\n}\n\n/** Ring/accent tone derived from the goal's real status + projection. */\nfunction goalTone(status: BraGoalStatus, projection: BraGoalProjection): VizTone {\n if (status === 'ACHIEVED') return 'success';\n switch (projection) {\n case 'AHEAD':\n case 'ON_TRACK':\n return 'brand';\n case 'BEHIND':\n return 'warning';\n case 'AT_RISK':\n default:\n return 'error';\n }\n}\n\n/**\n * A deterministic contribution trajectory from today to the target date, computed\n * purely from wired fields: starting funded balance + monthly contribution × month.\n * No randomness, no fabricated series — just the arithmetic funding path the user\n * has configured. Returns [] when there is nothing meaningful to chart.\n */\nfunction buildProjectionSeries(\n funded: number,\n monthly: number,\n targetIso?: string | null\n): AreaDatum[] {\n if (!targetIso) return [];\n const target = new Date(targetIso);\n if (Number.isNaN(target.getTime())) return [];\n const now = new Date();\n const totalMonths =\n (target.getFullYear() - now.getFullYear()) * 12 + (target.getMonth() - now.getMonth());\n if (totalMonths <= 0) return [];\n const steps = Math.min(Math.max(totalMonths, 2), 12);\n const fmt = new Intl.DateTimeFormat('en-US', { month: 'short', year: '2-digit' });\n const points: AreaDatum[] = [];\n for (let i = 0; i <= steps; i += 1) {\n const m = Math.round((totalMonths / steps) * i);\n const at = new Date(now.getFullYear(), now.getMonth() + m, 1);\n points.push({ x: fmt.format(at), y: Math.round(funded + monthly * m) });\n }\n return points;\n}\n\n/** yyyy-mm-dd for a date input, guarded against absent/invalid ISO strings. */\nfunction toDateInput(iso?: string | null): string {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toISOString().slice(0, 10);\n}\n\ninterface GoalFormState {\n name: string;\n type: BraGoalType;\n status: BraGoalStatus;\n targetAmount: string;\n targetDate: string;\n monthlyContribution: string;\n priority: string;\n currency: string;\n householdId: string;\n notes: string;\n}\n\nfunction emptyForm(): GoalFormState {\n return {\n name: '',\n type: 'CUSTOM',\n status: 'ACTIVE',\n targetAmount: '',\n targetDate: '',\n monthlyContribution: '',\n priority: '1',\n currency: 'USD',\n householdId: '',\n notes: '',\n };\n}\n\nfunction formFromGoal(goal: BraGoal): GoalFormState {\n return {\n name: goal.name,\n type: goal.type,\n status: goal.status,\n targetAmount: String(goal.targetAmount),\n targetDate: toDateInput(goal.targetDate),\n monthlyContribution: String(goal.monthlyContribution),\n priority: String(goal.priority),\n currency: goal.currency,\n householdId: goal.householdId ?? '',\n notes: goal.notes ?? '',\n };\n}\n\nconst HOUSEHOLD_NONE = '__none__';\n\nexport function GoalsPage() {\n const { t } = useI18n();\n const translate = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n\n const {\n items: goals,\n hasMore,\n loadMore,\n isFetchingNextPage,\n isLoading,\n isError,\n refetch,\n } = usePagedGoals();\n const { data: households } = useHouseholds();\n\n const createGoal = useCreateGoal();\n const updateGoal = useUpdateGoal();\n const archiveGoal = useArchiveGoal();\n\n const [createOpen, setCreateOpen] = useState(false);\n const [editing, setEditing] = useState<BraGoal | null>(null);\n const [detailId, setDetailId] = useState<string | null>(null);\n const [archiving, setArchiving] = useState<BraGoal | null>(null);\n const [form, setForm] = useState<GoalFormState>(emptyForm);\n\n const setField = <K extends keyof GoalFormState>(key: K, value: GoalFormState[K]) =>\n setForm((prev) => ({ ...prev, [key]: value }));\n\n const totals = useMemo(() => {\n const totalTarget = goals.reduce((s, g) => s + g.targetAmount, 0);\n const totalMonthly = goals.reduce((s, g) => s + g.monthlyContribution, 0);\n const atRisk = goals.filter(\n (g) => g.projection === 'AT_RISK' || g.projection === 'BEHIND'\n ).length;\n return { totalTarget, totalMonthly, atRisk };\n }, [goals]);\n\n const currency = goals[0]?.currency ?? 'USD';\n\n const openCreate = () => {\n setForm(emptyForm());\n setCreateOpen(true);\n };\n\n const openEdit = (goal: BraGoal) => {\n setForm(formFromGoal(goal));\n setEditing(goal);\n };\n\n const formValid =\n form.name.trim().length > 0 && Number(form.targetAmount) > 0 && form.targetDate.length > 0;\n\n const handleCreate = () => {\n if (!formValid) return;\n const input: BraCreateGoalInput = {\n name: form.name.trim(),\n type: form.type,\n targetAmount: Number(form.targetAmount),\n targetDate: new Date(form.targetDate).toISOString(),\n monthlyContribution: Number(form.monthlyContribution) || 0,\n priority: Number(form.priority) || 1,\n currency: form.currency.trim() || 'USD',\n notes: form.notes.trim() || null,\n tags: [],\n ...(form.householdId ? { householdId: form.householdId } : {}),\n };\n createGoal.mutate(input, { onSuccess: () => setCreateOpen(false) });\n };\n\n const handleUpdate = () => {\n if (!editing || !formValid) return;\n const input: BraUpdateGoalInput = {\n name: form.name.trim(),\n type: form.type,\n status: form.status,\n targetAmount: Number(form.targetAmount),\n targetDate: new Date(form.targetDate).toISOString(),\n monthlyContribution: Number(form.monthlyContribution) || 0,\n priority: Number(form.priority) || 1,\n currency: form.currency.trim() || 'USD',\n notes: form.notes.trim() || null,\n // Legacy `tags` scalar preserved as-is; the canonical tag surface is <TagField>.\n tags: editing.tags,\n };\n updateGoal.mutate({ id: editing.id, input }, { onSuccess: () => setEditing(null) });\n };\n\n const body = () => {\n if (isLoading) return <LoadingState rows={4} />;\n if (isError)\n return (\n <ErrorState\n title={translate('brainyrich.goals.error.title', 'Could not load goals')}\n description={translate(\n 'brainyrich.goals.error.description',\n 'We could not reach the goals service. Please try again.'\n )}\n onRetry={() => refetch()}\n />\n );\n if (goals.length === 0)\n return (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.goals.empty.title', 'No financial goals yet')}\n description={translate(\n 'brainyrich.goals.empty.description',\n 'Create your first goal to start tracking progress toward a milestone.'\n )}\n action={\n <Button size=\"sm\" onClick={openCreate}>\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.createGoal', 'New goal')}\n </Button>\n }\n />\n );\n\n return (\n <>\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <FadeIn index={0}>\n <StatTile\n glow\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.activeGoals', 'Goals')}\n value={String(goals.length)}\n />\n </FadeIn>\n <FadeIn index={1}>\n <StatTile\n icon={<PiggyBank className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.totalTarget', 'Total target')}\n value={formatMoney(totals.totalTarget, currency)}\n />\n </FadeIn>\n <FadeIn index={2}>\n <StatTile\n icon={<Coins className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.monthly', 'Monthly contributions')}\n value={formatMoney(totals.totalMonthly, currency)}\n />\n </FadeIn>\n <FadeIn index={3}>\n <StatTile\n icon={<AlertTriangle className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.metrics.atRisk', 'Needs attention')}\n value={String(totals.atRisk)}\n className={totals.atRisk > 0 ? 'ring-1 ring-status-error-text/30' : undefined}\n />\n </FadeIn>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {goals.map((g, i) => {\n const proj = projectionMeta(g.projection);\n const ProjIcon = proj.icon;\n const tone = goalTone(g.status, g.projection);\n const pct = fundedPercent(g);\n const achieved = g.status === 'ACHIEVED';\n return (\n <FadeIn key={g.id} index={i}>\n <Card\n className={`group flex h-full flex-col transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))] ${\n achieved ? 'ring-1 ring-status-success-text/30' : ''\n }`}\n >\n <CardHeader className=\"pb-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Target\n className=\"size-4 shrink-0 text-text-secondary\"\n aria-hidden=\"true\"\n />\n <span className=\"truncate\">{g.name}</span>\n </CardTitle>\n <CardDescription className=\"mt-1 flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\">{humanize(g.type)}</Badge>\n <Badge variant={statusBadgeVariant(g.status)}>{humanize(g.status)}</Badge>\n </CardDescription>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={translate('brainyrich.goals.actions.menu', 'Goal actions')}\n >\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onSelect={() => setDetailId(g.id)}>\n <Link2 className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.manageFunding', 'Manage funding')}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => openEdit(g)}>\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.editGoal', 'Edit goal')}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"text-status-error-text focus:text-status-error-text\"\n onSelect={() => setArchiving(g)}\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.goals.actions.archive', 'Archive goal')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </CardHeader>\n <CardContent className=\"flex flex-1 flex-col gap-4\">\n <div className=\"flex items-center gap-4\">\n <ProgressRing\n value={pct}\n tone={tone}\n size={92}\n strokeWidth={9}\n label={translate('brainyrich.goals.card.funded', 'funded')}\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.target', 'Target amount')}\n </p>\n <p className=\"truncate text-2xl font-semibold text-text-primary\">\n {formatMoney(g.targetAmount, g.currency)}\n </p>\n <span\n className={`mt-1 inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium ${proj.tone}`}\n >\n <ProjIcon className=\"size-3.5\" aria-hidden=\"true\" />\n {humanize(g.projection)}\n </span>\n </div>\n </div>\n\n <dl className=\"grid grid-cols-2 gap-3 rounded-lg bg-bg-sunken p-3 text-sm\">\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.targetDate', 'Target date')}\n </dt>\n <dd className=\"flex items-center gap-1 font-medium text-text-primary\">\n <CalendarClock\n className=\"size-3.5 text-text-secondary\"\n aria-hidden=\"true\"\n />\n {formatDate(g.targetDate)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.monthly', 'Monthly')}\n </dt>\n <dd className=\"font-medium text-text-primary\">\n {formatMoney(g.monthlyContribution, g.currency)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.priority', 'Priority')}\n </dt>\n <dd className=\"font-medium text-text-primary\">{g.priority}</dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.card.fundings', 'Funding links')}\n </dt>\n <dd className=\"font-medium text-text-primary\">{g.fundings.length}</dd>\n </div>\n </dl>\n\n <div className=\"mt-auto\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => setDetailId(g.id)}\n >\n {translate(\n 'brainyrich.goals.actions.viewDetails',\n 'View details & funding'\n )}\n </Button>\n </div>\n </CardContent>\n </Card>\n </FadeIn>\n );\n })}\n </div>\n\n <LoadMore\n hasMore={hasMore}\n loading={isFetchingNextPage}\n onClick={loadMore}\n label={translate('brainyrich.goals.actions.loadMore', 'Load more goals')}\n loadingLabel={translate('brainyrich.goals.actions.loadingMore', 'Loading…')}\n />\n </>\n );\n };\n\n return (\n <>\n <SectionShell\n title={translate('brainyrich.goals.title', 'Financial Goals')}\n description={translate(\n 'brainyrich.goals.description',\n 'Track progress toward your wealth milestones and life objectives'\n )}\n actionLabel={translate('brainyrich.goals.actions.createGoal', 'New goal')}\n onAction={openCreate}\n >\n {body()}\n </SectionShell>\n\n <GoalFormDialog\n open={createOpen}\n mode=\"create\"\n form={form}\n setField={setField}\n households={households.map((h) => ({ id: h.id, name: h.name }))}\n valid={formValid}\n pending={createGoal.isPending}\n onSubmit={handleCreate}\n onOpenChange={(v) => setCreateOpen(v)}\n translate={translate}\n />\n\n <GoalFormDialog\n open={Boolean(editing)}\n mode=\"edit\"\n goalId={editing?.id}\n form={form}\n setField={setField}\n households={households.map((h) => ({ id: h.id, name: h.name }))}\n valid={formValid}\n pending={updateGoal.isPending}\n onSubmit={handleUpdate}\n onOpenChange={(v) => {\n if (!v) setEditing(null);\n }}\n translate={translate}\n />\n\n <GoalDetailSheet goalId={detailId} onClose={() => setDetailId(null)} translate={translate} />\n\n <ConfirmDialog\n open={Boolean(archiving)}\n onOpenChange={(o) => {\n if (!o) setArchiving(null);\n }}\n title={translate('brainyrich.goals.archive.title', 'Archive goal?')}\n description={translate(\n 'brainyrich.goals.archive.description',\n 'This removes “{name}” from your active goals. You can no longer track its progress.',\n { name: archiving?.name ?? '' }\n )}\n confirmLabel={translate('brainyrich.goals.archive.confirm', 'Archive goal')}\n pendingLabel={translate('brainyrich.goals.archive.pending', 'Archiving…')}\n destructive\n pending={archiveGoal.isPending}\n onConfirm={() => {\n if (!archiving) return;\n archiveGoal.mutate(archiving.id, { onSuccess: () => setArchiving(null) });\n }}\n />\n </>\n );\n}\n\ntype Translate = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>\n) => string;\n\ninterface GoalFormDialogProps {\n open: boolean;\n mode: 'create' | 'edit';\n goalId?: string;\n form: GoalFormState;\n setField: <K extends keyof GoalFormState>(key: K, value: GoalFormState[K]) => void;\n households: { id: string; name: string }[];\n valid: boolean;\n pending: boolean;\n onSubmit: () => void;\n onOpenChange: (open: boolean) => void;\n translate: Translate;\n}\n\nfunction GoalFormDialog({\n open,\n mode,\n goalId,\n form,\n setField,\n households,\n valid,\n pending,\n onSubmit,\n onOpenChange,\n translate,\n}: GoalFormDialogProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-h-[90vh] overflow-y-auto sm:max-w-lg\">\n <DialogHeader>\n <DialogTitle>\n {mode === 'create'\n ? translate('brainyrich.goals.form.createTitle', 'New goal')\n : translate('brainyrich.goals.form.editTitle', 'Edit goal')}\n </DialogTitle>\n <DialogDescription>\n {translate(\n 'brainyrich.goals.form.subtitle',\n 'Define the milestone, target and contribution plan.'\n )}\n </DialogDescription>\n </DialogHeader>\n\n <form\n className=\"space-y-4\"\n onSubmit={(e) => {\n e.preventDefault();\n onSubmit();\n }}\n >\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-name\">{translate('brainyrich.goals.form.name', 'Name')}</Label>\n <Input\n id=\"goal-name\"\n value={form.name}\n onChange={(e) => setField('name', e.target.value)}\n placeholder={translate(\n 'brainyrich.goals.form.namePlaceholder',\n 'e.g. Retirement fund'\n )}\n required\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-type\">{translate('brainyrich.goals.form.type', 'Type')}</Label>\n <Select value={form.type} onValueChange={(v) => setField('type', v as BraGoalType)}>\n <SelectTrigger id=\"goal-type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {GOAL_TYPES.map((tpe) => (\n <SelectItem key={tpe} value={tpe}>\n {humanize(tpe)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {mode === 'edit' ? (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-status\">\n {translate('brainyrich.goals.form.status', 'Status')}\n </Label>\n <Select\n value={form.status}\n onValueChange={(v) => setField('status', v as BraGoalStatus)}\n >\n <SelectTrigger id=\"goal-status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {GOAL_STATUSES.map((st) => (\n <SelectItem key={st} value={st}>\n {humanize(st)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-priority\">\n {translate('brainyrich.goals.form.priority', 'Priority')}\n </Label>\n <Input\n id=\"goal-priority\"\n type=\"number\"\n min={1}\n value={form.priority}\n onChange={(e) => setField('priority', e.target.value)}\n />\n </div>\n )}\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-target\">\n {translate('brainyrich.goals.form.targetAmount', 'Target amount')}\n </Label>\n <Input\n id=\"goal-target\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={form.targetAmount}\n onChange={(e) => setField('targetAmount', e.target.value)}\n required\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-date\">\n {translate('brainyrich.goals.form.targetDate', 'Target date')}\n </Label>\n <Input\n id=\"goal-date\"\n type=\"date\"\n value={form.targetDate}\n onChange={(e) => setField('targetDate', e.target.value)}\n required\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-monthly\">\n {translate('brainyrich.goals.form.monthly', 'Monthly contribution')}\n </Label>\n <Input\n id=\"goal-monthly\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={form.monthlyContribution}\n onChange={(e) => setField('monthlyContribution', e.target.value)}\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-currency\">\n {translate('brainyrich.goals.form.currency', 'Currency')}\n </Label>\n <Input\n id=\"goal-currency\"\n value={form.currency}\n onChange={(e) => setField('currency', e.target.value.toUpperCase())}\n maxLength={3}\n />\n </div>\n </div>\n\n {mode === 'edit' ? (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-priority-edit\">\n {translate('brainyrich.goals.form.priority', 'Priority')}\n </Label>\n <Input\n id=\"goal-priority-edit\"\n type=\"number\"\n min={1}\n value={form.priority}\n onChange={(e) => setField('priority', e.target.value)}\n />\n </div>\n ) : null}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-household\">\n {translate('brainyrich.goals.form.household', 'Household (optional)')}\n </Label>\n <Select\n value={form.householdId || HOUSEHOLD_NONE}\n onValueChange={(v) => setField('householdId', v === HOUSEHOLD_NONE ? '' : v)}\n >\n <SelectTrigger id=\"goal-household\">\n <SelectValue\n placeholder={translate('brainyrich.goals.form.householdNone', 'None')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={HOUSEHOLD_NONE}>\n {translate('brainyrich.goals.form.householdNone', 'None')}\n </SelectItem>\n {households.map((h) => (\n <SelectItem key={h.id} value={h.id}>\n {h.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {mode === 'edit' && goalId ? (\n <TagField\n entityType=\"brainyrich-goal\"\n entityId={goalId}\n label={translate('brainyrich.goals.form.tags', 'Tags')}\n />\n ) : (\n <div className=\"space-y-1.5\">\n <Label>{translate('brainyrich.goals.form.tags', 'Tags')}</Label>\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.form.tagsAfterCreate',\n 'You can add tags after creating the goal.'\n )}\n </p>\n </div>\n )}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"goal-notes\">{translate('brainyrich.goals.form.notes', 'Notes')}</Label>\n <Textarea\n id=\"goal-notes\"\n value={form.notes}\n onChange={(e) => setField('notes', e.target.value)}\n rows={3}\n />\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n disabled={pending}\n >\n {translate('brainyrich.goals.form.cancel', 'Cancel')}\n </Button>\n <Button type=\"submit\" disabled={!valid || pending}>\n {pending\n ? translate('brainyrich.goals.form.saving', 'Saving…')\n : mode === 'create'\n ? translate('brainyrich.goals.form.create', 'Create goal')\n : translate('brainyrich.goals.form.save', 'Save changes')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\ntype FundingMode = 'PERCENT' | 'FIXED';\n\ninterface GoalDetailSheetProps {\n goalId: string | null;\n onClose: () => void;\n translate: Translate;\n}\n\nfunction GoalDetailSheet({ goalId, onClose, translate }: GoalDetailSheetProps) {\n const { data: goal, isLoading, isError, refetch } = useGoal(goalId ?? undefined);\n const { data: fundings } = useGoalFundings(goalId ?? undefined);\n const { data: accounts } = useAccounts();\n\n const linkFunding = useLinkGoalFunding();\n const unlinkFunding = useUnlinkGoalFunding();\n const recalc = useRecalcGoalProjection();\n\n const [accountId, setAccountId] = useState('');\n const [fundingMode, setFundingMode] = useState<FundingMode>('PERCENT');\n const [fundingValue, setFundingValue] = useState('');\n const [fundedAmount, setFundedAmount] = useState('');\n const [unlinking, setUnlinking] = useState<BraGoalFunding | null>(null);\n\n const fixedFunded = fundings.reduce((s, f) => s + (f.fixedAmount ?? 0), 0);\n const currency = goal?.currency ?? 'USD';\n const fundedPct = goal ? fundedPercent(goal) : 0;\n const tone: VizTone = goal ? goalTone(goal.status, goal.projection) : 'brand';\n const projectionSeries = goal\n ? buildProjectionSeries(fixedFunded, goal.monthlyContribution, goal.targetDate)\n : [];\n\n const accountName = (id: string) => accounts.find((a) => a.id === id)?.name ?? id;\n\n const handleLink = () => {\n if (!goalId || !accountId) return;\n const numeric = Number(fundingValue);\n if (!Number.isFinite(numeric) || numeric <= 0) return;\n linkFunding.mutate(\n {\n goalId,\n accountId,\n ...(fundingMode === 'PERCENT' ? { allocationPct: numeric } : { fixedAmount: numeric }),\n },\n {\n onSuccess: () => {\n setAccountId('');\n setFundingValue('');\n },\n }\n );\n };\n\n const handleRecalc = () => {\n if (!goalId) return;\n const amount = fundedAmount === '' ? fixedFunded : Number(fundedAmount);\n if (!Number.isFinite(amount)) return;\n recalc.mutate({ id: goalId, fundedAmount: amount });\n };\n\n const linkValid = Boolean(accountId) && Number(fundingValue) > 0;\n\n const unlinkingLabel = unlinking\n ? unlinking.fixedAmount != null\n ? formatMoney(unlinking.fixedAmount, currency)\n : accountName(unlinking.accountId)\n : '';\n\n return (\n <>\n <Sheet\n open={Boolean(goalId)}\n onOpenChange={(v) => {\n if (!v) onClose();\n }}\n >\n <SheetContent className=\"flex w-full flex-col gap-0 overflow-y-auto sm:max-w-xl\">\n <SheetHeader>\n <SheetTitle>\n {goal?.name ?? translate('brainyrich.goals.detail.title', 'Goal')}\n </SheetTitle>\n <SheetDescription>\n {translate(\n 'brainyrich.goals.detail.subtitle',\n 'Manage funding links and projection.'\n )}\n </SheetDescription>\n </SheetHeader>\n\n <div className=\"space-y-6 p-4\">\n {isLoading ? (\n <LoadingState rows={3} />\n ) : isError ? (\n <ErrorState\n title={translate('brainyrich.goals.detail.error', 'Could not load goal')}\n onRetry={() => refetch()}\n />\n ) : !goal ? (\n <EmptyState\n icon={<Target className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.goals.detail.notFound', 'Goal not found')}\n />\n ) : (\n <>\n {/* Hero: funded progress ring + headline */}\n <GlassCard glow className=\"flex items-center gap-5\">\n <ProgressRing\n value={fundedPct}\n tone={tone}\n size={116}\n strokeWidth={11}\n label={translate('brainyrich.goals.detail.funded', 'funded')}\n />\n <div className=\"min-w-0 flex-1 space-y-1\">\n <Badge variant={statusBadgeVariant(goal.projection)}>\n {humanize(goal.projection)}\n </Badge>\n <p className=\"text-2xl font-semibold text-text-primary\">\n {formatMoney(fixedFunded, currency)}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {translate('brainyrich.goals.detail.ofTarget', 'of {target} target', {\n target: formatCompact(goal.targetAmount, currency),\n })}\n </p>\n </div>\n </GlassCard>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <StatTile\n icon={<Target className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.target', 'Target')}\n value={formatMoney(goal.targetAmount, currency)}\n />\n <StatTile\n icon={<Wallet className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.funded', 'Funded (fixed)')}\n value={formatMoney(fixedFunded, currency)}\n />\n <StatTile\n icon={<Coins className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.monthly', 'Monthly')}\n value={formatMoney(goal.monthlyContribution, currency)}\n />\n <StatTile\n icon={<CalendarClock className=\"size-4\" aria-hidden=\"true\" />}\n label={translate('brainyrich.goals.detail.targetDate', 'Target date')}\n value={formatDate(goal.targetDate)}\n />\n </div>\n\n {/* Projection trajectory toward the target line */}\n {projectionSeries.length >= 2 ? (\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex items-center gap-2\">\n <LineChart className=\"size-4 text-text-secondary\" aria-hidden=\"true\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate(\n 'brainyrich.goals.detail.projectionChart',\n 'Contribution projection'\n )}\n </h3>\n </div>\n <MiniAreaChart\n data={projectionSeries}\n target={goal.targetAmount}\n tone={tone}\n height={180}\n valueFormatter={(v) => formatCompact(v, currency)}\n />\n <p className=\"text-xs text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.projectionHint',\n 'Starting balance plus {monthly}/mo through {date}.',\n {\n monthly: formatMoney(goal.monthlyContribution, currency),\n date: formatDate(goal.targetDate),\n }\n )}\n </p>\n </section>\n ) : null}\n\n {/* Funding sources table */}\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.fundingLinks', 'Funding sources')}\n </h3>\n {fundings.length === 0 ? (\n <p className=\"rounded-lg border border-dashed border-border-subtle bg-bg-surface px-4 py-6 text-center text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.noFundings',\n 'No accounts linked to fund this goal yet.'\n )}\n </p>\n ) : (\n <div className=\"overflow-x-auto rounded-lg border border-border-subtle\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>\n {translate('brainyrich.goals.detail.account', 'Account')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.goals.detail.allocation', 'Allocation')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.goals.detail.fixedAmount', 'Fixed amount')}\n </TableHead>\n <TableHead className=\"w-10\" />\n </TableRow>\n </TableHeader>\n <TableBody>\n {fundings.map((f) => (\n <TableRow key={f.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {accountName(f.accountId)}\n </TableCell>\n <TableCell className=\"text-right tabular-nums text-text-secondary\">\n {f.fixedAmount == null ? formatPct(f.allocationPct) : '—'}\n </TableCell>\n <TableCell className=\"text-right tabular-nums text-text-secondary\">\n {f.fixedAmount != null ? formatMoney(f.fixedAmount, currency) : '—'}\n </TableCell>\n <TableCell className=\"text-right\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={translate(\n 'brainyrich.goals.detail.unlink',\n 'Unlink funding'\n )}\n onClick={() => setUnlinking(f)}\n >\n <Unlink className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </section>\n\n {/* Link a new funding */}\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.linkTitle', 'Link an account')}\n </h3>\n {accounts.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.noAccounts',\n 'No accounts available to link.'\n )}\n </p>\n ) : (\n <>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-account\">\n {translate('brainyrich.goals.detail.account', 'Account')}\n </Label>\n <Select value={accountId} onValueChange={setAccountId}>\n <SelectTrigger id=\"funding-account\">\n <SelectValue\n placeholder={translate(\n 'brainyrich.goals.detail.selectAccount',\n 'Select account'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n {accounts.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-mode\">\n {translate('brainyrich.goals.detail.mode', 'Method')}\n </Label>\n <Select\n value={fundingMode}\n onValueChange={(v) => setFundingMode(v as FundingMode)}\n >\n <SelectTrigger id=\"funding-mode\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"PERCENT\">\n {translate('brainyrich.goals.detail.percent', 'Percentage')}\n </SelectItem>\n <SelectItem value=\"FIXED\">\n {translate('brainyrich.goals.detail.fixed', 'Fixed amount')}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"funding-value\">\n {fundingMode === 'PERCENT'\n ? translate('brainyrich.goals.detail.pct', 'Percent')\n : translate('brainyrich.goals.detail.amount', 'Amount')}\n </Label>\n <Input\n id=\"funding-value\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={fundingValue}\n onChange={(e) => setFundingValue(e.target.value)}\n />\n </div>\n </div>\n <Button\n size=\"sm\"\n className=\"w-full\"\n disabled={!linkValid || linkFunding.isPending}\n onClick={handleLink}\n >\n <Link2 className=\"size-4\" aria-hidden=\"true\" />\n {linkFunding.isPending\n ? translate('brainyrich.goals.detail.linking', 'Linking…')\n : translate('brainyrich.goals.detail.link', 'Link funding')}\n </Button>\n </>\n )}\n </section>\n\n {/* Recalc projection */}\n <section className=\"space-y-3 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {translate('brainyrich.goals.detail.recalcTitle', 'Recalculate projection')}\n </h3>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"recalc-funded\">\n {translate('brainyrich.goals.detail.fundedAmount', 'Funded amount')}\n </Label>\n <Input\n id=\"recalc-funded\"\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={fundedAmount}\n placeholder={String(fixedFunded)}\n onChange={(e) => setFundedAmount(e.target.value)}\n />\n <p className=\"text-xs text-text-secondary\">\n {translate(\n 'brainyrich.goals.detail.recalcHint',\n 'Defaults to the sum of fixed fundings when left blank.'\n )}\n </p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"w-full\"\n disabled={recalc.isPending}\n onClick={handleRecalc}\n >\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n {recalc.isPending\n ? translate('brainyrich.goals.detail.recalculating', 'Recalculating…')\n : translate('brainyrich.goals.detail.recalc', 'Recalculate')}\n </Button>\n </section>\n </>\n )}\n </div>\n </SheetContent>\n </Sheet>\n\n <ConfirmDialog\n open={Boolean(unlinking)}\n onOpenChange={(o) => {\n if (!o) setUnlinking(null);\n }}\n title={translate('brainyrich.goals.detail.unlinkTitle', 'Unlink funding?')}\n description={translate(\n 'brainyrich.goals.detail.unlinkConfirm',\n 'This removes the “{name}” funding link from this goal.',\n { name: unlinkingLabel }\n )}\n confirmLabel={translate('brainyrich.goals.detail.unlink', 'Unlink funding')}\n pendingLabel={translate('brainyrich.goals.detail.unlinking', 'Unlinking…')}\n destructive\n pending={unlinkFunding.isPending}\n onConfirm={() => {\n if (!unlinking) return;\n unlinkFunding.mutate(unlinking.id, { onSuccess: () => setUnlinking(null) });\n }}\n />\n </>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"InvestmentsPage.js","names":[],"sources":["../../../src/brainyrich/pages/InvestmentsPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CardDescription,\n Badge,\n Button,\n Input,\n Label,\n Textarea,\n Select,\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n CheckCircle2,\n Gauge,\n Layers,\n PieChart,\n Plus,\n ShieldCheck,\n Trash2,\n X,\n} from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n useModelPortfolios,\n useModelPortfolio,\n useCreateModelPortfolio,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraAssetClass,\n BraRiskProfile,\n BraModelAllocationInput,\n BraModelPortfolio,\n} from '../types/bra';\nimport {\n SectionShell,\n AllocationBars,\n EmptyState,\n LoadingState,\n ErrorState,\n formatDate,\n formatPct,\n statusBadgeVariant,\n type AllocationDatum,\n} from './_shared';\nimport {\n DonutChart,\n StatTile,\n ProgressRing,\n GlassCard,\n FadeIn,\n type DonutDatum,\n type VizTone,\n} from '../components';\n\n// ----------------------------------------------------------------------------\n// Enum option sets (mirror the SDL enums in ../types/bra) + humanizers.\n// No fabricated data: these are the exact allowed input values.\n// ----------------------------------------------------------------------------\n\nconst RISK_PROFILES: BraRiskProfile[] = [\n 'CONSERVATIVE',\n 'MODERATE',\n 'BALANCED',\n 'GROWTH',\n 'AGGRESSIVE',\n];\n\nconst ASSET_CLASSES: BraAssetClass[] = [\n 'EQUITY',\n 'FIXED_INCOME',\n 'CASH',\n 'REAL_ESTATE',\n 'COMMODITY',\n 'CRYPTO',\n 'ALTERNATIVE',\n];\n\n/** Turn an UPPER_SNAKE enum member into a readable label (derived, not invented). */\nfunction humanize(value: string): string {\n return value\n .toLowerCase()\n .split('_')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n}\n\nconst ALLOCATION_TONES: AllocationDatum['tone'][] = [\n 'accent',\n 'default',\n 'positive',\n 'warning',\n 'negative',\n];\n\n/**\n * Stable, distinct viz tone per asset class so the same class reads the same\n * emerald/blue/teal/… hue across every donut on the page. Purely presentational.\n */\nconst ASSET_TONE: Record<BraAssetClass, VizTone> = {\n EQUITY: 'brand',\n FIXED_INCOME: 'blue',\n CASH: 'teal',\n REAL_ESTATE: 'purple',\n COMMODITY: 'warning',\n CRYPTO: 'indigo',\n ALTERNATIVE: 'info',\n};\n\n/** Build tone-mapped donut slices from a set of model allocations (real data only). */\nfunction toDonutData(allocations: { assetClass: BraAssetClass; targetPct: number }[]): DonutDatum[] {\n return allocations\n .filter((a) => Number.isFinite(a.targetPct) && a.targetPct > 0)\n .map((a) => ({\n label: humanize(a.assetClass),\n value: a.targetPct,\n tone: ASSET_TONE[a.assetClass],\n }));\n}\n\n/**\n * Blend the target allocations of a set of models into a single normalised\n * distribution (each asset class = its share of the summed targets). This is a\n * derived aggregate of REAL model data — no fabricated series.\n */\nfunction blendAllocations(models: BraModelPortfolio[]): DonutDatum[] {\n const totals = new Map<BraAssetClass, number>();\n for (const m of models) {\n for (const a of m.allocations) {\n if (!Number.isFinite(a.targetPct) || a.targetPct <= 0) continue;\n totals.set(a.assetClass, (totals.get(a.assetClass) ?? 0) + a.targetPct);\n }\n }\n const grand = Array.from(totals.values()).reduce((s, v) => s + v, 0);\n if (grand <= 0) return [];\n return Array.from(totals.entries())\n .map(([assetClass, sum]) => ({\n label: humanize(assetClass),\n value: (sum / grand) * 100,\n tone: ASSET_TONE[assetClass],\n }))\n .sort((a, b) => b.value - a.value);\n}\n\ninterface AllocationRow {\n assetClass: BraAssetClass;\n targetPct: string;\n}\n\nconst emptyRow = (): AllocationRow => ({ assetClass: 'EQUITY', targetPct: '' });\n\nexport function InvestmentsPage() {\n const { t } = useI18n();\n const translate = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n\n const { data: models, isLoading, isError, refetch } = useModelPortfolios();\n const createModel = useCreateModelPortfolio();\n\n const [createOpen, setCreateOpen] = useState(false);\n const [detailId, setDetailId] = useState<string | null>(null);\n\n // -------- Create form state --------\n const [name, setName] = useState('');\n const [riskProfile, setRiskProfile] = useState<BraRiskProfile>('BALANCED');\n const [baseCurrency, setBaseCurrency] = useState('USD');\n const [description, setDescription] = useState('');\n const [rows, setRows] = useState<AllocationRow[]>([emptyRow()]);\n const [formError, setFormError] = useState<string | null>(null);\n\n const resetForm = () => {\n setName('');\n setRiskProfile('BALANCED');\n setBaseCurrency('USD');\n setDescription('');\n setRows([emptyRow()]);\n setFormError(null);\n };\n\n const allocationSum = useMemo(\n () =>\n rows.reduce(\n (s, r) => s + (Number.isFinite(parseFloat(r.targetPct)) ? parseFloat(r.targetPct) : 0),\n 0\n ),\n [rows]\n );\n\n // Live donut preview built from the current form rows (real, in-progress input).\n const previewDonut = useMemo<DonutDatum[]>(\n () =>\n toDonutData(\n rows.map((r) => ({ assetClass: r.assetClass, targetPct: parseFloat(r.targetPct) }))\n ),\n [rows]\n );\n const sumComplete = Math.abs(allocationSum - 100) <= 0.5;\n\n const updateRow = (index: number, patch: Partial<AllocationRow>) => {\n setRows((prev) => prev.map((r, i) => (i === index ? { ...r, ...patch } : r)));\n };\n const addRow = () => setRows((prev) => [...prev, emptyRow()]);\n const removeRow = (index: number) =>\n setRows((prev) => (prev.length > 1 ? prev.filter((_, i) => i !== index) : prev));\n\n const handleSubmit = () => {\n setFormError(null);\n const trimmedName = name.trim();\n if (!trimmedName) {\n setFormError(translate('brainyrich.investments.form.errorName', 'A model name is required.'));\n return;\n }\n const allocations: BraModelAllocationInput[] = [];\n for (const r of rows) {\n const pct = parseFloat(r.targetPct);\n if (!r.targetPct.trim() || !Number.isFinite(pct)) {\n setFormError(\n translate(\n 'brainyrich.investments.form.errorPct',\n 'Every allocation row needs a numeric target %.'\n )\n );\n return;\n }\n if (pct < 0) {\n setFormError(\n translate('brainyrich.investments.form.errorNegative', 'Target % cannot be negative.')\n );\n return;\n }\n allocations.push({ assetClass: r.assetClass, targetPct: pct });\n }\n if (Math.abs(allocationSum - 100) > 0.5) {\n setFormError(\n translate(\n 'brainyrich.investments.form.errorSum',\n 'Allocation targets must sum to ~100% (currently {sum}%).',\n {\n sum: allocationSum.toFixed(1),\n }\n )\n );\n return;\n }\n\n createModel.mutate(\n {\n name: trimmedName,\n riskProfile,\n baseCurrency: baseCurrency.trim() || 'USD',\n description: description.trim() ? description.trim() : null,\n allocations,\n },\n {\n onSuccess: () => {\n setCreateOpen(false);\n resetForm();\n },\n onError: (err: unknown) => {\n setFormError(\n err instanceof Error\n ? err.message\n : translate('brainyrich.investments.form.errorGeneric', 'Could not create the model.')\n );\n },\n }\n );\n };\n\n const title = translate('brainyrich.investments.title', 'Model Portfolios');\n const description2 = translate(\n 'brainyrich.investments.description',\n 'Reusable target allocations you can benchmark and drive rebalancing against'\n );\n\n const activeModels = models.filter((m) => m.isActive);\n const activeCount = activeModels.length;\n const riskCount = new Set(models.map((m) => m.riskProfile)).size;\n const classCount = new Set(models.flatMap((m) => m.allocations.map((a) => a.assetClass))).size;\n\n // Blended target mix across active models (falls back to all models). Derived\n // from real allocations — a headline aggregate, never fabricated.\n const blendSource = activeModels.length > 0 ? activeModels : models;\n const blended = useMemo(() => blendAllocations(blendSource), [blendSource]);\n\n const statTiles = [\n {\n label: translate('brainyrich.investments.kpi.total', 'Model portfolios'),\n value: String(models.length),\n icon: <Layers className=\"size-4\" aria-hidden=\"true\" />,\n glow: true,\n },\n {\n label: translate('brainyrich.investments.kpi.active', 'Active'),\n value: String(activeCount),\n icon: <CheckCircle2 className=\"size-4\" aria-hidden=\"true\" />,\n glow: false,\n },\n {\n label: translate('brainyrich.investments.kpi.risk', 'Risk profiles'),\n value: String(riskCount),\n icon: <Gauge className=\"size-4\" aria-hidden=\"true\" />,\n glow: false,\n },\n {\n label: translate('brainyrich.investments.kpi.classes', 'Asset classes'),\n value: String(classCount),\n icon: <PieChart className=\"size-4\" aria-hidden=\"true\" />,\n glow: false,\n },\n ];\n\n const newModelLabel = translate('brainyrich.investments.actions.newModel', 'New model');\n\n const renderBody = () => {\n if (isLoading) return <LoadingState rows={4} />;\n if (isError)\n return (\n <ErrorState\n title={translate('brainyrich.investments.error.title', 'Could not load model portfolios')}\n onRetry={() => refetch()}\n />\n );\n if (models.length === 0)\n return (\n <EmptyState\n icon={<PieChart className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.investments.empty.title', 'No model portfolios yet')}\n description={translate(\n 'brainyrich.investments.empty.description',\n 'Create a target allocation model to benchmark portfolios and drive rebalancing.'\n )}\n action={\n <Button size=\"sm\" onClick={() => setCreateOpen(true)}>\n <Plus className=\"mr-1 size-4\" aria-hidden=\"true\" />\n {newModelLabel}\n </Button>\n }\n />\n );\n\n return (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {models.map((m, idx) => {\n const donut = toDonutData(m.allocations);\n const dominant = [...m.allocations].sort((a, b) => b.targetPct - a.targetPct)[0];\n const summary = m.allocations\n .map((a) => `${humanize(a.assetClass)} ${formatPct(a.targetPct, 0)}`)\n .join(' · ');\n return (\n <FadeIn key={m.id} index={idx} className=\"h-full\">\n <Card className=\"group flex h-full flex-col overflow-hidden border-border-subtle bg-bg-surface transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <CardHeader className=\"space-y-2\">\n <div className=\"flex items-start justify-between gap-2\">\n <CardTitle className=\"text-base text-text-primary\">{m.name}</CardTitle>\n <Badge variant={m.isActive ? statusBadgeVariant('ACTIVE') : 'secondary'}>\n <span\n aria-hidden=\"true\"\n className={`mr-1 inline-block size-1.5 rounded-full ${\n m.isActive ? 'bg-status-success-text' : 'bg-text-secondary'\n }`}\n />\n {m.isActive\n ? translate('brainyrich.investments.badge.active', 'Active')\n : translate('brainyrich.investments.badge.inactive', 'Inactive')}\n </Badge>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\" className=\"gap-1\">\n <Gauge className=\"size-3\" aria-hidden=\"true\" />\n {humanize(m.riskProfile)}\n </Badge>\n <Badge variant=\"outline\">{m.baseCurrency}</Badge>\n </div>\n {m.description ? (\n <CardDescription className=\"line-clamp-2 text-text-secondary\">\n {m.description}\n </CardDescription>\n ) : null}\n </CardHeader>\n <CardContent className=\"mt-auto space-y-4\">\n {donut.length > 0 ? (\n <DonutChart\n data={donut}\n height={168}\n centerValue={dominant ? formatPct(dominant.targetPct, 0) : undefined}\n centerLabel={dominant ? humanize(dominant.assetClass) : undefined}\n valueFormatter={(v) => formatPct(v, 0)}\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.investments.card.noAllocations',\n 'No target allocations set.'\n )}\n </p>\n )}\n {summary ? (\n <p className=\"truncate text-xs text-text-secondary\" title={summary}>\n {summary}\n </p>\n ) : null}\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => setDetailId(m.id)}\n >\n {translate('brainyrich.investments.actions.viewDetails', 'View details')}\n </Button>\n </CardContent>\n </Card>\n </FadeIn>\n );\n })}\n </div>\n );\n };\n\n return (\n <>\n <SectionShell\n title={title}\n description={description2}\n actionLabel={newModelLabel}\n onAction={() => setCreateOpen(true)}\n badges={\n !isLoading && !isError\n ? [\n translate('brainyrich.investments.badges.count', '{count} models', {\n count: models.length,\n }),\n ]\n : []\n }\n >\n {!isLoading && !isError && models.length > 0 ? (\n <FadeIn>\n <GlassCard glow className=\"p-5\">\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,0.85fr)_minmax(0,1.15fr)] lg:items-center\">\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <ShieldCheck\n className=\"size-4 text-status-success-text\"\n aria-hidden=\"true\"\n />\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {translate(\n 'brainyrich.investments.hero.blended',\n 'Blended target mix — active models'\n )}\n </p>\n </div>\n {blended.length > 0 ? (\n <DonutChart\n data={blended}\n height={188}\n centerValue={String(activeCount || models.length)}\n centerLabel={translate('brainyrich.investments.hero.models', 'models')}\n valueFormatter={(v) => formatPct(v, 0)}\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.investments.hero.noBlend',\n 'Add target allocations to see the blended mix.'\n )}\n </p>\n )}\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n {statTiles.map((tile) => (\n <StatTile\n key={tile.label}\n label={tile.label}\n value={tile.value}\n icon={tile.icon}\n glow={tile.glow}\n />\n ))}\n </div>\n </div>\n </GlassCard>\n </FadeIn>\n ) : null}\n {renderBody()}\n </SectionShell>\n\n {/* ---------------- Create model dialog ---------------- */}\n <Dialog\n open={createOpen}\n onOpenChange={(open) => {\n setCreateOpen(open);\n if (!open) resetForm();\n }}\n >\n <DialogContent className=\"max-h-[90vh] overflow-y-auto sm:max-w-lg\">\n <DialogHeader>\n <DialogTitle>{newModelLabel}</DialogTitle>\n <DialogDescription>\n {translate(\n 'brainyrich.investments.form.subtitle',\n 'Define a target allocation. Targets should sum to about 100%.'\n )}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-name\">\n {translate('brainyrich.investments.form.name', 'Name')}\n </Label>\n <Input\n id=\"bra-model-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={translate(\n 'brainyrich.investments.form.namePlaceholder',\n 'Balanced Growth 60/40'\n )}\n />\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-risk\">\n {translate('brainyrich.investments.form.risk', 'Risk profile')}\n </Label>\n <Select\n value={riskProfile}\n onValueChange={(v) => setRiskProfile(v as BraRiskProfile)}\n >\n <SelectTrigger id=\"bra-model-risk\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {RISK_PROFILES.map((r) => (\n <SelectItem key={r} value={r}>\n {humanize(r)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-currency\">\n {translate('brainyrich.investments.form.currency', 'Base currency')}\n </Label>\n <Input\n id=\"bra-model-currency\"\n value={baseCurrency}\n onChange={(e) => setBaseCurrency(e.target.value.toUpperCase().slice(0, 3))}\n placeholder=\"USD\"\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-desc\">\n {translate('brainyrich.investments.form.description', 'Description')}\n </Label>\n <Textarea\n id=\"bra-model-desc\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n placeholder={translate(\n 'brainyrich.investments.form.descriptionPlaceholder',\n 'Who this model is for and how it is used'\n )}\n />\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <Label>\n {translate('brainyrich.investments.form.allocations', 'Target allocations')}\n </Label>\n <span\n className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium ${\n sumComplete\n ? 'bg-status-success-bg text-status-success-text'\n : 'bg-status-warning-bg text-status-warning-text'\n }`}\n >\n {sumComplete ? (\n <CheckCircle2 className=\"size-3\" aria-hidden=\"true\" />\n ) : (\n <span aria-hidden=\"true\">▲</span>\n )}\n {translate('brainyrich.investments.form.sum', 'Total: {sum}%', {\n sum: allocationSum.toFixed(allocationSum % 1 === 0 ? 0 : 1),\n })}\n </span>\n </div>\n\n {previewDonut.length > 0 ? (\n <div className=\"flex items-center gap-4 rounded-xl border border-border-subtle bg-bg-sunken/40 p-3\">\n <ProgressRing\n value={Math.min(100, allocationSum)}\n size={76}\n strokeWidth={8}\n tone={sumComplete ? 'success' : 'warning'}\n label={translate('brainyrich.investments.form.of100', 'of 100%')}\n />\n <div className=\"min-w-0 flex-1\">\n <DonutChart\n data={previewDonut}\n height={132}\n legend={false}\n valueFormatter={(v) => formatPct(v, 0)}\n />\n </div>\n </div>\n ) : null}\n\n <div className=\"space-y-2\">\n {rows.map((r, i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <Select\n value={r.assetClass}\n onValueChange={(v) => updateRow(i, { assetClass: v as BraAssetClass })}\n >\n <SelectTrigger className=\"flex-1\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ASSET_CLASSES.map((c) => (\n <SelectItem key={c} value={c}>\n {humanize(c)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Input\n type=\"number\"\n inputMode=\"decimal\"\n min={0}\n max={100}\n step=\"0.1\"\n className=\"w-24\"\n value={r.targetPct}\n onChange={(e) => updateRow(i, { targetPct: e.target.value })}\n placeholder=\"%\"\n aria-label={translate(\n 'brainyrich.investments.form.targetPct',\n 'Target percent'\n )}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => removeRow(i)}\n disabled={rows.length <= 1}\n aria-label={translate(\n 'brainyrich.investments.form.removeRow',\n 'Remove allocation row'\n )}\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </div>\n ))}\n </div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addRow}>\n <Plus className=\"mr-1 size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.investments.form.addRow', 'Add asset class')}\n </Button>\n </div>\n\n {formError ? (\n <p className=\"text-sm text-status-error-text\" role=\"alert\">\n {formError}\n </p>\n ) : null}\n </div>\n\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => {\n setCreateOpen(false);\n resetForm();\n }}\n disabled={createModel.isPending}\n >\n {translate('brainyrich.investments.form.cancel', 'Cancel')}\n </Button>\n <Button onClick={handleSubmit} disabled={createModel.isPending}>\n {createModel.isPending\n ? translate('brainyrich.investments.form.saving', 'Creating…')\n : translate('brainyrich.investments.form.create', 'Create model')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* ---------------- Detail dialog ---------------- */}\n <ModelDetailDialog id={detailId} onClose={() => setDetailId(null)} translate={translate} />\n </>\n );\n}\n\n// ----------------------------------------------------------------------------\n// Detail dialog — reads the single model via useModelPortfolio(id).\n// ----------------------------------------------------------------------------\n\nfunction ModelDetailDialog({\n id,\n onClose,\n translate,\n}: {\n id: string | null;\n onClose: () => void;\n translate: (key: string, fallback: string, params?: Record<string, string | number>) => string;\n}) {\n const { data: model, isLoading, isError, refetch } = useModelPortfolio(id ?? undefined);\n\n const bars: AllocationDatum[] = (model?.allocations ?? []).map((a, i) => ({\n label: humanize(a.assetClass),\n value: a.targetPct,\n tone: ALLOCATION_TONES[i % ALLOCATION_TONES.length],\n }));\n const donut = toDonutData(model?.allocations ?? []);\n const dominant = [...(model?.allocations ?? [])].sort((a, b) => b.targetPct - a.targetPct)[0];\n\n return (\n <Dialog open={Boolean(id)} onOpenChange={(open) => (!open ? onClose() : undefined)}>\n <DialogContent className=\"max-h-[90vh] overflow-y-auto sm:max-w-lg\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center justify-between gap-2 pr-6\">\n {model?.name ?? translate('brainyrich.investments.detail.title', 'Model portfolio')}\n </DialogTitle>\n {model?.description ? <DialogDescription>{model.description}</DialogDescription> : null}\n </DialogHeader>\n\n {isLoading ? (\n <LoadingState rows={3} />\n ) : isError ? (\n <ErrorState\n title={translate('brainyrich.investments.detail.error', 'Could not load this model')}\n onRetry={() => refetch()}\n />\n ) : !model ? (\n <EmptyState\n icon={<X className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.investments.detail.notFound', 'Model not found')}\n />\n ) : (\n <div className=\"space-y-5 py-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant={model.isActive ? statusBadgeVariant('ACTIVE') : 'secondary'}>\n {model.isActive\n ? translate('brainyrich.investments.badge.active', 'Active')\n : translate('brainyrich.investments.badge.inactive', 'Inactive')}\n </Badge>\n <Badge variant=\"outline\">{humanize(model.riskProfile)}</Badge>\n <Badge variant=\"outline\">{model.baseCurrency}</Badge>\n </div>\n\n <div>\n <p className=\"mb-2 text-sm font-medium text-text-primary\">\n {translate('brainyrich.investments.detail.allocations', 'Target allocations')}\n </p>\n {bars.length > 0 ? (\n <div className=\"space-y-4\">\n {donut.length > 0 ? (\n <div className=\"rounded-xl border border-border-subtle bg-bg-sunken/40 p-3\">\n <DonutChart\n data={donut}\n height={180}\n centerValue={dominant ? formatPct(dominant.targetPct, 0) : undefined}\n centerLabel={dominant ? humanize(dominant.assetClass) : undefined}\n valueFormatter={(v) => formatPct(v, 0)}\n />\n </div>\n ) : null}\n <AllocationBars data={bars} />\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.investments.card.noAllocations',\n 'No target allocations set.'\n )}\n </p>\n )}\n </div>\n\n <dl className=\"grid grid-cols-2 gap-4 border-t border-border-subtle pt-4 text-sm\">\n <div>\n <dt className=\"text-text-secondary\">\n {translate('brainyrich.investments.detail.created', 'Created')}\n </dt>\n <dd className=\"text-text-primary\">{formatDate(model.createdAt)}</dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {translate('brainyrich.investments.detail.updated', 'Updated')}\n </dt>\n <dd className=\"text-text-primary\">{formatDate(model.updatedAt)}</dd>\n </div>\n </dl>\n </div>\n )}\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose}>\n {translate('brainyrich.investments.detail.close', 'Close')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"InvestmentsPage.js","names":[],"sources":["../../../src/brainyrich/pages/InvestmentsPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CardDescription,\n Badge,\n Button,\n Input,\n Label,\n Textarea,\n Select,\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { CheckCircle2, Gauge, Layers, PieChart, Plus, ShieldCheck, Trash2, X } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n useModelPortfolios,\n useModelPortfolio,\n useCreateModelPortfolio,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraAssetClass,\n BraRiskProfile,\n BraModelAllocationInput,\n BraModelPortfolio,\n} from '../types/bra';\nimport {\n SectionShell,\n AllocationBars,\n EmptyState,\n LoadingState,\n ErrorState,\n formatDate,\n formatPct,\n statusBadgeVariant,\n type AllocationDatum,\n} from './_shared';\nimport {\n DonutChart,\n StatTile,\n ProgressRing,\n GlassCard,\n FadeIn,\n type DonutDatum,\n type VizTone,\n} from '../components';\n\n// ----------------------------------------------------------------------------\n// Enum option sets (mirror the SDL enums in ../types/bra) + humanizers.\n// No fabricated data: these are the exact allowed input values.\n// ----------------------------------------------------------------------------\n\nconst RISK_PROFILES: BraRiskProfile[] = [\n 'CONSERVATIVE',\n 'MODERATE',\n 'BALANCED',\n 'GROWTH',\n 'AGGRESSIVE',\n];\n\nconst ASSET_CLASSES: BraAssetClass[] = [\n 'EQUITY',\n 'FIXED_INCOME',\n 'CASH',\n 'REAL_ESTATE',\n 'COMMODITY',\n 'CRYPTO',\n 'ALTERNATIVE',\n];\n\n/** Turn an UPPER_SNAKE enum member into a readable label (derived, not invented). */\nfunction humanize(value: string): string {\n return value\n .toLowerCase()\n .split('_')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n}\n\nconst ALLOCATION_TONES: AllocationDatum['tone'][] = [\n 'accent',\n 'default',\n 'positive',\n 'warning',\n 'negative',\n];\n\n/**\n * Stable, distinct viz tone per asset class so the same class reads the same\n * emerald/blue/teal/… hue across every donut on the page. Purely presentational.\n */\nconst ASSET_TONE: Record<BraAssetClass, VizTone> = {\n EQUITY: 'brand',\n FIXED_INCOME: 'blue',\n CASH: 'teal',\n REAL_ESTATE: 'purple',\n COMMODITY: 'warning',\n CRYPTO: 'indigo',\n ALTERNATIVE: 'info',\n};\n\n/** Build tone-mapped donut slices from a set of model allocations (real data only). */\nfunction toDonutData(\n allocations: { assetClass: BraAssetClass; targetPct: number }[]\n): DonutDatum[] {\n return allocations\n .filter((a) => Number.isFinite(a.targetPct) && a.targetPct > 0)\n .map((a) => ({\n label: humanize(a.assetClass),\n value: a.targetPct,\n tone: ASSET_TONE[a.assetClass],\n }));\n}\n\n/**\n * Blend the target allocations of a set of models into a single normalised\n * distribution (each asset class = its share of the summed targets). This is a\n * derived aggregate of REAL model data — no fabricated series.\n */\nfunction blendAllocations(models: BraModelPortfolio[]): DonutDatum[] {\n const totals = new Map<BraAssetClass, number>();\n for (const m of models) {\n for (const a of m.allocations) {\n if (!Number.isFinite(a.targetPct) || a.targetPct <= 0) continue;\n totals.set(a.assetClass, (totals.get(a.assetClass) ?? 0) + a.targetPct);\n }\n }\n const grand = Array.from(totals.values()).reduce((s, v) => s + v, 0);\n if (grand <= 0) return [];\n return Array.from(totals.entries())\n .map(([assetClass, sum]) => ({\n label: humanize(assetClass),\n value: (sum / grand) * 100,\n tone: ASSET_TONE[assetClass],\n }))\n .sort((a, b) => b.value - a.value);\n}\n\ninterface AllocationRow {\n assetClass: BraAssetClass;\n targetPct: string;\n}\n\nconst emptyRow = (): AllocationRow => ({ assetClass: 'EQUITY', targetPct: '' });\n\nexport function InvestmentsPage() {\n const { t } = useI18n();\n const translate = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n\n const { data: models, isLoading, isError, refetch } = useModelPortfolios();\n const createModel = useCreateModelPortfolio();\n\n const [createOpen, setCreateOpen] = useState(false);\n const [detailId, setDetailId] = useState<string | null>(null);\n\n // -------- Create form state --------\n const [name, setName] = useState('');\n const [riskProfile, setRiskProfile] = useState<BraRiskProfile>('BALANCED');\n const [baseCurrency, setBaseCurrency] = useState('USD');\n const [description, setDescription] = useState('');\n const [rows, setRows] = useState<AllocationRow[]>([emptyRow()]);\n const [formError, setFormError] = useState<string | null>(null);\n\n const resetForm = () => {\n setName('');\n setRiskProfile('BALANCED');\n setBaseCurrency('USD');\n setDescription('');\n setRows([emptyRow()]);\n setFormError(null);\n };\n\n const allocationSum = useMemo(\n () =>\n rows.reduce(\n (s, r) => s + (Number.isFinite(parseFloat(r.targetPct)) ? parseFloat(r.targetPct) : 0),\n 0\n ),\n [rows]\n );\n\n // Live donut preview built from the current form rows (real, in-progress input).\n const previewDonut = useMemo<DonutDatum[]>(\n () =>\n toDonutData(\n rows.map((r) => ({ assetClass: r.assetClass, targetPct: parseFloat(r.targetPct) }))\n ),\n [rows]\n );\n const sumComplete = Math.abs(allocationSum - 100) <= 0.5;\n\n const updateRow = (index: number, patch: Partial<AllocationRow>) => {\n setRows((prev) => prev.map((r, i) => (i === index ? { ...r, ...patch } : r)));\n };\n const addRow = () => setRows((prev) => [...prev, emptyRow()]);\n const removeRow = (index: number) =>\n setRows((prev) => (prev.length > 1 ? prev.filter((_, i) => i !== index) : prev));\n\n const handleSubmit = () => {\n setFormError(null);\n const trimmedName = name.trim();\n if (!trimmedName) {\n setFormError(translate('brainyrich.investments.form.errorName', 'A model name is required.'));\n return;\n }\n const allocations: BraModelAllocationInput[] = [];\n for (const r of rows) {\n const pct = parseFloat(r.targetPct);\n if (!r.targetPct.trim() || !Number.isFinite(pct)) {\n setFormError(\n translate(\n 'brainyrich.investments.form.errorPct',\n 'Every allocation row needs a numeric target %.'\n )\n );\n return;\n }\n if (pct < 0) {\n setFormError(\n translate('brainyrich.investments.form.errorNegative', 'Target % cannot be negative.')\n );\n return;\n }\n allocations.push({ assetClass: r.assetClass, targetPct: pct });\n }\n if (Math.abs(allocationSum - 100) > 0.5) {\n setFormError(\n translate(\n 'brainyrich.investments.form.errorSum',\n 'Allocation targets must sum to ~100% (currently {sum}%).',\n {\n sum: allocationSum.toFixed(1),\n }\n )\n );\n return;\n }\n\n createModel.mutate(\n {\n name: trimmedName,\n riskProfile,\n baseCurrency: baseCurrency.trim() || 'USD',\n description: description.trim() ? description.trim() : null,\n allocations,\n },\n {\n onSuccess: () => {\n setCreateOpen(false);\n resetForm();\n },\n onError: (err: unknown) => {\n setFormError(\n err instanceof Error\n ? err.message\n : translate('brainyrich.investments.form.errorGeneric', 'Could not create the model.')\n );\n },\n }\n );\n };\n\n const title = translate('brainyrich.investments.title', 'Model Portfolios');\n const description2 = translate(\n 'brainyrich.investments.description',\n 'Reusable target allocations you can benchmark and drive rebalancing against'\n );\n\n const activeModels = models.filter((m) => m.isActive);\n const activeCount = activeModels.length;\n const riskCount = new Set(models.map((m) => m.riskProfile)).size;\n const classCount = new Set(models.flatMap((m) => m.allocations.map((a) => a.assetClass))).size;\n\n // Blended target mix across active models (falls back to all models). Derived\n // from real allocations — a headline aggregate, never fabricated.\n const blendSource = activeModels.length > 0 ? activeModels : models;\n const blended = useMemo(() => blendAllocations(blendSource), [blendSource]);\n\n const statTiles = [\n {\n label: translate('brainyrich.investments.kpi.total', 'Model portfolios'),\n value: String(models.length),\n icon: <Layers className=\"size-4\" aria-hidden=\"true\" />,\n glow: true,\n },\n {\n label: translate('brainyrich.investments.kpi.active', 'Active'),\n value: String(activeCount),\n icon: <CheckCircle2 className=\"size-4\" aria-hidden=\"true\" />,\n glow: false,\n },\n {\n label: translate('brainyrich.investments.kpi.risk', 'Risk profiles'),\n value: String(riskCount),\n icon: <Gauge className=\"size-4\" aria-hidden=\"true\" />,\n glow: false,\n },\n {\n label: translate('brainyrich.investments.kpi.classes', 'Asset classes'),\n value: String(classCount),\n icon: <PieChart className=\"size-4\" aria-hidden=\"true\" />,\n glow: false,\n },\n ];\n\n const newModelLabel = translate('brainyrich.investments.actions.newModel', 'New model');\n\n const renderBody = () => {\n if (isLoading) return <LoadingState rows={4} />;\n if (isError)\n return (\n <ErrorState\n title={translate('brainyrich.investments.error.title', 'Could not load model portfolios')}\n onRetry={() => refetch()}\n />\n );\n if (models.length === 0)\n return (\n <EmptyState\n icon={<PieChart className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.investments.empty.title', 'No model portfolios yet')}\n description={translate(\n 'brainyrich.investments.empty.description',\n 'Create a target allocation model to benchmark portfolios and drive rebalancing.'\n )}\n action={\n <Button size=\"sm\" onClick={() => setCreateOpen(true)}>\n <Plus className=\"mr-1 size-4\" aria-hidden=\"true\" />\n {newModelLabel}\n </Button>\n }\n />\n );\n\n return (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {models.map((m, idx) => {\n const donut = toDonutData(m.allocations);\n const dominant = [...m.allocations].sort((a, b) => b.targetPct - a.targetPct)[0];\n const summary = m.allocations\n .map((a) => `${humanize(a.assetClass)} ${formatPct(a.targetPct, 0)}`)\n .join(' · ');\n return (\n <FadeIn key={m.id} index={idx} className=\"h-full\">\n <Card className=\"group flex h-full flex-col overflow-hidden border-border-subtle bg-bg-surface transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <CardHeader className=\"space-y-2\">\n <div className=\"flex items-start justify-between gap-2\">\n <CardTitle className=\"text-base text-text-primary\">{m.name}</CardTitle>\n <Badge variant={m.isActive ? statusBadgeVariant('ACTIVE') : 'secondary'}>\n <span\n aria-hidden=\"true\"\n className={`mr-1 inline-block size-1.5 rounded-full ${\n m.isActive ? 'bg-status-success-text' : 'bg-text-secondary'\n }`}\n />\n {m.isActive\n ? translate('brainyrich.investments.badge.active', 'Active')\n : translate('brainyrich.investments.badge.inactive', 'Inactive')}\n </Badge>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\" className=\"gap-1\">\n <Gauge className=\"size-3\" aria-hidden=\"true\" />\n {humanize(m.riskProfile)}\n </Badge>\n <Badge variant=\"outline\">{m.baseCurrency}</Badge>\n </div>\n {m.description ? (\n <CardDescription className=\"line-clamp-2 text-text-secondary\">\n {m.description}\n </CardDescription>\n ) : null}\n </CardHeader>\n <CardContent className=\"mt-auto space-y-4\">\n {donut.length > 0 ? (\n <DonutChart\n data={donut}\n height={168}\n centerValue={dominant ? formatPct(dominant.targetPct, 0) : undefined}\n centerLabel={dominant ? humanize(dominant.assetClass) : undefined}\n valueFormatter={(v) => formatPct(v, 0)}\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.investments.card.noAllocations',\n 'No target allocations set.'\n )}\n </p>\n )}\n {summary ? (\n <p className=\"truncate text-xs text-text-secondary\" title={summary}>\n {summary}\n </p>\n ) : null}\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => setDetailId(m.id)}\n >\n {translate('brainyrich.investments.actions.viewDetails', 'View details')}\n </Button>\n </CardContent>\n </Card>\n </FadeIn>\n );\n })}\n </div>\n );\n };\n\n return (\n <>\n <SectionShell\n title={title}\n description={description2}\n actionLabel={newModelLabel}\n onAction={() => setCreateOpen(true)}\n badges={\n !isLoading && !isError\n ? [\n translate('brainyrich.investments.badges.count', '{count} models', {\n count: models.length,\n }),\n ]\n : []\n }\n >\n {!isLoading && !isError && models.length > 0 ? (\n <FadeIn>\n <GlassCard glow className=\"p-5\">\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,0.85fr)_minmax(0,1.15fr)] lg:items-center\">\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <ShieldCheck className=\"size-4 text-status-success-text\" aria-hidden=\"true\" />\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {translate(\n 'brainyrich.investments.hero.blended',\n 'Blended target mix — active models'\n )}\n </p>\n </div>\n {blended.length > 0 ? (\n <DonutChart\n data={blended}\n height={188}\n centerValue={String(activeCount || models.length)}\n centerLabel={translate('brainyrich.investments.hero.models', 'models')}\n valueFormatter={(v) => formatPct(v, 0)}\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.investments.hero.noBlend',\n 'Add target allocations to see the blended mix.'\n )}\n </p>\n )}\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n {statTiles.map((tile) => (\n <StatTile\n key={tile.label}\n label={tile.label}\n value={tile.value}\n icon={tile.icon}\n glow={tile.glow}\n />\n ))}\n </div>\n </div>\n </GlassCard>\n </FadeIn>\n ) : null}\n {renderBody()}\n </SectionShell>\n\n {/* ---------------- Create model dialog ---------------- */}\n <Dialog\n open={createOpen}\n onOpenChange={(open) => {\n setCreateOpen(open);\n if (!open) resetForm();\n }}\n >\n <DialogContent className=\"max-h-[90vh] overflow-y-auto sm:max-w-lg\">\n <DialogHeader>\n <DialogTitle>{newModelLabel}</DialogTitle>\n <DialogDescription>\n {translate(\n 'brainyrich.investments.form.subtitle',\n 'Define a target allocation. Targets should sum to about 100%.'\n )}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-name\">\n {translate('brainyrich.investments.form.name', 'Name')}\n </Label>\n <Input\n id=\"bra-model-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={translate(\n 'brainyrich.investments.form.namePlaceholder',\n 'Balanced Growth 60/40'\n )}\n />\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-risk\">\n {translate('brainyrich.investments.form.risk', 'Risk profile')}\n </Label>\n <Select\n value={riskProfile}\n onValueChange={(v) => setRiskProfile(v as BraRiskProfile)}\n >\n <SelectTrigger id=\"bra-model-risk\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {RISK_PROFILES.map((r) => (\n <SelectItem key={r} value={r}>\n {humanize(r)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-currency\">\n {translate('brainyrich.investments.form.currency', 'Base currency')}\n </Label>\n <Input\n id=\"bra-model-currency\"\n value={baseCurrency}\n onChange={(e) => setBaseCurrency(e.target.value.toUpperCase().slice(0, 3))}\n placeholder=\"USD\"\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-desc\">\n {translate('brainyrich.investments.form.description', 'Description')}\n </Label>\n <Textarea\n id=\"bra-model-desc\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n placeholder={translate(\n 'brainyrich.investments.form.descriptionPlaceholder',\n 'Who this model is for and how it is used'\n )}\n />\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <Label>\n {translate('brainyrich.investments.form.allocations', 'Target allocations')}\n </Label>\n <span\n className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium ${\n sumComplete\n ? 'bg-status-success-bg text-status-success-text'\n : 'bg-status-warning-bg text-status-warning-text'\n }`}\n >\n {sumComplete ? (\n <CheckCircle2 className=\"size-3\" aria-hidden=\"true\" />\n ) : (\n <span aria-hidden=\"true\">▲</span>\n )}\n {translate('brainyrich.investments.form.sum', 'Total: {sum}%', {\n sum: allocationSum.toFixed(allocationSum % 1 === 0 ? 0 : 1),\n })}\n </span>\n </div>\n\n {previewDonut.length > 0 ? (\n <div className=\"flex items-center gap-4 rounded-xl border border-border-subtle bg-bg-sunken/40 p-3\">\n <ProgressRing\n value={Math.min(100, allocationSum)}\n size={76}\n strokeWidth={8}\n tone={sumComplete ? 'success' : 'warning'}\n label={translate('brainyrich.investments.form.of100', 'of 100%')}\n />\n <div className=\"min-w-0 flex-1\">\n <DonutChart\n data={previewDonut}\n height={132}\n legend={false}\n valueFormatter={(v) => formatPct(v, 0)}\n />\n </div>\n </div>\n ) : null}\n\n <div className=\"space-y-2\">\n {rows.map((r, i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <Select\n value={r.assetClass}\n onValueChange={(v) => updateRow(i, { assetClass: v as BraAssetClass })}\n >\n <SelectTrigger className=\"flex-1\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ASSET_CLASSES.map((c) => (\n <SelectItem key={c} value={c}>\n {humanize(c)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Input\n type=\"number\"\n inputMode=\"decimal\"\n min={0}\n max={100}\n step=\"0.1\"\n className=\"w-24\"\n value={r.targetPct}\n onChange={(e) => updateRow(i, { targetPct: e.target.value })}\n placeholder=\"%\"\n aria-label={translate(\n 'brainyrich.investments.form.targetPct',\n 'Target percent'\n )}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => removeRow(i)}\n disabled={rows.length <= 1}\n aria-label={translate(\n 'brainyrich.investments.form.removeRow',\n 'Remove allocation row'\n )}\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </div>\n ))}\n </div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addRow}>\n <Plus className=\"mr-1 size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.investments.form.addRow', 'Add asset class')}\n </Button>\n </div>\n\n {formError ? (\n <p className=\"text-sm text-status-error-text\" role=\"alert\">\n {formError}\n </p>\n ) : null}\n </div>\n\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => {\n setCreateOpen(false);\n resetForm();\n }}\n disabled={createModel.isPending}\n >\n {translate('brainyrich.investments.form.cancel', 'Cancel')}\n </Button>\n <Button onClick={handleSubmit} disabled={createModel.isPending}>\n {createModel.isPending\n ? translate('brainyrich.investments.form.saving', 'Creating…')\n : translate('brainyrich.investments.form.create', 'Create model')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* ---------------- Detail dialog ---------------- */}\n <ModelDetailDialog id={detailId} onClose={() => setDetailId(null)} translate={translate} />\n </>\n );\n}\n\n// ----------------------------------------------------------------------------\n// Detail dialog — reads the single model via useModelPortfolio(id).\n// ----------------------------------------------------------------------------\n\nfunction ModelDetailDialog({\n id,\n onClose,\n translate,\n}: {\n id: string | null;\n onClose: () => void;\n translate: (key: string, fallback: string, params?: Record<string, string | number>) => string;\n}) {\n const { data: model, isLoading, isError, refetch } = useModelPortfolio(id ?? undefined);\n\n const bars: AllocationDatum[] = (model?.allocations ?? []).map((a, i) => ({\n label: humanize(a.assetClass),\n value: a.targetPct,\n tone: ALLOCATION_TONES[i % ALLOCATION_TONES.length],\n }));\n const donut = toDonutData(model?.allocations ?? []);\n const dominant = [...(model?.allocations ?? [])].sort((a, b) => b.targetPct - a.targetPct)[0];\n\n return (\n <Dialog open={Boolean(id)} onOpenChange={(open) => (!open ? onClose() : undefined)}>\n <DialogContent className=\"max-h-[90vh] overflow-y-auto sm:max-w-lg\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center justify-between gap-2 pr-6\">\n {model?.name ?? translate('brainyrich.investments.detail.title', 'Model portfolio')}\n </DialogTitle>\n {model?.description ? <DialogDescription>{model.description}</DialogDescription> : null}\n </DialogHeader>\n\n {isLoading ? (\n <LoadingState rows={3} />\n ) : isError ? (\n <ErrorState\n title={translate('brainyrich.investments.detail.error', 'Could not load this model')}\n onRetry={() => refetch()}\n />\n ) : !model ? (\n <EmptyState\n icon={<X className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.investments.detail.notFound', 'Model not found')}\n />\n ) : (\n <div className=\"space-y-5 py-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant={model.isActive ? statusBadgeVariant('ACTIVE') : 'secondary'}>\n {model.isActive\n ? translate('brainyrich.investments.badge.active', 'Active')\n : translate('brainyrich.investments.badge.inactive', 'Inactive')}\n </Badge>\n <Badge variant=\"outline\">{humanize(model.riskProfile)}</Badge>\n <Badge variant=\"outline\">{model.baseCurrency}</Badge>\n </div>\n\n <div>\n <p className=\"mb-2 text-sm font-medium text-text-primary\">\n {translate('brainyrich.investments.detail.allocations', 'Target allocations')}\n </p>\n {bars.length > 0 ? (\n <div className=\"space-y-4\">\n {donut.length > 0 ? (\n <div className=\"rounded-xl border border-border-subtle bg-bg-sunken/40 p-3\">\n <DonutChart\n data={donut}\n height={180}\n centerValue={dominant ? formatPct(dominant.targetPct, 0) : undefined}\n centerLabel={dominant ? humanize(dominant.assetClass) : undefined}\n valueFormatter={(v) => formatPct(v, 0)}\n />\n </div>\n ) : null}\n <AllocationBars data={bars} />\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {translate(\n 'brainyrich.investments.card.noAllocations',\n 'No target allocations set.'\n )}\n </p>\n )}\n </div>\n\n <dl className=\"grid grid-cols-2 gap-4 border-t border-border-subtle pt-4 text-sm\">\n <div>\n <dt className=\"text-text-secondary\">\n {translate('brainyrich.investments.detail.created', 'Created')}\n </dt>\n <dd className=\"text-text-primary\">{formatDate(model.createdAt)}</dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {translate('brainyrich.investments.detail.updated', 'Updated')}\n </dt>\n <dd className=\"text-text-primary\">{formatDate(model.updatedAt)}</dd>\n </div>\n </dl>\n </div>\n )}\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose}>\n {translate('brainyrich.investments.detail.close', 'Close')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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"}