xertica-ui 2.4.0 → 2.5.0

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 (559) hide show
  1. package/CHANGELOG.md +621 -564
  2. package/README.md +443 -417
  3. package/assets/xertica-logo.svg +37 -37
  4. package/assets/xertica-x-logo.svg +20 -20
  5. package/bin/cli.ts +1244 -1244
  6. package/bin/generate-tokens.ts +9 -9
  7. package/bin/language-config.ts +358 -358
  8. package/components/assistant/code-block/CodeBlock.tsx +268 -268
  9. package/components/assistant/formatted-document/FormattedDocument.tsx +147 -147
  10. package/components/assistant/modern-chat-input/ModernChatInput.tsx +564 -564
  11. package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +99 -99
  12. package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -104
  13. package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -81
  14. package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +88 -88
  15. package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +75 -75
  16. package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +564 -564
  17. package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +67 -67
  18. package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +103 -103
  19. package/components/assistant/xertica-assistant/use-assistant.ts +615 -615
  20. package/components/assistant/xertica-assistant/xertica-assistant.tsx +611 -611
  21. package/components/blocks/card-patterns/ActivityCard.tsx +100 -100
  22. package/components/blocks/card-patterns/ActivityCardSkeleton.tsx +56 -56
  23. package/components/blocks/card-patterns/FeatureCardSkeleton.tsx +58 -58
  24. package/components/blocks/card-patterns/NotificationCard.tsx +140 -140
  25. package/components/blocks/card-patterns/NotificationCardSkeleton.tsx +81 -81
  26. package/components/blocks/card-patterns/ProfileCard.tsx +112 -112
  27. package/components/blocks/card-patterns/ProfileCardSkeleton.tsx +69 -69
  28. package/components/blocks/card-patterns/ProjectCard.tsx +123 -123
  29. package/components/blocks/card-patterns/ProjectCardSkeleton.tsx +67 -67
  30. package/components/blocks/card-patterns/QuickActionCardSkeleton.tsx +44 -44
  31. package/components/blocks/card-patterns/card-patterns.stories.tsx +594 -594
  32. package/components/blocks/card-patterns/index.ts +29 -29
  33. package/components/brand/language-selector/LanguageSelector.tsx +102 -102
  34. package/components/brand/language-selector/language-selector.stories.tsx +111 -111
  35. package/components/brand/language-selector/language-selector.test.tsx +101 -101
  36. package/components/brand/theme-toggle/ThemeToggle.tsx +74 -74
  37. package/components/brand/xertica-provider/XerticaProvider.tsx +112 -109
  38. package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
  39. package/components/index.ts +86 -86
  40. package/components/layout/sidebar/sidebar.mdx +1 -1
  41. package/components/layout/sidebar/sidebar.stories.tsx +201 -0
  42. package/components/layout/sidebar/sidebar.tsx +1164 -1079
  43. package/components/media/FloatingMediaWrapper.tsx +371 -371
  44. package/components/media/audio-player/AudioPlayer.tsx +768 -768
  45. package/components/media/video-player/VideoPlayer.tsx +310 -310
  46. package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +188 -188
  47. package/components/pages/home-content/HomeContent.tsx +120 -120
  48. package/components/pages/home-content/home-content.mdx +62 -62
  49. package/components/pages/home-page/HomePage.tsx +78 -78
  50. package/components/pages/home-page/home-page.mdx +53 -53
  51. package/components/pages/login-page/LoginPage.tsx +218 -218
  52. package/components/pages/reset-password-page/ResetPasswordPage.tsx +243 -243
  53. package/components/pages/template-content/TemplateContent.tsx +1354 -1354
  54. package/components/pages/template-content/template-content.mdx +61 -61
  55. package/components/pages/template-page/TemplatePage.stories.tsx +8 -15
  56. package/components/pages/template-page/template-page.mdx +53 -53
  57. package/components/pages/verify-email-page/VerifyEmailPage.tsx +206 -206
  58. package/components/shared/error-boundary.stories.tsx +114 -114
  59. package/components/shared/error-boundary.tsx +150 -150
  60. package/components/shared/error-fallbacks.tsx +222 -222
  61. package/components/ui/accordion/accordion.mdx +8 -8
  62. package/components/ui/alert/alert.mdx +8 -8
  63. package/components/ui/alert-dialog/alert-dialog.mdx +8 -8
  64. package/components/ui/aspect-ratio/aspect-ratio.mdx +8 -8
  65. package/components/ui/assistant-chart/assistant-chart.mdx +8 -8
  66. package/components/ui/avatar/avatar.mdx +8 -8
  67. package/components/ui/badge/badge.mdx +8 -8
  68. package/components/ui/breadcrumb/breadcrumb.mdx +8 -8
  69. package/components/ui/button/button.mdx +8 -8
  70. package/components/ui/calendar/calendar.mdx +8 -8
  71. package/components/ui/card/card.mdx +8 -8
  72. package/components/ui/carousel/carousel.mdx +8 -8
  73. package/components/ui/chart/chart.mdx +8 -8
  74. package/components/ui/chart/chart.test.tsx +1 -1
  75. package/components/ui/chart/chart.tsx +13 -6
  76. package/components/ui/checkbox/checkbox.mdx +8 -8
  77. package/components/ui/collapsible/collapsible.mdx +8 -8
  78. package/components/ui/command/command.mdx +8 -8
  79. package/components/ui/context-menu/context-menu.mdx +8 -8
  80. package/components/ui/dialog/dialog.mdx +8 -8
  81. package/components/ui/drawer/drawer.mdx +8 -8
  82. package/components/ui/dropdown-menu/dropdown-menu.mdx +8 -8
  83. package/components/ui/empty/empty.mdx +8 -8
  84. package/components/ui/file-upload/file-upload.mdx +8 -8
  85. package/components/ui/hover-card/hover-card.mdx +8 -8
  86. package/components/ui/input/input.mdx +8 -8
  87. package/components/ui/input-otp/input-otp.mdx +8 -8
  88. package/components/ui/label/label.mdx +8 -8
  89. package/components/ui/map/map.mdx +8 -8
  90. package/components/ui/menubar/menubar.mdx +8 -8
  91. package/components/ui/navigation-menu/navigation-menu.mdx +8 -8
  92. package/components/ui/notification-badge/notification-badge.mdx +8 -8
  93. package/components/ui/pagination/pagination.mdx +8 -8
  94. package/components/ui/popover/popover.mdx +8 -8
  95. package/components/ui/progress/progress.mdx +8 -8
  96. package/components/ui/radio-group/radio-group.mdx +8 -8
  97. package/components/ui/rating/rating.mdx +8 -8
  98. package/components/ui/resizable/resizable.mdx +8 -8
  99. package/components/ui/route-map/route-map.mdx +8 -8
  100. package/components/ui/scroll-area/scroll-area.mdx +8 -8
  101. package/components/ui/search/search.mdx +8 -8
  102. package/components/ui/select/select.mdx +8 -8
  103. package/components/ui/separator/separator.mdx +8 -8
  104. package/components/ui/sheet/sheet.mdx +8 -8
  105. package/components/ui/simple-map/simple-map.mdx +8 -8
  106. package/components/ui/skeleton/skeleton.mdx +8 -8
  107. package/components/ui/slider/slider.mdx +8 -8
  108. package/components/ui/sonner/sonner.mdx +8 -8
  109. package/components/ui/stats-card/index.ts +2 -2
  110. package/components/ui/stats-card/stats-card-skeleton.tsx +60 -60
  111. package/components/ui/stats-card/stats-card.mdx +8 -8
  112. package/components/ui/stats-card/stats-card.stories.tsx +117 -99
  113. package/components/ui/stats-card/stats-card.tsx +18 -2
  114. package/components/ui/stepper/stepper.mdx +8 -8
  115. package/components/ui/switch/switch.mdx +8 -8
  116. package/components/ui/table/table.mdx +8 -8
  117. package/components/ui/tabs/tabs.mdx +8 -8
  118. package/components/ui/textarea/textarea.mdx +8 -8
  119. package/components/ui/timeline/timeline.mdx +8 -8
  120. package/components/ui/toggle/toggle.mdx +8 -8
  121. package/components/ui/toggle-group/toggle-group.mdx +8 -8
  122. package/components/ui/tooltip/tooltip.mdx +8 -8
  123. package/components/ui/tree-view/tree-view.mdx +8 -8
  124. package/components.json +153 -533
  125. package/contexts/AuthContext.tsx +121 -121
  126. package/contexts/BrandColorsContext.tsx +39 -8
  127. package/contexts/LanguageContext.test.tsx +121 -121
  128. package/contexts/LanguageContext.tsx +250 -250
  129. package/contexts/theme-data.ts +51 -0
  130. package/dist/AssistantChart-BKVtGUKF.js +3383 -0
  131. package/dist/AssistantChart-BZTPJ5dP.cjs +3551 -0
  132. package/dist/{AssistantChart-BAx9VQvb.cjs → AssistantChart-Bdd44uBn.cjs} +388 -127
  133. package/dist/{AssistantChart-CVko2A1W.js → AssistantChart-CFhDdGyU.js} +391 -130
  134. package/dist/{AssistantChart-CVzmmhx4.js → AssistantChart-C_hwFRRr.js} +4 -4
  135. package/dist/{AssistantChart-BAudAfne.cjs → AssistantChart-CldVCVDe.cjs} +5 -5
  136. package/dist/{AssistantChart-BP8upjMk.js → AssistantChart-Cu3m7RBo.js} +5 -5
  137. package/dist/AssistantChart-CxGjH7Qk.js +3477 -0
  138. package/dist/AssistantChart-DIpshm3i.js +4784 -0
  139. package/dist/AssistantChart-DMJJ_Amf.js +3383 -0
  140. package/dist/AssistantChart-D_PTeu8P.cjs +3503 -0
  141. package/dist/{AssistantChart-9w31gdAb.cjs → AssistantChart-DoZCyS5r.cjs} +4 -4
  142. package/dist/AssistantChart-WeycT5Pd.cjs +3551 -0
  143. package/dist/AssistantChart-zjsy2GaZ.cjs +4810 -0
  144. package/dist/AudioPlayer-B1lt5cPl.cjs +989 -0
  145. package/dist/AudioPlayer-BZ7bibzU.cjs +982 -0
  146. package/dist/AudioPlayer-BpRPS4-1.cjs +1277 -0
  147. package/dist/AudioPlayer-C12BjQBV.cjs +997 -0
  148. package/dist/{AudioPlayer-1ypwE2Wh.cjs → AudioPlayer-CFeV8t-5.cjs} +1 -1
  149. package/dist/{AudioPlayer-DuKXrCfy.js → AudioPlayer-CGRUtUdN.js} +1 -1
  150. package/dist/AudioPlayer-Coly3q5R.js +1278 -0
  151. package/dist/AudioPlayer-CySJIyvL.js +937 -0
  152. package/dist/AudioPlayer-DMcG_c7L.js +990 -0
  153. package/dist/AudioPlayer-DcFKRJE_.js +998 -0
  154. package/dist/AudioPlayer-IAU5q5T1.cjs +936 -0
  155. package/dist/AudioPlayer-e8LfNoqO.js +983 -0
  156. package/dist/BrandColorsContext-565dDHd5.js +660 -0
  157. package/dist/BrandColorsContext-BMRJ04Wf.js +718 -0
  158. package/dist/BrandColorsContext-BcJbtkqn.cjs +659 -0
  159. package/dist/BrandColorsContext-BwY-b6M4.cjs +725 -0
  160. package/dist/{xertica-assistant-Qp3ydksa.cjs → CodeBlock-7TTgmdGG.cjs} +263 -51
  161. package/dist/{xertica-assistant-gnCJdcZY.js → CodeBlock-BeSt1h5P.js} +219 -7
  162. package/dist/CodeBlock-BgfYL_rD.cjs +2094 -0
  163. package/dist/CodeBlock-BlcqlA9M.cjs +2094 -0
  164. package/dist/CodeBlock-Bnmeu5ez.cjs +2094 -0
  165. package/dist/CodeBlock-BtfPlbAI.js +2078 -0
  166. package/dist/CodeBlock-CIySIuYr.js +2078 -0
  167. package/dist/CodeBlock-CuPtUM-7.cjs +2094 -0
  168. package/dist/CodeBlock-D6ffWXgc.js +2078 -0
  169. package/dist/CodeBlock-D8dcwbit.cjs +2094 -0
  170. package/dist/CodeBlock-DMZrFnlw.cjs +2094 -0
  171. package/dist/CodeBlock-DlBehYN8.js +2078 -0
  172. package/dist/CodeBlock-DnYNI8rQ.js +2078 -0
  173. package/dist/CodeBlock-DvKWbSnE.cjs +2094 -0
  174. package/dist/CodeBlock-DwMCfkFY.js +2078 -0
  175. package/dist/CodeBlock-Dy6CNYyj.js +2078 -0
  176. package/dist/CodeBlock-U1pPOQI7.cjs +2094 -0
  177. package/dist/CodeBlock-f_GpNhEB.js +2078 -0
  178. package/dist/CodeBlock-oB6u8nI1.js +2078 -0
  179. package/dist/CodeBlock-tZC31B73.cjs +2094 -0
  180. package/dist/FeatureCard-CxC-7C-C.cjs +300 -0
  181. package/dist/FeatureCard-DbHWCb4E.js +301 -0
  182. package/dist/ImageWithFallback-CGtidP6B.cjs +4542 -0
  183. package/dist/ImageWithFallback-lsg3pdFg.js +4508 -0
  184. package/dist/{LanguageContext-DvUt5jBg.cjs → LanguageContext-B_KFTCzT.cjs} +2 -2
  185. package/dist/{LanguageContext-BwhwC3G2.js → LanguageContext-CS14yCpi.js} +2 -2
  186. package/dist/{XerticaXLogo-DHz5SugF.js → LanguageSelector-B5YfbHra.js} +115 -136
  187. package/dist/{XerticaXLogo-DTee_y8X.cjs → LanguageSelector-D6uacAIM.cjs} +115 -136
  188. package/dist/LayoutContext-B45-e9DI.cjs +93 -0
  189. package/dist/LayoutContext-BAql6ZRY.js +97 -0
  190. package/dist/LayoutContext-Bav3UMEA.js +94 -0
  191. package/dist/LayoutContext-BvK-ggDa.cjs +96 -0
  192. package/dist/{ThemeContext-Bo-W2WZH.js → ThemeContext-BWq9ACPo.js} +8 -13
  193. package/dist/{ThemeContext-ept8jhXI.js → ThemeContext-BXjrgUjW.js} +261 -200
  194. package/dist/{ThemeContext-BblcjQup.cjs → ThemeContext-Bmod0Cg2.cjs} +8 -13
  195. package/dist/ThemeContext-BoH4NLfN.js +734 -0
  196. package/dist/{ThemeContext-BbBNoFTG.js → ThemeContext-C2EwAPDt.js} +2 -2
  197. package/dist/{ThemeContext-U4dEYc6C.cjs → ThemeContext-CGk3KK0k.cjs} +1 -8
  198. package/dist/{ThemeContext-D3LzacmG.js → ThemeContext-CQSo4Iwc.js} +1 -8
  199. package/dist/{ThemeContext-CP3a0jxy.cjs → ThemeContext-j5aGtPky.cjs} +262 -193
  200. package/dist/ThemeContext-r69W20Xg.cjs +733 -0
  201. package/dist/{ThemeContext-Cmr8Ex8H.cjs → ThemeContext-vTjumZeM.cjs} +2 -2
  202. package/dist/{VerifyEmailPage-BRSP-Pwt.cjs → VerifyEmailPage--1Vurewl.cjs} +3 -3
  203. package/dist/{VerifyEmailPage-CbgjOF0v.js → VerifyEmailPage-1WwWczAn.js} +12 -22
  204. package/dist/{VerifyEmailPage-DF2ilhum.cjs → VerifyEmailPage-B4peJjAT.cjs} +356 -334
  205. package/dist/{VerifyEmailPage-CR7kb5df.cjs → VerifyEmailPage-BComraR7.cjs} +12 -22
  206. package/dist/{VerifyEmailPage-u_Dn7t1U.cjs → VerifyEmailPage-Bp1XXl3H.cjs} +4 -4
  207. package/dist/{VerifyEmailPage-CkBYfsNy.cjs → VerifyEmailPage-By3Jf__L.cjs} +4 -4
  208. package/dist/{VerifyEmailPage-Bv8Ah_TK.cjs → VerifyEmailPage-ByerOcm4.cjs} +20 -23
  209. package/dist/{VerifyEmailPage-BE-L9mB7.js → VerifyEmailPage-C0c2e5n0.js} +7 -7
  210. package/dist/{VerifyEmailPage-EhudUdqF.js → VerifyEmailPage-C5TNQTBa.js} +355 -343
  211. package/dist/{VerifyEmailPage-Dt7zgA4w.cjs → VerifyEmailPage-CFLMls1p.cjs} +4 -4
  212. package/dist/{VerifyEmailPage-Bvfv8HVQ.js → VerifyEmailPage-CGIwmWrm.js} +461 -379
  213. package/dist/{VerifyEmailPage-Cyl55sJb.js → VerifyEmailPage-CJLz3jrn.js} +20 -23
  214. package/dist/VerifyEmailPage-COiyNl1y.js +2825 -0
  215. package/dist/{VerifyEmailPage-DMBh4NM9.cjs → VerifyEmailPage-CYXtbKi3.cjs} +1 -1
  216. package/dist/{VerifyEmailPage-DTtFfC-J.js → VerifyEmailPage-CgMxRb4z.js} +3 -3
  217. package/dist/VerifyEmailPage-CpqqpLpo.cjs +3305 -0
  218. package/dist/VerifyEmailPage-CqKsR2v8.js +2827 -0
  219. package/dist/{VerifyEmailPage-Bae2cBXT.cjs → VerifyEmailPage-Cwi3kbol.cjs} +7 -7
  220. package/dist/{VerifyEmailPage-X14vhdyl.js → VerifyEmailPage-DGhuIqkb.js} +4 -4
  221. package/dist/{VerifyEmailPage-BIBOKV7Z.js → VerifyEmailPage-DSBMRHtl.js} +36 -41
  222. package/dist/{VerifyEmailPage-D-FRj5TU.cjs → VerifyEmailPage-De6bQjrz.cjs} +36 -41
  223. package/dist/{VerifyEmailPage-BJjAMUTW.js → VerifyEmailPage-DgIid028.js} +4 -4
  224. package/dist/VerifyEmailPage-DjQKRlUS.cjs +2824 -0
  225. package/dist/{VerifyEmailPage-CdYPSJoO.js → VerifyEmailPage-DvMLZgFt.js} +1 -1
  226. package/dist/{VerifyEmailPage-C_ihbcth.js → VerifyEmailPage-MTD7AG1Z.js} +4 -4
  227. package/dist/VerifyEmailPage-s-1X3LDJ.cjs +2826 -0
  228. package/dist/XerticaOrbe-KL1RBHzw.cjs +1354 -0
  229. package/dist/XerticaOrbe-zwS1p2a8.js +1355 -0
  230. package/dist/XerticaProvider-6btlAlzc.js +17 -0
  231. package/dist/{XerticaProvider-siSt9uG2.js → XerticaProvider-B7EVH-NF.js} +2 -2
  232. package/dist/{XerticaProvider-AbWlr7Af.cjs → XerticaProvider-BIrqfZ-i.cjs} +11 -8
  233. package/dist/XerticaProvider-BNoNOxQ5.cjs +16 -0
  234. package/dist/XerticaProvider-BlY2limY.cjs +38 -0
  235. package/dist/{XerticaProvider-CWgby5mY.js → XerticaProvider-C1DKnvLh.js} +4 -4
  236. package/dist/{XerticaProvider-AChwphCO.cjs → XerticaProvider-CBGc4EMA.cjs} +4 -4
  237. package/dist/{XerticaProvider-BITjgC5p.js → XerticaProvider-CEoWMTxu.js} +2 -2
  238. package/dist/XerticaProvider-CeS5G_n5.cjs +45 -0
  239. package/dist/{XerticaProvider-By8q3Roe.cjs → XerticaProvider-CllrbMEJ.cjs} +2 -2
  240. package/dist/{XerticaProvider-B8CaV7xu.cjs → XerticaProvider-D-yNhF94.cjs} +1 -1
  241. package/dist/XerticaProvider-DDuiIcKo.js +39 -0
  242. package/dist/{XerticaProvider-DQtvJU7m.js → XerticaProvider-DYq4JWtg.js} +1 -1
  243. package/dist/{XerticaProvider-CWs6EwNa.js → XerticaProvider-Dt5HEzbQ.js} +10 -10
  244. package/dist/{XerticaProvider-CW9hpCdF.cjs → XerticaProvider-ET0ihewn.cjs} +2 -2
  245. package/dist/XerticaProvider-cI9hSs27.cjs +38 -0
  246. package/dist/XerticaProvider-hSwhNQex.js +39 -0
  247. package/dist/XerticaProvider-ra2NciRq.js +43 -0
  248. package/dist/{XerticaXLogo-ChryA6xj.js → XerticaXLogo-B7xQ5dhi.js} +1 -1
  249. package/dist/{XerticaXLogo-CziKMQil.cjs → XerticaXLogo-CQUUjXoH.cjs} +8 -8
  250. package/dist/{XerticaXLogo-DfUvz-lD.js → XerticaXLogo-Cmsp-Eey.js} +9 -9
  251. package/dist/{XerticaXLogo-CFuIlYFH.js → XerticaXLogo-DZbo4vOE.js} +12 -12
  252. package/dist/{XerticaXLogo-8TTzBjHw.cjs → XerticaXLogo-Zw2B276b.cjs} +1 -1
  253. package/dist/{XerticaXLogo-kslQ8Tk_.cjs → XerticaXLogo-bvZSgwGF.cjs} +13 -7
  254. package/dist/alert-dialog-BOje--vD.js +847 -0
  255. package/dist/alert-dialog-BtEuQqrg.cjs +870 -0
  256. package/dist/{alert-dialog-yckpaOpy.cjs → alert-dialog-DSKByiKZ.cjs} +3 -3
  257. package/dist/{alert-dialog-iDe5VE5o.js → alert-dialog-s-vmNkJ_.js} +3 -3
  258. package/dist/assistant.cjs.js +1 -1
  259. package/dist/assistant.es.js +1 -1
  260. package/dist/brand.cjs.js +1 -1
  261. package/dist/brand.es.js +1 -1
  262. package/dist/breadcrumb-CqJ7bHY5.js +161 -0
  263. package/dist/breadcrumb-m9Hb2_XN.cjs +177 -0
  264. package/dist/cli.js +45 -9
  265. package/dist/components/assistant/xertica-assistant/hooks/index.d.ts +6 -0
  266. package/dist/components/assistant/xertica-assistant/hooks/use-assistant-conversations.d.ts +21 -0
  267. package/dist/components/assistant/xertica-assistant/hooks/use-assistant-messages.d.ts +49 -0
  268. package/dist/components/assistant/xertica-assistant/hooks/use-assistant-suggestions.d.ts +16 -0
  269. package/dist/components/blocks/audio-player/AudioPlayer.d.ts +35 -0
  270. package/dist/components/blocks/audio-player/index.d.ts +1 -0
  271. package/dist/components/blocks/document-editor/DocumentEditor.d.ts +26 -0
  272. package/dist/components/blocks/document-editor/index.d.ts +1 -0
  273. package/dist/components/blocks/podcast-player/PodcastPlayer.d.ts +41 -0
  274. package/dist/components/blocks/podcast-player/index.d.ts +1 -0
  275. package/dist/components/brand/xertica-provider/XerticaProvider.d.ts +3 -1
  276. package/dist/components/ui/chart/chart.d.ts +12 -3
  277. package/dist/components/ui/chart/parts/chart-dashboard.d.ts +113 -0
  278. package/dist/components/ui/chart/parts/chart-metric.d.ts +118 -0
  279. package/dist/components/ui/chart/parts/chart-primitives.d.ts +101 -0
  280. package/dist/components/ui/chart/parts/chart-shared.d.ts +20 -0
  281. package/dist/components/ui/chart/parts/chart-utils.d.ts +12 -0
  282. package/dist/components/ui/chart/parts/index.d.ts +5 -0
  283. package/dist/components/ui/stats-card/stats-card.d.ts +10 -0
  284. package/dist/contexts/theme-data.d.ts +4 -0
  285. package/dist/dropdown-menu-BDB5CmQs.cjs +247 -0
  286. package/dist/dropdown-menu-DQidbKBD.js +231 -0
  287. package/dist/google-maps-loader-BFWp6VPd.js +287 -0
  288. package/dist/google-maps-loader-BKcdgFbu.cjs +312 -0
  289. package/dist/{google-maps-loader-t2IlYBzw.js → google-maps-loader-CTYySAun.js} +4 -0
  290. package/dist/google-maps-loader-CumCNXeG.js +312 -0
  291. package/dist/{google-maps-loader-BqsYL48U.cjs → google-maps-loader-Y-QkD-Li.cjs} +5 -0
  292. package/dist/google-maps-loader-eS3uQ5TA.cjs +287 -0
  293. package/dist/header-Cgy6vYPk.cjs +731 -0
  294. package/dist/header-DRlT4jgI.js +715 -0
  295. package/dist/header-Dux00SI4.cjs +731 -0
  296. package/dist/header-EkGKXPsD.js +715 -0
  297. package/dist/header-WfEywpyc.cjs +731 -0
  298. package/dist/header-tifNQn2U.js +715 -0
  299. package/dist/hooks.cjs.js +1 -1
  300. package/dist/hooks.es.js +1 -1
  301. package/dist/index-BhapVLVj.js +8 -0
  302. package/dist/{index-D3RLKRAs.cjs → index-COtD8bRW.cjs} +1 -1
  303. package/dist/index-D6fxYEY8.cjs +7 -0
  304. package/dist/index-DAIp0_HK.js +8 -0
  305. package/dist/index-DW5tYe26.js +8 -0
  306. package/dist/index-GA__GvnG.cjs +7 -0
  307. package/dist/index.cjs.js +6 -6
  308. package/dist/index.es.js +6 -6
  309. package/dist/index.umd.js +1043 -470
  310. package/dist/input-2R4loU86.js +127 -0
  311. package/dist/input-DWANSKGb.cjs +145 -0
  312. package/dist/layout.cjs.js +1 -1
  313. package/dist/layout.es.js +1 -1
  314. package/dist/pages.cjs.js +1 -1
  315. package/dist/pages.es.js +1 -1
  316. package/dist/progress-DPtzoVV8.js +175 -0
  317. package/dist/progress-EeaoqqUs.cjs +191 -0
  318. package/dist/rich-text-editor-0mraWT5y.cjs +2376 -0
  319. package/dist/rich-text-editor-B-IkcPD0.js +2874 -0
  320. package/dist/rich-text-editor-B2CKz7nx.cjs +2903 -0
  321. package/dist/rich-text-editor-B6jMRLzk.cjs +1939 -0
  322. package/dist/rich-text-editor-B8_oYcIR.js +1730 -0
  323. package/dist/rich-text-editor-B9UbSXNb.js +1203 -0
  324. package/dist/rich-text-editor-BYuRBNBU.js +2373 -0
  325. package/dist/rich-text-editor-Bb9pySTs.cjs +2374 -0
  326. package/dist/rich-text-editor-BcL6L3cm.cjs +2374 -0
  327. package/dist/rich-text-editor-BoVZYtTs.cjs +2391 -0
  328. package/dist/rich-text-editor-Bp3zQqMC.js +2954 -0
  329. package/dist/rich-text-editor-CMgSN_w2.js +1189 -0
  330. package/dist/rich-text-editor-CPV1lEPH.cjs +1748 -0
  331. package/dist/rich-text-editor-CeucBdIv.cjs +2971 -0
  332. package/dist/rich-text-editor-CoKqbCtu.cjs +1799 -0
  333. package/dist/rich-text-editor-Cw56T_mB.js +2356 -0
  334. package/dist/rich-text-editor-Cyt8qs2b.js +1921 -0
  335. package/dist/rich-text-editor-D6H84OcX.cjs +1220 -0
  336. package/dist/rich-text-editor-D76gD-QI.js +2328 -0
  337. package/dist/rich-text-editor-DKkokOnA.js +1781 -0
  338. package/dist/rich-text-editor-DNsdpN64.cjs +2359 -0
  339. package/dist/rich-text-editor-DfG8bCyY.js +2358 -0
  340. package/dist/rich-text-editor-DloeW0wc.js +2832 -0
  341. package/dist/rich-text-editor-Dxjw31Z4.js +2341 -0
  342. package/dist/rich-text-editor-DzP0Epmb.js +2356 -0
  343. package/dist/rich-text-editor-bRkNoeZY.cjs +2891 -0
  344. package/dist/rich-text-editor-lyYE2ZG5.cjs +1207 -0
  345. package/dist/rich-text-editor-skplNlBM.cjs +2345 -0
  346. package/dist/select-Bkbr0f-Z.cjs +162 -0
  347. package/dist/select-CvIVdX2n.js +145 -0
  348. package/dist/{sidebar-CplprZpM.js → sidebar-0ocFLSks.js} +127 -50
  349. package/dist/{sidebar-CA6_ek3f.js → sidebar-B6SlKZYN.js} +40 -49
  350. package/dist/{sidebar-CmvwjnVb.js → sidebar-BViy8Eeu.js} +17 -9
  351. package/dist/{sidebar-Dz7bd3zP.js → sidebar-BbVIQvlP.js} +1 -1
  352. package/dist/{sidebar-CVUGHOS_.cjs → sidebar-BxGXsDAd.cjs} +16 -8
  353. package/dist/sidebar-CK_0ZQHj.cjs +803 -0
  354. package/dist/sidebar-CUuOvYhK.js +787 -0
  355. package/dist/{sidebar-B3EYhli0.cjs → sidebar-CeTMuzOx.cjs} +128 -47
  356. package/dist/{sidebar-KIS0C2JH.js → sidebar-CrQDDdcz.js} +24 -33
  357. package/dist/{sidebar-zowjejT2.cjs → sidebar-DAaY8bRU.cjs} +24 -33
  358. package/dist/{sidebar-B9NR0lCe.cjs → sidebar-DQj1z3jG.cjs} +227 -269
  359. package/dist/sidebar-Djn5syhi.cjs +786 -0
  360. package/dist/sidebar-LluMXfam.js +759 -0
  361. package/dist/sidebar-_rT7rBMk.js +787 -0
  362. package/dist/{sidebar-BvF5I2Ue.cjs → sidebar-nzPoVHBQ.cjs} +41 -46
  363. package/dist/{sidebar-C5B_LHek.cjs → sidebar-q7P2Godd.cjs} +1 -1
  364. package/dist/slider-Bc5Hd0y1.js +56 -0
  365. package/dist/slider-N7hFFj6X.cjs +73 -0
  366. package/dist/tooltip-Ded96neP.cjs +137 -0
  367. package/dist/tooltip-HDOoD2-0.js +120 -0
  368. package/dist/ui.cjs.js +2 -2
  369. package/dist/ui.es.js +2 -2
  370. package/dist/use-audio-player-B31J-aqh.cjs +187 -0
  371. package/dist/use-audio-player-BkmEmj8Q.js +185 -0
  372. package/dist/use-audio-player-CLFTWFW1.cjs +184 -0
  373. package/dist/use-audio-player-CLLn00I6.js +188 -0
  374. package/dist/{use-audio-player-Dn1NR9xN.cjs → use-audio-player-NKsWyjWu.cjs} +7 -3
  375. package/dist/{use-audio-player-Bkh23vQ3.js → use-audio-player-nv8ZSGa1.js} +7 -3
  376. package/dist/use-file-upload-BcjEo2S5.js +404 -0
  377. package/dist/use-file-upload-CRJR68Tj.cjs +403 -0
  378. package/dist/use-mobile-B0hNy_Y6.cjs +4303 -0
  379. package/dist/use-mobile-BXuYROXM.js +4202 -0
  380. package/dist/use-mobile-Bbd51ASU.cjs +4392 -0
  381. package/dist/use-mobile-Bk6CX-TC.js +4359 -0
  382. package/dist/use-mobile-BvYdisLP.js +4202 -0
  383. package/dist/use-mobile-BzuxjzNX.cjs +4392 -0
  384. package/dist/use-mobile-CG2-SdXV.cjs +4235 -0
  385. package/dist/use-mobile-CKb5pqTs.js +4269 -0
  386. package/dist/use-mobile-CYuAuGDl.js +4202 -0
  387. package/dist/use-mobile-CaENcqm-.js +4508 -0
  388. package/dist/use-mobile-CbrYgJGJ.js +4203 -0
  389. package/dist/use-mobile-Cd4xPrKq.cjs +46 -0
  390. package/dist/use-mobile-DMOvImGQ.cjs +4542 -0
  391. package/dist/use-mobile-DRB3BQgD.cjs +4235 -0
  392. package/dist/use-mobile-DZvv7QMR.js +4359 -0
  393. package/dist/use-mobile-DdI_TXam.cjs +4235 -0
  394. package/dist/use-mobile-DlceKf8a.js +4359 -0
  395. package/dist/use-mobile-DsOnow1o.cjs +4236 -0
  396. package/dist/use-mobile-Kcj6jSnK.cjs +4392 -0
  397. package/dist/use-mobile-bnKcua_i.js +4202 -0
  398. package/dist/use-mobile-j4w2Jrf1.js +30 -0
  399. package/dist/use-mobile-ncXBeE2z.cjs +4235 -0
  400. package/dist/use-rich-text-editor-DjiddBGv.js +282 -0
  401. package/dist/use-rich-text-editor-lpeswbCs.cjs +281 -0
  402. package/dist/xertica-assistant-BdiZag0h.js +2187 -0
  403. package/dist/xertica-assistant-CrgTb6Hs.cjs +2155 -0
  404. package/dist/xertica-assistant-CyikE3N_.js +2173 -0
  405. package/dist/xertica-assistant-DCsnQyi5.js +2156 -0
  406. package/dist/xertica-assistant-DUBpmEgo.cjs +2186 -0
  407. package/dist/xertica-assistant-QFUnv5I2.cjs +2180 -0
  408. package/dist/{xertica-assistant-Bj3vBCq_.cjs → xertica-assistant-V_IdW4WF.cjs} +27 -9
  409. package/dist/{xertica-assistant-BMqdyRVi.js → xertica-assistant-ciJaWqm1.js} +28 -10
  410. package/dist/{xertica-assistant-B1IaHXnB.cjs → xertica-assistant-dyP7KHM5.cjs} +533 -392
  411. package/dist/{xertica-assistant-DPsESB6t.js → xertica-assistant-yX1CFBBo.js} +535 -394
  412. package/dist/xertica-ui.css +2 -2
  413. package/docs/architecture-improvements.md +456 -456
  414. package/docs/architecture.md +312 -312
  415. package/docs/components/assistant.md +428 -428
  416. package/docs/components/branding.md +252 -252
  417. package/docs/components/card-patterns.md +447 -447
  418. package/docs/components/error-boundary.md +201 -201
  419. package/docs/components/hooks.md +432 -432
  420. package/docs/components/language-selector.md +176 -176
  421. package/docs/components/pages.md +323 -323
  422. package/docs/components/sidebar.md +19 -2
  423. package/docs/components/stats-card.md +20 -2
  424. package/docs/doc-audit.md +244 -244
  425. package/docs/getting-started.md +616 -616
  426. package/docs/guidelines.md +330 -330
  427. package/docs/i18n.md +480 -480
  428. package/docs/installation.md +268 -268
  429. package/docs/llms.md +295 -295
  430. package/docs/state-management.md +289 -289
  431. package/guidelines/Guidelines.md +409 -409
  432. package/llms-compact.txt +30 -1
  433. package/llms-full.txt +11553 -7133
  434. package/llms.txt +1 -1
  435. package/package.json +219 -219
  436. package/styles/xertica/base.css +90 -90
  437. package/styles/xertica/tokens.css +9 -9
  438. package/templates/.prettierignore +4 -4
  439. package/templates/.prettierrc +10 -10
  440. package/templates/CLAUDE.md +180 -180
  441. package/templates/guidelines/Guidelines.md +865 -577
  442. package/templates/package.json +69 -69
  443. package/templates/src/app/App.tsx +46 -46
  444. package/templates/src/app/components/AuthGuard.tsx +131 -131
  445. package/templates/src/features/assistant/data/mock.ts +75 -75
  446. package/templates/src/features/assistant/hooks/useAssistantConfig.ts +20 -20
  447. package/templates/src/features/assistant/index.ts +5 -5
  448. package/templates/src/features/auth/ui/AuthPageShell.tsx +32 -32
  449. package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -70
  450. package/templates/src/features/auth/ui/LoginContent.tsx +92 -92
  451. package/templates/src/features/auth/ui/ResetPasswordContent.tsx +183 -183
  452. package/templates/src/features/auth/ui/SocialLoginButtons.tsx +78 -78
  453. package/templates/src/features/auth/ui/VerifyEmailContent.tsx +80 -80
  454. package/templates/src/features/home/data/mock.ts +41 -41
  455. package/templates/src/features/home/hooks/useFeatureCards.ts +20 -20
  456. package/templates/src/features/home/index.ts +11 -11
  457. package/templates/src/features/home/ui/HomeContent.tsx +117 -117
  458. package/templates/src/features/template/ui/CrudTemplate.tsx +112 -112
  459. package/templates/src/features/template/ui/DashboardTemplate.tsx +110 -110
  460. package/templates/src/features/template/ui/FormTemplate.tsx +117 -117
  461. package/templates/src/features/template/ui/LoginTemplate.tsx +59 -59
  462. package/templates/src/features/template/ui/TemplateContent.tsx +1322 -1322
  463. package/templates/src/i18n.ts +124 -124
  464. package/templates/src/locales/en/common.json +21 -21
  465. package/templates/src/locales/en/components/activityCard.json +10 -10
  466. package/templates/src/locales/en/components/assistant.json +119 -119
  467. package/templates/src/locales/en/components/media.json +29 -29
  468. package/templates/src/locales/en/components/notificationCard.json +5 -5
  469. package/templates/src/locales/en/components/profileCard.json +8 -8
  470. package/templates/src/locales/en/components/projectCard.json +10 -10
  471. package/templates/src/locales/en/components/sidebar.json +14 -14
  472. package/templates/src/locales/en/components/stats.json +8 -8
  473. package/templates/src/locales/en/components/team.json +14 -14
  474. package/templates/src/locales/en/errors.json +9 -9
  475. package/templates/src/locales/en/languageSelector.json +7 -7
  476. package/templates/src/locales/en/nav.json +6 -6
  477. package/templates/src/locales/en/pages/crudTemplate.json +25 -25
  478. package/templates/src/locales/en/pages/dashboardTemplate.json +20 -20
  479. package/templates/src/locales/en/pages/forgotPassword.json +10 -10
  480. package/templates/src/locales/en/pages/formTemplate.json +16 -16
  481. package/templates/src/locales/en/pages/home.json +7 -7
  482. package/templates/src/locales/en/pages/login.json +15 -15
  483. package/templates/src/locales/en/pages/loginTemplate.json +9 -9
  484. package/templates/src/locales/en/pages/resetPassword.json +18 -18
  485. package/templates/src/locales/en/pages/templates.json +317 -317
  486. package/templates/src/locales/en/pages/verifyEmail.json +12 -12
  487. package/templates/src/locales/en/themeToggle.json +6 -6
  488. package/templates/src/locales/es/common.json +21 -21
  489. package/templates/src/locales/es/components/activityCard.json +10 -10
  490. package/templates/src/locales/es/components/assistant.json +119 -119
  491. package/templates/src/locales/es/components/media.json +29 -29
  492. package/templates/src/locales/es/components/notificationCard.json +5 -5
  493. package/templates/src/locales/es/components/profileCard.json +8 -8
  494. package/templates/src/locales/es/components/projectCard.json +10 -10
  495. package/templates/src/locales/es/components/sidebar.json +14 -14
  496. package/templates/src/locales/es/components/stats.json +8 -8
  497. package/templates/src/locales/es/components/team.json +14 -14
  498. package/templates/src/locales/es/errors.json +9 -9
  499. package/templates/src/locales/es/languageSelector.json +7 -7
  500. package/templates/src/locales/es/nav.json +6 -6
  501. package/templates/src/locales/es/pages/crudTemplate.json +25 -25
  502. package/templates/src/locales/es/pages/dashboardTemplate.json +20 -20
  503. package/templates/src/locales/es/pages/forgotPassword.json +10 -10
  504. package/templates/src/locales/es/pages/formTemplate.json +16 -16
  505. package/templates/src/locales/es/pages/home.json +7 -7
  506. package/templates/src/locales/es/pages/login.json +15 -15
  507. package/templates/src/locales/es/pages/loginTemplate.json +9 -9
  508. package/templates/src/locales/es/pages/resetPassword.json +18 -18
  509. package/templates/src/locales/es/pages/templates.json +317 -317
  510. package/templates/src/locales/es/pages/verifyEmail.json +12 -12
  511. package/templates/src/locales/es/themeToggle.json +6 -6
  512. package/templates/src/locales/pt-BR/common.json +21 -21
  513. package/templates/src/locales/pt-BR/components/activityCard.json +10 -10
  514. package/templates/src/locales/pt-BR/components/assistant.json +119 -119
  515. package/templates/src/locales/pt-BR/components/media.json +29 -29
  516. package/templates/src/locales/pt-BR/components/notificationCard.json +5 -5
  517. package/templates/src/locales/pt-BR/components/profileCard.json +8 -8
  518. package/templates/src/locales/pt-BR/components/projectCard.json +10 -10
  519. package/templates/src/locales/pt-BR/components/sidebar.json +14 -14
  520. package/templates/src/locales/pt-BR/components/stats.json +8 -8
  521. package/templates/src/locales/pt-BR/components/team.json +14 -14
  522. package/templates/src/locales/pt-BR/errors.json +9 -9
  523. package/templates/src/locales/pt-BR/languageSelector.json +7 -7
  524. package/templates/src/locales/pt-BR/nav.json +6 -6
  525. package/templates/src/locales/pt-BR/pages/crudTemplate.json +25 -25
  526. package/templates/src/locales/pt-BR/pages/dashboardTemplate.json +20 -20
  527. package/templates/src/locales/pt-BR/pages/forgotPassword.json +10 -10
  528. package/templates/src/locales/pt-BR/pages/formTemplate.json +16 -16
  529. package/templates/src/locales/pt-BR/pages/home.json +7 -7
  530. package/templates/src/locales/pt-BR/pages/login.json +15 -15
  531. package/templates/src/locales/pt-BR/pages/loginTemplate.json +9 -9
  532. package/templates/src/locales/pt-BR/pages/resetPassword.json +18 -18
  533. package/templates/src/locales/pt-BR/pages/templates.json +317 -317
  534. package/templates/src/locales/pt-BR/pages/verifyEmail.json +12 -12
  535. package/templates/src/locales/pt-BR/themeToggle.json +6 -6
  536. package/templates/src/pages/AssistantPage.tsx +470 -470
  537. package/templates/src/pages/HomePage.tsx +53 -53
  538. package/templates/src/shared/error-boundary.tsx +150 -150
  539. package/templates/src/shared/error-fallbacks.tsx +222 -222
  540. package/templates/src/styles/xertica/tokens.css +9 -9
  541. package/templates/vite.config.js +20 -20
  542. package/templates/vite.config.ts +55 -55
  543. package/dist/ThemeContext-CpqYShLq.cjs +0 -324
  544. package/dist/ThemeContext-Du2nE1PL.js +0 -325
  545. package/dist/ThemeContext-GeEBTJ3q.cjs +0 -1621
  546. package/dist/ThemeContext-JyLK9B1o.js +0 -1622
  547. package/dist/VerifyEmailPage-BiRm7Nh4.cjs +0 -3213
  548. package/dist/VerifyEmailPage-hdB8JQGv.cjs +0 -3213
  549. package/dist/VerifyEmailPage-vYHbYK3q.js +0 -3214
  550. package/dist/XerticaProvider-CUYJZc32.js +0 -49
  551. package/dist/XerticaProvider-CjQAQPcn.cjs +0 -48
  552. package/dist/XerticaProvider-D5lLumH-.js +0 -49
  553. package/dist/XerticaProvider-qQUDop71.cjs +0 -48
  554. package/dist/XerticaXLogo-BWaag64t.js +0 -252
  555. package/dist/XerticaXLogo-CU-U-GP4.cjs +0 -251
  556. package/dist/index-CkTUgOwX.js +0 -8
  557. package/dist/sidebar-OTO_up7Z.js +0 -801
  558. package/dist/{rich-text-editor-BmsjY03B.js → rich-text-editor-DgF8s7xW.js} +26 -26
  559. package/dist/{rich-text-editor-GS2kpTAK.cjs → rich-text-editor-mWoaSCE4.cjs} +26 -26
