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.
- package/CHANGELOG.md +621 -564
- package/README.md +443 -417
- package/assets/xertica-logo.svg +37 -37
- package/assets/xertica-x-logo.svg +20 -20
- package/bin/cli.ts +1244 -1244
- package/bin/generate-tokens.ts +9 -9
- package/bin/language-config.ts +358 -358
- package/components/assistant/code-block/CodeBlock.tsx +268 -268
- package/components/assistant/formatted-document/FormattedDocument.tsx +147 -147
- package/components/assistant/modern-chat-input/ModernChatInput.tsx +564 -564
- package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +99 -99
- package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -104
- package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -81
- package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +88 -88
- package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +75 -75
- package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +564 -564
- package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +67 -67
- package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +103 -103
- package/components/assistant/xertica-assistant/use-assistant.ts +615 -615
- package/components/assistant/xertica-assistant/xertica-assistant.tsx +611 -611
- package/components/blocks/card-patterns/ActivityCard.tsx +100 -100
- package/components/blocks/card-patterns/ActivityCardSkeleton.tsx +56 -56
- package/components/blocks/card-patterns/FeatureCardSkeleton.tsx +58 -58
- package/components/blocks/card-patterns/NotificationCard.tsx +140 -140
- package/components/blocks/card-patterns/NotificationCardSkeleton.tsx +81 -81
- package/components/blocks/card-patterns/ProfileCard.tsx +112 -112
- package/components/blocks/card-patterns/ProfileCardSkeleton.tsx +69 -69
- package/components/blocks/card-patterns/ProjectCard.tsx +123 -123
- package/components/blocks/card-patterns/ProjectCardSkeleton.tsx +67 -67
- package/components/blocks/card-patterns/QuickActionCardSkeleton.tsx +44 -44
- package/components/blocks/card-patterns/card-patterns.stories.tsx +594 -594
- package/components/blocks/card-patterns/index.ts +29 -29
- package/components/brand/language-selector/LanguageSelector.tsx +102 -102
- package/components/brand/language-selector/language-selector.stories.tsx +111 -111
- package/components/brand/language-selector/language-selector.test.tsx +101 -101
- package/components/brand/theme-toggle/ThemeToggle.tsx +74 -74
- package/components/brand/xertica-provider/XerticaProvider.tsx +112 -109
- package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
- package/components/index.ts +86 -86
- package/components/layout/sidebar/sidebar.mdx +1 -1
- package/components/layout/sidebar/sidebar.stories.tsx +201 -0
- package/components/layout/sidebar/sidebar.tsx +1164 -1079
- package/components/media/FloatingMediaWrapper.tsx +371 -371
- package/components/media/audio-player/AudioPlayer.tsx +768 -768
- package/components/media/video-player/VideoPlayer.tsx +310 -310
- package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +188 -188
- package/components/pages/home-content/HomeContent.tsx +120 -120
- package/components/pages/home-content/home-content.mdx +62 -62
- package/components/pages/home-page/HomePage.tsx +78 -78
- package/components/pages/home-page/home-page.mdx +53 -53
- package/components/pages/login-page/LoginPage.tsx +218 -218
- package/components/pages/reset-password-page/ResetPasswordPage.tsx +243 -243
- package/components/pages/template-content/TemplateContent.tsx +1354 -1354
- package/components/pages/template-content/template-content.mdx +61 -61
- package/components/pages/template-page/TemplatePage.stories.tsx +8 -15
- package/components/pages/template-page/template-page.mdx +53 -53
- package/components/pages/verify-email-page/VerifyEmailPage.tsx +206 -206
- package/components/shared/error-boundary.stories.tsx +114 -114
- package/components/shared/error-boundary.tsx +150 -150
- package/components/shared/error-fallbacks.tsx +222 -222
- package/components/ui/accordion/accordion.mdx +8 -8
- package/components/ui/alert/alert.mdx +8 -8
- package/components/ui/alert-dialog/alert-dialog.mdx +8 -8
- package/components/ui/aspect-ratio/aspect-ratio.mdx +8 -8
- package/components/ui/assistant-chart/assistant-chart.mdx +8 -8
- package/components/ui/avatar/avatar.mdx +8 -8
- package/components/ui/badge/badge.mdx +8 -8
- package/components/ui/breadcrumb/breadcrumb.mdx +8 -8
- package/components/ui/button/button.mdx +8 -8
- package/components/ui/calendar/calendar.mdx +8 -8
- package/components/ui/card/card.mdx +8 -8
- package/components/ui/carousel/carousel.mdx +8 -8
- package/components/ui/chart/chart.mdx +8 -8
- package/components/ui/chart/chart.test.tsx +1 -1
- package/components/ui/chart/chart.tsx +13 -6
- package/components/ui/checkbox/checkbox.mdx +8 -8
- package/components/ui/collapsible/collapsible.mdx +8 -8
- package/components/ui/command/command.mdx +8 -8
- package/components/ui/context-menu/context-menu.mdx +8 -8
- package/components/ui/dialog/dialog.mdx +8 -8
- package/components/ui/drawer/drawer.mdx +8 -8
- package/components/ui/dropdown-menu/dropdown-menu.mdx +8 -8
- package/components/ui/empty/empty.mdx +8 -8
- package/components/ui/file-upload/file-upload.mdx +8 -8
- package/components/ui/hover-card/hover-card.mdx +8 -8
- package/components/ui/input/input.mdx +8 -8
- package/components/ui/input-otp/input-otp.mdx +8 -8
- package/components/ui/label/label.mdx +8 -8
- package/components/ui/map/map.mdx +8 -8
- package/components/ui/menubar/menubar.mdx +8 -8
- package/components/ui/navigation-menu/navigation-menu.mdx +8 -8
- package/components/ui/notification-badge/notification-badge.mdx +8 -8
- package/components/ui/pagination/pagination.mdx +8 -8
- package/components/ui/popover/popover.mdx +8 -8
- package/components/ui/progress/progress.mdx +8 -8
- package/components/ui/radio-group/radio-group.mdx +8 -8
- package/components/ui/rating/rating.mdx +8 -8
- package/components/ui/resizable/resizable.mdx +8 -8
- package/components/ui/route-map/route-map.mdx +8 -8
- package/components/ui/scroll-area/scroll-area.mdx +8 -8
- package/components/ui/search/search.mdx +8 -8
- package/components/ui/select/select.mdx +8 -8
- package/components/ui/separator/separator.mdx +8 -8
- package/components/ui/sheet/sheet.mdx +8 -8
- package/components/ui/simple-map/simple-map.mdx +8 -8
- package/components/ui/skeleton/skeleton.mdx +8 -8
- package/components/ui/slider/slider.mdx +8 -8
- package/components/ui/sonner/sonner.mdx +8 -8
- package/components/ui/stats-card/index.ts +2 -2
- package/components/ui/stats-card/stats-card-skeleton.tsx +60 -60
- package/components/ui/stats-card/stats-card.mdx +8 -8
- package/components/ui/stats-card/stats-card.stories.tsx +117 -99
- package/components/ui/stats-card/stats-card.tsx +18 -2
- package/components/ui/stepper/stepper.mdx +8 -8
- package/components/ui/switch/switch.mdx +8 -8
- package/components/ui/table/table.mdx +8 -8
- package/components/ui/tabs/tabs.mdx +8 -8
- package/components/ui/textarea/textarea.mdx +8 -8
- package/components/ui/timeline/timeline.mdx +8 -8
- package/components/ui/toggle/toggle.mdx +8 -8
- package/components/ui/toggle-group/toggle-group.mdx +8 -8
- package/components/ui/tooltip/tooltip.mdx +8 -8
- package/components/ui/tree-view/tree-view.mdx +8 -8
- package/components.json +153 -533
- package/contexts/AuthContext.tsx +121 -121
- package/contexts/BrandColorsContext.tsx +39 -8
- package/contexts/LanguageContext.test.tsx +121 -121
- package/contexts/LanguageContext.tsx +250 -250
- package/contexts/theme-data.ts +51 -0
- package/dist/AssistantChart-BKVtGUKF.js +3383 -0
- package/dist/AssistantChart-BZTPJ5dP.cjs +3551 -0
- package/dist/{AssistantChart-BAx9VQvb.cjs → AssistantChart-Bdd44uBn.cjs} +388 -127
- package/dist/{AssistantChart-CVko2A1W.js → AssistantChart-CFhDdGyU.js} +391 -130
- package/dist/{AssistantChart-CVzmmhx4.js → AssistantChart-C_hwFRRr.js} +4 -4
- package/dist/{AssistantChart-BAudAfne.cjs → AssistantChart-CldVCVDe.cjs} +5 -5
- package/dist/{AssistantChart-BP8upjMk.js → AssistantChart-Cu3m7RBo.js} +5 -5
- package/dist/AssistantChart-CxGjH7Qk.js +3477 -0
- package/dist/AssistantChart-DIpshm3i.js +4784 -0
- package/dist/AssistantChart-DMJJ_Amf.js +3383 -0
- package/dist/AssistantChart-D_PTeu8P.cjs +3503 -0
- package/dist/{AssistantChart-9w31gdAb.cjs → AssistantChart-DoZCyS5r.cjs} +4 -4
- package/dist/AssistantChart-WeycT5Pd.cjs +3551 -0
- package/dist/AssistantChart-zjsy2GaZ.cjs +4810 -0
- package/dist/AudioPlayer-B1lt5cPl.cjs +989 -0
- package/dist/AudioPlayer-BZ7bibzU.cjs +982 -0
- package/dist/AudioPlayer-BpRPS4-1.cjs +1277 -0
- package/dist/AudioPlayer-C12BjQBV.cjs +997 -0
- package/dist/{AudioPlayer-1ypwE2Wh.cjs → AudioPlayer-CFeV8t-5.cjs} +1 -1
- package/dist/{AudioPlayer-DuKXrCfy.js → AudioPlayer-CGRUtUdN.js} +1 -1
- package/dist/AudioPlayer-Coly3q5R.js +1278 -0
- package/dist/AudioPlayer-CySJIyvL.js +937 -0
- package/dist/AudioPlayer-DMcG_c7L.js +990 -0
- package/dist/AudioPlayer-DcFKRJE_.js +998 -0
- package/dist/AudioPlayer-IAU5q5T1.cjs +936 -0
- package/dist/AudioPlayer-e8LfNoqO.js +983 -0
- package/dist/BrandColorsContext-565dDHd5.js +660 -0
- package/dist/BrandColorsContext-BMRJ04Wf.js +718 -0
- package/dist/BrandColorsContext-BcJbtkqn.cjs +659 -0
- package/dist/BrandColorsContext-BwY-b6M4.cjs +725 -0
- package/dist/{xertica-assistant-Qp3ydksa.cjs → CodeBlock-7TTgmdGG.cjs} +263 -51
- package/dist/{xertica-assistant-gnCJdcZY.js → CodeBlock-BeSt1h5P.js} +219 -7
- package/dist/CodeBlock-BgfYL_rD.cjs +2094 -0
- package/dist/CodeBlock-BlcqlA9M.cjs +2094 -0
- package/dist/CodeBlock-Bnmeu5ez.cjs +2094 -0
- package/dist/CodeBlock-BtfPlbAI.js +2078 -0
- package/dist/CodeBlock-CIySIuYr.js +2078 -0
- package/dist/CodeBlock-CuPtUM-7.cjs +2094 -0
- package/dist/CodeBlock-D6ffWXgc.js +2078 -0
- package/dist/CodeBlock-D8dcwbit.cjs +2094 -0
- package/dist/CodeBlock-DMZrFnlw.cjs +2094 -0
- package/dist/CodeBlock-DlBehYN8.js +2078 -0
- package/dist/CodeBlock-DnYNI8rQ.js +2078 -0
- package/dist/CodeBlock-DvKWbSnE.cjs +2094 -0
- package/dist/CodeBlock-DwMCfkFY.js +2078 -0
- package/dist/CodeBlock-Dy6CNYyj.js +2078 -0
- package/dist/CodeBlock-U1pPOQI7.cjs +2094 -0
- package/dist/CodeBlock-f_GpNhEB.js +2078 -0
- package/dist/CodeBlock-oB6u8nI1.js +2078 -0
- package/dist/CodeBlock-tZC31B73.cjs +2094 -0
- package/dist/FeatureCard-CxC-7C-C.cjs +300 -0
- package/dist/FeatureCard-DbHWCb4E.js +301 -0
- package/dist/ImageWithFallback-CGtidP6B.cjs +4542 -0
- package/dist/ImageWithFallback-lsg3pdFg.js +4508 -0
- package/dist/{LanguageContext-DvUt5jBg.cjs → LanguageContext-B_KFTCzT.cjs} +2 -2
- package/dist/{LanguageContext-BwhwC3G2.js → LanguageContext-CS14yCpi.js} +2 -2
- package/dist/{XerticaXLogo-DHz5SugF.js → LanguageSelector-B5YfbHra.js} +115 -136
- package/dist/{XerticaXLogo-DTee_y8X.cjs → LanguageSelector-D6uacAIM.cjs} +115 -136
- package/dist/LayoutContext-B45-e9DI.cjs +93 -0
- package/dist/LayoutContext-BAql6ZRY.js +97 -0
- package/dist/LayoutContext-Bav3UMEA.js +94 -0
- package/dist/LayoutContext-BvK-ggDa.cjs +96 -0
- package/dist/{ThemeContext-Bo-W2WZH.js → ThemeContext-BWq9ACPo.js} +8 -13
- package/dist/{ThemeContext-ept8jhXI.js → ThemeContext-BXjrgUjW.js} +261 -200
- package/dist/{ThemeContext-BblcjQup.cjs → ThemeContext-Bmod0Cg2.cjs} +8 -13
- package/dist/ThemeContext-BoH4NLfN.js +734 -0
- package/dist/{ThemeContext-BbBNoFTG.js → ThemeContext-C2EwAPDt.js} +2 -2
- package/dist/{ThemeContext-U4dEYc6C.cjs → ThemeContext-CGk3KK0k.cjs} +1 -8
- package/dist/{ThemeContext-D3LzacmG.js → ThemeContext-CQSo4Iwc.js} +1 -8
- package/dist/{ThemeContext-CP3a0jxy.cjs → ThemeContext-j5aGtPky.cjs} +262 -193
- package/dist/ThemeContext-r69W20Xg.cjs +733 -0
- package/dist/{ThemeContext-Cmr8Ex8H.cjs → ThemeContext-vTjumZeM.cjs} +2 -2
- package/dist/{VerifyEmailPage-BRSP-Pwt.cjs → VerifyEmailPage--1Vurewl.cjs} +3 -3
- package/dist/{VerifyEmailPage-CbgjOF0v.js → VerifyEmailPage-1WwWczAn.js} +12 -22
- package/dist/{VerifyEmailPage-DF2ilhum.cjs → VerifyEmailPage-B4peJjAT.cjs} +356 -334
- package/dist/{VerifyEmailPage-CR7kb5df.cjs → VerifyEmailPage-BComraR7.cjs} +12 -22
- package/dist/{VerifyEmailPage-u_Dn7t1U.cjs → VerifyEmailPage-Bp1XXl3H.cjs} +4 -4
- package/dist/{VerifyEmailPage-CkBYfsNy.cjs → VerifyEmailPage-By3Jf__L.cjs} +4 -4
- package/dist/{VerifyEmailPage-Bv8Ah_TK.cjs → VerifyEmailPage-ByerOcm4.cjs} +20 -23
- package/dist/{VerifyEmailPage-BE-L9mB7.js → VerifyEmailPage-C0c2e5n0.js} +7 -7
- package/dist/{VerifyEmailPage-EhudUdqF.js → VerifyEmailPage-C5TNQTBa.js} +355 -343
- package/dist/{VerifyEmailPage-Dt7zgA4w.cjs → VerifyEmailPage-CFLMls1p.cjs} +4 -4
- package/dist/{VerifyEmailPage-Bvfv8HVQ.js → VerifyEmailPage-CGIwmWrm.js} +461 -379
- package/dist/{VerifyEmailPage-Cyl55sJb.js → VerifyEmailPage-CJLz3jrn.js} +20 -23
- package/dist/VerifyEmailPage-COiyNl1y.js +2825 -0
- package/dist/{VerifyEmailPage-DMBh4NM9.cjs → VerifyEmailPage-CYXtbKi3.cjs} +1 -1
- package/dist/{VerifyEmailPage-DTtFfC-J.js → VerifyEmailPage-CgMxRb4z.js} +3 -3
- package/dist/VerifyEmailPage-CpqqpLpo.cjs +3305 -0
- package/dist/VerifyEmailPage-CqKsR2v8.js +2827 -0
- package/dist/{VerifyEmailPage-Bae2cBXT.cjs → VerifyEmailPage-Cwi3kbol.cjs} +7 -7
- package/dist/{VerifyEmailPage-X14vhdyl.js → VerifyEmailPage-DGhuIqkb.js} +4 -4
- package/dist/{VerifyEmailPage-BIBOKV7Z.js → VerifyEmailPage-DSBMRHtl.js} +36 -41
- package/dist/{VerifyEmailPage-D-FRj5TU.cjs → VerifyEmailPage-De6bQjrz.cjs} +36 -41
- package/dist/{VerifyEmailPage-BJjAMUTW.js → VerifyEmailPage-DgIid028.js} +4 -4
- package/dist/VerifyEmailPage-DjQKRlUS.cjs +2824 -0
- package/dist/{VerifyEmailPage-CdYPSJoO.js → VerifyEmailPage-DvMLZgFt.js} +1 -1
- package/dist/{VerifyEmailPage-C_ihbcth.js → VerifyEmailPage-MTD7AG1Z.js} +4 -4
- package/dist/VerifyEmailPage-s-1X3LDJ.cjs +2826 -0
- package/dist/XerticaOrbe-KL1RBHzw.cjs +1354 -0
- package/dist/XerticaOrbe-zwS1p2a8.js +1355 -0
- package/dist/XerticaProvider-6btlAlzc.js +17 -0
- package/dist/{XerticaProvider-siSt9uG2.js → XerticaProvider-B7EVH-NF.js} +2 -2
- package/dist/{XerticaProvider-AbWlr7Af.cjs → XerticaProvider-BIrqfZ-i.cjs} +11 -8
- package/dist/XerticaProvider-BNoNOxQ5.cjs +16 -0
- package/dist/XerticaProvider-BlY2limY.cjs +38 -0
- package/dist/{XerticaProvider-CWgby5mY.js → XerticaProvider-C1DKnvLh.js} +4 -4
- package/dist/{XerticaProvider-AChwphCO.cjs → XerticaProvider-CBGc4EMA.cjs} +4 -4
- package/dist/{XerticaProvider-BITjgC5p.js → XerticaProvider-CEoWMTxu.js} +2 -2
- package/dist/XerticaProvider-CeS5G_n5.cjs +45 -0
- package/dist/{XerticaProvider-By8q3Roe.cjs → XerticaProvider-CllrbMEJ.cjs} +2 -2
- package/dist/{XerticaProvider-B8CaV7xu.cjs → XerticaProvider-D-yNhF94.cjs} +1 -1
- package/dist/XerticaProvider-DDuiIcKo.js +39 -0
- package/dist/{XerticaProvider-DQtvJU7m.js → XerticaProvider-DYq4JWtg.js} +1 -1
- package/dist/{XerticaProvider-CWs6EwNa.js → XerticaProvider-Dt5HEzbQ.js} +10 -10
- package/dist/{XerticaProvider-CW9hpCdF.cjs → XerticaProvider-ET0ihewn.cjs} +2 -2
- package/dist/XerticaProvider-cI9hSs27.cjs +38 -0
- package/dist/XerticaProvider-hSwhNQex.js +39 -0
- package/dist/XerticaProvider-ra2NciRq.js +43 -0
- package/dist/{XerticaXLogo-ChryA6xj.js → XerticaXLogo-B7xQ5dhi.js} +1 -1
- package/dist/{XerticaXLogo-CziKMQil.cjs → XerticaXLogo-CQUUjXoH.cjs} +8 -8
- package/dist/{XerticaXLogo-DfUvz-lD.js → XerticaXLogo-Cmsp-Eey.js} +9 -9
- package/dist/{XerticaXLogo-CFuIlYFH.js → XerticaXLogo-DZbo4vOE.js} +12 -12
- package/dist/{XerticaXLogo-8TTzBjHw.cjs → XerticaXLogo-Zw2B276b.cjs} +1 -1
- package/dist/{XerticaXLogo-kslQ8Tk_.cjs → XerticaXLogo-bvZSgwGF.cjs} +13 -7
- package/dist/alert-dialog-BOje--vD.js +847 -0
- package/dist/alert-dialog-BtEuQqrg.cjs +870 -0
- package/dist/{alert-dialog-yckpaOpy.cjs → alert-dialog-DSKByiKZ.cjs} +3 -3
- package/dist/{alert-dialog-iDe5VE5o.js → alert-dialog-s-vmNkJ_.js} +3 -3
- package/dist/assistant.cjs.js +1 -1
- package/dist/assistant.es.js +1 -1
- package/dist/brand.cjs.js +1 -1
- package/dist/brand.es.js +1 -1
- package/dist/breadcrumb-CqJ7bHY5.js +161 -0
- package/dist/breadcrumb-m9Hb2_XN.cjs +177 -0
- package/dist/cli.js +45 -9
- package/dist/components/assistant/xertica-assistant/hooks/index.d.ts +6 -0
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-conversations.d.ts +21 -0
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-messages.d.ts +49 -0
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-suggestions.d.ts +16 -0
- package/dist/components/blocks/audio-player/AudioPlayer.d.ts +35 -0
- package/dist/components/blocks/audio-player/index.d.ts +1 -0
- package/dist/components/blocks/document-editor/DocumentEditor.d.ts +26 -0
- package/dist/components/blocks/document-editor/index.d.ts +1 -0
- package/dist/components/blocks/podcast-player/PodcastPlayer.d.ts +41 -0
- package/dist/components/blocks/podcast-player/index.d.ts +1 -0
- package/dist/components/brand/xertica-provider/XerticaProvider.d.ts +3 -1
- package/dist/components/ui/chart/chart.d.ts +12 -3
- package/dist/components/ui/chart/parts/chart-dashboard.d.ts +113 -0
- package/dist/components/ui/chart/parts/chart-metric.d.ts +118 -0
- package/dist/components/ui/chart/parts/chart-primitives.d.ts +101 -0
- package/dist/components/ui/chart/parts/chart-shared.d.ts +20 -0
- package/dist/components/ui/chart/parts/chart-utils.d.ts +12 -0
- package/dist/components/ui/chart/parts/index.d.ts +5 -0
- package/dist/components/ui/stats-card/stats-card.d.ts +10 -0
- package/dist/contexts/theme-data.d.ts +4 -0
- package/dist/dropdown-menu-BDB5CmQs.cjs +247 -0
- package/dist/dropdown-menu-DQidbKBD.js +231 -0
- package/dist/google-maps-loader-BFWp6VPd.js +287 -0
- package/dist/google-maps-loader-BKcdgFbu.cjs +312 -0
- package/dist/{google-maps-loader-t2IlYBzw.js → google-maps-loader-CTYySAun.js} +4 -0
- package/dist/google-maps-loader-CumCNXeG.js +312 -0
- package/dist/{google-maps-loader-BqsYL48U.cjs → google-maps-loader-Y-QkD-Li.cjs} +5 -0
- package/dist/google-maps-loader-eS3uQ5TA.cjs +287 -0
- package/dist/header-Cgy6vYPk.cjs +731 -0
- package/dist/header-DRlT4jgI.js +715 -0
- package/dist/header-Dux00SI4.cjs +731 -0
- package/dist/header-EkGKXPsD.js +715 -0
- package/dist/header-WfEywpyc.cjs +731 -0
- package/dist/header-tifNQn2U.js +715 -0
- package/dist/hooks.cjs.js +1 -1
- package/dist/hooks.es.js +1 -1
- package/dist/index-BhapVLVj.js +8 -0
- package/dist/{index-D3RLKRAs.cjs → index-COtD8bRW.cjs} +1 -1
- package/dist/index-D6fxYEY8.cjs +7 -0
- package/dist/index-DAIp0_HK.js +8 -0
- package/dist/index-DW5tYe26.js +8 -0
- package/dist/index-GA__GvnG.cjs +7 -0
- package/dist/index.cjs.js +6 -6
- package/dist/index.es.js +6 -6
- package/dist/index.umd.js +1043 -470
- package/dist/input-2R4loU86.js +127 -0
- package/dist/input-DWANSKGb.cjs +145 -0
- package/dist/layout.cjs.js +1 -1
- package/dist/layout.es.js +1 -1
- package/dist/pages.cjs.js +1 -1
- package/dist/pages.es.js +1 -1
- package/dist/progress-DPtzoVV8.js +175 -0
- package/dist/progress-EeaoqqUs.cjs +191 -0
- package/dist/rich-text-editor-0mraWT5y.cjs +2376 -0
- package/dist/rich-text-editor-B-IkcPD0.js +2874 -0
- package/dist/rich-text-editor-B2CKz7nx.cjs +2903 -0
- package/dist/rich-text-editor-B6jMRLzk.cjs +1939 -0
- package/dist/rich-text-editor-B8_oYcIR.js +1730 -0
- package/dist/rich-text-editor-B9UbSXNb.js +1203 -0
- package/dist/rich-text-editor-BYuRBNBU.js +2373 -0
- package/dist/rich-text-editor-Bb9pySTs.cjs +2374 -0
- package/dist/rich-text-editor-BcL6L3cm.cjs +2374 -0
- package/dist/rich-text-editor-BoVZYtTs.cjs +2391 -0
- package/dist/rich-text-editor-Bp3zQqMC.js +2954 -0
- package/dist/rich-text-editor-CMgSN_w2.js +1189 -0
- package/dist/rich-text-editor-CPV1lEPH.cjs +1748 -0
- package/dist/rich-text-editor-CeucBdIv.cjs +2971 -0
- package/dist/rich-text-editor-CoKqbCtu.cjs +1799 -0
- package/dist/rich-text-editor-Cw56T_mB.js +2356 -0
- package/dist/rich-text-editor-Cyt8qs2b.js +1921 -0
- package/dist/rich-text-editor-D6H84OcX.cjs +1220 -0
- package/dist/rich-text-editor-D76gD-QI.js +2328 -0
- package/dist/rich-text-editor-DKkokOnA.js +1781 -0
- package/dist/rich-text-editor-DNsdpN64.cjs +2359 -0
- package/dist/rich-text-editor-DfG8bCyY.js +2358 -0
- package/dist/rich-text-editor-DloeW0wc.js +2832 -0
- package/dist/rich-text-editor-Dxjw31Z4.js +2341 -0
- package/dist/rich-text-editor-DzP0Epmb.js +2356 -0
- package/dist/rich-text-editor-bRkNoeZY.cjs +2891 -0
- package/dist/rich-text-editor-lyYE2ZG5.cjs +1207 -0
- package/dist/rich-text-editor-skplNlBM.cjs +2345 -0
- package/dist/select-Bkbr0f-Z.cjs +162 -0
- package/dist/select-CvIVdX2n.js +145 -0
- package/dist/{sidebar-CplprZpM.js → sidebar-0ocFLSks.js} +127 -50
- package/dist/{sidebar-CA6_ek3f.js → sidebar-B6SlKZYN.js} +40 -49
- package/dist/{sidebar-CmvwjnVb.js → sidebar-BViy8Eeu.js} +17 -9
- package/dist/{sidebar-Dz7bd3zP.js → sidebar-BbVIQvlP.js} +1 -1
- package/dist/{sidebar-CVUGHOS_.cjs → sidebar-BxGXsDAd.cjs} +16 -8
- package/dist/sidebar-CK_0ZQHj.cjs +803 -0
- package/dist/sidebar-CUuOvYhK.js +787 -0
- package/dist/{sidebar-B3EYhli0.cjs → sidebar-CeTMuzOx.cjs} +128 -47
- package/dist/{sidebar-KIS0C2JH.js → sidebar-CrQDDdcz.js} +24 -33
- package/dist/{sidebar-zowjejT2.cjs → sidebar-DAaY8bRU.cjs} +24 -33
- package/dist/{sidebar-B9NR0lCe.cjs → sidebar-DQj1z3jG.cjs} +227 -269
- package/dist/sidebar-Djn5syhi.cjs +786 -0
- package/dist/sidebar-LluMXfam.js +759 -0
- package/dist/sidebar-_rT7rBMk.js +787 -0
- package/dist/{sidebar-BvF5I2Ue.cjs → sidebar-nzPoVHBQ.cjs} +41 -46
- package/dist/{sidebar-C5B_LHek.cjs → sidebar-q7P2Godd.cjs} +1 -1
- package/dist/slider-Bc5Hd0y1.js +56 -0
- package/dist/slider-N7hFFj6X.cjs +73 -0
- package/dist/tooltip-Ded96neP.cjs +137 -0
- package/dist/tooltip-HDOoD2-0.js +120 -0
- package/dist/ui.cjs.js +2 -2
- package/dist/ui.es.js +2 -2
- package/dist/use-audio-player-B31J-aqh.cjs +187 -0
- package/dist/use-audio-player-BkmEmj8Q.js +185 -0
- package/dist/use-audio-player-CLFTWFW1.cjs +184 -0
- package/dist/use-audio-player-CLLn00I6.js +188 -0
- package/dist/{use-audio-player-Dn1NR9xN.cjs → use-audio-player-NKsWyjWu.cjs} +7 -3
- package/dist/{use-audio-player-Bkh23vQ3.js → use-audio-player-nv8ZSGa1.js} +7 -3
- package/dist/use-file-upload-BcjEo2S5.js +404 -0
- package/dist/use-file-upload-CRJR68Tj.cjs +403 -0
- package/dist/use-mobile-B0hNy_Y6.cjs +4303 -0
- package/dist/use-mobile-BXuYROXM.js +4202 -0
- package/dist/use-mobile-Bbd51ASU.cjs +4392 -0
- package/dist/use-mobile-Bk6CX-TC.js +4359 -0
- package/dist/use-mobile-BvYdisLP.js +4202 -0
- package/dist/use-mobile-BzuxjzNX.cjs +4392 -0
- package/dist/use-mobile-CG2-SdXV.cjs +4235 -0
- package/dist/use-mobile-CKb5pqTs.js +4269 -0
- package/dist/use-mobile-CYuAuGDl.js +4202 -0
- package/dist/use-mobile-CaENcqm-.js +4508 -0
- package/dist/use-mobile-CbrYgJGJ.js +4203 -0
- package/dist/use-mobile-Cd4xPrKq.cjs +46 -0
- package/dist/use-mobile-DMOvImGQ.cjs +4542 -0
- package/dist/use-mobile-DRB3BQgD.cjs +4235 -0
- package/dist/use-mobile-DZvv7QMR.js +4359 -0
- package/dist/use-mobile-DdI_TXam.cjs +4235 -0
- package/dist/use-mobile-DlceKf8a.js +4359 -0
- package/dist/use-mobile-DsOnow1o.cjs +4236 -0
- package/dist/use-mobile-Kcj6jSnK.cjs +4392 -0
- package/dist/use-mobile-bnKcua_i.js +4202 -0
- package/dist/use-mobile-j4w2Jrf1.js +30 -0
- package/dist/use-mobile-ncXBeE2z.cjs +4235 -0
- package/dist/use-rich-text-editor-DjiddBGv.js +282 -0
- package/dist/use-rich-text-editor-lpeswbCs.cjs +281 -0
- package/dist/xertica-assistant-BdiZag0h.js +2187 -0
- package/dist/xertica-assistant-CrgTb6Hs.cjs +2155 -0
- package/dist/xertica-assistant-CyikE3N_.js +2173 -0
- package/dist/xertica-assistant-DCsnQyi5.js +2156 -0
- package/dist/xertica-assistant-DUBpmEgo.cjs +2186 -0
- package/dist/xertica-assistant-QFUnv5I2.cjs +2180 -0
- package/dist/{xertica-assistant-Bj3vBCq_.cjs → xertica-assistant-V_IdW4WF.cjs} +27 -9
- package/dist/{xertica-assistant-BMqdyRVi.js → xertica-assistant-ciJaWqm1.js} +28 -10
- package/dist/{xertica-assistant-B1IaHXnB.cjs → xertica-assistant-dyP7KHM5.cjs} +533 -392
- package/dist/{xertica-assistant-DPsESB6t.js → xertica-assistant-yX1CFBBo.js} +535 -394
- package/dist/xertica-ui.css +2 -2
- package/docs/architecture-improvements.md +456 -456
- package/docs/architecture.md +312 -312
- package/docs/components/assistant.md +428 -428
- package/docs/components/branding.md +252 -252
- package/docs/components/card-patterns.md +447 -447
- package/docs/components/error-boundary.md +201 -201
- package/docs/components/hooks.md +432 -432
- package/docs/components/language-selector.md +176 -176
- package/docs/components/pages.md +323 -323
- package/docs/components/sidebar.md +19 -2
- package/docs/components/stats-card.md +20 -2
- package/docs/doc-audit.md +244 -244
- package/docs/getting-started.md +616 -616
- package/docs/guidelines.md +330 -330
- package/docs/i18n.md +480 -480
- package/docs/installation.md +268 -268
- package/docs/llms.md +295 -295
- package/docs/state-management.md +289 -289
- package/guidelines/Guidelines.md +409 -409
- package/llms-compact.txt +30 -1
- package/llms-full.txt +11553 -7133
- package/llms.txt +1 -1
- package/package.json +219 -219
- package/styles/xertica/base.css +90 -90
- package/styles/xertica/tokens.css +9 -9
- package/templates/.prettierignore +4 -4
- package/templates/.prettierrc +10 -10
- package/templates/CLAUDE.md +180 -180
- package/templates/guidelines/Guidelines.md +865 -577
- package/templates/package.json +69 -69
- package/templates/src/app/App.tsx +46 -46
- package/templates/src/app/components/AuthGuard.tsx +131 -131
- package/templates/src/features/assistant/data/mock.ts +75 -75
- package/templates/src/features/assistant/hooks/useAssistantConfig.ts +20 -20
- package/templates/src/features/assistant/index.ts +5 -5
- package/templates/src/features/auth/ui/AuthPageShell.tsx +32 -32
- package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -70
- package/templates/src/features/auth/ui/LoginContent.tsx +92 -92
- package/templates/src/features/auth/ui/ResetPasswordContent.tsx +183 -183
- package/templates/src/features/auth/ui/SocialLoginButtons.tsx +78 -78
- package/templates/src/features/auth/ui/VerifyEmailContent.tsx +80 -80
- package/templates/src/features/home/data/mock.ts +41 -41
- package/templates/src/features/home/hooks/useFeatureCards.ts +20 -20
- package/templates/src/features/home/index.ts +11 -11
- package/templates/src/features/home/ui/HomeContent.tsx +117 -117
- package/templates/src/features/template/ui/CrudTemplate.tsx +112 -112
- package/templates/src/features/template/ui/DashboardTemplate.tsx +110 -110
- package/templates/src/features/template/ui/FormTemplate.tsx +117 -117
- package/templates/src/features/template/ui/LoginTemplate.tsx +59 -59
- package/templates/src/features/template/ui/TemplateContent.tsx +1322 -1322
- package/templates/src/i18n.ts +124 -124
- package/templates/src/locales/en/common.json +21 -21
- package/templates/src/locales/en/components/activityCard.json +10 -10
- package/templates/src/locales/en/components/assistant.json +119 -119
- package/templates/src/locales/en/components/media.json +29 -29
- package/templates/src/locales/en/components/notificationCard.json +5 -5
- package/templates/src/locales/en/components/profileCard.json +8 -8
- package/templates/src/locales/en/components/projectCard.json +10 -10
- package/templates/src/locales/en/components/sidebar.json +14 -14
- package/templates/src/locales/en/components/stats.json +8 -8
- package/templates/src/locales/en/components/team.json +14 -14
- package/templates/src/locales/en/errors.json +9 -9
- package/templates/src/locales/en/languageSelector.json +7 -7
- package/templates/src/locales/en/nav.json +6 -6
- package/templates/src/locales/en/pages/crudTemplate.json +25 -25
- package/templates/src/locales/en/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/en/pages/forgotPassword.json +10 -10
- package/templates/src/locales/en/pages/formTemplate.json +16 -16
- package/templates/src/locales/en/pages/home.json +7 -7
- package/templates/src/locales/en/pages/login.json +15 -15
- package/templates/src/locales/en/pages/loginTemplate.json +9 -9
- package/templates/src/locales/en/pages/resetPassword.json +18 -18
- package/templates/src/locales/en/pages/templates.json +317 -317
- package/templates/src/locales/en/pages/verifyEmail.json +12 -12
- package/templates/src/locales/en/themeToggle.json +6 -6
- package/templates/src/locales/es/common.json +21 -21
- package/templates/src/locales/es/components/activityCard.json +10 -10
- package/templates/src/locales/es/components/assistant.json +119 -119
- package/templates/src/locales/es/components/media.json +29 -29
- package/templates/src/locales/es/components/notificationCard.json +5 -5
- package/templates/src/locales/es/components/profileCard.json +8 -8
- package/templates/src/locales/es/components/projectCard.json +10 -10
- package/templates/src/locales/es/components/sidebar.json +14 -14
- package/templates/src/locales/es/components/stats.json +8 -8
- package/templates/src/locales/es/components/team.json +14 -14
- package/templates/src/locales/es/errors.json +9 -9
- package/templates/src/locales/es/languageSelector.json +7 -7
- package/templates/src/locales/es/nav.json +6 -6
- package/templates/src/locales/es/pages/crudTemplate.json +25 -25
- package/templates/src/locales/es/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/es/pages/forgotPassword.json +10 -10
- package/templates/src/locales/es/pages/formTemplate.json +16 -16
- package/templates/src/locales/es/pages/home.json +7 -7
- package/templates/src/locales/es/pages/login.json +15 -15
- package/templates/src/locales/es/pages/loginTemplate.json +9 -9
- package/templates/src/locales/es/pages/resetPassword.json +18 -18
- package/templates/src/locales/es/pages/templates.json +317 -317
- package/templates/src/locales/es/pages/verifyEmail.json +12 -12
- package/templates/src/locales/es/themeToggle.json +6 -6
- package/templates/src/locales/pt-BR/common.json +21 -21
- package/templates/src/locales/pt-BR/components/activityCard.json +10 -10
- package/templates/src/locales/pt-BR/components/assistant.json +119 -119
- package/templates/src/locales/pt-BR/components/media.json +29 -29
- package/templates/src/locales/pt-BR/components/notificationCard.json +5 -5
- package/templates/src/locales/pt-BR/components/profileCard.json +8 -8
- package/templates/src/locales/pt-BR/components/projectCard.json +10 -10
- package/templates/src/locales/pt-BR/components/sidebar.json +14 -14
- package/templates/src/locales/pt-BR/components/stats.json +8 -8
- package/templates/src/locales/pt-BR/components/team.json +14 -14
- package/templates/src/locales/pt-BR/errors.json +9 -9
- package/templates/src/locales/pt-BR/languageSelector.json +7 -7
- package/templates/src/locales/pt-BR/nav.json +6 -6
- package/templates/src/locales/pt-BR/pages/crudTemplate.json +25 -25
- package/templates/src/locales/pt-BR/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/pt-BR/pages/forgotPassword.json +10 -10
- package/templates/src/locales/pt-BR/pages/formTemplate.json +16 -16
- package/templates/src/locales/pt-BR/pages/home.json +7 -7
- package/templates/src/locales/pt-BR/pages/login.json +15 -15
- package/templates/src/locales/pt-BR/pages/loginTemplate.json +9 -9
- package/templates/src/locales/pt-BR/pages/resetPassword.json +18 -18
- package/templates/src/locales/pt-BR/pages/templates.json +317 -317
- package/templates/src/locales/pt-BR/pages/verifyEmail.json +12 -12
- package/templates/src/locales/pt-BR/themeToggle.json +6 -6
- package/templates/src/pages/AssistantPage.tsx +470 -470
- package/templates/src/pages/HomePage.tsx +53 -53
- package/templates/src/shared/error-boundary.tsx +150 -150
- package/templates/src/shared/error-fallbacks.tsx +222 -222
- package/templates/src/styles/xertica/tokens.css +9 -9
- package/templates/vite.config.js +20 -20
- package/templates/vite.config.ts +55 -55
- package/dist/ThemeContext-CpqYShLq.cjs +0 -324
- package/dist/ThemeContext-Du2nE1PL.js +0 -325
- package/dist/ThemeContext-GeEBTJ3q.cjs +0 -1621
- package/dist/ThemeContext-JyLK9B1o.js +0 -1622
- package/dist/VerifyEmailPage-BiRm7Nh4.cjs +0 -3213
- package/dist/VerifyEmailPage-hdB8JQGv.cjs +0 -3213
- package/dist/VerifyEmailPage-vYHbYK3q.js +0 -3214
- package/dist/XerticaProvider-CUYJZc32.js +0 -49
- package/dist/XerticaProvider-CjQAQPcn.cjs +0 -48
- package/dist/XerticaProvider-D5lLumH-.js +0 -49
- package/dist/XerticaProvider-qQUDop71.cjs +0 -48
- package/dist/XerticaXLogo-BWaag64t.js +0 -252
- package/dist/XerticaXLogo-CU-U-GP4.cjs +0 -251
- package/dist/index-CkTUgOwX.js +0 -8
- package/dist/sidebar-OTO_up7Z.js +0 -801
- package/dist/{rich-text-editor-BmsjY03B.js → rich-text-editor-DgF8s7xW.js} +26 -26
- package/dist/{rich-text-editor-GS2kpTAK.cjs → rich-text-editor-mWoaSCE4.cjs} +26 -26
|
@@ -1,206 +1,206 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { Button } from '../../ui/button';
|
|
3
|
-
import { XerticaLogo } from '../../brand/xertica-logo';
|
|
4
|
-
import { ImageWithFallback } from '../../figma/ImageWithFallback';
|
|
5
|
-
import { LanguageSelector } from '../../brand/language-selector';
|
|
6
|
-
import { ArrowLeft, Mail, CheckCircle2, Lock } from 'lucide-react';
|
|
7
|
-
import { useNavigate, useLocation } from 'react-router-dom';
|
|
8
|
-
import { useTranslation } from 'react-i18next';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Email Verification Page component.
|
|
12
|
-
*
|
|
13
|
-
* @description
|
|
14
|
-
* An informative screen shown after a password reset request. It instructs
|
|
15
|
-
* the user to check their email and provides a "Resend email" feature.
|
|
16
|
-
* Includes the same consistent layout with a hero image side-panel.
|
|
17
|
-
*
|
|
18
|
-
* @ai-rules
|
|
19
|
-
* 1. Data Source: It retrieves the email from the router's `location.state`.
|
|
20
|
-
* 2. Visual Feedback: Displays a temporary success message upon successful resale of the verification email.
|
|
21
|
-
* 3. Navigation: Includes a link to return to the `LoginPage`.
|
|
22
|
-
*/
|
|
23
|
-
export function VerifyEmailPage() {
|
|
24
|
-
const navigate = useNavigate();
|
|
25
|
-
const location = useLocation();
|
|
26
|
-
const { t } = useTranslation();
|
|
27
|
-
const email = location.state?.email || 'your@email.com';
|
|
28
|
-
const [isResending, setIsResending] = useState(false);
|
|
29
|
-
const [resendSuccess, setResendSuccess] = useState(false);
|
|
30
|
-
|
|
31
|
-
const handleResend = async () => {
|
|
32
|
-
setIsResending(true);
|
|
33
|
-
setResendSuccess(false);
|
|
34
|
-
|
|
35
|
-
// Simulate email resending
|
|
36
|
-
await new Promise(resolve => setTimeout(resolve, 1500));
|
|
37
|
-
|
|
38
|
-
setIsResending(false);
|
|
39
|
-
setResendSuccess(true);
|
|
40
|
-
|
|
41
|
-
// Remove success message after 3 seconds
|
|
42
|
-
setTimeout(() => setResendSuccess(false), 3000);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const handleSocialLogin = (_provider: string) => {
|
|
46
|
-
// Wire your SSO/social provider integration here
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<div className="h-full flex overflow-y-auto">
|
|
51
|
-
{/* Left side - Full background image */}
|
|
52
|
-
<div className="hidden lg:flex lg:flex-1 relative overflow-hidden">
|
|
53
|
-
{/* Background image filling all space */}
|
|
54
|
-
<ImageWithFallback
|
|
55
|
-
src="https://images.unsplash.com/photo-1563986768609-322da13575f3?w=1200&h=800&fit=crop&auto=format"
|
|
56
|
-
alt={t('verifyEmail.heroImageAlt')}
|
|
57
|
-
className="absolute inset-0 w-full h-full object-cover"
|
|
58
|
-
/>
|
|
59
|
-
|
|
60
|
-
{/* Gradient overlay */}
|
|
61
|
-
<div className="absolute inset-0 bg-[image:var(--gradient-diagonal)] opacity-80" />
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
{/* Right side - Content */}
|
|
65
|
-
<div className="flex-1 flex items-center justify-center px-4 sm:px-6 lg:px-8 lg:flex-none lg:w-1/2 relative bg-muted">
|
|
66
|
-
{/* Language selector in the top right corner */}
|
|
67
|
-
<div className="absolute top-4 right-4 z-20">
|
|
68
|
-
<LanguageSelector variant="minimal" showIcon={false} />
|
|
69
|
-
</div>
|
|
70
|
-
|
|
71
|
-
{/* Mobile background gradient */}
|
|
72
|
-
<div className="absolute inset-0 lg:hidden bg-[image:var(--gradient-diagonal)] opacity-10 dark:opacity-5" />
|
|
73
|
-
|
|
74
|
-
<div className="w-full max-w-sm space-y-6 relative z-10">
|
|
75
|
-
{/* Form header */}
|
|
76
|
-
<div className="text-center">
|
|
77
|
-
<div className="flex items-center justify-center mb-4">
|
|
78
|
-
<XerticaLogo
|
|
79
|
-
className="h-12 w-auto text-primary dark:text-foreground"
|
|
80
|
-
variant="theme"
|
|
81
|
-
/>
|
|
82
|
-
</div>
|
|
83
|
-
|
|
84
|
-
{/* Email icon */}
|
|
85
|
-
<div className="flex items-center justify-center mb-4">
|
|
86
|
-
<div className="p-4 bg-primary/10 rounded-[var(--radius)]">
|
|
87
|
-
<Mail className="w-12 h-12 text-primary" />
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
|
|
91
|
-
<h2 className="text-sm text-muted-foreground">{t('verifyEmail.heading')}</h2>
|
|
92
|
-
<p className="mt-2 text-muted-foreground">{t('verifyEmail.instructionsSent')}</p>
|
|
93
|
-
<p className="mt-1 text-primary">{email}</p>
|
|
94
|
-
</div>
|
|
95
|
-
|
|
96
|
-
{/* Instructions */}
|
|
97
|
-
<div className="bg-accent rounded-[var(--radius)] p-4 space-y-3">
|
|
98
|
-
<p className="text-muted-foreground">{t('verifyEmail.instructions')}</p>
|
|
99
|
-
<div className="flex items-start gap-2 text-muted-foreground">
|
|
100
|
-
<CheckCircle2 className="w-4 h-4 mt-0.5 flex-shrink-0 text-[var(--chart-2)]" />
|
|
101
|
-
<span className="text-sm">{t('verifyEmail.checkSpam')}</span>
|
|
102
|
-
</div>
|
|
103
|
-
</div>
|
|
104
|
-
|
|
105
|
-
{/* Success message on resend */}
|
|
106
|
-
{resendSuccess && (
|
|
107
|
-
<div className="bg-[var(--chart-2)]/10 border border-[var(--chart-2)]/20 rounded-[var(--radius)] p-3 flex items-center gap-2">
|
|
108
|
-
<CheckCircle2 className="w-5 h-5 text-[var(--chart-2)] flex-shrink-0" />
|
|
109
|
-
<span className="text-sm text-[var(--chart-2)]">
|
|
110
|
-
{t('verifyEmail.resentSuccess')}
|
|
111
|
-
</span>
|
|
112
|
-
</div>
|
|
113
|
-
)}
|
|
114
|
-
|
|
115
|
-
{/* Action buttons */}
|
|
116
|
-
<div className="space-y-3">
|
|
117
|
-
<p className="text-center text-muted-foreground">{t('verifyEmail.notReceived')}</p>
|
|
118
|
-
<Button
|
|
119
|
-
variant="outline"
|
|
120
|
-
className="w-full"
|
|
121
|
-
onClick={handleResend}
|
|
122
|
-
disabled={isResending}
|
|
123
|
-
>
|
|
124
|
-
{isResending ? t('verifyEmail.resending') : t('verifyEmail.resend')}
|
|
125
|
-
</Button>
|
|
126
|
-
|
|
127
|
-
<Button
|
|
128
|
-
type="button"
|
|
129
|
-
onClick={() => navigate('/login')}
|
|
130
|
-
variant="outline"
|
|
131
|
-
className="w-full text-muted-foreground hover:text-foreground"
|
|
132
|
-
>
|
|
133
|
-
<ArrowLeft className="w-4 h-4 mr-2" />
|
|
134
|
-
{t('verifyEmail.backToLogin')}
|
|
135
|
-
</Button>
|
|
136
|
-
</div>
|
|
137
|
-
|
|
138
|
-
{/* Divider */}
|
|
139
|
-
<div className="relative">
|
|
140
|
-
<div className="absolute inset-0 flex items-center">
|
|
141
|
-
<div className="w-full border-t border-border"></div>
|
|
142
|
-
</div>
|
|
143
|
-
<div className="relative flex justify-center text-sm">
|
|
144
|
-
<span className="bg-muted px-2 text-muted-foreground">
|
|
145
|
-
{t('login.orContinueWith')}
|
|
146
|
-
</span>
|
|
147
|
-
</div>
|
|
148
|
-
</div>
|
|
149
|
-
|
|
150
|
-
{/* Social/SSO login options */}
|
|
151
|
-
<div className="space-y-3">
|
|
152
|
-
{/* Google */}
|
|
153
|
-
<Button
|
|
154
|
-
type="button"
|
|
155
|
-
variant="outline"
|
|
156
|
-
className="w-full justify-center"
|
|
157
|
-
onClick={() => handleSocialLogin('Google')}
|
|
158
|
-
>
|
|
159
|
-
<svg className="w-5 h-5 mr-2" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
|
160
|
-
<path
|
|
161
|
-
fill="#EA4335"
|
|
162
|
-
d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"
|
|
163
|
-
></path>
|
|
164
|
-
<path
|
|
165
|
-
fill="#4285F4"
|
|
166
|
-
d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"
|
|
167
|
-
></path>
|
|
168
|
-
<path
|
|
169
|
-
fill="#FBBC05"
|
|
170
|
-
d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"
|
|
171
|
-
></path>
|
|
172
|
-
<path
|
|
173
|
-
fill="#34A853"
|
|
174
|
-
d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"
|
|
175
|
-
></path>
|
|
176
|
-
<path fill="none" d="M0 0h48v48H0z"></path>
|
|
177
|
-
</svg>
|
|
178
|
-
<span>{t('login.signInWithGoogle')}</span>
|
|
179
|
-
</Button>
|
|
180
|
-
|
|
181
|
-
{/* MT Login */}
|
|
182
|
-
<Button
|
|
183
|
-
type="button"
|
|
184
|
-
variant="outline"
|
|
185
|
-
className="w-full justify-center"
|
|
186
|
-
onClick={() => handleSocialLogin('MT Login')}
|
|
187
|
-
>
|
|
188
|
-
<Lock className="w-5 h-5 mr-2 text-[var(--chart-4)]" />
|
|
189
|
-
<span>{t('login.signInWithMTLogin')}</span>
|
|
190
|
-
</Button>
|
|
191
|
-
|
|
192
|
-
{/* gov.br */}
|
|
193
|
-
<Button
|
|
194
|
-
type="button"
|
|
195
|
-
variant="outline"
|
|
196
|
-
className="w-full justify-center font-normal"
|
|
197
|
-
onClick={() => handleSocialLogin('gov.br')}
|
|
198
|
-
>
|
|
199
|
-
<span>{t('login.signInWithGovBr')}</span>
|
|
200
|
-
</Button>
|
|
201
|
-
</div>
|
|
202
|
-
</div>
|
|
203
|
-
</div>
|
|
204
|
-
</div>
|
|
205
|
-
);
|
|
206
|
-
}
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Button } from '../../ui/button';
|
|
3
|
+
import { XerticaLogo } from '../../brand/xertica-logo';
|
|
4
|
+
import { ImageWithFallback } from '../../figma/ImageWithFallback';
|
|
5
|
+
import { LanguageSelector } from '../../brand/language-selector';
|
|
6
|
+
import { ArrowLeft, Mail, CheckCircle2, Lock } from 'lucide-react';
|
|
7
|
+
import { useNavigate, useLocation } from 'react-router-dom';
|
|
8
|
+
import { useTranslation } from 'react-i18next';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Email Verification Page component.
|
|
12
|
+
*
|
|
13
|
+
* @description
|
|
14
|
+
* An informative screen shown after a password reset request. It instructs
|
|
15
|
+
* the user to check their email and provides a "Resend email" feature.
|
|
16
|
+
* Includes the same consistent layout with a hero image side-panel.
|
|
17
|
+
*
|
|
18
|
+
* @ai-rules
|
|
19
|
+
* 1. Data Source: It retrieves the email from the router's `location.state`.
|
|
20
|
+
* 2. Visual Feedback: Displays a temporary success message upon successful resale of the verification email.
|
|
21
|
+
* 3. Navigation: Includes a link to return to the `LoginPage`.
|
|
22
|
+
*/
|
|
23
|
+
export function VerifyEmailPage() {
|
|
24
|
+
const navigate = useNavigate();
|
|
25
|
+
const location = useLocation();
|
|
26
|
+
const { t } = useTranslation();
|
|
27
|
+
const email = location.state?.email || 'your@email.com';
|
|
28
|
+
const [isResending, setIsResending] = useState(false);
|
|
29
|
+
const [resendSuccess, setResendSuccess] = useState(false);
|
|
30
|
+
|
|
31
|
+
const handleResend = async () => {
|
|
32
|
+
setIsResending(true);
|
|
33
|
+
setResendSuccess(false);
|
|
34
|
+
|
|
35
|
+
// Simulate email resending
|
|
36
|
+
await new Promise(resolve => setTimeout(resolve, 1500));
|
|
37
|
+
|
|
38
|
+
setIsResending(false);
|
|
39
|
+
setResendSuccess(true);
|
|
40
|
+
|
|
41
|
+
// Remove success message after 3 seconds
|
|
42
|
+
setTimeout(() => setResendSuccess(false), 3000);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const handleSocialLogin = (_provider: string) => {
|
|
46
|
+
// Wire your SSO/social provider integration here
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div className="h-screen w-full flex overflow-y-auto">
|
|
51
|
+
{/* Left side - Full background image */}
|
|
52
|
+
<div className="hidden lg:flex lg:flex-1 relative overflow-hidden">
|
|
53
|
+
{/* Background image filling all space */}
|
|
54
|
+
<ImageWithFallback
|
|
55
|
+
src="https://images.unsplash.com/photo-1563986768609-322da13575f3?w=1200&h=800&fit=crop&auto=format"
|
|
56
|
+
alt={t('verifyEmail.heroImageAlt')}
|
|
57
|
+
className="absolute inset-0 w-full h-full object-cover"
|
|
58
|
+
/>
|
|
59
|
+
|
|
60
|
+
{/* Gradient overlay */}
|
|
61
|
+
<div className="absolute inset-0 bg-[image:var(--gradient-diagonal)] opacity-80" />
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
{/* Right side - Content */}
|
|
65
|
+
<div className="flex-1 flex items-center justify-center px-4 sm:px-6 lg:px-8 lg:flex-none lg:w-1/2 relative bg-muted">
|
|
66
|
+
{/* Language selector in the top right corner */}
|
|
67
|
+
<div className="absolute top-4 right-4 z-20">
|
|
68
|
+
<LanguageSelector variant="minimal" showIcon={false} />
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
{/* Mobile background gradient */}
|
|
72
|
+
<div className="absolute inset-0 lg:hidden bg-[image:var(--gradient-diagonal)] opacity-10 dark:opacity-5" />
|
|
73
|
+
|
|
74
|
+
<div className="w-full max-w-sm space-y-6 relative z-10">
|
|
75
|
+
{/* Form header */}
|
|
76
|
+
<div className="text-center">
|
|
77
|
+
<div className="flex items-center justify-center mb-4">
|
|
78
|
+
<XerticaLogo
|
|
79
|
+
className="h-12 w-auto text-primary dark:text-foreground"
|
|
80
|
+
variant="theme"
|
|
81
|
+
/>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
{/* Email icon */}
|
|
85
|
+
<div className="flex items-center justify-center mb-4">
|
|
86
|
+
<div className="p-4 bg-primary/10 rounded-[var(--radius)]">
|
|
87
|
+
<Mail className="w-12 h-12 text-primary" />
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<h2 className="text-sm text-muted-foreground">{t('verifyEmail.heading')}</h2>
|
|
92
|
+
<p className="mt-2 text-muted-foreground">{t('verifyEmail.instructionsSent')}</p>
|
|
93
|
+
<p className="mt-1 text-primary">{email}</p>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
{/* Instructions */}
|
|
97
|
+
<div className="bg-accent rounded-[var(--radius)] p-4 space-y-3">
|
|
98
|
+
<p className="text-muted-foreground">{t('verifyEmail.instructions')}</p>
|
|
99
|
+
<div className="flex items-start gap-2 text-muted-foreground">
|
|
100
|
+
<CheckCircle2 className="w-4 h-4 mt-0.5 flex-shrink-0 text-[var(--chart-2)]" />
|
|
101
|
+
<span className="text-sm">{t('verifyEmail.checkSpam')}</span>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
{/* Success message on resend */}
|
|
106
|
+
{resendSuccess && (
|
|
107
|
+
<div className="bg-[var(--chart-2)]/10 border border-[var(--chart-2)]/20 rounded-[var(--radius)] p-3 flex items-center gap-2">
|
|
108
|
+
<CheckCircle2 className="w-5 h-5 text-[var(--chart-2)] flex-shrink-0" />
|
|
109
|
+
<span className="text-sm text-[var(--chart-2)]">
|
|
110
|
+
{t('verifyEmail.resentSuccess')}
|
|
111
|
+
</span>
|
|
112
|
+
</div>
|
|
113
|
+
)}
|
|
114
|
+
|
|
115
|
+
{/* Action buttons */}
|
|
116
|
+
<div className="space-y-3">
|
|
117
|
+
<p className="text-center text-muted-foreground">{t('verifyEmail.notReceived')}</p>
|
|
118
|
+
<Button
|
|
119
|
+
variant="outline"
|
|
120
|
+
className="w-full"
|
|
121
|
+
onClick={handleResend}
|
|
122
|
+
disabled={isResending}
|
|
123
|
+
>
|
|
124
|
+
{isResending ? t('verifyEmail.resending') : t('verifyEmail.resend')}
|
|
125
|
+
</Button>
|
|
126
|
+
|
|
127
|
+
<Button
|
|
128
|
+
type="button"
|
|
129
|
+
onClick={() => navigate('/login')}
|
|
130
|
+
variant="outline"
|
|
131
|
+
className="w-full text-muted-foreground hover:text-foreground"
|
|
132
|
+
>
|
|
133
|
+
<ArrowLeft className="w-4 h-4 mr-2" />
|
|
134
|
+
{t('verifyEmail.backToLogin')}
|
|
135
|
+
</Button>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
{/* Divider */}
|
|
139
|
+
<div className="relative">
|
|
140
|
+
<div className="absolute inset-0 flex items-center">
|
|
141
|
+
<div className="w-full border-t border-border"></div>
|
|
142
|
+
</div>
|
|
143
|
+
<div className="relative flex justify-center text-sm">
|
|
144
|
+
<span className="bg-muted px-2 text-muted-foreground">
|
|
145
|
+
{t('login.orContinueWith')}
|
|
146
|
+
</span>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
{/* Social/SSO login options */}
|
|
151
|
+
<div className="space-y-3">
|
|
152
|
+
{/* Google */}
|
|
153
|
+
<Button
|
|
154
|
+
type="button"
|
|
155
|
+
variant="outline"
|
|
156
|
+
className="w-full justify-center"
|
|
157
|
+
onClick={() => handleSocialLogin('Google')}
|
|
158
|
+
>
|
|
159
|
+
<svg className="w-5 h-5 mr-2" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
|
160
|
+
<path
|
|
161
|
+
fill="#EA4335"
|
|
162
|
+
d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"
|
|
163
|
+
></path>
|
|
164
|
+
<path
|
|
165
|
+
fill="#4285F4"
|
|
166
|
+
d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"
|
|
167
|
+
></path>
|
|
168
|
+
<path
|
|
169
|
+
fill="#FBBC05"
|
|
170
|
+
d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"
|
|
171
|
+
></path>
|
|
172
|
+
<path
|
|
173
|
+
fill="#34A853"
|
|
174
|
+
d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"
|
|
175
|
+
></path>
|
|
176
|
+
<path fill="none" d="M0 0h48v48H0z"></path>
|
|
177
|
+
</svg>
|
|
178
|
+
<span>{t('login.signInWithGoogle')}</span>
|
|
179
|
+
</Button>
|
|
180
|
+
|
|
181
|
+
{/* MT Login */}
|
|
182
|
+
<Button
|
|
183
|
+
type="button"
|
|
184
|
+
variant="outline"
|
|
185
|
+
className="w-full justify-center"
|
|
186
|
+
onClick={() => handleSocialLogin('MT Login')}
|
|
187
|
+
>
|
|
188
|
+
<Lock className="w-5 h-5 mr-2 text-[var(--chart-4)]" />
|
|
189
|
+
<span>{t('login.signInWithMTLogin')}</span>
|
|
190
|
+
</Button>
|
|
191
|
+
|
|
192
|
+
{/* gov.br */}
|
|
193
|
+
<Button
|
|
194
|
+
type="button"
|
|
195
|
+
variant="outline"
|
|
196
|
+
className="w-full justify-center font-normal"
|
|
197
|
+
onClick={() => handleSocialLogin('gov.br')}
|
|
198
|
+
>
|
|
199
|
+
<span>{t('login.signInWithGovBr')}</span>
|
|
200
|
+
</Button>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
@@ -1,114 +1,114 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import React, { useState } from 'react';
|
|
3
|
-
import { AppErrorBoundary, PageErrorBoundary, SectionErrorBoundary } from './error-boundary';
|
|
4
|
-
|
|
5
|
-
// ── Crash helper ─────────────────────────────────────────────────────────────
|
|
6
|
-
// A component that throws on the next render when `shouldCrash` is true.
|
|
7
|
-
// Used in every story to demonstrate real boundary behaviour.
|
|
8
|
-
|
|
9
|
-
function Crashable({ shouldCrash, label }: { shouldCrash: boolean; label: string }) {
|
|
10
|
-
if (shouldCrash) throw new Error(`Simulated crash in: ${label}`);
|
|
11
|
-
return (
|
|
12
|
-
<div className="flex items-center justify-center p-8 rounded-[var(--radius-lg)] border border-border bg-card text-card-foreground">
|
|
13
|
-
<p className="text-sm text-muted-foreground">
|
|
14
|
-
✅ <strong>{label}</strong> — rendering normally. Click the button to simulate a crash.
|
|
15
|
-
</p>
|
|
16
|
-
</div>
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// ── Wrapper that controls crash state ────────────────────────────────────────
|
|
21
|
-
|
|
22
|
-
function CrashController({
|
|
23
|
-
Boundary,
|
|
24
|
-
label,
|
|
25
|
-
}: {
|
|
26
|
-
Boundary: React.ComponentType<{ children: React.ReactNode }>;
|
|
27
|
-
label: string;
|
|
28
|
-
}) {
|
|
29
|
-
const [crashed, setCrashed] = useState(false);
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<div className="space-y-4">
|
|
33
|
-
<button
|
|
34
|
-
onClick={() => setCrashed(true)}
|
|
35
|
-
disabled={crashed}
|
|
36
|
-
className="inline-flex items-center px-4 py-2 text-sm rounded-[var(--radius-button)] bg-destructive text-destructive-foreground hover:bg-destructive/90 disabled:opacity-40 disabled:cursor-not-allowed"
|
|
37
|
-
>
|
|
38
|
-
Simulate crash
|
|
39
|
-
</button>
|
|
40
|
-
|
|
41
|
-
<Boundary>
|
|
42
|
-
<Crashable shouldCrash={crashed} label={label} />
|
|
43
|
-
</Boundary>
|
|
44
|
-
</div>
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// ── Meta ──────────────────────────────────────────────────────────────────────
|
|
49
|
-
|
|
50
|
-
const meta: Meta = {
|
|
51
|
-
title: 'Shared/ErrorBoundary',
|
|
52
|
-
parameters: {
|
|
53
|
-
layout: 'padded',
|
|
54
|
-
docs: {
|
|
55
|
-
description: {
|
|
56
|
-
component:
|
|
57
|
-
'Three pre-configured ErrorBoundary variants for root, page, and section-level error isolation. Click "Simulate crash" to see each fallback UI.',
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export default meta;
|
|
64
|
-
|
|
65
|
-
// ── Stories ───────────────────────────────────────────────────────────────────
|
|
66
|
-
|
|
67
|
-
export const App: StoryObj = {
|
|
68
|
-
name: 'AppErrorBoundary (root fallback)',
|
|
69
|
-
render: () => <CrashController Boundary={AppErrorBoundary} label="App-level component" />,
|
|
70
|
-
parameters: {
|
|
71
|
-
docs: {
|
|
72
|
-
description: {
|
|
73
|
-
story:
|
|
74
|
-
'`AppErrorBoundary` renders a full-screen fallback using only inline styles — no Tailwind dependency — so it works even if the design system itself fails to load.',
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export const Page: StoryObj = {
|
|
81
|
-
name: 'PageErrorBoundary (route fallback)',
|
|
82
|
-
render: () => <CrashController Boundary={PageErrorBoundary} label="Page component" />,
|
|
83
|
-
parameters: {
|
|
84
|
-
docs: {
|
|
85
|
-
description: {
|
|
86
|
-
story:
|
|
87
|
-
'`PageErrorBoundary` shows a half-height Tailwind-styled fallback. The sidebar, header, and other chrome remain visible — only the page content area is replaced.',
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export const Section: StoryObj = {
|
|
94
|
-
name: 'SectionErrorBoundary (inline fallback)',
|
|
95
|
-
render: () => (
|
|
96
|
-
<div className="space-y-6 max-w-2xl">
|
|
97
|
-
<p className="text-sm text-muted-foreground">
|
|
98
|
-
Each card below is independently wrapped. Crashing one does not affect the others.
|
|
99
|
-
</p>
|
|
100
|
-
|
|
101
|
-
{(['Team table', 'Chart', 'Assistant panel'] as const).map(label => (
|
|
102
|
-
<CrashController key={label} Boundary={SectionErrorBoundary} label={label} />
|
|
103
|
-
))}
|
|
104
|
-
</div>
|
|
105
|
-
),
|
|
106
|
-
parameters: {
|
|
107
|
-
docs: {
|
|
108
|
-
description: {
|
|
109
|
-
story:
|
|
110
|
-
'`SectionErrorBoundary` renders a compact inline fallback. Multiple independent sections on the same page can each fail in isolation.',
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
};
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { AppErrorBoundary, PageErrorBoundary, SectionErrorBoundary } from './error-boundary';
|
|
4
|
+
|
|
5
|
+
// ── Crash helper ─────────────────────────────────────────────────────────────
|
|
6
|
+
// A component that throws on the next render when `shouldCrash` is true.
|
|
7
|
+
// Used in every story to demonstrate real boundary behaviour.
|
|
8
|
+
|
|
9
|
+
function Crashable({ shouldCrash, label }: { shouldCrash: boolean; label: string }) {
|
|
10
|
+
if (shouldCrash) throw new Error(`Simulated crash in: ${label}`);
|
|
11
|
+
return (
|
|
12
|
+
<div className="flex items-center justify-center p-8 rounded-[var(--radius-lg)] border border-border bg-card text-card-foreground">
|
|
13
|
+
<p className="text-sm text-muted-foreground">
|
|
14
|
+
✅ <strong>{label}</strong> — rendering normally. Click the button to simulate a crash.
|
|
15
|
+
</p>
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ── Wrapper that controls crash state ────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
function CrashController({
|
|
23
|
+
Boundary,
|
|
24
|
+
label,
|
|
25
|
+
}: {
|
|
26
|
+
Boundary: React.ComponentType<{ children: React.ReactNode }>;
|
|
27
|
+
label: string;
|
|
28
|
+
}) {
|
|
29
|
+
const [crashed, setCrashed] = useState(false);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div className="space-y-4">
|
|
33
|
+
<button
|
|
34
|
+
onClick={() => setCrashed(true)}
|
|
35
|
+
disabled={crashed}
|
|
36
|
+
className="inline-flex items-center px-4 py-2 text-sm rounded-[var(--radius-button)] bg-destructive text-destructive-foreground hover:bg-destructive/90 disabled:opacity-40 disabled:cursor-not-allowed"
|
|
37
|
+
>
|
|
38
|
+
Simulate crash
|
|
39
|
+
</button>
|
|
40
|
+
|
|
41
|
+
<Boundary>
|
|
42
|
+
<Crashable shouldCrash={crashed} label={label} />
|
|
43
|
+
</Boundary>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ── Meta ──────────────────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
const meta: Meta = {
|
|
51
|
+
title: 'Shared/ErrorBoundary',
|
|
52
|
+
parameters: {
|
|
53
|
+
layout: 'padded',
|
|
54
|
+
docs: {
|
|
55
|
+
description: {
|
|
56
|
+
component:
|
|
57
|
+
'Three pre-configured ErrorBoundary variants for root, page, and section-level error isolation. Click "Simulate crash" to see each fallback UI.',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default meta;
|
|
64
|
+
|
|
65
|
+
// ── Stories ───────────────────────────────────────────────────────────────────
|
|
66
|
+
|
|
67
|
+
export const App: StoryObj = {
|
|
68
|
+
name: 'AppErrorBoundary (root fallback)',
|
|
69
|
+
render: () => <CrashController Boundary={AppErrorBoundary} label="App-level component" />,
|
|
70
|
+
parameters: {
|
|
71
|
+
docs: {
|
|
72
|
+
description: {
|
|
73
|
+
story:
|
|
74
|
+
'`AppErrorBoundary` renders a full-screen fallback using only inline styles — no Tailwind dependency — so it works even if the design system itself fails to load.',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const Page: StoryObj = {
|
|
81
|
+
name: 'PageErrorBoundary (route fallback)',
|
|
82
|
+
render: () => <CrashController Boundary={PageErrorBoundary} label="Page component" />,
|
|
83
|
+
parameters: {
|
|
84
|
+
docs: {
|
|
85
|
+
description: {
|
|
86
|
+
story:
|
|
87
|
+
'`PageErrorBoundary` shows a half-height Tailwind-styled fallback. The sidebar, header, and other chrome remain visible — only the page content area is replaced.',
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export const Section: StoryObj = {
|
|
94
|
+
name: 'SectionErrorBoundary (inline fallback)',
|
|
95
|
+
render: () => (
|
|
96
|
+
<div className="space-y-6 max-w-2xl">
|
|
97
|
+
<p className="text-sm text-muted-foreground">
|
|
98
|
+
Each card below is independently wrapped. Crashing one does not affect the others.
|
|
99
|
+
</p>
|
|
100
|
+
|
|
101
|
+
{(['Team table', 'Chart', 'Assistant panel'] as const).map(label => (
|
|
102
|
+
<CrashController key={label} Boundary={SectionErrorBoundary} label={label} />
|
|
103
|
+
))}
|
|
104
|
+
</div>
|
|
105
|
+
),
|
|
106
|
+
parameters: {
|
|
107
|
+
docs: {
|
|
108
|
+
description: {
|
|
109
|
+
story:
|
|
110
|
+
'`SectionErrorBoundary` renders a compact inline fallback. Multiple independent sections on the same page can each fail in isolation.',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
};
|