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,1354 +1,1354 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { Link, useNavigate } from 'react-router-dom';
|
|
3
|
-
import { Button } from '../../ui/button';
|
|
4
|
-
import { Input } from '../../ui/input';
|
|
5
|
-
import { Label } from '../../ui/label';
|
|
6
|
-
import {
|
|
7
|
-
Card,
|
|
8
|
-
CardHeader,
|
|
9
|
-
CardTitle,
|
|
10
|
-
CardDescription,
|
|
11
|
-
CardContent,
|
|
12
|
-
CardFooter,
|
|
13
|
-
} from '../../ui/card';
|
|
14
|
-
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../../ui/tabs';
|
|
15
|
-
import { Badge } from '../../ui/badge';
|
|
16
|
-
import { Alert, AlertDescription, AlertTitle } from '../../ui/alert';
|
|
17
|
-
import { Checkbox } from '../../ui/checkbox';
|
|
18
|
-
import { RadioGroup, RadioGroupItem } from '../../ui/radio-group';
|
|
19
|
-
import { Switch } from '../../ui/switch';
|
|
20
|
-
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
|
21
|
-
import { Textarea } from '../../ui/textarea';
|
|
22
|
-
import { Progress } from '../../ui/progress';
|
|
23
|
-
import { Separator } from '../../ui/separator';
|
|
24
|
-
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../../ui/table';
|
|
25
|
-
import {
|
|
26
|
-
Settings,
|
|
27
|
-
User,
|
|
28
|
-
Mail,
|
|
29
|
-
Phone,
|
|
30
|
-
Calendar,
|
|
31
|
-
Search,
|
|
32
|
-
Menu,
|
|
33
|
-
ChevronRight,
|
|
34
|
-
Home,
|
|
35
|
-
Users,
|
|
36
|
-
Plus,
|
|
37
|
-
Trash2,
|
|
38
|
-
Archive,
|
|
39
|
-
ArrowRightLeft,
|
|
40
|
-
History,
|
|
41
|
-
PanelRight,
|
|
42
|
-
FileEdit,
|
|
43
|
-
Filter,
|
|
44
|
-
Clock,
|
|
45
|
-
Map,
|
|
46
|
-
Bell,
|
|
47
|
-
} from 'lucide-react';
|
|
48
|
-
import { Slider } from '../../ui/slider';
|
|
49
|
-
import { toast } from 'sonner';
|
|
50
|
-
import { ScrollArea } from '../../ui/scroll-area';
|
|
51
|
-
import { ThemeToggle } from '../../brand/theme-toggle';
|
|
52
|
-
import { LanguageSelector } from '../../brand/language-selector';
|
|
53
|
-
import { MapShowcase } from '../../examples/MapShowcase';
|
|
54
|
-
import { Header } from '../../layout/header';
|
|
55
|
-
import { Sidebar } from '../../layout/sidebar';
|
|
56
|
-
import {
|
|
57
|
-
Dialog,
|
|
58
|
-
DialogTrigger,
|
|
59
|
-
DialogContent,
|
|
60
|
-
DialogHeader,
|
|
61
|
-
DialogTitle,
|
|
62
|
-
DialogDescription,
|
|
63
|
-
DialogFooter,
|
|
64
|
-
} from '../../ui/dialog';
|
|
65
|
-
import {
|
|
66
|
-
AlertDialog,
|
|
67
|
-
AlertDialogTrigger,
|
|
68
|
-
AlertDialogContent,
|
|
69
|
-
AlertDialogHeader,
|
|
70
|
-
AlertDialogTitle,
|
|
71
|
-
AlertDialogDescription,
|
|
72
|
-
AlertDialogFooter,
|
|
73
|
-
AlertDialogAction,
|
|
74
|
-
AlertDialogCancel,
|
|
75
|
-
} from '../../ui/alert-dialog';
|
|
76
|
-
import { PageHeader } from '../../ui/page-header';
|
|
77
|
-
|
|
78
|
-
import { useOptionalLayout } from '../../../contexts/LayoutContext';
|
|
79
|
-
import { useTheme } from '../../../contexts/ThemeContext';
|
|
80
|
-
import { useTeamMembers, useDashboardStore } from '../../../features/home';
|
|
81
|
-
import { useTranslation } from 'react-i18next';
|
|
82
|
-
import { SectionErrorBoundary } from '../../shared/error-boundary';
|
|
83
|
-
import { Skeleton } from '../../ui/skeleton';
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Comprehensive Showcase and Template Content component.
|
|
87
|
-
*
|
|
88
|
-
* @description
|
|
89
|
-
* This component serves as a living kitchen-sink demonstration of the Xertica UI
|
|
90
|
-
* Design System. It showcases almost every UI primitive (Cards, Tabs, Forms,
|
|
91
|
-
* Tables, Dialogs, etc.) and layout variation (Header flexibility, Sidebar
|
|
92
|
-
* toggling). It's primarily used for development, testing, and as a starting
|
|
93
|
-
* point for new pages.
|
|
94
|
-
*
|
|
95
|
-
* @ai-rules
|
|
96
|
-
* 1. Reference: Use this component as the primary source of truth for "how to compose" complex layouts in this library.
|
|
97
|
-
* 2. Layout: Adjusts its own padding based on the `useLayout` context's sidebar state.
|
|
98
|
-
* 3. Interaction: All showcase interactive elements (buttons, forms) use simple `toast` feedback or local state toggles.
|
|
99
|
-
*/
|
|
100
|
-
export function TemplateContent() {
|
|
101
|
-
const { t } = useTranslation();
|
|
102
|
-
const layout = useOptionalLayout();
|
|
103
|
-
const { disableDarkMode } = useTheme();
|
|
104
|
-
const [localSidebarExpanded, setLocalSidebarExpanded] = useState(false);
|
|
105
|
-
const [localSidebarWidth, setLocalSidebarWidth] = useState(280);
|
|
106
|
-
const sidebarExpanded = layout?.sidebarExpanded ?? localSidebarExpanded;
|
|
107
|
-
const sidebarWidth = layout?.sidebarWidth ?? localSidebarWidth;
|
|
108
|
-
const setSidebarWidth = layout?.setSidebarWidth ?? setLocalSidebarWidth;
|
|
109
|
-
const toggleSidebar = layout?.toggleSidebar ?? (() => setLocalSidebarExpanded(value => !value));
|
|
110
|
-
const navigate = useNavigate();
|
|
111
|
-
|
|
112
|
-
// Server state
|
|
113
|
-
const { data: teamMembers = [], isLoading: teamLoading } = useTeamMembers();
|
|
114
|
-
|
|
115
|
-
// Client-side UI state (Zustand)
|
|
116
|
-
const progress = useDashboardStore(s => s.progress);
|
|
117
|
-
const setProgress = useDashboardStore(s => s.setProgress);
|
|
118
|
-
const sliderValue = useDashboardStore(s => s.sliderValue);
|
|
119
|
-
const setSliderValue = useDashboardStore(s => s.setSliderValue);
|
|
120
|
-
const switchEnabled = useDashboardStore(s => s.switchEnabled);
|
|
121
|
-
const toggleSwitch = useDashboardStore(s => s.toggleSwitch);
|
|
122
|
-
|
|
123
|
-
// Local UI-only toggles (no global relevance)
|
|
124
|
-
const [showSidebarUser, setShowSidebarUser] = useState(true);
|
|
125
|
-
const [showSidebarSettings, setShowSidebarSettings] = useState(true);
|
|
126
|
-
const [showSidebarLogout, setShowSidebarLogout] = useState(true);
|
|
127
|
-
|
|
128
|
-
// Header State
|
|
129
|
-
const [showHeaderActions, setShowHeaderActions] = useState(true);
|
|
130
|
-
const [showHeaderBreadcrumbs, setShowHeaderBreadcrumbs] = useState(true);
|
|
131
|
-
|
|
132
|
-
const handleFormSubmit = (e: React.FormEvent) => {
|
|
133
|
-
e.preventDefault();
|
|
134
|
-
toast.success(t('templates.formSubmitSuccess'));
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
return (
|
|
138
|
-
<div
|
|
139
|
-
className="flex-1 flex flex-col overflow-hidden transition-all duration-300"
|
|
140
|
-
style={{
|
|
141
|
-
paddingLeft: sidebarExpanded ? `${sidebarWidth}px` : '80px',
|
|
142
|
-
}}
|
|
143
|
-
>
|
|
144
|
-
{/* Sticky Header */}
|
|
145
|
-
<Header
|
|
146
|
-
showThemeToggle={true}
|
|
147
|
-
showLanguageSelector={true}
|
|
148
|
-
breadcrumbs={[
|
|
149
|
-
{ label: t('nav.designSystem'), href: '/home', icon: <Home className="w-4 h-4" /> },
|
|
150
|
-
{ label: t('templates.breadcrumb') },
|
|
151
|
-
]}
|
|
152
|
-
renderLink={(href, props) => <Link to={href} {...props} />}
|
|
153
|
-
/>
|
|
154
|
-
|
|
155
|
-
{/* Content area */}
|
|
156
|
-
<main className="flex-1 overflow-hidden bg-muted">
|
|
157
|
-
<ScrollArea className="h-full">
|
|
158
|
-
<div className="p-5 sm:p-4 md:p-6">
|
|
159
|
-
<div className="max-w-6xl mx-auto space-y-8">
|
|
160
|
-
{/* Page header */}
|
|
161
|
-
<PageHeader title={t('templates.title')} subtitle={t('templates.subtitle')} />
|
|
162
|
-
|
|
163
|
-
{/* Page Header Example */}
|
|
164
|
-
<section>
|
|
165
|
-
<h3 className="mb-4">{t('templates.headerWithBreadcrumbs.sectionTitle')}</h3>
|
|
166
|
-
<Card>
|
|
167
|
-
<CardHeader>
|
|
168
|
-
<CardTitle>{t('templates.headerWithBreadcrumbs.cardTitle')}</CardTitle>
|
|
169
|
-
<CardDescription>
|
|
170
|
-
{t('templates.headerWithBreadcrumbs.cardDescription')}
|
|
171
|
-
</CardDescription>
|
|
172
|
-
</CardHeader>
|
|
173
|
-
<CardContent className="p-0 border-t bg-background overflow-hidden rounded-b-[var(--radius-lg)]">
|
|
174
|
-
<Header
|
|
175
|
-
className="border-b"
|
|
176
|
-
breadcrumbs={[
|
|
177
|
-
{
|
|
178
|
-
label: t('templates.headerWithBreadcrumbs.breadcrumbs.dashboard'),
|
|
179
|
-
href: '#',
|
|
180
|
-
icon: <Home className="w-4 h-4" />,
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
label: t('templates.headerWithBreadcrumbs.breadcrumbs.settings'),
|
|
184
|
-
href: '#',
|
|
185
|
-
icon: <Settings className="w-4 h-4" />,
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
label: t('templates.headerWithBreadcrumbs.breadcrumbs.users'),
|
|
189
|
-
href: '#',
|
|
190
|
-
icon: <Users className="w-4 h-4" />,
|
|
191
|
-
},
|
|
192
|
-
{ label: t('templates.headerWithBreadcrumbs.breadcrumbs.accessProfile') },
|
|
193
|
-
]}
|
|
194
|
-
showLanguageSelector={true}
|
|
195
|
-
showThemeToggle={true}
|
|
196
|
-
/>
|
|
197
|
-
<div className="p-6 min-h-[200px]">
|
|
198
|
-
<h4 className="text-lg font-semibold mb-2">
|
|
199
|
-
{t('templates.headerWithBreadcrumbs.exampleContentTitle')}
|
|
200
|
-
</h4>
|
|
201
|
-
<p className="text-muted-foreground">
|
|
202
|
-
{t('templates.headerWithBreadcrumbs.exampleContentDescriptionPart1')}
|
|
203
|
-
<strong>Header</strong>
|
|
204
|
-
{t('templates.headerWithBreadcrumbs.exampleContentDescriptionPart2')}
|
|
205
|
-
</p>
|
|
206
|
-
</div>
|
|
207
|
-
</CardContent>
|
|
208
|
-
</Card>
|
|
209
|
-
</section>
|
|
210
|
-
|
|
211
|
-
<Separator className="my-8" />
|
|
212
|
-
|
|
213
|
-
{/* Alert Examples */}
|
|
214
|
-
<section>
|
|
215
|
-
<h3 className="mb-4">{t('templates.sections.alerts')}</h3>
|
|
216
|
-
<div className="grid gap-4 md:grid-cols-2">
|
|
217
|
-
<Alert variant="info">
|
|
218
|
-
<AlertTitle>{t('templates.alerts.infoTitle')}</AlertTitle>
|
|
219
|
-
<AlertDescription>{t('templates.alerts.infoDescription')}</AlertDescription>
|
|
220
|
-
</Alert>
|
|
221
|
-
|
|
222
|
-
<Alert variant="destructive">
|
|
223
|
-
<AlertTitle>{t('templates.alerts.errorTitle')}</AlertTitle>
|
|
224
|
-
<AlertDescription>{t('templates.alerts.errorDescription')}</AlertDescription>
|
|
225
|
-
</Alert>
|
|
226
|
-
|
|
227
|
-
<Alert variant="success">
|
|
228
|
-
<AlertTitle>{t('templates.alerts.successTitle')}</AlertTitle>
|
|
229
|
-
<AlertDescription>{t('templates.alerts.successDescription')}</AlertDescription>
|
|
230
|
-
</Alert>
|
|
231
|
-
|
|
232
|
-
<Alert variant="warning">
|
|
233
|
-
<AlertTitle>{t('templates.alerts.warningTitle')}</AlertTitle>
|
|
234
|
-
<AlertDescription>{t('templates.alerts.warningDescription')}</AlertDescription>
|
|
235
|
-
</Alert>
|
|
236
|
-
</div>
|
|
237
|
-
</section>
|
|
238
|
-
|
|
239
|
-
<Separator className="my-8" />
|
|
240
|
-
|
|
241
|
-
{/* Cards & Tabs */}
|
|
242
|
-
<section>
|
|
243
|
-
<h3 className="mb-4">{t('templates.sections.cardsAndTabs')}</h3>
|
|
244
|
-
|
|
245
|
-
<Tabs defaultValue="overview" className="w-full">
|
|
246
|
-
<TabsList className="grid w-full grid-cols-4">
|
|
247
|
-
<TabsTrigger value="overview">{t('templates.tabs.overview')}</TabsTrigger>
|
|
248
|
-
<TabsTrigger value="forms">{t('templates.tabs.forms')}</TabsTrigger>
|
|
249
|
-
<TabsTrigger value="data">{t('templates.tabs.data')}</TabsTrigger>
|
|
250
|
-
<TabsTrigger value="settings">{t('templates.tabs.settings')}</TabsTrigger>
|
|
251
|
-
</TabsList>
|
|
252
|
-
|
|
253
|
-
{/* Overview Tab */}
|
|
254
|
-
<TabsContent value="overview" className="space-y-4">
|
|
255
|
-
<div className="grid gap-4 md:grid-cols-3">
|
|
256
|
-
<Card>
|
|
257
|
-
<CardHeader>
|
|
258
|
-
<CardTitle>{t('stats.totalUsers')}</CardTitle>
|
|
259
|
-
<CardDescription>{t('stats.last30Days')}</CardDescription>
|
|
260
|
-
</CardHeader>
|
|
261
|
-
<CardContent>
|
|
262
|
-
<div className="text-foreground">
|
|
263
|
-
<span className="[font-size:var(--text-stats)] [font-weight:var(--font-weight-bold)]">
|
|
264
|
-
1,234
|
|
265
|
-
</span>
|
|
266
|
-
<Badge variant="default" className="ml-2">
|
|
267
|
-
+12%
|
|
268
|
-
</Badge>
|
|
269
|
-
</div>
|
|
270
|
-
</CardContent>
|
|
271
|
-
</Card>
|
|
272
|
-
|
|
273
|
-
<Card>
|
|
274
|
-
<CardHeader>
|
|
275
|
-
<CardTitle>{t('stats.totalRevenue')}</CardTitle>
|
|
276
|
-
<CardDescription>{t('stats.currentMonth')}</CardDescription>
|
|
277
|
-
</CardHeader>
|
|
278
|
-
<CardContent>
|
|
279
|
-
<div className="text-foreground">
|
|
280
|
-
<span className="[font-size:var(--text-stats)] [font-weight:var(--font-weight-bold)]">
|
|
281
|
-
$ 45.2k
|
|
282
|
-
</span>
|
|
283
|
-
<Badge variant="secondary" className="ml-2">
|
|
284
|
-
+8%
|
|
285
|
-
</Badge>
|
|
286
|
-
</div>
|
|
287
|
-
</CardContent>
|
|
288
|
-
</Card>
|
|
289
|
-
|
|
290
|
-
<Card>
|
|
291
|
-
<CardHeader>
|
|
292
|
-
<CardTitle>{t('stats.conversionRate')}</CardTitle>
|
|
293
|
-
<CardDescription>{t('stats.currentWeek')}</CardDescription>
|
|
294
|
-
</CardHeader>
|
|
295
|
-
<CardContent>
|
|
296
|
-
<div className="text-foreground">
|
|
297
|
-
<span className="[font-size:var(--text-stats)] [font-weight:var(--font-weight-bold)]">
|
|
298
|
-
3.2%
|
|
299
|
-
</span>
|
|
300
|
-
<Badge variant="outline" className="ml-2">
|
|
301
|
-
-2%
|
|
302
|
-
</Badge>
|
|
303
|
-
</div>
|
|
304
|
-
</CardContent>
|
|
305
|
-
</Card>
|
|
306
|
-
</div>
|
|
307
|
-
|
|
308
|
-
<Card>
|
|
309
|
-
<CardHeader>
|
|
310
|
-
<CardTitle>{t('templates.overview.progressTitle')}</CardTitle>
|
|
311
|
-
<CardDescription>
|
|
312
|
-
{t('templates.overview.progressDescription')}
|
|
313
|
-
</CardDescription>
|
|
314
|
-
</CardHeader>
|
|
315
|
-
<CardContent className="space-y-6">
|
|
316
|
-
<div className="space-y-2">
|
|
317
|
-
<div className="flex items-center justify-between">
|
|
318
|
-
<Label>{t('templates.overview.projectProgress')}</Label>
|
|
319
|
-
<span className="[font-size:var(--text-small)] text-muted-foreground">
|
|
320
|
-
{progress}%
|
|
321
|
-
</span>
|
|
322
|
-
</div>
|
|
323
|
-
<Progress value={progress} className="w-full" />
|
|
324
|
-
<div className="flex gap-2">
|
|
325
|
-
<Button
|
|
326
|
-
size="sm"
|
|
327
|
-
onClick={() => setProgress(Math.max(0, progress - 10))}
|
|
328
|
-
>
|
|
329
|
-
-10%
|
|
330
|
-
</Button>
|
|
331
|
-
<Button
|
|
332
|
-
size="sm"
|
|
333
|
-
onClick={() => setProgress(Math.min(100, progress + 10))}
|
|
334
|
-
>
|
|
335
|
-
+10%
|
|
336
|
-
</Button>
|
|
337
|
-
</div>
|
|
338
|
-
</div>
|
|
339
|
-
|
|
340
|
-
<Separator />
|
|
341
|
-
|
|
342
|
-
<div className="space-y-2">
|
|
343
|
-
<div className="flex items-center justify-between">
|
|
344
|
-
<Label>{t('templates.overview.volume')}</Label>
|
|
345
|
-
<span className="[font-size:var(--text-small)] text-muted-foreground">
|
|
346
|
-
{sliderValue[0]}%
|
|
347
|
-
</span>
|
|
348
|
-
</div>
|
|
349
|
-
<Slider
|
|
350
|
-
value={sliderValue}
|
|
351
|
-
onValueChange={setSliderValue}
|
|
352
|
-
min={0}
|
|
353
|
-
max={100}
|
|
354
|
-
step={1}
|
|
355
|
-
className="w-full"
|
|
356
|
-
aria-label={t('templates.overview.volume')}
|
|
357
|
-
/>
|
|
358
|
-
</div>
|
|
359
|
-
</CardContent>
|
|
360
|
-
</Card>
|
|
361
|
-
</TabsContent>
|
|
362
|
-
|
|
363
|
-
{/* Forms Tab */}
|
|
364
|
-
<TabsContent value="forms" className="space-y-4">
|
|
365
|
-
<Card>
|
|
366
|
-
<CardHeader>
|
|
367
|
-
<CardTitle>{t('templates.forms.registrationTitle')}</CardTitle>
|
|
368
|
-
<CardDescription>
|
|
369
|
-
{t('templates.forms.registrationDescription')}
|
|
370
|
-
</CardDescription>
|
|
371
|
-
</CardHeader>
|
|
372
|
-
<CardContent>
|
|
373
|
-
<form onSubmit={handleFormSubmit} className="space-y-4">
|
|
374
|
-
<div className="grid gap-4 md:grid-cols-2">
|
|
375
|
-
<div className="space-y-2">
|
|
376
|
-
<Label htmlFor="firstName">{t('templates.forms.firstName')}</Label>
|
|
377
|
-
<Input
|
|
378
|
-
id="firstName"
|
|
379
|
-
placeholder={t('templates.forms.firstNamePlaceholder')}
|
|
380
|
-
/>
|
|
381
|
-
</div>
|
|
382
|
-
<div className="space-y-2">
|
|
383
|
-
<Label htmlFor="lastName">{t('templates.forms.lastName')}</Label>
|
|
384
|
-
<Input
|
|
385
|
-
id="lastName"
|
|
386
|
-
placeholder={t('templates.forms.lastNamePlaceholder')}
|
|
387
|
-
/>
|
|
388
|
-
</div>
|
|
389
|
-
</div>
|
|
390
|
-
|
|
391
|
-
<div className="space-y-2">
|
|
392
|
-
<Label htmlFor="email">{t('templates.forms.email')}</Label>
|
|
393
|
-
<div className="relative">
|
|
394
|
-
<Mail className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
|
395
|
-
<Input
|
|
396
|
-
id="email"
|
|
397
|
-
type="email"
|
|
398
|
-
placeholder={t('templates.forms.emailPlaceholder')}
|
|
399
|
-
className="pl-10"
|
|
400
|
-
/>
|
|
401
|
-
</div>
|
|
402
|
-
</div>
|
|
403
|
-
|
|
404
|
-
<div className="space-y-2">
|
|
405
|
-
<Label htmlFor="phone">{t('templates.forms.phone')}</Label>
|
|
406
|
-
<div className="relative">
|
|
407
|
-
<Phone className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
|
408
|
-
<Input
|
|
409
|
-
id="phone"
|
|
410
|
-
type="tel"
|
|
411
|
-
placeholder={t('templates.forms.phonePlaceholder')}
|
|
412
|
-
className="pl-10"
|
|
413
|
-
/>
|
|
414
|
-
</div>
|
|
415
|
-
</div>
|
|
416
|
-
|
|
417
|
-
<div className="space-y-2">
|
|
418
|
-
<Label htmlFor="role">{t('templates.forms.role')}</Label>
|
|
419
|
-
<Select>
|
|
420
|
-
<SelectTrigger id="role">
|
|
421
|
-
<SelectValue placeholder={t('templates.forms.rolePlaceholder')} />
|
|
422
|
-
</SelectTrigger>
|
|
423
|
-
<SelectContent>
|
|
424
|
-
<SelectItem value="developer">
|
|
425
|
-
{t('templates.forms.roles.developer')}
|
|
426
|
-
</SelectItem>
|
|
427
|
-
<SelectItem value="designer">
|
|
428
|
-
{t('templates.forms.roles.designer')}
|
|
429
|
-
</SelectItem>
|
|
430
|
-
<SelectItem value="manager">
|
|
431
|
-
{t('templates.forms.roles.manager')}
|
|
432
|
-
</SelectItem>
|
|
433
|
-
<SelectItem value="analyst">
|
|
434
|
-
{t('templates.forms.roles.analyst')}
|
|
435
|
-
</SelectItem>
|
|
436
|
-
</SelectContent>
|
|
437
|
-
</Select>
|
|
438
|
-
</div>
|
|
439
|
-
|
|
440
|
-
<div className="space-y-2">
|
|
441
|
-
<Label htmlFor="bio">{t('templates.forms.bio')}</Label>
|
|
442
|
-
<Textarea
|
|
443
|
-
id="bio"
|
|
444
|
-
placeholder={t('templates.forms.bioPlaceholder')}
|
|
445
|
-
rows={4}
|
|
446
|
-
/>
|
|
447
|
-
</div>
|
|
448
|
-
|
|
449
|
-
<Separator />
|
|
450
|
-
|
|
451
|
-
<div className="space-y-4">
|
|
452
|
-
<h4>{t('templates.forms.preferences')}</h4>
|
|
453
|
-
|
|
454
|
-
<div className="space-y-3">
|
|
455
|
-
<div className="flex items-center space-x-2">
|
|
456
|
-
<Checkbox id="newsletter" />
|
|
457
|
-
<Label htmlFor="newsletter" className="font-normal">
|
|
458
|
-
{t('templates.forms.newsletter')}
|
|
459
|
-
</Label>
|
|
460
|
-
</div>
|
|
461
|
-
|
|
462
|
-
<div className="flex items-center space-x-2">
|
|
463
|
-
<Checkbox id="notifications" />
|
|
464
|
-
<Label htmlFor="notifications" className="font-normal">
|
|
465
|
-
{t('templates.forms.pushNotifications')}
|
|
466
|
-
</Label>
|
|
467
|
-
</div>
|
|
468
|
-
|
|
469
|
-
<div className="flex items-center space-x-2">
|
|
470
|
-
<Checkbox id="updates" />
|
|
471
|
-
<Label htmlFor="updates" className="font-normal">
|
|
472
|
-
{t('templates.forms.featureUpdates')}
|
|
473
|
-
</Label>
|
|
474
|
-
</div>
|
|
475
|
-
</div>
|
|
476
|
-
|
|
477
|
-
<Separator />
|
|
478
|
-
|
|
479
|
-
<div className="space-y-3">
|
|
480
|
-
<Label>{t('templates.forms.accountType')}</Label>
|
|
481
|
-
<RadioGroup
|
|
482
|
-
defaultValue="personal"
|
|
483
|
-
aria-label={t('templates.forms.accountType')}
|
|
484
|
-
>
|
|
485
|
-
<div className="flex items-center space-x-2">
|
|
486
|
-
<RadioGroupItem value="personal" id="personal" />
|
|
487
|
-
<Label htmlFor="personal" className="font-normal">
|
|
488
|
-
{t('templates.forms.accountPersonal')}
|
|
489
|
-
</Label>
|
|
490
|
-
</div>
|
|
491
|
-
<div className="flex items-center space-x-2">
|
|
492
|
-
<RadioGroupItem value="business" id="business" />
|
|
493
|
-
<Label htmlFor="business" className="font-normal">
|
|
494
|
-
{t('templates.forms.accountBusiness')}
|
|
495
|
-
</Label>
|
|
496
|
-
</div>
|
|
497
|
-
<div className="flex items-center space-x-2">
|
|
498
|
-
<RadioGroupItem value="enterprise" id="enterprise" />
|
|
499
|
-
<Label htmlFor="enterprise" className="font-normal">
|
|
500
|
-
{t('templates.forms.accountEnterprise')}
|
|
501
|
-
</Label>
|
|
502
|
-
</div>
|
|
503
|
-
</RadioGroup>
|
|
504
|
-
</div>
|
|
505
|
-
</div>
|
|
506
|
-
</form>
|
|
507
|
-
</CardContent>
|
|
508
|
-
<CardFooter className="flex justify-between">
|
|
509
|
-
<Button variant="outline">{t('templates.forms.cancel')}</Button>
|
|
510
|
-
<Button onClick={handleFormSubmit}>
|
|
511
|
-
{t('templates.forms.createAccount')}
|
|
512
|
-
</Button>
|
|
513
|
-
</CardFooter>
|
|
514
|
-
</Card>
|
|
515
|
-
</TabsContent>
|
|
516
|
-
|
|
517
|
-
{/* Data Tab */}
|
|
518
|
-
<TabsContent value="data" className="space-y-4">
|
|
519
|
-
<SectionErrorBoundary>
|
|
520
|
-
<Card>
|
|
521
|
-
<CardHeader>
|
|
522
|
-
<CardTitle>{t('templates.data.title')}</CardTitle>
|
|
523
|
-
<CardDescription>{t('templates.data.description')}</CardDescription>
|
|
524
|
-
</CardHeader>
|
|
525
|
-
<CardContent>
|
|
526
|
-
<div className="mb-4">
|
|
527
|
-
<div className="relative">
|
|
528
|
-
<Search className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
|
529
|
-
<Input
|
|
530
|
-
placeholder={t('templates.data.searchPlaceholder')}
|
|
531
|
-
aria-label={t('templates.data.searchPlaceholder')}
|
|
532
|
-
className="pl-10"
|
|
533
|
-
/>
|
|
534
|
-
</div>
|
|
535
|
-
</div>
|
|
536
|
-
|
|
537
|
-
<div className="rounded-[var(--radius-lg)] border border-border overflow-hidden">
|
|
538
|
-
<Table>
|
|
539
|
-
<TableHeader>
|
|
540
|
-
<TableRow>
|
|
541
|
-
<TableHead>{t('team.name')}</TableHead>
|
|
542
|
-
<TableHead>{t('team.email')}</TableHead>
|
|
543
|
-
<TableHead>{t('team.role')}</TableHead>
|
|
544
|
-
<TableHead>{t('team.status')}</TableHead>
|
|
545
|
-
<TableHead className="text-right">{t('team.actions')}</TableHead>
|
|
546
|
-
</TableRow>
|
|
547
|
-
</TableHeader>
|
|
548
|
-
<TableBody>
|
|
549
|
-
{teamLoading ? (
|
|
550
|
-
<>
|
|
551
|
-
{Array.from({ length: 5 }).map((_, i) => (
|
|
552
|
-
<TableRow key={i}>
|
|
553
|
-
<TableCell>
|
|
554
|
-
<div className="flex items-center gap-2">
|
|
555
|
-
<Skeleton className="size-8 rounded-full shrink-0" />
|
|
556
|
-
<Skeleton className="h-3.5 w-28" />
|
|
557
|
-
</div>
|
|
558
|
-
</TableCell>
|
|
559
|
-
<TableCell>
|
|
560
|
-
<Skeleton className="h-3.5 w-36" />
|
|
561
|
-
</TableCell>
|
|
562
|
-
<TableCell>
|
|
563
|
-
<Skeleton className="h-3.5 w-20" />
|
|
564
|
-
</TableCell>
|
|
565
|
-
<TableCell>
|
|
566
|
-
<Skeleton className="h-5 w-16 rounded-full" />
|
|
567
|
-
</TableCell>
|
|
568
|
-
<TableCell className="text-right">
|
|
569
|
-
<Skeleton className="h-7 w-14 ml-auto" />
|
|
570
|
-
</TableCell>
|
|
571
|
-
</TableRow>
|
|
572
|
-
))}
|
|
573
|
-
</>
|
|
574
|
-
) : (
|
|
575
|
-
teamMembers.map(member => (
|
|
576
|
-
<TableRow key={member.id}>
|
|
577
|
-
<TableCell>{member.name}</TableCell>
|
|
578
|
-
<TableCell>{member.email}</TableCell>
|
|
579
|
-
<TableCell>{t(`team.roles.${member.role}`)}</TableCell>
|
|
580
|
-
<TableCell>
|
|
581
|
-
<Badge
|
|
582
|
-
variant={
|
|
583
|
-
member.status === 'active'
|
|
584
|
-
? 'default'
|
|
585
|
-
: member.status === 'away'
|
|
586
|
-
? 'secondary'
|
|
587
|
-
: 'outline'
|
|
588
|
-
}
|
|
589
|
-
>
|
|
590
|
-
{t(`common.${member.status}`)}
|
|
591
|
-
</Badge>
|
|
592
|
-
</TableCell>
|
|
593
|
-
<TableCell className="text-right">
|
|
594
|
-
<Button variant="ghost" size="sm">
|
|
595
|
-
{t('common.edit')}
|
|
596
|
-
</Button>
|
|
597
|
-
</TableCell>
|
|
598
|
-
</TableRow>
|
|
599
|
-
))
|
|
600
|
-
)}
|
|
601
|
-
</TableBody>
|
|
602
|
-
</Table>
|
|
603
|
-
</div>
|
|
604
|
-
</CardContent>
|
|
605
|
-
<CardFooter className="flex justify-between items-center">
|
|
606
|
-
<p className="text-muted-foreground">
|
|
607
|
-
{t('team.showing', {
|
|
608
|
-
count: teamMembers.length,
|
|
609
|
-
total: teamMembers.length,
|
|
610
|
-
})}
|
|
611
|
-
</p>
|
|
612
|
-
<div className="flex gap-2">
|
|
613
|
-
<Button variant="outline" size="sm">
|
|
614
|
-
{t('common.previous')}
|
|
615
|
-
</Button>
|
|
616
|
-
<Button variant="outline" size="sm">
|
|
617
|
-
{t('common.next')}
|
|
618
|
-
</Button>
|
|
619
|
-
</div>
|
|
620
|
-
</CardFooter>
|
|
621
|
-
</Card>
|
|
622
|
-
</SectionErrorBoundary>
|
|
623
|
-
</TabsContent>
|
|
624
|
-
|
|
625
|
-
{/* Settings Tab */}
|
|
626
|
-
<TabsContent value="settings" className="space-y-4">
|
|
627
|
-
<Card>
|
|
628
|
-
<CardHeader>
|
|
629
|
-
<CardTitle>{t('templates.settings.title')}</CardTitle>
|
|
630
|
-
<CardDescription>{t('templates.settings.description')}</CardDescription>
|
|
631
|
-
</CardHeader>
|
|
632
|
-
<CardContent className="space-y-6">
|
|
633
|
-
{!disableDarkMode && (
|
|
634
|
-
<>
|
|
635
|
-
<div className="flex items-center justify-between">
|
|
636
|
-
<div className="space-y-1">
|
|
637
|
-
<Label htmlFor="dark-mode">
|
|
638
|
-
{t('templates.settings.darkMode')}
|
|
639
|
-
</Label>
|
|
640
|
-
<p className="text-muted-foreground">
|
|
641
|
-
{t('templates.settings.darkModeDescription')}
|
|
642
|
-
</p>
|
|
643
|
-
</div>
|
|
644
|
-
<Switch
|
|
645
|
-
id="dark-mode"
|
|
646
|
-
checked={switchEnabled}
|
|
647
|
-
onCheckedChange={toggleSwitch}
|
|
648
|
-
/>
|
|
649
|
-
</div>
|
|
650
|
-
|
|
651
|
-
<Separator />
|
|
652
|
-
</>
|
|
653
|
-
)}
|
|
654
|
-
|
|
655
|
-
<div className="flex items-center justify-between">
|
|
656
|
-
<div className="space-y-1">
|
|
657
|
-
<Label htmlFor="email-notifications">
|
|
658
|
-
{t('templates.settings.emailNotifications')}
|
|
659
|
-
</Label>
|
|
660
|
-
<p className="text-muted-foreground">
|
|
661
|
-
{t('templates.settings.emailNotificationsDescription')}
|
|
662
|
-
</p>
|
|
663
|
-
</div>
|
|
664
|
-
<Switch id="email-notifications" defaultChecked />
|
|
665
|
-
</div>
|
|
666
|
-
|
|
667
|
-
<Separator />
|
|
668
|
-
|
|
669
|
-
<div className="flex items-center justify-between">
|
|
670
|
-
<div className="space-y-1">
|
|
671
|
-
<Label htmlFor="push-notifications">
|
|
672
|
-
{t('templates.settings.pushNotifications')}
|
|
673
|
-
</Label>
|
|
674
|
-
<p className="text-muted-foreground">
|
|
675
|
-
{t('templates.settings.pushNotificationsDescription')}
|
|
676
|
-
</p>
|
|
677
|
-
</div>
|
|
678
|
-
<Switch id="push-notifications" />
|
|
679
|
-
</div>
|
|
680
|
-
|
|
681
|
-
<Separator />
|
|
682
|
-
|
|
683
|
-
<div className="space-y-3">
|
|
684
|
-
<Label>{t('templates.settings.language')}</Label>
|
|
685
|
-
<Select defaultValue="pt-br">
|
|
686
|
-
<SelectTrigger aria-label={t('templates.settings.language')}>
|
|
687
|
-
<SelectValue />
|
|
688
|
-
</SelectTrigger>
|
|
689
|
-
<SelectContent>
|
|
690
|
-
<SelectItem value="pt-br">
|
|
691
|
-
{t('templates.settings.languages.ptBR')}
|
|
692
|
-
</SelectItem>
|
|
693
|
-
<SelectItem value="en">
|
|
694
|
-
{t('templates.settings.languages.en')}
|
|
695
|
-
</SelectItem>
|
|
696
|
-
<SelectItem value="es">
|
|
697
|
-
{t('templates.settings.languages.es')}
|
|
698
|
-
</SelectItem>
|
|
699
|
-
</SelectContent>
|
|
700
|
-
</Select>
|
|
701
|
-
</div>
|
|
702
|
-
|
|
703
|
-
<Separator />
|
|
704
|
-
|
|
705
|
-
<div className="space-y-3">
|
|
706
|
-
<Label>{t('templates.settings.timezone')}</Label>
|
|
707
|
-
<Select defaultValue="america-sao-paulo">
|
|
708
|
-
<SelectTrigger aria-label={t('templates.settings.timezone')}>
|
|
709
|
-
<SelectValue />
|
|
710
|
-
</SelectTrigger>
|
|
711
|
-
<SelectContent>
|
|
712
|
-
<SelectItem value="america-sao-paulo">
|
|
713
|
-
{t('templates.settings.timezones.saoPaulo')}
|
|
714
|
-
</SelectItem>
|
|
715
|
-
<SelectItem value="america-new-york">
|
|
716
|
-
{t('templates.settings.timezones.newYork')}
|
|
717
|
-
</SelectItem>
|
|
718
|
-
<SelectItem value="europe-london">
|
|
719
|
-
{t('templates.settings.timezones.london')}
|
|
720
|
-
</SelectItem>
|
|
721
|
-
</SelectContent>
|
|
722
|
-
</Select>
|
|
723
|
-
</div>
|
|
724
|
-
</CardContent>
|
|
725
|
-
<CardFooter className="flex justify-between">
|
|
726
|
-
<Button variant="outline">{t('templates.settings.restoreDefaults')}</Button>
|
|
727
|
-
<Button>{t('templates.settings.saveChanges')}</Button>
|
|
728
|
-
</CardFooter>
|
|
729
|
-
</Card>
|
|
730
|
-
</TabsContent>
|
|
731
|
-
</Tabs>
|
|
732
|
-
</section>
|
|
733
|
-
|
|
734
|
-
<Separator className="my-8" />
|
|
735
|
-
|
|
736
|
-
{/* Button Variants */}
|
|
737
|
-
<section>
|
|
738
|
-
<h3 className="mb-4">{t('templates.sections.buttons')}</h3>
|
|
739
|
-
<Card>
|
|
740
|
-
<CardHeader>
|
|
741
|
-
<CardTitle>{t('templates.buttons.title')}</CardTitle>
|
|
742
|
-
<CardDescription>{t('templates.buttons.description')}</CardDescription>
|
|
743
|
-
</CardHeader>
|
|
744
|
-
<CardContent className="space-y-6">
|
|
745
|
-
<div className="space-y-3">
|
|
746
|
-
<Label>{t('templates.buttons.variants')}</Label>
|
|
747
|
-
<div className="flex flex-wrap gap-3">
|
|
748
|
-
<Button variant="default">Default</Button>
|
|
749
|
-
<Button variant="secondary">Secondary</Button>
|
|
750
|
-
<Button variant="outline">Outline</Button>
|
|
751
|
-
<Button variant="ghost">Ghost</Button>
|
|
752
|
-
<Button variant="link">Link</Button>
|
|
753
|
-
<Button variant="destructive">Destructive</Button>
|
|
754
|
-
</div>
|
|
755
|
-
</div>
|
|
756
|
-
|
|
757
|
-
<Separator />
|
|
758
|
-
|
|
759
|
-
<div className="space-y-3">
|
|
760
|
-
<Label>{t('templates.buttons.sizes')}</Label>
|
|
761
|
-
<div className="flex flex-wrap items-center gap-3">
|
|
762
|
-
<Button size="sm">Small</Button>
|
|
763
|
-
<Button size="default">Default</Button>
|
|
764
|
-
<Button size="lg">Large</Button>
|
|
765
|
-
<Button size="icon" aria-label={t('nav.settings')}>
|
|
766
|
-
<Settings className="h-4 w-4" />
|
|
767
|
-
</Button>
|
|
768
|
-
</div>
|
|
769
|
-
</div>
|
|
770
|
-
|
|
771
|
-
<Separator />
|
|
772
|
-
|
|
773
|
-
<div className="space-y-3">
|
|
774
|
-
<Label>{t('templates.buttons.withIcons')}</Label>
|
|
775
|
-
<div className="flex flex-wrap gap-3">
|
|
776
|
-
<Button>
|
|
777
|
-
<User className="mr-2 h-4 w-4" />
|
|
778
|
-
{t('templates.buttons.profile')}
|
|
779
|
-
</Button>
|
|
780
|
-
<Button variant="secondary">
|
|
781
|
-
<Mail className="mr-2 h-4 w-4" />
|
|
782
|
-
{t('templates.buttons.messages')}
|
|
783
|
-
</Button>
|
|
784
|
-
<Button variant="outline">
|
|
785
|
-
<Calendar className="mr-2 h-4 w-4" />
|
|
786
|
-
{t('templates.buttons.schedule')}
|
|
787
|
-
</Button>
|
|
788
|
-
</div>
|
|
789
|
-
</div>
|
|
790
|
-
|
|
791
|
-
<Separator />
|
|
792
|
-
|
|
793
|
-
<div className="space-y-3">
|
|
794
|
-
<Label>{t('templates.buttons.states')}</Label>
|
|
795
|
-
<div className="flex flex-wrap gap-3">
|
|
796
|
-
<Button disabled>{t('templates.buttons.disabled')}</Button>
|
|
797
|
-
<Button variant="outline" disabled>
|
|
798
|
-
{t('templates.buttons.outlineDisabled')}
|
|
799
|
-
</Button>
|
|
800
|
-
</div>
|
|
801
|
-
</div>
|
|
802
|
-
</CardContent>
|
|
803
|
-
</Card>
|
|
804
|
-
</section>
|
|
805
|
-
|
|
806
|
-
<Separator className="my-8" />
|
|
807
|
-
|
|
808
|
-
{/* Badges */}
|
|
809
|
-
<section>
|
|
810
|
-
<h3 className="mb-4">{t('templates.sections.badges')}</h3>
|
|
811
|
-
<Card>
|
|
812
|
-
<CardHeader>
|
|
813
|
-
<CardTitle>{t('templates.badges.title')}</CardTitle>
|
|
814
|
-
<CardDescription>{t('templates.badges.description')}</CardDescription>
|
|
815
|
-
</CardHeader>
|
|
816
|
-
<CardContent>
|
|
817
|
-
<div className="flex flex-wrap gap-3">
|
|
818
|
-
<Badge variant="default">Default</Badge>
|
|
819
|
-
<Badge variant="secondary">Secondary</Badge>
|
|
820
|
-
<Badge variant="outline">Outline</Badge>
|
|
821
|
-
<Badge variant="destructive">Destructive</Badge>
|
|
822
|
-
<Badge className="bg-success text-success-foreground">Success</Badge>
|
|
823
|
-
<Badge className="bg-warning text-warning-foreground">Warning</Badge>
|
|
824
|
-
<Badge className="bg-info text-info-foreground">Info</Badge>
|
|
825
|
-
</div>
|
|
826
|
-
</CardContent>
|
|
827
|
-
</Card>
|
|
828
|
-
</section>
|
|
829
|
-
|
|
830
|
-
<Separator className="my-8" />
|
|
831
|
-
|
|
832
|
-
{/* Dialogs */}
|
|
833
|
-
<section>
|
|
834
|
-
<h3 className="mb-4">{t('templates.sections.dialogs')}</h3>
|
|
835
|
-
<div className="grid gap-4 md:grid-cols-2">
|
|
836
|
-
<Card>
|
|
837
|
-
<CardHeader>
|
|
838
|
-
<CardTitle>{t('templates.dialogs.dialogTitle')}</CardTitle>
|
|
839
|
-
<CardDescription>{t('templates.dialogs.dialogDescription')}</CardDescription>
|
|
840
|
-
</CardHeader>
|
|
841
|
-
<CardContent className="flex justify-center py-6">
|
|
842
|
-
<Dialog>
|
|
843
|
-
<DialogTrigger asChild>
|
|
844
|
-
<Button variant="outline">{t('templates.dialogs.editProfile')}</Button>
|
|
845
|
-
</DialogTrigger>
|
|
846
|
-
<DialogContent className="sm:max-w-[425px]">
|
|
847
|
-
<DialogHeader>
|
|
848
|
-
<DialogTitle>{t('templates.dialogs.editProfile')}</DialogTitle>
|
|
849
|
-
<DialogDescription>
|
|
850
|
-
{t('templates.dialogs.editProfileDescription')}
|
|
851
|
-
</DialogDescription>
|
|
852
|
-
</DialogHeader>
|
|
853
|
-
<div className="grid gap-4 py-4">
|
|
854
|
-
<div className="grid grid-cols-4 items-center gap-4">
|
|
855
|
-
<Label htmlFor="name" className="text-right">
|
|
856
|
-
{t('templates.dialogs.name')}
|
|
857
|
-
</Label>
|
|
858
|
-
<Input id="name" defaultValue="John Doe" className="col-span-3" />
|
|
859
|
-
</div>
|
|
860
|
-
<div className="grid grid-cols-4 items-center gap-4">
|
|
861
|
-
<Label htmlFor="username" className="text-right">
|
|
862
|
-
{t('templates.dialogs.username')}
|
|
863
|
-
</Label>
|
|
864
|
-
<Input id="username" defaultValue="@johndoe" className="col-span-3" />
|
|
865
|
-
</div>
|
|
866
|
-
</div>
|
|
867
|
-
<DialogFooter>
|
|
868
|
-
<Button type="submit">{t('templates.dialogs.update')}</Button>
|
|
869
|
-
</DialogFooter>
|
|
870
|
-
</DialogContent>
|
|
871
|
-
</Dialog>
|
|
872
|
-
</CardContent>
|
|
873
|
-
</Card>
|
|
874
|
-
|
|
875
|
-
<Card>
|
|
876
|
-
<CardHeader>
|
|
877
|
-
<CardTitle>{t('templates.dialogs.alertDialogTitle')}</CardTitle>
|
|
878
|
-
<CardDescription>
|
|
879
|
-
{t('templates.dialogs.alertDialogDescription')}
|
|
880
|
-
</CardDescription>
|
|
881
|
-
</CardHeader>
|
|
882
|
-
<CardContent className="flex justify-center py-6">
|
|
883
|
-
<AlertDialog>
|
|
884
|
-
<AlertDialogTrigger asChild>
|
|
885
|
-
<Button variant="destructive">
|
|
886
|
-
{t('templates.dialogs.deleteAccount')}
|
|
887
|
-
</Button>
|
|
888
|
-
</AlertDialogTrigger>
|
|
889
|
-
<AlertDialogContent className="sm:max-w-[425px]">
|
|
890
|
-
<AlertDialogHeader>
|
|
891
|
-
<AlertDialogTitle>{t('templates.dialogs.areYouSure')}</AlertDialogTitle>
|
|
892
|
-
<AlertDialogDescription>
|
|
893
|
-
{t('templates.dialogs.deleteWarning')}
|
|
894
|
-
</AlertDialogDescription>
|
|
895
|
-
</AlertDialogHeader>
|
|
896
|
-
<AlertDialogFooter>
|
|
897
|
-
<AlertDialogCancel>{t('templates.dialogs.cancel')}</AlertDialogCancel>
|
|
898
|
-
<AlertDialogAction className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
|
|
899
|
-
{t('templates.dialogs.continue')}
|
|
900
|
-
</AlertDialogAction>
|
|
901
|
-
</AlertDialogFooter>
|
|
902
|
-
</AlertDialogContent>
|
|
903
|
-
</AlertDialog>
|
|
904
|
-
</CardContent>
|
|
905
|
-
</Card>
|
|
906
|
-
</div>
|
|
907
|
-
</section>
|
|
908
|
-
|
|
909
|
-
<Separator className="my-8" />
|
|
910
|
-
|
|
911
|
-
{/* Maps */}
|
|
912
|
-
<section>
|
|
913
|
-
<MapShowcase />
|
|
914
|
-
</section>
|
|
915
|
-
|
|
916
|
-
<Separator className="my-8" />
|
|
917
|
-
|
|
918
|
-
{/* Header Variations */}
|
|
919
|
-
<section>
|
|
920
|
-
<h3 className="mb-4">{t('templates.headerVariations.sectionTitle')}</h3>
|
|
921
|
-
<Card>
|
|
922
|
-
<CardHeader>
|
|
923
|
-
<CardTitle>{t('templates.headerVariations.cardTitle')}</CardTitle>
|
|
924
|
-
<CardDescription>
|
|
925
|
-
{t('templates.headerVariations.cardDescription')}
|
|
926
|
-
</CardDescription>
|
|
927
|
-
</CardHeader>
|
|
928
|
-
<CardContent className="space-y-6">
|
|
929
|
-
<div className="p-4 border rounded-[var(--radius-lg)] bg-muted/30">
|
|
930
|
-
<h4 className="text-sm font-semibold mb-4">
|
|
931
|
-
{t('templates.headerVariations.visibleElements')}
|
|
932
|
-
</h4>
|
|
933
|
-
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
|
|
934
|
-
<div className="flex items-center space-x-2">
|
|
935
|
-
<Switch
|
|
936
|
-
id="header-actions"
|
|
937
|
-
checked={showHeaderActions}
|
|
938
|
-
onCheckedChange={setShowHeaderActions}
|
|
939
|
-
/>
|
|
940
|
-
<Label htmlFor="header-actions" className="cursor-pointer">
|
|
941
|
-
{t('templates.headerVariations.actionButtons')}
|
|
942
|
-
</Label>
|
|
943
|
-
</div>
|
|
944
|
-
<div className="flex items-center space-x-2">
|
|
945
|
-
<Switch
|
|
946
|
-
id="header-bread"
|
|
947
|
-
checked={showHeaderBreadcrumbs}
|
|
948
|
-
onCheckedChange={setShowHeaderBreadcrumbs}
|
|
949
|
-
/>
|
|
950
|
-
<Label htmlFor="header-bread" className="cursor-pointer">
|
|
951
|
-
{t('templates.headerVariations.breadcrumbsLabel')}
|
|
952
|
-
</Label>
|
|
953
|
-
</div>
|
|
954
|
-
</div>
|
|
955
|
-
</div>
|
|
956
|
-
|
|
957
|
-
<div className="relative border rounded-[var(--radius-lg)] bg-muted/10 overflow-hidden shadow-inner">
|
|
958
|
-
<div className="p-4 bg-background/50 border-b text-xs font-mono text-muted-foreground">
|
|
959
|
-
{t('templates.headerVariations.preview')}
|
|
960
|
-
</div>
|
|
961
|
-
<Header
|
|
962
|
-
title={
|
|
963
|
-
!showHeaderBreadcrumbs
|
|
964
|
-
? t('templates.headerVariations.currentPage')
|
|
965
|
-
: undefined
|
|
966
|
-
}
|
|
967
|
-
breadcrumbs={
|
|
968
|
-
showHeaderBreadcrumbs
|
|
969
|
-
? [
|
|
970
|
-
{
|
|
971
|
-
label: t('templates.headerVariations.breadcrumbBrand'),
|
|
972
|
-
href: '#',
|
|
973
|
-
icon: <Home className="w-4 h-4" />,
|
|
974
|
-
},
|
|
975
|
-
{
|
|
976
|
-
label: t('templates.headerVariations.breadcrumbSettings'),
|
|
977
|
-
href: '#',
|
|
978
|
-
},
|
|
979
|
-
{ label: t('templates.headerVariations.breadcrumbProfile') },
|
|
980
|
-
]
|
|
981
|
-
: undefined
|
|
982
|
-
}
|
|
983
|
-
actions={
|
|
984
|
-
showHeaderActions
|
|
985
|
-
? [
|
|
986
|
-
{
|
|
987
|
-
id: 'notify',
|
|
988
|
-
icon: <Bell className="w-5 h-5" />,
|
|
989
|
-
onClick: () =>
|
|
990
|
-
toast(t('templates.headerVariations.notificationsOpenedToast')),
|
|
991
|
-
},
|
|
992
|
-
{
|
|
993
|
-
id: 'mail',
|
|
994
|
-
label: t('templates.headerVariations.messagesLabel'),
|
|
995
|
-
icon: <Mail className="w-5 h-5" />,
|
|
996
|
-
onClick: () =>
|
|
997
|
-
toast(t('templates.headerVariations.messagesOpenedToast')),
|
|
998
|
-
},
|
|
999
|
-
]
|
|
1000
|
-
: undefined
|
|
1001
|
-
}
|
|
1002
|
-
/>
|
|
1003
|
-
<div className="h-32 flex items-center justify-center text-muted-foreground text-sm italic">
|
|
1004
|
-
{t('templates.headerVariations.contentArea')}
|
|
1005
|
-
</div>
|
|
1006
|
-
</div>
|
|
1007
|
-
</CardContent>
|
|
1008
|
-
</Card>
|
|
1009
|
-
</section>
|
|
1010
|
-
|
|
1011
|
-
<Separator className="my-8" />
|
|
1012
|
-
|
|
1013
|
-
{/* Sidebar Variations */}
|
|
1014
|
-
<section>
|
|
1015
|
-
<h3 className="mb-4">{t('templates.sections.sidebarVariations')}</h3>
|
|
1016
|
-
<Card>
|
|
1017
|
-
<CardHeader>
|
|
1018
|
-
<CardTitle>{t('templates.sidebar.title')}</CardTitle>
|
|
1019
|
-
<CardDescription>{t('templates.sidebar.description')}</CardDescription>
|
|
1020
|
-
</CardHeader>
|
|
1021
|
-
<CardContent>
|
|
1022
|
-
<Tabs defaultValue="assistant" className="w-full">
|
|
1023
|
-
<TabsList className="mb-4">
|
|
1024
|
-
<TabsTrigger value="assistant">
|
|
1025
|
-
{t('templates.sidebar.assistantMode')}
|
|
1026
|
-
</TabsTrigger>
|
|
1027
|
-
<TabsTrigger value="default">
|
|
1028
|
-
{t('templates.sidebar.defaultMode')}
|
|
1029
|
-
</TabsTrigger>
|
|
1030
|
-
</TabsList>
|
|
1031
|
-
|
|
1032
|
-
<div className="mb-6 p-4 border rounded-[var(--radius-lg)] bg-muted/30">
|
|
1033
|
-
<h4 className="text-sm font-semibold mb-4">
|
|
1034
|
-
{t('templates.sidebarControls.footerSettings')}
|
|
1035
|
-
</h4>
|
|
1036
|
-
<div className="flex flex-wrap gap-6 mt-2">
|
|
1037
|
-
<div className="flex items-center space-x-2">
|
|
1038
|
-
<Switch
|
|
1039
|
-
id="show-user"
|
|
1040
|
-
checked={showSidebarUser}
|
|
1041
|
-
onCheckedChange={setShowSidebarUser}
|
|
1042
|
-
/>
|
|
1043
|
-
<Label htmlFor="show-user" className="cursor-pointer">
|
|
1044
|
-
{t('templates.sidebarControls.userProfile')}
|
|
1045
|
-
</Label>
|
|
1046
|
-
</div>
|
|
1047
|
-
<div className="flex items-center space-x-2">
|
|
1048
|
-
<Switch
|
|
1049
|
-
id="show-settings"
|
|
1050
|
-
checked={showSidebarSettings}
|
|
1051
|
-
onCheckedChange={setShowSidebarSettings}
|
|
1052
|
-
/>
|
|
1053
|
-
<Label htmlFor="show-settings" className="cursor-pointer">
|
|
1054
|
-
{t('templates.sidebarControls.settings')}
|
|
1055
|
-
</Label>
|
|
1056
|
-
</div>
|
|
1057
|
-
<div className="flex items-center space-x-2">
|
|
1058
|
-
<Switch
|
|
1059
|
-
id="show-logout"
|
|
1060
|
-
checked={showSidebarLogout}
|
|
1061
|
-
onCheckedChange={setShowSidebarLogout}
|
|
1062
|
-
/>
|
|
1063
|
-
<Label htmlFor="show-logout" className="cursor-pointer">
|
|
1064
|
-
{t('templates.sidebarControls.logoutButton')}
|
|
1065
|
-
</Label>
|
|
1066
|
-
</div>
|
|
1067
|
-
</div>
|
|
1068
|
-
|
|
1069
|
-
<div className="mt-6 pt-6 border-t">
|
|
1070
|
-
<div className="flex items-center justify-between mb-4">
|
|
1071
|
-
<h4 className="text-sm font-semibold">
|
|
1072
|
-
{t('templates.sidebarControls.sidebarWidthDesktop')}
|
|
1073
|
-
</h4>
|
|
1074
|
-
<span className="text-xs font-mono bg-muted px-2 py-1 rounded">
|
|
1075
|
-
{sidebarWidth}px
|
|
1076
|
-
</span>
|
|
1077
|
-
</div>
|
|
1078
|
-
<div className="flex items-center gap-4">
|
|
1079
|
-
<span className="text-xs text-muted-foreground w-12 text-right">
|
|
1080
|
-
240px
|
|
1081
|
-
</span>
|
|
1082
|
-
<Slider
|
|
1083
|
-
value={[sidebarWidth]}
|
|
1084
|
-
onValueChange={val => setSidebarWidth(val[0])}
|
|
1085
|
-
min={240}
|
|
1086
|
-
max={450}
|
|
1087
|
-
step={10}
|
|
1088
|
-
className="flex-1"
|
|
1089
|
-
aria-label={t('templates.sidebarControls.sidebarWidthAriaLabel')}
|
|
1090
|
-
/>
|
|
1091
|
-
<span className="text-xs text-muted-foreground w-12">450px</span>
|
|
1092
|
-
</div>
|
|
1093
|
-
</div>
|
|
1094
|
-
</div>
|
|
1095
|
-
|
|
1096
|
-
<TabsContent value="assistant">
|
|
1097
|
-
<div
|
|
1098
|
-
className="relative h-[600px] border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
1099
|
-
style={{ transform: 'translateZ(0)' }}
|
|
1100
|
-
>
|
|
1101
|
-
<Sidebar
|
|
1102
|
-
expanded={true}
|
|
1103
|
-
width={sidebarWidth}
|
|
1104
|
-
onToggle={() => {}}
|
|
1105
|
-
user={{ email: 'admin@xertica.com' }}
|
|
1106
|
-
onLogout={() => toast(t('templates.sidebar.logoutToast'))}
|
|
1107
|
-
location={{ pathname: '/assistant/current' }}
|
|
1108
|
-
navigate={() => {}}
|
|
1109
|
-
variant="assistant"
|
|
1110
|
-
search={{
|
|
1111
|
-
show: true,
|
|
1112
|
-
placeholder: t('templates.sidebar.searchTopicsPlaceholder'),
|
|
1113
|
-
filter: {
|
|
1114
|
-
show: true,
|
|
1115
|
-
content: (
|
|
1116
|
-
<div className="p-2 space-y-2">
|
|
1117
|
-
<div className="text-xs font-semibold uppercase text-muted-foreground px-2">
|
|
1118
|
-
{t('templates.sidebarControls.filterByStatus')}
|
|
1119
|
-
</div>
|
|
1120
|
-
<div className="flex flex-wrap gap-2 p-1">
|
|
1121
|
-
<Badge className="bg-sidebar-foreground/20 text-sidebar-foreground border-none cursor-pointer hover:bg-sidebar-foreground/30">
|
|
1122
|
-
{t('templates.sidebarControls.filterActive')}
|
|
1123
|
-
</Badge>
|
|
1124
|
-
<Badge
|
|
1125
|
-
variant="outline"
|
|
1126
|
-
className="text-sidebar-foreground/70 border-sidebar-foreground/20 cursor-pointer hover:bg-sidebar-foreground/10"
|
|
1127
|
-
>
|
|
1128
|
-
{t('templates.sidebarControls.filterArchived')}
|
|
1129
|
-
</Badge>
|
|
1130
|
-
<Badge
|
|
1131
|
-
variant="outline"
|
|
1132
|
-
className="text-sidebar-foreground/70 border-sidebar-foreground/20 cursor-pointer hover:bg-sidebar-foreground/10"
|
|
1133
|
-
>
|
|
1134
|
-
{t('templates.sidebarControls.filterPending')}
|
|
1135
|
-
</Badge>
|
|
1136
|
-
</div>
|
|
1137
|
-
</div>
|
|
1138
|
-
),
|
|
1139
|
-
},
|
|
1140
|
-
}}
|
|
1141
|
-
fixedArea={{
|
|
1142
|
-
show: true,
|
|
1143
|
-
content: (
|
|
1144
|
-
<Button className="w-full bg-sidebar-primary hover:bg-sidebar-primary/90 text-sidebar-primary-foreground shadow-lg font-bold border-none transition-all duration-300 transform hover:scale-[1.02] active:scale-[0.98]">
|
|
1145
|
-
<Plus className="w-4 h-4 mr-2" />
|
|
1146
|
-
{t('templates.sidebar.newConversation')}
|
|
1147
|
-
</Button>
|
|
1148
|
-
),
|
|
1149
|
-
}}
|
|
1150
|
-
navigationGroups={[
|
|
1151
|
-
{
|
|
1152
|
-
id: 'recent',
|
|
1153
|
-
label: t('templates.sidebar.recent'),
|
|
1154
|
-
icon: Clock,
|
|
1155
|
-
items: [
|
|
1156
|
-
{
|
|
1157
|
-
path: '/assistant/refatoracao',
|
|
1158
|
-
label: t('templates.sidebar.items.sidebarRefactor'),
|
|
1159
|
-
description: t(
|
|
1160
|
-
'templates.sidebar.items.sidebarRefactorDescription'
|
|
1161
|
-
),
|
|
1162
|
-
actions: [
|
|
1163
|
-
{
|
|
1164
|
-
label: t('templates.sidebar.actions.rename'),
|
|
1165
|
-
icon: FileEdit,
|
|
1166
|
-
onClick: () =>
|
|
1167
|
-
toast(t('templates.sidebar.actions.renameToast')),
|
|
1168
|
-
},
|
|
1169
|
-
{
|
|
1170
|
-
label: t('templates.sidebar.actions.move'),
|
|
1171
|
-
icon: ArrowRightLeft,
|
|
1172
|
-
children: [
|
|
1173
|
-
{
|
|
1174
|
-
label: t('templates.sidebar.actions.moveActive'),
|
|
1175
|
-
onClick: () =>
|
|
1176
|
-
toast(t('templates.sidebar.actions.moveActiveToast')),
|
|
1177
|
-
},
|
|
1178
|
-
{
|
|
1179
|
-
label: t('templates.sidebar.actions.moveMonitoring'),
|
|
1180
|
-
onClick: () =>
|
|
1181
|
-
toast(
|
|
1182
|
-
t('templates.sidebar.actions.moveMonitoringToast')
|
|
1183
|
-
),
|
|
1184
|
-
},
|
|
1185
|
-
{
|
|
1186
|
-
label: t('templates.sidebar.actions.moveArchive'),
|
|
1187
|
-
onClick: () =>
|
|
1188
|
-
toast(
|
|
1189
|
-
t('templates.sidebar.actions.moveArchiveToast')
|
|
1190
|
-
),
|
|
1191
|
-
},
|
|
1192
|
-
],
|
|
1193
|
-
},
|
|
1194
|
-
{
|
|
1195
|
-
label: t('templates.sidebar.actions.clear'),
|
|
1196
|
-
icon: Trash2,
|
|
1197
|
-
onClick: () =>
|
|
1198
|
-
toast(t('templates.sidebar.actions.clearToast')),
|
|
1199
|
-
variant: 'destructive',
|
|
1200
|
-
},
|
|
1201
|
-
],
|
|
1202
|
-
},
|
|
1203
|
-
],
|
|
1204
|
-
},
|
|
1205
|
-
{
|
|
1206
|
-
id: 'projects',
|
|
1207
|
-
label: t('templates.sidebar.constructionMonitoring'),
|
|
1208
|
-
icon: Map,
|
|
1209
|
-
actions: [
|
|
1210
|
-
{
|
|
1211
|
-
label: t('templates.sidebar.actions.newCategory'),
|
|
1212
|
-
icon: Plus,
|
|
1213
|
-
onClick: () =>
|
|
1214
|
-
toast(t('templates.sidebar.actions.newCategoryToast')),
|
|
1215
|
-
},
|
|
1216
|
-
{
|
|
1217
|
-
label: t('templates.sidebar.actions.archiveGroup'),
|
|
1218
|
-
icon: Archive,
|
|
1219
|
-
onClick: () =>
|
|
1220
|
-
toast(t('templates.sidebar.actions.archiveGroupToast')),
|
|
1221
|
-
},
|
|
1222
|
-
],
|
|
1223
|
-
items: [
|
|
1224
|
-
{
|
|
1225
|
-
path: '/assistant/br163',
|
|
1226
|
-
label: t('templates.sidebar.items.br163Restoration'),
|
|
1227
|
-
icon: () => (
|
|
1228
|
-
<div className="w-2 h-2 rounded-full bg-yellow-500" />
|
|
1229
|
-
),
|
|
1230
|
-
description: (
|
|
1231
|
-
<div className="space-y-1.5 min-w-[160px]">
|
|
1232
|
-
<Progress
|
|
1233
|
-
value={67}
|
|
1234
|
-
className="h-1.5 bg-sidebar-foreground/10"
|
|
1235
|
-
/>
|
|
1236
|
-
<div className="flex justify-between items-center text-[10px] text-sidebar-foreground/60">
|
|
1237
|
-
<span>{t('templates.sidebar.items.br163Location')}</span>
|
|
1238
|
-
<span>67%</span>
|
|
1239
|
-
</div>
|
|
1240
|
-
</div>
|
|
1241
|
-
),
|
|
1242
|
-
},
|
|
1243
|
-
],
|
|
1244
|
-
},
|
|
1245
|
-
]}
|
|
1246
|
-
footer={{
|
|
1247
|
-
showUser: showSidebarUser,
|
|
1248
|
-
showSettings: showSidebarSettings,
|
|
1249
|
-
showLogout: showSidebarLogout,
|
|
1250
|
-
}}
|
|
1251
|
-
/>
|
|
1252
|
-
<div
|
|
1253
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
1254
|
-
style={{ left: `${sidebarWidth}px` }}
|
|
1255
|
-
>
|
|
1256
|
-
<p className="text-muted-foreground text-center">
|
|
1257
|
-
{t('templates.sidebar.assistantContent')}
|
|
1258
|
-
</p>
|
|
1259
|
-
</div>
|
|
1260
|
-
</div>
|
|
1261
|
-
</TabsContent>
|
|
1262
|
-
|
|
1263
|
-
<TabsContent value="default">
|
|
1264
|
-
<div
|
|
1265
|
-
className="relative h-[600px] border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
1266
|
-
style={{ transform: 'translateZ(0)' }}
|
|
1267
|
-
>
|
|
1268
|
-
<Sidebar
|
|
1269
|
-
expanded={true}
|
|
1270
|
-
width={sidebarWidth}
|
|
1271
|
-
onToggle={() => {}}
|
|
1272
|
-
user={{
|
|
1273
|
-
name: 'Ariel Santos',
|
|
1274
|
-
email: 'admin@xertica.com',
|
|
1275
|
-
avatar: 'https://github.com/shadcn.png',
|
|
1276
|
-
}}
|
|
1277
|
-
onLogout={() => toast(t('templates.sidebar.logoutToast'))}
|
|
1278
|
-
onSettingsClick={() =>
|
|
1279
|
-
toast(t('templates.sidebar.settingsClickedToast'))
|
|
1280
|
-
}
|
|
1281
|
-
location={{ pathname: '/home' }}
|
|
1282
|
-
navigate={() => {}}
|
|
1283
|
-
variant="default"
|
|
1284
|
-
routes={[
|
|
1285
|
-
{
|
|
1286
|
-
path: '/home',
|
|
1287
|
-
label: t('templates.sidebar.routes.home'),
|
|
1288
|
-
icon: Home,
|
|
1289
|
-
},
|
|
1290
|
-
{
|
|
1291
|
-
path: '/dashboard',
|
|
1292
|
-
label: t('templates.sidebar.routes.dashboard'),
|
|
1293
|
-
icon: Users,
|
|
1294
|
-
},
|
|
1295
|
-
{
|
|
1296
|
-
path: '/settings',
|
|
1297
|
-
label: t('templates.sidebar.routes.settings'),
|
|
1298
|
-
icon: Settings,
|
|
1299
|
-
},
|
|
1300
|
-
]}
|
|
1301
|
-
footer={{
|
|
1302
|
-
showUser: showSidebarUser,
|
|
1303
|
-
showSettings: showSidebarSettings,
|
|
1304
|
-
showLogout: showSidebarLogout,
|
|
1305
|
-
}}
|
|
1306
|
-
/>
|
|
1307
|
-
<div
|
|
1308
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
1309
|
-
style={{ left: `${sidebarWidth}px` }}
|
|
1310
|
-
>
|
|
1311
|
-
<p className="text-muted-foreground text-center">
|
|
1312
|
-
{t('templates.sidebar.defaultContent')}
|
|
1313
|
-
</p>
|
|
1314
|
-
</div>
|
|
1315
|
-
</div>
|
|
1316
|
-
</TabsContent>
|
|
1317
|
-
</Tabs>
|
|
1318
|
-
</CardContent>
|
|
1319
|
-
</Card>
|
|
1320
|
-
</section>
|
|
1321
|
-
|
|
1322
|
-
<Separator className="my-8" />
|
|
1323
|
-
|
|
1324
|
-
{/* Footer Note */}
|
|
1325
|
-
<Card className="mt-8">
|
|
1326
|
-
<CardHeader>
|
|
1327
|
-
<CardTitle>{t('templates.footer.title')}</CardTitle>
|
|
1328
|
-
<CardDescription>{t('templates.footer.subtitle')}</CardDescription>
|
|
1329
|
-
</CardHeader>
|
|
1330
|
-
<CardContent className="space-y-4">
|
|
1331
|
-
<p className="text-muted-foreground">
|
|
1332
|
-
{t('templates.footer.descriptionPart1')}
|
|
1333
|
-
<code className="bg-muted px-2 py-1 rounded-[var(--radius-sm)] [font-size:var(--text-small)]">
|
|
1334
|
-
xertica-ui
|
|
1335
|
-
</code>
|
|
1336
|
-
{t('templates.footer.descriptionPart2')}
|
|
1337
|
-
</p>
|
|
1338
|
-
<Alert variant="info">
|
|
1339
|
-
<AlertTitle>{t('templates.footer.tipTitle')}</AlertTitle>
|
|
1340
|
-
<AlertDescription>
|
|
1341
|
-
{t('templates.footer.tipDescriptionPart1')}
|
|
1342
|
-
<code className="bg-muted px-1 rounded">styles/xertica/tokens.css</code>
|
|
1343
|
-
{t('templates.footer.tipDescriptionPart2')}
|
|
1344
|
-
</AlertDescription>
|
|
1345
|
-
</Alert>
|
|
1346
|
-
</CardContent>
|
|
1347
|
-
</Card>
|
|
1348
|
-
</div>
|
|
1349
|
-
</div>
|
|
1350
|
-
</ScrollArea>
|
|
1351
|
-
</main>
|
|
1352
|
-
</div>
|
|
1353
|
-
);
|
|
1354
|
-
}
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Link, useNavigate } from 'react-router-dom';
|
|
3
|
+
import { Button } from '../../ui/button';
|
|
4
|
+
import { Input } from '../../ui/input';
|
|
5
|
+
import { Label } from '../../ui/label';
|
|
6
|
+
import {
|
|
7
|
+
Card,
|
|
8
|
+
CardHeader,
|
|
9
|
+
CardTitle,
|
|
10
|
+
CardDescription,
|
|
11
|
+
CardContent,
|
|
12
|
+
CardFooter,
|
|
13
|
+
} from '../../ui/card';
|
|
14
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../../ui/tabs';
|
|
15
|
+
import { Badge } from '../../ui/badge';
|
|
16
|
+
import { Alert, AlertDescription, AlertTitle } from '../../ui/alert';
|
|
17
|
+
import { Checkbox } from '../../ui/checkbox';
|
|
18
|
+
import { RadioGroup, RadioGroupItem } from '../../ui/radio-group';
|
|
19
|
+
import { Switch } from '../../ui/switch';
|
|
20
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
|
21
|
+
import { Textarea } from '../../ui/textarea';
|
|
22
|
+
import { Progress } from '../../ui/progress';
|
|
23
|
+
import { Separator } from '../../ui/separator';
|
|
24
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../../ui/table';
|
|
25
|
+
import {
|
|
26
|
+
Settings,
|
|
27
|
+
User,
|
|
28
|
+
Mail,
|
|
29
|
+
Phone,
|
|
30
|
+
Calendar,
|
|
31
|
+
Search,
|
|
32
|
+
Menu,
|
|
33
|
+
ChevronRight,
|
|
34
|
+
Home,
|
|
35
|
+
Users,
|
|
36
|
+
Plus,
|
|
37
|
+
Trash2,
|
|
38
|
+
Archive,
|
|
39
|
+
ArrowRightLeft,
|
|
40
|
+
History,
|
|
41
|
+
PanelRight,
|
|
42
|
+
FileEdit,
|
|
43
|
+
Filter,
|
|
44
|
+
Clock,
|
|
45
|
+
Map,
|
|
46
|
+
Bell,
|
|
47
|
+
} from 'lucide-react';
|
|
48
|
+
import { Slider } from '../../ui/slider';
|
|
49
|
+
import { toast } from 'sonner';
|
|
50
|
+
import { ScrollArea } from '../../ui/scroll-area';
|
|
51
|
+
import { ThemeToggle } from '../../brand/theme-toggle';
|
|
52
|
+
import { LanguageSelector } from '../../brand/language-selector';
|
|
53
|
+
import { MapShowcase } from '../../examples/MapShowcase';
|
|
54
|
+
import { Header } from '../../layout/header';
|
|
55
|
+
import { Sidebar } from '../../layout/sidebar';
|
|
56
|
+
import {
|
|
57
|
+
Dialog,
|
|
58
|
+
DialogTrigger,
|
|
59
|
+
DialogContent,
|
|
60
|
+
DialogHeader,
|
|
61
|
+
DialogTitle,
|
|
62
|
+
DialogDescription,
|
|
63
|
+
DialogFooter,
|
|
64
|
+
} from '../../ui/dialog';
|
|
65
|
+
import {
|
|
66
|
+
AlertDialog,
|
|
67
|
+
AlertDialogTrigger,
|
|
68
|
+
AlertDialogContent,
|
|
69
|
+
AlertDialogHeader,
|
|
70
|
+
AlertDialogTitle,
|
|
71
|
+
AlertDialogDescription,
|
|
72
|
+
AlertDialogFooter,
|
|
73
|
+
AlertDialogAction,
|
|
74
|
+
AlertDialogCancel,
|
|
75
|
+
} from '../../ui/alert-dialog';
|
|
76
|
+
import { PageHeader } from '../../ui/page-header';
|
|
77
|
+
|
|
78
|
+
import { useOptionalLayout } from '../../../contexts/LayoutContext';
|
|
79
|
+
import { useTheme } from '../../../contexts/ThemeContext';
|
|
80
|
+
import { useTeamMembers, useDashboardStore } from '../../../features/home';
|
|
81
|
+
import { useTranslation } from 'react-i18next';
|
|
82
|
+
import { SectionErrorBoundary } from '../../shared/error-boundary';
|
|
83
|
+
import { Skeleton } from '../../ui/skeleton';
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Comprehensive Showcase and Template Content component.
|
|
87
|
+
*
|
|
88
|
+
* @description
|
|
89
|
+
* This component serves as a living kitchen-sink demonstration of the Xertica UI
|
|
90
|
+
* Design System. It showcases almost every UI primitive (Cards, Tabs, Forms,
|
|
91
|
+
* Tables, Dialogs, etc.) and layout variation (Header flexibility, Sidebar
|
|
92
|
+
* toggling). It's primarily used for development, testing, and as a starting
|
|
93
|
+
* point for new pages.
|
|
94
|
+
*
|
|
95
|
+
* @ai-rules
|
|
96
|
+
* 1. Reference: Use this component as the primary source of truth for "how to compose" complex layouts in this library.
|
|
97
|
+
* 2. Layout: Adjusts its own padding based on the `useLayout` context's sidebar state.
|
|
98
|
+
* 3. Interaction: All showcase interactive elements (buttons, forms) use simple `toast` feedback or local state toggles.
|
|
99
|
+
*/
|
|
100
|
+
export function TemplateContent() {
|
|
101
|
+
const { t } = useTranslation();
|
|
102
|
+
const layout = useOptionalLayout();
|
|
103
|
+
const { disableDarkMode } = useTheme();
|
|
104
|
+
const [localSidebarExpanded, setLocalSidebarExpanded] = useState(false);
|
|
105
|
+
const [localSidebarWidth, setLocalSidebarWidth] = useState(280);
|
|
106
|
+
const sidebarExpanded = layout?.sidebarExpanded ?? localSidebarExpanded;
|
|
107
|
+
const sidebarWidth = layout?.sidebarWidth ?? localSidebarWidth;
|
|
108
|
+
const setSidebarWidth = layout?.setSidebarWidth ?? setLocalSidebarWidth;
|
|
109
|
+
const toggleSidebar = layout?.toggleSidebar ?? (() => setLocalSidebarExpanded(value => !value));
|
|
110
|
+
const navigate = useNavigate();
|
|
111
|
+
|
|
112
|
+
// Server state
|
|
113
|
+
const { data: teamMembers = [], isLoading: teamLoading } = useTeamMembers();
|
|
114
|
+
|
|
115
|
+
// Client-side UI state (Zustand)
|
|
116
|
+
const progress = useDashboardStore(s => s.progress);
|
|
117
|
+
const setProgress = useDashboardStore(s => s.setProgress);
|
|
118
|
+
const sliderValue = useDashboardStore(s => s.sliderValue);
|
|
119
|
+
const setSliderValue = useDashboardStore(s => s.setSliderValue);
|
|
120
|
+
const switchEnabled = useDashboardStore(s => s.switchEnabled);
|
|
121
|
+
const toggleSwitch = useDashboardStore(s => s.toggleSwitch);
|
|
122
|
+
|
|
123
|
+
// Local UI-only toggles (no global relevance)
|
|
124
|
+
const [showSidebarUser, setShowSidebarUser] = useState(true);
|
|
125
|
+
const [showSidebarSettings, setShowSidebarSettings] = useState(true);
|
|
126
|
+
const [showSidebarLogout, setShowSidebarLogout] = useState(true);
|
|
127
|
+
|
|
128
|
+
// Header State
|
|
129
|
+
const [showHeaderActions, setShowHeaderActions] = useState(true);
|
|
130
|
+
const [showHeaderBreadcrumbs, setShowHeaderBreadcrumbs] = useState(true);
|
|
131
|
+
|
|
132
|
+
const handleFormSubmit = (e: React.FormEvent) => {
|
|
133
|
+
e.preventDefault();
|
|
134
|
+
toast.success(t('templates.formSubmitSuccess'));
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<div
|
|
139
|
+
className="flex-1 flex flex-col overflow-hidden transition-all duration-300"
|
|
140
|
+
style={{
|
|
141
|
+
paddingLeft: sidebarExpanded ? `${sidebarWidth}px` : '80px',
|
|
142
|
+
}}
|
|
143
|
+
>
|
|
144
|
+
{/* Sticky Header */}
|
|
145
|
+
<Header
|
|
146
|
+
showThemeToggle={true}
|
|
147
|
+
showLanguageSelector={true}
|
|
148
|
+
breadcrumbs={[
|
|
149
|
+
{ label: t('nav.designSystem'), href: '/home', icon: <Home className="w-4 h-4" /> },
|
|
150
|
+
{ label: t('templates.breadcrumb') },
|
|
151
|
+
]}
|
|
152
|
+
renderLink={(href, props) => <Link to={href} {...props} />}
|
|
153
|
+
/>
|
|
154
|
+
|
|
155
|
+
{/* Content area */}
|
|
156
|
+
<main className="flex-1 overflow-hidden bg-muted">
|
|
157
|
+
<ScrollArea className="h-full">
|
|
158
|
+
<div className="p-5 sm:p-4 md:p-6">
|
|
159
|
+
<div className="max-w-6xl mx-auto space-y-8">
|
|
160
|
+
{/* Page header */}
|
|
161
|
+
<PageHeader title={t('templates.title')} subtitle={t('templates.subtitle')} />
|
|
162
|
+
|
|
163
|
+
{/* Page Header Example */}
|
|
164
|
+
<section>
|
|
165
|
+
<h3 className="mb-4">{t('templates.headerWithBreadcrumbs.sectionTitle')}</h3>
|
|
166
|
+
<Card>
|
|
167
|
+
<CardHeader>
|
|
168
|
+
<CardTitle>{t('templates.headerWithBreadcrumbs.cardTitle')}</CardTitle>
|
|
169
|
+
<CardDescription>
|
|
170
|
+
{t('templates.headerWithBreadcrumbs.cardDescription')}
|
|
171
|
+
</CardDescription>
|
|
172
|
+
</CardHeader>
|
|
173
|
+
<CardContent className="p-0 border-t bg-background overflow-hidden rounded-b-[var(--radius-lg)]">
|
|
174
|
+
<Header
|
|
175
|
+
className="border-b"
|
|
176
|
+
breadcrumbs={[
|
|
177
|
+
{
|
|
178
|
+
label: t('templates.headerWithBreadcrumbs.breadcrumbs.dashboard'),
|
|
179
|
+
href: '#',
|
|
180
|
+
icon: <Home className="w-4 h-4" />,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
label: t('templates.headerWithBreadcrumbs.breadcrumbs.settings'),
|
|
184
|
+
href: '#',
|
|
185
|
+
icon: <Settings className="w-4 h-4" />,
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
label: t('templates.headerWithBreadcrumbs.breadcrumbs.users'),
|
|
189
|
+
href: '#',
|
|
190
|
+
icon: <Users className="w-4 h-4" />,
|
|
191
|
+
},
|
|
192
|
+
{ label: t('templates.headerWithBreadcrumbs.breadcrumbs.accessProfile') },
|
|
193
|
+
]}
|
|
194
|
+
showLanguageSelector={true}
|
|
195
|
+
showThemeToggle={true}
|
|
196
|
+
/>
|
|
197
|
+
<div className="p-6 min-h-[200px]">
|
|
198
|
+
<h4 className="text-lg font-semibold mb-2">
|
|
199
|
+
{t('templates.headerWithBreadcrumbs.exampleContentTitle')}
|
|
200
|
+
</h4>
|
|
201
|
+
<p className="text-muted-foreground">
|
|
202
|
+
{t('templates.headerWithBreadcrumbs.exampleContentDescriptionPart1')}
|
|
203
|
+
<strong>Header</strong>
|
|
204
|
+
{t('templates.headerWithBreadcrumbs.exampleContentDescriptionPart2')}
|
|
205
|
+
</p>
|
|
206
|
+
</div>
|
|
207
|
+
</CardContent>
|
|
208
|
+
</Card>
|
|
209
|
+
</section>
|
|
210
|
+
|
|
211
|
+
<Separator className="my-8" />
|
|
212
|
+
|
|
213
|
+
{/* Alert Examples */}
|
|
214
|
+
<section>
|
|
215
|
+
<h3 className="mb-4">{t('templates.sections.alerts')}</h3>
|
|
216
|
+
<div className="grid gap-4 md:grid-cols-2">
|
|
217
|
+
<Alert variant="info">
|
|
218
|
+
<AlertTitle>{t('templates.alerts.infoTitle')}</AlertTitle>
|
|
219
|
+
<AlertDescription>{t('templates.alerts.infoDescription')}</AlertDescription>
|
|
220
|
+
</Alert>
|
|
221
|
+
|
|
222
|
+
<Alert variant="destructive">
|
|
223
|
+
<AlertTitle>{t('templates.alerts.errorTitle')}</AlertTitle>
|
|
224
|
+
<AlertDescription>{t('templates.alerts.errorDescription')}</AlertDescription>
|
|
225
|
+
</Alert>
|
|
226
|
+
|
|
227
|
+
<Alert variant="success">
|
|
228
|
+
<AlertTitle>{t('templates.alerts.successTitle')}</AlertTitle>
|
|
229
|
+
<AlertDescription>{t('templates.alerts.successDescription')}</AlertDescription>
|
|
230
|
+
</Alert>
|
|
231
|
+
|
|
232
|
+
<Alert variant="warning">
|
|
233
|
+
<AlertTitle>{t('templates.alerts.warningTitle')}</AlertTitle>
|
|
234
|
+
<AlertDescription>{t('templates.alerts.warningDescription')}</AlertDescription>
|
|
235
|
+
</Alert>
|
|
236
|
+
</div>
|
|
237
|
+
</section>
|
|
238
|
+
|
|
239
|
+
<Separator className="my-8" />
|
|
240
|
+
|
|
241
|
+
{/* Cards & Tabs */}
|
|
242
|
+
<section>
|
|
243
|
+
<h3 className="mb-4">{t('templates.sections.cardsAndTabs')}</h3>
|
|
244
|
+
|
|
245
|
+
<Tabs defaultValue="overview" className="w-full">
|
|
246
|
+
<TabsList className="grid w-full grid-cols-4">
|
|
247
|
+
<TabsTrigger value="overview">{t('templates.tabs.overview')}</TabsTrigger>
|
|
248
|
+
<TabsTrigger value="forms">{t('templates.tabs.forms')}</TabsTrigger>
|
|
249
|
+
<TabsTrigger value="data">{t('templates.tabs.data')}</TabsTrigger>
|
|
250
|
+
<TabsTrigger value="settings">{t('templates.tabs.settings')}</TabsTrigger>
|
|
251
|
+
</TabsList>
|
|
252
|
+
|
|
253
|
+
{/* Overview Tab */}
|
|
254
|
+
<TabsContent value="overview" className="space-y-4">
|
|
255
|
+
<div className="grid gap-4 md:grid-cols-3">
|
|
256
|
+
<Card>
|
|
257
|
+
<CardHeader>
|
|
258
|
+
<CardTitle>{t('stats.totalUsers')}</CardTitle>
|
|
259
|
+
<CardDescription>{t('stats.last30Days')}</CardDescription>
|
|
260
|
+
</CardHeader>
|
|
261
|
+
<CardContent>
|
|
262
|
+
<div className="text-foreground">
|
|
263
|
+
<span className="[font-size:var(--text-stats)] [font-weight:var(--font-weight-bold)]">
|
|
264
|
+
1,234
|
|
265
|
+
</span>
|
|
266
|
+
<Badge variant="default" className="ml-2">
|
|
267
|
+
+12%
|
|
268
|
+
</Badge>
|
|
269
|
+
</div>
|
|
270
|
+
</CardContent>
|
|
271
|
+
</Card>
|
|
272
|
+
|
|
273
|
+
<Card>
|
|
274
|
+
<CardHeader>
|
|
275
|
+
<CardTitle>{t('stats.totalRevenue')}</CardTitle>
|
|
276
|
+
<CardDescription>{t('stats.currentMonth')}</CardDescription>
|
|
277
|
+
</CardHeader>
|
|
278
|
+
<CardContent>
|
|
279
|
+
<div className="text-foreground">
|
|
280
|
+
<span className="[font-size:var(--text-stats)] [font-weight:var(--font-weight-bold)]">
|
|
281
|
+
$ 45.2k
|
|
282
|
+
</span>
|
|
283
|
+
<Badge variant="secondary" className="ml-2">
|
|
284
|
+
+8%
|
|
285
|
+
</Badge>
|
|
286
|
+
</div>
|
|
287
|
+
</CardContent>
|
|
288
|
+
</Card>
|
|
289
|
+
|
|
290
|
+
<Card>
|
|
291
|
+
<CardHeader>
|
|
292
|
+
<CardTitle>{t('stats.conversionRate')}</CardTitle>
|
|
293
|
+
<CardDescription>{t('stats.currentWeek')}</CardDescription>
|
|
294
|
+
</CardHeader>
|
|
295
|
+
<CardContent>
|
|
296
|
+
<div className="text-foreground">
|
|
297
|
+
<span className="[font-size:var(--text-stats)] [font-weight:var(--font-weight-bold)]">
|
|
298
|
+
3.2%
|
|
299
|
+
</span>
|
|
300
|
+
<Badge variant="outline" className="ml-2">
|
|
301
|
+
-2%
|
|
302
|
+
</Badge>
|
|
303
|
+
</div>
|
|
304
|
+
</CardContent>
|
|
305
|
+
</Card>
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<Card>
|
|
309
|
+
<CardHeader>
|
|
310
|
+
<CardTitle>{t('templates.overview.progressTitle')}</CardTitle>
|
|
311
|
+
<CardDescription>
|
|
312
|
+
{t('templates.overview.progressDescription')}
|
|
313
|
+
</CardDescription>
|
|
314
|
+
</CardHeader>
|
|
315
|
+
<CardContent className="space-y-6">
|
|
316
|
+
<div className="space-y-2">
|
|
317
|
+
<div className="flex items-center justify-between">
|
|
318
|
+
<Label>{t('templates.overview.projectProgress')}</Label>
|
|
319
|
+
<span className="[font-size:var(--text-small)] text-muted-foreground">
|
|
320
|
+
{progress}%
|
|
321
|
+
</span>
|
|
322
|
+
</div>
|
|
323
|
+
<Progress value={progress} className="w-full" />
|
|
324
|
+
<div className="flex gap-2">
|
|
325
|
+
<Button
|
|
326
|
+
size="sm"
|
|
327
|
+
onClick={() => setProgress(Math.max(0, progress - 10))}
|
|
328
|
+
>
|
|
329
|
+
-10%
|
|
330
|
+
</Button>
|
|
331
|
+
<Button
|
|
332
|
+
size="sm"
|
|
333
|
+
onClick={() => setProgress(Math.min(100, progress + 10))}
|
|
334
|
+
>
|
|
335
|
+
+10%
|
|
336
|
+
</Button>
|
|
337
|
+
</div>
|
|
338
|
+
</div>
|
|
339
|
+
|
|
340
|
+
<Separator />
|
|
341
|
+
|
|
342
|
+
<div className="space-y-2">
|
|
343
|
+
<div className="flex items-center justify-between">
|
|
344
|
+
<Label>{t('templates.overview.volume')}</Label>
|
|
345
|
+
<span className="[font-size:var(--text-small)] text-muted-foreground">
|
|
346
|
+
{sliderValue[0]}%
|
|
347
|
+
</span>
|
|
348
|
+
</div>
|
|
349
|
+
<Slider
|
|
350
|
+
value={sliderValue}
|
|
351
|
+
onValueChange={setSliderValue}
|
|
352
|
+
min={0}
|
|
353
|
+
max={100}
|
|
354
|
+
step={1}
|
|
355
|
+
className="w-full"
|
|
356
|
+
aria-label={t('templates.overview.volume')}
|
|
357
|
+
/>
|
|
358
|
+
</div>
|
|
359
|
+
</CardContent>
|
|
360
|
+
</Card>
|
|
361
|
+
</TabsContent>
|
|
362
|
+
|
|
363
|
+
{/* Forms Tab */}
|
|
364
|
+
<TabsContent value="forms" className="space-y-4">
|
|
365
|
+
<Card>
|
|
366
|
+
<CardHeader>
|
|
367
|
+
<CardTitle>{t('templates.forms.registrationTitle')}</CardTitle>
|
|
368
|
+
<CardDescription>
|
|
369
|
+
{t('templates.forms.registrationDescription')}
|
|
370
|
+
</CardDescription>
|
|
371
|
+
</CardHeader>
|
|
372
|
+
<CardContent>
|
|
373
|
+
<form onSubmit={handleFormSubmit} className="space-y-4">
|
|
374
|
+
<div className="grid gap-4 md:grid-cols-2">
|
|
375
|
+
<div className="space-y-2">
|
|
376
|
+
<Label htmlFor="firstName">{t('templates.forms.firstName')}</Label>
|
|
377
|
+
<Input
|
|
378
|
+
id="firstName"
|
|
379
|
+
placeholder={t('templates.forms.firstNamePlaceholder')}
|
|
380
|
+
/>
|
|
381
|
+
</div>
|
|
382
|
+
<div className="space-y-2">
|
|
383
|
+
<Label htmlFor="lastName">{t('templates.forms.lastName')}</Label>
|
|
384
|
+
<Input
|
|
385
|
+
id="lastName"
|
|
386
|
+
placeholder={t('templates.forms.lastNamePlaceholder')}
|
|
387
|
+
/>
|
|
388
|
+
</div>
|
|
389
|
+
</div>
|
|
390
|
+
|
|
391
|
+
<div className="space-y-2">
|
|
392
|
+
<Label htmlFor="email">{t('templates.forms.email')}</Label>
|
|
393
|
+
<div className="relative">
|
|
394
|
+
<Mail className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
|
395
|
+
<Input
|
|
396
|
+
id="email"
|
|
397
|
+
type="email"
|
|
398
|
+
placeholder={t('templates.forms.emailPlaceholder')}
|
|
399
|
+
className="pl-10"
|
|
400
|
+
/>
|
|
401
|
+
</div>
|
|
402
|
+
</div>
|
|
403
|
+
|
|
404
|
+
<div className="space-y-2">
|
|
405
|
+
<Label htmlFor="phone">{t('templates.forms.phone')}</Label>
|
|
406
|
+
<div className="relative">
|
|
407
|
+
<Phone className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
|
408
|
+
<Input
|
|
409
|
+
id="phone"
|
|
410
|
+
type="tel"
|
|
411
|
+
placeholder={t('templates.forms.phonePlaceholder')}
|
|
412
|
+
className="pl-10"
|
|
413
|
+
/>
|
|
414
|
+
</div>
|
|
415
|
+
</div>
|
|
416
|
+
|
|
417
|
+
<div className="space-y-2">
|
|
418
|
+
<Label htmlFor="role">{t('templates.forms.role')}</Label>
|
|
419
|
+
<Select>
|
|
420
|
+
<SelectTrigger id="role">
|
|
421
|
+
<SelectValue placeholder={t('templates.forms.rolePlaceholder')} />
|
|
422
|
+
</SelectTrigger>
|
|
423
|
+
<SelectContent>
|
|
424
|
+
<SelectItem value="developer">
|
|
425
|
+
{t('templates.forms.roles.developer')}
|
|
426
|
+
</SelectItem>
|
|
427
|
+
<SelectItem value="designer">
|
|
428
|
+
{t('templates.forms.roles.designer')}
|
|
429
|
+
</SelectItem>
|
|
430
|
+
<SelectItem value="manager">
|
|
431
|
+
{t('templates.forms.roles.manager')}
|
|
432
|
+
</SelectItem>
|
|
433
|
+
<SelectItem value="analyst">
|
|
434
|
+
{t('templates.forms.roles.analyst')}
|
|
435
|
+
</SelectItem>
|
|
436
|
+
</SelectContent>
|
|
437
|
+
</Select>
|
|
438
|
+
</div>
|
|
439
|
+
|
|
440
|
+
<div className="space-y-2">
|
|
441
|
+
<Label htmlFor="bio">{t('templates.forms.bio')}</Label>
|
|
442
|
+
<Textarea
|
|
443
|
+
id="bio"
|
|
444
|
+
placeholder={t('templates.forms.bioPlaceholder')}
|
|
445
|
+
rows={4}
|
|
446
|
+
/>
|
|
447
|
+
</div>
|
|
448
|
+
|
|
449
|
+
<Separator />
|
|
450
|
+
|
|
451
|
+
<div className="space-y-4">
|
|
452
|
+
<h4>{t('templates.forms.preferences')}</h4>
|
|
453
|
+
|
|
454
|
+
<div className="space-y-3">
|
|
455
|
+
<div className="flex items-center space-x-2">
|
|
456
|
+
<Checkbox id="newsletter" />
|
|
457
|
+
<Label htmlFor="newsletter" className="font-normal">
|
|
458
|
+
{t('templates.forms.newsletter')}
|
|
459
|
+
</Label>
|
|
460
|
+
</div>
|
|
461
|
+
|
|
462
|
+
<div className="flex items-center space-x-2">
|
|
463
|
+
<Checkbox id="notifications" />
|
|
464
|
+
<Label htmlFor="notifications" className="font-normal">
|
|
465
|
+
{t('templates.forms.pushNotifications')}
|
|
466
|
+
</Label>
|
|
467
|
+
</div>
|
|
468
|
+
|
|
469
|
+
<div className="flex items-center space-x-2">
|
|
470
|
+
<Checkbox id="updates" />
|
|
471
|
+
<Label htmlFor="updates" className="font-normal">
|
|
472
|
+
{t('templates.forms.featureUpdates')}
|
|
473
|
+
</Label>
|
|
474
|
+
</div>
|
|
475
|
+
</div>
|
|
476
|
+
|
|
477
|
+
<Separator />
|
|
478
|
+
|
|
479
|
+
<div className="space-y-3">
|
|
480
|
+
<Label>{t('templates.forms.accountType')}</Label>
|
|
481
|
+
<RadioGroup
|
|
482
|
+
defaultValue="personal"
|
|
483
|
+
aria-label={t('templates.forms.accountType')}
|
|
484
|
+
>
|
|
485
|
+
<div className="flex items-center space-x-2">
|
|
486
|
+
<RadioGroupItem value="personal" id="personal" />
|
|
487
|
+
<Label htmlFor="personal" className="font-normal">
|
|
488
|
+
{t('templates.forms.accountPersonal')}
|
|
489
|
+
</Label>
|
|
490
|
+
</div>
|
|
491
|
+
<div className="flex items-center space-x-2">
|
|
492
|
+
<RadioGroupItem value="business" id="business" />
|
|
493
|
+
<Label htmlFor="business" className="font-normal">
|
|
494
|
+
{t('templates.forms.accountBusiness')}
|
|
495
|
+
</Label>
|
|
496
|
+
</div>
|
|
497
|
+
<div className="flex items-center space-x-2">
|
|
498
|
+
<RadioGroupItem value="enterprise" id="enterprise" />
|
|
499
|
+
<Label htmlFor="enterprise" className="font-normal">
|
|
500
|
+
{t('templates.forms.accountEnterprise')}
|
|
501
|
+
</Label>
|
|
502
|
+
</div>
|
|
503
|
+
</RadioGroup>
|
|
504
|
+
</div>
|
|
505
|
+
</div>
|
|
506
|
+
</form>
|
|
507
|
+
</CardContent>
|
|
508
|
+
<CardFooter className="flex justify-between">
|
|
509
|
+
<Button variant="outline">{t('templates.forms.cancel')}</Button>
|
|
510
|
+
<Button onClick={handleFormSubmit}>
|
|
511
|
+
{t('templates.forms.createAccount')}
|
|
512
|
+
</Button>
|
|
513
|
+
</CardFooter>
|
|
514
|
+
</Card>
|
|
515
|
+
</TabsContent>
|
|
516
|
+
|
|
517
|
+
{/* Data Tab */}
|
|
518
|
+
<TabsContent value="data" className="space-y-4">
|
|
519
|
+
<SectionErrorBoundary>
|
|
520
|
+
<Card>
|
|
521
|
+
<CardHeader>
|
|
522
|
+
<CardTitle>{t('templates.data.title')}</CardTitle>
|
|
523
|
+
<CardDescription>{t('templates.data.description')}</CardDescription>
|
|
524
|
+
</CardHeader>
|
|
525
|
+
<CardContent>
|
|
526
|
+
<div className="mb-4">
|
|
527
|
+
<div className="relative">
|
|
528
|
+
<Search className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
|
529
|
+
<Input
|
|
530
|
+
placeholder={t('templates.data.searchPlaceholder')}
|
|
531
|
+
aria-label={t('templates.data.searchPlaceholder')}
|
|
532
|
+
className="pl-10"
|
|
533
|
+
/>
|
|
534
|
+
</div>
|
|
535
|
+
</div>
|
|
536
|
+
|
|
537
|
+
<div className="rounded-[var(--radius-lg)] border border-border overflow-hidden">
|
|
538
|
+
<Table>
|
|
539
|
+
<TableHeader>
|
|
540
|
+
<TableRow>
|
|
541
|
+
<TableHead>{t('team.name')}</TableHead>
|
|
542
|
+
<TableHead>{t('team.email')}</TableHead>
|
|
543
|
+
<TableHead>{t('team.role')}</TableHead>
|
|
544
|
+
<TableHead>{t('team.status')}</TableHead>
|
|
545
|
+
<TableHead className="text-right">{t('team.actions')}</TableHead>
|
|
546
|
+
</TableRow>
|
|
547
|
+
</TableHeader>
|
|
548
|
+
<TableBody>
|
|
549
|
+
{teamLoading ? (
|
|
550
|
+
<>
|
|
551
|
+
{Array.from({ length: 5 }).map((_, i) => (
|
|
552
|
+
<TableRow key={i}>
|
|
553
|
+
<TableCell>
|
|
554
|
+
<div className="flex items-center gap-2">
|
|
555
|
+
<Skeleton className="size-8 rounded-full shrink-0" />
|
|
556
|
+
<Skeleton className="h-3.5 w-28" />
|
|
557
|
+
</div>
|
|
558
|
+
</TableCell>
|
|
559
|
+
<TableCell>
|
|
560
|
+
<Skeleton className="h-3.5 w-36" />
|
|
561
|
+
</TableCell>
|
|
562
|
+
<TableCell>
|
|
563
|
+
<Skeleton className="h-3.5 w-20" />
|
|
564
|
+
</TableCell>
|
|
565
|
+
<TableCell>
|
|
566
|
+
<Skeleton className="h-5 w-16 rounded-full" />
|
|
567
|
+
</TableCell>
|
|
568
|
+
<TableCell className="text-right">
|
|
569
|
+
<Skeleton className="h-7 w-14 ml-auto" />
|
|
570
|
+
</TableCell>
|
|
571
|
+
</TableRow>
|
|
572
|
+
))}
|
|
573
|
+
</>
|
|
574
|
+
) : (
|
|
575
|
+
teamMembers.map(member => (
|
|
576
|
+
<TableRow key={member.id}>
|
|
577
|
+
<TableCell>{member.name}</TableCell>
|
|
578
|
+
<TableCell>{member.email}</TableCell>
|
|
579
|
+
<TableCell>{t(`team.roles.${member.role}`)}</TableCell>
|
|
580
|
+
<TableCell>
|
|
581
|
+
<Badge
|
|
582
|
+
variant={
|
|
583
|
+
member.status === 'active'
|
|
584
|
+
? 'default'
|
|
585
|
+
: member.status === 'away'
|
|
586
|
+
? 'secondary'
|
|
587
|
+
: 'outline'
|
|
588
|
+
}
|
|
589
|
+
>
|
|
590
|
+
{t(`common.${member.status}`)}
|
|
591
|
+
</Badge>
|
|
592
|
+
</TableCell>
|
|
593
|
+
<TableCell className="text-right">
|
|
594
|
+
<Button variant="ghost" size="sm">
|
|
595
|
+
{t('common.edit')}
|
|
596
|
+
</Button>
|
|
597
|
+
</TableCell>
|
|
598
|
+
</TableRow>
|
|
599
|
+
))
|
|
600
|
+
)}
|
|
601
|
+
</TableBody>
|
|
602
|
+
</Table>
|
|
603
|
+
</div>
|
|
604
|
+
</CardContent>
|
|
605
|
+
<CardFooter className="flex justify-between items-center">
|
|
606
|
+
<p className="text-muted-foreground">
|
|
607
|
+
{t('team.showing', {
|
|
608
|
+
count: teamMembers.length,
|
|
609
|
+
total: teamMembers.length,
|
|
610
|
+
})}
|
|
611
|
+
</p>
|
|
612
|
+
<div className="flex gap-2">
|
|
613
|
+
<Button variant="outline" size="sm">
|
|
614
|
+
{t('common.previous')}
|
|
615
|
+
</Button>
|
|
616
|
+
<Button variant="outline" size="sm">
|
|
617
|
+
{t('common.next')}
|
|
618
|
+
</Button>
|
|
619
|
+
</div>
|
|
620
|
+
</CardFooter>
|
|
621
|
+
</Card>
|
|
622
|
+
</SectionErrorBoundary>
|
|
623
|
+
</TabsContent>
|
|
624
|
+
|
|
625
|
+
{/* Settings Tab */}
|
|
626
|
+
<TabsContent value="settings" className="space-y-4">
|
|
627
|
+
<Card>
|
|
628
|
+
<CardHeader>
|
|
629
|
+
<CardTitle>{t('templates.settings.title')}</CardTitle>
|
|
630
|
+
<CardDescription>{t('templates.settings.description')}</CardDescription>
|
|
631
|
+
</CardHeader>
|
|
632
|
+
<CardContent className="space-y-6">
|
|
633
|
+
{!disableDarkMode && (
|
|
634
|
+
<>
|
|
635
|
+
<div className="flex items-center justify-between">
|
|
636
|
+
<div className="space-y-1">
|
|
637
|
+
<Label htmlFor="dark-mode">
|
|
638
|
+
{t('templates.settings.darkMode')}
|
|
639
|
+
</Label>
|
|
640
|
+
<p className="text-muted-foreground">
|
|
641
|
+
{t('templates.settings.darkModeDescription')}
|
|
642
|
+
</p>
|
|
643
|
+
</div>
|
|
644
|
+
<Switch
|
|
645
|
+
id="dark-mode"
|
|
646
|
+
checked={switchEnabled}
|
|
647
|
+
onCheckedChange={toggleSwitch}
|
|
648
|
+
/>
|
|
649
|
+
</div>
|
|
650
|
+
|
|
651
|
+
<Separator />
|
|
652
|
+
</>
|
|
653
|
+
)}
|
|
654
|
+
|
|
655
|
+
<div className="flex items-center justify-between">
|
|
656
|
+
<div className="space-y-1">
|
|
657
|
+
<Label htmlFor="email-notifications">
|
|
658
|
+
{t('templates.settings.emailNotifications')}
|
|
659
|
+
</Label>
|
|
660
|
+
<p className="text-muted-foreground">
|
|
661
|
+
{t('templates.settings.emailNotificationsDescription')}
|
|
662
|
+
</p>
|
|
663
|
+
</div>
|
|
664
|
+
<Switch id="email-notifications" defaultChecked />
|
|
665
|
+
</div>
|
|
666
|
+
|
|
667
|
+
<Separator />
|
|
668
|
+
|
|
669
|
+
<div className="flex items-center justify-between">
|
|
670
|
+
<div className="space-y-1">
|
|
671
|
+
<Label htmlFor="push-notifications">
|
|
672
|
+
{t('templates.settings.pushNotifications')}
|
|
673
|
+
</Label>
|
|
674
|
+
<p className="text-muted-foreground">
|
|
675
|
+
{t('templates.settings.pushNotificationsDescription')}
|
|
676
|
+
</p>
|
|
677
|
+
</div>
|
|
678
|
+
<Switch id="push-notifications" />
|
|
679
|
+
</div>
|
|
680
|
+
|
|
681
|
+
<Separator />
|
|
682
|
+
|
|
683
|
+
<div className="space-y-3">
|
|
684
|
+
<Label>{t('templates.settings.language')}</Label>
|
|
685
|
+
<Select defaultValue="pt-br">
|
|
686
|
+
<SelectTrigger aria-label={t('templates.settings.language')}>
|
|
687
|
+
<SelectValue />
|
|
688
|
+
</SelectTrigger>
|
|
689
|
+
<SelectContent>
|
|
690
|
+
<SelectItem value="pt-br">
|
|
691
|
+
{t('templates.settings.languages.ptBR')}
|
|
692
|
+
</SelectItem>
|
|
693
|
+
<SelectItem value="en">
|
|
694
|
+
{t('templates.settings.languages.en')}
|
|
695
|
+
</SelectItem>
|
|
696
|
+
<SelectItem value="es">
|
|
697
|
+
{t('templates.settings.languages.es')}
|
|
698
|
+
</SelectItem>
|
|
699
|
+
</SelectContent>
|
|
700
|
+
</Select>
|
|
701
|
+
</div>
|
|
702
|
+
|
|
703
|
+
<Separator />
|
|
704
|
+
|
|
705
|
+
<div className="space-y-3">
|
|
706
|
+
<Label>{t('templates.settings.timezone')}</Label>
|
|
707
|
+
<Select defaultValue="america-sao-paulo">
|
|
708
|
+
<SelectTrigger aria-label={t('templates.settings.timezone')}>
|
|
709
|
+
<SelectValue />
|
|
710
|
+
</SelectTrigger>
|
|
711
|
+
<SelectContent>
|
|
712
|
+
<SelectItem value="america-sao-paulo">
|
|
713
|
+
{t('templates.settings.timezones.saoPaulo')}
|
|
714
|
+
</SelectItem>
|
|
715
|
+
<SelectItem value="america-new-york">
|
|
716
|
+
{t('templates.settings.timezones.newYork')}
|
|
717
|
+
</SelectItem>
|
|
718
|
+
<SelectItem value="europe-london">
|
|
719
|
+
{t('templates.settings.timezones.london')}
|
|
720
|
+
</SelectItem>
|
|
721
|
+
</SelectContent>
|
|
722
|
+
</Select>
|
|
723
|
+
</div>
|
|
724
|
+
</CardContent>
|
|
725
|
+
<CardFooter className="flex justify-between">
|
|
726
|
+
<Button variant="outline">{t('templates.settings.restoreDefaults')}</Button>
|
|
727
|
+
<Button>{t('templates.settings.saveChanges')}</Button>
|
|
728
|
+
</CardFooter>
|
|
729
|
+
</Card>
|
|
730
|
+
</TabsContent>
|
|
731
|
+
</Tabs>
|
|
732
|
+
</section>
|
|
733
|
+
|
|
734
|
+
<Separator className="my-8" />
|
|
735
|
+
|
|
736
|
+
{/* Button Variants */}
|
|
737
|
+
<section>
|
|
738
|
+
<h3 className="mb-4">{t('templates.sections.buttons')}</h3>
|
|
739
|
+
<Card>
|
|
740
|
+
<CardHeader>
|
|
741
|
+
<CardTitle>{t('templates.buttons.title')}</CardTitle>
|
|
742
|
+
<CardDescription>{t('templates.buttons.description')}</CardDescription>
|
|
743
|
+
</CardHeader>
|
|
744
|
+
<CardContent className="space-y-6">
|
|
745
|
+
<div className="space-y-3">
|
|
746
|
+
<Label>{t('templates.buttons.variants')}</Label>
|
|
747
|
+
<div className="flex flex-wrap gap-3">
|
|
748
|
+
<Button variant="default">Default</Button>
|
|
749
|
+
<Button variant="secondary">Secondary</Button>
|
|
750
|
+
<Button variant="outline">Outline</Button>
|
|
751
|
+
<Button variant="ghost">Ghost</Button>
|
|
752
|
+
<Button variant="link">Link</Button>
|
|
753
|
+
<Button variant="destructive">Destructive</Button>
|
|
754
|
+
</div>
|
|
755
|
+
</div>
|
|
756
|
+
|
|
757
|
+
<Separator />
|
|
758
|
+
|
|
759
|
+
<div className="space-y-3">
|
|
760
|
+
<Label>{t('templates.buttons.sizes')}</Label>
|
|
761
|
+
<div className="flex flex-wrap items-center gap-3">
|
|
762
|
+
<Button size="sm">Small</Button>
|
|
763
|
+
<Button size="default">Default</Button>
|
|
764
|
+
<Button size="lg">Large</Button>
|
|
765
|
+
<Button size="icon" aria-label={t('nav.settings')}>
|
|
766
|
+
<Settings className="h-4 w-4" />
|
|
767
|
+
</Button>
|
|
768
|
+
</div>
|
|
769
|
+
</div>
|
|
770
|
+
|
|
771
|
+
<Separator />
|
|
772
|
+
|
|
773
|
+
<div className="space-y-3">
|
|
774
|
+
<Label>{t('templates.buttons.withIcons')}</Label>
|
|
775
|
+
<div className="flex flex-wrap gap-3">
|
|
776
|
+
<Button>
|
|
777
|
+
<User className="mr-2 h-4 w-4" />
|
|
778
|
+
{t('templates.buttons.profile')}
|
|
779
|
+
</Button>
|
|
780
|
+
<Button variant="secondary">
|
|
781
|
+
<Mail className="mr-2 h-4 w-4" />
|
|
782
|
+
{t('templates.buttons.messages')}
|
|
783
|
+
</Button>
|
|
784
|
+
<Button variant="outline">
|
|
785
|
+
<Calendar className="mr-2 h-4 w-4" />
|
|
786
|
+
{t('templates.buttons.schedule')}
|
|
787
|
+
</Button>
|
|
788
|
+
</div>
|
|
789
|
+
</div>
|
|
790
|
+
|
|
791
|
+
<Separator />
|
|
792
|
+
|
|
793
|
+
<div className="space-y-3">
|
|
794
|
+
<Label>{t('templates.buttons.states')}</Label>
|
|
795
|
+
<div className="flex flex-wrap gap-3">
|
|
796
|
+
<Button disabled>{t('templates.buttons.disabled')}</Button>
|
|
797
|
+
<Button variant="outline" disabled>
|
|
798
|
+
{t('templates.buttons.outlineDisabled')}
|
|
799
|
+
</Button>
|
|
800
|
+
</div>
|
|
801
|
+
</div>
|
|
802
|
+
</CardContent>
|
|
803
|
+
</Card>
|
|
804
|
+
</section>
|
|
805
|
+
|
|
806
|
+
<Separator className="my-8" />
|
|
807
|
+
|
|
808
|
+
{/* Badges */}
|
|
809
|
+
<section>
|
|
810
|
+
<h3 className="mb-4">{t('templates.sections.badges')}</h3>
|
|
811
|
+
<Card>
|
|
812
|
+
<CardHeader>
|
|
813
|
+
<CardTitle>{t('templates.badges.title')}</CardTitle>
|
|
814
|
+
<CardDescription>{t('templates.badges.description')}</CardDescription>
|
|
815
|
+
</CardHeader>
|
|
816
|
+
<CardContent>
|
|
817
|
+
<div className="flex flex-wrap gap-3">
|
|
818
|
+
<Badge variant="default">Default</Badge>
|
|
819
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
820
|
+
<Badge variant="outline">Outline</Badge>
|
|
821
|
+
<Badge variant="destructive">Destructive</Badge>
|
|
822
|
+
<Badge className="bg-success text-success-foreground">Success</Badge>
|
|
823
|
+
<Badge className="bg-warning text-warning-foreground">Warning</Badge>
|
|
824
|
+
<Badge className="bg-info text-info-foreground">Info</Badge>
|
|
825
|
+
</div>
|
|
826
|
+
</CardContent>
|
|
827
|
+
</Card>
|
|
828
|
+
</section>
|
|
829
|
+
|
|
830
|
+
<Separator className="my-8" />
|
|
831
|
+
|
|
832
|
+
{/* Dialogs */}
|
|
833
|
+
<section>
|
|
834
|
+
<h3 className="mb-4">{t('templates.sections.dialogs')}</h3>
|
|
835
|
+
<div className="grid gap-4 md:grid-cols-2">
|
|
836
|
+
<Card>
|
|
837
|
+
<CardHeader>
|
|
838
|
+
<CardTitle>{t('templates.dialogs.dialogTitle')}</CardTitle>
|
|
839
|
+
<CardDescription>{t('templates.dialogs.dialogDescription')}</CardDescription>
|
|
840
|
+
</CardHeader>
|
|
841
|
+
<CardContent className="flex justify-center py-6">
|
|
842
|
+
<Dialog>
|
|
843
|
+
<DialogTrigger asChild>
|
|
844
|
+
<Button variant="outline">{t('templates.dialogs.editProfile')}</Button>
|
|
845
|
+
</DialogTrigger>
|
|
846
|
+
<DialogContent className="sm:max-w-[425px]">
|
|
847
|
+
<DialogHeader>
|
|
848
|
+
<DialogTitle>{t('templates.dialogs.editProfile')}</DialogTitle>
|
|
849
|
+
<DialogDescription>
|
|
850
|
+
{t('templates.dialogs.editProfileDescription')}
|
|
851
|
+
</DialogDescription>
|
|
852
|
+
</DialogHeader>
|
|
853
|
+
<div className="grid gap-4 py-4">
|
|
854
|
+
<div className="grid grid-cols-4 items-center gap-4">
|
|
855
|
+
<Label htmlFor="name" className="text-right">
|
|
856
|
+
{t('templates.dialogs.name')}
|
|
857
|
+
</Label>
|
|
858
|
+
<Input id="name" defaultValue="John Doe" className="col-span-3" />
|
|
859
|
+
</div>
|
|
860
|
+
<div className="grid grid-cols-4 items-center gap-4">
|
|
861
|
+
<Label htmlFor="username" className="text-right">
|
|
862
|
+
{t('templates.dialogs.username')}
|
|
863
|
+
</Label>
|
|
864
|
+
<Input id="username" defaultValue="@johndoe" className="col-span-3" />
|
|
865
|
+
</div>
|
|
866
|
+
</div>
|
|
867
|
+
<DialogFooter>
|
|
868
|
+
<Button type="submit">{t('templates.dialogs.update')}</Button>
|
|
869
|
+
</DialogFooter>
|
|
870
|
+
</DialogContent>
|
|
871
|
+
</Dialog>
|
|
872
|
+
</CardContent>
|
|
873
|
+
</Card>
|
|
874
|
+
|
|
875
|
+
<Card>
|
|
876
|
+
<CardHeader>
|
|
877
|
+
<CardTitle>{t('templates.dialogs.alertDialogTitle')}</CardTitle>
|
|
878
|
+
<CardDescription>
|
|
879
|
+
{t('templates.dialogs.alertDialogDescription')}
|
|
880
|
+
</CardDescription>
|
|
881
|
+
</CardHeader>
|
|
882
|
+
<CardContent className="flex justify-center py-6">
|
|
883
|
+
<AlertDialog>
|
|
884
|
+
<AlertDialogTrigger asChild>
|
|
885
|
+
<Button variant="destructive">
|
|
886
|
+
{t('templates.dialogs.deleteAccount')}
|
|
887
|
+
</Button>
|
|
888
|
+
</AlertDialogTrigger>
|
|
889
|
+
<AlertDialogContent className="sm:max-w-[425px]">
|
|
890
|
+
<AlertDialogHeader>
|
|
891
|
+
<AlertDialogTitle>{t('templates.dialogs.areYouSure')}</AlertDialogTitle>
|
|
892
|
+
<AlertDialogDescription>
|
|
893
|
+
{t('templates.dialogs.deleteWarning')}
|
|
894
|
+
</AlertDialogDescription>
|
|
895
|
+
</AlertDialogHeader>
|
|
896
|
+
<AlertDialogFooter>
|
|
897
|
+
<AlertDialogCancel>{t('templates.dialogs.cancel')}</AlertDialogCancel>
|
|
898
|
+
<AlertDialogAction className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
|
|
899
|
+
{t('templates.dialogs.continue')}
|
|
900
|
+
</AlertDialogAction>
|
|
901
|
+
</AlertDialogFooter>
|
|
902
|
+
</AlertDialogContent>
|
|
903
|
+
</AlertDialog>
|
|
904
|
+
</CardContent>
|
|
905
|
+
</Card>
|
|
906
|
+
</div>
|
|
907
|
+
</section>
|
|
908
|
+
|
|
909
|
+
<Separator className="my-8" />
|
|
910
|
+
|
|
911
|
+
{/* Maps */}
|
|
912
|
+
<section>
|
|
913
|
+
<MapShowcase />
|
|
914
|
+
</section>
|
|
915
|
+
|
|
916
|
+
<Separator className="my-8" />
|
|
917
|
+
|
|
918
|
+
{/* Header Variations */}
|
|
919
|
+
<section>
|
|
920
|
+
<h3 className="mb-4">{t('templates.headerVariations.sectionTitle')}</h3>
|
|
921
|
+
<Card>
|
|
922
|
+
<CardHeader>
|
|
923
|
+
<CardTitle>{t('templates.headerVariations.cardTitle')}</CardTitle>
|
|
924
|
+
<CardDescription>
|
|
925
|
+
{t('templates.headerVariations.cardDescription')}
|
|
926
|
+
</CardDescription>
|
|
927
|
+
</CardHeader>
|
|
928
|
+
<CardContent className="space-y-6">
|
|
929
|
+
<div className="p-4 border rounded-[var(--radius-lg)] bg-muted/30">
|
|
930
|
+
<h4 className="text-sm font-semibold mb-4">
|
|
931
|
+
{t('templates.headerVariations.visibleElements')}
|
|
932
|
+
</h4>
|
|
933
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
|
|
934
|
+
<div className="flex items-center space-x-2">
|
|
935
|
+
<Switch
|
|
936
|
+
id="header-actions"
|
|
937
|
+
checked={showHeaderActions}
|
|
938
|
+
onCheckedChange={setShowHeaderActions}
|
|
939
|
+
/>
|
|
940
|
+
<Label htmlFor="header-actions" className="cursor-pointer">
|
|
941
|
+
{t('templates.headerVariations.actionButtons')}
|
|
942
|
+
</Label>
|
|
943
|
+
</div>
|
|
944
|
+
<div className="flex items-center space-x-2">
|
|
945
|
+
<Switch
|
|
946
|
+
id="header-bread"
|
|
947
|
+
checked={showHeaderBreadcrumbs}
|
|
948
|
+
onCheckedChange={setShowHeaderBreadcrumbs}
|
|
949
|
+
/>
|
|
950
|
+
<Label htmlFor="header-bread" className="cursor-pointer">
|
|
951
|
+
{t('templates.headerVariations.breadcrumbsLabel')}
|
|
952
|
+
</Label>
|
|
953
|
+
</div>
|
|
954
|
+
</div>
|
|
955
|
+
</div>
|
|
956
|
+
|
|
957
|
+
<div className="relative border rounded-[var(--radius-lg)] bg-muted/10 overflow-hidden shadow-inner">
|
|
958
|
+
<div className="p-4 bg-background/50 border-b text-xs font-mono text-muted-foreground">
|
|
959
|
+
{t('templates.headerVariations.preview')}
|
|
960
|
+
</div>
|
|
961
|
+
<Header
|
|
962
|
+
title={
|
|
963
|
+
!showHeaderBreadcrumbs
|
|
964
|
+
? t('templates.headerVariations.currentPage')
|
|
965
|
+
: undefined
|
|
966
|
+
}
|
|
967
|
+
breadcrumbs={
|
|
968
|
+
showHeaderBreadcrumbs
|
|
969
|
+
? [
|
|
970
|
+
{
|
|
971
|
+
label: t('templates.headerVariations.breadcrumbBrand'),
|
|
972
|
+
href: '#',
|
|
973
|
+
icon: <Home className="w-4 h-4" />,
|
|
974
|
+
},
|
|
975
|
+
{
|
|
976
|
+
label: t('templates.headerVariations.breadcrumbSettings'),
|
|
977
|
+
href: '#',
|
|
978
|
+
},
|
|
979
|
+
{ label: t('templates.headerVariations.breadcrumbProfile') },
|
|
980
|
+
]
|
|
981
|
+
: undefined
|
|
982
|
+
}
|
|
983
|
+
actions={
|
|
984
|
+
showHeaderActions
|
|
985
|
+
? [
|
|
986
|
+
{
|
|
987
|
+
id: 'notify',
|
|
988
|
+
icon: <Bell className="w-5 h-5" />,
|
|
989
|
+
onClick: () =>
|
|
990
|
+
toast(t('templates.headerVariations.notificationsOpenedToast')),
|
|
991
|
+
},
|
|
992
|
+
{
|
|
993
|
+
id: 'mail',
|
|
994
|
+
label: t('templates.headerVariations.messagesLabel'),
|
|
995
|
+
icon: <Mail className="w-5 h-5" />,
|
|
996
|
+
onClick: () =>
|
|
997
|
+
toast(t('templates.headerVariations.messagesOpenedToast')),
|
|
998
|
+
},
|
|
999
|
+
]
|
|
1000
|
+
: undefined
|
|
1001
|
+
}
|
|
1002
|
+
/>
|
|
1003
|
+
<div className="h-32 flex items-center justify-center text-muted-foreground text-sm italic">
|
|
1004
|
+
{t('templates.headerVariations.contentArea')}
|
|
1005
|
+
</div>
|
|
1006
|
+
</div>
|
|
1007
|
+
</CardContent>
|
|
1008
|
+
</Card>
|
|
1009
|
+
</section>
|
|
1010
|
+
|
|
1011
|
+
<Separator className="my-8" />
|
|
1012
|
+
|
|
1013
|
+
{/* Sidebar Variations */}
|
|
1014
|
+
<section>
|
|
1015
|
+
<h3 className="mb-4">{t('templates.sections.sidebarVariations')}</h3>
|
|
1016
|
+
<Card>
|
|
1017
|
+
<CardHeader>
|
|
1018
|
+
<CardTitle>{t('templates.sidebar.title')}</CardTitle>
|
|
1019
|
+
<CardDescription>{t('templates.sidebar.description')}</CardDescription>
|
|
1020
|
+
</CardHeader>
|
|
1021
|
+
<CardContent>
|
|
1022
|
+
<Tabs defaultValue="assistant" className="w-full">
|
|
1023
|
+
<TabsList className="mb-4">
|
|
1024
|
+
<TabsTrigger value="assistant">
|
|
1025
|
+
{t('templates.sidebar.assistantMode')}
|
|
1026
|
+
</TabsTrigger>
|
|
1027
|
+
<TabsTrigger value="default">
|
|
1028
|
+
{t('templates.sidebar.defaultMode')}
|
|
1029
|
+
</TabsTrigger>
|
|
1030
|
+
</TabsList>
|
|
1031
|
+
|
|
1032
|
+
<div className="mb-6 p-4 border rounded-[var(--radius-lg)] bg-muted/30">
|
|
1033
|
+
<h4 className="text-sm font-semibold mb-4">
|
|
1034
|
+
{t('templates.sidebarControls.footerSettings')}
|
|
1035
|
+
</h4>
|
|
1036
|
+
<div className="flex flex-wrap gap-6 mt-2">
|
|
1037
|
+
<div className="flex items-center space-x-2">
|
|
1038
|
+
<Switch
|
|
1039
|
+
id="show-user"
|
|
1040
|
+
checked={showSidebarUser}
|
|
1041
|
+
onCheckedChange={setShowSidebarUser}
|
|
1042
|
+
/>
|
|
1043
|
+
<Label htmlFor="show-user" className="cursor-pointer">
|
|
1044
|
+
{t('templates.sidebarControls.userProfile')}
|
|
1045
|
+
</Label>
|
|
1046
|
+
</div>
|
|
1047
|
+
<div className="flex items-center space-x-2">
|
|
1048
|
+
<Switch
|
|
1049
|
+
id="show-settings"
|
|
1050
|
+
checked={showSidebarSettings}
|
|
1051
|
+
onCheckedChange={setShowSidebarSettings}
|
|
1052
|
+
/>
|
|
1053
|
+
<Label htmlFor="show-settings" className="cursor-pointer">
|
|
1054
|
+
{t('templates.sidebarControls.settings')}
|
|
1055
|
+
</Label>
|
|
1056
|
+
</div>
|
|
1057
|
+
<div className="flex items-center space-x-2">
|
|
1058
|
+
<Switch
|
|
1059
|
+
id="show-logout"
|
|
1060
|
+
checked={showSidebarLogout}
|
|
1061
|
+
onCheckedChange={setShowSidebarLogout}
|
|
1062
|
+
/>
|
|
1063
|
+
<Label htmlFor="show-logout" className="cursor-pointer">
|
|
1064
|
+
{t('templates.sidebarControls.logoutButton')}
|
|
1065
|
+
</Label>
|
|
1066
|
+
</div>
|
|
1067
|
+
</div>
|
|
1068
|
+
|
|
1069
|
+
<div className="mt-6 pt-6 border-t">
|
|
1070
|
+
<div className="flex items-center justify-between mb-4">
|
|
1071
|
+
<h4 className="text-sm font-semibold">
|
|
1072
|
+
{t('templates.sidebarControls.sidebarWidthDesktop')}
|
|
1073
|
+
</h4>
|
|
1074
|
+
<span className="text-xs font-mono bg-muted px-2 py-1 rounded">
|
|
1075
|
+
{sidebarWidth}px
|
|
1076
|
+
</span>
|
|
1077
|
+
</div>
|
|
1078
|
+
<div className="flex items-center gap-4">
|
|
1079
|
+
<span className="text-xs text-muted-foreground w-12 text-right">
|
|
1080
|
+
240px
|
|
1081
|
+
</span>
|
|
1082
|
+
<Slider
|
|
1083
|
+
value={[sidebarWidth]}
|
|
1084
|
+
onValueChange={val => setSidebarWidth(val[0])}
|
|
1085
|
+
min={240}
|
|
1086
|
+
max={450}
|
|
1087
|
+
step={10}
|
|
1088
|
+
className="flex-1"
|
|
1089
|
+
aria-label={t('templates.sidebarControls.sidebarWidthAriaLabel')}
|
|
1090
|
+
/>
|
|
1091
|
+
<span className="text-xs text-muted-foreground w-12">450px</span>
|
|
1092
|
+
</div>
|
|
1093
|
+
</div>
|
|
1094
|
+
</div>
|
|
1095
|
+
|
|
1096
|
+
<TabsContent value="assistant">
|
|
1097
|
+
<div
|
|
1098
|
+
className="relative h-[600px] border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
1099
|
+
style={{ transform: 'translateZ(0)' }}
|
|
1100
|
+
>
|
|
1101
|
+
<Sidebar
|
|
1102
|
+
expanded={true}
|
|
1103
|
+
width={sidebarWidth}
|
|
1104
|
+
onToggle={() => {}}
|
|
1105
|
+
user={{ email: 'admin@xertica.com' }}
|
|
1106
|
+
onLogout={() => toast(t('templates.sidebar.logoutToast'))}
|
|
1107
|
+
location={{ pathname: '/assistant/current' }}
|
|
1108
|
+
navigate={() => {}}
|
|
1109
|
+
variant="assistant"
|
|
1110
|
+
search={{
|
|
1111
|
+
show: true,
|
|
1112
|
+
placeholder: t('templates.sidebar.searchTopicsPlaceholder'),
|
|
1113
|
+
filter: {
|
|
1114
|
+
show: true,
|
|
1115
|
+
content: (
|
|
1116
|
+
<div className="p-2 space-y-2">
|
|
1117
|
+
<div className="text-xs font-semibold uppercase text-muted-foreground px-2">
|
|
1118
|
+
{t('templates.sidebarControls.filterByStatus')}
|
|
1119
|
+
</div>
|
|
1120
|
+
<div className="flex flex-wrap gap-2 p-1">
|
|
1121
|
+
<Badge className="bg-sidebar-foreground/20 text-sidebar-foreground border-none cursor-pointer hover:bg-sidebar-foreground/30">
|
|
1122
|
+
{t('templates.sidebarControls.filterActive')}
|
|
1123
|
+
</Badge>
|
|
1124
|
+
<Badge
|
|
1125
|
+
variant="outline"
|
|
1126
|
+
className="text-sidebar-foreground/70 border-sidebar-foreground/20 cursor-pointer hover:bg-sidebar-foreground/10"
|
|
1127
|
+
>
|
|
1128
|
+
{t('templates.sidebarControls.filterArchived')}
|
|
1129
|
+
</Badge>
|
|
1130
|
+
<Badge
|
|
1131
|
+
variant="outline"
|
|
1132
|
+
className="text-sidebar-foreground/70 border-sidebar-foreground/20 cursor-pointer hover:bg-sidebar-foreground/10"
|
|
1133
|
+
>
|
|
1134
|
+
{t('templates.sidebarControls.filterPending')}
|
|
1135
|
+
</Badge>
|
|
1136
|
+
</div>
|
|
1137
|
+
</div>
|
|
1138
|
+
),
|
|
1139
|
+
},
|
|
1140
|
+
}}
|
|
1141
|
+
fixedArea={{
|
|
1142
|
+
show: true,
|
|
1143
|
+
content: (
|
|
1144
|
+
<Button className="w-full bg-sidebar-primary hover:bg-sidebar-primary/90 text-sidebar-primary-foreground shadow-lg font-bold border-none transition-all duration-300 transform hover:scale-[1.02] active:scale-[0.98]">
|
|
1145
|
+
<Plus className="w-4 h-4 mr-2" />
|
|
1146
|
+
{t('templates.sidebar.newConversation')}
|
|
1147
|
+
</Button>
|
|
1148
|
+
),
|
|
1149
|
+
}}
|
|
1150
|
+
navigationGroups={[
|
|
1151
|
+
{
|
|
1152
|
+
id: 'recent',
|
|
1153
|
+
label: t('templates.sidebar.recent'),
|
|
1154
|
+
icon: Clock,
|
|
1155
|
+
items: [
|
|
1156
|
+
{
|
|
1157
|
+
path: '/assistant/refatoracao',
|
|
1158
|
+
label: t('templates.sidebar.items.sidebarRefactor'),
|
|
1159
|
+
description: t(
|
|
1160
|
+
'templates.sidebar.items.sidebarRefactorDescription'
|
|
1161
|
+
),
|
|
1162
|
+
actions: [
|
|
1163
|
+
{
|
|
1164
|
+
label: t('templates.sidebar.actions.rename'),
|
|
1165
|
+
icon: FileEdit,
|
|
1166
|
+
onClick: () =>
|
|
1167
|
+
toast(t('templates.sidebar.actions.renameToast')),
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
label: t('templates.sidebar.actions.move'),
|
|
1171
|
+
icon: ArrowRightLeft,
|
|
1172
|
+
children: [
|
|
1173
|
+
{
|
|
1174
|
+
label: t('templates.sidebar.actions.moveActive'),
|
|
1175
|
+
onClick: () =>
|
|
1176
|
+
toast(t('templates.sidebar.actions.moveActiveToast')),
|
|
1177
|
+
},
|
|
1178
|
+
{
|
|
1179
|
+
label: t('templates.sidebar.actions.moveMonitoring'),
|
|
1180
|
+
onClick: () =>
|
|
1181
|
+
toast(
|
|
1182
|
+
t('templates.sidebar.actions.moveMonitoringToast')
|
|
1183
|
+
),
|
|
1184
|
+
},
|
|
1185
|
+
{
|
|
1186
|
+
label: t('templates.sidebar.actions.moveArchive'),
|
|
1187
|
+
onClick: () =>
|
|
1188
|
+
toast(
|
|
1189
|
+
t('templates.sidebar.actions.moveArchiveToast')
|
|
1190
|
+
),
|
|
1191
|
+
},
|
|
1192
|
+
],
|
|
1193
|
+
},
|
|
1194
|
+
{
|
|
1195
|
+
label: t('templates.sidebar.actions.clear'),
|
|
1196
|
+
icon: Trash2,
|
|
1197
|
+
onClick: () =>
|
|
1198
|
+
toast(t('templates.sidebar.actions.clearToast')),
|
|
1199
|
+
variant: 'destructive',
|
|
1200
|
+
},
|
|
1201
|
+
],
|
|
1202
|
+
},
|
|
1203
|
+
],
|
|
1204
|
+
},
|
|
1205
|
+
{
|
|
1206
|
+
id: 'projects',
|
|
1207
|
+
label: t('templates.sidebar.constructionMonitoring'),
|
|
1208
|
+
icon: Map,
|
|
1209
|
+
actions: [
|
|
1210
|
+
{
|
|
1211
|
+
label: t('templates.sidebar.actions.newCategory'),
|
|
1212
|
+
icon: Plus,
|
|
1213
|
+
onClick: () =>
|
|
1214
|
+
toast(t('templates.sidebar.actions.newCategoryToast')),
|
|
1215
|
+
},
|
|
1216
|
+
{
|
|
1217
|
+
label: t('templates.sidebar.actions.archiveGroup'),
|
|
1218
|
+
icon: Archive,
|
|
1219
|
+
onClick: () =>
|
|
1220
|
+
toast(t('templates.sidebar.actions.archiveGroupToast')),
|
|
1221
|
+
},
|
|
1222
|
+
],
|
|
1223
|
+
items: [
|
|
1224
|
+
{
|
|
1225
|
+
path: '/assistant/br163',
|
|
1226
|
+
label: t('templates.sidebar.items.br163Restoration'),
|
|
1227
|
+
icon: () => (
|
|
1228
|
+
<div className="w-2 h-2 rounded-full bg-yellow-500" />
|
|
1229
|
+
),
|
|
1230
|
+
description: (
|
|
1231
|
+
<div className="space-y-1.5 min-w-[160px]">
|
|
1232
|
+
<Progress
|
|
1233
|
+
value={67}
|
|
1234
|
+
className="h-1.5 bg-sidebar-foreground/10"
|
|
1235
|
+
/>
|
|
1236
|
+
<div className="flex justify-between items-center text-[10px] text-sidebar-foreground/60">
|
|
1237
|
+
<span>{t('templates.sidebar.items.br163Location')}</span>
|
|
1238
|
+
<span>67%</span>
|
|
1239
|
+
</div>
|
|
1240
|
+
</div>
|
|
1241
|
+
),
|
|
1242
|
+
},
|
|
1243
|
+
],
|
|
1244
|
+
},
|
|
1245
|
+
]}
|
|
1246
|
+
footer={{
|
|
1247
|
+
showUser: showSidebarUser,
|
|
1248
|
+
showSettings: showSidebarSettings,
|
|
1249
|
+
showLogout: showSidebarLogout,
|
|
1250
|
+
}}
|
|
1251
|
+
/>
|
|
1252
|
+
<div
|
|
1253
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
1254
|
+
style={{ left: `${sidebarWidth}px` }}
|
|
1255
|
+
>
|
|
1256
|
+
<p className="text-muted-foreground text-center">
|
|
1257
|
+
{t('templates.sidebar.assistantContent')}
|
|
1258
|
+
</p>
|
|
1259
|
+
</div>
|
|
1260
|
+
</div>
|
|
1261
|
+
</TabsContent>
|
|
1262
|
+
|
|
1263
|
+
<TabsContent value="default">
|
|
1264
|
+
<div
|
|
1265
|
+
className="relative h-[600px] border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
1266
|
+
style={{ transform: 'translateZ(0)' }}
|
|
1267
|
+
>
|
|
1268
|
+
<Sidebar
|
|
1269
|
+
expanded={true}
|
|
1270
|
+
width={sidebarWidth}
|
|
1271
|
+
onToggle={() => {}}
|
|
1272
|
+
user={{
|
|
1273
|
+
name: 'Ariel Santos',
|
|
1274
|
+
email: 'admin@xertica.com',
|
|
1275
|
+
avatar: 'https://github.com/shadcn.png',
|
|
1276
|
+
}}
|
|
1277
|
+
onLogout={() => toast(t('templates.sidebar.logoutToast'))}
|
|
1278
|
+
onSettingsClick={() =>
|
|
1279
|
+
toast(t('templates.sidebar.settingsClickedToast'))
|
|
1280
|
+
}
|
|
1281
|
+
location={{ pathname: '/home' }}
|
|
1282
|
+
navigate={() => {}}
|
|
1283
|
+
variant="default"
|
|
1284
|
+
routes={[
|
|
1285
|
+
{
|
|
1286
|
+
path: '/home',
|
|
1287
|
+
label: t('templates.sidebar.routes.home'),
|
|
1288
|
+
icon: Home,
|
|
1289
|
+
},
|
|
1290
|
+
{
|
|
1291
|
+
path: '/dashboard',
|
|
1292
|
+
label: t('templates.sidebar.routes.dashboard'),
|
|
1293
|
+
icon: Users,
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
path: '/settings',
|
|
1297
|
+
label: t('templates.sidebar.routes.settings'),
|
|
1298
|
+
icon: Settings,
|
|
1299
|
+
},
|
|
1300
|
+
]}
|
|
1301
|
+
footer={{
|
|
1302
|
+
showUser: showSidebarUser,
|
|
1303
|
+
showSettings: showSidebarSettings,
|
|
1304
|
+
showLogout: showSidebarLogout,
|
|
1305
|
+
}}
|
|
1306
|
+
/>
|
|
1307
|
+
<div
|
|
1308
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
1309
|
+
style={{ left: `${sidebarWidth}px` }}
|
|
1310
|
+
>
|
|
1311
|
+
<p className="text-muted-foreground text-center">
|
|
1312
|
+
{t('templates.sidebar.defaultContent')}
|
|
1313
|
+
</p>
|
|
1314
|
+
</div>
|
|
1315
|
+
</div>
|
|
1316
|
+
</TabsContent>
|
|
1317
|
+
</Tabs>
|
|
1318
|
+
</CardContent>
|
|
1319
|
+
</Card>
|
|
1320
|
+
</section>
|
|
1321
|
+
|
|
1322
|
+
<Separator className="my-8" />
|
|
1323
|
+
|
|
1324
|
+
{/* Footer Note */}
|
|
1325
|
+
<Card className="mt-8">
|
|
1326
|
+
<CardHeader>
|
|
1327
|
+
<CardTitle>{t('templates.footer.title')}</CardTitle>
|
|
1328
|
+
<CardDescription>{t('templates.footer.subtitle')}</CardDescription>
|
|
1329
|
+
</CardHeader>
|
|
1330
|
+
<CardContent className="space-y-4">
|
|
1331
|
+
<p className="text-muted-foreground">
|
|
1332
|
+
{t('templates.footer.descriptionPart1')}
|
|
1333
|
+
<code className="bg-muted px-2 py-1 rounded-[var(--radius-sm)] [font-size:var(--text-small)]">
|
|
1334
|
+
xertica-ui
|
|
1335
|
+
</code>
|
|
1336
|
+
{t('templates.footer.descriptionPart2')}
|
|
1337
|
+
</p>
|
|
1338
|
+
<Alert variant="info">
|
|
1339
|
+
<AlertTitle>{t('templates.footer.tipTitle')}</AlertTitle>
|
|
1340
|
+
<AlertDescription>
|
|
1341
|
+
{t('templates.footer.tipDescriptionPart1')}
|
|
1342
|
+
<code className="bg-muted px-1 rounded">styles/xertica/tokens.css</code>
|
|
1343
|
+
{t('templates.footer.tipDescriptionPart2')}
|
|
1344
|
+
</AlertDescription>
|
|
1345
|
+
</Alert>
|
|
1346
|
+
</CardContent>
|
|
1347
|
+
</Card>
|
|
1348
|
+
</div>
|
|
1349
|
+
</div>
|
|
1350
|
+
</ScrollArea>
|
|
1351
|
+
</main>
|
|
1352
|
+
</div>
|
|
1353
|
+
);
|
|
1354
|
+
}
|