@@ -1,121 +1,121 @@
1
- import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
2
- import { useNavigate } from 'react-router-dom';
3
-
4
- // ─────────────────────────────────────────────────────────────────────────────
5
- // Types
6
- // ─────────────────────────────────────────────────────────────────────────────
7
-
8
- export interface AuthUser {
9
- email: string;
10
- name?: string;
11
- avatar?: string;
12
- }
13
-
14
- interface AuthContextValue {
15
- /** Currently authenticated user, or null when logged out */
16
- user: AuthUser | null;
17
- /** True while the initial session hydration from localStorage is pending */
18
- isLoading: boolean;
19
- /** Attempt login — returns true on success, false on invalid credentials */
20
- login: (email: string, password: string) => boolean;
21
- /** Clear session and redirect to /login */
22
- logout: () => void;
23
- }
24
-
25
- // ─────────────────────────────────────────────────────────────────────────────
26
- // Context
27
- // ─────────────────────────────────────────────────────────────────────────────
28
-
29
- const AuthContext = createContext<AuthContextValue | null>(null);
30
-
31
- const STORAGE_KEY = 'xertica_user';
32
- const AUTH_PATHS = ['/login', '/forgot-password', '/verify-email', '/reset-password'];
33
-
34
- // ─────────────────────────────────────────────────────────────────────────────
35
- // Provider
36
- // ─────────────────────────────────────────────────────────────────────────────
37
-
38
- /**
39
- * `AuthProvider` — manages authentication state for the devops app.
40
- *
41
- * Must be rendered **inside** `<BrowserRouter>` so that `useNavigate` is available.
42
- * Wrap your `<Routes>` tree with this provider to give all pages access to
43
- * `user`, `login`, and `logout` via `useAuth()` without prop-drilling.
44
- *
45
- * @example
46
- * ```tsx
47
- * <Router>
48
- * <AuthProvider>
49
- * <AppRoutes />
50
- * </AuthProvider>
51
- * </Router>
52
- * ```
53
- */
54
- export function AuthProvider({ children }: { children: React.ReactNode }) {
55
- const [user, setUser] = useState<AuthUser | null>(null);
56
- const [isLoading, setIsLoading] = useState(true);
57
- const navigate = useNavigate();
58
-
59
- // Hydrate session from localStorage on mount
60
- useEffect(() => {
61
- try {
62
- const raw = localStorage.getItem(STORAGE_KEY);
63
- if (raw) setUser(JSON.parse(raw));
64
- } catch {
65
- localStorage.removeItem(STORAGE_KEY);
66
- } finally {
67
- setIsLoading(false);
68
- }
69
- }, []);
70
-
71
- // Redirect authenticated users away from auth-only pages
72
- useEffect(() => {
73
- if (!isLoading && user && AUTH_PATHS.includes(window.location.pathname)) {
74
- navigate('/home', { replace: true });
75
- }
76
- }, [isLoading, user, navigate]);
77
-
78
- const login = useCallback(
79
- (email: string, password: string): boolean => {
80
- if (!email.trim() || !password.trim()) return false;
81
- const userData: AuthUser = { email };
82
- setUser(userData);
83
- localStorage.setItem(STORAGE_KEY, JSON.stringify(userData));
84
- navigate('/home');
85
- return true;
86
- },
87
- [navigate]
88
- );
89
-
90
- const logout = useCallback(() => {
91
- setUser(null);
92
- localStorage.removeItem(STORAGE_KEY);
93
- navigate('/login');
94
- }, [navigate]);
95
-
96
- return (
97
- <AuthContext.Provider value={{ user, isLoading, login, logout }}>
98
- {children}
99
- </AuthContext.Provider>
100
- );
101
- }
102
-
103
- // ─────────────────────────────────────────────────────────────────────────────
104
- // Hook
105
- // ─────────────────────────────────────────────────────────────────────────────
106
-
107
- /**
108
- * `useAuth` — consume authentication state anywhere inside `<AuthProvider>`.
109
- *
110
- * @throws if called outside `<AuthProvider>`
111
- *
112
- * @example
113
- * ```tsx
114
- * const { user, logout } = useAuth();
115
- * ```
116
- */
117
- export function useAuth(): AuthContextValue {
118
- const ctx = useContext(AuthContext);
119
- if (!ctx) throw new Error('useAuth must be used within <AuthProvider>');
120
- return ctx;
121
- }
1
+ import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
2
+ import { useNavigate } from 'react-router-dom';
3
+
4
+ // ─────────────────────────────────────────────────────────────────────────────
5
+ // Types
6
+ // ─────────────────────────────────────────────────────────────────────────────
7
+
8
+ export interface AuthUser {
9
+ email: string;
10
+ name?: string;
11
+ avatar?: string;
12
+ }
13
+
14
+ interface AuthContextValue {
15
+ /** Currently authenticated user, or null when logged out */
16
+ user: AuthUser | null;
17
+ /** True while the initial session hydration from localStorage is pending */
18
+ isLoading: boolean;
19
+ /** Attempt login — returns true on success, false on invalid credentials */
20
+ login: (email: string, password: string) => boolean;
21
+ /** Clear session and redirect to /login */
22
+ logout: () => void;
23
+ }
24
+
25
+ // ─────────────────────────────────────────────────────────────────────────────
26
+ // Context
27
+ // ─────────────────────────────────────────────────────────────────────────────
28
+
29
+ const AuthContext = createContext<AuthContextValue | null>(null);
30
+
31
+ const STORAGE_KEY = 'xertica_user';
32
+ const AUTH_PATHS = ['/login', '/forgot-password', '/verify-email', '/reset-password'];
33
+
34
+ // ─────────────────────────────────────────────────────────────────────────────
35
+ // Provider
36
+ // ─────────────────────────────────────────────────────────────────────────────
37
+
38
+ /**
39
+ * `AuthProvider` — manages authentication state for the devops app.
40
+ *
41
+ * Must be rendered **inside** `<BrowserRouter>` so that `useNavigate` is available.
42
+ * Wrap your `<Routes>` tree with this provider to give all pages access to
43
+ * `user`, `login`, and `logout` via `useAuth()` without prop-drilling.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * <Router>
48
+ * <AuthProvider>
49
+ * <AppRoutes />
50
+ * </AuthProvider>
51
+ * </Router>
52
+ * ```
53
+ */
54
+ export function AuthProvider({ children }: { children: React.ReactNode }) {
55
+ const [user, setUser] = useState<AuthUser | null>(null);
56
+ const [isLoading, setIsLoading] = useState(true);
57
+ const navigate = useNavigate();
58
+
59
+ // Hydrate session from localStorage on mount
60
+ useEffect(() => {
61
+ try {
62
+ const raw = localStorage.getItem(STORAGE_KEY);
63
+ if (raw) setUser(JSON.parse(raw));
64
+ } catch {
65
+ localStorage.removeItem(STORAGE_KEY);
66
+ } finally {
67
+ setIsLoading(false);
68
+ }
69
+ }, []);
70
+
71
+ // Redirect authenticated users away from auth-only pages
72
+ useEffect(() => {
73
+ if (!isLoading && user && AUTH_PATHS.includes(window.location.pathname)) {
74
+ navigate('/home', { replace: true });
75
+ }
76
+ }, [isLoading, user, navigate]);
77
+
78
+ const login = useCallback(
79
+ (email: string, password: string): boolean => {
80
+ if (!email.trim() || !password.trim()) return false;
81
+ const userData: AuthUser = { email };
82
+ setUser(userData);
83
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(userData));
84
+ navigate('/home');
85
+ return true;
86
+ },
87
+ [navigate]
88
+ );
89
+
90
+ const logout = useCallback(() => {
91
+ setUser(null);
92
+ localStorage.removeItem(STORAGE_KEY);
93
+ navigate('/login');
94
+ }, [navigate]);
95
+
96
+ return (
97
+ <AuthContext.Provider value={{ user, isLoading, login, logout }}>
98
+ {children}
99
+ </AuthContext.Provider>
100
+ );
101
+ }
102
+
103
+ // ─────────────────────────────────────────────────────────────────────────────
104
+ // Hook
105
+ // ─────────────────────────────────────────────────────────────────────────────
106
+
107
+ /**
108
+ * `useAuth` — consume authentication state anywhere inside `<AuthProvider>`.
109
+ *
110
+ * @throws if called outside `<AuthProvider>`
111
+ *
112
+ * @example
113
+ * ```tsx
114
+ * const { user, logout } = useAuth();
115
+ * ```
116
+ */
117
+ export function useAuth(): AuthContextValue {
118
+ const ctx = useContext(AuthContext);
119
+ if (!ctx) throw new Error('useAuth must be used within <AuthProvider>');
120
+ return ctx;
121
+ }
@@ -178,20 +178,51 @@ export const BrandColorsProvider: React.FC<BrandColorsProviderProps> = ({
178
178
  `--gradient-diagonal: linear-gradient(135deg, ${gradientStart} 0%, ${gradientEnd} 100%)`
179
179
  );
180
180
 
181
- // Inject into head as a style tag rather than inline on HTML element
182
- // Usamos prepend em vez de appendChild para garantir que a injeção seja
183
- // lida ANTES de qualquer arquivo CSS estático (como tokens.css), garantindo que
184
- // as modificações feitas pelo desenvolvedor em :root tenham prioridade natural de cascata.
181
+ // 7. Surface colors for dark mode (tinted toward the theme hue)
182
+ // Only applied when dark surface tokens exist on the theme.
183
+ const darkSurfaceVars: string[] = [];
184
+ if (colors.darkBackground) {
185
+ darkSurfaceVars.push(`--background: ${colors.darkBackground}`);
186
+ darkSurfaceVars.push(`--card: ${colors.darkCard}`);
187
+ darkSurfaceVars.push(`--popover: ${colors.darkCard}`);
188
+ darkSurfaceVars.push(`--secondary: ${colors.darkMuted}`);
189
+ darkSurfaceVars.push(`--muted: ${colors.darkMuted}`);
190
+ darkSurfaceVars.push(`--accent: ${colors.darkMuted}`);
191
+ darkSurfaceVars.push(`--border: ${colors.darkBorder}`);
192
+ darkSurfaceVars.push(`--input: ${colors.darkMuted}`);
193
+ darkSurfaceVars.push(`--input-background: ${colors.darkMuted}`);
194
+ }
195
+
196
+ // Apply primary-related tokens directly as inline styles on <html>.
197
+ // Inline styles have the highest possible specificity and always win over
198
+ // any stylesheet rule, regardless of order or selector specificity.
199
+ cssVars.forEach(declaration => {
200
+ const eqIdx = declaration.indexOf(':');
201
+ if (eqIdx === -1) return;
202
+ const prop = declaration.substring(0, eqIdx).trim();
203
+ const val = declaration.substring(eqIdx + 1).trim();
204
+ root.style.setProperty(prop, val); // `root` is document.documentElement, declared at line 79
205
+ });
206
+
207
+ // Surface tokens (background, card, muted, etc.) are injected via a style
208
+ // tag appended last in <head> so they win the cascade for their selectors.
185
209
  const styleId = 'xertica-brand-colors-injection';
186
210
  let styleEl = document.getElementById(styleId);
187
211
  if (!styleEl) {
188
212
  styleEl = document.createElement('style');
189
213
  styleEl.id = styleId;
190
- document.head.prepend(styleEl);
214
+ document.head.appendChild(styleEl);
215
+ } else {
216
+ document.head.appendChild(styleEl);
191
217
  }
192
- styleEl.innerHTML = `:root {
193
- ${cssVars.join(';\n ')};
194
- }`;
218
+
219
+ const darkSurfaceBlock =
220
+ darkSurfaceVars.length > 0
221
+ ? `\n:root[data-mode='dark'], .dark {\n ${darkSurfaceVars.join(';\n ')};\n}`
222
+ : '';
223
+
224
+ // The style tag handles only the surface tokens that vary per theme in dark mode.
225
+ styleEl.innerHTML = darkSurfaceBlock.trim();
195
226
  }, [colors, currentTheme, radius, useCustomTokens]);
