@atlashub/smartstack 3.29.0 → 3.31.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/dist/chunks/{AgentSkillsPage-ChykpPZx.js → AgentSkillsPage-CDMhqrhE.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-ChykpPZx.js.map → AgentSkillsPage-CDMhqrhE.js.map} +1 -1
- package/dist/chunks/{AgentSkillsPage-ABpqnnyK.js → AgentSkillsPage-DcvOMm5k.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-ABpqnnyK.js.map → AgentSkillsPage-DcvOMm5k.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-BltzNlXI.js → AgentWorkloadPage-DYBPNzjQ.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-BltzNlXI.js.map → AgentWorkloadPage-DYBPNzjQ.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-BI5QWJyQ.js → AgentWorkloadPage-YpJSDaWc.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-BI5QWJyQ.js.map → AgentWorkloadPage-YpJSDaWc.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-BaheZKBq.js → ApiCatalogDetailPage-9r1axtCg.js} +3 -3
- package/dist/chunks/{ApiCatalogDetailPage-BaheZKBq.js.map → ApiCatalogDetailPage-9r1axtCg.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-CsRxlHwO.js → ApiCatalogDetailPage-TjCQ8_A8.js} +2 -2
- package/dist/chunks/{ApiCatalogDetailPage-CsRxlHwO.js.map → ApiCatalogDetailPage-TjCQ8_A8.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-B0yIz8-U.js → ApiCatalogPage-COxazTnz.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-B0yIz8-U.js.map → ApiCatalogPage-COxazTnz.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-CqmmHpQ4.js → ApiCatalogPage-QRysH0pT.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-CqmmHpQ4.js.map → ApiCatalogPage-QRysH0pT.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-CdT6KNd7.js → ApplicationDetailPage-Dbx01Ikm.js} +4 -4
- package/dist/chunks/{ApplicationDetailPage-CdT6KNd7.js.map → ApplicationDetailPage-Dbx01Ikm.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-CngD5JSN.js → ApplicationDetailPage-jSHy3MPz.js} +2 -2
- package/dist/chunks/{ApplicationDetailPage-CngD5JSN.js.map → ApplicationDetailPage-jSHy3MPz.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-1V4iQ6eY.js → ApplicationsDashboardPage-CclKc0wI.js} +3 -3
- package/dist/chunks/{ApplicationsDashboardPage-1V4iQ6eY.js.map → ApplicationsDashboardPage-CclKc0wI.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-DHmnjk2O.js → ApplicationsDashboardPage-CxWmOc1x.js} +2 -2
- package/dist/chunks/{ApplicationsDashboardPage-DHmnjk2O.js.map → ApplicationsDashboardPage-CxWmOc1x.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-CiMJFlB_.js → ApplicationsGridPage-BJXWXwyI.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-CiMJFlB_.js.map → ApplicationsGridPage-BJXWXwyI.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-Bo3NDnBF.js → ApplicationsGridPage-D2l8cM3o.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-Bo3NDnBF.js.map → ApplicationsGridPage-D2l8cM3o.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-L2_S23aN.js → ApplicationsListPage-CMosl3my.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-L2_S23aN.js.map → ApplicationsListPage-CMosl3my.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-De8jQ1Cm.js → ApplicationsListPage-Dc6NGQ61.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-De8jQ1Cm.js.map → ApplicationsListPage-Dc6NGQ61.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-DBq7_Sm8.js → ApplicationsPage-DH7tpMlF.js} +2 -2
- package/dist/chunks/{ApplicationsPage-DBq7_Sm8.js.map → ApplicationsPage-DH7tpMlF.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-CiNI-b0R.js → ApplicationsPage-DI-iMqoJ.js} +4 -4
- package/dist/chunks/{ApplicationsPage-CiNI-b0R.js.map → ApplicationsPage-DI-iMqoJ.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-C8rfUsMB.js → AssignmentRulesPage-B5UbujbZ.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-C8rfUsMB.js.map → AssignmentRulesPage-B5UbujbZ.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-DFsO4ZES.js → AssignmentRulesPage-E79QBSLb.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-DFsO4ZES.js.map → AssignmentRulesPage-E79QBSLb.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-COCikISI.js → AssignmentsPage-CDFaL1gT.js} +2 -2
- package/dist/chunks/{AssignmentsPage-COCikISI.js.map → AssignmentsPage-CDFaL1gT.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-78C_EBsw.js → AssignmentsPage-CPeKJjyK.js} +2 -2
- package/dist/chunks/{AssignmentsPage-78C_EBsw.js.map → AssignmentsPage-CPeKJjyK.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-DqT6ueVi.js → AuthCallbackPage-BZ3Ocos5.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-DqT6ueVi.js.map → AuthCallbackPage-BZ3Ocos5.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-BF4bkTnR.js → AuthCallbackPage-Bml48QpH.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-BF4bkTnR.js.map → AuthCallbackPage-Bml48QpH.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-DJy4idrf.js → ConfirmEmailPage-DP1XPaKK.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-DJy4idrf.js.map → ConfirmEmailPage-DP1XPaKK.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-Bh_K5qJn.js → ConfirmEmailPage-DyzslZ06.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-Bh_K5qJn.js.map → ConfirmEmailPage-DyzslZ06.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-pL7jbG9o.js → CreateSupportTicketPage-Bz2KrMik.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-pL7jbG9o.js.map → CreateSupportTicketPage-Bz2KrMik.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-AVTwXbJd.js → CreateSupportTicketPage-hKjKM0Bh.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-AVTwXbJd.js.map → CreateSupportTicketPage-hKjKM0Bh.js.map} +1 -1
- package/dist/chunks/{DashboardPage-DdQlTLw0.js → DashboardPage-B4nAd8Tj.js} +2 -2
- package/dist/chunks/{DashboardPage-DdQlTLw0.js.map → DashboardPage-B4nAd8Tj.js.map} +1 -1
- package/dist/chunks/{DashboardPage-DOitDfGV.js → DashboardPage-C9qgPBS-.js} +3 -3
- package/dist/chunks/{DashboardPage-DOitDfGV.js.map → DashboardPage-C9qgPBS-.js.map} +1 -1
- package/dist/chunks/{DashboardPage-C55mIiB6.js → DashboardPage-CjbNGMo1.js} +3 -3
- package/dist/chunks/{DashboardPage-C55mIiB6.js.map → DashboardPage-CjbNGMo1.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CcCnUl7s.js → DashboardPage-rN7IFlTR.js} +2 -2
- package/dist/chunks/{DashboardPage-CcCnUl7s.js.map → DashboardPage-rN7IFlTR.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-DRr55328.js → EscalationConfigPage-CGv2L62M.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-DRr55328.js.map → EscalationConfigPage-CGv2L62M.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-DNnZftCH.js → EscalationConfigPage-DpYDmsgw.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-DNnZftCH.js.map → EscalationConfigPage-DpYDmsgw.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-1SCOPIqK.js → ForceChangePasswordPage-CLI_fpF4.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-1SCOPIqK.js.map → ForceChangePasswordPage-CLI_fpF4.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-DBeG_HRO.js → ForceChangePasswordPage-Db6sOrZN.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-DBeG_HRO.js.map → ForceChangePasswordPage-Db6sOrZN.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-Dlb6wKfC.js → ForgotPasswordPage-BhMz2B6A.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-Dlb6wKfC.js.map → ForgotPasswordPage-BhMz2B6A.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-DffYfXva.js → ForgotPasswordPage-D06arMXO.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-DffYfXva.js.map → ForgotPasswordPage-D06arMXO.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-C9nRbeHI.js → GroupDetailPage-BCM8KBCd.js} +5 -5
- package/dist/chunks/{GroupDetailPage-C9nRbeHI.js.map → GroupDetailPage-BCM8KBCd.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-CPPUWzXf.js → GroupDetailPage-CGMV3bWt.js} +2 -2
- package/dist/chunks/{GroupDetailPage-CPPUWzXf.js.map → GroupDetailPage-CGMV3bWt.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-BAX0xwJX.js → MyAccessRequestsPage-BBrwEomx.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-BAX0xwJX.js.map → MyAccessRequestsPage-BBrwEomx.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-BMY1V631.js → MyAccessRequestsPage-CrlWe3gd.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-BMY1V631.js.map → MyAccessRequestsPage-CrlWe3gd.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-BHtp67SD.js → MyTenantsPage-BOV34_rJ.js} +3 -3
- package/dist/chunks/{MyTenantsPage-BHtp67SD.js.map → MyTenantsPage-BOV34_rJ.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-Bbn4HxN2.js → MyTenantsPage-CK4-klmd.js} +2 -2
- package/dist/chunks/{MyTenantsPage-Bbn4HxN2.js.map → MyTenantsPage-CK4-klmd.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-D9IGVofj.js → MyTicketsPage-CFZ1G4dG.js} +2 -2
- package/dist/chunks/{MyTicketsPage-D9IGVofj.js.map → MyTicketsPage-CFZ1G4dG.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-BvZeiTXu.js → MyTicketsPage-DuhpwhZx.js} +2 -2
- package/dist/chunks/{MyTicketsPage-BvZeiTXu.js.map → MyTicketsPage-DuhpwhZx.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-ChtMK1yt.js → NavigationAppsPage-BnNQRfBP.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-ChtMK1yt.js.map → NavigationAppsPage-BnNQRfBP.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-DiPBCsAF.js → NavigationAppsPage-DdJxEoTZ.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-DiPBCsAF.js.map → NavigationAppsPage-DdJxEoTZ.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-BCnL9oPb.js → NotificationsPage-BllOlagk.js} +2 -2
- package/dist/chunks/{NotificationsPage-BCnL9oPb.js.map → NotificationsPage-BllOlagk.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-BxCiGzHk.js → NotificationsPage-D1T_ozHl.js} +2 -2
- package/dist/chunks/{NotificationsPage-BxCiGzHk.js.map → NotificationsPage-D1T_ozHl.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-CV_cxq7k.js → OnboardingWizardPage-CioLaCYz.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-CV_cxq7k.js.map → OnboardingWizardPage-CioLaCYz.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-Du-tQ2ag.js → OnboardingWizardPage-CrAQt7qL.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-Du-tQ2ag.js.map → OnboardingWizardPage-CrAQt7qL.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-C1iuWv0G.js → PermissionDetailPage-BIG78-1-.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-C1iuWv0G.js.map → PermissionDetailPage-BIG78-1-.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-Ds4Jt1os.js → PermissionDetailPage-CvPqugYu.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-Ds4Jt1os.js.map → PermissionDetailPage-CvPqugYu.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-BGI2nxCn.js → PermissionsPage-CDSuc8vw.js} +2 -2
- package/dist/chunks/{PermissionsPage-BGI2nxCn.js.map → PermissionsPage-CDSuc8vw.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-sauv7ct1.js → PermissionsPage-XaOrGrPZ.js} +2 -2
- package/dist/chunks/{PermissionsPage-sauv7ct1.js.map → PermissionsPage-XaOrGrPZ.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-CQWEcghD.js → PortalDashboardPage-BsWVXkMe.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-CQWEcghD.js.map → PortalDashboardPage-BsWVXkMe.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-2kCbJw9w.js → PortalDashboardPage-oSD7oQhJ.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-2kCbJw9w.js.map → PortalDashboardPage-oSD7oQhJ.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-Bu4gaDRb.js → PreferencesPage-DD0_XWdT.js} +2 -2
- package/dist/chunks/{PreferencesPage-Bu4gaDRb.js.map → PreferencesPage-DD0_XWdT.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-Dbg0bEYD.js → PreferencesPage-ca2BOdoH.js} +2 -2
- package/dist/chunks/{PreferencesPage-Dbg0bEYD.js.map → PreferencesPage-ca2BOdoH.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DfiBhOUt.js → ProfilePage-Bex_JN5N.js} +2 -2
- package/dist/chunks/{ProfilePage-DfiBhOUt.js.map → ProfilePage-Bex_JN5N.js.map} +1 -1
- package/dist/chunks/{ProfilePage-C5QS7tsh.js → ProfilePage-C8tUIOnb.js} +2 -2
- package/dist/chunks/{ProfilePage-C5QS7tsh.js.map → ProfilePage-C8tUIOnb.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-C0RgHbJb.js → ReferencesManagementPage-B-FXS2ln.js} +2 -2
- package/dist/chunks/{ReferencesManagementPage-C0RgHbJb.js.map → ReferencesManagementPage-B-FXS2ln.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-Bs0mapj8.js → ReferencesManagementPage-C8KZprkI.js} +3 -3
- package/dist/chunks/{ReferencesManagementPage-Bs0mapj8.js.map → ReferencesManagementPage-C8KZprkI.js.map} +1 -1
- package/dist/chunks/{RegisterPage-DoeIiJt0.js → RegisterPage-BYt__zKJ.js} +2 -2
- package/dist/chunks/{RegisterPage-DoeIiJt0.js.map → RegisterPage-BYt__zKJ.js.map} +1 -1
- package/dist/chunks/{RegisterPage-DS1chV_A.js → RegisterPage-MWcVu-LY.js} +2 -2
- package/dist/chunks/{RegisterPage-DS1chV_A.js.map → RegisterPage-MWcVu-LY.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-3KEk3zj5.js → ResetPasswordPage-DaJiMj5Z.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-3KEk3zj5.js.map → ResetPasswordPage-DaJiMj5Z.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-C_VQSFB5.js → ResetPasswordPage-rCLUIj_T.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-C_VQSFB5.js.map → ResetPasswordPage-rCLUIj_T.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-S6URD--N.js → ResolutionModal-DeuPnLWg.js} +2 -2
- package/dist/chunks/{ResolutionModal-S6URD--N.js.map → ResolutionModal-DeuPnLWg.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-BzI1x79r.js → ResolutionModal-j7Rp6apG.js} +2 -2
- package/dist/chunks/{ResolutionModal-BzI1x79r.js.map → ResolutionModal-j7Rp6apG.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-SXK9cq_3.js → RoleDetailPage-CLtZWX17.js} +3 -3
- package/dist/chunks/{RoleDetailPage-SXK9cq_3.js.map → RoleDetailPage-CLtZWX17.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-DvEEWPKr.js → RoleDetailPage-TGyGmLMM.js} +2 -2
- package/dist/chunks/{RoleDetailPage-DvEEWPKr.js.map → RoleDetailPage-TGyGmLMM.js.map} +1 -1
- package/dist/chunks/{RolesPage-C5gYJxAl.js → RolesPage-C0c5G9e7.js} +2 -2
- package/dist/chunks/{RolesPage-C5gYJxAl.js.map → RolesPage-C0c5G9e7.js.map} +1 -1
- package/dist/chunks/{RolesPage-B75lCugt.js → RolesPage-Dm03fBBf.js} +2 -2
- package/dist/chunks/{RolesPage-B75lCugt.js.map → RolesPage-Dm03fBBf.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-BqXHATb6.js → SlaConfigPage-B4WDzEKi.js} +2 -2
- package/dist/chunks/{SlaConfigPage-BqXHATb6.js.map → SlaConfigPage-B4WDzEKi.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-DZ4P1FFW.js → SlaConfigPage-Cwo9NwxH.js} +2 -2
- package/dist/chunks/{SlaConfigPage-DZ4P1FFW.js.map → SlaConfigPage-Cwo9NwxH.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-DW7KJjYK.js → SupportPermissionsPage-CL12dFy-.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-DW7KJjYK.js.map → SupportPermissionsPage-CL12dFy-.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-B4xy_pCQ.js → SupportPermissionsPage-CneIhl30.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-B4xy_pCQ.js.map → SupportPermissionsPage-CneIhl30.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-m5-sLJ7F.js → TemplatesPage-DStKmwHT.js} +2 -2
- package/dist/chunks/{TemplatesPage-m5-sLJ7F.js.map → TemplatesPage-DStKmwHT.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-DZa0PQTE.js → TemplatesPage-X4Rrhs9p.js} +2 -2
- package/dist/chunks/{TemplatesPage-DZa0PQTE.js.map → TemplatesPage-X4Rrhs9p.js.map} +1 -1
- package/dist/chunks/{TenantCard-CqfifMrM.js → TenantCard-BUBYWtvR.js} +2 -2
- package/dist/chunks/{TenantCard-CqfifMrM.js.map → TenantCard-BUBYWtvR.js.map} +1 -1
- package/dist/chunks/{TenantCard-BJQi7Oew.js → TenantCard-CAgiB-NG.js} +2 -2
- package/dist/chunks/{TenantCard-BJQi7Oew.js.map → TenantCard-CAgiB-NG.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-CdiYJvuH.js → TenantScopeSelector-B9vtpIZx.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-CdiYJvuH.js.map → TenantScopeSelector-B9vtpIZx.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-Cl5DD318.js → TenantScopeSelector-BAoah-mL.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-Cl5DD318.js.map → TenantScopeSelector-BAoah-mL.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-C1UuMxD8.js → TicketDetailPage-BFcP4X8s.js} +2 -2
- package/dist/chunks/{TicketDetailPage-C1UuMxD8.js.map → TicketDetailPage-BFcP4X8s.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-BOC9rHu3.js → TicketDetailPage-D_Npnt4A.js} +2 -2
- package/dist/chunks/{TicketDetailPage-BOC9rHu3.js.map → TicketDetailPage-D_Npnt4A.js.map} +1 -1
- package/dist/chunks/{TicketsPage-BjaN4Baq.js → TicketsPage-DBP9kalU.js} +2 -2
- package/dist/chunks/{TicketsPage-BjaN4Baq.js.map → TicketsPage-DBP9kalU.js.map} +1 -1
- package/dist/chunks/{TicketsPage-BCgHZA-m.js → TicketsPage-p21DLhUb.js} +2 -2
- package/dist/chunks/{TicketsPage-BCgHZA-m.js.map → TicketsPage-p21DLhUb.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-ChQL1mVY.js → UserCreateTicketPage-DOwShnG8.js} +3 -3
- package/dist/chunks/UserCreateTicketPage-DOwShnG8.js.map +1 -0
- package/dist/chunks/{UserCreateTicketPage-DkjsHeV7.js → UserCreateTicketPage-lvlvp2u6.js} +48 -48
- package/dist/chunks/UserCreateTicketPage-lvlvp2u6.js.map +1 -0
- package/dist/chunks/{UserDashboardPage-81-3GJAQ.js → UserDashboardPage-C_tm7Pld.js} +2 -2
- package/dist/chunks/{UserDashboardPage-81-3GJAQ.js.map → UserDashboardPage-C_tm7Pld.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-BMYrtF3o.js → UserDashboardPage-Dp6q6FEW.js} +2 -2
- package/dist/chunks/{UserDashboardPage-BMYrtF3o.js.map → UserDashboardPage-Dp6q6FEW.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-D6oCH2eS.js → UserDetailPage-6grZ6gmV.js} +5 -5
- package/dist/chunks/{UserDetailPage-D6oCH2eS.js.map → UserDetailPage-6grZ6gmV.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-BMW8jAWG.js → UserDetailPage-DXLxO7LF.js} +2 -2
- package/dist/chunks/{UserDetailPage-BMW8jAWG.js.map → UserDetailPage-DXLxO7LF.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-ZH2BDWBt.js → UserTicketDetailPage-Ch9IfCPo.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-ZH2BDWBt.js.map → UserTicketDetailPage-Ch9IfCPo.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-Z_myXXJ0.js → UserTicketDetailPage-a4II5VEE.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-Z_myXXJ0.js.map → UserTicketDetailPage-a4II5VEE.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-B8Ka6uRa.js → UsersGroupsPage-B7Er0V4l.js} +3 -3
- package/dist/chunks/{UsersGroupsPage-B8Ka6uRa.js.map → UsersGroupsPage-B7Er0V4l.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-xJmGib8b.js → UsersGroupsPage-BeAv4QfV.js} +2 -2
- package/dist/chunks/{UsersGroupsPage-xJmGib8b.js.map → UsersGroupsPage-BeAv4QfV.js.map} +1 -1
- package/dist/chunks/{UsersPage-CQ38akZ_.js → UsersPage-0M1FLqOe.js} +2 -2
- package/dist/chunks/{UsersPage-CQ38akZ_.js.map → UsersPage-0M1FLqOe.js.map} +1 -1
- package/dist/chunks/{UsersPage-Bd2-vl39.js → UsersPage-ZR9r9vvf.js} +2 -2
- package/dist/chunks/{UsersPage-Bd2-vl39.js.map → UsersPage-ZR9r9vvf.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-DguOx0q0.js → accessRequestsApi-BJH8EE1K.js} +2 -2
- package/dist/chunks/{accessRequestsApi-DguOx0q0.js.map → accessRequestsApi-BJH8EE1K.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-COtWo9kC.js → accessRequestsApi-CBpF5d54.js} +2 -2
- package/dist/chunks/{accessRequestsApi-COtWo9kC.js.map → accessRequestsApi-CBpF5d54.js.map} +1 -1
- package/dist/chunks/{aiApi-CITiWGYX.js → aiApi-CkkWAvNB.js} +2 -2
- package/dist/chunks/{aiApi-CITiWGYX.js.map → aiApi-CkkWAvNB.js.map} +1 -1
- package/dist/chunks/{aiApi-BmZsud6O.js → aiApi-Dl7a2lWz.js} +2 -2
- package/dist/chunks/{aiApi-BmZsud6O.js.map → aiApi-Dl7a2lWz.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-D62lc6z4.js → applicationAnalyticsApi-BwcSE_H1.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-D62lc6z4.js.map → applicationAnalyticsApi-BwcSE_H1.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-BYoEJzSN.js → applicationAnalyticsApi-DKMmDvWk.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-BYoEJzSN.js.map → applicationAnalyticsApi-DKMmDvWk.js.map} +1 -1
- package/dist/chunks/auth-Ca2Rn6on.js +2 -0
- package/dist/chunks/auth-Ca2Rn6on.js.map +1 -0
- package/dist/chunks/auth-ClNTDOqm.js +18 -0
- package/dist/chunks/auth-ClNTDOqm.js.map +1 -0
- package/dist/chunks/auth-DECnMZjF.js +18 -0
- package/dist/chunks/auth-DECnMZjF.js.map +1 -0
- package/dist/chunks/auth-DPvxdqy4.js +18 -0
- package/dist/chunks/auth-DPvxdqy4.js.map +1 -0
- package/dist/chunks/auth-HzvnTaOm.js +2 -0
- package/dist/chunks/auth-HzvnTaOm.js.map +1 -0
- package/dist/chunks/auth-M6aNTKCH.js +2 -0
- package/dist/chunks/auth-M6aNTKCH.js.map +1 -0
- package/dist/chunks/auth-UHnAu6_e.js +2 -0
- package/dist/chunks/auth-UHnAu6_e.js.map +1 -0
- package/dist/chunks/auth-YrujJY7m.js +18 -0
- package/dist/chunks/auth-YrujJY7m.js.map +1 -0
- package/dist/chunks/{groupsApi-3CR-_g5b.js → groupsApi-BzDV3_Jc.js} +2 -2
- package/dist/chunks/{groupsApi-3CR-_g5b.js.map → groupsApi-BzDV3_Jc.js.map} +1 -1
- package/dist/chunks/{groupsApi-BUyBgf_N.js → groupsApi-CQ4vFMdP.js} +2 -2
- package/dist/chunks/{groupsApi-BUyBgf_N.js.map → groupsApi-CQ4vFMdP.js.map} +1 -1
- package/dist/chunks/{index-BIqcvvbh.js → index-BBmMbSZV.js} +9 -8
- package/dist/chunks/index-BBmMbSZV.js.map +1 -0
- package/dist/chunks/{index-_g82N2nb.js → index-BLlESTfA.js} +2 -2
- package/dist/chunks/{index-_g82N2nb.js.map → index-BLlESTfA.js.map} +1 -1
- package/dist/chunks/{index-DEOBhXS_.js → index-BPMjxWVx.js} +2 -2
- package/dist/chunks/{index-DEOBhXS_.js.map → index-BPMjxWVx.js.map} +1 -1
- package/dist/chunks/{index-Czk12A3G.js → index-CEbwdURd.js} +2 -2
- package/dist/chunks/{index-Czk12A3G.js.map → index-CEbwdURd.js.map} +1 -1
- package/dist/chunks/{index-BOKR3bw6.js → index-CUZygY5Q.js} +2 -2
- package/dist/chunks/{index-BOKR3bw6.js.map → index-CUZygY5Q.js.map} +1 -1
- package/dist/chunks/{index-IJR_91Yt.js → index-Ci1SqFiY.js} +2 -2
- package/dist/chunks/{index-IJR_91Yt.js.map → index-Ci1SqFiY.js.map} +1 -1
- package/dist/chunks/{index-Br2wsGE8.js → index-Cib93xtp.js} +2 -2
- package/dist/chunks/{index-Br2wsGE8.js.map → index-Cib93xtp.js.map} +1 -1
- package/dist/chunks/{index-BxHVPJ-j.js → index-CoHIgn5H.js} +2 -2
- package/dist/chunks/{index-BxHVPJ-j.js.map → index-CoHIgn5H.js.map} +1 -1
- package/dist/chunks/{index-DA5VyW0k.js → index-CpY95_ro.js} +2296 -2309
- package/dist/chunks/index-CpY95_ro.js.map +1 -0
- package/dist/chunks/{index-BMsjMCv9.js → index-D-2xSu5W.js} +3 -3
- package/dist/chunks/{index-BMsjMCv9.js.map → index-D-2xSu5W.js.map} +1 -1
- package/dist/chunks/{index-DIQ6Jmmq.js → index-D18t9DhC.js} +4 -4
- package/dist/chunks/{index-DIQ6Jmmq.js.map → index-D18t9DhC.js.map} +1 -1
- package/dist/chunks/index-DK5czlkn.js +48 -0
- package/dist/chunks/index-DK5czlkn.js.map +1 -0
- package/dist/chunks/{index-CxgEV-rT.js → index-DQd324n7.js} +2 -2
- package/dist/chunks/{index-CxgEV-rT.js.map → index-DQd324n7.js.map} +1 -1
- package/dist/chunks/{index-S-X8qFYW.js → index-Dbq-x5H9.js} +2 -2
- package/dist/chunks/{index-S-X8qFYW.js.map → index-Dbq-x5H9.js.map} +1 -1
- package/dist/chunks/{index-CNxx56kE.js → index-Det9dEaQ.js} +2 -2
- package/dist/chunks/{index-CNxx56kE.js.map → index-Det9dEaQ.js.map} +1 -1
- package/dist/chunks/{index-C1w97Ejz.js → index-bgT9XOKZ.js} +2 -2
- package/dist/chunks/{index-C1w97Ejz.js.map → index-bgT9XOKZ.js.map} +1 -1
- package/dist/chunks/index-h7ZrwrQg.js +2 -0
- package/dist/chunks/index-h7ZrwrQg.js.map +1 -0
- package/dist/chunks/{index-Djy4eIbB.js → index-k4USDz2P.js} +2 -2
- package/dist/chunks/{index-Djy4eIbB.js.map → index-k4USDz2P.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-COKA97Ug.js → tenantIconMap-7ihIWxAh.js} +2 -2
- package/dist/chunks/{tenantIconMap-COKA97Ug.js.map → tenantIconMap-7ihIWxAh.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-BuSQUUyZ.js → tenantIconMap-Dk6K-UTE.js} +2 -2
- package/dist/chunks/{tenantIconMap-BuSQUUyZ.js.map → tenantIconMap-Dk6K-UTE.js.map} +1 -1
- package/dist/chunks/{ticketingApi-C6EbupqP.js → ticketingApi-BCMKkzlv.js} +2 -2
- package/dist/chunks/{ticketingApi-C6EbupqP.js.map → ticketingApi-BCMKkzlv.js.map} +1 -1
- package/dist/chunks/{ticketingApi-DbREwHez.js → ticketingApi-Dwn7pl5z.js} +2 -2
- package/dist/chunks/{ticketingApi-DbREwHez.js.map → ticketingApi-Dwn7pl5z.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-vucIb3_w.js → useAccessRequests-Du7CvowE.js} +3 -3
- package/dist/chunks/{useAccessRequests-vucIb3_w.js.map → useAccessRequests-Du7CvowE.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-C0dY6y-4.js → useAccessRequests-gJ7yhWyi.js} +2 -2
- package/dist/chunks/{useAccessRequests-C0dY6y-4.js.map → useAccessRequests-gJ7yhWyi.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-Cj0nkesW.js → useUserAccessRequests-5wWea2Jg.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-Cj0nkesW.js.map → useUserAccessRequests-5wWea2Jg.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-BBcw1Rk9.js → useUserAccessRequests-Bk_v8egy.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-BBcw1Rk9.js.map → useUserAccessRequests-Bk_v8egy.js.map} +1 -1
- package/dist/components/routing/ProtectedRoute.d.ts.map +1 -1
- package/dist/contexts/AuthContext.d.ts.map +1 -1
- package/dist/pages/LoginPage.d.ts.map +1 -1
- package/dist/pages/platform/administration/tenants/TenantDetailPage.d.ts.map +1 -1
- package/dist/pages/platform/support/UserCreateTicketPage.d.ts.map +1 -1
- package/dist/services/api/apiClient.d.ts.map +1 -1
- package/dist/services/support/ticketDraftService.d.ts.map +1 -1
- package/dist/smartstack.cjs +1 -1
- package/dist/smartstack.js +6 -6
- package/dist/utils/permissions.generated.d.ts +288 -0
- package/dist/utils/permissions.generated.d.ts.map +1 -0
- package/dist/utils/uuid.d.ts +6 -0
- package/dist/utils/uuid.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/chunks/UserCreateTicketPage-ChQL1mVY.js.map +0 -1
- package/dist/chunks/UserCreateTicketPage-DkjsHeV7.js.map +0 -1
- package/dist/chunks/auth-B-hELPDB.js +0 -2
- package/dist/chunks/auth-B-hELPDB.js.map +0 -1
- package/dist/chunks/auth-BYaMuq7D.js +0 -16
- package/dist/chunks/auth-BYaMuq7D.js.map +0 -1
- package/dist/chunks/auth-C5zpZ9k7.js +0 -2
- package/dist/chunks/auth-C5zpZ9k7.js.map +0 -1
- package/dist/chunks/auth-CDpRMVv1.js +0 -16
- package/dist/chunks/auth-CDpRMVv1.js.map +0 -1
- package/dist/chunks/auth-CyPkCta2.js +0 -2
- package/dist/chunks/auth-CyPkCta2.js.map +0 -1
- package/dist/chunks/auth-DL47kvnl.js +0 -2
- package/dist/chunks/auth-DL47kvnl.js.map +0 -1
- package/dist/chunks/auth-Diiv90i1.js +0 -16
- package/dist/chunks/auth-Diiv90i1.js.map +0 -1
- package/dist/chunks/auth-rog9MvUr.js +0 -16
- package/dist/chunks/auth-rog9MvUr.js.map +0 -1
- package/dist/chunks/index-BIqcvvbh.js.map +0 -1
- package/dist/chunks/index-DA5VyW0k.js.map +0 -1
- package/dist/chunks/index-Dht6EQW1.js +0 -2
- package/dist/chunks/index-Dht6EQW1.js.map +0 -1
- package/dist/chunks/index-vXiLh35n.js +0 -48
- package/dist/chunks/index-vXiLh35n.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationsPage-BCnL9oPb.js","sources":["../../src/pages/notifications/NotificationsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Bell,\r\n Check,\r\n CheckCheck,\r\n Trash2,\r\n Loader2,\r\n Filter,\r\n Settings,\r\n} from 'lucide-react';\r\nimport {\r\n notificationsApi,\r\n type NotificationDto,\r\n} from '@/services/api/supportApi';\r\nimport { Pagination } from '@/components/ui/DataView';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { getTenantBadgeVariant } from '@/utils/notificationTenant';\r\n\r\nexport function NotificationsPage(): ReactElement | null {\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('common');\r\n const { currentTenant, userTenants, hasMultipleTenants } = useTenant();\r\n const [loading, setLoading] = useState(true);\r\n const [notifications, setNotifications] = useState<NotificationDto[]>([]);\r\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\r\n const [deleting, setDeleting] = useState(false);\r\n const [page, setPage] = useState(1);\r\n const [totalPages, setTotalPages] = useState(1);\r\n const [totalCount, setTotalCount] = useState(0);\r\n const [filterRead, setFilterRead] = useState<boolean | undefined>(undefined);\r\n const [filterTenantId, setFilterTenantId] = useState<string | undefined>(undefined);\r\n\r\n const loadNotifications = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const result = await notificationsApi.getAll(page, 20, filterRead, filterTenantId);\r\n setNotifications(result.items);\r\n setTotalPages(result.totalPages);\r\n setTotalCount(result.totalCount);\r\n } catch (error) {\r\n console.error('Failed to load notifications:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [page, filterRead, filterTenantId]);\r\n\r\n useEffect(() => {\r\n loadNotifications();\r\n }, [loadNotifications]);\r\n\r\n const handleMarkAsRead = async (id: string) => {\r\n try {\r\n await notificationsApi.markAsRead(id);\r\n setNotifications((prev) =>\r\n prev.map((n) => (n.id === id ? { ...n, isRead: true, readAt: new Date().toISOString() } : n))\r\n );\r\n } catch (error) {\r\n console.error('Failed to mark as read:', error);\r\n }\r\n };\r\n\r\n const handleMarkAllAsRead = async () => {\r\n try {\r\n await notificationsApi.markAllAsRead();\r\n setNotifications((prev) => prev.map((n) => ({ ...n, isRead: true, readAt: new Date().toISOString() })));\r\n } catch (error) {\r\n console.error('Failed to mark all as read:', error);\r\n }\r\n };\r\n\r\n const handleDelete = async (id: string) => {\r\n try {\r\n await notificationsApi.delete(id);\r\n setNotifications((prev) => prev.filter((n) => n.id !== id));\r\n setTotalCount((prev) => prev - 1);\r\n } catch (error) {\r\n console.error('Failed to delete notification:', error);\r\n }\r\n };\r\n\r\n const handleDeleteAll = async () => {\r\n try {\r\n setDeleting(true);\r\n await notificationsApi.deleteAll();\r\n setNotifications([]);\r\n setTotalCount(0);\r\n setTotalPages(1);\r\n } catch (error) {\r\n console.error('Failed to delete all notifications:', error);\r\n } finally {\r\n setDeleting(false);\r\n setShowDeleteConfirm(false);\r\n }\r\n };\r\n\r\n const handleNotificationClick = (notification: NotificationDto) => {\r\n if (!notification.isRead) {\r\n handleMarkAsRead(notification.id);\r\n }\r\n if (notification.actionUrl) {\r\n navigate(notification.actionUrl);\r\n }\r\n };\r\n\r\n const getNotificationIcon = (type: string) => {\r\n switch (type) {\r\n case 'TicketCreated':\r\n return '🎫';\r\n case 'TicketAssigned':\r\n return '👤';\r\n case 'StatusChanged':\r\n return '🔄';\r\n case 'CommentAdded':\r\n return '💬';\r\n case 'SlaResponseBreached':\r\n case 'SlaResolutionBreached':\r\n return '⚠️';\r\n case 'SlaWarning':\r\n return '⏰';\r\n case 'TicketEscalated':\r\n return '📈';\r\n case 'SatisfactionRequested':\r\n return '⭐';\r\n default:\r\n return '📌';\r\n }\r\n };\r\n\r\n const formatDate = (dateStr: string) => {\r\n const date = new Date(dateStr);\r\n return date.toLocaleString();\r\n };\r\n\r\n const renderTenantBadge = (notification: NotificationDto) => {\r\n if (!hasMultipleTenants) return null;\r\n\r\n const variant = getTenantBadgeVariant(notification.tenantId, currentTenant?.id ?? null);\r\n\r\n if (variant === 'global') {\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-700\">\r\n System\r\n </span>\r\n );\r\n }\r\n\r\n if (variant === 'current') {\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] border border-[var(--border-color)]\">\r\n {notification.tenantName}\r\n </span>\r\n );\r\n }\r\n\r\n // 'other' tenant - highlighted\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 border border-blue-200 dark:border-blue-700 font-medium\">\r\n {notification.tenantName}\r\n </span>\r\n );\r\n };\r\n\r\n const unreadCount = notifications.filter((n) => !n.isRead).length;\r\n\r\n const getFilterReadValue = () => {\r\n if (filterRead === undefined) return '';\r\n return filterRead ? 'read' : 'unread';\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold flex items-center gap-2\">\r\n <Bell className=\"w-6 h-6\" />\r\n Notifications\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {totalCount} notification{totalCount !== 1 ? 's' : ''}, {unreadCount} unread\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => navigate('/myspace/notification-preferences')}\r\n className=\"btn btn-secondary flex items-center gap-2\"\r\n >\r\n <Settings className=\"w-4 h-4\" />\r\n Preferences\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Filters and Actions */}\r\n <div className=\"flex flex-col md:flex-row gap-4 items-start md:items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n <select\r\n value={getFilterReadValue()}\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n setFilterRead(value === '' ? undefined : value === 'read');\r\n setPage(1);\r\n }}\r\n className=\"input\"\r\n >\r\n <option value=\"\">All Notifications</option>\r\n <option value=\"unread\">Unread Only</option>\r\n <option value=\"read\">Read Only</option>\r\n </select>\r\n\r\n {hasMultipleTenants && (\r\n <select\r\n value={filterTenantId || ''}\r\n onChange={(e) => {\r\n setFilterTenantId(e.target.value || undefined);\r\n setPage(1);\r\n }}\r\n className=\"input\"\r\n >\r\n <option value=\"\">All Workspaces</option>\r\n {userTenants\r\n .filter(t => t.status === 'Active')\r\n .map(tenant => (\r\n <option key={tenant.id} value={tenant.id}>\r\n {tenant.name}\r\n </option>\r\n ))}\r\n </select>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n {unreadCount > 0 && (\r\n <button\r\n onClick={handleMarkAllAsRead}\r\n className=\"btn btn-secondary flex items-center gap-2\"\r\n >\r\n <CheckCheck className=\"w-4 h-4\" />\r\n Mark All Read\r\n </button>\r\n )}\r\n {notifications.length > 0 && (\r\n <button\r\n onClick={() => setShowDeleteConfirm(true)}\r\n className=\"btn btn-secondary flex items-center gap-2 text-red-600\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n Delete All\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Notifications List */}\r\n {loading && (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n )}\r\n {!loading && notifications.length > 0 && (\r\n <div className=\"card divide-y divide-[var(--border-color)]\">\r\n {notifications.map((notification) => (\r\n <button\r\n type=\"button\"\r\n key={notification.id}\r\n onClick={() => handleNotificationClick(notification)}\r\n className={`w-full text-left p-4 cursor-pointer hover:bg-[var(--bg-hover)] transition-colors ${\r\n !notification.isRead ? 'bg-blue-50/50' : ''\r\n }`}\r\n >\r\n <div className=\"flex gap-4\">\r\n <span className=\"text-2xl flex-shrink-0\">\r\n {getNotificationIcon(notification.type)}\r\n </span>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-start justify-between gap-4\">\r\n <div>\r\n <h3 className={`${!notification.isRead ? 'font-semibold' : ''}`}>\r\n {notification.title}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {notification.message}\r\n </p>\r\n </div>\r\n <div className=\"text-right flex-shrink-0\">\r\n <div className=\"text-sm text-[var(--text-secondary)]\">\r\n {formatDate(notification.createdAt)}\r\n </div>\r\n {notification.isRead && notification.readAt && (\r\n <div className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n Read {formatDate(notification.readAt)}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 mt-2\">\r\n <span className=\"text-xs px-2 py-1 bg-[var(--bg-secondary)] rounded\">\r\n {formatNotificationType(notification.type)}\r\n </span>\r\n {renderTenantBadge(notification)}\r\n {notification.relatedEntityType && (\r\n <span className=\"text-xs text-[var(--text-secondary)]\">\r\n {notification.relatedEntityType}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex flex-col gap-2 flex-shrink-0\" onClick={(e) => e.stopPropagation()}>\r\n {!notification.isRead && (\r\n <button\r\n onClick={() => handleMarkAsRead(notification.id)}\r\n className=\"p-2 rounded hover:bg-[var(--bg-secondary)] transition-colors\"\r\n title=\"Mark as read\"\r\n >\r\n <Check className=\"w-4 h-4 text-green-600\" />\r\n </button>\r\n )}\r\n <button\r\n onClick={() => handleDelete(notification.id)}\r\n className=\"p-2 rounded hover:bg-[var(--bg-secondary)] transition-colors\"\r\n title=\"Delete\"\r\n >\r\n <Trash2 className=\"w-4 h-4 text-red-500\" />\r\n </button>\r\n </div>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n {!loading && notifications.length === 0 && (\r\n <div className=\"card p-12 text-center\">\r\n <Bell className=\"w-16 h-16 mx-auto mb-4 opacity-30\" />\r\n <h3 className=\"text-lg font-medium mb-2\">No notifications</h3>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {(() => {\r\n if (filterRead === false) return 'You have no unread notifications';\r\n if (filterRead === true) return 'You have no read notifications';\r\n return \"You're all caught up!\";\r\n })()}\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Pagination */}\r\n {!loading && totalPages > 1 && (\r\n <Pagination\r\n page={page}\r\n totalPages={totalPages}\r\n totalCount={totalCount}\r\n onPageChange={setPage}\r\n />\r\n )}\r\n\r\n {/* Delete All Confirmation */}\r\n <ConfirmModal\r\n isOpen={showDeleteConfirm}\r\n title={t('notifications.deleteAll.title')}\r\n message={t('notifications.deleteAll.message')}\r\n confirmLabel={t('notifications.deleteAll.confirm')}\r\n variant=\"danger\"\r\n loading={deleting}\r\n onConfirm={handleDeleteAll}\r\n onCancel={() => setShowDeleteConfirm(false)}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\nfunction formatNotificationType(type: string): string {\r\n return type\r\n .replace(/([A-Z])/g, ' $1')\r\n .replace(/^./, (str) => str.toUpperCase())\r\n .trim();\r\n}\r\n"],"names":["NotificationsPage","navigate","useNavigate","t","useTranslation","currentTenant","userTenants","hasMultipleTenants","useTenant","loading","setLoading","useState","notifications","setNotifications","showDeleteConfirm","setShowDeleteConfirm","deleting","setDeleting","page","setPage","totalPages","setTotalPages","totalCount","setTotalCount","filterRead","setFilterRead","filterTenantId","setFilterTenantId","loadNotifications","useCallback","result","notificationsApi","error","useEffect","handleMarkAsRead","id","prev","n","handleMarkAllAsRead","handleDelete","handleDeleteAll","handleNotificationClick","notification","getNotificationIcon","type","formatDate","dateStr","renderTenantBadge","variant","getTenantBadgeVariant","jsx","unreadCount","getFilterReadValue","jsxs","Bell","Settings","Filter","value","tenant","CheckCheck","Trash2","Loader2","formatNotificationType","e","Check","Pagination","ConfirmModal","str"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NotificationsPage-BllOlagk.js","sources":["../../src/pages/notifications/NotificationsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Bell,\r\n Check,\r\n CheckCheck,\r\n Trash2,\r\n Loader2,\r\n Filter,\r\n Settings,\r\n} from 'lucide-react';\r\nimport {\r\n notificationsApi,\r\n type NotificationDto,\r\n} from '@/services/api/supportApi';\r\nimport { Pagination } from '@/components/ui/DataView';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { getTenantBadgeVariant } from '@/utils/notificationTenant';\r\n\r\nexport function NotificationsPage(): ReactElement | null {\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('common');\r\n const { currentTenant, userTenants, hasMultipleTenants } = useTenant();\r\n const [loading, setLoading] = useState(true);\r\n const [notifications, setNotifications] = useState<NotificationDto[]>([]);\r\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\r\n const [deleting, setDeleting] = useState(false);\r\n const [page, setPage] = useState(1);\r\n const [totalPages, setTotalPages] = useState(1);\r\n const [totalCount, setTotalCount] = useState(0);\r\n const [filterRead, setFilterRead] = useState<boolean | undefined>(undefined);\r\n const [filterTenantId, setFilterTenantId] = useState<string | undefined>(undefined);\r\n\r\n const loadNotifications = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const result = await notificationsApi.getAll(page, 20, filterRead, filterTenantId);\r\n setNotifications(result.items);\r\n setTotalPages(result.totalPages);\r\n setTotalCount(result.totalCount);\r\n } catch (error) {\r\n console.error('Failed to load notifications:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [page, filterRead, filterTenantId]);\r\n\r\n useEffect(() => {\r\n loadNotifications();\r\n }, [loadNotifications]);\r\n\r\n const handleMarkAsRead = async (id: string) => {\r\n try {\r\n await notificationsApi.markAsRead(id);\r\n setNotifications((prev) =>\r\n prev.map((n) => (n.id === id ? { ...n, isRead: true, readAt: new Date().toISOString() } : n))\r\n );\r\n } catch (error) {\r\n console.error('Failed to mark as read:', error);\r\n }\r\n };\r\n\r\n const handleMarkAllAsRead = async () => {\r\n try {\r\n await notificationsApi.markAllAsRead();\r\n setNotifications((prev) => prev.map((n) => ({ ...n, isRead: true, readAt: new Date().toISOString() })));\r\n } catch (error) {\r\n console.error('Failed to mark all as read:', error);\r\n }\r\n };\r\n\r\n const handleDelete = async (id: string) => {\r\n try {\r\n await notificationsApi.delete(id);\r\n setNotifications((prev) => prev.filter((n) => n.id !== id));\r\n setTotalCount((prev) => prev - 1);\r\n } catch (error) {\r\n console.error('Failed to delete notification:', error);\r\n }\r\n };\r\n\r\n const handleDeleteAll = async () => {\r\n try {\r\n setDeleting(true);\r\n await notificationsApi.deleteAll();\r\n setNotifications([]);\r\n setTotalCount(0);\r\n setTotalPages(1);\r\n } catch (error) {\r\n console.error('Failed to delete all notifications:', error);\r\n } finally {\r\n setDeleting(false);\r\n setShowDeleteConfirm(false);\r\n }\r\n };\r\n\r\n const handleNotificationClick = (notification: NotificationDto) => {\r\n if (!notification.isRead) {\r\n handleMarkAsRead(notification.id);\r\n }\r\n if (notification.actionUrl) {\r\n navigate(notification.actionUrl);\r\n }\r\n };\r\n\r\n const getNotificationIcon = (type: string) => {\r\n switch (type) {\r\n case 'TicketCreated':\r\n return '🎫';\r\n case 'TicketAssigned':\r\n return '👤';\r\n case 'StatusChanged':\r\n return '🔄';\r\n case 'CommentAdded':\r\n return '💬';\r\n case 'SlaResponseBreached':\r\n case 'SlaResolutionBreached':\r\n return '⚠️';\r\n case 'SlaWarning':\r\n return '⏰';\r\n case 'TicketEscalated':\r\n return '📈';\r\n case 'SatisfactionRequested':\r\n return '⭐';\r\n default:\r\n return '📌';\r\n }\r\n };\r\n\r\n const formatDate = (dateStr: string) => {\r\n const date = new Date(dateStr);\r\n return date.toLocaleString();\r\n };\r\n\r\n const renderTenantBadge = (notification: NotificationDto) => {\r\n if (!hasMultipleTenants) return null;\r\n\r\n const variant = getTenantBadgeVariant(notification.tenantId, currentTenant?.id ?? null);\r\n\r\n if (variant === 'global') {\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-700\">\r\n System\r\n </span>\r\n );\r\n }\r\n\r\n if (variant === 'current') {\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] border border-[var(--border-color)]\">\r\n {notification.tenantName}\r\n </span>\r\n );\r\n }\r\n\r\n // 'other' tenant - highlighted\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 border border-blue-200 dark:border-blue-700 font-medium\">\r\n {notification.tenantName}\r\n </span>\r\n );\r\n };\r\n\r\n const unreadCount = notifications.filter((n) => !n.isRead).length;\r\n\r\n const getFilterReadValue = () => {\r\n if (filterRead === undefined) return '';\r\n return filterRead ? 'read' : 'unread';\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold flex items-center gap-2\">\r\n <Bell className=\"w-6 h-6\" />\r\n Notifications\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {totalCount} notification{totalCount !== 1 ? 's' : ''}, {unreadCount} unread\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => navigate('/myspace/notification-preferences')}\r\n className=\"btn btn-secondary flex items-center gap-2\"\r\n >\r\n <Settings className=\"w-4 h-4\" />\r\n Preferences\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Filters and Actions */}\r\n <div className=\"flex flex-col md:flex-row gap-4 items-start md:items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n <select\r\n value={getFilterReadValue()}\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n setFilterRead(value === '' ? undefined : value === 'read');\r\n setPage(1);\r\n }}\r\n className=\"input\"\r\n >\r\n <option value=\"\">All Notifications</option>\r\n <option value=\"unread\">Unread Only</option>\r\n <option value=\"read\">Read Only</option>\r\n </select>\r\n\r\n {hasMultipleTenants && (\r\n <select\r\n value={filterTenantId || ''}\r\n onChange={(e) => {\r\n setFilterTenantId(e.target.value || undefined);\r\n setPage(1);\r\n }}\r\n className=\"input\"\r\n >\r\n <option value=\"\">All Workspaces</option>\r\n {userTenants\r\n .filter(t => t.status === 'Active')\r\n .map(tenant => (\r\n <option key={tenant.id} value={tenant.id}>\r\n {tenant.name}\r\n </option>\r\n ))}\r\n </select>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n {unreadCount > 0 && (\r\n <button\r\n onClick={handleMarkAllAsRead}\r\n className=\"btn btn-secondary flex items-center gap-2\"\r\n >\r\n <CheckCheck className=\"w-4 h-4\" />\r\n Mark All Read\r\n </button>\r\n )}\r\n {notifications.length > 0 && (\r\n <button\r\n onClick={() => setShowDeleteConfirm(true)}\r\n className=\"btn btn-secondary flex items-center gap-2 text-red-600\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n Delete All\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Notifications List */}\r\n {loading && (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n )}\r\n {!loading && notifications.length > 0 && (\r\n <div className=\"card divide-y divide-[var(--border-color)]\">\r\n {notifications.map((notification) => (\r\n <button\r\n type=\"button\"\r\n key={notification.id}\r\n onClick={() => handleNotificationClick(notification)}\r\n className={`w-full text-left p-4 cursor-pointer hover:bg-[var(--bg-hover)] transition-colors ${\r\n !notification.isRead ? 'bg-blue-50/50' : ''\r\n }`}\r\n >\r\n <div className=\"flex gap-4\">\r\n <span className=\"text-2xl flex-shrink-0\">\r\n {getNotificationIcon(notification.type)}\r\n </span>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-start justify-between gap-4\">\r\n <div>\r\n <h3 className={`${!notification.isRead ? 'font-semibold' : ''}`}>\r\n {notification.title}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {notification.message}\r\n </p>\r\n </div>\r\n <div className=\"text-right flex-shrink-0\">\r\n <div className=\"text-sm text-[var(--text-secondary)]\">\r\n {formatDate(notification.createdAt)}\r\n </div>\r\n {notification.isRead && notification.readAt && (\r\n <div className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n Read {formatDate(notification.readAt)}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 mt-2\">\r\n <span className=\"text-xs px-2 py-1 bg-[var(--bg-secondary)] rounded\">\r\n {formatNotificationType(notification.type)}\r\n </span>\r\n {renderTenantBadge(notification)}\r\n {notification.relatedEntityType && (\r\n <span className=\"text-xs text-[var(--text-secondary)]\">\r\n {notification.relatedEntityType}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex flex-col gap-2 flex-shrink-0\" onClick={(e) => e.stopPropagation()}>\r\n {!notification.isRead && (\r\n <button\r\n onClick={() => handleMarkAsRead(notification.id)}\r\n className=\"p-2 rounded hover:bg-[var(--bg-secondary)] transition-colors\"\r\n title=\"Mark as read\"\r\n >\r\n <Check className=\"w-4 h-4 text-green-600\" />\r\n </button>\r\n )}\r\n <button\r\n onClick={() => handleDelete(notification.id)}\r\n className=\"p-2 rounded hover:bg-[var(--bg-secondary)] transition-colors\"\r\n title=\"Delete\"\r\n >\r\n <Trash2 className=\"w-4 h-4 text-red-500\" />\r\n </button>\r\n </div>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n {!loading && notifications.length === 0 && (\r\n <div className=\"card p-12 text-center\">\r\n <Bell className=\"w-16 h-16 mx-auto mb-4 opacity-30\" />\r\n <h3 className=\"text-lg font-medium mb-2\">No notifications</h3>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {(() => {\r\n if (filterRead === false) return 'You have no unread notifications';\r\n if (filterRead === true) return 'You have no read notifications';\r\n return \"You're all caught up!\";\r\n })()}\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Pagination */}\r\n {!loading && totalPages > 1 && (\r\n <Pagination\r\n page={page}\r\n totalPages={totalPages}\r\n totalCount={totalCount}\r\n onPageChange={setPage}\r\n />\r\n )}\r\n\r\n {/* Delete All Confirmation */}\r\n <ConfirmModal\r\n isOpen={showDeleteConfirm}\r\n title={t('notifications.deleteAll.title')}\r\n message={t('notifications.deleteAll.message')}\r\n confirmLabel={t('notifications.deleteAll.confirm')}\r\n variant=\"danger\"\r\n loading={deleting}\r\n onConfirm={handleDeleteAll}\r\n onCancel={() => setShowDeleteConfirm(false)}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\nfunction formatNotificationType(type: string): string {\r\n return type\r\n .replace(/([A-Z])/g, ' $1')\r\n .replace(/^./, (str) => str.toUpperCase())\r\n .trim();\r\n}\r\n"],"names":["NotificationsPage","navigate","useNavigate","t","useTranslation","currentTenant","userTenants","hasMultipleTenants","useTenant","loading","setLoading","useState","notifications","setNotifications","showDeleteConfirm","setShowDeleteConfirm","deleting","setDeleting","page","setPage","totalPages","setTotalPages","totalCount","setTotalCount","filterRead","setFilterRead","filterTenantId","setFilterTenantId","loadNotifications","useCallback","result","notificationsApi","error","useEffect","handleMarkAsRead","id","prev","n","handleMarkAllAsRead","handleDelete","handleDeleteAll","handleNotificationClick","notification","getNotificationIcon","type","formatDate","dateStr","renderTenantBadge","variant","getTenantBadgeVariant","jsx","unreadCount","getFilterReadValue","jsxs","Bell","Settings","Filter","value","tenant","CheckCheck","Trash2","Loader2","formatNotificationType","e","Check","Pagination","ConfirmModal","str"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { useState as s, useCallback as $, useEffect as W } from "react";
|
|
|
3
3
|
import { useNavigate as q } from "react-router-dom";
|
|
4
4
|
import { useTranslation as Z } from "react-i18next";
|
|
5
5
|
import { Bell as S, Settings as z, Filter as G, CheckCheck as H, Trash2 as D, Loader2 as J, Check as K } from "lucide-react";
|
|
6
|
-
import { a as Q, n as d, P as X, g as _ } from "./index-
|
|
6
|
+
import { a as Q, n as d, P as X, g as _ } from "./index-CpY95_ro.js";
|
|
7
7
|
import { C as ee } from "./ConfirmModal-BEfzLWOz.js";
|
|
8
8
|
function de() {
|
|
9
9
|
const m = q(), { t: n } = Z("common"), { currentTenant: F, userTenants: P, hasMultipleTenants: N } = Q(), [u, b] = s(!0), [c, i] = s([]), [j, h] = s(!1), [I, y] = s(!1), [p, g] = s(1), [k, C] = s(1), [f, x] = s(0), [l, M] = s(void 0), [v, B] = s(void 0), w = $(async () => {
|
|
@@ -252,4 +252,4 @@ function te(m) {
|
|
|
252
252
|
export {
|
|
253
253
|
de as NotificationsPage
|
|
254
254
|
};
|
|
255
|
-
//# sourceMappingURL=NotificationsPage-
|
|
255
|
+
//# sourceMappingURL=NotificationsPage-D1T_ozHl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationsPage-BxCiGzHk.js","sources":["../../src/pages/notifications/NotificationsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Bell,\r\n Check,\r\n CheckCheck,\r\n Trash2,\r\n Loader2,\r\n Filter,\r\n Settings,\r\n} from 'lucide-react';\r\nimport {\r\n notificationsApi,\r\n type NotificationDto,\r\n} from '@/services/api/supportApi';\r\nimport { Pagination } from '@/components/ui/DataView';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { getTenantBadgeVariant } from '@/utils/notificationTenant';\r\n\r\nexport function NotificationsPage(): ReactElement | null {\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('common');\r\n const { currentTenant, userTenants, hasMultipleTenants } = useTenant();\r\n const [loading, setLoading] = useState(true);\r\n const [notifications, setNotifications] = useState<NotificationDto[]>([]);\r\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\r\n const [deleting, setDeleting] = useState(false);\r\n const [page, setPage] = useState(1);\r\n const [totalPages, setTotalPages] = useState(1);\r\n const [totalCount, setTotalCount] = useState(0);\r\n const [filterRead, setFilterRead] = useState<boolean | undefined>(undefined);\r\n const [filterTenantId, setFilterTenantId] = useState<string | undefined>(undefined);\r\n\r\n const loadNotifications = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const result = await notificationsApi.getAll(page, 20, filterRead, filterTenantId);\r\n setNotifications(result.items);\r\n setTotalPages(result.totalPages);\r\n setTotalCount(result.totalCount);\r\n } catch (error) {\r\n console.error('Failed to load notifications:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [page, filterRead, filterTenantId]);\r\n\r\n useEffect(() => {\r\n loadNotifications();\r\n }, [loadNotifications]);\r\n\r\n const handleMarkAsRead = async (id: string) => {\r\n try {\r\n await notificationsApi.markAsRead(id);\r\n setNotifications((prev) =>\r\n prev.map((n) => (n.id === id ? { ...n, isRead: true, readAt: new Date().toISOString() } : n))\r\n );\r\n } catch (error) {\r\n console.error('Failed to mark as read:', error);\r\n }\r\n };\r\n\r\n const handleMarkAllAsRead = async () => {\r\n try {\r\n await notificationsApi.markAllAsRead();\r\n setNotifications((prev) => prev.map((n) => ({ ...n, isRead: true, readAt: new Date().toISOString() })));\r\n } catch (error) {\r\n console.error('Failed to mark all as read:', error);\r\n }\r\n };\r\n\r\n const handleDelete = async (id: string) => {\r\n try {\r\n await notificationsApi.delete(id);\r\n setNotifications((prev) => prev.filter((n) => n.id !== id));\r\n setTotalCount((prev) => prev - 1);\r\n } catch (error) {\r\n console.error('Failed to delete notification:', error);\r\n }\r\n };\r\n\r\n const handleDeleteAll = async () => {\r\n try {\r\n setDeleting(true);\r\n await notificationsApi.deleteAll();\r\n setNotifications([]);\r\n setTotalCount(0);\r\n setTotalPages(1);\r\n } catch (error) {\r\n console.error('Failed to delete all notifications:', error);\r\n } finally {\r\n setDeleting(false);\r\n setShowDeleteConfirm(false);\r\n }\r\n };\r\n\r\n const handleNotificationClick = (notification: NotificationDto) => {\r\n if (!notification.isRead) {\r\n handleMarkAsRead(notification.id);\r\n }\r\n if (notification.actionUrl) {\r\n navigate(notification.actionUrl);\r\n }\r\n };\r\n\r\n const getNotificationIcon = (type: string) => {\r\n switch (type) {\r\n case 'TicketCreated':\r\n return '🎫';\r\n case 'TicketAssigned':\r\n return '👤';\r\n case 'StatusChanged':\r\n return '🔄';\r\n case 'CommentAdded':\r\n return '💬';\r\n case 'SlaResponseBreached':\r\n case 'SlaResolutionBreached':\r\n return '⚠️';\r\n case 'SlaWarning':\r\n return '⏰';\r\n case 'TicketEscalated':\r\n return '📈';\r\n case 'SatisfactionRequested':\r\n return '⭐';\r\n default:\r\n return '📌';\r\n }\r\n };\r\n\r\n const formatDate = (dateStr: string) => {\r\n const date = new Date(dateStr);\r\n return date.toLocaleString();\r\n };\r\n\r\n const renderTenantBadge = (notification: NotificationDto) => {\r\n if (!hasMultipleTenants) return null;\r\n\r\n const variant = getTenantBadgeVariant(notification.tenantId, currentTenant?.id ?? null);\r\n\r\n if (variant === 'global') {\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-700\">\r\n System\r\n </span>\r\n );\r\n }\r\n\r\n if (variant === 'current') {\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] border border-[var(--border-color)]\">\r\n {notification.tenantName}\r\n </span>\r\n );\r\n }\r\n\r\n // 'other' tenant - highlighted\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 border border-blue-200 dark:border-blue-700 font-medium\">\r\n {notification.tenantName}\r\n </span>\r\n );\r\n };\r\n\r\n const unreadCount = notifications.filter((n) => !n.isRead).length;\r\n\r\n const getFilterReadValue = () => {\r\n if (filterRead === undefined) return '';\r\n return filterRead ? 'read' : 'unread';\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold flex items-center gap-2\">\r\n <Bell className=\"w-6 h-6\" />\r\n Notifications\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {totalCount} notification{totalCount !== 1 ? 's' : ''}, {unreadCount} unread\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => navigate('/myspace/notification-preferences')}\r\n className=\"btn btn-secondary flex items-center gap-2\"\r\n >\r\n <Settings className=\"w-4 h-4\" />\r\n Preferences\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Filters and Actions */}\r\n <div className=\"flex flex-col md:flex-row gap-4 items-start md:items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n <select\r\n value={getFilterReadValue()}\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n setFilterRead(value === '' ? undefined : value === 'read');\r\n setPage(1);\r\n }}\r\n className=\"input\"\r\n >\r\n <option value=\"\">All Notifications</option>\r\n <option value=\"unread\">Unread Only</option>\r\n <option value=\"read\">Read Only</option>\r\n </select>\r\n\r\n {hasMultipleTenants && (\r\n <select\r\n value={filterTenantId || ''}\r\n onChange={(e) => {\r\n setFilterTenantId(e.target.value || undefined);\r\n setPage(1);\r\n }}\r\n className=\"input\"\r\n >\r\n <option value=\"\">All Workspaces</option>\r\n {userTenants\r\n .filter(t => t.status === 'Active')\r\n .map(tenant => (\r\n <option key={tenant.id} value={tenant.id}>\r\n {tenant.name}\r\n </option>\r\n ))}\r\n </select>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n {unreadCount > 0 && (\r\n <button\r\n onClick={handleMarkAllAsRead}\r\n className=\"btn btn-secondary flex items-center gap-2\"\r\n >\r\n <CheckCheck className=\"w-4 h-4\" />\r\n Mark All Read\r\n </button>\r\n )}\r\n {notifications.length > 0 && (\r\n <button\r\n onClick={() => setShowDeleteConfirm(true)}\r\n className=\"btn btn-secondary flex items-center gap-2 text-red-600\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n Delete All\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Notifications List */}\r\n {loading && (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n )}\r\n {!loading && notifications.length > 0 && (\r\n <div className=\"card divide-y divide-[var(--border-color)]\">\r\n {notifications.map((notification) => (\r\n <button\r\n type=\"button\"\r\n key={notification.id}\r\n onClick={() => handleNotificationClick(notification)}\r\n className={`w-full text-left p-4 cursor-pointer hover:bg-[var(--bg-hover)] transition-colors ${\r\n !notification.isRead ? 'bg-blue-50/50' : ''\r\n }`}\r\n >\r\n <div className=\"flex gap-4\">\r\n <span className=\"text-2xl flex-shrink-0\">\r\n {getNotificationIcon(notification.type)}\r\n </span>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-start justify-between gap-4\">\r\n <div>\r\n <h3 className={`${!notification.isRead ? 'font-semibold' : ''}`}>\r\n {notification.title}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {notification.message}\r\n </p>\r\n </div>\r\n <div className=\"text-right flex-shrink-0\">\r\n <div className=\"text-sm text-[var(--text-secondary)]\">\r\n {formatDate(notification.createdAt)}\r\n </div>\r\n {notification.isRead && notification.readAt && (\r\n <div className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n Read {formatDate(notification.readAt)}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 mt-2\">\r\n <span className=\"text-xs px-2 py-1 bg-[var(--bg-secondary)] rounded\">\r\n {formatNotificationType(notification.type)}\r\n </span>\r\n {renderTenantBadge(notification)}\r\n {notification.relatedEntityType && (\r\n <span className=\"text-xs text-[var(--text-secondary)]\">\r\n {notification.relatedEntityType}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex flex-col gap-2 flex-shrink-0\" onClick={(e) => e.stopPropagation()}>\r\n {!notification.isRead && (\r\n <button\r\n onClick={() => handleMarkAsRead(notification.id)}\r\n className=\"p-2 rounded hover:bg-[var(--bg-secondary)] transition-colors\"\r\n title=\"Mark as read\"\r\n >\r\n <Check className=\"w-4 h-4 text-green-600\" />\r\n </button>\r\n )}\r\n <button\r\n onClick={() => handleDelete(notification.id)}\r\n className=\"p-2 rounded hover:bg-[var(--bg-secondary)] transition-colors\"\r\n title=\"Delete\"\r\n >\r\n <Trash2 className=\"w-4 h-4 text-red-500\" />\r\n </button>\r\n </div>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n {!loading && notifications.length === 0 && (\r\n <div className=\"card p-12 text-center\">\r\n <Bell className=\"w-16 h-16 mx-auto mb-4 opacity-30\" />\r\n <h3 className=\"text-lg font-medium mb-2\">No notifications</h3>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {(() => {\r\n if (filterRead === false) return 'You have no unread notifications';\r\n if (filterRead === true) return 'You have no read notifications';\r\n return \"You're all caught up!\";\r\n })()}\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Pagination */}\r\n {!loading && totalPages > 1 && (\r\n <Pagination\r\n page={page}\r\n totalPages={totalPages}\r\n totalCount={totalCount}\r\n onPageChange={setPage}\r\n />\r\n )}\r\n\r\n {/* Delete All Confirmation */}\r\n <ConfirmModal\r\n isOpen={showDeleteConfirm}\r\n title={t('notifications.deleteAll.title')}\r\n message={t('notifications.deleteAll.message')}\r\n confirmLabel={t('notifications.deleteAll.confirm')}\r\n variant=\"danger\"\r\n loading={deleting}\r\n onConfirm={handleDeleteAll}\r\n onCancel={() => setShowDeleteConfirm(false)}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\nfunction formatNotificationType(type: string): string {\r\n return type\r\n .replace(/([A-Z])/g, ' $1')\r\n .replace(/^./, (str) => str.toUpperCase())\r\n .trim();\r\n}\r\n"],"names":["NotificationsPage","navigate","useNavigate","t","useTranslation","currentTenant","userTenants","hasMultipleTenants","useTenant","loading","setLoading","useState","notifications","setNotifications","showDeleteConfirm","setShowDeleteConfirm","deleting","setDeleting","page","setPage","totalPages","setTotalPages","totalCount","setTotalCount","filterRead","setFilterRead","filterTenantId","setFilterTenantId","loadNotifications","useCallback","result","notificationsApi","error","useEffect","handleMarkAsRead","id","prev","n","handleMarkAllAsRead","handleDelete","handleDeleteAll","handleNotificationClick","notification","getNotificationIcon","type","formatDate","dateStr","renderTenantBadge","variant","getTenantBadgeVariant","jsx","unreadCount","jsxs","Bell","Settings","Filter","value","tenant","CheckCheck","Trash2","Loader2","formatNotificationType","e","Check","Pagination","ConfirmModal","str"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NotificationsPage-D1T_ozHl.js","sources":["../../src/pages/notifications/NotificationsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Bell,\r\n Check,\r\n CheckCheck,\r\n Trash2,\r\n Loader2,\r\n Filter,\r\n Settings,\r\n} from 'lucide-react';\r\nimport {\r\n notificationsApi,\r\n type NotificationDto,\r\n} from '@/services/api/supportApi';\r\nimport { Pagination } from '@/components/ui/DataView';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { getTenantBadgeVariant } from '@/utils/notificationTenant';\r\n\r\nexport function NotificationsPage(): ReactElement | null {\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('common');\r\n const { currentTenant, userTenants, hasMultipleTenants } = useTenant();\r\n const [loading, setLoading] = useState(true);\r\n const [notifications, setNotifications] = useState<NotificationDto[]>([]);\r\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\r\n const [deleting, setDeleting] = useState(false);\r\n const [page, setPage] = useState(1);\r\n const [totalPages, setTotalPages] = useState(1);\r\n const [totalCount, setTotalCount] = useState(0);\r\n const [filterRead, setFilterRead] = useState<boolean | undefined>(undefined);\r\n const [filterTenantId, setFilterTenantId] = useState<string | undefined>(undefined);\r\n\r\n const loadNotifications = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const result = await notificationsApi.getAll(page, 20, filterRead, filterTenantId);\r\n setNotifications(result.items);\r\n setTotalPages(result.totalPages);\r\n setTotalCount(result.totalCount);\r\n } catch (error) {\r\n console.error('Failed to load notifications:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [page, filterRead, filterTenantId]);\r\n\r\n useEffect(() => {\r\n loadNotifications();\r\n }, [loadNotifications]);\r\n\r\n const handleMarkAsRead = async (id: string) => {\r\n try {\r\n await notificationsApi.markAsRead(id);\r\n setNotifications((prev) =>\r\n prev.map((n) => (n.id === id ? { ...n, isRead: true, readAt: new Date().toISOString() } : n))\r\n );\r\n } catch (error) {\r\n console.error('Failed to mark as read:', error);\r\n }\r\n };\r\n\r\n const handleMarkAllAsRead = async () => {\r\n try {\r\n await notificationsApi.markAllAsRead();\r\n setNotifications((prev) => prev.map((n) => ({ ...n, isRead: true, readAt: new Date().toISOString() })));\r\n } catch (error) {\r\n console.error('Failed to mark all as read:', error);\r\n }\r\n };\r\n\r\n const handleDelete = async (id: string) => {\r\n try {\r\n await notificationsApi.delete(id);\r\n setNotifications((prev) => prev.filter((n) => n.id !== id));\r\n setTotalCount((prev) => prev - 1);\r\n } catch (error) {\r\n console.error('Failed to delete notification:', error);\r\n }\r\n };\r\n\r\n const handleDeleteAll = async () => {\r\n try {\r\n setDeleting(true);\r\n await notificationsApi.deleteAll();\r\n setNotifications([]);\r\n setTotalCount(0);\r\n setTotalPages(1);\r\n } catch (error) {\r\n console.error('Failed to delete all notifications:', error);\r\n } finally {\r\n setDeleting(false);\r\n setShowDeleteConfirm(false);\r\n }\r\n };\r\n\r\n const handleNotificationClick = (notification: NotificationDto) => {\r\n if (!notification.isRead) {\r\n handleMarkAsRead(notification.id);\r\n }\r\n if (notification.actionUrl) {\r\n navigate(notification.actionUrl);\r\n }\r\n };\r\n\r\n const getNotificationIcon = (type: string) => {\r\n switch (type) {\r\n case 'TicketCreated':\r\n return '🎫';\r\n case 'TicketAssigned':\r\n return '👤';\r\n case 'StatusChanged':\r\n return '🔄';\r\n case 'CommentAdded':\r\n return '💬';\r\n case 'SlaResponseBreached':\r\n case 'SlaResolutionBreached':\r\n return '⚠️';\r\n case 'SlaWarning':\r\n return '⏰';\r\n case 'TicketEscalated':\r\n return '📈';\r\n case 'SatisfactionRequested':\r\n return '⭐';\r\n default:\r\n return '📌';\r\n }\r\n };\r\n\r\n const formatDate = (dateStr: string) => {\r\n const date = new Date(dateStr);\r\n return date.toLocaleString();\r\n };\r\n\r\n const renderTenantBadge = (notification: NotificationDto) => {\r\n if (!hasMultipleTenants) return null;\r\n\r\n const variant = getTenantBadgeVariant(notification.tenantId, currentTenant?.id ?? null);\r\n\r\n if (variant === 'global') {\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-700\">\r\n System\r\n </span>\r\n );\r\n }\r\n\r\n if (variant === 'current') {\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] border border-[var(--border-color)]\">\r\n {notification.tenantName}\r\n </span>\r\n );\r\n }\r\n\r\n // 'other' tenant - highlighted\r\n return (\r\n <span className=\"text-xs px-2 py-1 rounded bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 border border-blue-200 dark:border-blue-700 font-medium\">\r\n {notification.tenantName}\r\n </span>\r\n );\r\n };\r\n\r\n const unreadCount = notifications.filter((n) => !n.isRead).length;\r\n\r\n const getFilterReadValue = () => {\r\n if (filterRead === undefined) return '';\r\n return filterRead ? 'read' : 'unread';\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold flex items-center gap-2\">\r\n <Bell className=\"w-6 h-6\" />\r\n Notifications\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {totalCount} notification{totalCount !== 1 ? 's' : ''}, {unreadCount} unread\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => navigate('/myspace/notification-preferences')}\r\n className=\"btn btn-secondary flex items-center gap-2\"\r\n >\r\n <Settings className=\"w-4 h-4\" />\r\n Preferences\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Filters and Actions */}\r\n <div className=\"flex flex-col md:flex-row gap-4 items-start md:items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n <select\r\n value={getFilterReadValue()}\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n setFilterRead(value === '' ? undefined : value === 'read');\r\n setPage(1);\r\n }}\r\n className=\"input\"\r\n >\r\n <option value=\"\">All Notifications</option>\r\n <option value=\"unread\">Unread Only</option>\r\n <option value=\"read\">Read Only</option>\r\n </select>\r\n\r\n {hasMultipleTenants && (\r\n <select\r\n value={filterTenantId || ''}\r\n onChange={(e) => {\r\n setFilterTenantId(e.target.value || undefined);\r\n setPage(1);\r\n }}\r\n className=\"input\"\r\n >\r\n <option value=\"\">All Workspaces</option>\r\n {userTenants\r\n .filter(t => t.status === 'Active')\r\n .map(tenant => (\r\n <option key={tenant.id} value={tenant.id}>\r\n {tenant.name}\r\n </option>\r\n ))}\r\n </select>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n {unreadCount > 0 && (\r\n <button\r\n onClick={handleMarkAllAsRead}\r\n className=\"btn btn-secondary flex items-center gap-2\"\r\n >\r\n <CheckCheck className=\"w-4 h-4\" />\r\n Mark All Read\r\n </button>\r\n )}\r\n {notifications.length > 0 && (\r\n <button\r\n onClick={() => setShowDeleteConfirm(true)}\r\n className=\"btn btn-secondary flex items-center gap-2 text-red-600\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n Delete All\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Notifications List */}\r\n {loading && (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n )}\r\n {!loading && notifications.length > 0 && (\r\n <div className=\"card divide-y divide-[var(--border-color)]\">\r\n {notifications.map((notification) => (\r\n <button\r\n type=\"button\"\r\n key={notification.id}\r\n onClick={() => handleNotificationClick(notification)}\r\n className={`w-full text-left p-4 cursor-pointer hover:bg-[var(--bg-hover)] transition-colors ${\r\n !notification.isRead ? 'bg-blue-50/50' : ''\r\n }`}\r\n >\r\n <div className=\"flex gap-4\">\r\n <span className=\"text-2xl flex-shrink-0\">\r\n {getNotificationIcon(notification.type)}\r\n </span>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-start justify-between gap-4\">\r\n <div>\r\n <h3 className={`${!notification.isRead ? 'font-semibold' : ''}`}>\r\n {notification.title}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {notification.message}\r\n </p>\r\n </div>\r\n <div className=\"text-right flex-shrink-0\">\r\n <div className=\"text-sm text-[var(--text-secondary)]\">\r\n {formatDate(notification.createdAt)}\r\n </div>\r\n {notification.isRead && notification.readAt && (\r\n <div className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n Read {formatDate(notification.readAt)}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 mt-2\">\r\n <span className=\"text-xs px-2 py-1 bg-[var(--bg-secondary)] rounded\">\r\n {formatNotificationType(notification.type)}\r\n </span>\r\n {renderTenantBadge(notification)}\r\n {notification.relatedEntityType && (\r\n <span className=\"text-xs text-[var(--text-secondary)]\">\r\n {notification.relatedEntityType}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex flex-col gap-2 flex-shrink-0\" onClick={(e) => e.stopPropagation()}>\r\n {!notification.isRead && (\r\n <button\r\n onClick={() => handleMarkAsRead(notification.id)}\r\n className=\"p-2 rounded hover:bg-[var(--bg-secondary)] transition-colors\"\r\n title=\"Mark as read\"\r\n >\r\n <Check className=\"w-4 h-4 text-green-600\" />\r\n </button>\r\n )}\r\n <button\r\n onClick={() => handleDelete(notification.id)}\r\n className=\"p-2 rounded hover:bg-[var(--bg-secondary)] transition-colors\"\r\n title=\"Delete\"\r\n >\r\n <Trash2 className=\"w-4 h-4 text-red-500\" />\r\n </button>\r\n </div>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n {!loading && notifications.length === 0 && (\r\n <div className=\"card p-12 text-center\">\r\n <Bell className=\"w-16 h-16 mx-auto mb-4 opacity-30\" />\r\n <h3 className=\"text-lg font-medium mb-2\">No notifications</h3>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {(() => {\r\n if (filterRead === false) return 'You have no unread notifications';\r\n if (filterRead === true) return 'You have no read notifications';\r\n return \"You're all caught up!\";\r\n })()}\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Pagination */}\r\n {!loading && totalPages > 1 && (\r\n <Pagination\r\n page={page}\r\n totalPages={totalPages}\r\n totalCount={totalCount}\r\n onPageChange={setPage}\r\n />\r\n )}\r\n\r\n {/* Delete All Confirmation */}\r\n <ConfirmModal\r\n isOpen={showDeleteConfirm}\r\n title={t('notifications.deleteAll.title')}\r\n message={t('notifications.deleteAll.message')}\r\n confirmLabel={t('notifications.deleteAll.confirm')}\r\n variant=\"danger\"\r\n loading={deleting}\r\n onConfirm={handleDeleteAll}\r\n onCancel={() => setShowDeleteConfirm(false)}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\nfunction formatNotificationType(type: string): string {\r\n return type\r\n .replace(/([A-Z])/g, ' $1')\r\n .replace(/^./, (str) => str.toUpperCase())\r\n .trim();\r\n}\r\n"],"names":["NotificationsPage","navigate","useNavigate","t","useTranslation","currentTenant","userTenants","hasMultipleTenants","useTenant","loading","setLoading","useState","notifications","setNotifications","showDeleteConfirm","setShowDeleteConfirm","deleting","setDeleting","page","setPage","totalPages","setTotalPages","totalCount","setTotalCount","filterRead","setFilterRead","filterTenantId","setFilterTenantId","loadNotifications","useCallback","result","notificationsApi","error","useEffect","handleMarkAsRead","id","prev","n","handleMarkAllAsRead","handleDelete","handleDeleteAll","handleNotificationClick","notification","getNotificationIcon","type","formatDate","dateStr","renderTenantBadge","variant","getTenantBadgeVariant","jsx","unreadCount","jsxs","Bell","Settings","Filter","value","tenant","CheckCheck","Trash2","Loader2","formatNotificationType","e","Check","Pagination","ConfirmModal","str"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { useState as c, useEffect as k } from "react";
|
|
|
3
3
|
import { useNavigate as D } from "react-router-dom";
|
|
4
4
|
import { useTranslation as F } from "react-i18next";
|
|
5
5
|
import { CheckCircle as w, Loader2 as C, Sparkles as S, Globe as j, Palette as K, ArrowLeft as M, ArrowRight as z } from "lucide-react";
|
|
6
|
-
import { h as G, i as L } from "./index-
|
|
6
|
+
import { h as G, i as L } from "./index-CpY95_ro.js";
|
|
7
7
|
const I = [
|
|
8
8
|
{ code: "fr", name: "Francais", flag: "🇫🇷" },
|
|
9
9
|
{ code: "en", name: "English", flag: "🇬🇧" },
|
|
@@ -208,4 +208,4 @@ function V() {
|
|
|
208
208
|
export {
|
|
209
209
|
V as OnboardingWizardPage
|
|
210
210
|
};
|
|
211
|
-
//# sourceMappingURL=OnboardingWizardPage-
|
|
211
|
+
//# sourceMappingURL=OnboardingWizardPage-CioLaCYz.js.map
|
package/dist/chunks/{OnboardingWizardPage-CV_cxq7k.js.map → OnboardingWizardPage-CioLaCYz.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OnboardingWizardPage-CV_cxq7k.js","sources":["../../src/pages/auth/OnboardingWizardPage.tsx"],"sourcesContent":["import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, CheckCircle, Globe, Palette, Sparkles, ArrowRight, ArrowLeft } from 'lucide-react';\r\nimport { api } from '@/services/api/apiClient';\r\nimport { changeLanguage } from '@/i18n/config';\r\n\r\ntype Step = 'language' | 'theme' | 'complete';\r\n\r\ninterface LanguageOption {\r\n code: string;\r\n name: string;\r\n flag: string;\r\n}\r\n\r\ninterface ThemeOption {\r\n value: string;\r\n labelKey: string;\r\n icon: string;\r\n}\r\n\r\nconst languages: LanguageOption[] = [\r\n { code: 'fr', name: 'Francais', flag: '🇫🇷' },\r\n { code: 'en', name: 'English', flag: '🇬🇧' },\r\n { code: 'de', name: 'Deutsch', flag: '🇩🇪' },\r\n { code: 'it', name: 'Italiano', flag: '🇮🇹' },\r\n];\r\n\r\nconst themes: ThemeOption[] = [\r\n { value: 'light', labelKey: 'themeLight', icon: '☀️' },\r\n { value: 'dark', labelKey: 'themeDark', icon: '🌙' },\r\n { value: 'system', labelKey: 'themeSystem', icon: '💻' },\r\n];\r\n\r\nconst accentColors = [\r\n { key: 'indigo', color: '#6366f1', name: 'Indigo' },\r\n { key: 'blue', color: '#3b82f6', name: 'Blue' },\r\n { key: 'emerald', color: '#10b981', name: 'Emerald' },\r\n { key: 'amber', color: '#f59e0b', name: 'Amber' },\r\n { key: 'rose', color: '#f43f5e', name: 'Rose' },\r\n { key: 'purple', color: '#a855f7', name: 'Purple' },\r\n];\r\n\r\nexport function OnboardingWizardPage(): ReactElement {\r\n const { t, i18n } = useTranslation('auth');\r\n const navigate = useNavigate();\r\n\r\n const [currentStep, setCurrentStep] = useState<Step>('language');\r\n const [selectedLanguage, setSelectedLanguage] = useState(i18n.language?.substring(0, 2) || 'fr');\r\n const [selectedTheme, setSelectedTheme] = useState('dark');\r\n const [selectedAccentColor, setSelectedAccentColor] = useState('indigo');\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState(false);\r\n\r\n // Check onboarding status on load\r\n useEffect(() => {\r\n const checkOnboardingStatus = async () => {\r\n try {\r\n const response = await api.get<{ hasCompletedOnboarding: boolean }>('/api/onboarding/status');\r\n if (response.hasCompletedOnboarding) {\r\n // Already completed, redirect to home\r\n navigate('/myspace', { replace: true });\r\n }\r\n } catch {\r\n // If we can't check status, allow proceeding\r\n }\r\n };\r\n\r\n checkOnboardingStatus();\r\n }, [navigate]);\r\n\r\n // Update language immediately when selected (lazy loads translations if needed)\r\n useEffect(() => {\r\n if (selectedLanguage && selectedLanguage !== i18n.language?.substring(0, 2)) {\r\n changeLanguage(selectedLanguage);\r\n }\r\n }, [selectedLanguage, i18n]);\r\n\r\n const steps: { key: Step; labelKey: string; icon: React.ReactNode }[] = [\r\n { key: 'language', labelKey: 'stepLanguage', icon: <Globe className=\"w-5 h-5\" /> },\r\n { key: 'theme', labelKey: 'stepTheme', icon: <Palette className=\"w-5 h-5\" /> },\r\n { key: 'complete', labelKey: 'stepComplete', icon: <Sparkles className=\"w-5 h-5\" /> },\r\n ];\r\n\r\n const currentStepIndex = steps.findIndex((s) => s.key === currentStep);\r\n\r\n const handleNext = () => {\r\n const nextIndex = currentStepIndex + 1;\r\n if (nextIndex < steps.length) {\r\n setCurrentStep(steps[nextIndex].key);\r\n }\r\n };\r\n\r\n const handleBack = () => {\r\n const prevIndex = currentStepIndex - 1;\r\n if (prevIndex >= 0) {\r\n setCurrentStep(steps[prevIndex].key);\r\n }\r\n };\r\n\r\n const handleComplete = async () => {\r\n setIsSubmitting(true);\r\n setError(null);\r\n\r\n try {\r\n await api.post('/api/onboarding/complete', {\r\n language: selectedLanguage,\r\n theme: selectedTheme,\r\n accentColorKey: selectedAccentColor,\r\n });\r\n\r\n // Save preferences locally\r\n localStorage.setItem('i18nextLng', selectedLanguage);\r\n localStorage.setItem(\r\n 'smartstack-theme-config',\r\n JSON.stringify({\r\n mode: selectedTheme,\r\n accentColorKey: selectedAccentColor,\r\n borderRadius: {},\r\n itemPaletteKey: 'neutral',\r\n })\r\n );\r\n\r\n setSuccess(true);\r\n\r\n // Redirect after success animation\r\n setTimeout(() => {\r\n window.location.href = '/myspace';\r\n }, 2000);\r\n } catch (err) {\r\n console.error('Onboarding error:', err);\r\n setError(t('onboarding.errorMessage'));\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n };\r\n\r\n if (success) {\r\n return (\r\n <div className=\"min-h-screen flex items-center justify-center bg-[var(--bg-primary)]\">\r\n <div className=\"max-w-md w-full mx-4\">\r\n <div className=\"bg-[var(--bg-secondary)] rounded-2xl p-8 shadow-lg border border-[var(--border-color)]\">\r\n <div className=\"text-center\">\r\n <div className=\"w-20 h-20 mx-auto bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center mb-6\">\r\n <CheckCircle className=\"w-12 h-12 text-green-600 dark:text-green-400\" />\r\n </div>\r\n <h2 className=\"text-2xl font-bold mb-3\">{t('onboarding.successTitle')}</h2>\r\n <p className=\"text-[var(--text-secondary)]\">{t('onboarding.successMessage')}</p>\r\n <div className=\"mt-6\">\r\n <Loader2 className=\"w-6 h-6 mx-auto text-[var(--color-accent-500)] animate-spin\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"min-h-screen flex items-center justify-center bg-[var(--bg-primary)] p-4\">\r\n <div className=\"max-w-lg w-full\">\r\n {/* Header */}\r\n <div className=\"text-center mb-8\">\r\n <div className=\"flex items-center justify-center gap-2 mb-4\">\r\n <div className=\"w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center\">\r\n <span className=\"text-white text-xl font-bold\">S</span>\r\n </div>\r\n </div>\r\n <h1 className=\"text-3xl font-bold mb-2\">{t('onboarding.title')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('onboarding.subtitle')}</p>\r\n </div>\r\n\r\n {/* Steps indicator */}\r\n <div className=\"flex justify-center mb-8\">\r\n <div className=\"flex items-center gap-2\">\r\n {steps.map((step, index) => (\r\n <div key={step.key} className=\"flex items-center\">\r\n <div\r\n className={`w-10 h-10 rounded-full flex items-center justify-center transition-all ${\r\n index <= currentStepIndex\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}\r\n >\r\n {step.icon}\r\n </div>\r\n {index < steps.length - 1 && (\r\n <div\r\n className={`w-12 h-1 mx-1 rounded transition-all ${\r\n index < currentStepIndex\r\n ? 'bg-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n />\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Card */}\r\n <div className=\"bg-[var(--bg-secondary)] rounded-2xl p-8 shadow-lg border border-[var(--border-color)]\">\r\n {/* Language Step */}\r\n {currentStep === 'language' && (\r\n <div>\r\n <h2 className=\"text-xl font-semibold mb-6 text-center\">{t('onboarding.languageLabel')}</h2>\r\n <div className=\"grid grid-cols-2 gap-4\">\r\n {languages.map((lang) => (\r\n <button\r\n key={lang.code}\r\n onClick={() => setSelectedLanguage(lang.code)}\r\n className={`p-4 rounded-xl border-2 transition-all ${\r\n selectedLanguage === lang.code\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-300)]'\r\n }`}\r\n >\r\n <span className=\"text-3xl mb-2 block\">{lang.flag}</span>\r\n <span className=\"font-medium\">{lang.name}</span>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Theme Step */}\r\n {currentStep === 'theme' && (\r\n <div>\r\n <h2 className=\"text-xl font-semibold mb-6 text-center\">{t('onboarding.themeLabel')}</h2>\r\n\r\n {/* Theme selection */}\r\n <div className=\"grid grid-cols-3 gap-3 mb-8\">\r\n {themes.map((theme) => (\r\n <button\r\n key={theme.value}\r\n onClick={() => setSelectedTheme(theme.value)}\r\n className={`p-4 rounded-xl border-2 transition-all ${\r\n selectedTheme === theme.value\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-300)]'\r\n }`}\r\n >\r\n <span className=\"text-2xl mb-2 block\">{theme.icon}</span>\r\n <span className=\"text-sm font-medium\">{t(`onboarding.${theme.labelKey}`)}</span>\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Accent color selection */}\r\n <div>\r\n <h3 className=\"text-sm font-medium mb-3 text-[var(--text-secondary)]\">\r\n {t('onboarding.accentColorLabel')}\r\n </h3>\r\n <div className=\"flex justify-center gap-3\">\r\n {accentColors.map((color) => (\r\n <button\r\n key={color.key}\r\n onClick={() => setSelectedAccentColor(color.key)}\r\n className={`w-10 h-10 rounded-full transition-all ${\r\n selectedAccentColor === color.key\r\n ? 'ring-2 ring-offset-2 ring-[var(--color-accent-500)] ring-offset-[var(--bg-secondary)]'\r\n : 'hover:scale-110'\r\n }`}\r\n style={{ backgroundColor: color.color }}\r\n title={color.name}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Complete Step */}\r\n {currentStep === 'complete' && (\r\n <div className=\"text-center\">\r\n <div className=\"w-20 h-20 mx-auto bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30 rounded-full flex items-center justify-center mb-6\">\r\n <Sparkles className=\"w-10 h-10 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <h2 className=\"text-xl font-semibold mb-4\">{t('onboarding.stepComplete')}</h2>\r\n <div className=\"text-[var(--text-secondary)] mb-6 space-y-2\">\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <Globe className=\"w-4 h-4\" />\r\n {languages.find((l) => l.code === selectedLanguage)?.name}\r\n </span>\r\n </p>\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <Palette className=\"w-4 h-4\" />\r\n {themes.find((t) => t.value === selectedTheme)?.icon}{' '}\r\n {t(`onboarding.${themes.find((th) => th.value === selectedTheme)?.labelKey}`)}\r\n </span>\r\n </p>\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <span\r\n className=\"w-4 h-4 rounded-full\"\r\n style={{ backgroundColor: accentColors.find((c) => c.key === selectedAccentColor)?.color }}\r\n />\r\n {accentColors.find((c) => c.key === selectedAccentColor)?.name}\r\n </span>\r\n </p>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 rounded-lg p-3 mb-4 text-sm\">\r\n {error}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Navigation buttons */}\r\n <div className=\"flex justify-between mt-8\">\r\n {currentStepIndex > 0 ? (\r\n <button\r\n onClick={handleBack}\r\n className=\"flex items-center gap-2 px-4 py-2 text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-4 h-4\" />\r\n {t('onboarding.back')}\r\n </button>\r\n ) : (\r\n <div />\r\n )}\r\n\r\n {currentStep === 'complete' ? (\r\n <button\r\n onClick={handleComplete}\r\n disabled={isSubmitting}\r\n className=\"flex items-center gap-2 px-6 py-2 bg-[var(--color-accent-500)] hover:bg-[var(--color-accent-600)] text-white rounded-lg font-medium transition-colors disabled:opacity-50\"\r\n >\r\n {isSubmitting ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n {t('onboarding.completing')}\r\n </>\r\n ) : (\r\n <>\r\n {t('onboarding.complete')}\r\n <CheckCircle className=\"w-4 h-4\" />\r\n </>\r\n )}\r\n </button>\r\n ) : (\r\n <button\r\n onClick={handleNext}\r\n className=\"flex items-center gap-2 px-6 py-2 bg-[var(--color-accent-500)] hover:bg-[var(--color-accent-600)] text-white rounded-lg font-medium transition-colors\"\r\n >\r\n {t('onboarding.continue')}\r\n <ArrowRight className=\"w-4 h-4\" />\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["languages","themes","accentColors","OnboardingWizardPage","i18n","useTranslation","navigate","useNavigate","currentStep","setCurrentStep","useState","selectedLanguage","setSelectedLanguage","selectedTheme","setSelectedTheme","selectedAccentColor","setSelectedAccentColor","isSubmitting","setIsSubmitting","error","setError","success","setSuccess","useEffect","api","changeLanguage","steps","jsx","Globe","Palette","Sparkles","currentStepIndex","s","handleNext","nextIndex","handleBack","prevIndex","handleComplete","err","jsxs","CheckCircle","Loader2","step","index","lang","theme","color","l","t","th","c","ArrowLeft","Fragment","ArrowRight"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OnboardingWizardPage-CioLaCYz.js","sources":["../../src/pages/auth/OnboardingWizardPage.tsx"],"sourcesContent":["import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, CheckCircle, Globe, Palette, Sparkles, ArrowRight, ArrowLeft } from 'lucide-react';\r\nimport { api } from '@/services/api/apiClient';\r\nimport { changeLanguage } from '@/i18n/config';\r\n\r\ntype Step = 'language' | 'theme' | 'complete';\r\n\r\ninterface LanguageOption {\r\n code: string;\r\n name: string;\r\n flag: string;\r\n}\r\n\r\ninterface ThemeOption {\r\n value: string;\r\n labelKey: string;\r\n icon: string;\r\n}\r\n\r\nconst languages: LanguageOption[] = [\r\n { code: 'fr', name: 'Francais', flag: '🇫🇷' },\r\n { code: 'en', name: 'English', flag: '🇬🇧' },\r\n { code: 'de', name: 'Deutsch', flag: '🇩🇪' },\r\n { code: 'it', name: 'Italiano', flag: '🇮🇹' },\r\n];\r\n\r\nconst themes: ThemeOption[] = [\r\n { value: 'light', labelKey: 'themeLight', icon: '☀️' },\r\n { value: 'dark', labelKey: 'themeDark', icon: '🌙' },\r\n { value: 'system', labelKey: 'themeSystem', icon: '💻' },\r\n];\r\n\r\nconst accentColors = [\r\n { key: 'indigo', color: '#6366f1', name: 'Indigo' },\r\n { key: 'blue', color: '#3b82f6', name: 'Blue' },\r\n { key: 'emerald', color: '#10b981', name: 'Emerald' },\r\n { key: 'amber', color: '#f59e0b', name: 'Amber' },\r\n { key: 'rose', color: '#f43f5e', name: 'Rose' },\r\n { key: 'purple', color: '#a855f7', name: 'Purple' },\r\n];\r\n\r\nexport function OnboardingWizardPage(): ReactElement {\r\n const { t, i18n } = useTranslation('auth');\r\n const navigate = useNavigate();\r\n\r\n const [currentStep, setCurrentStep] = useState<Step>('language');\r\n const [selectedLanguage, setSelectedLanguage] = useState(i18n.language?.substring(0, 2) || 'fr');\r\n const [selectedTheme, setSelectedTheme] = useState('dark');\r\n const [selectedAccentColor, setSelectedAccentColor] = useState('indigo');\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState(false);\r\n\r\n // Check onboarding status on load\r\n useEffect(() => {\r\n const checkOnboardingStatus = async () => {\r\n try {\r\n const response = await api.get<{ hasCompletedOnboarding: boolean }>('/api/onboarding/status');\r\n if (response.hasCompletedOnboarding) {\r\n // Already completed, redirect to home\r\n navigate('/myspace', { replace: true });\r\n }\r\n } catch {\r\n // If we can't check status, allow proceeding\r\n }\r\n };\r\n\r\n checkOnboardingStatus();\r\n }, [navigate]);\r\n\r\n // Update language immediately when selected (lazy loads translations if needed)\r\n useEffect(() => {\r\n if (selectedLanguage && selectedLanguage !== i18n.language?.substring(0, 2)) {\r\n changeLanguage(selectedLanguage);\r\n }\r\n }, [selectedLanguage, i18n]);\r\n\r\n const steps: { key: Step; labelKey: string; icon: React.ReactNode }[] = [\r\n { key: 'language', labelKey: 'stepLanguage', icon: <Globe className=\"w-5 h-5\" /> },\r\n { key: 'theme', labelKey: 'stepTheme', icon: <Palette className=\"w-5 h-5\" /> },\r\n { key: 'complete', labelKey: 'stepComplete', icon: <Sparkles className=\"w-5 h-5\" /> },\r\n ];\r\n\r\n const currentStepIndex = steps.findIndex((s) => s.key === currentStep);\r\n\r\n const handleNext = () => {\r\n const nextIndex = currentStepIndex + 1;\r\n if (nextIndex < steps.length) {\r\n setCurrentStep(steps[nextIndex].key);\r\n }\r\n };\r\n\r\n const handleBack = () => {\r\n const prevIndex = currentStepIndex - 1;\r\n if (prevIndex >= 0) {\r\n setCurrentStep(steps[prevIndex].key);\r\n }\r\n };\r\n\r\n const handleComplete = async () => {\r\n setIsSubmitting(true);\r\n setError(null);\r\n\r\n try {\r\n await api.post('/api/onboarding/complete', {\r\n language: selectedLanguage,\r\n theme: selectedTheme,\r\n accentColorKey: selectedAccentColor,\r\n });\r\n\r\n // Save preferences locally\r\n localStorage.setItem('i18nextLng', selectedLanguage);\r\n localStorage.setItem(\r\n 'smartstack-theme-config',\r\n JSON.stringify({\r\n mode: selectedTheme,\r\n accentColorKey: selectedAccentColor,\r\n borderRadius: {},\r\n itemPaletteKey: 'neutral',\r\n })\r\n );\r\n\r\n setSuccess(true);\r\n\r\n // Redirect after success animation\r\n setTimeout(() => {\r\n window.location.href = '/myspace';\r\n }, 2000);\r\n } catch (err) {\r\n console.error('Onboarding error:', err);\r\n setError(t('onboarding.errorMessage'));\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n };\r\n\r\n if (success) {\r\n return (\r\n <div className=\"min-h-screen flex items-center justify-center bg-[var(--bg-primary)]\">\r\n <div className=\"max-w-md w-full mx-4\">\r\n <div className=\"bg-[var(--bg-secondary)] rounded-2xl p-8 shadow-lg border border-[var(--border-color)]\">\r\n <div className=\"text-center\">\r\n <div className=\"w-20 h-20 mx-auto bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center mb-6\">\r\n <CheckCircle className=\"w-12 h-12 text-green-600 dark:text-green-400\" />\r\n </div>\r\n <h2 className=\"text-2xl font-bold mb-3\">{t('onboarding.successTitle')}</h2>\r\n <p className=\"text-[var(--text-secondary)]\">{t('onboarding.successMessage')}</p>\r\n <div className=\"mt-6\">\r\n <Loader2 className=\"w-6 h-6 mx-auto text-[var(--color-accent-500)] animate-spin\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"min-h-screen flex items-center justify-center bg-[var(--bg-primary)] p-4\">\r\n <div className=\"max-w-lg w-full\">\r\n {/* Header */}\r\n <div className=\"text-center mb-8\">\r\n <div className=\"flex items-center justify-center gap-2 mb-4\">\r\n <div className=\"w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center\">\r\n <span className=\"text-white text-xl font-bold\">S</span>\r\n </div>\r\n </div>\r\n <h1 className=\"text-3xl font-bold mb-2\">{t('onboarding.title')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('onboarding.subtitle')}</p>\r\n </div>\r\n\r\n {/* Steps indicator */}\r\n <div className=\"flex justify-center mb-8\">\r\n <div className=\"flex items-center gap-2\">\r\n {steps.map((step, index) => (\r\n <div key={step.key} className=\"flex items-center\">\r\n <div\r\n className={`w-10 h-10 rounded-full flex items-center justify-center transition-all ${\r\n index <= currentStepIndex\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}\r\n >\r\n {step.icon}\r\n </div>\r\n {index < steps.length - 1 && (\r\n <div\r\n className={`w-12 h-1 mx-1 rounded transition-all ${\r\n index < currentStepIndex\r\n ? 'bg-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n />\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Card */}\r\n <div className=\"bg-[var(--bg-secondary)] rounded-2xl p-8 shadow-lg border border-[var(--border-color)]\">\r\n {/* Language Step */}\r\n {currentStep === 'language' && (\r\n <div>\r\n <h2 className=\"text-xl font-semibold mb-6 text-center\">{t('onboarding.languageLabel')}</h2>\r\n <div className=\"grid grid-cols-2 gap-4\">\r\n {languages.map((lang) => (\r\n <button\r\n key={lang.code}\r\n onClick={() => setSelectedLanguage(lang.code)}\r\n className={`p-4 rounded-xl border-2 transition-all ${\r\n selectedLanguage === lang.code\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-300)]'\r\n }`}\r\n >\r\n <span className=\"text-3xl mb-2 block\">{lang.flag}</span>\r\n <span className=\"font-medium\">{lang.name}</span>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Theme Step */}\r\n {currentStep === 'theme' && (\r\n <div>\r\n <h2 className=\"text-xl font-semibold mb-6 text-center\">{t('onboarding.themeLabel')}</h2>\r\n\r\n {/* Theme selection */}\r\n <div className=\"grid grid-cols-3 gap-3 mb-8\">\r\n {themes.map((theme) => (\r\n <button\r\n key={theme.value}\r\n onClick={() => setSelectedTheme(theme.value)}\r\n className={`p-4 rounded-xl border-2 transition-all ${\r\n selectedTheme === theme.value\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-300)]'\r\n }`}\r\n >\r\n <span className=\"text-2xl mb-2 block\">{theme.icon}</span>\r\n <span className=\"text-sm font-medium\">{t(`onboarding.${theme.labelKey}`)}</span>\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Accent color selection */}\r\n <div>\r\n <h3 className=\"text-sm font-medium mb-3 text-[var(--text-secondary)]\">\r\n {t('onboarding.accentColorLabel')}\r\n </h3>\r\n <div className=\"flex justify-center gap-3\">\r\n {accentColors.map((color) => (\r\n <button\r\n key={color.key}\r\n onClick={() => setSelectedAccentColor(color.key)}\r\n className={`w-10 h-10 rounded-full transition-all ${\r\n selectedAccentColor === color.key\r\n ? 'ring-2 ring-offset-2 ring-[var(--color-accent-500)] ring-offset-[var(--bg-secondary)]'\r\n : 'hover:scale-110'\r\n }`}\r\n style={{ backgroundColor: color.color }}\r\n title={color.name}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Complete Step */}\r\n {currentStep === 'complete' && (\r\n <div className=\"text-center\">\r\n <div className=\"w-20 h-20 mx-auto bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30 rounded-full flex items-center justify-center mb-6\">\r\n <Sparkles className=\"w-10 h-10 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <h2 className=\"text-xl font-semibold mb-4\">{t('onboarding.stepComplete')}</h2>\r\n <div className=\"text-[var(--text-secondary)] mb-6 space-y-2\">\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <Globe className=\"w-4 h-4\" />\r\n {languages.find((l) => l.code === selectedLanguage)?.name}\r\n </span>\r\n </p>\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <Palette className=\"w-4 h-4\" />\r\n {themes.find((t) => t.value === selectedTheme)?.icon}{' '}\r\n {t(`onboarding.${themes.find((th) => th.value === selectedTheme)?.labelKey}`)}\r\n </span>\r\n </p>\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <span\r\n className=\"w-4 h-4 rounded-full\"\r\n style={{ backgroundColor: accentColors.find((c) => c.key === selectedAccentColor)?.color }}\r\n />\r\n {accentColors.find((c) => c.key === selectedAccentColor)?.name}\r\n </span>\r\n </p>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 rounded-lg p-3 mb-4 text-sm\">\r\n {error}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Navigation buttons */}\r\n <div className=\"flex justify-between mt-8\">\r\n {currentStepIndex > 0 ? (\r\n <button\r\n onClick={handleBack}\r\n className=\"flex items-center gap-2 px-4 py-2 text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-4 h-4\" />\r\n {t('onboarding.back')}\r\n </button>\r\n ) : (\r\n <div />\r\n )}\r\n\r\n {currentStep === 'complete' ? (\r\n <button\r\n onClick={handleComplete}\r\n disabled={isSubmitting}\r\n className=\"flex items-center gap-2 px-6 py-2 bg-[var(--color-accent-500)] hover:bg-[var(--color-accent-600)] text-white rounded-lg font-medium transition-colors disabled:opacity-50\"\r\n >\r\n {isSubmitting ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n {t('onboarding.completing')}\r\n </>\r\n ) : (\r\n <>\r\n {t('onboarding.complete')}\r\n <CheckCircle className=\"w-4 h-4\" />\r\n </>\r\n )}\r\n </button>\r\n ) : (\r\n <button\r\n onClick={handleNext}\r\n className=\"flex items-center gap-2 px-6 py-2 bg-[var(--color-accent-500)] hover:bg-[var(--color-accent-600)] text-white rounded-lg font-medium transition-colors\"\r\n >\r\n {t('onboarding.continue')}\r\n <ArrowRight className=\"w-4 h-4\" />\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["languages","themes","accentColors","OnboardingWizardPage","i18n","useTranslation","navigate","useNavigate","currentStep","setCurrentStep","useState","selectedLanguage","setSelectedLanguage","selectedTheme","setSelectedTheme","selectedAccentColor","setSelectedAccentColor","isSubmitting","setIsSubmitting","error","setError","success","setSuccess","useEffect","api","changeLanguage","steps","jsx","Globe","Palette","Sparkles","currentStepIndex","s","handleNext","nextIndex","handleBack","prevIndex","handleComplete","err","jsxs","CheckCircle","Loader2","step","index","lang","theme","color","l","t","th","c","ArrowLeft","Fragment","ArrowRight"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),r=require("react"),P=require("react-router-dom"),T=require("react-i18next"),t=require("lucide-react"),g=require("./index-
|
|
2
|
-
//# sourceMappingURL=OnboardingWizardPage-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),r=require("react"),P=require("react-router-dom"),T=require("react-i18next"),t=require("lucide-react"),g=require("./index-DK5czlkn.js"),N=[{code:"fr",name:"Francais",flag:"🇫🇷"},{code:"en",name:"English",flag:"🇬🇧"},{code:"de",name:"Deutsch",flag:"🇩🇪"},{code:"it",name:"Italiano",flag:"🇮🇹"}],b=[{value:"light",labelKey:"themeLight",icon:"☀️"},{value:"dark",labelKey:"themeDark",icon:"🌙"},{value:"system",labelKey:"themeSystem",icon:"💻"}],u=[{key:"indigo",color:"#6366f1",name:"Indigo"},{key:"blue",color:"#3b82f6",name:"Blue"},{key:"emerald",color:"#10b981",name:"Emerald"},{key:"amber",color:"#f59e0b",name:"Amber"},{key:"rose",color:"#f43f5e",name:"Rose"},{key:"purple",color:"#a855f7",name:"Purple"}];function $(){const{t:s,i18n:x}=T.useTranslation("auth"),h=P.useNavigate(),[l,f]=r.useState("language"),[n,k]=r.useState(x.language?.substring(0,2)||"fr"),[o,w]=r.useState("dark"),[i,S]=r.useState("indigo"),[p,v]=r.useState(!1),[j,y]=r.useState(null),[C,L]=r.useState(!1);r.useEffect(()=>{(async()=>{try{(await g.api.get("/api/onboarding/status")).hasCompletedOnboarding&&h("/myspace",{replace:!0})}catch{}})()},[h]),r.useEffect(()=>{n&&n!==x.language?.substring(0,2)&&g.changeLanguage(n)},[n,x]);const c=[{key:"language",labelKey:"stepLanguage",icon:e.jsx(t.Globe,{className:"w-5 h-5"})},{key:"theme",labelKey:"stepTheme",icon:e.jsx(t.Palette,{className:"w-5 h-5"})},{key:"complete",labelKey:"stepComplete",icon:e.jsx(t.Sparkles,{className:"w-5 h-5"})}],d=c.findIndex(a=>a.key===l),I=()=>{const a=d+1;a<c.length&&f(c[a].key)},K=()=>{const a=d-1;a>=0&&f(c[a].key)},O=async()=>{v(!0),y(null);try{await g.api.post("/api/onboarding/complete",{language:n,theme:o,accentColorKey:i}),localStorage.setItem("i18nextLng",n),localStorage.setItem("smartstack-theme-config",JSON.stringify({mode:o,accentColorKey:i,borderRadius:{},itemPaletteKey:"neutral"})),L(!0),setTimeout(()=>{window.location.href="/myspace"},2e3)}catch(a){console.error("Onboarding error:",a),y(s("onboarding.errorMessage"))}finally{v(!1)}};return C?e.jsx("div",{className:"min-h-screen flex items-center justify-center bg-[var(--bg-primary)]",children:e.jsx("div",{className:"max-w-md w-full mx-4",children:e.jsx("div",{className:"bg-[var(--bg-secondary)] rounded-2xl p-8 shadow-lg border border-[var(--border-color)]",children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"w-20 h-20 mx-auto bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center mb-6",children:e.jsx(t.CheckCircle,{className:"w-12 h-12 text-green-600 dark:text-green-400"})}),e.jsx("h2",{className:"text-2xl font-bold mb-3",children:s("onboarding.successTitle")}),e.jsx("p",{className:"text-[var(--text-secondary)]",children:s("onboarding.successMessage")}),e.jsx("div",{className:"mt-6",children:e.jsx(t.Loader2,{className:"w-6 h-6 mx-auto text-[var(--color-accent-500)] animate-spin"})})]})})})}):e.jsx("div",{className:"min-h-screen flex items-center justify-center bg-[var(--bg-primary)] p-4",children:e.jsxs("div",{className:"max-w-lg w-full",children:[e.jsxs("div",{className:"text-center mb-8",children:[e.jsx("div",{className:"flex items-center justify-center gap-2 mb-4",children:e.jsx("div",{className:"w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center",children:e.jsx("span",{className:"text-white text-xl font-bold",children:"S"})})}),e.jsx("h1",{className:"text-3xl font-bold mb-2",children:s("onboarding.title")}),e.jsx("p",{className:"text-[var(--text-secondary)]",children:s("onboarding.subtitle")})]}),e.jsx("div",{className:"flex justify-center mb-8",children:e.jsx("div",{className:"flex items-center gap-2",children:c.map((a,m)=>e.jsxs("div",{className:"flex items-center",children:[e.jsx("div",{className:`w-10 h-10 rounded-full flex items-center justify-center transition-all ${m<=d?"bg-[var(--color-accent-500)] text-white":"bg-[var(--bg-tertiary)] text-[var(--text-secondary)]"}`,children:a.icon}),m<c.length-1&&e.jsx("div",{className:`w-12 h-1 mx-1 rounded transition-all ${m<d?"bg-[var(--color-accent-500)]":"bg-[var(--bg-tertiary)]"}`})]},a.key))})}),e.jsxs("div",{className:"bg-[var(--bg-secondary)] rounded-2xl p-8 shadow-lg border border-[var(--border-color)]",children:[l==="language"&&e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold mb-6 text-center",children:s("onboarding.languageLabel")}),e.jsx("div",{className:"grid grid-cols-2 gap-4",children:N.map(a=>e.jsxs("button",{onClick:()=>k(a.code),className:`p-4 rounded-xl border-2 transition-all ${n===a.code?"border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20":"border-[var(--border-color)] hover:border-[var(--color-accent-300)]"}`,children:[e.jsx("span",{className:"text-3xl mb-2 block",children:a.flag}),e.jsx("span",{className:"font-medium",children:a.name})]},a.code))})]}),l==="theme"&&e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold mb-6 text-center",children:s("onboarding.themeLabel")}),e.jsx("div",{className:"grid grid-cols-3 gap-3 mb-8",children:b.map(a=>e.jsxs("button",{onClick:()=>w(a.value),className:`p-4 rounded-xl border-2 transition-all ${o===a.value?"border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20":"border-[var(--border-color)] hover:border-[var(--color-accent-300)]"}`,children:[e.jsx("span",{className:"text-2xl mb-2 block",children:a.icon}),e.jsx("span",{className:"text-sm font-medium",children:s(`onboarding.${a.labelKey}`)})]},a.value))}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium mb-3 text-[var(--text-secondary)]",children:s("onboarding.accentColorLabel")}),e.jsx("div",{className:"flex justify-center gap-3",children:u.map(a=>e.jsx("button",{onClick:()=>S(a.key),className:`w-10 h-10 rounded-full transition-all ${i===a.key?"ring-2 ring-offset-2 ring-[var(--color-accent-500)] ring-offset-[var(--bg-secondary)]":"hover:scale-110"}`,style:{backgroundColor:a.color},title:a.name},a.key))})]})]}),l==="complete"&&e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"w-20 h-20 mx-auto bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30 rounded-full flex items-center justify-center mb-6",children:e.jsx(t.Sparkles,{className:"w-10 h-10 text-[var(--color-accent-500)]"})}),e.jsx("h2",{className:"text-xl font-semibold mb-4",children:s("onboarding.stepComplete")}),e.jsxs("div",{className:"text-[var(--text-secondary)] mb-6 space-y-2",children:[e.jsx("p",{children:e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(t.Globe,{className:"w-4 h-4"}),N.find(a=>a.code===n)?.name]})}),e.jsx("p",{children:e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(t.Palette,{className:"w-4 h-4"}),b.find(a=>a.value===o)?.icon," ",s(`onboarding.${b.find(a=>a.value===o)?.labelKey}`)]})}),e.jsx("p",{children:e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx("span",{className:"w-4 h-4 rounded-full",style:{backgroundColor:u.find(a=>a.key===i)?.color}}),u.find(a=>a.key===i)?.name]})})]}),j&&e.jsx("div",{className:"bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 rounded-lg p-3 mb-4 text-sm",children:j})]}),e.jsxs("div",{className:"flex justify-between mt-8",children:[d>0?e.jsxs("button",{onClick:K,className:"flex items-center gap-2 px-4 py-2 text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors",children:[e.jsx(t.ArrowLeft,{className:"w-4 h-4"}),s("onboarding.back")]}):e.jsx("div",{}),l==="complete"?e.jsx("button",{onClick:O,disabled:p,className:"flex items-center gap-2 px-6 py-2 bg-[var(--color-accent-500)] hover:bg-[var(--color-accent-600)] text-white rounded-lg font-medium transition-colors disabled:opacity-50",children:p?e.jsxs(e.Fragment,{children:[e.jsx(t.Loader2,{className:"w-4 h-4 animate-spin"}),s("onboarding.completing")]}):e.jsxs(e.Fragment,{children:[s("onboarding.complete"),e.jsx(t.CheckCircle,{className:"w-4 h-4"})]})}):e.jsxs("button",{onClick:I,className:"flex items-center gap-2 px-6 py-2 bg-[var(--color-accent-500)] hover:bg-[var(--color-accent-600)] text-white rounded-lg font-medium transition-colors",children:[s("onboarding.continue"),e.jsx(t.ArrowRight,{className:"w-4 h-4"})]})]})]})]})})}exports.OnboardingWizardPage=$;
|
|
2
|
+
//# sourceMappingURL=OnboardingWizardPage-CrAQt7qL.js.map
|
package/dist/chunks/{OnboardingWizardPage-Du-tQ2ag.js.map → OnboardingWizardPage-CrAQt7qL.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OnboardingWizardPage-Du-tQ2ag.js","sources":["../../src/pages/auth/OnboardingWizardPage.tsx"],"sourcesContent":["import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, CheckCircle, Globe, Palette, Sparkles, ArrowRight, ArrowLeft } from 'lucide-react';\r\nimport { api } from '@/services/api/apiClient';\r\nimport { changeLanguage } from '@/i18n/config';\r\n\r\ntype Step = 'language' | 'theme' | 'complete';\r\n\r\ninterface LanguageOption {\r\n code: string;\r\n name: string;\r\n flag: string;\r\n}\r\n\r\ninterface ThemeOption {\r\n value: string;\r\n labelKey: string;\r\n icon: string;\r\n}\r\n\r\nconst languages: LanguageOption[] = [\r\n { code: 'fr', name: 'Francais', flag: '🇫🇷' },\r\n { code: 'en', name: 'English', flag: '🇬🇧' },\r\n { code: 'de', name: 'Deutsch', flag: '🇩🇪' },\r\n { code: 'it', name: 'Italiano', flag: '🇮🇹' },\r\n];\r\n\r\nconst themes: ThemeOption[] = [\r\n { value: 'light', labelKey: 'themeLight', icon: '☀️' },\r\n { value: 'dark', labelKey: 'themeDark', icon: '🌙' },\r\n { value: 'system', labelKey: 'themeSystem', icon: '💻' },\r\n];\r\n\r\nconst accentColors = [\r\n { key: 'indigo', color: '#6366f1', name: 'Indigo' },\r\n { key: 'blue', color: '#3b82f6', name: 'Blue' },\r\n { key: 'emerald', color: '#10b981', name: 'Emerald' },\r\n { key: 'amber', color: '#f59e0b', name: 'Amber' },\r\n { key: 'rose', color: '#f43f5e', name: 'Rose' },\r\n { key: 'purple', color: '#a855f7', name: 'Purple' },\r\n];\r\n\r\nexport function OnboardingWizardPage(): ReactElement {\r\n const { t, i18n } = useTranslation('auth');\r\n const navigate = useNavigate();\r\n\r\n const [currentStep, setCurrentStep] = useState<Step>('language');\r\n const [selectedLanguage, setSelectedLanguage] = useState(i18n.language?.substring(0, 2) || 'fr');\r\n const [selectedTheme, setSelectedTheme] = useState('dark');\r\n const [selectedAccentColor, setSelectedAccentColor] = useState('indigo');\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState(false);\r\n\r\n // Check onboarding status on load\r\n useEffect(() => {\r\n const checkOnboardingStatus = async () => {\r\n try {\r\n const response = await api.get<{ hasCompletedOnboarding: boolean }>('/api/onboarding/status');\r\n if (response.hasCompletedOnboarding) {\r\n // Already completed, redirect to home\r\n navigate('/myspace', { replace: true });\r\n }\r\n } catch {\r\n // If we can't check status, allow proceeding\r\n }\r\n };\r\n\r\n checkOnboardingStatus();\r\n }, [navigate]);\r\n\r\n // Update language immediately when selected (lazy loads translations if needed)\r\n useEffect(() => {\r\n if (selectedLanguage && selectedLanguage !== i18n.language?.substring(0, 2)) {\r\n changeLanguage(selectedLanguage);\r\n }\r\n }, [selectedLanguage, i18n]);\r\n\r\n const steps: { key: Step; labelKey: string; icon: React.ReactNode }[] = [\r\n { key: 'language', labelKey: 'stepLanguage', icon: <Globe className=\"w-5 h-5\" /> },\r\n { key: 'theme', labelKey: 'stepTheme', icon: <Palette className=\"w-5 h-5\" /> },\r\n { key: 'complete', labelKey: 'stepComplete', icon: <Sparkles className=\"w-5 h-5\" /> },\r\n ];\r\n\r\n const currentStepIndex = steps.findIndex((s) => s.key === currentStep);\r\n\r\n const handleNext = () => {\r\n const nextIndex = currentStepIndex + 1;\r\n if (nextIndex < steps.length) {\r\n setCurrentStep(steps[nextIndex].key);\r\n }\r\n };\r\n\r\n const handleBack = () => {\r\n const prevIndex = currentStepIndex - 1;\r\n if (prevIndex >= 0) {\r\n setCurrentStep(steps[prevIndex].key);\r\n }\r\n };\r\n\r\n const handleComplete = async () => {\r\n setIsSubmitting(true);\r\n setError(null);\r\n\r\n try {\r\n await api.post('/api/onboarding/complete', {\r\n language: selectedLanguage,\r\n theme: selectedTheme,\r\n accentColorKey: selectedAccentColor,\r\n });\r\n\r\n // Save preferences locally\r\n localStorage.setItem('i18nextLng', selectedLanguage);\r\n localStorage.setItem(\r\n 'smartstack-theme-config',\r\n JSON.stringify({\r\n mode: selectedTheme,\r\n accentColorKey: selectedAccentColor,\r\n borderRadius: {},\r\n itemPaletteKey: 'neutral',\r\n })\r\n );\r\n\r\n setSuccess(true);\r\n\r\n // Redirect after success animation\r\n setTimeout(() => {\r\n window.location.href = '/myspace';\r\n }, 2000);\r\n } catch (err) {\r\n console.error('Onboarding error:', err);\r\n setError(t('onboarding.errorMessage'));\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n };\r\n\r\n if (success) {\r\n return (\r\n <div className=\"min-h-screen flex items-center justify-center bg-[var(--bg-primary)]\">\r\n <div className=\"max-w-md w-full mx-4\">\r\n <div className=\"bg-[var(--bg-secondary)] rounded-2xl p-8 shadow-lg border border-[var(--border-color)]\">\r\n <div className=\"text-center\">\r\n <div className=\"w-20 h-20 mx-auto bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center mb-6\">\r\n <CheckCircle className=\"w-12 h-12 text-green-600 dark:text-green-400\" />\r\n </div>\r\n <h2 className=\"text-2xl font-bold mb-3\">{t('onboarding.successTitle')}</h2>\r\n <p className=\"text-[var(--text-secondary)]\">{t('onboarding.successMessage')}</p>\r\n <div className=\"mt-6\">\r\n <Loader2 className=\"w-6 h-6 mx-auto text-[var(--color-accent-500)] animate-spin\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"min-h-screen flex items-center justify-center bg-[var(--bg-primary)] p-4\">\r\n <div className=\"max-w-lg w-full\">\r\n {/* Header */}\r\n <div className=\"text-center mb-8\">\r\n <div className=\"flex items-center justify-center gap-2 mb-4\">\r\n <div className=\"w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center\">\r\n <span className=\"text-white text-xl font-bold\">S</span>\r\n </div>\r\n </div>\r\n <h1 className=\"text-3xl font-bold mb-2\">{t('onboarding.title')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('onboarding.subtitle')}</p>\r\n </div>\r\n\r\n {/* Steps indicator */}\r\n <div className=\"flex justify-center mb-8\">\r\n <div className=\"flex items-center gap-2\">\r\n {steps.map((step, index) => (\r\n <div key={step.key} className=\"flex items-center\">\r\n <div\r\n className={`w-10 h-10 rounded-full flex items-center justify-center transition-all ${\r\n index <= currentStepIndex\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}\r\n >\r\n {step.icon}\r\n </div>\r\n {index < steps.length - 1 && (\r\n <div\r\n className={`w-12 h-1 mx-1 rounded transition-all ${\r\n index < currentStepIndex\r\n ? 'bg-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n />\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Card */}\r\n <div className=\"bg-[var(--bg-secondary)] rounded-2xl p-8 shadow-lg border border-[var(--border-color)]\">\r\n {/* Language Step */}\r\n {currentStep === 'language' && (\r\n <div>\r\n <h2 className=\"text-xl font-semibold mb-6 text-center\">{t('onboarding.languageLabel')}</h2>\r\n <div className=\"grid grid-cols-2 gap-4\">\r\n {languages.map((lang) => (\r\n <button\r\n key={lang.code}\r\n onClick={() => setSelectedLanguage(lang.code)}\r\n className={`p-4 rounded-xl border-2 transition-all ${\r\n selectedLanguage === lang.code\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-300)]'\r\n }`}\r\n >\r\n <span className=\"text-3xl mb-2 block\">{lang.flag}</span>\r\n <span className=\"font-medium\">{lang.name}</span>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Theme Step */}\r\n {currentStep === 'theme' && (\r\n <div>\r\n <h2 className=\"text-xl font-semibold mb-6 text-center\">{t('onboarding.themeLabel')}</h2>\r\n\r\n {/* Theme selection */}\r\n <div className=\"grid grid-cols-3 gap-3 mb-8\">\r\n {themes.map((theme) => (\r\n <button\r\n key={theme.value}\r\n onClick={() => setSelectedTheme(theme.value)}\r\n className={`p-4 rounded-xl border-2 transition-all ${\r\n selectedTheme === theme.value\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-300)]'\r\n }`}\r\n >\r\n <span className=\"text-2xl mb-2 block\">{theme.icon}</span>\r\n <span className=\"text-sm font-medium\">{t(`onboarding.${theme.labelKey}`)}</span>\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Accent color selection */}\r\n <div>\r\n <h3 className=\"text-sm font-medium mb-3 text-[var(--text-secondary)]\">\r\n {t('onboarding.accentColorLabel')}\r\n </h3>\r\n <div className=\"flex justify-center gap-3\">\r\n {accentColors.map((color) => (\r\n <button\r\n key={color.key}\r\n onClick={() => setSelectedAccentColor(color.key)}\r\n className={`w-10 h-10 rounded-full transition-all ${\r\n selectedAccentColor === color.key\r\n ? 'ring-2 ring-offset-2 ring-[var(--color-accent-500)] ring-offset-[var(--bg-secondary)]'\r\n : 'hover:scale-110'\r\n }`}\r\n style={{ backgroundColor: color.color }}\r\n title={color.name}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Complete Step */}\r\n {currentStep === 'complete' && (\r\n <div className=\"text-center\">\r\n <div className=\"w-20 h-20 mx-auto bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30 rounded-full flex items-center justify-center mb-6\">\r\n <Sparkles className=\"w-10 h-10 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <h2 className=\"text-xl font-semibold mb-4\">{t('onboarding.stepComplete')}</h2>\r\n <div className=\"text-[var(--text-secondary)] mb-6 space-y-2\">\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <Globe className=\"w-4 h-4\" />\r\n {languages.find((l) => l.code === selectedLanguage)?.name}\r\n </span>\r\n </p>\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <Palette className=\"w-4 h-4\" />\r\n {themes.find((t) => t.value === selectedTheme)?.icon}{' '}\r\n {t(`onboarding.${themes.find((th) => th.value === selectedTheme)?.labelKey}`)}\r\n </span>\r\n </p>\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <span\r\n className=\"w-4 h-4 rounded-full\"\r\n style={{ backgroundColor: accentColors.find((c) => c.key === selectedAccentColor)?.color }}\r\n />\r\n {accentColors.find((c) => c.key === selectedAccentColor)?.name}\r\n </span>\r\n </p>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 rounded-lg p-3 mb-4 text-sm\">\r\n {error}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Navigation buttons */}\r\n <div className=\"flex justify-between mt-8\">\r\n {currentStepIndex > 0 ? (\r\n <button\r\n onClick={handleBack}\r\n className=\"flex items-center gap-2 px-4 py-2 text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-4 h-4\" />\r\n {t('onboarding.back')}\r\n </button>\r\n ) : (\r\n <div />\r\n )}\r\n\r\n {currentStep === 'complete' ? (\r\n <button\r\n onClick={handleComplete}\r\n disabled={isSubmitting}\r\n className=\"flex items-center gap-2 px-6 py-2 bg-[var(--color-accent-500)] hover:bg-[var(--color-accent-600)] text-white rounded-lg font-medium transition-colors disabled:opacity-50\"\r\n >\r\n {isSubmitting ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n {t('onboarding.completing')}\r\n </>\r\n ) : (\r\n <>\r\n {t('onboarding.complete')}\r\n <CheckCircle className=\"w-4 h-4\" />\r\n </>\r\n )}\r\n </button>\r\n ) : (\r\n <button\r\n onClick={handleNext}\r\n className=\"flex items-center gap-2 px-6 py-2 bg-[var(--color-accent-500)] hover:bg-[var(--color-accent-600)] text-white rounded-lg font-medium transition-colors\"\r\n >\r\n {t('onboarding.continue')}\r\n <ArrowRight className=\"w-4 h-4\" />\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["languages","themes","accentColors","OnboardingWizardPage","t","i18n","useTranslation","navigate","useNavigate","currentStep","setCurrentStep","useState","selectedLanguage","setSelectedLanguage","selectedTheme","setSelectedTheme","selectedAccentColor","setSelectedAccentColor","isSubmitting","setIsSubmitting","error","setError","success","setSuccess","useEffect","api","changeLanguage","steps","jsx","Globe","Palette","Sparkles","currentStepIndex","s","handleNext","nextIndex","handleBack","prevIndex","handleComplete","err","jsxs","CheckCircle","Loader2","step","index","lang","theme","color","l","th","c","ArrowLeft","Fragment","ArrowRight"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OnboardingWizardPage-CrAQt7qL.js","sources":["../../src/pages/auth/OnboardingWizardPage.tsx"],"sourcesContent":["import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, CheckCircle, Globe, Palette, Sparkles, ArrowRight, ArrowLeft } from 'lucide-react';\r\nimport { api } from '@/services/api/apiClient';\r\nimport { changeLanguage } from '@/i18n/config';\r\n\r\ntype Step = 'language' | 'theme' | 'complete';\r\n\r\ninterface LanguageOption {\r\n code: string;\r\n name: string;\r\n flag: string;\r\n}\r\n\r\ninterface ThemeOption {\r\n value: string;\r\n labelKey: string;\r\n icon: string;\r\n}\r\n\r\nconst languages: LanguageOption[] = [\r\n { code: 'fr', name: 'Francais', flag: '🇫🇷' },\r\n { code: 'en', name: 'English', flag: '🇬🇧' },\r\n { code: 'de', name: 'Deutsch', flag: '🇩🇪' },\r\n { code: 'it', name: 'Italiano', flag: '🇮🇹' },\r\n];\r\n\r\nconst themes: ThemeOption[] = [\r\n { value: 'light', labelKey: 'themeLight', icon: '☀️' },\r\n { value: 'dark', labelKey: 'themeDark', icon: '🌙' },\r\n { value: 'system', labelKey: 'themeSystem', icon: '💻' },\r\n];\r\n\r\nconst accentColors = [\r\n { key: 'indigo', color: '#6366f1', name: 'Indigo' },\r\n { key: 'blue', color: '#3b82f6', name: 'Blue' },\r\n { key: 'emerald', color: '#10b981', name: 'Emerald' },\r\n { key: 'amber', color: '#f59e0b', name: 'Amber' },\r\n { key: 'rose', color: '#f43f5e', name: 'Rose' },\r\n { key: 'purple', color: '#a855f7', name: 'Purple' },\r\n];\r\n\r\nexport function OnboardingWizardPage(): ReactElement {\r\n const { t, i18n } = useTranslation('auth');\r\n const navigate = useNavigate();\r\n\r\n const [currentStep, setCurrentStep] = useState<Step>('language');\r\n const [selectedLanguage, setSelectedLanguage] = useState(i18n.language?.substring(0, 2) || 'fr');\r\n const [selectedTheme, setSelectedTheme] = useState('dark');\r\n const [selectedAccentColor, setSelectedAccentColor] = useState('indigo');\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState(false);\r\n\r\n // Check onboarding status on load\r\n useEffect(() => {\r\n const checkOnboardingStatus = async () => {\r\n try {\r\n const response = await api.get<{ hasCompletedOnboarding: boolean }>('/api/onboarding/status');\r\n if (response.hasCompletedOnboarding) {\r\n // Already completed, redirect to home\r\n navigate('/myspace', { replace: true });\r\n }\r\n } catch {\r\n // If we can't check status, allow proceeding\r\n }\r\n };\r\n\r\n checkOnboardingStatus();\r\n }, [navigate]);\r\n\r\n // Update language immediately when selected (lazy loads translations if needed)\r\n useEffect(() => {\r\n if (selectedLanguage && selectedLanguage !== i18n.language?.substring(0, 2)) {\r\n changeLanguage(selectedLanguage);\r\n }\r\n }, [selectedLanguage, i18n]);\r\n\r\n const steps: { key: Step; labelKey: string; icon: React.ReactNode }[] = [\r\n { key: 'language', labelKey: 'stepLanguage', icon: <Globe className=\"w-5 h-5\" /> },\r\n { key: 'theme', labelKey: 'stepTheme', icon: <Palette className=\"w-5 h-5\" /> },\r\n { key: 'complete', labelKey: 'stepComplete', icon: <Sparkles className=\"w-5 h-5\" /> },\r\n ];\r\n\r\n const currentStepIndex = steps.findIndex((s) => s.key === currentStep);\r\n\r\n const handleNext = () => {\r\n const nextIndex = currentStepIndex + 1;\r\n if (nextIndex < steps.length) {\r\n setCurrentStep(steps[nextIndex].key);\r\n }\r\n };\r\n\r\n const handleBack = () => {\r\n const prevIndex = currentStepIndex - 1;\r\n if (prevIndex >= 0) {\r\n setCurrentStep(steps[prevIndex].key);\r\n }\r\n };\r\n\r\n const handleComplete = async () => {\r\n setIsSubmitting(true);\r\n setError(null);\r\n\r\n try {\r\n await api.post('/api/onboarding/complete', {\r\n language: selectedLanguage,\r\n theme: selectedTheme,\r\n accentColorKey: selectedAccentColor,\r\n });\r\n\r\n // Save preferences locally\r\n localStorage.setItem('i18nextLng', selectedLanguage);\r\n localStorage.setItem(\r\n 'smartstack-theme-config',\r\n JSON.stringify({\r\n mode: selectedTheme,\r\n accentColorKey: selectedAccentColor,\r\n borderRadius: {},\r\n itemPaletteKey: 'neutral',\r\n })\r\n );\r\n\r\n setSuccess(true);\r\n\r\n // Redirect after success animation\r\n setTimeout(() => {\r\n window.location.href = '/myspace';\r\n }, 2000);\r\n } catch (err) {\r\n console.error('Onboarding error:', err);\r\n setError(t('onboarding.errorMessage'));\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n };\r\n\r\n if (success) {\r\n return (\r\n <div className=\"min-h-screen flex items-center justify-center bg-[var(--bg-primary)]\">\r\n <div className=\"max-w-md w-full mx-4\">\r\n <div className=\"bg-[var(--bg-secondary)] rounded-2xl p-8 shadow-lg border border-[var(--border-color)]\">\r\n <div className=\"text-center\">\r\n <div className=\"w-20 h-20 mx-auto bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center mb-6\">\r\n <CheckCircle className=\"w-12 h-12 text-green-600 dark:text-green-400\" />\r\n </div>\r\n <h2 className=\"text-2xl font-bold mb-3\">{t('onboarding.successTitle')}</h2>\r\n <p className=\"text-[var(--text-secondary)]\">{t('onboarding.successMessage')}</p>\r\n <div className=\"mt-6\">\r\n <Loader2 className=\"w-6 h-6 mx-auto text-[var(--color-accent-500)] animate-spin\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"min-h-screen flex items-center justify-center bg-[var(--bg-primary)] p-4\">\r\n <div className=\"max-w-lg w-full\">\r\n {/* Header */}\r\n <div className=\"text-center mb-8\">\r\n <div className=\"flex items-center justify-center gap-2 mb-4\">\r\n <div className=\"w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center\">\r\n <span className=\"text-white text-xl font-bold\">S</span>\r\n </div>\r\n </div>\r\n <h1 className=\"text-3xl font-bold mb-2\">{t('onboarding.title')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('onboarding.subtitle')}</p>\r\n </div>\r\n\r\n {/* Steps indicator */}\r\n <div className=\"flex justify-center mb-8\">\r\n <div className=\"flex items-center gap-2\">\r\n {steps.map((step, index) => (\r\n <div key={step.key} className=\"flex items-center\">\r\n <div\r\n className={`w-10 h-10 rounded-full flex items-center justify-center transition-all ${\r\n index <= currentStepIndex\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}\r\n >\r\n {step.icon}\r\n </div>\r\n {index < steps.length - 1 && (\r\n <div\r\n className={`w-12 h-1 mx-1 rounded transition-all ${\r\n index < currentStepIndex\r\n ? 'bg-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n />\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Card */}\r\n <div className=\"bg-[var(--bg-secondary)] rounded-2xl p-8 shadow-lg border border-[var(--border-color)]\">\r\n {/* Language Step */}\r\n {currentStep === 'language' && (\r\n <div>\r\n <h2 className=\"text-xl font-semibold mb-6 text-center\">{t('onboarding.languageLabel')}</h2>\r\n <div className=\"grid grid-cols-2 gap-4\">\r\n {languages.map((lang) => (\r\n <button\r\n key={lang.code}\r\n onClick={() => setSelectedLanguage(lang.code)}\r\n className={`p-4 rounded-xl border-2 transition-all ${\r\n selectedLanguage === lang.code\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-300)]'\r\n }`}\r\n >\r\n <span className=\"text-3xl mb-2 block\">{lang.flag}</span>\r\n <span className=\"font-medium\">{lang.name}</span>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Theme Step */}\r\n {currentStep === 'theme' && (\r\n <div>\r\n <h2 className=\"text-xl font-semibold mb-6 text-center\">{t('onboarding.themeLabel')}</h2>\r\n\r\n {/* Theme selection */}\r\n <div className=\"grid grid-cols-3 gap-3 mb-8\">\r\n {themes.map((theme) => (\r\n <button\r\n key={theme.value}\r\n onClick={() => setSelectedTheme(theme.value)}\r\n className={`p-4 rounded-xl border-2 transition-all ${\r\n selectedTheme === theme.value\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-300)]'\r\n }`}\r\n >\r\n <span className=\"text-2xl mb-2 block\">{theme.icon}</span>\r\n <span className=\"text-sm font-medium\">{t(`onboarding.${theme.labelKey}`)}</span>\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Accent color selection */}\r\n <div>\r\n <h3 className=\"text-sm font-medium mb-3 text-[var(--text-secondary)]\">\r\n {t('onboarding.accentColorLabel')}\r\n </h3>\r\n <div className=\"flex justify-center gap-3\">\r\n {accentColors.map((color) => (\r\n <button\r\n key={color.key}\r\n onClick={() => setSelectedAccentColor(color.key)}\r\n className={`w-10 h-10 rounded-full transition-all ${\r\n selectedAccentColor === color.key\r\n ? 'ring-2 ring-offset-2 ring-[var(--color-accent-500)] ring-offset-[var(--bg-secondary)]'\r\n : 'hover:scale-110'\r\n }`}\r\n style={{ backgroundColor: color.color }}\r\n title={color.name}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Complete Step */}\r\n {currentStep === 'complete' && (\r\n <div className=\"text-center\">\r\n <div className=\"w-20 h-20 mx-auto bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30 rounded-full flex items-center justify-center mb-6\">\r\n <Sparkles className=\"w-10 h-10 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <h2 className=\"text-xl font-semibold mb-4\">{t('onboarding.stepComplete')}</h2>\r\n <div className=\"text-[var(--text-secondary)] mb-6 space-y-2\">\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <Globe className=\"w-4 h-4\" />\r\n {languages.find((l) => l.code === selectedLanguage)?.name}\r\n </span>\r\n </p>\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <Palette className=\"w-4 h-4\" />\r\n {themes.find((t) => t.value === selectedTheme)?.icon}{' '}\r\n {t(`onboarding.${themes.find((th) => th.value === selectedTheme)?.labelKey}`)}\r\n </span>\r\n </p>\r\n <p>\r\n <span className=\"inline-flex items-center gap-2\">\r\n <span\r\n className=\"w-4 h-4 rounded-full\"\r\n style={{ backgroundColor: accentColors.find((c) => c.key === selectedAccentColor)?.color }}\r\n />\r\n {accentColors.find((c) => c.key === selectedAccentColor)?.name}\r\n </span>\r\n </p>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 rounded-lg p-3 mb-4 text-sm\">\r\n {error}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Navigation buttons */}\r\n <div className=\"flex justify-between mt-8\">\r\n {currentStepIndex > 0 ? (\r\n <button\r\n onClick={handleBack}\r\n className=\"flex items-center gap-2 px-4 py-2 text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-4 h-4\" />\r\n {t('onboarding.back')}\r\n </button>\r\n ) : (\r\n <div />\r\n )}\r\n\r\n {currentStep === 'complete' ? (\r\n <button\r\n onClick={handleComplete}\r\n disabled={isSubmitting}\r\n className=\"flex items-center gap-2 px-6 py-2 bg-[var(--color-accent-500)] hover:bg-[var(--color-accent-600)] text-white rounded-lg font-medium transition-colors disabled:opacity-50\"\r\n >\r\n {isSubmitting ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n {t('onboarding.completing')}\r\n </>\r\n ) : (\r\n <>\r\n {t('onboarding.complete')}\r\n <CheckCircle className=\"w-4 h-4\" />\r\n </>\r\n )}\r\n </button>\r\n ) : (\r\n <button\r\n onClick={handleNext}\r\n className=\"flex items-center gap-2 px-6 py-2 bg-[var(--color-accent-500)] hover:bg-[var(--color-accent-600)] text-white rounded-lg font-medium transition-colors\"\r\n >\r\n {t('onboarding.continue')}\r\n <ArrowRight className=\"w-4 h-4\" />\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["languages","themes","accentColors","OnboardingWizardPage","t","i18n","useTranslation","navigate","useNavigate","currentStep","setCurrentStep","useState","selectedLanguage","setSelectedLanguage","selectedTheme","setSelectedTheme","selectedAccentColor","setSelectedAccentColor","isSubmitting","setIsSubmitting","error","setError","success","setSuccess","useEffect","api","changeLanguage","steps","jsx","Globe","Palette","Sparkles","currentStepIndex","s","handleNext","nextIndex","handleBack","prevIndex","handleComplete","err","jsxs","CheckCircle","Loader2","step","index","lang","theme","color","l","th","c","ArrowLeft","Fragment","ArrowRight"],"mappings":"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"}
|