xertica-ui 2.5.2 → 2.6.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 +687 -656
- package/README.md +482 -482
- package/assets/xertica-logo.svg +37 -37
- package/assets/xertica-x-logo.svg +20 -20
- package/bin/cli.ts +1293 -1256
- package/bin/generate-tokens.ts +256 -262
- package/bin/language-config.test.ts +32 -0
- package/bin/language-config.ts +36 -11
- package/components/Introduction.mdx +121 -121
- package/components/assistant/code-block/CodeBlock.tsx +7 -6
- package/components/assistant/code-block/code-block.mdx +38 -38
- package/components/assistant/code-block/code-block.test.tsx +2 -1
- package/components/assistant/formatted-document/FormattedDocument.tsx +3 -0
- package/components/assistant/formatted-document/formatted-document.mdx +31 -31
- package/components/assistant/formatted-document/formatted-document.test.tsx +5 -4
- package/components/assistant/markdown-message/MarkdownMessage.tsx +1 -1
- package/components/assistant/markdown-message/markdown-message.mdx +44 -44
- package/components/assistant/modern-chat-input/modern-chat-input.mdx +71 -71
- package/components/assistant/modern-chat-input/modern-chat-input.test.tsx +3 -2
- package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +1 -1
- package/components/assistant/xertica-assistant/types.ts +3 -2
- package/components/assistant/xertica-assistant/use-assistant.ts +5 -4
- package/components/assistant/xertica-assistant/xertica-assistant.mdx +66 -66
- package/components/assistant/xertica-assistant/xertica-assistant.test.tsx +2 -1
- package/components/blocks/card-patterns/card-patterns.mdx +123 -123
- package/components/brand/branding/branding.mdx +27 -27
- package/components/brand/language-selector/language-selector.mdx +126 -126
- package/components/brand/theme-toggle/theme-toggle.mdx +47 -47
- package/components/brand/theme-toggle/theme-toggle.test.tsx +6 -2
- package/components/brand/xertica-logo/xertica-logo.mdx +56 -56
- package/components/brand/xertica-orbe/xertica-orbe.mdx +38 -38
- package/components/brand/xertica-provider/XerticaProvider.tsx +112 -112
- package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
- package/components/brand/xertica-provider/xertica-provider.test.tsx +25 -13
- package/components/brand/xertica-xlogo/xertica-xlogo.mdx +55 -55
- package/components/examples/DrawingMapExample.tsx +1 -4
- package/components/layout/header/header.mdx +117 -117
- package/components/layout/header/header.test.tsx +2 -1
- package/components/layout/sidebar/sidebar.mdx +99 -99
- package/components/layout/sidebar/sidebar.stories.tsx +1033 -1033
- package/components/layout/sidebar/sidebar.test.tsx +2 -1
- package/components/layout/sidebar/sidebar.tsx +1509 -1501
- package/components/media/audio-player/AudioPlayer.mdx +67 -67
- package/components/media/audio-player/AudioPlayer.test.tsx +2 -1
- package/components/media/floating-media-wrapper.mdx +74 -74
- package/components/media/video-player/VideoPlayer.mdx +102 -102
- package/components/media/video-player/VideoPlayer.test.tsx +3 -2
- package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +188 -188
- package/components/pages/forgot-password-page/forgot-password-page.mdx +60 -60
- package/components/pages/forgot-password-page/forgot-password-page.test.tsx +2 -1
- package/components/pages/home-content/HomeContent.tsx +2 -3
- package/components/pages/home-content/home-content.mdx +62 -62
- package/components/pages/home-page/HomePage.stories.tsx +8 -15
- package/components/pages/home-page/home-page.mdx +53 -53
- package/components/pages/home-page/home-page.test.tsx +2 -1
- package/components/pages/login-page/LoginPage.mdx +31 -31
- package/components/pages/login-page/LoginPage.tsx +218 -218
- package/components/pages/login-page/login-page.test.tsx +2 -1
- package/components/pages/reset-password-page/ResetPasswordPage.tsx +243 -243
- package/components/pages/reset-password-page/reset-password-page.mdx +63 -63
- package/components/pages/template-content/TemplateContent.tsx +2 -3
- package/components/pages/template-content/template-content.mdx +61 -61
- package/components/pages/template-page/TemplatePage.stories.tsx +32 -32
- package/components/pages/template-page/template-page.mdx +53 -53
- package/components/pages/template-page/template-page.test.tsx +2 -1
- package/components/pages/verify-email-page/VerifyEmailPage.tsx +206 -206
- package/components/pages/verify-email-page/verify-email-page.mdx +55 -55
- package/components/public-api-smoke.test.tsx +10 -6
- package/components/shared/assistant-utils.ts +3 -2
- package/components/shared/navigation.ts +2 -2
- package/components/ui/accordion/accordion.mdx +29 -29
- package/components/ui/alert/alert.mdx +29 -29
- package/components/ui/alert-dialog/alert-dialog.mdx +26 -26
- package/components/ui/aspect-ratio/aspect-ratio.mdx +25 -25
- package/components/ui/assistant-chart/AssistantChart.tsx +8 -2
- package/components/ui/assistant-chart/assistant-chart.mdx +25 -25
- package/components/ui/avatar/avatar.mdx +26 -26
- package/components/ui/badge/badge.mdx +28 -28
- package/components/ui/breadcrumb/breadcrumb.mdx +26 -26
- package/components/ui/button/button.mdx +29 -29
- package/components/ui/calendar/calendar.mdx +26 -26
- package/components/ui/card/card.mdx +26 -26
- package/components/ui/carousel/carousel.mdx +26 -26
- package/components/ui/chart/chart.mdx +26 -26
- package/components/ui/chart/chart.test.tsx +178 -178
- package/components/ui/chart/chart.tsx +2252 -2245
- package/components/ui/checkbox/checkbox.mdx +26 -26
- package/components/ui/collapsible/collapsible.mdx +25 -25
- package/components/ui/command/command.mdx +26 -26
- package/components/ui/context-menu/context-menu.mdx +26 -26
- package/components/ui/dialog/dialog.mdx +26 -26
- package/components/ui/drawer/drawer.mdx +26 -26
- package/components/ui/dropdown-menu/dropdown-menu.mdx +26 -26
- package/components/ui/empty/empty.mdx +26 -26
- package/components/ui/file-upload/file-upload.mdx +26 -26
- package/components/ui/form/form.mdx +20 -20
- package/components/ui/google-maps-loader/google-maps-loader.mdx +68 -68
- package/components/ui/hover-card/hover-card.mdx +26 -26
- package/components/ui/input/input.mdx +29 -29
- package/components/ui/input-otp/input-otp.mdx +26 -26
- package/components/ui/label/label.mdx +25 -25
- package/components/ui/map/map.mdx +26 -26
- package/components/ui/map/map.tsx +6 -1
- package/components/ui/menubar/menubar.mdx +26 -26
- package/components/ui/navigation-menu/navigation-menu.mdx +26 -26
- package/components/ui/notification-badge/notification-badge.mdx +26 -26
- package/components/ui/page-header/page-header.mdx +44 -44
- package/components/ui/pagination/pagination.mdx +26 -26
- package/components/ui/popover/popover.mdx +26 -26
- package/components/ui/progress/progress.mdx +25 -25
- package/components/ui/radio-group/radio-group.mdx +26 -26
- package/components/ui/rating/rating.mdx +26 -26
- package/components/ui/resizable/resizable.mdx +26 -26
- package/components/ui/resizable/resizable.tsx +13 -8
- package/components/ui/rich-text-editor/rich-text-editor.mdx +47 -47
- package/components/ui/route-map/route-map.mdx +26 -26
- package/components/ui/scroll-area/scroll-area.mdx +25 -25
- package/components/ui/search/search.mdx +27 -27
- package/components/ui/select/select.mdx +26 -26
- package/components/ui/separator/separator.mdx +25 -25
- package/components/ui/sheet/sheet.mdx +26 -26
- package/components/ui/simple-map/simple-map.mdx +25 -25
- package/components/ui/skeleton/skeleton.mdx +25 -25
- package/components/ui/slider/slider.mdx +26 -26
- package/components/ui/sonner/sonner.mdx +26 -26
- package/components/ui/stats-card/stats-card.mdx +26 -26
- package/components/ui/stats-card/stats-card.stories.tsx +117 -117
- package/components/ui/stats-card/stats-card.tsx +109 -109
- package/components/ui/stepper/stepper.mdx +26 -26
- package/components/ui/switch/switch.mdx +25 -25
- package/components/ui/table/table.mdx +27 -27
- package/components/ui/tabs/tabs.mdx +26 -26
- package/components/ui/textarea/textarea.mdx +25 -25
- package/components/ui/timeline/timeline.mdx +26 -26
- package/components/ui/toggle/toggle.mdx +26 -26
- package/components/ui/toggle-group/toggle-group.mdx +26 -26
- package/components/ui/tooltip/tooltip.mdx +26 -26
- package/components/ui/tree-view/tree-view.mdx +26 -26
- package/components.json +511 -511
- package/contexts/BrandColorsContext.tsx +282 -282
- package/contexts/i18n-singleton.test.tsx +57 -0
- package/contexts/theme-data.ts +391 -391
- package/dist/{AssistantChart-DMJJ_Amf.js → AssistantChart-BMNSA_Pk.js} +5 -5
- package/dist/{AssistantChart-D0A1FPYt.cjs → AssistantChart-BzM7plyc.cjs} +150 -114
- package/dist/{AssistantChart-BXU1ACnh.js → AssistantChart-C842evTi.js} +134 -240
- package/dist/{AssistantChart-BZTPJ5dP.cjs → AssistantChart-CVF2uh37.cjs} +5 -5
- package/dist/{AssistantChart-COGiOV-g.cjs → AssistantChart-JooMdVQU.cjs} +17 -7
- package/dist/{AssistantChart-CWX1OWNM.js → AssistantChart-KHS-tp-L.js} +17 -7
- package/dist/{BrandColorsContext-BwY-b6M4.cjs → BrandColorsContext-B4_81eas.cjs} +2 -2
- package/dist/{BrandColorsContext-BMRJ04Wf.js → BrandColorsContext-DbK5LnQ_.js} +2 -2
- package/dist/{CodeBlock-CjeFavqV.js → CodeBlock-DiKO8ocT.js} +11 -11
- package/dist/{CodeBlock-CV6dtsTM.cjs → CodeBlock-ZYThr7Kn.cjs} +12 -9
- package/dist/{XerticaXLogo-mqjoBiLI.js → LanguageSelector-CmTj3lWq.js} +85 -82
- package/dist/{XerticaXLogo-BX3ueACh.js → LanguageSelector-DxW6o7bt.js} +81 -81
- package/dist/{XerticaXLogo-uQgwns_E.cjs → LanguageSelector-Sw73qvWV.cjs} +84 -81
- package/dist/{ThemeContext-BgclCB35.js → ThemeContext-BGeh_Kdr.js} +290 -212
- package/dist/{ThemeContext-BblcjQup.cjs → ThemeContext-D50irx5T.cjs} +291 -205
- package/dist/{VerifyEmailPage-C_Zk6Gen.cjs → VerifyEmailPage-B6bOrybJ.cjs} +17 -17
- package/dist/{VerifyEmailPage-B31mCrMc.js → VerifyEmailPage-BRE5Fz59.js} +8 -8
- package/dist/{VerifyEmailPage-BJjAMUTW.js → VerifyEmailPage-BcCluouh.js} +151 -78
- package/dist/VerifyEmailPage-Bx1sr0uQ.cjs +3298 -0
- package/dist/{VerifyEmailPage-X14vhdyl.js → VerifyEmailPage-DUYyXCX9.js} +12 -12
- package/dist/VerifyEmailPage-DXXMHbzq.js +3289 -0
- package/dist/{VerifyEmailPage-u_Dn7t1U.cjs → VerifyEmailPage-DpYtFk35.cjs} +21 -21
- package/dist/{VerifyEmailPage-Cyl55sJb.js → VerifyEmailPage-NXKWW3Dk.js} +134 -64
- package/dist/{VerifyEmailPage-Bv8Ah_TK.cjs → VerifyEmailPage-QrCz4Wqr.cjs} +143 -73
- package/dist/{VerifyEmailPage-CkBYfsNy.cjs → VerifyEmailPage-ZmQra0Wi.cjs} +160 -87
- package/dist/{XerticaProvider-BErr83Bg.js → XerticaProvider-BF3q_myt.js} +5 -4
- package/dist/{XerticaProvider-CeS5G_n5.cjs → XerticaProvider-C_JSOz1U.cjs} +2 -2
- package/dist/{XerticaProvider-CwOkHxiT.cjs → XerticaProvider-D5zjrqZq.cjs} +5 -4
- package/dist/{XerticaProvider-ra2NciRq.js → XerticaProvider-KTGl4Cn1.js} +2 -2
- package/dist/{alert-dialog-DqlRW_An.js → alert-dialog-BrpwXKwS.js} +3 -3
- package/dist/{alert-dialog-DhwPioBa.cjs → alert-dialog-CZU1Zase.cjs} +3 -3
- package/dist/{alert-dialog-KpoabzJb.js → alert-dialog-ClRoLH7l.js} +40 -56
- package/dist/{alert-dialog-B4M3vQKS.cjs → alert-dialog-DBBqvU-V.cjs} +53 -38
- package/dist/assistant.cjs.js +2 -2
- package/dist/assistant.es.js +2 -2
- package/dist/brand.cjs.js +6 -6
- package/dist/brand.es.js +2 -2
- package/dist/cli.js +63 -21
- package/dist/components/assistant/code-block/CodeBlock.d.ts +2 -1
- package/dist/components/assistant/formatted-document/FormattedDocument.d.ts +2 -1
- package/dist/components/assistant/markdown-message/MarkdownMessage.d.ts +2 -1
- package/dist/components/assistant/modern-chat-input/ModernChatInput.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantCollapsedView.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantConversationList.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantHeader.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantMessageBubble.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantTabBar.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/types.d.ts +3 -2
- package/dist/components/assistant/xertica-assistant/use-assistant.d.ts +1 -1
- package/dist/components/assistant/xertica-assistant/xertica-assistant.d.ts +2 -1
- package/dist/components/blocks/card-patterns/ActivityCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/ActivityCardSkeleton.d.ts +1 -1
- package/dist/components/blocks/card-patterns/FeatureCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/FeatureCardSkeleton.d.ts +1 -1
- package/dist/components/blocks/card-patterns/NotificationCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/NotificationCardSkeleton.d.ts +1 -1
- package/dist/components/blocks/card-patterns/ProfileCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/ProfileCardSkeleton.d.ts +1 -1
- package/dist/components/blocks/card-patterns/ProjectCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/ProjectCardSkeleton.d.ts +1 -1
- package/dist/components/blocks/card-patterns/QuickActionCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/QuickActionCardSkeleton.d.ts +1 -1
- package/dist/components/brand/language-selector/LanguageSelector.d.ts +2 -1
- package/dist/components/brand/theme-toggle/ThemeToggle.d.ts +2 -1
- package/dist/components/brand/xertica-logo/XerticaLogo.d.ts +2 -1
- package/dist/components/brand/xertica-orbe/XerticaOrbe.d.ts +2 -1
- package/dist/components/brand/xertica-provider/XerticaProvider.d.ts +1 -1
- package/dist/components/brand/xertica-xlogo/XerticaXLogo.d.ts +2 -1
- package/dist/components/examples/DrawingMapExample.d.ts +2 -1
- package/dist/components/examples/FilterableMapExample.d.ts +1 -1
- package/dist/components/examples/MapShowcase.d.ts +2 -1
- package/dist/components/examples/SimpleFilterableMap.d.ts +2 -1
- package/dist/components/figma/ImageWithFallback.d.ts +1 -1
- package/dist/components/layout/header/header.d.ts +1 -1
- package/dist/components/layout/sidebar/sidebar.d.ts +25 -13
- package/dist/components/media/FloatingMediaWrapper.d.ts +1 -1
- package/dist/components/media/audio-player/AudioPlayer.d.ts +2 -1
- package/dist/components/media/video-player/VideoPlayer.d.ts +2 -1
- package/dist/components/pages/forgot-password-page/ForgotPasswordPage.d.ts +2 -1
- package/dist/components/pages/home-content/HomeContent.d.ts +2 -1
- package/dist/components/pages/home-page/HomePage.d.ts +2 -1
- package/dist/components/pages/login-page/LoginPage.d.ts +2 -1
- package/dist/components/pages/reset-password-page/ResetPasswordPage.d.ts +2 -1
- package/dist/components/pages/template-content/TemplateContent.d.ts +2 -1
- package/dist/components/pages/template-page/TemplatePage.d.ts +2 -1
- package/dist/components/pages/verify-email-page/VerifyEmailPage.d.ts +2 -1
- package/dist/components/shared/CustomTooltipContent.d.ts +1 -1
- package/dist/components/shared/assistant-utils.d.ts +3 -2
- package/dist/components/shared/error-boundary.d.ts +4 -4
- package/dist/components/shared/error-fallbacks.d.ts +4 -3
- package/dist/components/shared/navigation.d.ts +6 -2
- package/dist/components/ui/accordion/accordion.d.ts +4 -4
- package/dist/components/ui/alert/alert.d.ts +3 -3
- package/dist/components/ui/alert-dialog/alert-dialog.d.ts +10 -10
- package/dist/components/ui/aspect-ratio/aspect-ratio.d.ts +1 -1
- package/dist/components/ui/assistant-chart/AssistantChart.d.ts +4 -3
- package/dist/components/ui/avatar/avatar.d.ts +3 -3
- package/dist/components/ui/badge/badge.d.ts +1 -1
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts +7 -7
- package/dist/components/ui/calendar/calendar.d.ts +2 -2
- package/dist/components/ui/card/card.d.ts +7 -7
- package/dist/components/ui/carousel/carousel.d.ts +5 -5
- package/dist/components/ui/chart/chart.d.ts +16 -16
- package/dist/components/ui/collapsible/collapsible.d.ts +3 -3
- package/dist/components/ui/command/command.d.ts +9 -9
- package/dist/components/ui/context-menu/context-menu.d.ts +15 -15
- package/dist/components/ui/dialog/dialog.d.ts +9 -9
- package/dist/components/ui/drawer/drawer.d.ts +10 -10
- package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts +15 -15
- package/dist/components/ui/form/form.d.ts +7 -7
- package/dist/components/ui/google-maps-loader/google-maps-loader.d.ts +3 -3
- package/dist/components/ui/hover-card/hover-card.d.ts +3 -3
- package/dist/components/ui/input-otp/input-otp.d.ts +4 -4
- package/dist/components/ui/label/label.d.ts +1 -1
- package/dist/components/ui/menubar/menubar.d.ts +16 -16
- package/dist/components/ui/navigation-menu/navigation-menu.d.ts +8 -8
- package/dist/components/ui/page-header/page-header.d.ts +3 -3
- package/dist/components/ui/pagination/pagination.d.ts +7 -7
- package/dist/components/ui/popover/popover.d.ts +4 -4
- package/dist/components/ui/progress/progress.d.ts +1 -1
- package/dist/components/ui/resizable/resizable.d.ts +11 -7
- package/dist/components/ui/rich-text-editor/rich-text-editor.d.ts +1 -1
- package/dist/components/ui/scroll-area/scroll-area.d.ts +2 -2
- package/dist/components/ui/separator/separator.d.ts +1 -1
- package/dist/components/ui/sheet/sheet.d.ts +10 -10
- package/dist/components/ui/skeleton/skeleton.d.ts +1 -1
- package/dist/components/ui/sonner/sonner.d.ts +2 -1
- package/dist/components/ui/stats-card/stats-card-skeleton.d.ts +1 -1
- package/dist/components/ui/table/table.d.ts +8 -8
- package/dist/components/ui/tabs/tabs.d.ts +4 -4
- package/dist/components/ui/tooltip/tooltip.d.ts +4 -4
- package/dist/contexts/ApiKeyContext.d.ts +2 -2
- package/dist/contexts/AssistenteContext.d.ts +1 -1
- package/dist/contexts/AuthContext.d.ts +1 -1
- package/dist/contexts/LanguageContext.d.ts +2 -2
- package/dist/contexts/LayoutContext.d.ts +2 -2
- package/dist/contexts/ThemeContext.d.ts +1 -1
- package/dist/features/assistant/hooks/useAssistantConfig.d.ts +1 -1
- package/dist/features/home/hooks/useDashboardStats.d.ts +1 -1
- package/dist/features/home/hooks/useFeatureCards.d.ts +1 -1
- package/dist/features/home/hooks/useTeamMembers.d.ts +1 -1
- package/dist/{google-maps-loader-BCe58h9D.js → google-maps-loader-BOug999f.js} +0 -4
- package/dist/{google-maps-loader-casMyxlo.cjs → google-maps-loader-DfeBRI8Q.cjs} +0 -5
- package/dist/hooks.cjs.js +2 -2
- package/dist/hooks.es.js +2 -2
- package/dist/{index-9GWd0qxq.cjs → index-BQjx1Mdf.cjs} +1 -1
- package/dist/index-Bei5DzAL.js +6 -0
- package/dist/index.cjs.js +18 -18
- package/dist/index.es.js +12 -12
- package/dist/{input-cc-PTD4R.js → input-B0_vbA3g.js} +3 -61
- package/dist/{input-C_UiS2Py.cjs → input-ByYuOv8A.cjs} +1 -62
- 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/{rich-text-editor-DxO1Hz3a.cjs → rich-text-editor-BuqSu718.cjs} +70 -5
- package/dist/{rich-text-editor-DqLICivI.js → rich-text-editor-CV8FtA_l.js} +68 -6
- package/dist/{rich-text-editor-DloeW0wc.js → rich-text-editor-DV1SixzE.js} +61 -3
- package/dist/{rich-text-editor-B2CKz7nx.cjs → rich-text-editor-DnSDglzW.cjs} +63 -2
- package/dist/{sidebar-BS1p2V7t.cjs → sidebar-BGJ0j567.cjs} +367 -9
- package/dist/{sidebar-3XyzjVBw.js → sidebar-BI6mZlC8.js} +364 -6
- package/dist/{sidebar-DyYvgyBj.cjs → sidebar-BtmotOg-.cjs} +367 -9
- package/dist/{sidebar-Duermn32.js → sidebar-D3EgGVxF.js} +77 -63
- package/dist/{sidebar-CLmIjgNd.cjs → sidebar-DDTqMGnR.cjs} +80 -66
- package/dist/{sidebar-B4ZWaMrE.js → sidebar-I7EXyf5D.js} +364 -6
- package/dist/ui.cjs.js +7 -7
- package/dist/ui.es.js +5 -5
- package/dist/{xertica-assistant-QFUnv5I2.cjs → xertica-assistant-BrF9jScR.cjs} +4 -4
- package/dist/{xertica-assistant-BbgzsgsG.js → xertica-assistant-CJVnvMqU.js} +55 -45
- package/dist/{xertica-assistant-d2qs2Vd9.cjs → xertica-assistant-CKPtc1z5.cjs} +58 -40
- package/dist/{xertica-assistant-CyikE3N_.js → xertica-assistant-CsBsxTsI.js} +2 -2
- package/dist/{xertica-assistant-CIaUlbIt.cjs → xertica-assistant-DER0brPQ.cjs} +6 -5
- package/dist/{xertica-assistant-B1NaSFFj.js → xertica-assistant-DQCjpk5M.js} +4 -3
- package/dist/{xertica-assistant-B687qEPU.js → xertica-assistant-Dk-9AJzw.js} +16 -7
- package/dist/{xertica-assistant-sOHwTgIP.cjs → xertica-assistant-DxhIKvuY.cjs} +18 -9
- package/dist/xertica-ui.css +2 -2
- package/docs/components/audio-player.md +1 -1
- package/docs/components/sidebar.md +331 -331
- package/docs/components/stats-card.md +138 -138
- package/docs/components/toggle.md +12 -0
- package/docs/doc-audit.md +35 -229
- package/docs/i18n.md +31 -10
- package/docs/llms.md +6 -4
- package/llms-compact.txt +444 -444
- package/llms-full.txt +12144 -12144
- package/llms.txt +187 -187
- package/package.json +223 -219
- package/scripts/a11y-audit.mjs +162 -162
- package/scripts/fix-stories.cjs +19 -19
- package/styles/globals.css +0 -1
- package/styles/xertica/base.css +8 -0
- package/styles/xertica/tokens.css +240 -240
- package/templates/.env.example +2 -2
- package/templates/.prettierignore +4 -4
- package/templates/.prettierrc +10 -10
- package/templates/guidelines/Guidelines.md +865 -865
- package/templates/index.html +13 -13
- package/templates/package.json +69 -69
- package/templates/src/app/components/AuthGuard.tsx +11 -0
- package/templates/src/features/auth/ui/AuthPageShell.tsx +32 -32
- package/templates/src/features/home/ui/HomeContent.tsx +2 -3
- package/templates/src/features/settings/index.ts +2 -0
- package/templates/src/features/settings/ui/SettingsContent.tsx +134 -0
- package/templates/src/features/template/ui/TemplateContent.tsx +2 -3
- package/templates/src/i18n.ts +36 -13
- package/templates/src/locales/en/pages/settings.json +15 -0
- package/templates/src/locales/es/pages/settings.json +15 -0
- package/templates/src/locales/pt-BR/pages/settings.json +15 -0
- package/templates/src/pages/SettingsPage.tsx +28 -0
- package/templates/src/shared/config/navigation.ts +2 -2
- package/templates/src/styles/xertica/tokens.css +240 -240
- package/templates/vite.config.d.ts +2 -2
- package/templates/vite.config.js +20 -20
- package/utils/gemini.ts +2 -2
- package/dist/AssistantChart-9w31gdAb.cjs +0 -3363
- package/dist/AssistantChart-BAudAfne.cjs +0 -3591
- package/dist/AssistantChart-BAx9VQvb.cjs +0 -3374
- package/dist/AssistantChart-BP8upjMk.js +0 -3565
- package/dist/AssistantChart-CVko2A1W.js +0 -3348
- package/dist/AssistantChart-CVzmmhx4.js +0 -3337
- package/dist/AssistantChart-CeU2dIb6.js +0 -3469
- package/dist/AssistantChart-DO5UuX4J.cjs +0 -3495
- package/dist/AudioPlayer-1ypwE2Wh.cjs +0 -936
- package/dist/AudioPlayer-BJ2IuRQW.cjs +0 -1275
- package/dist/AudioPlayer-BWDW6TN9.cjs +0 -1279
- package/dist/AudioPlayer-CM962GEh.js +0 -1280
- package/dist/AudioPlayer-CbZId7cj.cjs +0 -998
- package/dist/AudioPlayer-DU8zt8-z.js +0 -999
- package/dist/AudioPlayer-DuKXrCfy.js +0 -937
- package/dist/AudioPlayer-Xxma6_-H.js +0 -1276
- package/dist/BrandColorsContext-DLVJgtmH.js +0 -666
- package/dist/BrandColorsContext-DZT7JjeD.js +0 -659
- package/dist/BrandColorsContext-GUyFmkX0.cjs +0 -665
- package/dist/BrandColorsContext-awnBCmC4.cjs +0 -666
- package/dist/CodeBlock-C2ZUXt8V.js +0 -219
- package/dist/CodeBlock-C5oYnLQp.cjs +0 -218
- package/dist/CodeBlock-DuxdtN-l.js +0 -219
- package/dist/CodeBlock-POVYONvC.cjs +0 -218
- package/dist/CustomTooltipContent-BT6brkVJ.cjs +0 -49
- package/dist/CustomTooltipContent-CfOfikhq.js +0 -33
- package/dist/CustomTooltipContent-DHjkY0ww.js +0 -40
- package/dist/CustomTooltipContent-c_K-DWRr.cjs +0 -56
- package/dist/FeatureCard-9GhnlgL3.js +0 -336
- package/dist/FeatureCard-Bcb3Zi54.js +0 -302
- package/dist/FeatureCard-Cfs6Ishq.js +0 -485
- package/dist/FeatureCard-CkPd2psQ.cjs +0 -301
- package/dist/FeatureCard-Dkp-xmzM.cjs +0 -335
- package/dist/FeatureCard-ie3L8Fpr.cjs +0 -484
- package/dist/FeatureCardSkeleton-CAgu8stE.js +0 -27
- package/dist/FeatureCardSkeleton-mO3Bdm_V.cjs +0 -26
- package/dist/LanguageContext-BwhwC3G2.js +0 -657
- package/dist/LanguageContext-DvUt5jBg.cjs +0 -656
- package/dist/LayoutContext-BDmcZfMH.cjs +0 -84
- package/dist/LayoutContext-C4kKN9RV.cjs +0 -93
- package/dist/LayoutContext-CGEe1oPq.js +0 -94
- package/dist/LayoutContext-CwT5KLiW.cjs +0 -104
- package/dist/LayoutContext-DVLCsoQn.js +0 -105
- package/dist/LayoutContext-dbQvdC4O.js +0 -85
- package/dist/ThemeContext-BbBNoFTG.js +0 -735
- package/dist/ThemeContext-Bo-W2WZH.js +0 -1856
- package/dist/ThemeContext-CP3a0jxy.cjs +0 -1855
- package/dist/ThemeContext-Cmr8Ex8H.cjs +0 -734
- package/dist/ThemeContext-CpqYShLq.cjs +0 -324
- package/dist/ThemeContext-D3LzacmG.js +0 -188
- package/dist/ThemeContext-DQUOeziy.cjs +0 -1855
- package/dist/ThemeContext-Du2nE1PL.js +0 -325
- package/dist/ThemeContext-GeEBTJ3q.cjs +0 -1621
- package/dist/ThemeContext-JyLK9B1o.js +0 -1622
- package/dist/ThemeContext-RTy1m2Uq.js +0 -82
- package/dist/ThemeContext-U4dEYc6C.cjs +0 -187
- package/dist/ThemeContext-bSzuOit2.cjs +0 -81
- package/dist/ThemeContext-ept8jhXI.js +0 -1856
- package/dist/VerifyEmailPage-BE-L9mB7.js +0 -2828
- package/dist/VerifyEmailPage-BIBOKV7Z.js +0 -3214
- package/dist/VerifyEmailPage-BRSP-Pwt.cjs +0 -3196
- package/dist/VerifyEmailPage-Bae2cBXT.cjs +0 -2827
- package/dist/VerifyEmailPage-BiRm7Nh4.cjs +0 -3213
- package/dist/VerifyEmailPage-Bvfv8HVQ.js +0 -3214
- package/dist/VerifyEmailPage-CR7kb5df.cjs +0 -2827
- package/dist/VerifyEmailPage-C_ihbcth.js +0 -2828
- package/dist/VerifyEmailPage-CbgjOF0v.js +0 -2828
- package/dist/VerifyEmailPage-CdYPSJoO.js +0 -2828
- package/dist/VerifyEmailPage-D-FRj5TU.cjs +0 -3213
- package/dist/VerifyEmailPage-DF2ilhum.cjs +0 -3210
- package/dist/VerifyEmailPage-DMBh4NM9.cjs +0 -2827
- package/dist/VerifyEmailPage-DTtFfC-J.js +0 -3197
- package/dist/VerifyEmailPage-Dt7zgA4w.cjs +0 -2827
- package/dist/VerifyEmailPage-EhudUdqF.js +0 -3211
- package/dist/VerifyEmailPage-RrUApqBN.js +0 -3214
- package/dist/VerifyEmailPage-VoMI7MYH.cjs +0 -3213
- package/dist/VerifyEmailPage-hdB8JQGv.cjs +0 -3213
- package/dist/VerifyEmailPage-vYHbYK3q.js +0 -3214
- package/dist/XerticaOrbe-BCUVSPPB.cjs +0 -1924
- package/dist/XerticaOrbe-BGIB1CTK.js +0 -1355
- package/dist/XerticaOrbe-By8eEvR-.js +0 -1925
- package/dist/XerticaOrbe-FWGjBj0U.cjs +0 -1354
- package/dist/XerticaProvider-AChwphCO.cjs +0 -48
- package/dist/XerticaProvider-AbWlr7Af.cjs +0 -48
- package/dist/XerticaProvider-B8CaV7xu.cjs +0 -39
- package/dist/XerticaProvider-BITjgC5p.js +0 -39
- package/dist/XerticaProvider-BSyFrmC0.js +0 -49
- package/dist/XerticaProvider-By8q3Roe.cjs +0 -38
- package/dist/XerticaProvider-CUYJZc32.js +0 -49
- package/dist/XerticaProvider-CW9hpCdF.cjs +0 -39
- package/dist/XerticaProvider-CWgby5mY.js +0 -49
- package/dist/XerticaProvider-CWs6EwNa.js +0 -49
- package/dist/XerticaProvider-CiNKjMx1.cjs +0 -48
- package/dist/XerticaProvider-CjQAQPcn.cjs +0 -48
- package/dist/XerticaProvider-D5lLumH-.js +0 -49
- package/dist/XerticaProvider-DQtvJU7m.js +0 -40
- package/dist/XerticaProvider-DUOJg9iX.js +0 -49
- package/dist/XerticaProvider-Dl_b72_l.cjs +0 -51
- package/dist/XerticaProvider-qQUDop71.cjs +0 -48
- package/dist/XerticaProvider-siSt9uG2.js +0 -40
- package/dist/XerticaXLogo-8TTzBjHw.cjs +0 -251
- package/dist/XerticaXLogo-B2svDGZh.cjs +0 -251
- package/dist/XerticaXLogo-BWaag64t.js +0 -252
- package/dist/XerticaXLogo-CFuIlYFH.js +0 -252
- package/dist/XerticaXLogo-CU-U-GP4.cjs +0 -251
- package/dist/XerticaXLogo-ChryA6xj.js +0 -252
- package/dist/XerticaXLogo-CowGv7BC.js +0 -252
- package/dist/XerticaXLogo-CziKMQil.cjs +0 -242
- package/dist/XerticaXLogo-D8jf0SNv.cjs +0 -214
- package/dist/XerticaXLogo-DHz5SugF.js +0 -252
- package/dist/XerticaXLogo-DTee_y8X.cjs +0 -251
- package/dist/XerticaXLogo-DfUvz-lD.js +0 -243
- package/dist/XerticaXLogo-DzXKZBtG.js +0 -231
- package/dist/XerticaXLogo-fAJMy3H4.js +0 -215
- package/dist/XerticaXLogo-kslQ8Tk_.cjs +0 -251
- package/dist/XerticaXLogo-xWbElCZj.cjs +0 -230
- package/dist/alert-dialog-iDe5VE5o.js +0 -842
- package/dist/alert-dialog-yckpaOpy.cjs +0 -865
- package/dist/avatar-Cq5_E8r9.cjs +0 -78
- package/dist/avatar-CuYu2MKt.cjs +0 -72
- package/dist/avatar-Cxyofu1H.js +0 -56
- package/dist/avatar-DSBfJMRJ.js +0 -62
- package/dist/breadcrumb-CVzzzqfo.js +0 -103
- package/dist/breadcrumb-DIJ0X3Ot.js +0 -96
- package/dist/breadcrumb-DjSxkjlQ.cjs +0 -95
- package/dist/breadcrumb-DnDlQFg2.cjs +0 -102
- package/dist/button-0CXwCRTm.cjs +0 -85
- package/dist/button-Bnv9SvYK.cjs +0 -79
- package/dist/button-C6uvh0rV.js +0 -63
- package/dist/button-qkz7Icqf.js +0 -69
- package/dist/card-B8-Gl5DL.js +0 -73
- package/dist/card-Bv_c57KU.cjs +0 -72
- package/dist/card-DJTsYhLL.cjs +0 -89
- package/dist/card-fi8zAN-I.js +0 -90
- package/dist/dropdown-menu-B_uEXNc4.cjs +0 -220
- package/dist/dropdown-menu-CFuCssWA.js +0 -204
- package/dist/dropdown-menu-Ze1YZFyc.cjs +0 -247
- package/dist/dropdown-menu-nc_Lvg-u.js +0 -231
- package/dist/google-maps-loader-BVoVhUwA.js +0 -316
- package/dist/google-maps-loader-BqsYL48U.cjs +0 -285
- package/dist/google-maps-loader-DjJaYhV6.cjs +0 -316
- package/dist/google-maps-loader-t2IlYBzw.js +0 -286
- package/dist/index-B7A523O_.js +0 -8
- package/dist/index-BabBx2pa.js +0 -6
- package/dist/index-CkTUgOwX.js +0 -8
- package/dist/index-D3RLKRAs.cjs +0 -7
- package/dist/index-DmHhnb7a.cjs +0 -7
- package/dist/index.umd.js +0 -13712
- package/dist/input-CNFHVKvo.cjs +0 -145
- package/dist/input-CPl84zAx.cjs +0 -151
- package/dist/input-D-6IsAca.js +0 -133
- package/dist/input-wPYg0d0P.js +0 -127
- package/dist/progress-BLwqortq.cjs +0 -105
- package/dist/progress-Cs9i4DPx.js +0 -81
- package/dist/progress-D9mtsf6j.js +0 -89
- package/dist/progress-DDeuWPZw.cjs +0 -97
- package/dist/rich-text-editor-1UW3Y2JK.js +0 -2891
- package/dist/rich-text-editor-BM-LPpTh.js +0 -2902
- package/dist/rich-text-editor-BmsjY03B.js +0 -2949
- package/dist/rich-text-editor-BrdC5evx.js +0 -2244
- package/dist/rich-text-editor-CyggTOLQ.cjs +0 -2908
- package/dist/rich-text-editor-DbV-S7Fi.cjs +0 -2261
- package/dist/rich-text-editor-DoCkKhzk.cjs +0 -2919
- package/dist/rich-text-editor-GS2kpTAK.cjs +0 -2966
- package/dist/routes.d.ts +0 -10
- package/dist/select-Cmb8zF7w.cjs +0 -156
- package/dist/select-CprSNX0z.js +0 -139
- package/dist/select-DT7Zjn42.cjs +0 -162
- package/dist/select-En8DkoaQ.js +0 -145
- package/dist/sidebar-B3EYhli0.cjs +0 -800
- package/dist/sidebar-B9NR0lCe.cjs +0 -800
- package/dist/sidebar-BcJ6LxvX.cjs +0 -733
- package/dist/sidebar-BvF5I2Ue.cjs +0 -800
- package/dist/sidebar-C5B_LHek.cjs +0 -795
- package/dist/sidebar-CA6_ek3f.js +0 -801
- package/dist/sidebar-CRMiBtAi.js +0 -801
- package/dist/sidebar-CVUGHOS_.cjs +0 -756
- package/dist/sidebar-CZ2mWaMM.cjs +0 -800
- package/dist/sidebar-CmvwjnVb.js +0 -757
- package/dist/sidebar-CplprZpM.js +0 -801
- package/dist/sidebar-Dz7bd3zP.js +0 -796
- package/dist/sidebar-KIS0C2JH.js +0 -801
- package/dist/sidebar-OTO_up7Z.js +0 -801
- package/dist/sidebar-WoKvFWCN.js +0 -717
- package/dist/sidebar-zowjejT2.cjs +0 -800
- package/dist/skeleton-4zoHiFJ_.cjs +0 -83
- package/dist/skeleton-C4bHqUBf.js +0 -84
- package/dist/slider-C0JKA9k3.js +0 -56
- package/dist/slider-CPmwzm_3.cjs +0 -73
- package/dist/slider-DcJharR9.cjs +0 -73
- package/dist/slider-Pay3fka2.js +0 -56
- package/dist/sonner-DeUIj0Zg.cjs +0 -63
- package/dist/sonner-g9RIfi35.js +0 -47
- package/dist/tooltip-CNtsL5cB.cjs +0 -71
- package/dist/tooltip-CTyZCD8h.js +0 -55
- package/dist/tooltip-CwgSdy3h.cjs +0 -67
- package/dist/tooltip-D-OrYnKO.js +0 -51
- package/dist/use-audio-player-BJFV24XW.js +0 -188
- package/dist/use-audio-player-Bkh23vQ3.js +0 -177
- package/dist/use-audio-player-Dn1NR9xN.cjs +0 -176
- package/dist/use-audio-player-DyVYlOnR.cjs +0 -187
- package/dist/use-mobile-BB4M_4Ru.cjs +0 -47
- package/dist/use-mobile-CLu9nqGL.js +0 -31
- package/dist/use-mobile-CNwiBNxu.js +0 -33
- package/dist/use-mobile-Dlf74ufz.cjs +0 -49
- package/dist/xertica-assistant-B1IaHXnB.cjs +0 -1894
- package/dist/xertica-assistant-BMqdyRVi.js +0 -2082
- package/dist/xertica-assistant-Bj3vBCq_.cjs +0 -2081
- package/dist/xertica-assistant-CfBCo21g.js +0 -2148
- package/dist/xertica-assistant-DIM_Do1k.js +0 -1866
- package/dist/xertica-assistant-DPsESB6t.js +0 -1878
- package/dist/xertica-assistant-DrsRwla1.cjs +0 -2147
- package/dist/xertica-assistant-Qp3ydksa.cjs +0 -1882
- package/dist/xertica-assistant-gnCJdcZY.js +0 -1866
- package/dist/xertica-assistant-yyrR0JKl.cjs +0 -1882
- package/styles/xertica/app-overrides/scrollbar.css +0 -33
- package/dist/{XerticaXLogo-qBPhwK3g.cjs → LanguageSelector-1cINLJ23.cjs} +80 -80
|
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react';
|
|
|
2
2
|
import { HomePage } from './HomePage';
|
|
3
3
|
import { MemoryRouter } from 'react-router-dom';
|
|
4
4
|
import { LayoutProvider } from '../../../contexts/LayoutContext';
|
|
5
|
+
import { AuthProvider } from '../../../contexts/AuthContext';
|
|
5
6
|
import React from 'react';
|
|
6
7
|
|
|
7
8
|
const meta: Meta<typeof HomePage> = {
|
|
@@ -10,9 +11,11 @@ const meta: Meta<typeof HomePage> = {
|
|
|
10
11
|
decorators: [
|
|
11
12
|
Story => (
|
|
12
13
|
<MemoryRouter initialEntries={['/home']}>
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
|
|
14
|
+
<AuthProvider>
|
|
15
|
+
<LayoutProvider>
|
|
16
|
+
<Story />
|
|
17
|
+
</LayoutProvider>
|
|
18
|
+
</AuthProvider>
|
|
16
19
|
</MemoryRouter>
|
|
17
20
|
),
|
|
18
21
|
],
|
|
@@ -24,16 +27,6 @@ const meta: Meta<typeof HomePage> = {
|
|
|
24
27
|
export default meta;
|
|
25
28
|
type Story = StoryObj<typeof HomePage>;
|
|
26
29
|
|
|
27
|
-
export const Default: Story = {
|
|
28
|
-
args: {
|
|
29
|
-
user: { email: 'ariel@xertica.com' },
|
|
30
|
-
onLogout: () => {},
|
|
31
|
-
},
|
|
32
|
-
};
|
|
30
|
+
export const Default: Story = {};
|
|
33
31
|
|
|
34
|
-
export const NoUser: Story = {
|
|
35
|
-
args: {
|
|
36
|
-
user: null,
|
|
37
|
-
onLogout: () => {},
|
|
38
|
-
},
|
|
39
|
-
};
|
|
32
|
+
export const NoUser: Story = {};
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
import { Meta, Title, Subtitle } from '@storybook/addon-docs/blocks';
|
|
2
|
-
import * as HomePageStories from './HomePage.stories';
|
|
3
|
-
|
|
4
|
-
<Meta of={HomePageStories} />
|
|
5
|
-
|
|
6
|
-
<Title>HomePage</Title>
|
|
7
|
-
<Subtitle>Full application shell composed from Sidebar, HomeContent, and XerticaAssistant.</Subtitle>
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Overview
|
|
12
|
-
|
|
13
|
-
`HomePage` is the root authenticated page. It assembles the three major layout pillars:
|
|
14
|
-
|
|
15
|
-
- **Sidebar** - Primary navigation.
|
|
16
|
-
- **HomeContent** - Dashboard area with breadcrumb header and feature card grid.
|
|
17
|
-
- **XerticaAssistant** - Floating AI assistant panel.
|
|
18
|
-
|
|
19
|
-
When `XerticaProvider` is present, the page synchronizes sidebar width, sidebar expansion, and assistant visibility through `LayoutContext`. Without the provider, it renders with local fallback layout state.
|
|
20
|
-
|
|
21
|
-
**Requires:** React Router v6. `XerticaProvider` is recommended for app-level synchronization.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Props
|
|
26
|
-
|
|
27
|
-
| Prop | Type | Required | Description |
|
|
28
|
-
|---|---|---|---|
|
|
29
|
-
| `user` | `{ email: string } \| null` | Yes | Currently authenticated user. Passed to Sidebar and HomeContent for display. |
|
|
30
|
-
| `onLogout` | `() => void` | Yes | Called when the user triggers logout from the Sidebar or Header. |
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Composition
|
|
35
|
-
|
|
36
|
-
```tsx
|
|
37
|
-
import { HomePage } from 'xertica-ui';
|
|
38
|
-
|
|
39
|
-
<Route
|
|
40
|
-
path="/home"
|
|
41
|
-
element={<HomePage user={currentUser} onLogout={handleLogout} />}
|
|
42
|
-
/>
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## AI Best Practices
|
|
48
|
-
|
|
49
|
-
> [!IMPORTANT]
|
|
50
|
-
> - **Top-level only** - `HomePage` is a full-screen layout component. Do not nest it inside other layouts.
|
|
51
|
-
> - **No logic here** - Keep business logic in `HomeContent` or lower-level components.
|
|
52
|
-
> - **Provider fallback** - The page renders without `XerticaProvider`, but the provider is recommended for synchronized app layout.
|
|
53
|
-
> - **Extend via HomeContent** - To add dashboard sections, edit `HomeContent`, not `HomePage`.
|
|
1
|
+
import { Meta, Title, Subtitle } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as HomePageStories from './HomePage.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={HomePageStories} />
|
|
5
|
+
|
|
6
|
+
<Title>HomePage</Title>
|
|
7
|
+
<Subtitle>Full application shell composed from Sidebar, HomeContent, and XerticaAssistant.</Subtitle>
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
`HomePage` is the root authenticated page. It assembles the three major layout pillars:
|
|
14
|
+
|
|
15
|
+
- **Sidebar** - Primary navigation.
|
|
16
|
+
- **HomeContent** - Dashboard area with breadcrumb header and feature card grid.
|
|
17
|
+
- **XerticaAssistant** - Floating AI assistant panel.
|
|
18
|
+
|
|
19
|
+
When `XerticaProvider` is present, the page synchronizes sidebar width, sidebar expansion, and assistant visibility through `LayoutContext`. Without the provider, it renders with local fallback layout state.
|
|
20
|
+
|
|
21
|
+
**Requires:** React Router v6. `XerticaProvider` is recommended for app-level synchronization.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Props
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Required | Description |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| `user` | `{ email: string } \| null` | Yes | Currently authenticated user. Passed to Sidebar and HomeContent for display. |
|
|
30
|
+
| `onLogout` | `() => void` | Yes | Called when the user triggers logout from the Sidebar or Header. |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Composition
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import { HomePage } from 'xertica-ui';
|
|
38
|
+
|
|
39
|
+
<Route
|
|
40
|
+
path="/home"
|
|
41
|
+
element={<HomePage user={currentUser} onLogout={handleLogout} />}
|
|
42
|
+
/>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## AI Best Practices
|
|
48
|
+
|
|
49
|
+
> [!IMPORTANT]
|
|
50
|
+
> - **Top-level only** - `HomePage` is a full-screen layout component. Do not nest it inside other layouts.
|
|
51
|
+
> - **No logic here** - Keep business logic in `HomeContent` or lower-level components.
|
|
52
|
+
> - **Provider fallback** - The page renders without `XerticaProvider`, but the provider is recommended for synchronized app layout.
|
|
53
|
+
> - **Extend via HomeContent** - To add dashboard sections, edit `HomeContent`, not `HomePage`.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { screen } from '@testing-library/react';
|
|
2
|
+
import { renderWithProviders as render } from '../../../test/render';
|
|
2
3
|
import { describe, it, expect, vi } from 'vitest';
|
|
3
4
|
import { HomePage } from './HomePage';
|
|
4
5
|
import React from 'react';
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Canvas } from '@storybook/addon-docs/blocks';
|
|
2
|
-
import * as LoginPageStories from './LoginPage.stories';
|
|
3
|
-
|
|
4
|
-
<Meta of={LoginPageStories} />
|
|
5
|
-
|
|
6
|
-
<Title />
|
|
7
|
-
<Subtitle>A complete, responsive login screen with hero image and SSO support.</Subtitle>
|
|
8
|
-
|
|
9
|
-
<Description />
|
|
10
|
-
|
|
11
|
-
<Primary />
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Features
|
|
16
|
-
- **Responsive Layout**: Side-by-side on desktop, stacked on mobile.
|
|
17
|
-
- **SSO Options**: Built-in support for Google, MT Login, and gov.br.
|
|
18
|
-
- **Form States**: Integrated loading and error handling.
|
|
19
|
-
|
|
20
|
-
<Canvas>
|
|
21
|
-
<LoginPageStories.Default />
|
|
22
|
-
</Canvas>
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## AI Best Practices
|
|
27
|
-
|
|
28
|
-
> [!IMPORTANT]
|
|
29
|
-
> - **Logic** — Provide the `onLogin` callback to handle actual authentication.
|
|
30
|
-
> - **Customization** — Customize hero images and SSO buttons as per project requirements.
|
|
31
|
-
> - **Routing** — The page uses `useNavigate()` for the forgot-password flow.
|
|
1
|
+
import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Canvas } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as LoginPageStories from './LoginPage.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={LoginPageStories} />
|
|
5
|
+
|
|
6
|
+
<Title />
|
|
7
|
+
<Subtitle>A complete, responsive login screen with hero image and SSO support.</Subtitle>
|
|
8
|
+
|
|
9
|
+
<Description />
|
|
10
|
+
|
|
11
|
+
<Primary />
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
- **Responsive Layout**: Side-by-side on desktop, stacked on mobile.
|
|
17
|
+
- **SSO Options**: Built-in support for Google, MT Login, and gov.br.
|
|
18
|
+
- **Form States**: Integrated loading and error handling.
|
|
19
|
+
|
|
20
|
+
<Canvas>
|
|
21
|
+
<LoginPageStories.Default />
|
|
22
|
+
</Canvas>
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## AI Best Practices
|
|
27
|
+
|
|
28
|
+
> [!IMPORTANT]
|
|
29
|
+
> - **Logic** — Provide the `onLogin` callback to handle actual authentication.
|
|
30
|
+
> - **Customization** — Customize hero images and SSO buttons as per project requirements.
|
|
31
|
+
> - **Routing** — The page uses `useNavigate()` for the forgot-password flow.
|
|
@@ -1,218 +1,218 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { Button } from '../../ui/button';
|
|
3
|
-
import { Input } from '../../ui/input';
|
|
4
|
-
import { Label } from '../../ui/label';
|
|
5
|
-
import { XerticaLogo } from '../../brand/xertica-logo';
|
|
6
|
-
import { ImageWithFallback } from '../../figma/ImageWithFallback';
|
|
7
|
-
import { LanguageSelector } from '../../brand/language-selector';
|
|
8
|
-
import { Lock } from 'lucide-react';
|
|
9
|
-
import { useNavigate } from 'react-router-dom';
|
|
10
|
-
import { useTranslation } from 'react-i18next';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Props for the LoginPage component.
|
|
14
|
-
*/
|
|
15
|
-
interface LoginPageProps {
|
|
16
|
-
/**
|
|
17
|
-
* Callback for login submission.
|
|
18
|
-
* Returns true if validation succeeds, false otherwise.
|
|
19
|
-
*/
|
|
20
|
-
onLogin: (email: string, password: string) => boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Standard Login Page component.
|
|
25
|
-
*
|
|
26
|
-
* @description
|
|
27
|
-
* A complete, responsive login screen featuring a hero image side-panel (on desktop)
|
|
28
|
-
* and a focused authentication form. Supports email/password login and placeholders
|
|
29
|
-
* for Social/SSO providers (Google, MT Login, gov.br).
|
|
30
|
-
*
|
|
31
|
-
* @ai-rules
|
|
32
|
-
* 1. State Management: You must provide the `onLogin` callback to handle the actual authentication logic.
|
|
33
|
-
* 2. Visuals: Hero images use `ImageWithFallback`. You can customize the `src` if needed.
|
|
34
|
-
* 3. Routing: Uses `react-router` for navigation to the forgot-password flow.
|
|
35
|
-
*/
|
|
36
|
-
export function LoginPage({ onLogin }: LoginPageProps) {
|
|
37
|
-
const navigate = useNavigate();
|
|
38
|
-
const { t } = useTranslation();
|
|
39
|
-
const [email, setEmail] = useState('');
|
|
40
|
-
const [password, setPassword] = useState('');
|
|
41
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
42
|
-
const [error, setError] = useState('');
|
|
43
|
-
|
|
44
|
-
const handleSubmit = async (e: React.FormEvent) => {
|
|
45
|
-
e.preventDefault();
|
|
46
|
-
setError('');
|
|
47
|
-
setIsLoading(true);
|
|
48
|
-
|
|
49
|
-
// Simulate a small delay to show loading state
|
|
50
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
51
|
-
|
|
52
|
-
const success = onLogin(email, password);
|
|
53
|
-
|
|
54
|
-
if (!success) {
|
|
55
|
-
setError(t('login.errorFillFields'));
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
setIsLoading(false);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const handleSocialLogin = (_provider: string) => {
|
|
62
|
-
// Wire your SSO/social provider integration here
|
|
63
|
-
onLogin('social@user.com', 'social-auth');
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
return (
|
|
67
|
-
<div className="h-screen w-full flex overflow-y-auto">
|
|
68
|
-
{/* Left side - Full background image */}
|
|
69
|
-
<div className="hidden lg:flex lg:flex-1 relative overflow-hidden">
|
|
70
|
-
{/* Background image filling all space */}
|
|
71
|
-
<ImageWithFallback
|
|
72
|
-
src="https://images.unsplash.com/photo-1551434678-e076c223a692?w=1200&h=800&fit=crop&auto=format"
|
|
73
|
-
alt={t('login.heroImageAlt')}
|
|
74
|
-
className="absolute inset-0 w-full h-full object-cover"
|
|
75
|
-
/>
|
|
76
|
-
|
|
77
|
-
{/* Gradient overlay */}
|
|
78
|
-
<div className="absolute inset-0 bg-[image:var(--gradient-diagonal)] opacity-80" />
|
|
79
|
-
</div>
|
|
80
|
-
|
|
81
|
-
{/* Right side - Form */}
|
|
82
|
-
<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">
|
|
83
|
-
{/* Language selector in the top right corner */}
|
|
84
|
-
<div className="absolute top-4 right-4 z-20">
|
|
85
|
-
<LanguageSelector variant="minimal" showIcon={false} />
|
|
86
|
-
</div>
|
|
87
|
-
|
|
88
|
-
{/* Mobile background gradient */}
|
|
89
|
-
<div className="absolute inset-0 lg:hidden bg-[image:var(--gradient-diagonal)] opacity-10 dark:opacity-5" />
|
|
90
|
-
<div className="w-full max-w-sm space-y-6 relative z-10">
|
|
91
|
-
{/* Form header */}
|
|
92
|
-
<div className="text-center">
|
|
93
|
-
<div className="flex items-center justify-center mb-4">
|
|
94
|
-
<XerticaLogo
|
|
95
|
-
className="h-12 w-auto text-primary dark:text-foreground"
|
|
96
|
-
variant="theme"
|
|
97
|
-
/>
|
|
98
|
-
</div>
|
|
99
|
-
<h2 className="text-sm text-muted-foreground">{t('login.heading')}</h2>
|
|
100
|
-
</div>
|
|
101
|
-
|
|
102
|
-
{/* Form */}
|
|
103
|
-
<form className="space-y-6" onSubmit={handleSubmit}>
|
|
104
|
-
<div className="space-y-2">
|
|
105
|
-
<Label htmlFor="email">{t('login.emailLabel')}</Label>
|
|
106
|
-
<Input
|
|
107
|
-
id="email"
|
|
108
|
-
name="email"
|
|
109
|
-
type="email"
|
|
110
|
-
required
|
|
111
|
-
className="w-full"
|
|
112
|
-
placeholder={t('login.emailPlaceholder')}
|
|
113
|
-
value={email}
|
|
114
|
-
onChange={e => setEmail(e.target.value)}
|
|
115
|
-
/>
|
|
116
|
-
</div>
|
|
117
|
-
|
|
118
|
-
<div className="space-y-2">
|
|
119
|
-
<Label htmlFor="password">{t('login.passwordLabel')}</Label>
|
|
120
|
-
<Input
|
|
121
|
-
id="password"
|
|
122
|
-
name="password"
|
|
123
|
-
type="password"
|
|
124
|
-
required
|
|
125
|
-
className="w-full"
|
|
126
|
-
placeholder="••••••••"
|
|
127
|
-
value={password}
|
|
128
|
-
onChange={e => setPassword(e.target.value)}
|
|
129
|
-
/>
|
|
130
|
-
</div>
|
|
131
|
-
|
|
132
|
-
{error && <div className="text-destructive text-sm text-center">{error}</div>}
|
|
133
|
-
|
|
134
|
-
<Button type="submit" className="w-full" disabled={isLoading}>
|
|
135
|
-
{isLoading ? t('login.submitting') : t('login.submit')}
|
|
136
|
-
</Button>
|
|
137
|
-
|
|
138
|
-
{/* Password recovery link */}
|
|
139
|
-
<div className="text-center">
|
|
140
|
-
<button
|
|
141
|
-
type="button"
|
|
142
|
-
onClick={() => navigate('/forgot-password')}
|
|
143
|
-
className="text-sm text-primary hover:opacity-80 transition-colors"
|
|
144
|
-
>
|
|
145
|
-
{t('login.forgotPassword')}
|
|
146
|
-
</button>
|
|
147
|
-
</div>
|
|
148
|
-
</form>
|
|
149
|
-
|
|
150
|
-
{/* Divider */}
|
|
151
|
-
<div className="relative">
|
|
152
|
-
<div className="absolute inset-0 flex items-center">
|
|
153
|
-
<div className="w-full border-t border-border"></div>
|
|
154
|
-
</div>
|
|
155
|
-
<div className="relative flex justify-center text-sm">
|
|
156
|
-
<span className="bg-muted px-2 text-muted-foreground">
|
|
157
|
-
{t('login.orContinueWith')}
|
|
158
|
-
</span>
|
|
159
|
-
</div>
|
|
160
|
-
</div>
|
|
161
|
-
|
|
162
|
-
{/* Social/SSO login options */}
|
|
163
|
-
<div className="space-y-3">
|
|
164
|
-
{/* Google */}
|
|
165
|
-
<Button
|
|
166
|
-
type="button"
|
|
167
|
-
variant="outline"
|
|
168
|
-
className="w-full justify-center"
|
|
169
|
-
onClick={() => handleSocialLogin('Google')}
|
|
170
|
-
>
|
|
171
|
-
<svg className="w-5 h-5 mr-2" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
|
172
|
-
<path
|
|
173
|
-
fill="#EA4335"
|
|
174
|
-
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"
|
|
175
|
-
></path>
|
|
176
|
-
<path
|
|
177
|
-
fill="#4285F4"
|
|
178
|
-
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"
|
|
179
|
-
></path>
|
|
180
|
-
<path
|
|
181
|
-
fill="#FBBC05"
|
|
182
|
-
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"
|
|
183
|
-
></path>
|
|
184
|
-
<path
|
|
185
|
-
fill="#34A853"
|
|
186
|
-
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"
|
|
187
|
-
></path>
|
|
188
|
-
<path fill="none" d="M0 0h48v48H0z"></path>
|
|
189
|
-
</svg>
|
|
190
|
-
<span>{t('login.signInWithGoogle')}</span>
|
|
191
|
-
</Button>
|
|
192
|
-
|
|
193
|
-
{/* MT Login */}
|
|
194
|
-
<Button
|
|
195
|
-
type="button"
|
|
196
|
-
variant="outline"
|
|
197
|
-
className="w-full justify-center"
|
|
198
|
-
onClick={() => handleSocialLogin('MT Login')}
|
|
199
|
-
>
|
|
200
|
-
<Lock className="w-5 h-5 mr-2 text-[var(--chart-4)]" />
|
|
201
|
-
<span>{t('login.signInWithMTLogin')}</span>
|
|
202
|
-
</Button>
|
|
203
|
-
|
|
204
|
-
{/* gov.br */}
|
|
205
|
-
<Button
|
|
206
|
-
type="button"
|
|
207
|
-
variant="outline"
|
|
208
|
-
className="w-full justify-center font-normal"
|
|
209
|
-
onClick={() => handleSocialLogin('gov.br')}
|
|
210
|
-
>
|
|
211
|
-
<span>{t('login.signInWithGovBr')}</span>
|
|
212
|
-
</Button>
|
|
213
|
-
</div>
|
|
214
|
-
</div>
|
|
215
|
-
</div>
|
|
216
|
-
</div>
|
|
217
|
-
);
|
|
218
|
-
}
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Button } from '../../ui/button';
|
|
3
|
+
import { Input } from '../../ui/input';
|
|
4
|
+
import { Label } from '../../ui/label';
|
|
5
|
+
import { XerticaLogo } from '../../brand/xertica-logo';
|
|
6
|
+
import { ImageWithFallback } from '../../figma/ImageWithFallback';
|
|
7
|
+
import { LanguageSelector } from '../../brand/language-selector';
|
|
8
|
+
import { Lock } from 'lucide-react';
|
|
9
|
+
import { useNavigate } from 'react-router-dom';
|
|
10
|
+
import { useTranslation } from 'react-i18next';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Props for the LoginPage component.
|
|
14
|
+
*/
|
|
15
|
+
interface LoginPageProps {
|
|
16
|
+
/**
|
|
17
|
+
* Callback for login submission.
|
|
18
|
+
* Returns true if validation succeeds, false otherwise.
|
|
19
|
+
*/
|
|
20
|
+
onLogin: (email: string, password: string) => boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Standard Login Page component.
|
|
25
|
+
*
|
|
26
|
+
* @description
|
|
27
|
+
* A complete, responsive login screen featuring a hero image side-panel (on desktop)
|
|
28
|
+
* and a focused authentication form. Supports email/password login and placeholders
|
|
29
|
+
* for Social/SSO providers (Google, MT Login, gov.br).
|
|
30
|
+
*
|
|
31
|
+
* @ai-rules
|
|
32
|
+
* 1. State Management: You must provide the `onLogin` callback to handle the actual authentication logic.
|
|
33
|
+
* 2. Visuals: Hero images use `ImageWithFallback`. You can customize the `src` if needed.
|
|
34
|
+
* 3. Routing: Uses `react-router` for navigation to the forgot-password flow.
|
|
35
|
+
*/
|
|
36
|
+
export function LoginPage({ onLogin }: LoginPageProps) {
|
|
37
|
+
const navigate = useNavigate();
|
|
38
|
+
const { t } = useTranslation();
|
|
39
|
+
const [email, setEmail] = useState('');
|
|
40
|
+
const [password, setPassword] = useState('');
|
|
41
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
42
|
+
const [error, setError] = useState('');
|
|
43
|
+
|
|
44
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
setError('');
|
|
47
|
+
setIsLoading(true);
|
|
48
|
+
|
|
49
|
+
// Simulate a small delay to show loading state
|
|
50
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
51
|
+
|
|
52
|
+
const success = onLogin(email, password);
|
|
53
|
+
|
|
54
|
+
if (!success) {
|
|
55
|
+
setError(t('login.errorFillFields'));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setIsLoading(false);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const handleSocialLogin = (_provider: string) => {
|
|
62
|
+
// Wire your SSO/social provider integration here
|
|
63
|
+
onLogin('social@user.com', 'social-auth');
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<div className="h-screen w-full flex overflow-y-auto">
|
|
68
|
+
{/* Left side - Full background image */}
|
|
69
|
+
<div className="hidden lg:flex lg:flex-1 relative overflow-hidden">
|
|
70
|
+
{/* Background image filling all space */}
|
|
71
|
+
<ImageWithFallback
|
|
72
|
+
src="https://images.unsplash.com/photo-1551434678-e076c223a692?w=1200&h=800&fit=crop&auto=format"
|
|
73
|
+
alt={t('login.heroImageAlt')}
|
|
74
|
+
className="absolute inset-0 w-full h-full object-cover"
|
|
75
|
+
/>
|
|
76
|
+
|
|
77
|
+
{/* Gradient overlay */}
|
|
78
|
+
<div className="absolute inset-0 bg-[image:var(--gradient-diagonal)] opacity-80" />
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
{/* Right side - Form */}
|
|
82
|
+
<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">
|
|
83
|
+
{/* Language selector in the top right corner */}
|
|
84
|
+
<div className="absolute top-4 right-4 z-20">
|
|
85
|
+
<LanguageSelector variant="minimal" showIcon={false} />
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
{/* Mobile background gradient */}
|
|
89
|
+
<div className="absolute inset-0 lg:hidden bg-[image:var(--gradient-diagonal)] opacity-10 dark:opacity-5" />
|
|
90
|
+
<div className="w-full max-w-sm space-y-6 relative z-10">
|
|
91
|
+
{/* Form header */}
|
|
92
|
+
<div className="text-center">
|
|
93
|
+
<div className="flex items-center justify-center mb-4">
|
|
94
|
+
<XerticaLogo
|
|
95
|
+
className="h-12 w-auto text-primary dark:text-foreground"
|
|
96
|
+
variant="theme"
|
|
97
|
+
/>
|
|
98
|
+
</div>
|
|
99
|
+
<h2 className="text-sm text-muted-foreground">{t('login.heading')}</h2>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
{/* Form */}
|
|
103
|
+
<form className="space-y-6" onSubmit={handleSubmit}>
|
|
104
|
+
<div className="space-y-2">
|
|
105
|
+
<Label htmlFor="email">{t('login.emailLabel')}</Label>
|
|
106
|
+
<Input
|
|
107
|
+
id="email"
|
|
108
|
+
name="email"
|
|
109
|
+
type="email"
|
|
110
|
+
required
|
|
111
|
+
className="w-full"
|
|
112
|
+
placeholder={t('login.emailPlaceholder')}
|
|
113
|
+
value={email}
|
|
114
|
+
onChange={e => setEmail(e.target.value)}
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<div className="space-y-2">
|
|
119
|
+
<Label htmlFor="password">{t('login.passwordLabel')}</Label>
|
|
120
|
+
<Input
|
|
121
|
+
id="password"
|
|
122
|
+
name="password"
|
|
123
|
+
type="password"
|
|
124
|
+
required
|
|
125
|
+
className="w-full"
|
|
126
|
+
placeholder="••••••••"
|
|
127
|
+
value={password}
|
|
128
|
+
onChange={e => setPassword(e.target.value)}
|
|
129
|
+
/>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
{error && <div className="text-destructive text-sm text-center">{error}</div>}
|
|
133
|
+
|
|
134
|
+
<Button type="submit" className="w-full" disabled={isLoading}>
|
|
135
|
+
{isLoading ? t('login.submitting') : t('login.submit')}
|
|
136
|
+
</Button>
|
|
137
|
+
|
|
138
|
+
{/* Password recovery link */}
|
|
139
|
+
<div className="text-center">
|
|
140
|
+
<button
|
|
141
|
+
type="button"
|
|
142
|
+
onClick={() => navigate('/forgot-password')}
|
|
143
|
+
className="text-sm text-primary hover:opacity-80 transition-colors"
|
|
144
|
+
>
|
|
145
|
+
{t('login.forgotPassword')}
|
|
146
|
+
</button>
|
|
147
|
+
</div>
|
|
148
|
+
</form>
|
|
149
|
+
|
|
150
|
+
{/* Divider */}
|
|
151
|
+
<div className="relative">
|
|
152
|
+
<div className="absolute inset-0 flex items-center">
|
|
153
|
+
<div className="w-full border-t border-border"></div>
|
|
154
|
+
</div>
|
|
155
|
+
<div className="relative flex justify-center text-sm">
|
|
156
|
+
<span className="bg-muted px-2 text-muted-foreground">
|
|
157
|
+
{t('login.orContinueWith')}
|
|
158
|
+
</span>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
{/* Social/SSO login options */}
|
|
163
|
+
<div className="space-y-3">
|
|
164
|
+
{/* Google */}
|
|
165
|
+
<Button
|
|
166
|
+
type="button"
|
|
167
|
+
variant="outline"
|
|
168
|
+
className="w-full justify-center"
|
|
169
|
+
onClick={() => handleSocialLogin('Google')}
|
|
170
|
+
>
|
|
171
|
+
<svg className="w-5 h-5 mr-2" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
|
172
|
+
<path
|
|
173
|
+
fill="#EA4335"
|
|
174
|
+
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"
|
|
175
|
+
></path>
|
|
176
|
+
<path
|
|
177
|
+
fill="#4285F4"
|
|
178
|
+
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"
|
|
179
|
+
></path>
|
|
180
|
+
<path
|
|
181
|
+
fill="#FBBC05"
|
|
182
|
+
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"
|
|
183
|
+
></path>
|
|
184
|
+
<path
|
|
185
|
+
fill="#34A853"
|
|
186
|
+
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"
|
|
187
|
+
></path>
|
|
188
|
+
<path fill="none" d="M0 0h48v48H0z"></path>
|
|
189
|
+
</svg>
|
|
190
|
+
<span>{t('login.signInWithGoogle')}</span>
|
|
191
|
+
</Button>
|
|
192
|
+
|
|
193
|
+
{/* MT Login */}
|
|
194
|
+
<Button
|
|
195
|
+
type="button"
|
|
196
|
+
variant="outline"
|
|
197
|
+
className="w-full justify-center"
|
|
198
|
+
onClick={() => handleSocialLogin('MT Login')}
|
|
199
|
+
>
|
|
200
|
+
<Lock className="w-5 h-5 mr-2 text-[var(--chart-4)]" />
|
|
201
|
+
<span>{t('login.signInWithMTLogin')}</span>
|
|
202
|
+
</Button>
|
|
203
|
+
|
|
204
|
+
{/* gov.br */}
|
|
205
|
+
<Button
|
|
206
|
+
type="button"
|
|
207
|
+
variant="outline"
|
|
208
|
+
className="w-full justify-center font-normal"
|
|
209
|
+
onClick={() => handleSocialLogin('gov.br')}
|
|
210
|
+
>
|
|
211
|
+
<span>{t('login.signInWithGovBr')}</span>
|
|
212
|
+
</Button>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
);
|
|
218
|
+
}
|