196
227
 
197
228
  // Aplicar cores quando elas mudarem
@@ -1,121 +1,121 @@
1
- import { renderHook, act } from '@testing-library/react';
2
- import { describe, it, expect, beforeEach, vi } from 'vitest';
3
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
4
- import {
5
- LanguageProvider,
6
- useLanguage,
7
- DEFAULT_LANGUAGES,
8
- type LanguageDefinition,
9
- } from './LanguageContext';
10
- import React from 'react';
11
-
12
- function makeWrapper(props?: Partial<React.ComponentProps<typeof LanguageProvider>>) {
13
- const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
14
- return ({ children }: { children: React.ReactNode }) => (
15
- <QueryClientProvider client={queryClient}>
16
- <LanguageProvider {...props}>{children}</LanguageProvider>
17
- </QueryClientProvider>
18
- );
19
- }
20
-
21
- describe('LanguageContext', () => {
22
- beforeEach(() => {
23
- window.localStorage.clear();
24
- });
25
-
26
- describe('default behavior', () => {
27
- it('provides default language (pt-BR)', () => {
28
- const { result } = renderHook(() => useLanguage(), { wrapper: makeWrapper() });
29
- expect(result.current.language).toBe('pt-BR');
30
- });
31
-
32
- it('exposes the default three languages', () => {
33
- const { result } = renderHook(() => useLanguage(), { wrapper: makeWrapper() });
34
- expect(result.current.availableLanguages).toHaveLength(3);
35
- expect(result.current.availableLanguages.map(l => l.code)).toEqual(['pt-BR', 'en', 'es']);
36
- });
37
-
38
- it('is not monolingual when using defaults', () => {
39
- const { result } = renderHook(() => useLanguage(), { wrapper: makeWrapper() });
40
- expect(result.current.isMonolingual).toBe(false);
41
- });
42
-
43
- it('updates language', () => {
44
- const { result } = renderHook(() => useLanguage(), { wrapper: makeWrapper() });
45
- act(() => result.current.setLanguage('en'));
46
- expect(result.current.language).toBe('en');
47
- });
48
- });
49
-
50
- describe('monolingual mode', () => {
51
- const englishOnly: LanguageDefinition[] = [{ code: 'en', label: 'English' }];
52
-
53
- it('reports isMonolingual = true with a single language', () => {
54
- const { result } = renderHook(() => useLanguage(), {
55
- wrapper: makeWrapper({ availableLanguages: englishOnly }),
56
- });
57
- expect(result.current.isMonolingual).toBe(true);
58
- expect(result.current.availableLanguages).toEqual(englishOnly);
59
- });
60
-
61
- it('defaults to the only language available', () => {
62
- const { result } = renderHook(() => useLanguage(), {
63
- wrapper: makeWrapper({ availableLanguages: englishOnly }),
64
- });
65
- expect(result.current.language).toBe('en');
66
- });
67
- });
68
-
69
- describe('custom languages', () => {
70
- it('accepts extra languages beyond the defaults', () => {
71
- const extended: LanguageDefinition[] = [
72
- ...DEFAULT_LANGUAGES,
73
- { code: 'fr', label: 'Français', shortLabel: 'FR' },
74
- ];
75
- const { result } = renderHook(() => useLanguage(), {
76
- wrapper: makeWrapper({ availableLanguages: extended }),
77
- });
78
- expect(result.current.availableLanguages).toHaveLength(4);
79
- act(() => result.current.setLanguage('fr'));
80
- expect(result.current.language).toBe('fr');
81
- });
82
-
83
- it('ignores attempts to switch to a language not in the list', () => {
84
- const { result } = renderHook(() => useLanguage(), {
85
- wrapper: makeWrapper({ availableLanguages: [{ code: 'en', label: 'English' }] }),
86
- });
87
- act(() => result.current.setLanguage('xx-XX' as any));
88
- // language should remain 'en' (the only valid option)
89
- expect(result.current.language).toBe('en');
90
- });
91
- });
92
-
93
- describe('defaultLanguage prop', () => {
94
- it('respects an explicit defaultLanguage', () => {
95
- const { result } = renderHook(() => useLanguage(), {
96
- wrapper: makeWrapper({ defaultLanguage: 'es' }),
97
- });
98
- expect(result.current.language).toBe('es');
99
- });
100
- });
101
-
102
- describe('error handling', () => {
103
- it('throws when availableLanguages is an empty array', () => {
104
- // Suppress React's error logging for this expected throw
105
- const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
106
- expect(() =>
107
- renderHook(() => useLanguage(), { wrapper: makeWrapper({ availableLanguages: [] }) })
108
- ).toThrow(/availableLanguages.*cannot be empty/);
109
- consoleErrorSpy.mockRestore();
110
- });
111
- });
112
-
113
- describe('reference stability', () => {
114
- it('keeps setLanguage stable across re-renders with the same languages', () => {
115
- const { result, rerender } = renderHook(() => useLanguage(), { wrapper: makeWrapper() });
116
- const firstSetLanguage = result.current.setLanguage;
117
- rerender();
118
- expect(result.current.setLanguage).toBe(firstSetLanguage);
119
- });
120
- });
121
- });
1
+ import { renderHook, act } from '@testing-library/react';
2
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
3
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
4
+ import {
5
+ LanguageProvider,
6
+ useLanguage,
7
+ DEFAULT_LANGUAGES,
8
+ type LanguageDefinition,
9
+ } from './LanguageContext';
10
+ import React from 'react';
11
+
12
+ function makeWrapper(props?: Partial<React.ComponentProps<typeof LanguageProvider>>) {
13
+ const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
14
+ return ({ children }: { children: React.ReactNode }) => (
15
+ <QueryClientProvider client={queryClient}>
16
+ <LanguageProvider {...props}>{children}</LanguageProvider>
17
+ </QueryClientProvider>
18
+ );
19
+ }
20
+
21
+ describe('LanguageContext', () => {
22
+ beforeEach(() => {
23
+ window.localStorage.clear();
24
+ });
25
+
26
+ describe('default behavior', () => {
27
+ it('provides default language (pt-BR)', () => {
28
+ const { result } = renderHook(() => useLanguage(), { wrapper: makeWrapper() });
29
+ expect(result.current.language).toBe('pt-BR');
30
+ });
31
+
32
+ it('exposes the default three languages', () => {
33
+ const { result } = renderHook(() => useLanguage(), { wrapper: makeWrapper() });
34
+ expect(result.current.availableLanguages).toHaveLength(3);
35
+ expect(result.current.availableLanguages.map(l => l.code)).toEqual(['pt-BR', 'en', 'es']);
36
+ });
37
+
38
+ it('is not monolingual when using defaults', () => {
39
+ const { result } = renderHook(() => useLanguage(), { wrapper: makeWrapper() });
40
+ expect(result.current.isMonolingual).toBe(false);
41
+ });
42
+
43
+ it('updates language', () => {
44
+ const { result } = renderHook(() => useLanguage(), { wrapper: makeWrapper() });
45
+ act(() => result.current.setLanguage('en'));
46
+ expect(result.current.language).toBe('en');
47
+ });
48
+ });
49
+
50
+ describe('monolingual mode', () => {
51
+ const englishOnly: LanguageDefinition[] = [{ code: 'en', label: 'English' }];
52
+
53
+ it('reports isMonolingual = true with a single language', () => {
54
+ const { result } = renderHook(() => useLanguage(), {
55
+ wrapper: makeWrapper({ availableLanguages: englishOnly }),
56
+ });
57
+ expect(result.current.isMonolingual).toBe(true);
58
+ expect(result.current.availableLanguages).toEqual(englishOnly);
59
+ });
60
+
61
+ it('defaults to the only language available', () => {
62
+ const { result } = renderHook(() => useLanguage(), {
63
+ wrapper: makeWrapper({ availableLanguages: englishOnly }),
64
+ });
65
+ expect(result.current.language).toBe('en');
66
+ });
67
+ });
68
+
69
+ describe('custom languages', () => {
70
+ it('accepts extra languages beyond the defaults', () => {
71
+ const extended: LanguageDefinition[] = [
72
+ ...DEFAULT_LANGUAGES,
73
+ { code: 'fr', label: 'Français', shortLabel: 'FR' },
74
+ ];
75
+ const { result } = renderHook(() => useLanguage(), {
76
+ wrapper: makeWrapper({ availableLanguages: extended }),
77
+ });
78
+ expect(result.current.availableLanguages).toHaveLength(4);
79
+ act(() => result.current.setLanguage('fr'));
80
+ expect(result.current.language).toBe('fr');
81
+ });
82
+
83
+ it('ignores attempts to switch to a language not in the list', () => {
84
+ const { result } = renderHook(() => useLanguage(), {
85
+ wrapper: makeWrapper({ availableLanguages: [{ code: 'en', label: 'English' }] }),
86
+ });
87
+ act(() => result.current.setLanguage('xx-XX' as any));
88
+ // language should remain 'en' (the only valid option)
89
+ expect(result.current.language).toBe('en');
90
+ });
91
+ });
92
+
93
+ describe('defaultLanguage prop', () => {
94
+ it('respects an explicit defaultLanguage', () => {
95
+ const { result } = renderHook(() => useLanguage(), {
96
+ wrapper: makeWrapper({ defaultLanguage: 'es' }),
97
+ });
98
+ expect(result.current.language).toBe('es');
99
+ });
100
+ });
101
+
102
+ describe('error handling', () => {
103
+ it('throws when availableLanguages is an empty array', () => {
104
+ // Suppress React's error logging for this expected throw
105
+ const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
106
+ expect(() =>
107
+ renderHook(() => useLanguage(), { wrapper: makeWrapper({ availableLanguages: [] }) })
108
+ ).toThrow(/availableLanguages.*cannot be empty/);
109
+ consoleErrorSpy.mockRestore();
110
+ });
111
+ });
112
+
113
+ describe('reference stability', () => {
114
+ it('keeps setLanguage stable across re-renders with the same languages', () => {
115
+ const { result, rerender } = renderHook(() => useLanguage(), { wrapper: makeWrapper() });
116
+ const firstSetLanguage = result.current.setLanguage;
117
+ rerender();
118
+ expect(result.current.setLanguage).toBe(firstSetLanguage);
119
+ });
120
+ });
121
+ });