@atlashub/smartstack 3.30.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-CVq3qZoe.js → AgentSkillsPage-CDMhqrhE.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-CVq3qZoe.js.map → AgentSkillsPage-CDMhqrhE.js.map} +1 -1
- package/dist/chunks/{AgentSkillsPage-DJb49NMA.js → AgentSkillsPage-DcvOMm5k.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-DJb49NMA.js.map → AgentSkillsPage-DcvOMm5k.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-D_nk3gKj.js → AgentWorkloadPage-DYBPNzjQ.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-D_nk3gKj.js.map → AgentWorkloadPage-DYBPNzjQ.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-oHEi-sFh.js → AgentWorkloadPage-YpJSDaWc.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-oHEi-sFh.js.map → AgentWorkloadPage-YpJSDaWc.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-Cr0q2HnB.js → ApiCatalogDetailPage-9r1axtCg.js} +3 -3
- package/dist/chunks/{ApiCatalogDetailPage-Cr0q2HnB.js.map → ApiCatalogDetailPage-9r1axtCg.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-DX8buBkV.js → ApiCatalogDetailPage-TjCQ8_A8.js} +2 -2
- package/dist/chunks/{ApiCatalogDetailPage-DX8buBkV.js.map → ApiCatalogDetailPage-TjCQ8_A8.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-DqboIzZE.js → ApiCatalogPage-COxazTnz.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-DqboIzZE.js.map → ApiCatalogPage-COxazTnz.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-DN7sazvI.js → ApiCatalogPage-QRysH0pT.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-DN7sazvI.js.map → ApiCatalogPage-QRysH0pT.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-CCNjr64K.js → ApplicationDetailPage-Dbx01Ikm.js} +4 -4
- package/dist/chunks/{ApplicationDetailPage-CCNjr64K.js.map → ApplicationDetailPage-Dbx01Ikm.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage--9YwwS5A.js → ApplicationDetailPage-jSHy3MPz.js} +2 -2
- package/dist/chunks/{ApplicationDetailPage--9YwwS5A.js.map → ApplicationDetailPage-jSHy3MPz.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-Bs-Xgca4.js → ApplicationsDashboardPage-CclKc0wI.js} +3 -3
- package/dist/chunks/{ApplicationsDashboardPage-Bs-Xgca4.js.map → ApplicationsDashboardPage-CclKc0wI.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-BSsHN3Yj.js → ApplicationsDashboardPage-CxWmOc1x.js} +2 -2
- package/dist/chunks/{ApplicationsDashboardPage-BSsHN3Yj.js.map → ApplicationsDashboardPage-CxWmOc1x.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-s1WEzOXS.js → ApplicationsGridPage-BJXWXwyI.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-s1WEzOXS.js.map → ApplicationsGridPage-BJXWXwyI.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-DDysNWJ5.js → ApplicationsGridPage-D2l8cM3o.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-DDysNWJ5.js.map → ApplicationsGridPage-D2l8cM3o.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-B3CSMiV0.js → ApplicationsListPage-CMosl3my.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-B3CSMiV0.js.map → ApplicationsListPage-CMosl3my.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-B6ZCecIl.js → ApplicationsListPage-Dc6NGQ61.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-B6ZCecIl.js.map → ApplicationsListPage-Dc6NGQ61.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-BBaiBM--.js → ApplicationsPage-DH7tpMlF.js} +2 -2
- package/dist/chunks/{ApplicationsPage-BBaiBM--.js.map → ApplicationsPage-DH7tpMlF.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-ztPwoAGt.js → ApplicationsPage-DI-iMqoJ.js} +4 -4
- package/dist/chunks/{ApplicationsPage-ztPwoAGt.js.map → ApplicationsPage-DI-iMqoJ.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-DFSVFFXr.js → AssignmentRulesPage-B5UbujbZ.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-DFSVFFXr.js.map → AssignmentRulesPage-B5UbujbZ.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-CK4L4rBO.js → AssignmentRulesPage-E79QBSLb.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-CK4L4rBO.js.map → AssignmentRulesPage-E79QBSLb.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-JCLpyg94.js → AssignmentsPage-CDFaL1gT.js} +2 -2
- package/dist/chunks/{AssignmentsPage-JCLpyg94.js.map → AssignmentsPage-CDFaL1gT.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-Bp7oQD7Q.js → AssignmentsPage-CPeKJjyK.js} +2 -2
- package/dist/chunks/{AssignmentsPage-Bp7oQD7Q.js.map → AssignmentsPage-CPeKJjyK.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-Bl9xlJ3h.js → AuthCallbackPage-BZ3Ocos5.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-Bl9xlJ3h.js.map → AuthCallbackPage-BZ3Ocos5.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-CzMHz4jy.js → AuthCallbackPage-Bml48QpH.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-CzMHz4jy.js.map → AuthCallbackPage-Bml48QpH.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-M7mJgXvn.js → ConfirmEmailPage-DP1XPaKK.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-M7mJgXvn.js.map → ConfirmEmailPage-DP1XPaKK.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-D_8T1vqV.js → ConfirmEmailPage-DyzslZ06.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-D_8T1vqV.js.map → ConfirmEmailPage-DyzslZ06.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-BNEGavlu.js → CreateSupportTicketPage-Bz2KrMik.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-BNEGavlu.js.map → CreateSupportTicketPage-Bz2KrMik.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-C2X2mfds.js → CreateSupportTicketPage-hKjKM0Bh.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-C2X2mfds.js.map → CreateSupportTicketPage-hKjKM0Bh.js.map} +1 -1
- package/dist/chunks/{DashboardPage-4oy2YqvT.js → DashboardPage-B4nAd8Tj.js} +2 -2
- package/dist/chunks/{DashboardPage-4oy2YqvT.js.map → DashboardPage-B4nAd8Tj.js.map} +1 -1
- package/dist/chunks/{DashboardPage-D5MRMxEV.js → DashboardPage-C9qgPBS-.js} +3 -3
- package/dist/chunks/{DashboardPage-D5MRMxEV.js.map → DashboardPage-C9qgPBS-.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CO-8B8EI.js → DashboardPage-CjbNGMo1.js} +3 -3
- package/dist/chunks/{DashboardPage-CO-8B8EI.js.map → DashboardPage-CjbNGMo1.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CPArUG-S.js → DashboardPage-rN7IFlTR.js} +2 -2
- package/dist/chunks/{DashboardPage-CPArUG-S.js.map → DashboardPage-rN7IFlTR.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-DnjLFXnL.js → EscalationConfigPage-CGv2L62M.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-DnjLFXnL.js.map → EscalationConfigPage-CGv2L62M.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-CwdnfJbJ.js → EscalationConfigPage-DpYDmsgw.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-CwdnfJbJ.js.map → EscalationConfigPage-DpYDmsgw.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-ZEIfyqwE.js → ForceChangePasswordPage-CLI_fpF4.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-ZEIfyqwE.js.map → ForceChangePasswordPage-CLI_fpF4.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-sh-3h_H9.js → ForceChangePasswordPage-Db6sOrZN.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-sh-3h_H9.js.map → ForceChangePasswordPage-Db6sOrZN.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-B4M6-xeM.js → ForgotPasswordPage-BhMz2B6A.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-B4M6-xeM.js.map → ForgotPasswordPage-BhMz2B6A.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-MIu-U7p0.js → ForgotPasswordPage-D06arMXO.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-MIu-U7p0.js.map → ForgotPasswordPage-D06arMXO.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-4XK3Bs_r.js → GroupDetailPage-BCM8KBCd.js} +5 -5
- package/dist/chunks/{GroupDetailPage-4XK3Bs_r.js.map → GroupDetailPage-BCM8KBCd.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-C-kvtd2T.js → GroupDetailPage-CGMV3bWt.js} +2 -2
- package/dist/chunks/{GroupDetailPage-C-kvtd2T.js.map → GroupDetailPage-CGMV3bWt.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-CP41FzHi.js → MyAccessRequestsPage-BBrwEomx.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-CP41FzHi.js.map → MyAccessRequestsPage-BBrwEomx.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-DzrXTrVi.js → MyAccessRequestsPage-CrlWe3gd.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-DzrXTrVi.js.map → MyAccessRequestsPage-CrlWe3gd.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-V_SwYio2.js → MyTenantsPage-BOV34_rJ.js} +3 -3
- package/dist/chunks/{MyTenantsPage-V_SwYio2.js.map → MyTenantsPage-BOV34_rJ.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-CZRkMbh8.js → MyTenantsPage-CK4-klmd.js} +2 -2
- package/dist/chunks/{MyTenantsPage-CZRkMbh8.js.map → MyTenantsPage-CK4-klmd.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-DnvAIeyr.js → MyTicketsPage-CFZ1G4dG.js} +2 -2
- package/dist/chunks/{MyTicketsPage-DnvAIeyr.js.map → MyTicketsPage-CFZ1G4dG.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-DOUhaLal.js → MyTicketsPage-DuhpwhZx.js} +2 -2
- package/dist/chunks/{MyTicketsPage-DOUhaLal.js.map → MyTicketsPage-DuhpwhZx.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-DfTa4jCG.js → NavigationAppsPage-BnNQRfBP.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-DfTa4jCG.js.map → NavigationAppsPage-BnNQRfBP.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-DXvpLsbt.js → NavigationAppsPage-DdJxEoTZ.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-DXvpLsbt.js.map → NavigationAppsPage-DdJxEoTZ.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-I1yCk7tk.js → NotificationsPage-BllOlagk.js} +2 -2
- package/dist/chunks/{NotificationsPage-I1yCk7tk.js.map → NotificationsPage-BllOlagk.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-D76MdAs-.js → NotificationsPage-D1T_ozHl.js} +2 -2
- package/dist/chunks/{NotificationsPage-D76MdAs-.js.map → NotificationsPage-D1T_ozHl.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-BRUzcl1A.js → OnboardingWizardPage-CioLaCYz.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-BRUzcl1A.js.map → OnboardingWizardPage-CioLaCYz.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-DtWUPCh3.js → OnboardingWizardPage-CrAQt7qL.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-DtWUPCh3.js.map → OnboardingWizardPage-CrAQt7qL.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-CUNKbl7t.js → PermissionDetailPage-BIG78-1-.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-CUNKbl7t.js.map → PermissionDetailPage-BIG78-1-.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-DJJGbXoX.js → PermissionDetailPage-CvPqugYu.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-DJJGbXoX.js.map → PermissionDetailPage-CvPqugYu.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-B8wmawPV.js → PermissionsPage-CDSuc8vw.js} +2 -2
- package/dist/chunks/{PermissionsPage-B8wmawPV.js.map → PermissionsPage-CDSuc8vw.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-Dbjcctuh.js → PermissionsPage-XaOrGrPZ.js} +2 -2
- package/dist/chunks/{PermissionsPage-Dbjcctuh.js.map → PermissionsPage-XaOrGrPZ.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-BeNfBZmb.js → PortalDashboardPage-BsWVXkMe.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-BeNfBZmb.js.map → PortalDashboardPage-BsWVXkMe.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-zii0ll57.js → PortalDashboardPage-oSD7oQhJ.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-zii0ll57.js.map → PortalDashboardPage-oSD7oQhJ.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-BCpuIGzv.js → PreferencesPage-DD0_XWdT.js} +2 -2
- package/dist/chunks/{PreferencesPage-BCpuIGzv.js.map → PreferencesPage-DD0_XWdT.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-BmvrBaAD.js → PreferencesPage-ca2BOdoH.js} +2 -2
- package/dist/chunks/{PreferencesPage-BmvrBaAD.js.map → PreferencesPage-ca2BOdoH.js.map} +1 -1
- package/dist/chunks/{ProfilePage-mf5wI0-n.js → ProfilePage-Bex_JN5N.js} +2 -2
- package/dist/chunks/{ProfilePage-mf5wI0-n.js.map → ProfilePage-Bex_JN5N.js.map} +1 -1
- package/dist/chunks/{ProfilePage-eowQd59_.js → ProfilePage-C8tUIOnb.js} +2 -2
- package/dist/chunks/{ProfilePage-eowQd59_.js.map → ProfilePage-C8tUIOnb.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-CLsaUNqA.js → ReferencesManagementPage-B-FXS2ln.js} +2 -2
- package/dist/chunks/{ReferencesManagementPage-CLsaUNqA.js.map → ReferencesManagementPage-B-FXS2ln.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-8UPgkVE8.js → ReferencesManagementPage-C8KZprkI.js} +3 -3
- package/dist/chunks/{ReferencesManagementPage-8UPgkVE8.js.map → ReferencesManagementPage-C8KZprkI.js.map} +1 -1
- package/dist/chunks/{RegisterPage-CNyHSbqs.js → RegisterPage-BYt__zKJ.js} +2 -2
- package/dist/chunks/{RegisterPage-CNyHSbqs.js.map → RegisterPage-BYt__zKJ.js.map} +1 -1
- package/dist/chunks/{RegisterPage-57X-ILDb.js → RegisterPage-MWcVu-LY.js} +2 -2
- package/dist/chunks/{RegisterPage-57X-ILDb.js.map → RegisterPage-MWcVu-LY.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-CyV8l-Zo.js → ResetPasswordPage-DaJiMj5Z.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-CyV8l-Zo.js.map → ResetPasswordPage-DaJiMj5Z.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-JW8-mh_k.js → ResetPasswordPage-rCLUIj_T.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-JW8-mh_k.js.map → ResetPasswordPage-rCLUIj_T.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-CjwE73NX.js → ResolutionModal-DeuPnLWg.js} +2 -2
- package/dist/chunks/{ResolutionModal-CjwE73NX.js.map → ResolutionModal-DeuPnLWg.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-wddG59kg.js → ResolutionModal-j7Rp6apG.js} +2 -2
- package/dist/chunks/{ResolutionModal-wddG59kg.js.map → ResolutionModal-j7Rp6apG.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-CrioVHFI.js → RoleDetailPage-CLtZWX17.js} +3 -3
- package/dist/chunks/{RoleDetailPage-CrioVHFI.js.map → RoleDetailPage-CLtZWX17.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-TUOGR1ow.js → RoleDetailPage-TGyGmLMM.js} +2 -2
- package/dist/chunks/{RoleDetailPage-TUOGR1ow.js.map → RoleDetailPage-TGyGmLMM.js.map} +1 -1
- package/dist/chunks/{RolesPage-sJBWaNff.js → RolesPage-C0c5G9e7.js} +2 -2
- package/dist/chunks/{RolesPage-sJBWaNff.js.map → RolesPage-C0c5G9e7.js.map} +1 -1
- package/dist/chunks/{RolesPage-CAcols3D.js → RolesPage-Dm03fBBf.js} +2 -2
- package/dist/chunks/{RolesPage-CAcols3D.js.map → RolesPage-Dm03fBBf.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-BPGRloOS.js → SlaConfigPage-B4WDzEKi.js} +2 -2
- package/dist/chunks/{SlaConfigPage-BPGRloOS.js.map → SlaConfigPage-B4WDzEKi.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-D5TRn7Ir.js → SlaConfigPage-Cwo9NwxH.js} +2 -2
- package/dist/chunks/{SlaConfigPage-D5TRn7Ir.js.map → SlaConfigPage-Cwo9NwxH.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-UXmYLrIq.js → SupportPermissionsPage-CL12dFy-.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-UXmYLrIq.js.map → SupportPermissionsPage-CL12dFy-.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-Dc2bWTzG.js → SupportPermissionsPage-CneIhl30.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-Dc2bWTzG.js.map → SupportPermissionsPage-CneIhl30.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-nTY85sNA.js → TemplatesPage-DStKmwHT.js} +2 -2
- package/dist/chunks/{TemplatesPage-nTY85sNA.js.map → TemplatesPage-DStKmwHT.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-dmPlqqiD.js → TemplatesPage-X4Rrhs9p.js} +2 -2
- package/dist/chunks/{TemplatesPage-dmPlqqiD.js.map → TemplatesPage-X4Rrhs9p.js.map} +1 -1
- package/dist/chunks/{TenantCard-BhT-31ls.js → TenantCard-BUBYWtvR.js} +2 -2
- package/dist/chunks/{TenantCard-BhT-31ls.js.map → TenantCard-BUBYWtvR.js.map} +1 -1
- package/dist/chunks/{TenantCard-BUXfstRZ.js → TenantCard-CAgiB-NG.js} +2 -2
- package/dist/chunks/{TenantCard-BUXfstRZ.js.map → TenantCard-CAgiB-NG.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-3_mzBLNI.js → TenantScopeSelector-B9vtpIZx.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-3_mzBLNI.js.map → TenantScopeSelector-B9vtpIZx.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-B-SRDR2R.js → TenantScopeSelector-BAoah-mL.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-B-SRDR2R.js.map → TenantScopeSelector-BAoah-mL.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-xN3wPnFL.js → TicketDetailPage-BFcP4X8s.js} +2 -2
- package/dist/chunks/{TicketDetailPage-xN3wPnFL.js.map → TicketDetailPage-BFcP4X8s.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-B4cR3rOC.js → TicketDetailPage-D_Npnt4A.js} +2 -2
- package/dist/chunks/{TicketDetailPage-B4cR3rOC.js.map → TicketDetailPage-D_Npnt4A.js.map} +1 -1
- package/dist/chunks/{TicketsPage-Dwi2xpMI.js → TicketsPage-DBP9kalU.js} +2 -2
- package/dist/chunks/{TicketsPage-Dwi2xpMI.js.map → TicketsPage-DBP9kalU.js.map} +1 -1
- package/dist/chunks/{TicketsPage-CkHgXSxU.js → TicketsPage-p21DLhUb.js} +2 -2
- package/dist/chunks/{TicketsPage-CkHgXSxU.js.map → TicketsPage-p21DLhUb.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-D2a3EOey.js → UserCreateTicketPage-DOwShnG8.js} +2 -2
- package/dist/chunks/{UserCreateTicketPage-D2a3EOey.js.map → UserCreateTicketPage-DOwShnG8.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-bcbSLglE.js → UserCreateTicketPage-lvlvp2u6.js} +2 -2
- package/dist/chunks/{UserCreateTicketPage-bcbSLglE.js.map → UserCreateTicketPage-lvlvp2u6.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-ZMsx8LWw.js → UserDashboardPage-C_tm7Pld.js} +2 -2
- package/dist/chunks/{UserDashboardPage-ZMsx8LWw.js.map → UserDashboardPage-C_tm7Pld.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-DwnDRNoW.js → UserDashboardPage-Dp6q6FEW.js} +2 -2
- package/dist/chunks/{UserDashboardPage-DwnDRNoW.js.map → UserDashboardPage-Dp6q6FEW.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-CZyV-zsg.js → UserDetailPage-6grZ6gmV.js} +5 -5
- package/dist/chunks/{UserDetailPage-CZyV-zsg.js.map → UserDetailPage-6grZ6gmV.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-BRFowOFL.js → UserDetailPage-DXLxO7LF.js} +2 -2
- package/dist/chunks/{UserDetailPage-BRFowOFL.js.map → UserDetailPage-DXLxO7LF.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-BstGk_BP.js → UserTicketDetailPage-Ch9IfCPo.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-BstGk_BP.js.map → UserTicketDetailPage-Ch9IfCPo.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-DzB_pELt.js → UserTicketDetailPage-a4II5VEE.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-DzB_pELt.js.map → UserTicketDetailPage-a4II5VEE.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-BygTv_kK.js → UsersGroupsPage-B7Er0V4l.js} +3 -3
- package/dist/chunks/{UsersGroupsPage-BygTv_kK.js.map → UsersGroupsPage-B7Er0V4l.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-DTmhzttW.js → UsersGroupsPage-BeAv4QfV.js} +2 -2
- package/dist/chunks/{UsersGroupsPage-DTmhzttW.js.map → UsersGroupsPage-BeAv4QfV.js.map} +1 -1
- package/dist/chunks/{UsersPage-DcwLyMAX.js → UsersPage-0M1FLqOe.js} +2 -2
- package/dist/chunks/{UsersPage-DcwLyMAX.js.map → UsersPage-0M1FLqOe.js.map} +1 -1
- package/dist/chunks/{UsersPage-TIqSHgHj.js → UsersPage-ZR9r9vvf.js} +2 -2
- package/dist/chunks/{UsersPage-TIqSHgHj.js.map → UsersPage-ZR9r9vvf.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-3FjMFbpa.js → accessRequestsApi-BJH8EE1K.js} +2 -2
- package/dist/chunks/{accessRequestsApi-3FjMFbpa.js.map → accessRequestsApi-BJH8EE1K.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-B6dsJzvH.js → accessRequestsApi-CBpF5d54.js} +2 -2
- package/dist/chunks/{accessRequestsApi-B6dsJzvH.js.map → accessRequestsApi-CBpF5d54.js.map} +1 -1
- package/dist/chunks/{aiApi-9G4wG_mT.js → aiApi-CkkWAvNB.js} +2 -2
- package/dist/chunks/{aiApi-9G4wG_mT.js.map → aiApi-CkkWAvNB.js.map} +1 -1
- package/dist/chunks/{aiApi-DXOdsoxr.js → aiApi-Dl7a2lWz.js} +2 -2
- package/dist/chunks/{aiApi-DXOdsoxr.js.map → aiApi-Dl7a2lWz.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-DhOd6idI.js → applicationAnalyticsApi-BwcSE_H1.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-DhOd6idI.js.map → applicationAnalyticsApi-BwcSE_H1.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-D0DEp9Y-.js → applicationAnalyticsApi-DKMmDvWk.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-D0DEp9Y-.js.map → applicationAnalyticsApi-DKMmDvWk.js.map} +1 -1
- package/dist/chunks/{groupsApi-Db8G2lLs.js → groupsApi-BzDV3_Jc.js} +2 -2
- package/dist/chunks/{groupsApi-Db8G2lLs.js.map → groupsApi-BzDV3_Jc.js.map} +1 -1
- package/dist/chunks/{groupsApi-lbxNsHFv.js → groupsApi-CQ4vFMdP.js} +2 -2
- package/dist/chunks/{groupsApi-lbxNsHFv.js.map → groupsApi-CQ4vFMdP.js.map} +1 -1
- package/dist/chunks/{index-DEtq-xUL.js → index-BBmMbSZV.js} +8 -8
- package/dist/chunks/{index-DEtq-xUL.js.map → index-BBmMbSZV.js.map} +1 -1
- package/dist/chunks/{index-D0HS542b.js → index-BLlESTfA.js} +2 -2
- package/dist/chunks/{index-D0HS542b.js.map → index-BLlESTfA.js.map} +1 -1
- package/dist/chunks/{index-DUS-tunb.js → index-BPMjxWVx.js} +2 -2
- package/dist/chunks/{index-DUS-tunb.js.map → index-BPMjxWVx.js.map} +1 -1
- package/dist/chunks/{index-TiWOcC0g.js → index-CEbwdURd.js} +2 -2
- package/dist/chunks/{index-TiWOcC0g.js.map → index-CEbwdURd.js.map} +1 -1
- package/dist/chunks/{index-DF93KQFR.js → index-CUZygY5Q.js} +2 -2
- package/dist/chunks/{index-DF93KQFR.js.map → index-CUZygY5Q.js.map} +1 -1
- package/dist/chunks/{index-BI2dc1FS.js → index-Ci1SqFiY.js} +2 -2
- package/dist/chunks/{index-BI2dc1FS.js.map → index-Ci1SqFiY.js.map} +1 -1
- package/dist/chunks/{index-CTGSmYvs.js → index-Cib93xtp.js} +2 -2
- package/dist/chunks/{index-CTGSmYvs.js.map → index-Cib93xtp.js.map} +1 -1
- package/dist/chunks/{index-DqbVFB1H.js → index-CoHIgn5H.js} +2 -2
- package/dist/chunks/{index-DqbVFB1H.js.map → index-CoHIgn5H.js.map} +1 -1
- package/dist/chunks/{index-CN2WRyg1.js → index-CpY95_ro.js} +294 -292
- package/dist/chunks/{index-CN2WRyg1.js.map → index-CpY95_ro.js.map} +1 -1
- package/dist/chunks/{index-DjC1u2hI.js → index-D-2xSu5W.js} +3 -3
- package/dist/chunks/{index-DjC1u2hI.js.map → index-D-2xSu5W.js.map} +1 -1
- package/dist/chunks/{index-Bn8HzILk.js → index-D18t9DhC.js} +4 -4
- package/dist/chunks/{index-Bn8HzILk.js.map → index-D18t9DhC.js.map} +1 -1
- package/dist/chunks/{index-cAikSVW0.js → index-DK5czlkn.js} +9 -9
- package/dist/chunks/{index-cAikSVW0.js.map → index-DK5czlkn.js.map} +1 -1
- package/dist/chunks/{index-DLekpNSE.js → index-DQd324n7.js} +2 -2
- package/dist/chunks/{index-DLekpNSE.js.map → index-DQd324n7.js.map} +1 -1
- package/dist/chunks/{index-CgtbaFf5.js → index-Dbq-x5H9.js} +2 -2
- package/dist/chunks/{index-CgtbaFf5.js.map → index-Dbq-x5H9.js.map} +1 -1
- package/dist/chunks/{index-xhRXN1Jq.js → index-Det9dEaQ.js} +2 -2
- package/dist/chunks/{index-xhRXN1Jq.js.map → index-Det9dEaQ.js.map} +1 -1
- package/dist/chunks/{index-HsAOBno4.js → index-bgT9XOKZ.js} +2 -2
- package/dist/chunks/{index-HsAOBno4.js.map → index-bgT9XOKZ.js.map} +1 -1
- package/dist/chunks/{index-CUICSveU.js → index-h7ZrwrQg.js} +2 -2
- package/dist/chunks/{index-CUICSveU.js.map → index-h7ZrwrQg.js.map} +1 -1
- package/dist/chunks/{index-DwqLhQ8S.js → index-k4USDz2P.js} +2 -2
- package/dist/chunks/{index-DwqLhQ8S.js.map → index-k4USDz2P.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-CHeS7oLt.js → tenantIconMap-7ihIWxAh.js} +2 -2
- package/dist/chunks/{tenantIconMap-CHeS7oLt.js.map → tenantIconMap-7ihIWxAh.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-__FKj6CN.js → tenantIconMap-Dk6K-UTE.js} +2 -2
- package/dist/chunks/{tenantIconMap-__FKj6CN.js.map → tenantIconMap-Dk6K-UTE.js.map} +1 -1
- package/dist/chunks/{ticketingApi-DF4RwD_6.js → ticketingApi-BCMKkzlv.js} +2 -2
- package/dist/chunks/{ticketingApi-DF4RwD_6.js.map → ticketingApi-BCMKkzlv.js.map} +1 -1
- package/dist/chunks/{ticketingApi-Cj239hYB.js → ticketingApi-Dwn7pl5z.js} +2 -2
- package/dist/chunks/{ticketingApi-Cj239hYB.js.map → ticketingApi-Dwn7pl5z.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-CFam8zFR.js → useAccessRequests-Du7CvowE.js} +3 -3
- package/dist/chunks/{useAccessRequests-CFam8zFR.js.map → useAccessRequests-Du7CvowE.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-CViOUwyF.js → useAccessRequests-gJ7yhWyi.js} +2 -2
- package/dist/chunks/{useAccessRequests-CViOUwyF.js.map → useAccessRequests-gJ7yhWyi.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-CslSQeBJ.js → useUserAccessRequests-5wWea2Jg.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-CslSQeBJ.js.map → useUserAccessRequests-5wWea2Jg.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-B-Cs6NX1.js → useUserAccessRequests-Bk_v8egy.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-B-Cs6NX1.js.map → useUserAccessRequests-Bk_v8egy.js.map} +1 -1
- package/dist/components/routing/ProtectedRoute.d.ts.map +1 -1
- package/dist/smartstack.cjs +1 -1
- package/dist/smartstack.js +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import { jsx as e, jsxs as o, Fragment as I } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState as k, useCallback as q, useEffect as Q } from "react";
|
|
3
3
|
import { useTranslation as j } from "react-i18next";
|
|
4
4
|
import { useNavigate as X, useLocation as Z, Outlet as _, useOutletContext as z } from "react-router-dom";
|
|
5
|
-
import { k as K, B as ee } from "./index-
|
|
5
|
+
import { k as K, B as ee } from "./index-CpY95_ro.js";
|
|
6
6
|
import { Loader2 as B, Settings as O, Upload as W, FileText as G, Clock as V, Save as R, RotateCcw as P, History as L, AlertTriangle as re, Shield as ae } from "lucide-react";
|
|
7
7
|
const M = [
|
|
8
8
|
{ id: "general", labelKey: "settings.tabs.general", icon: O, route: "/administration/configuration/settings/general" },
|
|
@@ -657,4 +657,4 @@ export {
|
|
|
657
657
|
me as LegalFileSettingsSection,
|
|
658
658
|
ie as SettingsPage
|
|
659
659
|
};
|
|
660
|
-
//# sourceMappingURL=index-
|
|
660
|
+
//# sourceMappingURL=index-CEbwdURd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-TiWOcC0g.js","sources":["../../src/pages/platform/administration/configuration/settings/SettingsPage.tsx","../../src/hooks/useSettingsSection.ts","../../src/components/platform/administration/settings/SettingsHistoryModal.tsx","../../src/pages/platform/administration/configuration/settings/GeneralSettingsSection.tsx","../../src/pages/platform/administration/configuration/settings/FileUploadSettingsSection.tsx","../../src/pages/platform/administration/configuration/settings/LegalFileSettingsSection.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate, useLocation, Outlet } from 'react-router-dom';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { Settings, Upload, FileText, Loader2 } from 'lucide-react';\r\nimport { adminApi, type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface TabConfig {\r\n id: string;\r\n labelKey: string;\r\n icon: React.ElementType;\r\n route: string;\r\n}\r\n\r\nconst TABS: TabConfig[] = [\r\n { id: 'general', labelKey: 'settings.tabs.general', icon: Settings, route: '/administration/configuration/settings/general' },\r\n { id: 'file-upload', labelKey: 'settings.tabs.fileUpload', icon: Upload, route: '/administration/configuration/settings/file-upload' },\r\n { id: 'legal-file', labelKey: 'settings.tabs.legalFile', icon: FileText, route: '/administration/configuration/settings/legal-file' }\r\n];\r\n\r\nexport function SettingsPage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n const location = useLocation();\r\n const [settings, setSettings] = useState<SettingViewModel[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n\r\n const loadSettings = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const result = await adminApi.settings.getAll();\r\n setSettings(result);\r\n } catch (err) {\r\n console.error('Failed to load settings:', err);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadSettings();\r\n }, [loadSettings]);\r\n\r\n const getCurrentTab = () => {\r\n const path = location.pathname;\r\n const tab = TABS.find(t => path.includes(t.id));\r\n return tab?.id || 'general';\r\n };\r\n\r\n const handleTabChange = (tabId: string) => {\r\n const tab = TABS.find(t => t.id === tabId);\r\n if (tab) {\r\n navigate(tab.route);\r\n }\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('settings.title', 'Settings') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('settings.title')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)] mt-1\">\r\n {t('settings.subtitle')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Tabs */}\r\n <div className=\"border-b border-[var(--border-color)]\">\r\n <nav className=\"-mb-px flex space-x-8\" aria-label=\"Tabs\">\r\n {TABS.map((tab) => {\r\n const Icon = tab.icon;\r\n const isActive = getCurrentTab() === tab.id;\r\n return (\r\n <button\r\n key={tab.id}\r\n onClick={() => handleTabChange(tab.id)}\r\n className={`\r\n group inline-flex items-center py-4 px-1 border-b-2 font-medium text-sm transition-colors\r\n ${isActive\r\n ? 'border-[var(--color-accent-500)] text-[var(--color-accent-600)]'\r\n : 'border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:border-[var(--border-color)]'\r\n }\r\n `}\r\n >\r\n <Icon className={`mr-2 h-5 w-5 ${isActive ? 'text-[var(--color-accent-500)]' : 'text-[var(--text-tertiary)] group-hover:text-[var(--text-secondary)]'}`} />\r\n {t(tab.labelKey)}\r\n </button>\r\n );\r\n })}\r\n </nav>\r\n </div>\r\n\r\n {/* Content */}\r\n <Outlet context={{ settings, refreshSettings: loadSettings }} />\r\n </div>\r\n );\r\n}\r\n\r\nexport default SettingsPage;\r\n","import { useState } from 'react';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { adminApi, type SettingViewModel, type SettingHistoryDto } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\nexport function useSettingsSection(): {\n settings: SettingViewModel[];\n editedValues: Record<string, string>;\n saving: string | null;\n historyModal: { category: string; key: string } | null;\n history: SettingHistoryDto[];\n loadingHistory: boolean;\n handleValueChange: (category: string, key: string, value: string) => void;\n hasChanges: (setting: SettingViewModel) => boolean;\n getDisplayValue: (setting: SettingViewModel) => string;\n getEditKey: (setting: SettingViewModel) => string;\n handleSave: (setting: SettingViewModel) => Promise<void>;\n handleReset: (setting: SettingViewModel) => Promise<void>;\n openHistory: (category: string, key: string) => Promise<void>;\n closeHistory: () => void;\n} {\r\n const { settings, refreshSettings } = useOutletContext<SettingsContext>();\r\n const [editedValues, setEditedValues] = useState<Record<string, string>>({});\r\n const [saving, setSaving] = useState<string | null>(null);\r\n const [historyModal, setHistoryModal] = useState<{ category: string; key: string } | null>(null);\r\n const [history, setHistory] = useState<SettingHistoryDto[]>([]);\r\n const [loadingHistory, setLoadingHistory] = useState(false);\r\n\r\n const handleValueChange = (category: string, key: string, value: string) => {\r\n setEditedValues(prev => ({\r\n ...prev,\r\n [`${category}.${key}`]: value\r\n }));\r\n };\r\n\r\n const hasChanges = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n return editedValues[editKey] !== undefined && editedValues[editKey] !== setting.value;\r\n };\r\n\r\n const getDisplayValue = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n return editedValues[editKey] ?? setting.value;\r\n };\r\n\r\n const getEditKey = (setting: SettingViewModel) => `${setting.category}.${setting.key}`;\r\n\r\n const handleSave = async (setting: SettingViewModel) => {\r\n const editKey = getEditKey(setting);\r\n const newValue = editedValues[editKey];\r\n if (newValue === undefined || newValue === setting.value) return;\r\n\r\n try {\r\n setSaving(editKey);\r\n await adminApi.settings.update(setting.category, setting.key, newValue);\r\n setEditedValues(prev => {\r\n const next = { ...prev };\r\n delete next[editKey];\r\n return next;\r\n });\r\n await refreshSettings();\r\n } catch (err) {\r\n console.error('Failed to save setting:', err);\r\n } finally {\r\n setSaving(null);\r\n }\r\n };\r\n\r\n const handleReset = async (setting: SettingViewModel) => {\r\n const editKey = getEditKey(setting);\r\n try {\r\n setSaving(editKey);\r\n await adminApi.settings.reset(setting.category, setting.key);\r\n setEditedValues(prev => {\r\n const next = { ...prev };\r\n delete next[editKey];\r\n return next;\r\n });\r\n await refreshSettings();\r\n } catch (err) {\r\n console.error('Failed to reset setting:', err);\r\n } finally {\r\n setSaving(null);\r\n }\r\n };\r\n\r\n const openHistory = async (category: string, key: string) => {\r\n setHistoryModal({ category, key });\r\n setLoadingHistory(true);\r\n try {\r\n const result = await adminApi.settings.getHistory(category, key);\r\n setHistory(result);\r\n } catch (err) {\r\n console.error('Failed to load history:', err);\r\n } finally {\r\n setLoadingHistory(false);\r\n }\r\n };\r\n\r\n const closeHistory = () => setHistoryModal(null);\r\n\r\n return {\r\n settings,\r\n editedValues,\r\n saving,\r\n historyModal,\r\n history,\r\n loadingHistory,\r\n handleValueChange,\r\n hasChanges,\r\n getDisplayValue,\r\n getEditKey,\r\n handleSave,\r\n handleReset,\r\n openHistory,\r\n closeHistory,\r\n };\r\n}\r\n\r\nexport type { SettingsContext };\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2 } from 'lucide-react';\r\nimport type { SettingHistoryDto } from '@/services/api/adminApi';\r\n\r\ninterface SettingsHistoryModalProps {\r\n readonly category: string;\r\n readonly settingKey: string;\r\n readonly history: SettingHistoryDto[];\r\n readonly loading: boolean;\r\n readonly onClose: () => void;\r\n}\r\n\r\nexport function SettingsHistoryModal({ category, settingKey, history, loading, onClose }: SettingsHistoryModalProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div className=\"fixed inset-0 z-50 overflow-y-auto\">\r\n <div className=\"flex items-center justify-center min-h-screen px-4\">\r\n <button type=\"button\" className=\"fixed inset-0 bg-black/50\" onClick={onClose} aria-label=\"Close modal\" />\r\n <div className=\"relative rounded-[var(--radius-card)] bg-[var(--bg-card)] shadow-xl max-w-2xl w-full p-6\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('settings.historyTitle', { key: `${category}.${settingKey}` })}\r\n </h3>\r\n\r\n {loading && (\r\n <div className=\"flex justify-center py-8\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n )}\r\n {!loading && history.length === 0 && (\r\n <p className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('settings.noHistory')}\r\n </p>\r\n )}\r\n {!loading && history.length > 0 && (\r\n <div className=\"space-y-3 max-h-96 overflow-y-auto\">\r\n {history.map((entry) => (\r\n <div key={entry.id} className=\"p-3 bg-[var(--bg-secondary)] rounded-lg\">\r\n <div className=\"flex justify-between text-sm\">\r\n <span className=\"text-[var(--text-secondary)]\">\r\n {entry.changedByUserName || t('settings.system')}\r\n </span>\r\n <span className=\"text-[var(--text-tertiary)]\">\r\n {new Date(entry.changedAt).toLocaleString()}\r\n </span>\r\n </div>\r\n <div className=\"mt-2 text-sm\">\r\n <span className=\"text-[var(--error-text)] line-through\">{entry.oldValue}</span>\r\n <span className=\"mx-2 text-[var(--text-tertiary)]\">→</span>\r\n <span className=\"text-[var(--success-text)]\">{entry.newValue}</span>\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"mt-6 flex justify-end\">\r\n <button\r\n onClick={onClose}\r\n className=\"px-4 py-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import type { ReactElement } from 'react';\nimport { useTranslation } from 'react-i18next';\r\nimport { Save, RotateCcw, Loader2, Clock, History, Settings as SettingsIcon } from 'lucide-react';\r\nimport type { SettingViewModel } from '@/services/api/adminApi';\r\nimport { useSettingsSection } from '@/hooks/useSettingsSection';\r\nimport { SettingsHistoryModal } from '@/components/platform/administration/settings/SettingsHistoryModal';\r\n\r\nexport function GeneralSettingsSection(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const {\r\n settings,\r\n saving,\r\n historyModal,\r\n history,\r\n loadingHistory,\r\n handleValueChange,\r\n hasChanges,\r\n getDisplayValue,\r\n getEditKey,\r\n handleSave,\r\n handleReset,\r\n openHistory,\r\n closeHistory,\r\n } = useSettingsSection();\r\n\r\n // Filter settings for Session and General categories\r\n const sessionSettings = settings.filter(s => s.category === 'Session');\r\n const generalSettings = settings.filter(s => s.category === 'General');\r\n\r\n const getSourceBadgeClass = (source: string): string => {\r\n if (source === 'Database') {\r\n return 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-600)]';\r\n }\r\n if (source === 'AppSettings') {\r\n return 'bg-purple-500/10 text-purple-600 dark:text-purple-400';\r\n }\r\n return 'bg-[var(--bg-secondary)] text-[var(--text-tertiary)]';\r\n };\r\n\r\n const getSettingInput = (setting: SettingViewModel, displayValue: string, isEditing: boolean): React.ReactNode => {\r\n if (setting.valueType === 'Bool') {\r\n return (\r\n <label className=\"relative inline-flex items-center cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={displayValue === 'true'}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.checked ? 'true' : 'false')}\r\n disabled={!setting.isEditable || isEditing}\r\n className=\"sr-only peer\"\r\n />\r\n <div className=\"w-11 h-6 bg-[var(--bg-tertiary)] peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-[var(--color-accent-500)]/30 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-[var(--border-color)] after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-[var(--color-accent-600)] peer-disabled:opacity-50 peer-disabled:cursor-not-allowed\"></div>\r\n </label>\r\n );\r\n }\r\n if (setting.valueType === 'Int' || setting.valueType === 'Decimal') {\r\n return (\r\n <input\r\n type=\"number\"\r\n value={displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing}\r\n className=\"w-24 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n );\r\n }\r\n return (\r\n <input\r\n type={setting.isSensitive ? 'password' : 'text'}\r\n value={setting.isSensitive ? '********' : displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing || setting.isSensitive}\r\n className=\"w-48 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n );\r\n };\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = getEditKey(setting);\r\n const isEditing = saving === editKey;\r\n const changed = hasChanges(setting);\r\n const displayValue = getDisplayValue(setting);\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-4 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`settings.keys.${setting.category}.${setting.key}`, setting.key)}\r\n </span>\r\n {!setting.isEditable && (\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--bg-secondary)] text-[var(--text-tertiary)] rounded\">\r\n {t('settings.readonly')}\r\n </span>\r\n )}\r\n <span className={`px-2 py-0.5 text-xs rounded ${getSourceBadgeClass(setting.source)}`}>\r\n {setting.source}\r\n </span>\r\n </div>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`settings.descriptions.${setting.category}.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n {setting.modifiedAt && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1 flex items-center gap-1\">\r\n <Clock className=\"w-3 h-3\" />\r\n {t('settings.modifiedBy', { user: setting.modifiedByUserName, date: new Date(setting.modifiedAt).toLocaleString() })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n {getSettingInput(setting, displayValue, isEditing)}\r\n\r\n {setting.isEditable && setting.source === 'Database' && (\r\n <>\r\n <button\r\n onClick={() => handleSave(setting)}\r\n disabled={!changed || isEditing}\r\n className=\"p-2 text-[var(--color-accent-600)] hover:bg-[var(--color-accent-500)]/10 rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('common.save')}\r\n >\r\n {isEditing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n </button>\r\n <button\r\n onClick={() => handleReset(setting)}\r\n disabled={setting.value === setting.defaultValue || isEditing}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('settings.resetToDefault')}\r\n >\r\n <RotateCcw className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n onClick={() => openHistory(setting.category, setting.key)}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n title={t('settings.viewHistory')}\r\n >\r\n <History className=\"w-4 h-4\" />\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Session Settings */}\r\n {sessionSettings.length > 0 && (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] overflow-hidden shadow-sm\">\r\n <div className=\"px-6 py-4 bg-gradient-to-r from-[var(--color-accent-500)]/10 to-[var(--color-accent-600)]/5 border-b border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--color-accent-500)]/20\">\r\n <Clock className=\"w-5 h-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('settings.sections.session')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('settings.sections.sessionDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {sessionSettings.map(renderSetting)}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* General Settings */}\r\n {generalSettings.length > 0 && (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] overflow-hidden shadow-sm\">\r\n <div className=\"px-6 py-4 bg-gradient-to-r from-[var(--color-accent-500)]/10 to-[var(--color-accent-600)]/5 border-b border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--color-accent-500)]/20\">\r\n <SettingsIcon className=\"w-5 h-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('settings.sections.general')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('settings.sections.generalDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {generalSettings.map(renderSetting)}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {sessionSettings.length === 0 && generalSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('settings.noSettings')}\r\n </div>\r\n )}\r\n\r\n {historyModal && (\r\n <SettingsHistoryModal\r\n category={historyModal.category}\r\n settingKey={historyModal.key}\r\n history={history}\r\n loading={loadingHistory}\r\n onClose={closeHistory}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default GeneralSettingsSection;\r\n","import type { ReactElement } from 'react';\nimport { useTranslation } from 'react-i18next';\r\nimport { Save, RotateCcw, Loader2, Upload, History, Clock } from 'lucide-react';\r\nimport type { SettingViewModel } from '@/services/api/adminApi';\r\nimport { useSettingsSection } from '@/hooks/useSettingsSection';\r\nimport { SettingsHistoryModal } from '@/components/platform/administration/settings/SettingsHistoryModal';\r\n\r\nexport function FileUploadSettingsSection(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const {\r\n settings,\r\n saving,\r\n historyModal,\r\n history,\r\n loadingHistory,\r\n handleValueChange,\r\n hasChanges,\r\n getDisplayValue,\r\n getEditKey,\r\n handleSave,\r\n handleReset,\r\n openHistory,\r\n closeHistory,\r\n } = useSettingsSection();\r\n\r\n // Filter settings for FileUpload category\r\n const fileUploadSettings = settings.filter(s => s.category === 'FileUpload');\r\n\r\n // Parse JSON extensions for display\r\n const parseExtensions = (value: string): string[] => {\r\n try {\r\n return JSON.parse(value);\r\n } catch {\r\n return [];\r\n }\r\n };\r\n\r\n const renderSettingInput = (setting: SettingViewModel, displayValue: string, isEditing: boolean) => {\r\n if (setting.valueType === 'Int') {\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"number\"\r\n value={displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing}\r\n className=\"w-24 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n {setting.key === 'MaxFileSizeMB' && (\r\n <span className=\"text-sm text-[var(--text-secondary)]\">MB</span>\r\n )}\r\n </div>\r\n );\r\n }\r\n return (\r\n <input\r\n type={setting.isSensitive ? 'password' : 'text'}\r\n value={setting.isSensitive ? '********' : displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing || setting.isSensitive}\r\n className=\"w-48 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n );\r\n };\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = getEditKey(setting);\r\n const isEditing = saving === editKey;\r\n const changed = hasChanges(setting);\r\n const displayValue = getDisplayValue(setting);\r\n\r\n // Special rendering for JSON arrays (extensions)\r\n if (setting.valueType === 'Json' && setting.key === 'AllowedExtensions') {\r\n const extensions = parseExtensions(displayValue);\r\n return (\r\n <div key={editKey} className=\"py-4 border-b border-[var(--border-color)] last:border-0\">\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`settings.keys.${setting.category}.${setting.key}`, setting.key)}\r\n </span>\r\n {!setting.isEditable && (\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--bg-secondary)] text-[var(--text-tertiary)] rounded\">\r\n {t('settings.readonly')}\r\n </span>\r\n )}\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--color-accent-500)]/10 text-[var(--color-accent-600)] rounded\">\r\n {setting.source}\r\n </span>\r\n </div>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`settings.descriptions.${setting.category}.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n </div>\r\n {setting.isEditable && setting.source === 'Database' && (\r\n <button\r\n onClick={() => openHistory(setting.category, setting.key)}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n title={t('settings.viewHistory')}\r\n >\r\n <History className=\"w-4 h-4\" />\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {extensions.map((ext) => (\r\n <span\r\n key={ext}\r\n className=\"px-3 py-1 bg-[var(--bg-secondary)] text-[var(--text-secondary)] rounded-full text-sm\"\r\n >\r\n {ext}\r\n </span>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-4 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`settings.keys.${setting.category}.${setting.key}`, setting.key)}\r\n </span>\r\n {!setting.isEditable && (\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--bg-secondary)] text-[var(--text-tertiary)] rounded\">\r\n {t('settings.readonly')}\r\n </span>\r\n )}\r\n <span className={`px-2 py-0.5 text-xs rounded ${\r\n setting.source === 'Database'\r\n ? 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-600)]'\r\n : setting.source === 'AppSettings'\r\n ? 'bg-purple-500/10 text-purple-600 dark:text-purple-400'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-tertiary)]'\r\n }`}>\r\n {setting.source}\r\n </span>\r\n </div>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`settings.descriptions.${setting.category}.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n {setting.modifiedAt && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1 flex items-center gap-1\">\r\n <Clock className=\"w-3 h-3\" />\r\n {t('settings.modifiedBy', { user: setting.modifiedByUserName, date: new Date(setting.modifiedAt).toLocaleString() })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n {renderSettingInput(setting, displayValue, isEditing)}\r\n\r\n {setting.isEditable && setting.source === 'Database' && (\r\n <>\r\n <button\r\n onClick={() => handleSave(setting)}\r\n disabled={!changed || isEditing}\r\n className=\"p-2 text-[var(--color-accent-600)] hover:bg-[var(--color-accent-500)]/10 rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('common.save')}\r\n >\r\n {isEditing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n </button>\r\n <button\r\n onClick={() => handleReset(setting)}\r\n disabled={setting.value === setting.defaultValue || isEditing}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('settings.resetToDefault')}\r\n >\r\n <RotateCcw className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n onClick={() => openHistory(setting.category, setting.key)}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n title={t('settings.viewHistory')}\r\n >\r\n <History className=\"w-4 h-4\" />\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] overflow-hidden shadow-sm\">\r\n <div className=\"px-6 py-4 bg-gradient-to-r from-[var(--color-accent-500)]/10 to-[var(--color-accent-600)]/5 border-b border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--color-accent-500)]/20\">\r\n <Upload className=\"w-5 h-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('settings.sections.fileUpload')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('settings.sections.fileUploadDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {fileUploadSettings.length > 0 ? (\r\n fileUploadSettings.map(renderSetting)\r\n ) : (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('settings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {historyModal && (\r\n <SettingsHistoryModal\r\n category={historyModal.category}\r\n settingKey={historyModal.key}\r\n history={history}\r\n loading={loadingHistory}\r\n onClose={closeHistory}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default FileUploadSettingsSection;\r\n","import { useState } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { Save, RotateCcw, Loader2, FileText, History, Clock, AlertTriangle, Shield } from 'lucide-react';\r\nimport { adminApi, type SettingViewModel, type SettingHistoryDto } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\nexport function LegalFileSettingsSection(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { settings, refreshSettings } = useOutletContext<SettingsContext>();\r\n const [editedValues, setEditedValues] = useState<Record<string, string>>({});\r\n const [saving, setSaving] = useState<string | null>(null);\r\n const [historyModal, setHistoryModal] = useState<{ category: string; key: string } | null>(null);\r\n const [history, setHistory] = useState<SettingHistoryDto[]>([]);\r\n const [loadingHistory, setLoadingHistory] = useState(false);\r\n\r\n // Filter settings for LegalFile category\r\n const legalFileSettings = settings.filter(s => s.category === 'LegalFile');\r\n\r\n const handleValueChange = (category: string, key: string, value: string) => {\r\n setEditedValues(prev => ({\r\n ...prev,\r\n [`${category}.${key}`]: value\r\n }));\r\n };\r\n\r\n const hasChanges = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n return editedValues[editKey] !== undefined && editedValues[editKey] !== setting.value;\r\n };\r\n\r\n const getDisplayValue = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n return editedValues[editKey] ?? setting.value;\r\n };\r\n\r\n const handleSave = async (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n const newValue = editedValues[editKey];\r\n if (newValue === undefined || newValue === setting.value) return;\r\n\r\n try {\r\n setSaving(editKey);\r\n await adminApi.settings.update(setting.category, setting.key, newValue);\r\n setEditedValues(prev => {\r\n const next = { ...prev };\r\n delete next[editKey];\r\n return next;\r\n });\r\n await refreshSettings();\r\n } catch (err) {\r\n console.error('Failed to save setting:', err);\r\n } finally {\r\n setSaving(null);\r\n }\r\n };\r\n\r\n const handleReset = async (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n try {\r\n setSaving(editKey);\r\n await adminApi.settings.reset(setting.category, setting.key);\r\n setEditedValues(prev => {\r\n const next = { ...prev };\r\n delete next[editKey];\r\n return next;\r\n });\r\n await refreshSettings();\r\n } catch (err) {\r\n console.error('Failed to reset setting:', err);\r\n } finally {\r\n setSaving(null);\r\n }\r\n };\r\n\r\n const openHistory = async (category: string, key: string) => {\r\n setHistoryModal({ category, key });\r\n setLoadingHistory(true);\r\n try {\r\n const result = await adminApi.settings.getHistory(category, key);\r\n setHistory(result);\r\n } catch (err) {\r\n console.error('Failed to load history:', err);\r\n } finally {\r\n setLoadingHistory(false);\r\n }\r\n };\r\n\r\n // Convert days to years for display\r\n const daysToYears = (days: number): string => {\r\n const years = Math.floor(days / 365);\r\n const remainingDays = days % 365;\r\n if (remainingDays === 0) {\r\n return `${years} ${t('settings.years')}`;\r\n }\r\n return `${years} ${t('settings.years')} ${remainingDays} ${t('settings.days')}`;\r\n };\r\n\r\n const getLegallyProtected = (setting: SettingViewModel): boolean => {\r\n return !setting.isEditable && (setting.key === 'RetentionDays' || setting.key === 'EnableWorm');\r\n };\r\n\r\n const renderSettingInput = (setting: SettingViewModel, displayValue: string, isEditing: boolean, handleValueChange: (category: string, key: string, value: string) => void) => {\r\n if (setting.valueType === 'Bool') {\r\n return (\r\n <label className=\"relative inline-flex cursor-pointer\">\r\n <span className=\"sr-only\">{setting.key}</span>\r\n <input\r\n type=\"checkbox\"\r\n checked={displayValue === 'true'}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.checked ? 'true' : 'false')}\r\n disabled={!setting.isEditable || isEditing}\r\n className=\"sr-only peer\"\r\n aria-label={setting.key}\r\n />\r\n <div className=\"w-11 h-6 bg-[var(--bg-tertiary)] peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-[var(--color-accent-500)]/30 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-[var(--border-color)] after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-[var(--color-accent-600)] peer-disabled:opacity-50 peer-disabled:cursor-not-allowed\"></div>\r\n </label>\r\n );\r\n }\r\n if (setting.valueType === 'Int') {\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"number\"\r\n value={displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing}\r\n className=\"w-24 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n {(setting.key === 'RetentionDays' || setting.key === 'ArchiveAfterDays') && (\r\n <span className=\"text-sm text-[var(--text-secondary)]\">\r\n ({daysToYears(parseInt(displayValue) || 0)})\r\n </span>\r\n )}\r\n </div>\r\n );\r\n }\r\n return (\r\n <input\r\n type={setting.isSensitive ? 'password' : 'text'}\r\n value={setting.isSensitive ? '********' : displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing || setting.isSensitive}\r\n className=\"w-48 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n );\r\n };\r\n\r\n const getSourceBadgeClass = (source: string): string => {\r\n if (source === 'Database') return 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-600)]';\r\n if (source === 'AppSettings') return 'bg-purple-500/10 text-purple-600 dark:text-purple-400';\r\n return 'bg-[var(--bg-secondary)] text-[var(--text-tertiary)]';\r\n };\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n const isEditing = saving === editKey;\r\n const changed = hasChanges(setting);\r\n const displayValue = getDisplayValue(setting);\r\n const isLegallyProtected = getLegallyProtected(setting);\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className={`flex items-center justify-between py-4 border-b border-[var(--border-color)] last:border-0 ${\r\n isLegallyProtected ? 'bg-[var(--warning-bg)] -mx-6 px-6' : ''\r\n }`}\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`settings.keys.${setting.category}.${setting.key}`, setting.key)}\r\n </span>\r\n {isLegallyProtected && (\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)] rounded flex items-center gap-1\">\r\n <Shield className=\"w-3 h-3\" />\r\n {t('settings.legallyProtected')}\r\n </span>\r\n )}\r\n {!setting.isEditable && !isLegallyProtected && (\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--bg-secondary)] text-[var(--text-tertiary)] rounded\">\r\n {t('settings.readonly')}\r\n </span>\r\n )}\r\n <span className={`px-2 py-0.5 text-xs rounded ${getSourceBadgeClass(setting.source)}`}>\r\n {setting.source}\r\n </span>\r\n </div>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`settings.descriptions.${setting.category}.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n {setting.modifiedAt && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1 flex items-center gap-1\">\r\n <Clock className=\"w-3 h-3\" />\r\n {t('settings.modifiedBy', { user: setting.modifiedByUserName, date: new Date(setting.modifiedAt).toLocaleString() })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n {renderSettingInput(setting, displayValue, isEditing, handleValueChange)}\r\n\r\n {setting.isEditable && setting.source === 'Database' && (\r\n <>\r\n <button\r\n onClick={() => handleSave(setting)}\r\n disabled={!changed || isEditing}\r\n className=\"p-2 text-[var(--color-accent-600)] hover:bg-[var(--color-accent-500)]/10 rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('common.save')}\r\n >\r\n {isEditing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n </button>\r\n <button\r\n onClick={() => handleReset(setting)}\r\n disabled={setting.value === setting.defaultValue || isEditing}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('settings.resetToDefault')}\r\n >\r\n <RotateCcw className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n onClick={() => openHistory(setting.category, setting.key)}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n title={t('settings.viewHistory')}\r\n >\r\n <History className=\"w-4 h-4\" />\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Legal Warning Banner */}\r\n <div className=\"bg-[var(--warning-bg)] border border-[var(--warning-border)] rounded-[var(--radius-card)] p-4\">\r\n <div className=\"flex items-start gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--warning-text)] flex-shrink-0 mt-0.5\" />\r\n <div>\r\n <h4 className=\"font-medium text-[var(--warning-text)]\">\r\n {t('settings.legalWarningTitle')}\r\n </h4>\r\n <p className=\"text-sm text-[var(--warning-text)] opacity-90 mt-1\">\r\n {t('settings.legalWarningDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] overflow-hidden shadow-sm\">\r\n <div className=\"px-6 py-4 bg-gradient-to-r from-amber-500/10 to-amber-600/5 border-b border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-amber-500/20\">\r\n <FileText className=\"w-5 h-5 text-amber-600\" />\r\n </div>\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('settings.sections.legalFile')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('settings.sections.legalFileDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {legalFileSettings.length > 0 ? (\r\n legalFileSettings.map(renderSetting)\r\n ) : (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('settings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* History Modal */}\r\n {historyModal && (\r\n <div className=\"fixed inset-0 z-50 overflow-y-auto\">\r\n <div className=\"flex items-center justify-center min-h-screen px-4\">\r\n <button type=\"button\" className=\"fixed inset-0 bg-black/50\" onClick={() => setHistoryModal(null)} aria-label=\"Close modal\" />\r\n <div className=\"relative rounded-[var(--radius-card)] bg-[var(--bg-card)] shadow-xl max-w-2xl w-full p-6\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('settings.historyTitle', { key: `${historyModal.category}.${historyModal.key}` })}\r\n </h3>\r\n\r\n {loadingHistory && (\r\n <div className=\"flex justify-center py-8\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n )}\r\n {!loadingHistory && history.length === 0 && (\r\n <p className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('settings.noHistory')}\r\n </p>\r\n )}\r\n {!loadingHistory && history.length > 0 && (\r\n <div className=\"space-y-3 max-h-96 overflow-y-auto\">\r\n {history.map((entry) => (\r\n <div key={entry.id} className=\"p-3 bg-[var(--bg-secondary)] rounded-lg\">\r\n <div className=\"flex justify-between text-sm\">\r\n <span className=\"text-[var(--text-secondary)]\">\r\n {entry.changedByUserName || t('settings.system')}\r\n </span>\r\n <span className=\"text-[var(--text-tertiary)]\">\r\n {new Date(entry.changedAt).toLocaleString()}\r\n </span>\r\n </div>\r\n <div className=\"mt-2 text-sm\">\r\n <span className=\"text-[var(--error-text)] line-through\">{entry.oldValue}</span>\r\n <span className=\"mx-2 text-[var(--text-tertiary)]\">→</span>\r\n <span className=\"text-[var(--success-text)]\">{entry.newValue}</span>\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"mt-6 flex justify-end\">\r\n <button\r\n onClick={() => setHistoryModal(null)}\r\n className=\"px-4 py-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default LegalFileSettingsSection;\r\n"],"names":["TABS","Settings","Upload","FileText","SettingsPage","useTranslation","navigate","useNavigate","location","useLocation","settings","setSettings","useState","loading","setLoading","loadSettings","useCallback","result","adminApi","err","useEffect","getCurrentTab","path","t","handleTabChange","tabId","tab","jsx","Loader2","jsxs","Breadcrumb","Icon","isActive","Outlet","useSettingsSection","refreshSettings","useOutletContext","editedValues","setEditedValues","saving","setSaving","historyModal","setHistoryModal","history","setHistory","loadingHistory","setLoadingHistory","handleValueChange","category","key","value","prev","hasChanges","setting","editKey","getDisplayValue","getEditKey","newValue","next","SettingsHistoryModal","settingKey","onClose","entry","GeneralSettingsSection","handleSave","handleReset","openHistory","closeHistory","sessionSettings","generalSettings","getSourceBadgeClass","source","getSettingInput","displayValue","isEditing","e","renderSetting","changed","Clock","Fragment","Save","RotateCcw","History","SettingsIcon","FileUploadSettingsSection","fileUploadSettings","s","parseExtensions","renderSettingInput","extensions","ext","LegalFileSettingsSection","legalFileSettings","daysToYears","days","years","remainingDays","getLegallyProtected","isLegallyProtected","Shield","AlertTriangle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-CEbwdURd.js","sources":["../../src/pages/platform/administration/configuration/settings/SettingsPage.tsx","../../src/hooks/useSettingsSection.ts","../../src/components/platform/administration/settings/SettingsHistoryModal.tsx","../../src/pages/platform/administration/configuration/settings/GeneralSettingsSection.tsx","../../src/pages/platform/administration/configuration/settings/FileUploadSettingsSection.tsx","../../src/pages/platform/administration/configuration/settings/LegalFileSettingsSection.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate, useLocation, Outlet } from 'react-router-dom';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { Settings, Upload, FileText, Loader2 } from 'lucide-react';\r\nimport { adminApi, type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface TabConfig {\r\n id: string;\r\n labelKey: string;\r\n icon: React.ElementType;\r\n route: string;\r\n}\r\n\r\nconst TABS: TabConfig[] = [\r\n { id: 'general', labelKey: 'settings.tabs.general', icon: Settings, route: '/administration/configuration/settings/general' },\r\n { id: 'file-upload', labelKey: 'settings.tabs.fileUpload', icon: Upload, route: '/administration/configuration/settings/file-upload' },\r\n { id: 'legal-file', labelKey: 'settings.tabs.legalFile', icon: FileText, route: '/administration/configuration/settings/legal-file' }\r\n];\r\n\r\nexport function SettingsPage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n const location = useLocation();\r\n const [settings, setSettings] = useState<SettingViewModel[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n\r\n const loadSettings = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const result = await adminApi.settings.getAll();\r\n setSettings(result);\r\n } catch (err) {\r\n console.error('Failed to load settings:', err);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadSettings();\r\n }, [loadSettings]);\r\n\r\n const getCurrentTab = () => {\r\n const path = location.pathname;\r\n const tab = TABS.find(t => path.includes(t.id));\r\n return tab?.id || 'general';\r\n };\r\n\r\n const handleTabChange = (tabId: string) => {\r\n const tab = TABS.find(t => t.id === tabId);\r\n if (tab) {\r\n navigate(tab.route);\r\n }\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('settings.title', 'Settings') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('settings.title')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)] mt-1\">\r\n {t('settings.subtitle')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Tabs */}\r\n <div className=\"border-b border-[var(--border-color)]\">\r\n <nav className=\"-mb-px flex space-x-8\" aria-label=\"Tabs\">\r\n {TABS.map((tab) => {\r\n const Icon = tab.icon;\r\n const isActive = getCurrentTab() === tab.id;\r\n return (\r\n <button\r\n key={tab.id}\r\n onClick={() => handleTabChange(tab.id)}\r\n className={`\r\n group inline-flex items-center py-4 px-1 border-b-2 font-medium text-sm transition-colors\r\n ${isActive\r\n ? 'border-[var(--color-accent-500)] text-[var(--color-accent-600)]'\r\n : 'border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:border-[var(--border-color)]'\r\n }\r\n `}\r\n >\r\n <Icon className={`mr-2 h-5 w-5 ${isActive ? 'text-[var(--color-accent-500)]' : 'text-[var(--text-tertiary)] group-hover:text-[var(--text-secondary)]'}`} />\r\n {t(tab.labelKey)}\r\n </button>\r\n );\r\n })}\r\n </nav>\r\n </div>\r\n\r\n {/* Content */}\r\n <Outlet context={{ settings, refreshSettings: loadSettings }} />\r\n </div>\r\n );\r\n}\r\n\r\nexport default SettingsPage;\r\n","import { useState } from 'react';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { adminApi, type SettingViewModel, type SettingHistoryDto } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\nexport function useSettingsSection(): {\n settings: SettingViewModel[];\n editedValues: Record<string, string>;\n saving: string | null;\n historyModal: { category: string; key: string } | null;\n history: SettingHistoryDto[];\n loadingHistory: boolean;\n handleValueChange: (category: string, key: string, value: string) => void;\n hasChanges: (setting: SettingViewModel) => boolean;\n getDisplayValue: (setting: SettingViewModel) => string;\n getEditKey: (setting: SettingViewModel) => string;\n handleSave: (setting: SettingViewModel) => Promise<void>;\n handleReset: (setting: SettingViewModel) => Promise<void>;\n openHistory: (category: string, key: string) => Promise<void>;\n closeHistory: () => void;\n} {\r\n const { settings, refreshSettings } = useOutletContext<SettingsContext>();\r\n const [editedValues, setEditedValues] = useState<Record<string, string>>({});\r\n const [saving, setSaving] = useState<string | null>(null);\r\n const [historyModal, setHistoryModal] = useState<{ category: string; key: string } | null>(null);\r\n const [history, setHistory] = useState<SettingHistoryDto[]>([]);\r\n const [loadingHistory, setLoadingHistory] = useState(false);\r\n\r\n const handleValueChange = (category: string, key: string, value: string) => {\r\n setEditedValues(prev => ({\r\n ...prev,\r\n [`${category}.${key}`]: value\r\n }));\r\n };\r\n\r\n const hasChanges = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n return editedValues[editKey] !== undefined && editedValues[editKey] !== setting.value;\r\n };\r\n\r\n const getDisplayValue = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n return editedValues[editKey] ?? setting.value;\r\n };\r\n\r\n const getEditKey = (setting: SettingViewModel) => `${setting.category}.${setting.key}`;\r\n\r\n const handleSave = async (setting: SettingViewModel) => {\r\n const editKey = getEditKey(setting);\r\n const newValue = editedValues[editKey];\r\n if (newValue === undefined || newValue === setting.value) return;\r\n\r\n try {\r\n setSaving(editKey);\r\n await adminApi.settings.update(setting.category, setting.key, newValue);\r\n setEditedValues(prev => {\r\n const next = { ...prev };\r\n delete next[editKey];\r\n return next;\r\n });\r\n await refreshSettings();\r\n } catch (err) {\r\n console.error('Failed to save setting:', err);\r\n } finally {\r\n setSaving(null);\r\n }\r\n };\r\n\r\n const handleReset = async (setting: SettingViewModel) => {\r\n const editKey = getEditKey(setting);\r\n try {\r\n setSaving(editKey);\r\n await adminApi.settings.reset(setting.category, setting.key);\r\n setEditedValues(prev => {\r\n const next = { ...prev };\r\n delete next[editKey];\r\n return next;\r\n });\r\n await refreshSettings();\r\n } catch (err) {\r\n console.error('Failed to reset setting:', err);\r\n } finally {\r\n setSaving(null);\r\n }\r\n };\r\n\r\n const openHistory = async (category: string, key: string) => {\r\n setHistoryModal({ category, key });\r\n setLoadingHistory(true);\r\n try {\r\n const result = await adminApi.settings.getHistory(category, key);\r\n setHistory(result);\r\n } catch (err) {\r\n console.error('Failed to load history:', err);\r\n } finally {\r\n setLoadingHistory(false);\r\n }\r\n };\r\n\r\n const closeHistory = () => setHistoryModal(null);\r\n\r\n return {\r\n settings,\r\n editedValues,\r\n saving,\r\n historyModal,\r\n history,\r\n loadingHistory,\r\n handleValueChange,\r\n hasChanges,\r\n getDisplayValue,\r\n getEditKey,\r\n handleSave,\r\n handleReset,\r\n openHistory,\r\n closeHistory,\r\n };\r\n}\r\n\r\nexport type { SettingsContext };\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2 } from 'lucide-react';\r\nimport type { SettingHistoryDto } from '@/services/api/adminApi';\r\n\r\ninterface SettingsHistoryModalProps {\r\n readonly category: string;\r\n readonly settingKey: string;\r\n readonly history: SettingHistoryDto[];\r\n readonly loading: boolean;\r\n readonly onClose: () => void;\r\n}\r\n\r\nexport function SettingsHistoryModal({ category, settingKey, history, loading, onClose }: SettingsHistoryModalProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div className=\"fixed inset-0 z-50 overflow-y-auto\">\r\n <div className=\"flex items-center justify-center min-h-screen px-4\">\r\n <button type=\"button\" className=\"fixed inset-0 bg-black/50\" onClick={onClose} aria-label=\"Close modal\" />\r\n <div className=\"relative rounded-[var(--radius-card)] bg-[var(--bg-card)] shadow-xl max-w-2xl w-full p-6\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('settings.historyTitle', { key: `${category}.${settingKey}` })}\r\n </h3>\r\n\r\n {loading && (\r\n <div className=\"flex justify-center py-8\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n )}\r\n {!loading && history.length === 0 && (\r\n <p className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('settings.noHistory')}\r\n </p>\r\n )}\r\n {!loading && history.length > 0 && (\r\n <div className=\"space-y-3 max-h-96 overflow-y-auto\">\r\n {history.map((entry) => (\r\n <div key={entry.id} className=\"p-3 bg-[var(--bg-secondary)] rounded-lg\">\r\n <div className=\"flex justify-between text-sm\">\r\n <span className=\"text-[var(--text-secondary)]\">\r\n {entry.changedByUserName || t('settings.system')}\r\n </span>\r\n <span className=\"text-[var(--text-tertiary)]\">\r\n {new Date(entry.changedAt).toLocaleString()}\r\n </span>\r\n </div>\r\n <div className=\"mt-2 text-sm\">\r\n <span className=\"text-[var(--error-text)] line-through\">{entry.oldValue}</span>\r\n <span className=\"mx-2 text-[var(--text-tertiary)]\">→</span>\r\n <span className=\"text-[var(--success-text)]\">{entry.newValue}</span>\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"mt-6 flex justify-end\">\r\n <button\r\n onClick={onClose}\r\n className=\"px-4 py-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import type { ReactElement } from 'react';\nimport { useTranslation } from 'react-i18next';\r\nimport { Save, RotateCcw, Loader2, Clock, History, Settings as SettingsIcon } from 'lucide-react';\r\nimport type { SettingViewModel } from '@/services/api/adminApi';\r\nimport { useSettingsSection } from '@/hooks/useSettingsSection';\r\nimport { SettingsHistoryModal } from '@/components/platform/administration/settings/SettingsHistoryModal';\r\n\r\nexport function GeneralSettingsSection(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const {\r\n settings,\r\n saving,\r\n historyModal,\r\n history,\r\n loadingHistory,\r\n handleValueChange,\r\n hasChanges,\r\n getDisplayValue,\r\n getEditKey,\r\n handleSave,\r\n handleReset,\r\n openHistory,\r\n closeHistory,\r\n } = useSettingsSection();\r\n\r\n // Filter settings for Session and General categories\r\n const sessionSettings = settings.filter(s => s.category === 'Session');\r\n const generalSettings = settings.filter(s => s.category === 'General');\r\n\r\n const getSourceBadgeClass = (source: string): string => {\r\n if (source === 'Database') {\r\n return 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-600)]';\r\n }\r\n if (source === 'AppSettings') {\r\n return 'bg-purple-500/10 text-purple-600 dark:text-purple-400';\r\n }\r\n return 'bg-[var(--bg-secondary)] text-[var(--text-tertiary)]';\r\n };\r\n\r\n const getSettingInput = (setting: SettingViewModel, displayValue: string, isEditing: boolean): React.ReactNode => {\r\n if (setting.valueType === 'Bool') {\r\n return (\r\n <label className=\"relative inline-flex items-center cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={displayValue === 'true'}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.checked ? 'true' : 'false')}\r\n disabled={!setting.isEditable || isEditing}\r\n className=\"sr-only peer\"\r\n />\r\n <div className=\"w-11 h-6 bg-[var(--bg-tertiary)] peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-[var(--color-accent-500)]/30 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-[var(--border-color)] after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-[var(--color-accent-600)] peer-disabled:opacity-50 peer-disabled:cursor-not-allowed\"></div>\r\n </label>\r\n );\r\n }\r\n if (setting.valueType === 'Int' || setting.valueType === 'Decimal') {\r\n return (\r\n <input\r\n type=\"number\"\r\n value={displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing}\r\n className=\"w-24 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n );\r\n }\r\n return (\r\n <input\r\n type={setting.isSensitive ? 'password' : 'text'}\r\n value={setting.isSensitive ? '********' : displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing || setting.isSensitive}\r\n className=\"w-48 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n );\r\n };\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = getEditKey(setting);\r\n const isEditing = saving === editKey;\r\n const changed = hasChanges(setting);\r\n const displayValue = getDisplayValue(setting);\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-4 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`settings.keys.${setting.category}.${setting.key}`, setting.key)}\r\n </span>\r\n {!setting.isEditable && (\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--bg-secondary)] text-[var(--text-tertiary)] rounded\">\r\n {t('settings.readonly')}\r\n </span>\r\n )}\r\n <span className={`px-2 py-0.5 text-xs rounded ${getSourceBadgeClass(setting.source)}`}>\r\n {setting.source}\r\n </span>\r\n </div>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`settings.descriptions.${setting.category}.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n {setting.modifiedAt && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1 flex items-center gap-1\">\r\n <Clock className=\"w-3 h-3\" />\r\n {t('settings.modifiedBy', { user: setting.modifiedByUserName, date: new Date(setting.modifiedAt).toLocaleString() })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n {getSettingInput(setting, displayValue, isEditing)}\r\n\r\n {setting.isEditable && setting.source === 'Database' && (\r\n <>\r\n <button\r\n onClick={() => handleSave(setting)}\r\n disabled={!changed || isEditing}\r\n className=\"p-2 text-[var(--color-accent-600)] hover:bg-[var(--color-accent-500)]/10 rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('common.save')}\r\n >\r\n {isEditing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n </button>\r\n <button\r\n onClick={() => handleReset(setting)}\r\n disabled={setting.value === setting.defaultValue || isEditing}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('settings.resetToDefault')}\r\n >\r\n <RotateCcw className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n onClick={() => openHistory(setting.category, setting.key)}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n title={t('settings.viewHistory')}\r\n >\r\n <History className=\"w-4 h-4\" />\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Session Settings */}\r\n {sessionSettings.length > 0 && (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] overflow-hidden shadow-sm\">\r\n <div className=\"px-6 py-4 bg-gradient-to-r from-[var(--color-accent-500)]/10 to-[var(--color-accent-600)]/5 border-b border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--color-accent-500)]/20\">\r\n <Clock className=\"w-5 h-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('settings.sections.session')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('settings.sections.sessionDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {sessionSettings.map(renderSetting)}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* General Settings */}\r\n {generalSettings.length > 0 && (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] overflow-hidden shadow-sm\">\r\n <div className=\"px-6 py-4 bg-gradient-to-r from-[var(--color-accent-500)]/10 to-[var(--color-accent-600)]/5 border-b border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--color-accent-500)]/20\">\r\n <SettingsIcon className=\"w-5 h-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('settings.sections.general')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('settings.sections.generalDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {generalSettings.map(renderSetting)}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {sessionSettings.length === 0 && generalSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('settings.noSettings')}\r\n </div>\r\n )}\r\n\r\n {historyModal && (\r\n <SettingsHistoryModal\r\n category={historyModal.category}\r\n settingKey={historyModal.key}\r\n history={history}\r\n loading={loadingHistory}\r\n onClose={closeHistory}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default GeneralSettingsSection;\r\n","import type { ReactElement } from 'react';\nimport { useTranslation } from 'react-i18next';\r\nimport { Save, RotateCcw, Loader2, Upload, History, Clock } from 'lucide-react';\r\nimport type { SettingViewModel } from '@/services/api/adminApi';\r\nimport { useSettingsSection } from '@/hooks/useSettingsSection';\r\nimport { SettingsHistoryModal } from '@/components/platform/administration/settings/SettingsHistoryModal';\r\n\r\nexport function FileUploadSettingsSection(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const {\r\n settings,\r\n saving,\r\n historyModal,\r\n history,\r\n loadingHistory,\r\n handleValueChange,\r\n hasChanges,\r\n getDisplayValue,\r\n getEditKey,\r\n handleSave,\r\n handleReset,\r\n openHistory,\r\n closeHistory,\r\n } = useSettingsSection();\r\n\r\n // Filter settings for FileUpload category\r\n const fileUploadSettings = settings.filter(s => s.category === 'FileUpload');\r\n\r\n // Parse JSON extensions for display\r\n const parseExtensions = (value: string): string[] => {\r\n try {\r\n return JSON.parse(value);\r\n } catch {\r\n return [];\r\n }\r\n };\r\n\r\n const renderSettingInput = (setting: SettingViewModel, displayValue: string, isEditing: boolean) => {\r\n if (setting.valueType === 'Int') {\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"number\"\r\n value={displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing}\r\n className=\"w-24 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n {setting.key === 'MaxFileSizeMB' && (\r\n <span className=\"text-sm text-[var(--text-secondary)]\">MB</span>\r\n )}\r\n </div>\r\n );\r\n }\r\n return (\r\n <input\r\n type={setting.isSensitive ? 'password' : 'text'}\r\n value={setting.isSensitive ? '********' : displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing || setting.isSensitive}\r\n className=\"w-48 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n );\r\n };\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = getEditKey(setting);\r\n const isEditing = saving === editKey;\r\n const changed = hasChanges(setting);\r\n const displayValue = getDisplayValue(setting);\r\n\r\n // Special rendering for JSON arrays (extensions)\r\n if (setting.valueType === 'Json' && setting.key === 'AllowedExtensions') {\r\n const extensions = parseExtensions(displayValue);\r\n return (\r\n <div key={editKey} className=\"py-4 border-b border-[var(--border-color)] last:border-0\">\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`settings.keys.${setting.category}.${setting.key}`, setting.key)}\r\n </span>\r\n {!setting.isEditable && (\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--bg-secondary)] text-[var(--text-tertiary)] rounded\">\r\n {t('settings.readonly')}\r\n </span>\r\n )}\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--color-accent-500)]/10 text-[var(--color-accent-600)] rounded\">\r\n {setting.source}\r\n </span>\r\n </div>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`settings.descriptions.${setting.category}.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n </div>\r\n {setting.isEditable && setting.source === 'Database' && (\r\n <button\r\n onClick={() => openHistory(setting.category, setting.key)}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n title={t('settings.viewHistory')}\r\n >\r\n <History className=\"w-4 h-4\" />\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {extensions.map((ext) => (\r\n <span\r\n key={ext}\r\n className=\"px-3 py-1 bg-[var(--bg-secondary)] text-[var(--text-secondary)] rounded-full text-sm\"\r\n >\r\n {ext}\r\n </span>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-4 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`settings.keys.${setting.category}.${setting.key}`, setting.key)}\r\n </span>\r\n {!setting.isEditable && (\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--bg-secondary)] text-[var(--text-tertiary)] rounded\">\r\n {t('settings.readonly')}\r\n </span>\r\n )}\r\n <span className={`px-2 py-0.5 text-xs rounded ${\r\n setting.source === 'Database'\r\n ? 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-600)]'\r\n : setting.source === 'AppSettings'\r\n ? 'bg-purple-500/10 text-purple-600 dark:text-purple-400'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-tertiary)]'\r\n }`}>\r\n {setting.source}\r\n </span>\r\n </div>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`settings.descriptions.${setting.category}.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n {setting.modifiedAt && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1 flex items-center gap-1\">\r\n <Clock className=\"w-3 h-3\" />\r\n {t('settings.modifiedBy', { user: setting.modifiedByUserName, date: new Date(setting.modifiedAt).toLocaleString() })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n {renderSettingInput(setting, displayValue, isEditing)}\r\n\r\n {setting.isEditable && setting.source === 'Database' && (\r\n <>\r\n <button\r\n onClick={() => handleSave(setting)}\r\n disabled={!changed || isEditing}\r\n className=\"p-2 text-[var(--color-accent-600)] hover:bg-[var(--color-accent-500)]/10 rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('common.save')}\r\n >\r\n {isEditing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n </button>\r\n <button\r\n onClick={() => handleReset(setting)}\r\n disabled={setting.value === setting.defaultValue || isEditing}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('settings.resetToDefault')}\r\n >\r\n <RotateCcw className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n onClick={() => openHistory(setting.category, setting.key)}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n title={t('settings.viewHistory')}\r\n >\r\n <History className=\"w-4 h-4\" />\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] overflow-hidden shadow-sm\">\r\n <div className=\"px-6 py-4 bg-gradient-to-r from-[var(--color-accent-500)]/10 to-[var(--color-accent-600)]/5 border-b border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--color-accent-500)]/20\">\r\n <Upload className=\"w-5 h-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('settings.sections.fileUpload')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('settings.sections.fileUploadDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {fileUploadSettings.length > 0 ? (\r\n fileUploadSettings.map(renderSetting)\r\n ) : (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('settings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {historyModal && (\r\n <SettingsHistoryModal\r\n category={historyModal.category}\r\n settingKey={historyModal.key}\r\n history={history}\r\n loading={loadingHistory}\r\n onClose={closeHistory}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default FileUploadSettingsSection;\r\n","import { useState } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { Save, RotateCcw, Loader2, FileText, History, Clock, AlertTriangle, Shield } from 'lucide-react';\r\nimport { adminApi, type SettingViewModel, type SettingHistoryDto } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\nexport function LegalFileSettingsSection(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { settings, refreshSettings } = useOutletContext<SettingsContext>();\r\n const [editedValues, setEditedValues] = useState<Record<string, string>>({});\r\n const [saving, setSaving] = useState<string | null>(null);\r\n const [historyModal, setHistoryModal] = useState<{ category: string; key: string } | null>(null);\r\n const [history, setHistory] = useState<SettingHistoryDto[]>([]);\r\n const [loadingHistory, setLoadingHistory] = useState(false);\r\n\r\n // Filter settings for LegalFile category\r\n const legalFileSettings = settings.filter(s => s.category === 'LegalFile');\r\n\r\n const handleValueChange = (category: string, key: string, value: string) => {\r\n setEditedValues(prev => ({\r\n ...prev,\r\n [`${category}.${key}`]: value\r\n }));\r\n };\r\n\r\n const hasChanges = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n return editedValues[editKey] !== undefined && editedValues[editKey] !== setting.value;\r\n };\r\n\r\n const getDisplayValue = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n return editedValues[editKey] ?? setting.value;\r\n };\r\n\r\n const handleSave = async (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n const newValue = editedValues[editKey];\r\n if (newValue === undefined || newValue === setting.value) return;\r\n\r\n try {\r\n setSaving(editKey);\r\n await adminApi.settings.update(setting.category, setting.key, newValue);\r\n setEditedValues(prev => {\r\n const next = { ...prev };\r\n delete next[editKey];\r\n return next;\r\n });\r\n await refreshSettings();\r\n } catch (err) {\r\n console.error('Failed to save setting:', err);\r\n } finally {\r\n setSaving(null);\r\n }\r\n };\r\n\r\n const handleReset = async (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n try {\r\n setSaving(editKey);\r\n await adminApi.settings.reset(setting.category, setting.key);\r\n setEditedValues(prev => {\r\n const next = { ...prev };\r\n delete next[editKey];\r\n return next;\r\n });\r\n await refreshSettings();\r\n } catch (err) {\r\n console.error('Failed to reset setting:', err);\r\n } finally {\r\n setSaving(null);\r\n }\r\n };\r\n\r\n const openHistory = async (category: string, key: string) => {\r\n setHistoryModal({ category, key });\r\n setLoadingHistory(true);\r\n try {\r\n const result = await adminApi.settings.getHistory(category, key);\r\n setHistory(result);\r\n } catch (err) {\r\n console.error('Failed to load history:', err);\r\n } finally {\r\n setLoadingHistory(false);\r\n }\r\n };\r\n\r\n // Convert days to years for display\r\n const daysToYears = (days: number): string => {\r\n const years = Math.floor(days / 365);\r\n const remainingDays = days % 365;\r\n if (remainingDays === 0) {\r\n return `${years} ${t('settings.years')}`;\r\n }\r\n return `${years} ${t('settings.years')} ${remainingDays} ${t('settings.days')}`;\r\n };\r\n\r\n const getLegallyProtected = (setting: SettingViewModel): boolean => {\r\n return !setting.isEditable && (setting.key === 'RetentionDays' || setting.key === 'EnableWorm');\r\n };\r\n\r\n const renderSettingInput = (setting: SettingViewModel, displayValue: string, isEditing: boolean, handleValueChange: (category: string, key: string, value: string) => void) => {\r\n if (setting.valueType === 'Bool') {\r\n return (\r\n <label className=\"relative inline-flex cursor-pointer\">\r\n <span className=\"sr-only\">{setting.key}</span>\r\n <input\r\n type=\"checkbox\"\r\n checked={displayValue === 'true'}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.checked ? 'true' : 'false')}\r\n disabled={!setting.isEditable || isEditing}\r\n className=\"sr-only peer\"\r\n aria-label={setting.key}\r\n />\r\n <div className=\"w-11 h-6 bg-[var(--bg-tertiary)] peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-[var(--color-accent-500)]/30 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-[var(--border-color)] after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-[var(--color-accent-600)] peer-disabled:opacity-50 peer-disabled:cursor-not-allowed\"></div>\r\n </label>\r\n );\r\n }\r\n if (setting.valueType === 'Int') {\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"number\"\r\n value={displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing}\r\n className=\"w-24 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n {(setting.key === 'RetentionDays' || setting.key === 'ArchiveAfterDays') && (\r\n <span className=\"text-sm text-[var(--text-secondary)]\">\r\n ({daysToYears(parseInt(displayValue) || 0)})\r\n </span>\r\n )}\r\n </div>\r\n );\r\n }\r\n return (\r\n <input\r\n type={setting.isSensitive ? 'password' : 'text'}\r\n value={setting.isSensitive ? '********' : displayValue}\r\n onChange={(e) => handleValueChange(setting.category, setting.key, e.target.value)}\r\n disabled={!setting.isEditable || isEditing || setting.isSensitive}\r\n className=\"w-48 px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-button)] bg-[var(--bg-card)] text-[var(--text-primary)] disabled:opacity-50 disabled:cursor-not-allowed focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-[var(--color-accent-500)]\"\r\n />\r\n );\r\n };\r\n\r\n const getSourceBadgeClass = (source: string): string => {\r\n if (source === 'Database') return 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-600)]';\r\n if (source === 'AppSettings') return 'bg-purple-500/10 text-purple-600 dark:text-purple-400';\r\n return 'bg-[var(--bg-secondary)] text-[var(--text-tertiary)]';\r\n };\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n const isEditing = saving === editKey;\r\n const changed = hasChanges(setting);\r\n const displayValue = getDisplayValue(setting);\r\n const isLegallyProtected = getLegallyProtected(setting);\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className={`flex items-center justify-between py-4 border-b border-[var(--border-color)] last:border-0 ${\r\n isLegallyProtected ? 'bg-[var(--warning-bg)] -mx-6 px-6' : ''\r\n }`}\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`settings.keys.${setting.category}.${setting.key}`, setting.key)}\r\n </span>\r\n {isLegallyProtected && (\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)] rounded flex items-center gap-1\">\r\n <Shield className=\"w-3 h-3\" />\r\n {t('settings.legallyProtected')}\r\n </span>\r\n )}\r\n {!setting.isEditable && !isLegallyProtected && (\r\n <span className=\"px-2 py-0.5 text-xs bg-[var(--bg-secondary)] text-[var(--text-tertiary)] rounded\">\r\n {t('settings.readonly')}\r\n </span>\r\n )}\r\n <span className={`px-2 py-0.5 text-xs rounded ${getSourceBadgeClass(setting.source)}`}>\r\n {setting.source}\r\n </span>\r\n </div>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`settings.descriptions.${setting.category}.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n {setting.modifiedAt && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1 flex items-center gap-1\">\r\n <Clock className=\"w-3 h-3\" />\r\n {t('settings.modifiedBy', { user: setting.modifiedByUserName, date: new Date(setting.modifiedAt).toLocaleString() })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n {renderSettingInput(setting, displayValue, isEditing, handleValueChange)}\r\n\r\n {setting.isEditable && setting.source === 'Database' && (\r\n <>\r\n <button\r\n onClick={() => handleSave(setting)}\r\n disabled={!changed || isEditing}\r\n className=\"p-2 text-[var(--color-accent-600)] hover:bg-[var(--color-accent-500)]/10 rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('common.save')}\r\n >\r\n {isEditing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n </button>\r\n <button\r\n onClick={() => handleReset(setting)}\r\n disabled={setting.value === setting.defaultValue || isEditing}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('settings.resetToDefault')}\r\n >\r\n <RotateCcw className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n onClick={() => openHistory(setting.category, setting.key)}\r\n className=\"p-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n title={t('settings.viewHistory')}\r\n >\r\n <History className=\"w-4 h-4\" />\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Legal Warning Banner */}\r\n <div className=\"bg-[var(--warning-bg)] border border-[var(--warning-border)] rounded-[var(--radius-card)] p-4\">\r\n <div className=\"flex items-start gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--warning-text)] flex-shrink-0 mt-0.5\" />\r\n <div>\r\n <h4 className=\"font-medium text-[var(--warning-text)]\">\r\n {t('settings.legalWarningTitle')}\r\n </h4>\r\n <p className=\"text-sm text-[var(--warning-text)] opacity-90 mt-1\">\r\n {t('settings.legalWarningDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] overflow-hidden shadow-sm\">\r\n <div className=\"px-6 py-4 bg-gradient-to-r from-amber-500/10 to-amber-600/5 border-b border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-amber-500/20\">\r\n <FileText className=\"w-5 h-5 text-amber-600\" />\r\n </div>\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('settings.sections.legalFile')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('settings.sections.legalFileDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {legalFileSettings.length > 0 ? (\r\n legalFileSettings.map(renderSetting)\r\n ) : (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('settings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* History Modal */}\r\n {historyModal && (\r\n <div className=\"fixed inset-0 z-50 overflow-y-auto\">\r\n <div className=\"flex items-center justify-center min-h-screen px-4\">\r\n <button type=\"button\" className=\"fixed inset-0 bg-black/50\" onClick={() => setHistoryModal(null)} aria-label=\"Close modal\" />\r\n <div className=\"relative rounded-[var(--radius-card)] bg-[var(--bg-card)] shadow-xl max-w-2xl w-full p-6\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('settings.historyTitle', { key: `${historyModal.category}.${historyModal.key}` })}\r\n </h3>\r\n\r\n {loadingHistory && (\r\n <div className=\"flex justify-center py-8\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n )}\r\n {!loadingHistory && history.length === 0 && (\r\n <p className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('settings.noHistory')}\r\n </p>\r\n )}\r\n {!loadingHistory && history.length > 0 && (\r\n <div className=\"space-y-3 max-h-96 overflow-y-auto\">\r\n {history.map((entry) => (\r\n <div key={entry.id} className=\"p-3 bg-[var(--bg-secondary)] rounded-lg\">\r\n <div className=\"flex justify-between text-sm\">\r\n <span className=\"text-[var(--text-secondary)]\">\r\n {entry.changedByUserName || t('settings.system')}\r\n </span>\r\n <span className=\"text-[var(--text-tertiary)]\">\r\n {new Date(entry.changedAt).toLocaleString()}\r\n </span>\r\n </div>\r\n <div className=\"mt-2 text-sm\">\r\n <span className=\"text-[var(--error-text)] line-through\">{entry.oldValue}</span>\r\n <span className=\"mx-2 text-[var(--text-tertiary)]\">→</span>\r\n <span className=\"text-[var(--success-text)]\">{entry.newValue}</span>\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"mt-6 flex justify-end\">\r\n <button\r\n onClick={() => setHistoryModal(null)}\r\n className=\"px-4 py-2 text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)] rounded-[var(--radius-button)] transition-colors\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default LegalFileSettingsSection;\r\n"],"names":["TABS","Settings","Upload","FileText","SettingsPage","useTranslation","navigate","useNavigate","location","useLocation","settings","setSettings","useState","loading","setLoading","loadSettings","useCallback","result","adminApi","err","useEffect","getCurrentTab","path","t","handleTabChange","tabId","tab","jsx","Loader2","jsxs","Breadcrumb","Icon","isActive","Outlet","useSettingsSection","refreshSettings","useOutletContext","editedValues","setEditedValues","saving","setSaving","historyModal","setHistoryModal","history","setHistory","loadingHistory","setLoadingHistory","handleValueChange","category","key","value","prev","hasChanges","setting","editKey","getDisplayValue","getEditKey","newValue","next","SettingsHistoryModal","settingKey","onClose","entry","GeneralSettingsSection","handleSave","handleReset","openHistory","closeHistory","sessionSettings","generalSettings","getSourceBadgeClass","source","getSettingInput","displayValue","isEditing","e","renderSetting","changed","Clock","Fragment","Save","RotateCcw","History","SettingsIcon","FileUploadSettingsSection","fileUploadSettings","s","parseExtensions","renderSettingInput","extensions","ext","LegalFileSettingsSection","legalFileSettings","daysToYears","days","years","remainingDays","getLegallyProtected","isLegallyProtected","Shield","AlertTriangle"],"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"),N=require("react"),G=require("react-i18next"),V=require("react-router-dom"),A=require("./index-cAikSVW0.js"),r=require("lucide-react"),E={blue:"bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]",green:"bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]",yellow:"bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]",red:"bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]",neutral:"bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]"};function F(s){return s.status==="NoLicense"||s.isReadOnlyMode?"red":s.isInGracePeriod||s.isInTrial&&s.trialDaysRemaining<=7||s.status==="Active"&&s.daysUntilExpiration<=30?"yellow":s.status==="Active"?"green":"red"}function B(s){if(s.isPerpetual)return"green";const t=s.isInTrial?s.trialDaysRemaining:s.daysUntilExpiration;return t<=15?"red":t<=30?"yellow":"green"}function M(s){return s?new Date(s).toLocaleDateString(void 0,{year:"numeric",month:"long",day:"numeric"}):"-"}function O(s,t){const a=F(s),n=s.isInTrial?s.trialDaysRemaining:s.daysUntilExpiration,i=B(s);return[{label:t("license.info.edition","Edition"),value:t(`license.edition.${s.edition.toLowerCase()}`,s.edition),icon:r.Shield,color:"blue"},{label:t("license.info.status","Status"),value:s.isInGracePeriod?t("license.page.gracePeriod","Grace Period"):t(`license.status.${s.status.toLowerCase()}`,s.status),icon:s.isReadOnlyMode?r.AlertTriangle:r.CheckCircle,color:a},{label:t("license.page.daysRemaining","Days remaining"),value:s.isPerpetual?"∞":n.toString(),icon:s.isPerpetual?r.Infinity:r.Clock,color:i},{label:t("license.page.maxUsers","Max Users"),value:s.limits.users>0?s.limits.users.toString():t("license.page.unlimited","Unlimited"),icon:r.Users,color:"blue"}]}function q({showTrialSuccess:s,isInGracePeriod:t,validationResult:a,gracePeriodDays:n,onTrialSuccessClose:i,onValidationResultClear:l,t:d}){return e.jsxs(e.Fragment,{children:[s&&e.jsxs("div",{className:"flex items-center gap-3 p-4 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg animate-in fade-in slide-in-from-top",children:[e.jsx(r.CheckCircle,{className:"w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0"}),e.jsx("div",{className:"flex-1",children:e.jsx("p",{className:"text-sm font-medium text-green-900 dark:text-green-300",children:d("license.trial.successBanner","Your 30-day trial is activated!")})}),e.jsx("button",{onClick:i,className:"text-green-600 dark:text-green-400 hover:text-green-700 dark:hover:text-green-300",children:e.jsx(r.X,{className:"w-4 h-4"})})]}),t&&e.jsxs("div",{className:"flex items-center gap-3 p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg",children:[e.jsx(r.AlertTriangle,{className:"w-5 h-5 text-amber-600 dark:text-amber-400 flex-shrink-0"}),e.jsx("div",{className:"flex-1",children:e.jsx("p",{className:"text-sm font-medium text-amber-900 dark:text-amber-300",children:d("license.page.gracePeriodBanner","Your license has expired. You are in a {{days}}-day grace period. Renew to avoid service interruption.",{days:n})})})]}),a&&e.jsxs("div",{className:`flex items-center gap-3 p-4 rounded-lg border ${a.type==="success"?"bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800":a.type==="revoked"?"bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800":"bg-amber-50 dark:bg-amber-900/20 border-amber-200 dark:border-amber-800"}`,children:[a.type==="success"?e.jsx(r.CheckCircle,{className:"w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0"}):e.jsx(r.AlertTriangle,{className:`w-5 h-5 flex-shrink-0 ${a.type==="revoked"?"text-red-600 dark:text-red-400":"text-amber-600 dark:text-amber-400"}`}),e.jsx("p",{className:`text-sm font-medium flex-1 ${a.type==="success"?"text-green-900 dark:text-green-300":a.type==="revoked"?"text-red-900 dark:text-red-300":"text-amber-900 dark:text-amber-300"}`,children:a.message}),e.jsx("button",{onClick:l,className:a.type==="success"?"text-green-600 dark:text-green-400 hover:text-green-700 dark:hover:text-green-300":a.type==="revoked"?"text-red-600 dark:text-red-400 hover:text-red-700 dark:hover:text-red-300":"text-amber-600 dark:text-amber-400 hover:text-amber-700 dark:hover:text-amber-400",children:e.jsx(r.X,{className:"w-4 h-4"})})]})]})}function K({hasAllFeatures:s,enabledFeatures:t,availableFeatures:a,t:n}){return!a||a.length===0?e.jsx("p",{className:"text-[var(--text-secondary)] text-sm italic",children:n("license.page.noFeatures","No features enabled")}):e.jsxs(e.Fragment,{children:[s&&e.jsxs("div",{className:"flex items-center gap-2 p-3 mb-4 bg-[var(--success-bg)] text-[var(--success-text)] rounded-lg border border-[var(--success-border)]",children:[e.jsx(r.CheckCircle,{className:"w-5 h-5"}),e.jsx("span",{className:"font-medium",children:n("license.page.allFeatures","All features enabled")})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6",children:a.map(({group:i,features:l})=>e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold text-[var(--text-secondary)] uppercase tracking-wider mb-3",children:n(`license.group.${i}`,i)}),e.jsx("div",{className:"space-y-2",children:l.map(d=>{const m=s||t.some(c=>c.toLowerCase()===d.toLowerCase());return e.jsxs("div",{className:`flex items-center gap-2 px-3 py-2 rounded-lg border ${m?"bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]":"bg-[var(--bg-secondary)] text-[var(--text-secondary)] border-[var(--border-color)] opacity-60"}`,children:[m?e.jsx(r.Unlock,{className:"w-4 h-4 flex-shrink-0"}):e.jsx(r.Lock,{className:"w-4 h-4 flex-shrink-0"}),e.jsx("span",{className:"text-sm font-medium",children:n(`license.module.${d}`,d)})]},d)})})]},i))}),!s&&t.length===0&&e.jsx("p",{className:"text-[var(--text-secondary)] text-sm italic mt-3",children:n("license.page.noFeatures","No features enabled")})]})}function Y(s,t){const[a,n]=N.useState(!1),[i,l]=N.useState(null),d=N.useCallback(async()=>{n(!0),l(null);try{const c=await A.api.post("/api/administration/license/validate-server");c.revoked?(l({type:"revoked",message:t("license.validationRevoked","The license has been revoked by the server.")}),await s()):c.valid?(l({type:"success",message:t("license.validationSuccess","License is valid")}),await s()):l({type:"error",message:c.error||t("license.validationError","Unable to validate the license with the server.")})}catch{l({type:"error",message:t("license.validationError","Unable to validate the license with the server.")})}finally{n(!1),setTimeout(()=>l(null),5e3)}},[t,s]),m=N.useCallback(()=>l(null),[]);return{isValidating:a,validationResult:i,handleValidate:d,clearValidationResult:m}}function W(){const{t:s}=G.useTranslation("admin"),{license:t,usage:a,isLoading:n,error:i,refreshLicense:l}=A.useLicense(),[d,m]=N.useState(!1),[c,x]=V.useSearchParams(),[b,u]=N.useState(!1),{isValidating:p,validationResult:k,handleValidate:h,clearValidationResult:$}=Y(l,s);if(N.useEffect(()=>{l()},[l]),N.useEffect(()=>{if(c.get("trial")==="success"){u(!0);const o=setTimeout(()=>{u(!1),c.delete("trial"),x(c,{replace:!0})},5e3);return()=>clearTimeout(o)}},[c,x]),n)return e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx(r.Loader2,{className:"w-8 h-8 animate-spin text-[var(--text-secondary)]"})});if(i||!t)return e.jsx("div",{className:"p-6",children:e.jsxs("div",{className:"card p-6 text-center",children:[e.jsx(r.AlertTriangle,{className:"w-12 h-12 mx-auto mb-4 text-[var(--warning-text)]"}),e.jsx("h2",{className:"text-lg font-semibold mb-2",children:s("license.page.errorTitle","Unable to load license")}),e.jsx("p",{className:"text-[var(--text-secondary)] mb-4",children:i||s("license.page.errorDesc","License information is not available.")}),e.jsx("button",{onClick:()=>l(),className:"btn-primary px-4 py-2",children:s("common.retry","Retry")})]})});const S=A.hasAllLicenseFeatures(t.enabledFeatures),w=O(t,s);return e.jsxs("div",{className:"p-6 space-y-6",children:[e.jsx(q,{showTrialSuccess:b,isInGracePeriod:t.isInGracePeriod,validationResult:k,gracePeriodDays:t.gracePeriodDays,onTrialSuccessClose:()=>u(!1),onValidationResultClear:$,t:s}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-[var(--text-primary)]",children:s("license.page.title","License Management")}),e.jsx("p",{className:"text-[var(--text-secondary)] mt-1",children:s("license.page.subtitle","View and manage your platform license")})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(A.LicenseStatusBadge,{showDetails:!0}),e.jsxs("button",{onClick:h,disabled:p,className:"btn-secondary px-4 py-2 flex items-center gap-2",children:[p?e.jsx(r.Loader2,{className:"w-4 h-4 animate-spin"}):e.jsx(r.ShieldCheck,{className:"w-4 h-4"}),p?s("license.validating","Validating..."):s("license.validate","Validate")]}),e.jsxs("button",{onClick:()=>m(!0),className:"btn-primary px-4 py-2 flex items-center gap-2",children:[e.jsx(r.Key,{className:"w-4 h-4"}),s("license.activate","Activate")]})]})]}),e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:w.map(o=>e.jsxs("div",{className:`card p-4 border ${E[o.color]}`,children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(o.icon,{className:"w-5 h-5 opacity-80"}),e.jsx("span",{className:"text-sm opacity-80",children:o.label})]}),e.jsx("div",{className:"text-2xl font-bold",children:o.value})]},o.label))}),e.jsxs("div",{className:"card p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4 flex items-center gap-2",children:[e.jsx(r.Zap,{className:"w-5 h-5"}),s("license.info.limits","Limits")]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsx(D,{icon:r.Users,label:s("license.page.usersLimit","Users"),max:t.limits.users,current:a?.activeUsers??0,margin:10,t:s}),e.jsx(D,{icon:r.Building,label:s("license.page.tenantsLimit","Tenants (B2B)"),max:t.limits.tenants,current:a?.activeTenants??0,margin:2,t:s})]}),(()=>{const o=["users","tenants","max_instances","max_users"],C=Object.entries(t.limits.custom??{}).filter(([L])=>!o.includes(L));return C.length===0?null:e.jsxs("div",{className:"mt-4 pt-4 border-t border-[var(--border-color)]",children:[e.jsx("h3",{className:"text-sm font-medium text-[var(--text-secondary)] mb-3",children:s("license.page.customLimits","Custom Limits")}),e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:C.map(([L,P])=>e.jsxs("div",{className:"flex justify-between items-center py-1.5 px-3 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:L}),e.jsx("span",{className:"text-sm font-medium",children:P})]},L))})]})})()]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[e.jsxs("div",{className:"card p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4 flex items-center gap-2",children:[e.jsx(r.Calendar,{className:"w-5 h-5"}),s("license.page.details","License Details")]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(g,{label:s("license.info.productId","Product"),value:t.productId}),e.jsx(g,{label:s("license.info.company","Company"),value:t.companyName||"-"}),e.jsx(g,{label:s("license.info.edition","Edition"),value:s(`license.edition.${t.edition.toLowerCase()}`,t.edition)}),e.jsx(g,{label:s("license.info.status","Status"),value:s(`license.status.${t.status.toLowerCase()}`,t.status)}),e.jsx(g,{label:s("license.info.activatedAt","Activated At"),value:M(t.activatedAt)}),e.jsx(g,{label:s("license.info.expiresAt","Expires At"),value:t.isPerpetual?s("license.page.never","Never (Perpetual)"):M(t.expiresAt)})]})]}),e.jsxs("div",{className:"card p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4 flex items-center gap-2",children:[e.jsx(r.Server,{className:"w-5 h-5"}),s("license.page.subscription","Subscription")]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(g,{label:s("license.page.licenseType","License Type"),value:t.isPerpetual?s("license.page.perpetual","Perpetual"):t.isInTrial?s("license.edition.trial","Trial"):s("license.page.subscription","Subscription")}),e.jsx(g,{label:s("license.page.maxUsers","Max Users"),value:t.limits.users>0?t.limits.users.toString():s("license.page.unlimited","Unlimited")}),e.jsx(g,{label:s("license.page.gracePeriodDays","Grace Period"),value:t.gracePeriodDays>0?s("license.page.gracePeriodValue","{{days}} days",{days:t.gracePeriodDays}):s("license.page.noGracePeriod","None")}),e.jsx(g,{label:s("license.page.renewalDate","Renewal Date"),value:M(t.renewalDate)}),e.jsx(g,{label:s("license.page.mode","Mode"),value:t.isReadOnlyMode?s("license.page.readOnly","Read-only"):t.isInTrial?s("license.edition.trial","Trial"):s("license.page.licensed","Licensed")}),t.isInGracePeriod&&e.jsx(g,{label:s("license.page.gracePeriodStatus","Grace Period Status"),value:s("license.page.inGracePeriod","Active"),highlight:"yellow"})]})]}),e.jsxs("div",{className:"card p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4 flex items-center gap-2",children:[e.jsx(r.Monitor,{className:"w-5 h-5"}),s("license.page.machineInfo","Machine")]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"py-2 border-b border-[var(--border-color)] last:border-b-0",children:[e.jsx("div",{className:"flex justify-between items-center mb-1",children:e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:s("license.page.machineName","Machine Name")})}),e.jsx("span",{className:"text-xs font-mono text-[var(--text-primary)] break-all",children:t.machineName||"-"})]}),e.jsxs("div",{className:"py-2 border-b border-[var(--border-color)] last:border-b-0",children:[e.jsx("div",{className:"flex justify-between items-center mb-1",children:e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:s("license.page.instanceId","Instance ID")})}),e.jsx("span",{className:"text-xs font-mono text-[var(--text-primary)] break-all",children:t.instanceId||"-"})]}),e.jsxs("div",{className:"py-2 border-b border-[var(--border-color)] last:border-b-0",children:[e.jsx("div",{className:"flex justify-between items-center mb-1",children:e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:s("license.page.licenseId","License ID")})}),e.jsx("span",{className:"text-xs font-mono text-[var(--text-primary)] break-all",children:t.licenseServerId||"-"})]})]})]})]}),e.jsxs("div",{className:"card p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4 flex items-center gap-2",children:[e.jsx(r.Layers,{className:"w-5 h-5"}),s("license.info.features","Features")]}),e.jsx(K,{hasAllFeatures:S,enabledFeatures:t.enabledFeatures,availableFeatures:t.availableFeatures,t:s})]}),e.jsx(A.LicenseActivationDialog,{open:d,onOpenChange:m})]})}function g({label:s,value:t,highlight:a}){const n=a==="yellow"?"text-amber-600 dark:text-amber-400 font-semibold":a==="red"?"text-red-600 dark:text-red-400 font-semibold":a==="green"?"text-green-600 dark:text-green-400 font-semibold":"text-[var(--text-primary)]";return e.jsxs("div",{className:"flex justify-between items-center py-2 border-b border-[var(--border-color)] last:border-b-0",children:[e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:s}),e.jsx("span",{className:`text-sm font-medium ${n}`,children:t})]})}function X(s,t){return s?"text-red-500":t?"text-amber-500":"text-blue-500"}function Z(s,t){return s?"text-red-500":t?"text-amber-500":"text-[var(--text-primary)]"}function D({icon:s,label:t,max:a,current:n,margin:i=0,t:l}){const d=a<=0,m=a-i,c=a,x=140,b=12,u=(x-b)/2,p=x/2,k=135,h=270,$=c>0?Math.min(1,n/c):0,S=c>0?m/c:1,w=i>0&&n>m&&n<=c,o=n>c;let C="#3b82f6";o?C="#ef4444":w&&(C="#f59e0b");const L="rgba(245, 158, 11, 0.25)",P=f=>{const j=f*Math.PI/180;return{x:p+u*Math.cos(j),y:p+u*Math.sin(j)}},T=f=>{if(f<=0)return"";const j=k+f,y=P(k),v=P(j),I=f>180?1:0;return`M ${y.x} ${y.y} A ${u} ${u} 0 ${I} 1 ${v.x} ${v.y}`},U=c>0?Math.round(n/m*100):0;return d?e.jsxs("div",{className:"flex flex-col items-center gap-3 py-4",children:[e.jsxs("div",{className:"relative",style:{width:x,height:x},children:[e.jsxs("svg",{width:x,height:x,children:[e.jsx("path",{d:T(h),fill:"none",stroke:"var(--bg-tertiary)",strokeWidth:b,strokeLinecap:"round"}),e.jsx("path",{d:T(h),fill:"none",stroke:"#22c55e",strokeWidth:b,strokeLinecap:"round",opacity:.5})]}),e.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center",children:[e.jsx(s,{className:"w-6 h-6 text-green-500 mb-1"}),e.jsx("span",{className:"text-lg font-bold text-green-500",children:"∞"})]})]}),e.jsx("span",{className:"text-sm font-medium text-[var(--text-primary)]",children:t}),e.jsx("span",{className:"text-xs text-[var(--text-secondary)]",children:l("license.page.unlimited","Unlimited")})]}):e.jsxs("div",{className:"flex flex-col items-center gap-3 py-4",children:[e.jsxs("div",{className:"relative",style:{width:x,height:x},children:[e.jsxs("svg",{width:x,height:x,children:[e.jsx("path",{d:T(h),fill:"none",stroke:"var(--bg-tertiary)",strokeWidth:b,strokeLinecap:"round"}),i>0&&(()=>{const f=h*(1-S),j=k+h*S,y=P(j),v=P(k+h),I=f>180?1:0,R=`M ${y.x} ${y.y} A ${u} ${u} 0 ${I} 1 ${v.x} ${v.y}`;return e.jsx("path",{d:R,fill:"none",stroke:L,strokeWidth:b,strokeLinecap:"round"})})(),e.jsx("path",{d:T(h*$),fill:"none",stroke:C,strokeWidth:b,strokeLinecap:"round",style:{transition:"stroke 0.3s, d 0.3s"}}),i>0&&(()=>{const f=k+h*S,j=u-b/2-2,y=u+b/2+2,v=f*Math.PI/180;return e.jsx("line",{x1:p+j*Math.cos(v),y1:p+j*Math.sin(v),x2:p+y*Math.cos(v),y2:p+y*Math.sin(v),stroke:"var(--text-secondary)",strokeWidth:2,strokeLinecap:"round"})})()]}),e.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center",children:[e.jsx(s,{className:`w-5 h-5 mb-0.5 ${X(o,w)}`}),e.jsxs("span",{className:`text-2xl font-bold ${Z(o,w)}`,children:[U,"%"]}),e.jsxs("span",{className:"text-xs text-[var(--text-secondary)]",children:[n," / ",m]})]})]}),e.jsx("span",{className:"text-sm font-medium text-[var(--text-primary)]",children:t}),i>0&&e.jsxs("span",{className:`text-xs ${w||o?"text-amber-600 dark:text-amber-400":"text-[var(--text-secondary)]"}`,children:["+",i," ",l("license.page.tolerance","tolerance")]})]})}exports.LicenseManagementPage=W;
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),N=require("react"),G=require("react-i18next"),V=require("react-router-dom"),A=require("./index-DK5czlkn.js"),r=require("lucide-react"),E={blue:"bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]",green:"bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]",yellow:"bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]",red:"bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]",neutral:"bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]"};function F(s){return s.status==="NoLicense"||s.isReadOnlyMode?"red":s.isInGracePeriod||s.isInTrial&&s.trialDaysRemaining<=7||s.status==="Active"&&s.daysUntilExpiration<=30?"yellow":s.status==="Active"?"green":"red"}function B(s){if(s.isPerpetual)return"green";const t=s.isInTrial?s.trialDaysRemaining:s.daysUntilExpiration;return t<=15?"red":t<=30?"yellow":"green"}function M(s){return s?new Date(s).toLocaleDateString(void 0,{year:"numeric",month:"long",day:"numeric"}):"-"}function O(s,t){const a=F(s),n=s.isInTrial?s.trialDaysRemaining:s.daysUntilExpiration,i=B(s);return[{label:t("license.info.edition","Edition"),value:t(`license.edition.${s.edition.toLowerCase()}`,s.edition),icon:r.Shield,color:"blue"},{label:t("license.info.status","Status"),value:s.isInGracePeriod?t("license.page.gracePeriod","Grace Period"):t(`license.status.${s.status.toLowerCase()}`,s.status),icon:s.isReadOnlyMode?r.AlertTriangle:r.CheckCircle,color:a},{label:t("license.page.daysRemaining","Days remaining"),value:s.isPerpetual?"∞":n.toString(),icon:s.isPerpetual?r.Infinity:r.Clock,color:i},{label:t("license.page.maxUsers","Max Users"),value:s.limits.users>0?s.limits.users.toString():t("license.page.unlimited","Unlimited"),icon:r.Users,color:"blue"}]}function q({showTrialSuccess:s,isInGracePeriod:t,validationResult:a,gracePeriodDays:n,onTrialSuccessClose:i,onValidationResultClear:l,t:d}){return e.jsxs(e.Fragment,{children:[s&&e.jsxs("div",{className:"flex items-center gap-3 p-4 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg animate-in fade-in slide-in-from-top",children:[e.jsx(r.CheckCircle,{className:"w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0"}),e.jsx("div",{className:"flex-1",children:e.jsx("p",{className:"text-sm font-medium text-green-900 dark:text-green-300",children:d("license.trial.successBanner","Your 30-day trial is activated!")})}),e.jsx("button",{onClick:i,className:"text-green-600 dark:text-green-400 hover:text-green-700 dark:hover:text-green-300",children:e.jsx(r.X,{className:"w-4 h-4"})})]}),t&&e.jsxs("div",{className:"flex items-center gap-3 p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg",children:[e.jsx(r.AlertTriangle,{className:"w-5 h-5 text-amber-600 dark:text-amber-400 flex-shrink-0"}),e.jsx("div",{className:"flex-1",children:e.jsx("p",{className:"text-sm font-medium text-amber-900 dark:text-amber-300",children:d("license.page.gracePeriodBanner","Your license has expired. You are in a {{days}}-day grace period. Renew to avoid service interruption.",{days:n})})})]}),a&&e.jsxs("div",{className:`flex items-center gap-3 p-4 rounded-lg border ${a.type==="success"?"bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800":a.type==="revoked"?"bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800":"bg-amber-50 dark:bg-amber-900/20 border-amber-200 dark:border-amber-800"}`,children:[a.type==="success"?e.jsx(r.CheckCircle,{className:"w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0"}):e.jsx(r.AlertTriangle,{className:`w-5 h-5 flex-shrink-0 ${a.type==="revoked"?"text-red-600 dark:text-red-400":"text-amber-600 dark:text-amber-400"}`}),e.jsx("p",{className:`text-sm font-medium flex-1 ${a.type==="success"?"text-green-900 dark:text-green-300":a.type==="revoked"?"text-red-900 dark:text-red-300":"text-amber-900 dark:text-amber-300"}`,children:a.message}),e.jsx("button",{onClick:l,className:a.type==="success"?"text-green-600 dark:text-green-400 hover:text-green-700 dark:hover:text-green-300":a.type==="revoked"?"text-red-600 dark:text-red-400 hover:text-red-700 dark:hover:text-red-300":"text-amber-600 dark:text-amber-400 hover:text-amber-700 dark:hover:text-amber-400",children:e.jsx(r.X,{className:"w-4 h-4"})})]})]})}function K({hasAllFeatures:s,enabledFeatures:t,availableFeatures:a,t:n}){return!a||a.length===0?e.jsx("p",{className:"text-[var(--text-secondary)] text-sm italic",children:n("license.page.noFeatures","No features enabled")}):e.jsxs(e.Fragment,{children:[s&&e.jsxs("div",{className:"flex items-center gap-2 p-3 mb-4 bg-[var(--success-bg)] text-[var(--success-text)] rounded-lg border border-[var(--success-border)]",children:[e.jsx(r.CheckCircle,{className:"w-5 h-5"}),e.jsx("span",{className:"font-medium",children:n("license.page.allFeatures","All features enabled")})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6",children:a.map(({group:i,features:l})=>e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold text-[var(--text-secondary)] uppercase tracking-wider mb-3",children:n(`license.group.${i}`,i)}),e.jsx("div",{className:"space-y-2",children:l.map(d=>{const m=s||t.some(c=>c.toLowerCase()===d.toLowerCase());return e.jsxs("div",{className:`flex items-center gap-2 px-3 py-2 rounded-lg border ${m?"bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]":"bg-[var(--bg-secondary)] text-[var(--text-secondary)] border-[var(--border-color)] opacity-60"}`,children:[m?e.jsx(r.Unlock,{className:"w-4 h-4 flex-shrink-0"}):e.jsx(r.Lock,{className:"w-4 h-4 flex-shrink-0"}),e.jsx("span",{className:"text-sm font-medium",children:n(`license.module.${d}`,d)})]},d)})})]},i))}),!s&&t.length===0&&e.jsx("p",{className:"text-[var(--text-secondary)] text-sm italic mt-3",children:n("license.page.noFeatures","No features enabled")})]})}function Y(s,t){const[a,n]=N.useState(!1),[i,l]=N.useState(null),d=N.useCallback(async()=>{n(!0),l(null);try{const c=await A.api.post("/api/administration/license/validate-server");c.revoked?(l({type:"revoked",message:t("license.validationRevoked","The license has been revoked by the server.")}),await s()):c.valid?(l({type:"success",message:t("license.validationSuccess","License is valid")}),await s()):l({type:"error",message:c.error||t("license.validationError","Unable to validate the license with the server.")})}catch{l({type:"error",message:t("license.validationError","Unable to validate the license with the server.")})}finally{n(!1),setTimeout(()=>l(null),5e3)}},[t,s]),m=N.useCallback(()=>l(null),[]);return{isValidating:a,validationResult:i,handleValidate:d,clearValidationResult:m}}function W(){const{t:s}=G.useTranslation("admin"),{license:t,usage:a,isLoading:n,error:i,refreshLicense:l}=A.useLicense(),[d,m]=N.useState(!1),[c,x]=V.useSearchParams(),[b,u]=N.useState(!1),{isValidating:p,validationResult:k,handleValidate:h,clearValidationResult:$}=Y(l,s);if(N.useEffect(()=>{l()},[l]),N.useEffect(()=>{if(c.get("trial")==="success"){u(!0);const o=setTimeout(()=>{u(!1),c.delete("trial"),x(c,{replace:!0})},5e3);return()=>clearTimeout(o)}},[c,x]),n)return e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx(r.Loader2,{className:"w-8 h-8 animate-spin text-[var(--text-secondary)]"})});if(i||!t)return e.jsx("div",{className:"p-6",children:e.jsxs("div",{className:"card p-6 text-center",children:[e.jsx(r.AlertTriangle,{className:"w-12 h-12 mx-auto mb-4 text-[var(--warning-text)]"}),e.jsx("h2",{className:"text-lg font-semibold mb-2",children:s("license.page.errorTitle","Unable to load license")}),e.jsx("p",{className:"text-[var(--text-secondary)] mb-4",children:i||s("license.page.errorDesc","License information is not available.")}),e.jsx("button",{onClick:()=>l(),className:"btn-primary px-4 py-2",children:s("common.retry","Retry")})]})});const S=A.hasAllLicenseFeatures(t.enabledFeatures),w=O(t,s);return e.jsxs("div",{className:"p-6 space-y-6",children:[e.jsx(q,{showTrialSuccess:b,isInGracePeriod:t.isInGracePeriod,validationResult:k,gracePeriodDays:t.gracePeriodDays,onTrialSuccessClose:()=>u(!1),onValidationResultClear:$,t:s}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-[var(--text-primary)]",children:s("license.page.title","License Management")}),e.jsx("p",{className:"text-[var(--text-secondary)] mt-1",children:s("license.page.subtitle","View and manage your platform license")})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(A.LicenseStatusBadge,{showDetails:!0}),e.jsxs("button",{onClick:h,disabled:p,className:"btn-secondary px-4 py-2 flex items-center gap-2",children:[p?e.jsx(r.Loader2,{className:"w-4 h-4 animate-spin"}):e.jsx(r.ShieldCheck,{className:"w-4 h-4"}),p?s("license.validating","Validating..."):s("license.validate","Validate")]}),e.jsxs("button",{onClick:()=>m(!0),className:"btn-primary px-4 py-2 flex items-center gap-2",children:[e.jsx(r.Key,{className:"w-4 h-4"}),s("license.activate","Activate")]})]})]}),e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:w.map(o=>e.jsxs("div",{className:`card p-4 border ${E[o.color]}`,children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(o.icon,{className:"w-5 h-5 opacity-80"}),e.jsx("span",{className:"text-sm opacity-80",children:o.label})]}),e.jsx("div",{className:"text-2xl font-bold",children:o.value})]},o.label))}),e.jsxs("div",{className:"card p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4 flex items-center gap-2",children:[e.jsx(r.Zap,{className:"w-5 h-5"}),s("license.info.limits","Limits")]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsx(D,{icon:r.Users,label:s("license.page.usersLimit","Users"),max:t.limits.users,current:a?.activeUsers??0,margin:10,t:s}),e.jsx(D,{icon:r.Building,label:s("license.page.tenantsLimit","Tenants (B2B)"),max:t.limits.tenants,current:a?.activeTenants??0,margin:2,t:s})]}),(()=>{const o=["users","tenants","max_instances","max_users"],C=Object.entries(t.limits.custom??{}).filter(([L])=>!o.includes(L));return C.length===0?null:e.jsxs("div",{className:"mt-4 pt-4 border-t border-[var(--border-color)]",children:[e.jsx("h3",{className:"text-sm font-medium text-[var(--text-secondary)] mb-3",children:s("license.page.customLimits","Custom Limits")}),e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:C.map(([L,P])=>e.jsxs("div",{className:"flex justify-between items-center py-1.5 px-3 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:L}),e.jsx("span",{className:"text-sm font-medium",children:P})]},L))})]})})()]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[e.jsxs("div",{className:"card p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4 flex items-center gap-2",children:[e.jsx(r.Calendar,{className:"w-5 h-5"}),s("license.page.details","License Details")]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(g,{label:s("license.info.productId","Product"),value:t.productId}),e.jsx(g,{label:s("license.info.company","Company"),value:t.companyName||"-"}),e.jsx(g,{label:s("license.info.edition","Edition"),value:s(`license.edition.${t.edition.toLowerCase()}`,t.edition)}),e.jsx(g,{label:s("license.info.status","Status"),value:s(`license.status.${t.status.toLowerCase()}`,t.status)}),e.jsx(g,{label:s("license.info.activatedAt","Activated At"),value:M(t.activatedAt)}),e.jsx(g,{label:s("license.info.expiresAt","Expires At"),value:t.isPerpetual?s("license.page.never","Never (Perpetual)"):M(t.expiresAt)})]})]}),e.jsxs("div",{className:"card p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4 flex items-center gap-2",children:[e.jsx(r.Server,{className:"w-5 h-5"}),s("license.page.subscription","Subscription")]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(g,{label:s("license.page.licenseType","License Type"),value:t.isPerpetual?s("license.page.perpetual","Perpetual"):t.isInTrial?s("license.edition.trial","Trial"):s("license.page.subscription","Subscription")}),e.jsx(g,{label:s("license.page.maxUsers","Max Users"),value:t.limits.users>0?t.limits.users.toString():s("license.page.unlimited","Unlimited")}),e.jsx(g,{label:s("license.page.gracePeriodDays","Grace Period"),value:t.gracePeriodDays>0?s("license.page.gracePeriodValue","{{days}} days",{days:t.gracePeriodDays}):s("license.page.noGracePeriod","None")}),e.jsx(g,{label:s("license.page.renewalDate","Renewal Date"),value:M(t.renewalDate)}),e.jsx(g,{label:s("license.page.mode","Mode"),value:t.isReadOnlyMode?s("license.page.readOnly","Read-only"):t.isInTrial?s("license.edition.trial","Trial"):s("license.page.licensed","Licensed")}),t.isInGracePeriod&&e.jsx(g,{label:s("license.page.gracePeriodStatus","Grace Period Status"),value:s("license.page.inGracePeriod","Active"),highlight:"yellow"})]})]}),e.jsxs("div",{className:"card p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4 flex items-center gap-2",children:[e.jsx(r.Monitor,{className:"w-5 h-5"}),s("license.page.machineInfo","Machine")]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"py-2 border-b border-[var(--border-color)] last:border-b-0",children:[e.jsx("div",{className:"flex justify-between items-center mb-1",children:e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:s("license.page.machineName","Machine Name")})}),e.jsx("span",{className:"text-xs font-mono text-[var(--text-primary)] break-all",children:t.machineName||"-"})]}),e.jsxs("div",{className:"py-2 border-b border-[var(--border-color)] last:border-b-0",children:[e.jsx("div",{className:"flex justify-between items-center mb-1",children:e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:s("license.page.instanceId","Instance ID")})}),e.jsx("span",{className:"text-xs font-mono text-[var(--text-primary)] break-all",children:t.instanceId||"-"})]}),e.jsxs("div",{className:"py-2 border-b border-[var(--border-color)] last:border-b-0",children:[e.jsx("div",{className:"flex justify-between items-center mb-1",children:e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:s("license.page.licenseId","License ID")})}),e.jsx("span",{className:"text-xs font-mono text-[var(--text-primary)] break-all",children:t.licenseServerId||"-"})]})]})]})]}),e.jsxs("div",{className:"card p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4 flex items-center gap-2",children:[e.jsx(r.Layers,{className:"w-5 h-5"}),s("license.info.features","Features")]}),e.jsx(K,{hasAllFeatures:S,enabledFeatures:t.enabledFeatures,availableFeatures:t.availableFeatures,t:s})]}),e.jsx(A.LicenseActivationDialog,{open:d,onOpenChange:m})]})}function g({label:s,value:t,highlight:a}){const n=a==="yellow"?"text-amber-600 dark:text-amber-400 font-semibold":a==="red"?"text-red-600 dark:text-red-400 font-semibold":a==="green"?"text-green-600 dark:text-green-400 font-semibold":"text-[var(--text-primary)]";return e.jsxs("div",{className:"flex justify-between items-center py-2 border-b border-[var(--border-color)] last:border-b-0",children:[e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:s}),e.jsx("span",{className:`text-sm font-medium ${n}`,children:t})]})}function X(s,t){return s?"text-red-500":t?"text-amber-500":"text-blue-500"}function Z(s,t){return s?"text-red-500":t?"text-amber-500":"text-[var(--text-primary)]"}function D({icon:s,label:t,max:a,current:n,margin:i=0,t:l}){const d=a<=0,m=a-i,c=a,x=140,b=12,u=(x-b)/2,p=x/2,k=135,h=270,$=c>0?Math.min(1,n/c):0,S=c>0?m/c:1,w=i>0&&n>m&&n<=c,o=n>c;let C="#3b82f6";o?C="#ef4444":w&&(C="#f59e0b");const L="rgba(245, 158, 11, 0.25)",P=f=>{const j=f*Math.PI/180;return{x:p+u*Math.cos(j),y:p+u*Math.sin(j)}},T=f=>{if(f<=0)return"";const j=k+f,y=P(k),v=P(j),I=f>180?1:0;return`M ${y.x} ${y.y} A ${u} ${u} 0 ${I} 1 ${v.x} ${v.y}`},U=c>0?Math.round(n/m*100):0;return d?e.jsxs("div",{className:"flex flex-col items-center gap-3 py-4",children:[e.jsxs("div",{className:"relative",style:{width:x,height:x},children:[e.jsxs("svg",{width:x,height:x,children:[e.jsx("path",{d:T(h),fill:"none",stroke:"var(--bg-tertiary)",strokeWidth:b,strokeLinecap:"round"}),e.jsx("path",{d:T(h),fill:"none",stroke:"#22c55e",strokeWidth:b,strokeLinecap:"round",opacity:.5})]}),e.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center",children:[e.jsx(s,{className:"w-6 h-6 text-green-500 mb-1"}),e.jsx("span",{className:"text-lg font-bold text-green-500",children:"∞"})]})]}),e.jsx("span",{className:"text-sm font-medium text-[var(--text-primary)]",children:t}),e.jsx("span",{className:"text-xs text-[var(--text-secondary)]",children:l("license.page.unlimited","Unlimited")})]}):e.jsxs("div",{className:"flex flex-col items-center gap-3 py-4",children:[e.jsxs("div",{className:"relative",style:{width:x,height:x},children:[e.jsxs("svg",{width:x,height:x,children:[e.jsx("path",{d:T(h),fill:"none",stroke:"var(--bg-tertiary)",strokeWidth:b,strokeLinecap:"round"}),i>0&&(()=>{const f=h*(1-S),j=k+h*S,y=P(j),v=P(k+h),I=f>180?1:0,R=`M ${y.x} ${y.y} A ${u} ${u} 0 ${I} 1 ${v.x} ${v.y}`;return e.jsx("path",{d:R,fill:"none",stroke:L,strokeWidth:b,strokeLinecap:"round"})})(),e.jsx("path",{d:T(h*$),fill:"none",stroke:C,strokeWidth:b,strokeLinecap:"round",style:{transition:"stroke 0.3s, d 0.3s"}}),i>0&&(()=>{const f=k+h*S,j=u-b/2-2,y=u+b/2+2,v=f*Math.PI/180;return e.jsx("line",{x1:p+j*Math.cos(v),y1:p+j*Math.sin(v),x2:p+y*Math.cos(v),y2:p+y*Math.sin(v),stroke:"var(--text-secondary)",strokeWidth:2,strokeLinecap:"round"})})()]}),e.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center",children:[e.jsx(s,{className:`w-5 h-5 mb-0.5 ${X(o,w)}`}),e.jsxs("span",{className:`text-2xl font-bold ${Z(o,w)}`,children:[U,"%"]}),e.jsxs("span",{className:"text-xs text-[var(--text-secondary)]",children:[n," / ",m]})]})]}),e.jsx("span",{className:"text-sm font-medium text-[var(--text-primary)]",children:t}),i>0&&e.jsxs("span",{className:`text-xs ${w||o?"text-amber-600 dark:text-amber-400":"text-[var(--text-secondary)]"}`,children:["+",i," ",l("license.page.tolerance","tolerance")]})]})}exports.LicenseManagementPage=W;
|
|
2
|
+
//# sourceMappingURL=index-CUZygY5Q.js.map
|