@atlashub/smartstack 3.21.0 → 3.24.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-7si3Ng8e.js → AgentSkillsPage-BWQSCYl-.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-7si3Ng8e.js.map → AgentSkillsPage-BWQSCYl-.js.map} +1 -1
- package/dist/chunks/{AgentSkillsPage-D0cD1QdM.js → AgentSkillsPage-IQcMnBaD.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-D0cD1QdM.js.map → AgentSkillsPage-IQcMnBaD.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-H_7ze33H.js → AgentWorkloadPage-DqrjkvWL.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-H_7ze33H.js.map → AgentWorkloadPage-DqrjkvWL.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-D4d86cdV.js → AgentWorkloadPage-w-HiyFYP.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-D4d86cdV.js.map → AgentWorkloadPage-w-HiyFYP.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-2ktkRrCb.js → ApiCatalogDetailPage-D3L8Yf4G.js} +3 -3
- package/dist/chunks/{ApiCatalogDetailPage-2ktkRrCb.js.map → ApiCatalogDetailPage-D3L8Yf4G.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-BQ53xuwD.js → ApiCatalogDetailPage-MPT3Kz6H.js} +2 -2
- package/dist/chunks/{ApiCatalogDetailPage-BQ53xuwD.js.map → ApiCatalogDetailPage-MPT3Kz6H.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-BEqTDJz8.js → ApiCatalogPage-D4Hg3uiS.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-BEqTDJz8.js.map → ApiCatalogPage-D4Hg3uiS.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-BBkWSLI8.js → ApiCatalogPage-DRg5Cz0r.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-BBkWSLI8.js.map → ApiCatalogPage-DRg5Cz0r.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-BYJ2YMPq.js → ApplicationDetailPage-Caizuyn2.js} +2 -2
- package/dist/chunks/{ApplicationDetailPage-BYJ2YMPq.js.map → ApplicationDetailPage-Caizuyn2.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js → ApplicationDetailPage-CuCW6aMB.js} +4 -4
- package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js.map → ApplicationDetailPage-CuCW6aMB.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-BBlLms2r.js → ApplicationsDashboardPage-B2MW8-Kc.js} +2 -2
- package/dist/chunks/{ApplicationsDashboardPage-BBlLms2r.js.map → ApplicationsDashboardPage-B2MW8-Kc.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-DTWZxJJM.js → ApplicationsDashboardPage-BDIjFIYZ.js} +3 -3
- package/dist/chunks/{ApplicationsDashboardPage-DTWZxJJM.js.map → ApplicationsDashboardPage-BDIjFIYZ.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-BQaMsK1K.js → ApplicationsGridPage-DV-FihKj.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-BQaMsK1K.js.map → ApplicationsGridPage-DV-FihKj.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-DbVcvezt.js → ApplicationsGridPage-DXsTfXPI.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-DbVcvezt.js.map → ApplicationsGridPage-DXsTfXPI.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-DYKM2Yeo.js → ApplicationsListPage--CGkyBuJ.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-DYKM2Yeo.js.map → ApplicationsListPage--CGkyBuJ.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-C91v2rZt.js → ApplicationsListPage-JUX823bh.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-C91v2rZt.js.map → ApplicationsListPage-JUX823bh.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-BCbgotIx.js → ApplicationsPage-6zgFye6w.js} +2 -2
- package/dist/chunks/{ApplicationsPage-BCbgotIx.js.map → ApplicationsPage-6zgFye6w.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-CW3-Hjlu.js → ApplicationsPage-CQPuuiO6.js} +4 -4
- package/dist/chunks/{ApplicationsPage-CW3-Hjlu.js.map → ApplicationsPage-CQPuuiO6.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-D8vfGDBN.js → AssignmentRulesPage-CFffeEbo.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-D8vfGDBN.js.map → AssignmentRulesPage-CFffeEbo.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-CxktlEMB.js → AssignmentRulesPage-D78UeUId.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-CxktlEMB.js.map → AssignmentRulesPage-D78UeUId.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-DmfBYQAD.js → AssignmentsPage-Cww2ifZF.js} +2 -2
- package/dist/chunks/{AssignmentsPage-DmfBYQAD.js.map → AssignmentsPage-Cww2ifZF.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-sRCCBmRc.js → AssignmentsPage-DE_QS2LO.js} +2 -2
- package/dist/chunks/{AssignmentsPage-sRCCBmRc.js.map → AssignmentsPage-DE_QS2LO.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-C7XiZxKb.js → AuthCallbackPage-CA2nO6DG.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-C7XiZxKb.js.map → AuthCallbackPage-CA2nO6DG.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-BCe_bwJM.js → AuthCallbackPage-CDUAoX-N.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-BCe_bwJM.js.map → AuthCallbackPage-CDUAoX-N.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-BUfGSqxF.js → ConfirmEmailPage-BqsILAYH.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-BUfGSqxF.js.map → ConfirmEmailPage-BqsILAYH.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-Buj4x-rx.js → ConfirmEmailPage-INeHCuMB.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-Buj4x-rx.js.map → ConfirmEmailPage-INeHCuMB.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-CKDX_HQm.js → CreateSupportTicketPage-BWeuV2aU.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-CKDX_HQm.js.map → CreateSupportTicketPage-BWeuV2aU.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-0LgY-_pu.js → CreateSupportTicketPage-OBwF4v7b.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-0LgY-_pu.js.map → CreateSupportTicketPage-OBwF4v7b.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CUZ80NGV.js → DashboardPage-CKHqWrdS.js} +3 -3
- package/dist/chunks/{DashboardPage-CUZ80NGV.js.map → DashboardPage-CKHqWrdS.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CaNOAstg.js → DashboardPage-COmc9b__.js} +3 -3
- package/dist/chunks/{DashboardPage-CaNOAstg.js.map → DashboardPage-COmc9b__.js.map} +1 -1
- package/dist/chunks/{DashboardPage-B48_rQFi.js → DashboardPage-CfKZHiSj.js} +2 -2
- package/dist/chunks/{DashboardPage-B48_rQFi.js.map → DashboardPage-CfKZHiSj.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CUZV1J9t.js → DashboardPage-CwEZZ3jx.js} +2 -2
- package/dist/chunks/{DashboardPage-CUZV1J9t.js.map → DashboardPage-CwEZZ3jx.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-CdzAbnGy.js → EscalationConfigPage--7lgZ0kJ.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-CdzAbnGy.js.map → EscalationConfigPage--7lgZ0kJ.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-CYGIl_e6.js → EscalationConfigPage-DPyiBcqV.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-CYGIl_e6.js.map → EscalationConfigPage-DPyiBcqV.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-lRpkwcX7.js → ForceChangePasswordPage-BE-6umub.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-lRpkwcX7.js.map → ForceChangePasswordPage-BE-6umub.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-CvmYAV3r.js → ForceChangePasswordPage-CnsYoWmV.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-CvmYAV3r.js.map → ForceChangePasswordPage-CnsYoWmV.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-0u49E4Pw.js → ForgotPasswordPage-CSq4DnFF.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-0u49E4Pw.js.map → ForgotPasswordPage-CSq4DnFF.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-CxQUqKOm.js → ForgotPasswordPage-DZLVolAC.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-CxQUqKOm.js.map → ForgotPasswordPage-DZLVolAC.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-DFBvVO1S.js → GroupDetailPage-Bf9Wb_2j.js} +5 -5
- package/dist/chunks/{GroupDetailPage-DFBvVO1S.js.map → GroupDetailPage-Bf9Wb_2j.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-B2FkKrGG.js → GroupDetailPage-R-hf3rJ7.js} +2 -2
- package/dist/chunks/{GroupDetailPage-B2FkKrGG.js.map → GroupDetailPage-R-hf3rJ7.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-C9IX4c0K.js → MyAccessRequestsPage-BIisvWM6.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-C9IX4c0K.js.map → MyAccessRequestsPage-BIisvWM6.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-D6pVULNM.js → MyAccessRequestsPage-BLSV7Tbx.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-D6pVULNM.js.map → MyAccessRequestsPage-BLSV7Tbx.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-BEcYYdGR.js → MyTenantsPage-D-7k9CP1.js} +3 -3
- package/dist/chunks/{MyTenantsPage-BEcYYdGR.js.map → MyTenantsPage-D-7k9CP1.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-D9f85zjF.js → MyTenantsPage-DqGW6aDt.js} +2 -2
- package/dist/chunks/{MyTenantsPage-D9f85zjF.js.map → MyTenantsPage-DqGW6aDt.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-DJR8h6y1.js → MyTicketsPage--DgDsnZA.js} +2 -2
- package/dist/chunks/{MyTicketsPage-DJR8h6y1.js.map → MyTicketsPage--DgDsnZA.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-DiOUExKJ.js → MyTicketsPage-CqJ3Aqob.js} +2 -2
- package/dist/chunks/{MyTicketsPage-DiOUExKJ.js.map → MyTicketsPage-CqJ3Aqob.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-CeHbxfZw.js → NavigationAppsPage-Bebis_RT.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-CeHbxfZw.js.map → NavigationAppsPage-Bebis_RT.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-If7tmCFY.js → NavigationAppsPage-THNPOAjv.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-If7tmCFY.js.map → NavigationAppsPage-THNPOAjv.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-C29Lln5o.js → NotificationsPage-CAbNW_Cn.js} +2 -2
- package/dist/chunks/{NotificationsPage-C29Lln5o.js.map → NotificationsPage-CAbNW_Cn.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-BiaLRb0s.js → NotificationsPage-DxwizUhL.js} +2 -2
- package/dist/chunks/{NotificationsPage-BiaLRb0s.js.map → NotificationsPage-DxwizUhL.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-DQrBKNBq.js → OnboardingWizardPage-C6HlbJ3K.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-DQrBKNBq.js.map → OnboardingWizardPage-C6HlbJ3K.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-BQah4cI8.js → OnboardingWizardPage-CyC2zONO.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-BQah4cI8.js.map → OnboardingWizardPage-CyC2zONO.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-Ckjdjvf9.js → PermissionDetailPage-BDHiNgky.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-Ckjdjvf9.js.map → PermissionDetailPage-BDHiNgky.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-Dh8v7mGj.js → PermissionDetailPage-C5K17ydY.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-Dh8v7mGj.js.map → PermissionDetailPage-C5K17ydY.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-l0PnY-EE.js → PermissionsPage-COI5LJPo.js} +2 -2
- package/dist/chunks/{PermissionsPage-l0PnY-EE.js.map → PermissionsPage-COI5LJPo.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-DLy9U3P3.js → PermissionsPage-CkOwH2_d.js} +2 -2
- package/dist/chunks/{PermissionsPage-DLy9U3P3.js.map → PermissionsPage-CkOwH2_d.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-DFBx38-x.js → PortalDashboardPage-CoEC4CmC.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-DFBx38-x.js.map → PortalDashboardPage-CoEC4CmC.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-rQYhrX0q.js → PortalDashboardPage-DrYymEf-.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-rQYhrX0q.js.map → PortalDashboardPage-DrYymEf-.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-BBu8yZQB.js → PreferencesPage-CJRaU3ba.js} +2 -2
- package/dist/chunks/{PreferencesPage-BBu8yZQB.js.map → PreferencesPage-CJRaU3ba.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-B81MsNV1.js → PreferencesPage-Cqr9mAab.js} +2 -2
- package/dist/chunks/{PreferencesPage-B81MsNV1.js.map → PreferencesPage-Cqr9mAab.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DDrl10zj.js → ProfilePage-BZVpg6-l.js} +2 -2
- package/dist/chunks/{ProfilePage-DDrl10zj.js.map → ProfilePage-BZVpg6-l.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DPoXwdnc.js → ProfilePage-Cu_FITeL.js} +2 -2
- package/dist/chunks/{ProfilePage-DPoXwdnc.js.map → ProfilePage-Cu_FITeL.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-eFsKjIEK.js → ReferencesManagementPage-DUlVk9Ps.js} +3 -3
- package/dist/chunks/{ReferencesManagementPage-eFsKjIEK.js.map → ReferencesManagementPage-DUlVk9Ps.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-DhVsuElE.js → ReferencesManagementPage-ZCuYtqd7.js} +2 -2
- package/dist/chunks/{ReferencesManagementPage-DhVsuElE.js.map → ReferencesManagementPage-ZCuYtqd7.js.map} +1 -1
- package/dist/chunks/{RegisterPage-CiQib3-6.js → RegisterPage-C4xmVwh9.js} +2 -2
- package/dist/chunks/{RegisterPage-CiQib3-6.js.map → RegisterPage-C4xmVwh9.js.map} +1 -1
- package/dist/chunks/{RegisterPage-bXCcJD88.js → RegisterPage-DGyzoIHT.js} +2 -2
- package/dist/chunks/{RegisterPage-bXCcJD88.js.map → RegisterPage-DGyzoIHT.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-Dqiahhnj.js → ResetPasswordPage-DqDD6VPR.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-Dqiahhnj.js.map → ResetPasswordPage-DqDD6VPR.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-CubPG3yv.js → ResetPasswordPage-Glu-aeqv.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-CubPG3yv.js.map → ResetPasswordPage-Glu-aeqv.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-Bg7XZmR1.js → ResolutionModal-CxjANAOP.js} +2 -2
- package/dist/chunks/{ResolutionModal-Bg7XZmR1.js.map → ResolutionModal-CxjANAOP.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-DqRk_T0n.js → ResolutionModal-Duat18qV.js} +2 -2
- package/dist/chunks/{ResolutionModal-DqRk_T0n.js.map → ResolutionModal-Duat18qV.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-Blau6_4c.js → RoleDetailPage-BQffUSnt.js} +3 -3
- package/dist/chunks/{RoleDetailPage-Blau6_4c.js.map → RoleDetailPage-BQffUSnt.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-CiRVxxIP.js → RoleDetailPage-JTm5lD1_.js} +2 -2
- package/dist/chunks/{RoleDetailPage-CiRVxxIP.js.map → RoleDetailPage-JTm5lD1_.js.map} +1 -1
- package/dist/chunks/{RolesPage-Pm-RN3lP.js → RolesPage-B9rRzciI.js} +2 -2
- package/dist/chunks/{RolesPage-Pm-RN3lP.js.map → RolesPage-B9rRzciI.js.map} +1 -1
- package/dist/chunks/{RolesPage-Cb8joqdJ.js → RolesPage-BN8_zMOC.js} +2 -2
- package/dist/chunks/{RolesPage-Cb8joqdJ.js.map → RolesPage-BN8_zMOC.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-B86McKM6.js → SlaConfigPage-B7kZNig4.js} +2 -2
- package/dist/chunks/{SlaConfigPage-B86McKM6.js.map → SlaConfigPage-B7kZNig4.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-BY7gvYU6.js → SlaConfigPage-okvZfA_K.js} +2 -2
- package/dist/chunks/{SlaConfigPage-BY7gvYU6.js.map → SlaConfigPage-okvZfA_K.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-BYxcLMSd.js → SupportPermissionsPage-DGAPqJbl.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-BYxcLMSd.js.map → SupportPermissionsPage-DGAPqJbl.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-MXqXNJIZ.js → SupportPermissionsPage-Dg_wLOme.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-MXqXNJIZ.js.map → SupportPermissionsPage-Dg_wLOme.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-BDguJ401.js → TemplatesPage-DT9fhlAU.js} +2 -2
- package/dist/chunks/{TemplatesPage-BDguJ401.js.map → TemplatesPage-DT9fhlAU.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-DdnGgioU.js → TemplatesPage-DiEk538p.js} +2 -2
- package/dist/chunks/{TemplatesPage-DdnGgioU.js.map → TemplatesPage-DiEk538p.js.map} +1 -1
- package/dist/chunks/{TenantCard-ffwWsgFQ.js → TenantCard-BbSYk9_Z.js} +2 -2
- package/dist/chunks/{TenantCard-ffwWsgFQ.js.map → TenantCard-BbSYk9_Z.js.map} +1 -1
- package/dist/chunks/{TenantCard-CUjb6og9.js → TenantCard-CEkiKxcZ.js} +2 -2
- package/dist/chunks/{TenantCard-CUjb6og9.js.map → TenantCard-CEkiKxcZ.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-Dz7i1I43.js → TenantScopeSelector-BWfYxvEa.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-Dz7i1I43.js.map → TenantScopeSelector-BWfYxvEa.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-Cym_Zyps.js → TenantScopeSelector-D-BKgQPV.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-Cym_Zyps.js.map → TenantScopeSelector-D-BKgQPV.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-GOh9GX7E.js → TicketDetailPage-C1mNS9Up.js} +2 -2
- package/dist/chunks/{TicketDetailPage-GOh9GX7E.js.map → TicketDetailPage-C1mNS9Up.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-Du8WMyqf.js → TicketDetailPage-ieVDRh42.js} +2 -2
- package/dist/chunks/{TicketDetailPage-Du8WMyqf.js.map → TicketDetailPage-ieVDRh42.js.map} +1 -1
- package/dist/chunks/{TicketsPage-Bqd6moQy.js → TicketsPage-CnuWsnIW.js} +2 -2
- package/dist/chunks/{TicketsPage-Bqd6moQy.js.map → TicketsPage-CnuWsnIW.js.map} +1 -1
- package/dist/chunks/{TicketsPage-WdU4Bb7M.js → TicketsPage-jjyY15_D.js} +2 -2
- package/dist/chunks/{TicketsPage-WdU4Bb7M.js.map → TicketsPage-jjyY15_D.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-Cm1emgwR.js → UserCreateTicketPage-B8Tvf-ag.js} +2 -2
- package/dist/chunks/{UserCreateTicketPage-Cm1emgwR.js.map → UserCreateTicketPage-B8Tvf-ag.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-BPw-5Y_D.js → UserCreateTicketPage-DnOsDlfO.js} +2 -2
- package/dist/chunks/{UserCreateTicketPage-BPw-5Y_D.js.map → UserCreateTicketPage-DnOsDlfO.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-BP5WeXPS.js → UserDashboardPage-BrtkJ-NB.js} +2 -2
- package/dist/chunks/{UserDashboardPage-BP5WeXPS.js.map → UserDashboardPage-BrtkJ-NB.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-B53C8fUq.js → UserDashboardPage-KLB5CQP5.js} +2 -2
- package/dist/chunks/{UserDashboardPage-B53C8fUq.js.map → UserDashboardPage-KLB5CQP5.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-B110bmGX.js → UserDetailPage-U7smBQoF.js} +5 -5
- package/dist/chunks/{UserDetailPage-B110bmGX.js.map → UserDetailPage-U7smBQoF.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-CV2VCE46.js → UserDetailPage-_J6lcKAU.js} +2 -2
- package/dist/chunks/{UserDetailPage-CV2VCE46.js.map → UserDetailPage-_J6lcKAU.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-CCNJON1V.js → UserTicketDetailPage-CWoYQgH-.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-CCNJON1V.js.map → UserTicketDetailPage-CWoYQgH-.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-V0mLXrox.js → UserTicketDetailPage-DkufSlvZ.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-V0mLXrox.js.map → UserTicketDetailPage-DkufSlvZ.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-CmdaU-z-.js → UsersGroupsPage-C38s2-Rq.js} +3 -3
- package/dist/chunks/{UsersGroupsPage-CmdaU-z-.js.map → UsersGroupsPage-C38s2-Rq.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-BgfAMgEP.js → UsersGroupsPage-Dq3rAteo.js} +2 -2
- package/dist/chunks/{UsersGroupsPage-BgfAMgEP.js.map → UsersGroupsPage-Dq3rAteo.js.map} +1 -1
- package/dist/chunks/{UsersPage-Bg7033pp.js → UsersPage-B5C5KEUR.js} +2 -2
- package/dist/chunks/{UsersPage-Bg7033pp.js.map → UsersPage-B5C5KEUR.js.map} +1 -1
- package/dist/chunks/{UsersPage-TYAfwPY1.js → UsersPage-CXC9Hvq6.js} +2 -2
- package/dist/chunks/{UsersPage-TYAfwPY1.js.map → UsersPage-CXC9Hvq6.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-DZeDvzwv.js → accessRequestsApi-B-4TJ5_U.js} +2 -2
- package/dist/chunks/{accessRequestsApi-DZeDvzwv.js.map → accessRequestsApi-B-4TJ5_U.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-ZXFPCid2.js → accessRequestsApi-DZSfThpd.js} +2 -2
- package/dist/chunks/{accessRequestsApi-ZXFPCid2.js.map → accessRequestsApi-DZSfThpd.js.map} +1 -1
- package/dist/chunks/{aiApi-CsH8DXgs.js → aiApi-B20Teu2v.js} +2 -2
- package/dist/chunks/{aiApi-CsH8DXgs.js.map → aiApi-B20Teu2v.js.map} +1 -1
- package/dist/chunks/{aiApi-CVPzFTXa.js → aiApi-DMGz-RPM.js} +2 -2
- package/dist/chunks/{aiApi-CVPzFTXa.js.map → aiApi-DMGz-RPM.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-B8AhFYLr.js → applicationAnalyticsApi-Bwa75Fzd.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-B8AhFYLr.js.map → applicationAnalyticsApi-Bwa75Fzd.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-Ce_1qOk-.js → applicationAnalyticsApi-CLBqRPfN.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-Ce_1qOk-.js.map → applicationAnalyticsApi-CLBqRPfN.js.map} +1 -1
- package/dist/chunks/{groupsApi-BgCk2fsp.js → groupsApi-QzXI-5xu.js} +2 -2
- package/dist/chunks/{groupsApi-BgCk2fsp.js.map → groupsApi-QzXI-5xu.js.map} +1 -1
- package/dist/chunks/{groupsApi-BIbG665N.js → groupsApi-hB9kSWEd.js} +2 -2
- package/dist/chunks/{groupsApi-BIbG665N.js.map → groupsApi-hB9kSWEd.js.map} +1 -1
- package/dist/chunks/{index-Cb3LotuT.js → index--NGcBYUu.js} +3 -3
- package/dist/chunks/{index-Cb3LotuT.js.map → index--NGcBYUu.js.map} +1 -1
- package/dist/chunks/{index-C33zcyF4.js → index--aPwOFjF.js} +2 -2
- package/dist/chunks/{index-C33zcyF4.js.map → index--aPwOFjF.js.map} +1 -1
- package/dist/chunks/{index-sMr9qND_.js → index-0VrOtwP0.js} +2 -2
- package/dist/chunks/{index-sMr9qND_.js.map → index-0VrOtwP0.js.map} +1 -1
- package/dist/chunks/{index-DDKetfKq.js → index-37U271aw.js} +2 -2
- package/dist/chunks/{index-DDKetfKq.js.map → index-37U271aw.js.map} +1 -1
- package/dist/chunks/{index-B9fS7ir6.js → index-B7qZTuQ-.js} +2 -2
- package/dist/chunks/{index-B9fS7ir6.js.map → index-B7qZTuQ-.js.map} +1 -1
- package/dist/chunks/{index-CdjBY7L8.js → index-Bedzmqr-.js} +2 -2
- package/dist/chunks/{index-CdjBY7L8.js.map → index-Bedzmqr-.js.map} +1 -1
- package/dist/chunks/{index-CHG_O1fS.js → index-Betxo5g5.js} +2 -2
- package/dist/chunks/{index-CHG_O1fS.js.map → index-Betxo5g5.js.map} +1 -1
- package/dist/chunks/{index-jiGu-H8x.js → index-BmaJz475.js} +2 -2
- package/dist/chunks/{index-jiGu-H8x.js.map → index-BmaJz475.js.map} +1 -1
- package/dist/chunks/{index-C53JoVNk.js → index-Buhqag3v.js} +2 -2
- package/dist/chunks/{index-C53JoVNk.js.map → index-Buhqag3v.js.map} +1 -1
- package/dist/chunks/{index-DO0Rw7hX.js → index-C3VxlfKq.js} +2 -2
- package/dist/chunks/{index-DO0Rw7hX.js.map → index-C3VxlfKq.js.map} +1 -1
- package/dist/chunks/{index-CSQ60fpG.js → index-CgpRo8Oe.js} +2 -2
- package/dist/chunks/{index-CSQ60fpG.js.map → index-CgpRo8Oe.js.map} +1 -1
- package/dist/chunks/{index-B-e-ELsf.js → index-DOY0w8Iu.js} +8 -8
- package/dist/chunks/{index-B-e-ELsf.js.map → index-DOY0w8Iu.js.map} +1 -1
- package/dist/chunks/{index-D2REDIRX.js → index-DwuvIOrQ.js} +2 -2
- package/dist/chunks/{index-D2REDIRX.js.map → index-DwuvIOrQ.js.map} +1 -1
- package/dist/chunks/{index-DCcl7Qof.js → index-DzedSLdI.js} +2 -2
- package/dist/chunks/{index-DCcl7Qof.js.map → index-DzedSLdI.js.map} +1 -1
- package/dist/chunks/{index-2wUhd9Lu.js → index-IgLVXPg8.js} +10 -10
- package/dist/chunks/index-IgLVXPg8.js.map +1 -0
- package/dist/chunks/{index-CwSaRXXg.js → index-lpIzhufD.js} +1916 -1900
- package/dist/chunks/index-lpIzhufD.js.map +1 -0
- package/dist/chunks/{index-Cuwn2q-f.js → index-mLUKwbGl.js} +4 -4
- package/dist/chunks/{index-Cuwn2q-f.js.map → index-mLUKwbGl.js.map} +1 -1
- package/dist/chunks/{index-B0mk2tNY.js → index-tO6MMIFB.js} +2 -2
- package/dist/chunks/{index-B0mk2tNY.js.map → index-tO6MMIFB.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-BpNANQ5s.js → tenantIconMap-BQD9byc8.js} +2 -2
- package/dist/chunks/{tenantIconMap-BpNANQ5s.js.map → tenantIconMap-BQD9byc8.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-DtdUgvJO.js → tenantIconMap-CTMuSt18.js} +2 -2
- package/dist/chunks/{tenantIconMap-DtdUgvJO.js.map → tenantIconMap-CTMuSt18.js.map} +1 -1
- package/dist/chunks/{ticketingApi-Bu4rKwLl.js → ticketingApi-BNIdox5t.js} +2 -2
- package/dist/chunks/{ticketingApi-Bu4rKwLl.js.map → ticketingApi-BNIdox5t.js.map} +1 -1
- package/dist/chunks/{ticketingApi-r4Avm9iS.js → ticketingApi-J0vC_t7r.js} +2 -2
- package/dist/chunks/{ticketingApi-r4Avm9iS.js.map → ticketingApi-J0vC_t7r.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-B9bF4swg.js → useAccessRequests-DCNNLnxk.js} +3 -3
- package/dist/chunks/{useAccessRequests-B9bF4swg.js.map → useAccessRequests-DCNNLnxk.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-JyPUX3Om.js → useAccessRequests-DT7X4FAK.js} +2 -2
- package/dist/chunks/{useAccessRequests-JyPUX3Om.js.map → useAccessRequests-DT7X4FAK.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-DjPQenC2.js → useUserAccessRequests-BYbmG4c7.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-DjPQenC2.js.map → useUserAccessRequests-BYbmG4c7.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-BB6FHW14.js → useUserAccessRequests-CylKxRN6.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-BB6FHW14.js.map → useUserAccessRequests-CylKxRN6.js.map} +1 -1
- package/dist/hooks/useCollapsibleState.d.ts +5 -2
- package/dist/hooks/useCollapsibleState.d.ts.map +1 -1
- package/dist/i18n/config.d.ts +1 -0
- package/dist/i18n/config.d.ts.map +1 -1
- package/dist/main.d.ts +0 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/smartstack.cjs +1 -1
- package/dist/smartstack.js +1 -1
- package/dist/utils/permissions.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/index-2wUhd9Lu.js.map +0 -1
- package/dist/chunks/index-CwSaRXXg.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),D=require("react"),$=require("react-i18next"),S=require("react-router-dom"),I=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),D=require("react"),$=require("react-i18next"),S=require("react-router-dom"),I=require("./index-IgLVXPg8.js"),a=require("lucide-react"),E=[{id:"infrastructure",labelKey:"appsettings.tabs.infrastructure",icon:a.Server,route:"/administration/configuration/appsettings/infrastructure"},{id:"authentication",labelKey:"appsettings.tabs.authentication",icon:a.Shield,route:"/administration/configuration/appsettings/authentication"},{id:"logging",labelKey:"appsettings.tabs.logging",icon:a.FileText,route:"/administration/configuration/appsettings/logging"},{id:"email",labelKey:"appsettings.tabs.email",icon:a.Mail,route:"/administration/configuration/appsettings/email"},{id:"entra",labelKey:"appsettings.tabs.entra",icon:a.Cloud,route:"/administration/configuration/appsettings/entra"}];function L(){const{t}=$.useTranslation("admin"),y=S.useNavigate(),l=S.useLocation(),[x,u]=D.useState([]),[h,v]=D.useState(!0),f=D.useCallback(async()=>{try{v(!0);const d=(await I.adminApi.settings.getAll()).filter(o=>o.source==="AppSettings"||o.source==="Environment"||o.source==="Computed");u(d)}catch(s){console.error("Failed to load settings:",s)}finally{v(!1)}},[]);D.useEffect(()=>{f()},[f]);const c=()=>{const s=l.pathname;return E.find(o=>s.includes(o.id))?.id||"infrastructure"},i=s=>{const d=E.find(o=>o.id===s);d&&y(d.route)};return h?e.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:e.jsx(a.Loader2,{className:"w-8 h-8 animate-spin text-[var(--color-accent-600)]"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsx(I.Breadcrumb,{items:[{label:t("header.title"),href:"/administration"},{label:t("appsettings.title","Application Settings")}]}),e.jsx("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:t("appsettings.title")}),e.jsx("p",{className:"text-[var(--text-secondary)] mt-1",children:t("appsettings.subtitle")})]})}),e.jsx("div",{className:"bg-[var(--info-bg)] border border-[var(--info-border)] rounded-[var(--radius-card)] p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(a.Info,{className:"w-5 h-5 text-[var(--info-text)] flex-shrink-0 mt-0.5"}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-medium text-[var(--info-text)]",children:t("appsettings.readonlyBannerTitle")}),e.jsx("p",{className:"text-sm text-[var(--info-text)] opacity-90 mt-1",children:t("appsettings.readonlyBannerDescription")})]})]})}),e.jsx("div",{className:"border-b border-[var(--border-color)]",children:e.jsx("nav",{className:"-mb-px flex space-x-8","aria-label":"Tabs",children:E.map(s=>{const d=s.icon,o=c()===s.id;return e.jsxs("button",{onClick:()=>i(s.id),className:`
|
|
2
2
|
group inline-flex items-center py-4 px-1 border-b-2 font-medium text-sm transition-colors
|
|
3
3
|
${o?"border-[var(--color-accent-500)] text-[var(--color-accent-600)]":"border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:border-[var(--border-color)]"}
|
|
4
4
|
`,children:[e.jsx(d,{className:`mr-2 h-5 w-5 ${o?"text-[var(--color-accent-500)]":"text-[var(--text-tertiary)] group-hover:text-[var(--text-secondary)]"}`}),t(s.labelKey)]},s.id)})})}),e.jsx(S.Outlet,{context:{settings:x,refreshSettings:f}})]})}function T(){const{t}=$.useTranslation("admin"),{settings:y}=S.useOutletContext(),l=y.filter(r=>r.category==="Database"),x=y.filter(r=>r.category==="Storage"),u=x.filter(r=>r.key.startsWith("Local")||r.key==="Provider"),h=x.filter(r=>r.key.startsWith("Azure")),v=x.find(r=>r.key==="Provider")?.value,f=l.find(r=>r.key==="Server")?.value,c=l.find(r=>r.key==="DatabaseName")?.value,i=v==="Azure",s=v==="Local"||v==="FileSystem",d=r=>{const n=`${r.category}.${r.key}`,m=()=>{if(r.isSensitive)return"********";const g=r.displayValue||r.value;return r.valueType==="Bool"?t(g==="true"||g==="Yes"?"common.yes":"common.no"):g};return e.jsxs("div",{className:"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0",children:[e.jsxs("div",{className:"flex-1 min-w-0 pr-4",children:[e.jsx("span",{className:"font-medium text-[var(--text-primary)]",children:t(`appsettings.keys.${r.category}.${r.key}`,r.key)}),r.description&&e.jsx("p",{className:"text-sm text-[var(--text-secondary)] mt-1",children:t(`appsettings.descriptions.${r.category}.${r.key}`,r.description)})]}),e.jsx("div",{className:"text-right max-w-[50%]",children:e.jsx("span",{className:`font-mono text-sm break-all ${r.isSensitive?"text-[var(--text-tertiary)]":"text-[var(--text-primary)]"}`,children:m()})})]},n)},o=(r,n,m,g,p,b,j="neutral",N)=>{const k=g;if(m.length===0)return null;const C=j==="inactive",A=j==="active";let w="border-[var(--border-color)]";return A?w="border-green-500/50 ring-1 ring-green-500/20":C&&(w="border-gray-400/30"),e.jsxs("div",{className:`rounded-[var(--radius-card)] border ${w} bg-[var(--bg-card)] overflow-hidden shadow-sm ${C?"opacity-50":""}`,children:[e.jsx("div",{className:`px-6 py-4 bg-gradient-to-r ${p} border-b border-[var(--border-color)]`,children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${b}`,children:e.jsx(k,{className:"w-5 h-5"})}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-lg font-semibold text-[var(--text-primary)]",children:r}),A&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30",children:[e.jsx(a.CheckCircle2,{className:"w-3 h-3"}),t("appsettings.active","Actif")]}),C&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30",children:[e.jsx(a.CircleSlash,{className:"w-3 h-3"}),t("appsettings.notUsed","Non utilisé")]}),N&&e.jsxs("span",{className:"text-xs text-[var(--text-secondary)] ml-1",children:["(",N,")"]})]}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:n})]})]})}),e.jsx("div",{className:"px-6 py-2",children:m.map(d)})]})};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4",children:[e.jsx("div",{className:"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1",children:t("appsettings.sections.database","Database")}),e.jsxs("div",{className:"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2",children:[e.jsx(a.Database,{className:"w-5 h-5 text-cyan-500"}),c||"N/A"]}),e.jsx("div",{className:"text-xs text-[var(--text-secondary)] mt-1",children:f})]}),e.jsxs("div",{className:"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4",children:[e.jsx("div",{className:"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1",children:t("appsettings.keys.Storage.Provider","Storage Provider")}),e.jsxs("div",{className:"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2",children:[i?e.jsx(a.Cloud,{className:"w-5 h-5 text-sky-500"}):e.jsx(a.HardDrive,{className:"w-5 h-5 text-blue-500"}),v||"N/A"]})]})]}),o(t("appsettings.sections.database","Database"),t("appsettings.sections.databaseDescription","SQL Server database configuration"),l,a.Database,"from-cyan-500/10 to-cyan-600/5","bg-cyan-500/20 text-cyan-600","active"),o(t("appsettings.sections.localStorage","Local Storage"),t("appsettings.sections.localStorageDescription","File system storage configuration"),u.filter(r=>r.key!=="Provider"),a.HardDrive,s?"from-green-500/10 to-green-600/5":"from-gray-500/10 to-gray-600/5",s?"bg-green-500/20 text-green-600":"bg-gray-500/20 text-gray-500",s?"active":"inactive",s?v:void 0),o(t("appsettings.sections.azureStorage","Azure Blob Storage"),t("appsettings.sections.azureStorageDescription","Cloud storage configuration"),h,a.Cloud,i?"from-green-500/10 to-green-600/5":"from-gray-500/10 to-gray-600/5",i?"bg-green-500/20 text-green-600":"bg-gray-500/20 text-gray-500",i?"active":"inactive",i?"Azure":void 0),l.length===0&&x.length===0&&e.jsx("div",{className:"text-center py-12 text-[var(--text-secondary)]",children:t("appsettings.noSettings")})]})}const V=()=>e.jsx("svg",{className:"w-5 h-5",viewBox:"0 0 24 24",fill:"currentColor",children:e.jsx("path",{d:"M11.4 24H0V12.6h11.4V24zM24 24H12.6V12.6H24V24zM11.4 11.4H0V0h11.4v11.4zm12.6 0H12.6V0H24v11.4z"})}),M=()=>e.jsxs("svg",{className:"w-5 h-5",viewBox:"0 0 24 24",fill:"currentColor",children:[e.jsx("path",{d:"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"}),e.jsx("path",{d:"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"}),e.jsx("path",{d:"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"}),e.jsx("path",{d:"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"})]});function F(){const{t}=$.useTranslation("admin"),{settings:y}=S.useOutletContext(),l=y.filter(s=>s.category==="Authentication"),x=y.filter(s=>s.category==="Session"),u=l.filter(s=>s.key.startsWith("Jwt")||s.key.includes("Token")),h=l.find(s=>s.key==="MicrosoftOAuth")?.value==="true",v=l.find(s=>s.key==="GoogleOAuth")?.value==="true",f=s=>{const d=`${s.category}.${s.key}`,o=()=>{if(s.isSensitive)return"********";const r=s.displayValue||s.value;return s.valueType==="Bool"?t(r==="true"||r==="Yes"?"common.yes":"common.no"):r};return e.jsxs("div",{className:"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0",children:[e.jsxs("div",{className:"flex-1 min-w-0 pr-4",children:[e.jsx("span",{className:"font-medium text-[var(--text-primary)]",children:t(`appsettings.keys.Authentication.${s.key}`,{defaultValue:s.key})}),s.description&&e.jsx("p",{className:"text-sm text-[var(--text-secondary)] mt-1",children:t(`appsettings.descriptions.Authentication.${s.key}`,{defaultValue:s.description})})]}),e.jsx("div",{className:"text-right max-w-[50%]",children:e.jsx("span",{className:`font-mono text-sm break-all ${s.isSensitive?"text-[var(--text-tertiary)]":"text-[var(--text-primary)]"}`,children:o()})})]},d)},c=(s,d,o,r,n,m,g="neutral",p)=>{const b=r;if(o.length===0)return null;const j=g==="inactive",N=g==="active";let k="border-[var(--border-color)]";return N?k="border-green-500/50 ring-1 ring-green-500/20":j&&(k="border-gray-400/30"),e.jsxs("div",{className:`rounded-[var(--radius-card)] border ${k} bg-[var(--bg-card)] overflow-hidden shadow-sm ${j?"opacity-50":""}`,children:[e.jsx("div",{className:`px-6 py-4 bg-gradient-to-r ${n} border-b border-[var(--border-color)]`,children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${m}`,children:e.jsx(b,{className:"w-5 h-5"})}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-lg font-semibold text-[var(--text-primary)]",children:s}),N&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30",children:[e.jsx(a.CheckCircle2,{className:"w-3 h-3"}),t("appsettings.configured","Configuré")]}),j&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30",children:[e.jsx(a.CircleSlash,{className:"w-3 h-3"}),t("appsettings.notConfigured","Non configuré")]}),p]}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:d})]})]})}),e.jsx("div",{className:"px-6 py-2",children:o.map(f)})]})},i=(s,d,o,r)=>e.jsx("div",{className:`rounded-lg border ${d?"border-green-500/50 ring-1 ring-green-500/20":"border-gray-400/30 opacity-50"} bg-[var(--bg-card)] p-4`,children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${r}`,children:e.jsx(o,{})}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-semibold text-[var(--text-primary)]",children:s}),d?e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30",children:[e.jsx(a.CheckCircle2,{className:"w-3 h-3"}),t("appsettings.configured","Configuré")]}):e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30",children:[e.jsx(a.CircleSlash,{className:"w-3 h-3"}),t("appsettings.notConfigured","Non configuré")]})]}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)] mt-1",children:d?t("appsettings.oauthConfiguredDesc","OAuth authentication is enabled"):t("appsettings.oauthNotConfiguredDesc","ClientId not configured in appsettings.json")})]})]})});return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold text-[var(--text-primary)] mb-4",children:t("appsettings.sections.oauthProviders","OAuth Providers")}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[i("Microsoft",h,V,"bg-blue-500/20 text-blue-600"),i("Google",v,M,"bg-red-500/20 text-red-600")]})]}),c(t("appsettings.sections.jwt","JWT Configuration"),t("appsettings.sections.jwtDescription","JSON Web Token settings for authentication"),u,a.Key,"from-violet-500/10 to-violet-600/5","bg-violet-500/20 text-violet-600","active"),c(t("appsettings.sections.session","Session"),t("appsettings.sections.sessionDescription","User session timeout and validation settings"),x,a.Clock,"from-amber-500/10 to-amber-600/5","bg-amber-500/20 text-amber-600","active"),l.length===0&&x.length===0&&e.jsx("div",{className:"text-center py-12 text-[var(--text-secondary)]",children:t("appsettings.noSettings")})]})}function z(){const{t}=$.useTranslation("admin"),{settings:y}=S.useOutletContext(),l=y.filter(n=>n.category==="Logging"),x=l.filter(n=>n.key.includes("File")||n.key.includes("Rolling")||n.key.includes("Retention")),u=l.filter(n=>n.key.includes("Seq")),h=l.filter(n=>n.key.includes("AppInsights")),v=l.filter(n=>n.key.includes("Level")||n.key.includes("Minimum")),f=l.find(n=>n.key==="ConsoleEnabled")?.value==="true",c=l.find(n=>n.key==="FileEnabled")?.value==="true",i=l.find(n=>n.key==="SeqEnabled")?.value==="true",s=l.find(n=>n.key==="AppInsightsEnabled")?.value==="true",d=n=>{const m=`${n.category}.${n.key}`,g=()=>{if(n.isSensitive)return"********";const p=n.displayValue||n.value;return n.valueType==="Bool"?t(p==="true"||p==="Yes"?"common.yes":"common.no"):p};return e.jsxs("div",{className:"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0",children:[e.jsxs("div",{className:"flex-1 min-w-0 pr-4",children:[e.jsx("span",{className:"font-medium text-[var(--text-primary)]",children:t(`appsettings.keys.Logging.${n.key}`,n.key)}),n.description&&e.jsx("p",{className:"text-sm text-[var(--text-secondary)] mt-1",children:t(`appsettings.descriptions.Logging.${n.key}`,n.description)})]}),e.jsx("div",{className:"text-right max-w-[50%]",children:e.jsx("span",{className:`font-mono text-sm break-all ${n.isSensitive?"text-[var(--text-tertiary)]":"text-[var(--text-primary)]"}`,children:g()})})]},m)},o=(n,m,g,p,b,j,N="neutral")=>{const k=p;if(g.length===0)return null;const C=N==="inactive",A=N==="active";let w="border-[var(--border-color)]";return A?w="border-green-500/50 ring-1 ring-green-500/20":C&&(w="border-gray-400/30"),e.jsxs("div",{className:`rounded-[var(--radius-card)] border ${w} bg-[var(--bg-card)] overflow-hidden shadow-sm ${C?"opacity-50":""}`,children:[e.jsx("div",{className:`px-6 py-4 bg-gradient-to-r ${b} border-b border-[var(--border-color)]`,children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${j}`,children:e.jsx(k,{className:"w-5 h-5"})}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-lg font-semibold text-[var(--text-primary)]",children:n}),A&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30",children:[e.jsx(a.CheckCircle2,{className:"w-3 h-3"}),t("appsettings.enabled","Activé")]}),C&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30",children:[e.jsx(a.CircleSlash,{className:"w-3 h-3"}),t("appsettings.disabled","Désactivé")]})]}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:m})]})]})}),e.jsx("div",{className:"px-6 py-2",children:g.map(d)})]})},r=(n,m,g,p)=>{const b=g;return e.jsx("div",{className:`rounded-lg border ${m?"border-green-500/50":"border-gray-400/30 opacity-50"} bg-[var(--bg-card)] p-4`,children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${p}`,children:e.jsx(b,{className:"w-5 h-5"})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("span",{className:"font-semibold text-[var(--text-primary)]",children:n}),m?e.jsxs("span",{className:"ml-2 inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400",children:[e.jsx(a.CheckCircle2,{className:"w-3 h-3"}),t("appsettings.enabled","Activé")]}):e.jsxs("span",{className:"ml-2 inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400",children:[e.jsx(a.CircleSlash,{className:"w-3 h-3"}),t("appsettings.disabled","Désactivé")]})]})]})})};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold text-[var(--text-primary)] mb-4",children:t("appsettings.sections.loggingSinks","Logging Sinks")}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4",children:[r("Console",f,a.Monitor,"bg-gray-500/20 text-gray-600"),r("File",c,a.FileText,"bg-violet-500/20 text-violet-600"),r("Seq",i,a.Database,"bg-blue-500/20 text-blue-600"),r("App Insights",s,a.BarChart3,"bg-purple-500/20 text-purple-600")]})]}),o(t("appsettings.sections.logLevels","Log Levels"),t("appsettings.sections.logLevelsDescription","Minimum log level configuration"),v,a.BarChart3,"from-emerald-500/10 to-emerald-600/5","bg-emerald-500/20 text-emerald-600","neutral"),o(t("appsettings.sections.fileLogging","File Logging"),t("appsettings.sections.fileLoggingDescription","File-based log output configuration"),x,a.FileText,c?"from-violet-500/10 to-violet-600/5":"from-gray-500/10 to-gray-600/5",c?"bg-violet-500/20 text-violet-600":"bg-gray-500/20 text-gray-500",c?"active":"inactive"),u.length>0&&o(t("appsettings.sections.seqLogging","Seq"),t("appsettings.sections.seqLoggingDescription","Seq structured logging server"),u,a.Database,i?"from-blue-500/10 to-blue-600/5":"from-gray-500/10 to-gray-600/5",i?"bg-blue-500/20 text-blue-600":"bg-gray-500/20 text-gray-500",i?"active":"inactive"),h.length>0&&o(t("appsettings.sections.appInsights","Application Insights"),t("appsettings.sections.appInsightsDescription","Azure Application Insights telemetry"),h,a.BarChart3,s?"from-purple-500/10 to-purple-600/5":"from-gray-500/10 to-gray-600/5",s?"bg-purple-500/20 text-purple-600":"bg-gray-500/20 text-gray-500",s?"active":"inactive"),l.length===0&&e.jsx("div",{className:"text-center py-12 text-[var(--text-secondary)]",children:t("appsettings.noSettings")})]})}function P(){const{t}=$.useTranslation("admin"),{settings:y}=S.useOutletContext(),l=y.filter(c=>c.category==="Email"),x=l.find(c=>c.key==="Enabled")?.value==="true",u=l.find(c=>c.key==="Provider")?.value,h=l.find(c=>c.key==="FromEmail")?.value,v=c=>{const i=`${c.category}.${c.key}`,s=()=>{if(c.isSensitive)return"********";const d=c.displayValue||c.value;return c.valueType==="Bool"?t(d==="true"||d==="Yes"?"common.yes":"common.no"):d};return e.jsxs("div",{className:"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0",children:[e.jsxs("div",{className:"flex-1 min-w-0 pr-4",children:[e.jsx("span",{className:"font-medium text-[var(--text-primary)]",children:t(`appsettings.keys.Email.${c.key}`,c.key)}),c.description&&e.jsx("p",{className:"text-sm text-[var(--text-secondary)] mt-1",children:t(`appsettings.descriptions.Email.${c.key}`,c.description)})]}),e.jsx("div",{className:"text-right max-w-[50%]",children:e.jsx("span",{className:`font-mono text-sm break-all ${c.isSensitive?"text-[var(--text-tertiary)]":"text-[var(--text-primary)]"}`,children:s()})})]},i)},f=(c,i,s,d,o,r,n="neutral")=>{const m=d;if(s.length===0)return null;const g=n==="inactive",p=n==="active";let b="border-[var(--border-color)]";return p?b="border-green-500/50 ring-1 ring-green-500/20":g&&(b="border-gray-400/30"),e.jsxs("div",{className:`rounded-[var(--radius-card)] border ${b} bg-[var(--bg-card)] overflow-hidden shadow-sm ${g?"opacity-50":""}`,children:[e.jsx("div",{className:`px-6 py-4 bg-gradient-to-r ${o} border-b border-[var(--border-color)]`,children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${r}`,children:e.jsx(m,{className:"w-5 h-5"})}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-lg font-semibold text-[var(--text-primary)]",children:c}),p&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30",children:[e.jsx(a.CheckCircle2,{className:"w-3 h-3"}),t("appsettings.enabled","Activé")]}),g&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30",children:[e.jsx(a.CircleSlash,{className:"w-3 h-3"}),t("appsettings.disabled","Désactivé")]})]}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:i})]})]})}),e.jsx("div",{className:"px-6 py-2",children:s.map(v)})]})};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsxs("div",{className:`rounded-lg border ${x?"border-green-500/50":"border-gray-400/30 opacity-50"} bg-[var(--bg-card)] p-4`,children:[e.jsx("div",{className:"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1",children:t("appsettings.status","Status")}),e.jsx("div",{className:"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2",children:x?e.jsxs(e.Fragment,{children:[e.jsx(a.CheckCircle2,{className:"w-5 h-5 text-green-500"}),t("appsettings.enabled","Activé")]}):e.jsxs(e.Fragment,{children:[e.jsx(a.CircleSlash,{className:"w-5 h-5 text-gray-500"}),t("appsettings.disabled","Désactivé")]})})]}),e.jsxs("div",{className:"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4",children:[e.jsx("div",{className:"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1",children:t("appsettings.keys.Email.Provider","Provider")}),e.jsxs("div",{className:"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2",children:[e.jsx(a.Send,{className:"w-5 h-5 text-amber-500"}),u||"N/A"]})]}),e.jsxs("div",{className:"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4",children:[e.jsx("div",{className:"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1",children:t("appsettings.keys.Email.FromEmail","From Email")}),e.jsxs("div",{className:"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2",children:[e.jsx(a.Mail,{className:"w-5 h-5 text-amber-500"}),e.jsx("span",{className:"truncate",children:h||"N/A"})]})]})]}),f(t("appsettings.sections.emailConfiguration","Email Configuration"),t("appsettings.sections.emailConfigurationDescription","SMTP and email provider settings"),l,a.Mail,x?"from-amber-500/10 to-amber-600/5":"from-gray-500/10 to-gray-600/5",x?"bg-amber-500/20 text-amber-600":"bg-gray-500/20 text-gray-500",x?"active":"inactive"),l.length===0&&e.jsx("div",{className:"text-center py-12 text-[var(--text-secondary)]",children:t("appsettings.noSettings")})]})}function q(){const{t}=$.useTranslation("admin"),{settings:y}=S.useOutletContext(),l=y.filter(i=>i.category==="Entra"),x=l.find(i=>i.key==="SyncEnabled")?.value==="true",u=l.find(i=>i.key==="Configured")?.value==="true",h=l.find(i=>i.key==="SyncIntervalMinutes")?.value,v=l.find(i=>i.key==="UseDeltaSync")?.value==="true",f=i=>{const s=`${i.category}.${i.key}`,d=()=>{if(i.isSensitive)return"********";const o=i.displayValue||i.value;return i.valueType==="Bool"?t(o==="true"||o==="Yes"?"common.yes":"common.no"):o};return e.jsxs("div",{className:"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0",children:[e.jsxs("div",{className:"flex-1 min-w-0 pr-4",children:[e.jsx("span",{className:"font-medium text-[var(--text-primary)]",children:t(`appsettings.keys.Entra.${i.key}`,i.key)}),i.description&&e.jsx("p",{className:"text-sm text-[var(--text-secondary)] mt-1",children:t(`appsettings.descriptions.Entra.${i.key}`,i.description)})]}),e.jsx("div",{className:"text-right max-w-[50%]",children:e.jsx("span",{className:`font-mono text-sm break-all ${i.isSensitive?"text-[var(--text-tertiary)]":"text-[var(--text-primary)]"}`,children:d()})})]},s)},c=(i,s,d,o,r,n,m="neutral")=>{const g=o;if(d.length===0)return null;const p=m==="inactive",b=m==="active";let j="border-[var(--border-color)]";return b?j="border-green-500/50 ring-1 ring-green-500/20":p&&(j="border-gray-400/30"),e.jsxs("div",{className:`rounded-[var(--radius-card)] border ${j} bg-[var(--bg-card)] overflow-hidden shadow-sm ${p?"opacity-50":""}`,children:[e.jsx("div",{className:`px-6 py-4 bg-gradient-to-r ${r} border-b border-[var(--border-color)]`,children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${n}`,children:e.jsx(g,{className:"w-5 h-5"})}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-lg font-semibold text-[var(--text-primary)]",children:i}),b&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30",children:[e.jsx(a.CheckCircle2,{className:"w-3 h-3"}),t("appsettings.enabled","Activé")]}),p&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30",children:[e.jsx(a.CircleSlash,{className:"w-3 h-3"}),t("appsettings.disabled","Désactivé")]})]}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:s})]})]})}),e.jsx("div",{className:"px-6 py-2",children:d.map(f)})]})};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-4",children:[e.jsxs("div",{className:`rounded-lg border ${u?"border-green-500/50":"border-gray-400/30 opacity-50"} bg-[var(--bg-card)] p-4`,children:[e.jsx("div",{className:"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1",children:t("appsettings.configuration","Configuration")}),e.jsx("div",{className:"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2",children:u?e.jsxs(e.Fragment,{children:[e.jsx(a.CheckCircle2,{className:"w-5 h-5 text-green-500"}),t("appsettings.configured","Configuré")]}):e.jsxs(e.Fragment,{children:[e.jsx(a.CircleSlash,{className:"w-5 h-5 text-gray-500"}),t("appsettings.notConfigured","Non configuré")]})})]}),e.jsxs("div",{className:`rounded-lg border ${x?"border-green-500/50":"border-gray-400/30 opacity-50"} bg-[var(--bg-card)] p-4`,children:[e.jsx("div",{className:"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1",children:t("appsettings.keys.Entra.SyncEnabled","Sync Status")}),e.jsxs("div",{className:"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2",children:[e.jsx(a.RefreshCw,{className:`w-5 h-5 ${x?"text-green-500":"text-gray-500"}`}),x?t("appsettings.enabled","Activé"):t("appsettings.disabled","Désactivé")]})]}),e.jsxs("div",{className:"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4",children:[e.jsx("div",{className:"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1",children:t("appsettings.keys.Entra.SyncIntervalMinutes","Sync Interval")}),e.jsxs("div",{className:"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2",children:[e.jsx(a.Cloud,{className:"w-5 h-5 text-sky-500"}),h?`${h} min`:"N/A"]})]}),e.jsxs("div",{className:`rounded-lg border ${v?"border-green-500/50":"border-[var(--border-color)]"} bg-[var(--bg-card)] p-4`,children:[e.jsx("div",{className:"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1",children:t("appsettings.keys.Entra.UseDeltaSync","Delta Sync")}),e.jsx("div",{className:"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2",children:v?e.jsxs(e.Fragment,{children:[e.jsx(a.CheckCircle2,{className:"w-5 h-5 text-green-500"}),t("common.yes","Oui")]}):e.jsxs(e.Fragment,{children:[e.jsx(a.CircleSlash,{className:"w-5 h-5 text-gray-500"}),t("common.no","Non")]})})]})]}),c(t("appsettings.sections.entraConfiguration","Microsoft Entra ID"),t("appsettings.sections.entraConfigurationDescription","Azure AD synchronization settings"),l,a.Cloud,u?"from-sky-500/10 to-sky-600/5":"from-gray-500/10 to-gray-600/5",u?"bg-sky-500/20 text-sky-600":"bg-gray-500/20 text-gray-500",u?"active":"inactive"),l.length===0&&e.jsx("div",{className:"text-center py-12 text-[var(--text-secondary)]",children:t("appsettings.noSettings")})]})}exports.AppSettingsPage=L;exports.AuthenticationSection=F;exports.EmailSection=P;exports.EntraSection=q;exports.InfrastructureSection=T;exports.LoggingSection=z;
|
|
5
|
-
//# sourceMappingURL=index
|
|
5
|
+
//# sourceMappingURL=index--aPwOFjF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-C33zcyF4.js","sources":["../../src/pages/platform/administration/configuration/appsettings/AppSettingsPage.tsx","../../src/pages/platform/administration/configuration/appsettings/InfrastructureSection.tsx","../../src/pages/platform/administration/configuration/appsettings/AuthenticationSection.tsx","../../src/pages/platform/administration/configuration/appsettings/LoggingSection.tsx","../../src/pages/platform/administration/configuration/appsettings/EmailSection.tsx","../../src/pages/platform/administration/configuration/appsettings/EntraSection.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 { Server, Shield, FileText, Mail, Cloud, Loader2, Info } 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: 'infrastructure', labelKey: 'appsettings.tabs.infrastructure', icon: Server, route: '/administration/configuration/appsettings/infrastructure' },\r\n { id: 'authentication', labelKey: 'appsettings.tabs.authentication', icon: Shield, route: '/administration/configuration/appsettings/authentication' },\r\n { id: 'logging', labelKey: 'appsettings.tabs.logging', icon: FileText, route: '/administration/configuration/appsettings/logging' },\r\n { id: 'email', labelKey: 'appsettings.tabs.email', icon: Mail, route: '/administration/configuration/appsettings/email' },\r\n { id: 'entra', labelKey: 'appsettings.tabs.entra', icon: Cloud, route: '/administration/configuration/appsettings/entra' }\r\n];\r\n\r\nexport function AppSettingsPage(): 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 // Filter only AppSettings and Environment sources (readonly)\r\n const readonlySettings = result.filter(s =>\r\n s.source === 'AppSettings' || s.source === 'Environment' || s.source === 'Computed'\r\n );\r\n setSettings(readonlySettings);\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 || 'infrastructure';\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('appsettings.title', 'Application 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('appsettings.title')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)] mt-1\">\r\n {t('appsettings.subtitle')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Info Banner */}\r\n <div className=\"bg-[var(--info-bg)] border border-[var(--info-border)] rounded-[var(--radius-card)] p-4\">\r\n <div className=\"flex items-start gap-3\">\r\n <Info className=\"w-5 h-5 text-[var(--info-text)] flex-shrink-0 mt-0.5\" />\r\n <div>\r\n <h4 className=\"font-medium text-[var(--info-text)]\">\r\n {t('appsettings.readonlyBannerTitle')}\r\n </h4>\r\n <p className=\"text-sm text-[var(--info-text)] opacity-90 mt-1\">\r\n {t('appsettings.readonlyBannerDescription')}\r\n </p>\r\n </div>\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 AppSettingsPage;\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { Database, HardDrive, Cloud, CheckCircle2, CircleSlash } from 'lucide-react';\r\nimport { type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\ntype SectionStatus = 'active' | 'inactive' | 'neutral';\r\n\r\nexport function InfrastructureSection(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { settings } = useOutletContext<SettingsContext>();\r\n\r\n // Filter infrastructure settings\r\n const databaseSettings = settings.filter(s => s.category === 'Database');\r\n const storageSettings = settings.filter(s => s.category === 'Storage');\r\n const localStorageSettings = storageSettings.filter(s => s.key.startsWith('Local') || s.key === 'Provider');\r\n const azureStorageSettings = storageSettings.filter(s => s.key.startsWith('Azure'));\r\n\r\n // Determine active providers\r\n const storageProvider = storageSettings.find(s => s.key === 'Provider')?.value;\r\n const databaseServer = databaseSettings.find(s => s.key === 'Server')?.value;\r\n const databaseName = databaseSettings.find(s => s.key === 'DatabaseName')?.value;\r\n\r\n const isAzureActive = storageProvider === 'Azure';\r\n const isLocalActive = storageProvider === 'Local' || storageProvider === 'FileSystem';\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n\r\n const getDisplayValue = () => {\r\n if (setting.isSensitive) return '********';\r\n const displayVal = setting.displayValue || setting.value;\r\n if (setting.valueType === 'Bool') {\r\n return displayVal === 'true' || displayVal === 'Yes' ? t('common.yes') : t('common.no');\r\n }\r\n return displayVal;\r\n };\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`appsettings.keys.${setting.category}.${setting.key}`, setting.key)}\r\n </span>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`appsettings.descriptions.${setting.category}.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"text-right max-w-[50%]\">\r\n <span className={`font-mono text-sm break-all ${\r\n setting.isSensitive\r\n ? 'text-[var(--text-tertiary)]'\r\n : 'text-[var(--text-primary)]'\r\n }`}>\r\n {getDisplayValue()}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderSection = (\r\n title: string,\r\n description: string,\r\n items: SettingViewModel[],\r\n icon: React.ElementType,\r\n gradientFrom: string,\r\n iconColor: string,\r\n status: SectionStatus = 'neutral',\r\n statusLabel?: string\r\n ) => {\r\n const Icon = icon;\r\n if (items.length === 0) return null;\r\n\r\n const isInactive = status === 'inactive';\r\n const isActive = status === 'active';\r\n\r\n let borderClass = 'border-[var(--border-color)]';\r\n if (isActive) borderClass = 'border-green-500/50 ring-1 ring-green-500/20';\r\n else if (isInactive) borderClass = 'border-gray-400/30';\r\n\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border ${borderClass} bg-[var(--bg-card)] overflow-hidden shadow-sm ${isInactive ? 'opacity-50' : ''}`}>\r\n <div className={`px-6 py-4 bg-gradient-to-r ${gradientFrom} border-b border-[var(--border-color)]`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${iconColor}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {title}\r\n </h3>\r\n {isActive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.active', 'Actif')}\r\n </span>\r\n )}\r\n {isInactive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.notUsed', 'Non utilisé')}\r\n </span>\r\n )}\r\n {statusLabel && (\r\n <span className=\"text-xs text-[var(--text-secondary)] ml-1\">\r\n ({statusLabel})\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {items.map(renderSetting)}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Summary Cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\r\n <div className=\"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.sections.database', 'Database')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Database className=\"w-5 h-5 text-cyan-500\" />\r\n {databaseName || 'N/A'}\r\n </div>\r\n <div className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {databaseServer}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Storage.Provider', 'Storage Provider')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n {isAzureActive ? <Cloud className=\"w-5 h-5 text-sky-500\" /> : <HardDrive className=\"w-5 h-5 text-blue-500\" />}\r\n {storageProvider || 'N/A'}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Database Section */}\r\n {renderSection(\r\n t('appsettings.sections.database', 'Database'),\r\n t('appsettings.sections.databaseDescription', 'SQL Server database configuration'),\r\n databaseSettings,\r\n Database,\r\n 'from-cyan-500/10 to-cyan-600/5',\r\n 'bg-cyan-500/20 text-cyan-600',\r\n 'active'\r\n )}\r\n\r\n {/* Local Storage Section */}\r\n {renderSection(\r\n t('appsettings.sections.localStorage', 'Local Storage'),\r\n t('appsettings.sections.localStorageDescription', 'File system storage configuration'),\r\n localStorageSettings.filter(s => s.key !== 'Provider'),\r\n HardDrive,\r\n isLocalActive ? 'from-green-500/10 to-green-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n isLocalActive ? 'bg-green-500/20 text-green-600' : 'bg-gray-500/20 text-gray-500',\r\n isLocalActive ? 'active' : 'inactive',\r\n isLocalActive ? storageProvider : undefined\r\n )}\r\n\r\n {/* Azure Storage Section */}\r\n {renderSection(\r\n t('appsettings.sections.azureStorage', 'Azure Blob Storage'),\r\n t('appsettings.sections.azureStorageDescription', 'Cloud storage configuration'),\r\n azureStorageSettings,\r\n Cloud,\r\n isAzureActive ? 'from-green-500/10 to-green-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n isAzureActive ? 'bg-green-500/20 text-green-600' : 'bg-gray-500/20 text-gray-500',\r\n isAzureActive ? 'active' : 'inactive',\r\n isAzureActive ? 'Azure' : undefined\r\n )}\r\n\r\n {databaseSettings.length === 0 && storageSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('appsettings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default InfrastructureSection;\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { Key, Clock, CheckCircle2, CircleSlash } from 'lucide-react';\r\nimport { type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\ntype SectionStatus = 'active' | 'inactive' | 'neutral';\r\n\r\n// Microsoft and Google icons as inline SVG\r\nconst MicrosoftIcon = () => (\r\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M11.4 24H0V12.6h11.4V24zM24 24H12.6V12.6H24V24zM11.4 11.4H0V0h11.4v11.4zm12.6 0H12.6V0H24v11.4z\"/>\r\n </svg>\r\n);\r\n\r\nconst GoogleIcon = () => (\r\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"/>\r\n <path d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/>\r\n <path d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"/>\r\n <path d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/>\r\n </svg>\r\n);\r\n\r\nexport function AuthenticationSection(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { settings } = useOutletContext<SettingsContext>();\r\n\r\n // Filter authentication settings\r\n const authSettings = settings.filter(s => s.category === 'Authentication');\r\n const sessionSettings = settings.filter(s => s.category === 'Session');\r\n\r\n // JWT settings\r\n const jwtSettings = authSettings.filter(s =>\r\n s.key.startsWith('Jwt') || s.key.includes('Token')\r\n );\r\n\r\n // OAuth providers\r\n const microsoftConfigured = authSettings.find(s => s.key === 'MicrosoftOAuth')?.value === 'true';\r\n const googleConfigured = authSettings.find(s => s.key === 'GoogleOAuth')?.value === 'true';\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n\r\n const getDisplayValue = () => {\r\n if (setting.isSensitive) return '********';\r\n const displayVal = setting.displayValue || setting.value;\r\n if (setting.valueType === 'Bool') {\r\n return displayVal === 'true' || displayVal === 'Yes' ? t('common.yes') : t('common.no');\r\n }\r\n return displayVal;\r\n };\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`appsettings.keys.Authentication.${setting.key}`, { defaultValue: setting.key })}\r\n </span>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`appsettings.descriptions.Authentication.${setting.key}`, { defaultValue: setting.description })}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"text-right max-w-[50%]\">\r\n <span className={`font-mono text-sm break-all ${\r\n setting.isSensitive\r\n ? 'text-[var(--text-tertiary)]'\r\n : 'text-[var(--text-primary)]'\r\n }`}>\r\n {getDisplayValue()}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderSection = (\r\n title: string,\r\n description: string,\r\n items: SettingViewModel[],\r\n icon: React.ElementType,\r\n gradientFrom: string,\r\n iconColor: string,\r\n status: SectionStatus = 'neutral',\r\n statusLabel?: string\r\n ) => {\r\n const Icon = icon;\r\n if (items.length === 0) return null;\r\n\r\n const isInactive = status === 'inactive';\r\n const isActive = status === 'active';\r\n\r\n let borderClass = 'border-[var(--border-color)]';\r\n if (isActive) borderClass = 'border-green-500/50 ring-1 ring-green-500/20';\r\n else if (isInactive) borderClass = 'border-gray-400/30';\r\n\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border ${borderClass} bg-[var(--bg-card)] overflow-hidden shadow-sm ${isInactive ? 'opacity-50' : ''}`}>\r\n <div className={`px-6 py-4 bg-gradient-to-r ${gradientFrom} border-b border-[var(--border-color)]`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${iconColor}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {title}\r\n </h3>\r\n {isActive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.configured', 'Configuré')}\r\n </span>\r\n )}\r\n {isInactive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.notConfigured', 'Non configuré')}\r\n </span>\r\n )}\r\n {statusLabel && (\r\n <span className=\"text-xs text-[var(--text-secondary)] ml-1\">\r\n ({statusLabel})\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {items.map(renderSetting)}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n // Custom OAuth provider card\r\n const renderOAuthCard = (\r\n name: string,\r\n isConfigured: boolean,\r\n IconComponent: React.FC,\r\n color: string\r\n ) => {\r\n return (\r\n <div className={`rounded-lg border ${isConfigured ? 'border-green-500/50 ring-1 ring-green-500/20' : 'border-gray-400/30 opacity-50'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${color}`}>\r\n <IconComponent />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"font-semibold text-[var(--text-primary)]\">{name}</span>\r\n {isConfigured ? (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.configured', 'Configuré')}\r\n </span>\r\n ) : (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.notConfigured', 'Non configuré')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {isConfigured\r\n ? t('appsettings.oauthConfiguredDesc', 'OAuth authentication is enabled')\r\n : t('appsettings.oauthNotConfiguredDesc', 'ClientId not configured in appsettings.json')\r\n }\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* OAuth Providers Summary */}\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('appsettings.sections.oauthProviders', 'OAuth Providers')}\r\n </h3>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {renderOAuthCard('Microsoft', microsoftConfigured, MicrosoftIcon, 'bg-blue-500/20 text-blue-600')}\r\n {renderOAuthCard('Google', googleConfigured, GoogleIcon, 'bg-red-500/20 text-red-600')}\r\n </div>\r\n </div>\r\n\r\n {/* JWT Configuration */}\r\n {renderSection(\r\n t('appsettings.sections.jwt', 'JWT Configuration'),\r\n t('appsettings.sections.jwtDescription', 'JSON Web Token settings for authentication'),\r\n jwtSettings,\r\n Key,\r\n 'from-violet-500/10 to-violet-600/5',\r\n 'bg-violet-500/20 text-violet-600',\r\n 'active'\r\n )}\r\n\r\n {/* Session Configuration */}\r\n {renderSection(\r\n t('appsettings.sections.session', 'Session'),\r\n t('appsettings.sections.sessionDescription', 'User session timeout and validation settings'),\r\n sessionSettings,\r\n Clock,\r\n 'from-amber-500/10 to-amber-600/5',\r\n 'bg-amber-500/20 text-amber-600',\r\n 'active'\r\n )}\r\n\r\n {authSettings.length === 0 && sessionSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('appsettings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default AuthenticationSection;\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { FileText, Monitor, Database, BarChart3, CheckCircle2, CircleSlash } from 'lucide-react';\r\nimport { type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\ntype SectionStatus = 'active' | 'inactive' | 'neutral';\r\n\r\nexport function LoggingSection(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { settings } = useOutletContext<SettingsContext>();\r\n\r\n // Filter logging settings\r\n const loggingSettings = settings.filter(s => s.category === 'Logging');\r\n\r\n // Categorize logging settings\r\n const fileSettings = loggingSettings.filter(s =>\r\n s.key.includes('File') || s.key.includes('Rolling') || s.key.includes('Retention')\r\n );\r\n const seqSettings = loggingSettings.filter(s => s.key.includes('Seq'));\r\n const appInsightsSettings = loggingSettings.filter(s => s.key.includes('AppInsights'));\r\n const levelSettings = loggingSettings.filter(s => s.key.includes('Level') || s.key.includes('Minimum'));\r\n\r\n // Check which sinks are enabled\r\n const consoleEnabled = loggingSettings.find(s => s.key === 'ConsoleEnabled')?.value === 'true';\r\n const fileEnabled = loggingSettings.find(s => s.key === 'FileEnabled')?.value === 'true';\r\n const seqEnabled = loggingSettings.find(s => s.key === 'SeqEnabled')?.value === 'true';\r\n const appInsightsEnabled = loggingSettings.find(s => s.key === 'AppInsightsEnabled')?.value === 'true';\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n\r\n const getDisplayValue = () => {\r\n if (setting.isSensitive) return '********';\r\n const displayVal = setting.displayValue || setting.value;\r\n if (setting.valueType === 'Bool') {\r\n return displayVal === 'true' || displayVal === 'Yes' ? t('common.yes') : t('common.no');\r\n }\r\n return displayVal;\r\n };\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`appsettings.keys.Logging.${setting.key}`, setting.key)}\r\n </span>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`appsettings.descriptions.Logging.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"text-right max-w-[50%]\">\r\n <span className={`font-mono text-sm break-all ${\r\n setting.isSensitive\r\n ? 'text-[var(--text-tertiary)]'\r\n : 'text-[var(--text-primary)]'\r\n }`}>\r\n {getDisplayValue()}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderSection = (\r\n title: string,\r\n description: string,\r\n items: SettingViewModel[],\r\n icon: React.ElementType,\r\n gradientFrom: string,\r\n iconColor: string,\r\n status: SectionStatus = 'neutral'\r\n ) => {\r\n const Icon = icon;\r\n if (items.length === 0) return null;\r\n\r\n const isInactive = status === 'inactive';\r\n const isActive = status === 'active';\r\n\r\n let borderClass = 'border-[var(--border-color)]';\r\n if (isActive) borderClass = 'border-green-500/50 ring-1 ring-green-500/20';\r\n else if (isInactive) borderClass = 'border-gray-400/30';\r\n\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border ${borderClass} bg-[var(--bg-card)] overflow-hidden shadow-sm ${isInactive ? 'opacity-50' : ''}`}>\r\n <div className={`px-6 py-4 bg-gradient-to-r ${gradientFrom} border-b border-[var(--border-color)]`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${iconColor}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {title}\r\n </h3>\r\n {isActive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.enabled', 'Activé')}\r\n </span>\r\n )}\r\n {isInactive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.disabled', 'Désactivé')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {items.map(renderSetting)}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n // Summary cards for sinks\r\n const renderSinkCard = (\r\n name: string,\r\n enabled: boolean,\r\n icon: React.ElementType,\r\n color: string\r\n ) => {\r\n const Icon = icon;\r\n return (\r\n <div className={`rounded-lg border ${enabled ? 'border-green-500/50' : 'border-gray-400/30 opacity-50'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${color}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <span className=\"font-semibold text-[var(--text-primary)]\">{name}</span>\r\n {enabled ? (\r\n <span className=\"ml-2 inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.enabled', 'Activé')}\r\n </span>\r\n ) : (\r\n <span className=\"ml-2 inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.disabled', 'Désactivé')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Sinks Summary */}\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('appsettings.sections.loggingSinks', 'Logging Sinks')}\r\n </h3>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4\">\r\n {renderSinkCard('Console', consoleEnabled, Monitor, 'bg-gray-500/20 text-gray-600')}\r\n {renderSinkCard('File', fileEnabled, FileText, 'bg-violet-500/20 text-violet-600')}\r\n {renderSinkCard('Seq', seqEnabled, Database, 'bg-blue-500/20 text-blue-600')}\r\n {renderSinkCard('App Insights', appInsightsEnabled, BarChart3, 'bg-purple-500/20 text-purple-600')}\r\n </div>\r\n </div>\r\n\r\n {/* Log Levels */}\r\n {renderSection(\r\n t('appsettings.sections.logLevels', 'Log Levels'),\r\n t('appsettings.sections.logLevelsDescription', 'Minimum log level configuration'),\r\n levelSettings,\r\n BarChart3,\r\n 'from-emerald-500/10 to-emerald-600/5',\r\n 'bg-emerald-500/20 text-emerald-600',\r\n 'neutral'\r\n )}\r\n\r\n {/* File Logging */}\r\n {renderSection(\r\n t('appsettings.sections.fileLogging', 'File Logging'),\r\n t('appsettings.sections.fileLoggingDescription', 'File-based log output configuration'),\r\n fileSettings,\r\n FileText,\r\n fileEnabled ? 'from-violet-500/10 to-violet-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n fileEnabled ? 'bg-violet-500/20 text-violet-600' : 'bg-gray-500/20 text-gray-500',\r\n fileEnabled ? 'active' : 'inactive'\r\n )}\r\n\r\n {/* Seq Logging */}\r\n {seqSettings.length > 0 && renderSection(\r\n t('appsettings.sections.seqLogging', 'Seq'),\r\n t('appsettings.sections.seqLoggingDescription', 'Seq structured logging server'),\r\n seqSettings,\r\n Database,\r\n seqEnabled ? 'from-blue-500/10 to-blue-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n seqEnabled ? 'bg-blue-500/20 text-blue-600' : 'bg-gray-500/20 text-gray-500',\r\n seqEnabled ? 'active' : 'inactive'\r\n )}\r\n\r\n {/* App Insights */}\r\n {appInsightsSettings.length > 0 && renderSection(\r\n t('appsettings.sections.appInsights', 'Application Insights'),\r\n t('appsettings.sections.appInsightsDescription', 'Azure Application Insights telemetry'),\r\n appInsightsSettings,\r\n BarChart3,\r\n appInsightsEnabled ? 'from-purple-500/10 to-purple-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n appInsightsEnabled ? 'bg-purple-500/20 text-purple-600' : 'bg-gray-500/20 text-gray-500',\r\n appInsightsEnabled ? 'active' : 'inactive'\r\n )}\r\n\r\n {loggingSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('appsettings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default LoggingSection;\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { Mail, Send, CheckCircle2, CircleSlash } from 'lucide-react';\r\nimport { type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\ntype SectionStatus = 'active' | 'inactive' | 'neutral';\r\n\r\nexport function EmailSection(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { settings } = useOutletContext<SettingsContext>();\r\n\r\n // Filter email settings\r\n const emailSettings = settings.filter(s => s.category === 'Email');\r\n\r\n // Check status\r\n const emailEnabled = emailSettings.find(s => s.key === 'Enabled')?.value === 'true';\r\n const emailProvider = emailSettings.find(s => s.key === 'Provider')?.value;\r\n const fromEmail = emailSettings.find(s => s.key === 'FromEmail')?.value;\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n\r\n const getDisplayValue = () => {\r\n if (setting.isSensitive) return '********';\r\n const displayVal = setting.displayValue || setting.value;\r\n if (setting.valueType === 'Bool') {\r\n return displayVal === 'true' || displayVal === 'Yes' ? t('common.yes') : t('common.no');\r\n }\r\n return displayVal;\r\n };\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`appsettings.keys.Email.${setting.key}`, setting.key)}\r\n </span>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`appsettings.descriptions.Email.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"text-right max-w-[50%]\">\r\n <span className={`font-mono text-sm break-all ${\r\n setting.isSensitive\r\n ? 'text-[var(--text-tertiary)]'\r\n : 'text-[var(--text-primary)]'\r\n }`}>\r\n {getDisplayValue()}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderSection = (\r\n title: string,\r\n description: string,\r\n items: SettingViewModel[],\r\n icon: React.ElementType,\r\n gradientFrom: string,\r\n iconColor: string,\r\n status: SectionStatus = 'neutral'\r\n ) => {\r\n const Icon = icon;\r\n if (items.length === 0) return null;\r\n\r\n const isInactive = status === 'inactive';\r\n const isActive = status === 'active';\r\n\r\n let borderClass = 'border-[var(--border-color)]';\r\n if (isActive) borderClass = 'border-green-500/50 ring-1 ring-green-500/20';\r\n else if (isInactive) borderClass = 'border-gray-400/30';\r\n\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border ${borderClass} bg-[var(--bg-card)] overflow-hidden shadow-sm ${isInactive ? 'opacity-50' : ''}`}>\r\n <div className={`px-6 py-4 bg-gradient-to-r ${gradientFrom} border-b border-[var(--border-color)]`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${iconColor}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {title}\r\n </h3>\r\n {isActive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.enabled', 'Activé')}\r\n </span>\r\n )}\r\n {isInactive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.disabled', 'Désactivé')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {items.map(renderSetting)}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Summary Card */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n <div className={`rounded-lg border ${emailEnabled ? 'border-green-500/50' : 'border-gray-400/30 opacity-50'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.status', 'Status')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n {emailEnabled ? (\r\n <>\r\n <CheckCircle2 className=\"w-5 h-5 text-green-500\" />\r\n {t('appsettings.enabled', 'Activé')}\r\n </>\r\n ) : (\r\n <>\r\n <CircleSlash className=\"w-5 h-5 text-gray-500\" />\r\n {t('appsettings.disabled', 'Désactivé')}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Email.Provider', 'Provider')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Send className=\"w-5 h-5 text-amber-500\" />\r\n {emailProvider || 'N/A'}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Email.FromEmail', 'From Email')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Mail className=\"w-5 h-5 text-amber-500\" />\r\n <span className=\"truncate\">{fromEmail || 'N/A'}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Email Configuration */}\r\n {renderSection(\r\n t('appsettings.sections.emailConfiguration', 'Email Configuration'),\r\n t('appsettings.sections.emailConfigurationDescription', 'SMTP and email provider settings'),\r\n emailSettings,\r\n Mail,\r\n emailEnabled ? 'from-amber-500/10 to-amber-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n emailEnabled ? 'bg-amber-500/20 text-amber-600' : 'bg-gray-500/20 text-gray-500',\r\n emailEnabled ? 'active' : 'inactive'\r\n )}\r\n\r\n {emailSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('appsettings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default EmailSection;\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { Cloud, RefreshCw, CheckCircle2, CircleSlash } from 'lucide-react';\r\nimport { type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\ntype SectionStatus = 'active' | 'inactive' | 'neutral';\r\n\r\nexport function EntraSection(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { settings } = useOutletContext<SettingsContext>();\r\n\r\n // Filter Entra settings\r\n const entraSettings = settings.filter(s => s.category === 'Entra');\r\n\r\n // Check status\r\n const syncEnabled = entraSettings.find(s => s.key === 'SyncEnabled')?.value === 'true';\r\n const isConfigured = entraSettings.find(s => s.key === 'Configured')?.value === 'true';\r\n const syncInterval = entraSettings.find(s => s.key === 'SyncIntervalMinutes')?.value;\r\n const useDeltaSync = entraSettings.find(s => s.key === 'UseDeltaSync')?.value === 'true';\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n\r\n const getDisplayValue = () => {\r\n if (setting.isSensitive) return '********';\r\n const displayVal = setting.displayValue || setting.value;\r\n if (setting.valueType === 'Bool') {\r\n return displayVal === 'true' || displayVal === 'Yes' ? t('common.yes') : t('common.no');\r\n }\r\n return displayVal;\r\n };\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`appsettings.keys.Entra.${setting.key}`, setting.key)}\r\n </span>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`appsettings.descriptions.Entra.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"text-right max-w-[50%]\">\r\n <span className={`font-mono text-sm break-all ${\r\n setting.isSensitive\r\n ? 'text-[var(--text-tertiary)]'\r\n : 'text-[var(--text-primary)]'\r\n }`}>\r\n {getDisplayValue()}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderSection = (\r\n title: string,\r\n description: string,\r\n items: SettingViewModel[],\r\n icon: React.ElementType,\r\n gradientFrom: string,\r\n iconColor: string,\r\n status: SectionStatus = 'neutral'\r\n ) => {\r\n const Icon = icon;\r\n if (items.length === 0) return null;\r\n\r\n const isInactive = status === 'inactive';\r\n const isActive = status === 'active';\r\n\r\n let borderClass = 'border-[var(--border-color)]';\r\n if (isActive) borderClass = 'border-green-500/50 ring-1 ring-green-500/20';\r\n else if (isInactive) borderClass = 'border-gray-400/30';\r\n\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border ${borderClass} bg-[var(--bg-card)] overflow-hidden shadow-sm ${isInactive ? 'opacity-50' : ''}`}>\r\n <div className={`px-6 py-4 bg-gradient-to-r ${gradientFrom} border-b border-[var(--border-color)]`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${iconColor}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {title}\r\n </h3>\r\n {isActive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.enabled', 'Activé')}\r\n </span>\r\n )}\r\n {isInactive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.disabled', 'Désactivé')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {items.map(renderSetting)}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Summary Cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-4 gap-4\">\r\n <div className={`rounded-lg border ${isConfigured ? 'border-green-500/50' : 'border-gray-400/30 opacity-50'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.configuration', 'Configuration')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n {isConfigured ? (\r\n <>\r\n <CheckCircle2 className=\"w-5 h-5 text-green-500\" />\r\n {t('appsettings.configured', 'Configuré')}\r\n </>\r\n ) : (\r\n <>\r\n <CircleSlash className=\"w-5 h-5 text-gray-500\" />\r\n {t('appsettings.notConfigured', 'Non configuré')}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n <div className={`rounded-lg border ${syncEnabled ? 'border-green-500/50' : 'border-gray-400/30 opacity-50'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Entra.SyncEnabled', 'Sync Status')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <RefreshCw className={`w-5 h-5 ${syncEnabled ? 'text-green-500' : 'text-gray-500'}`} />\r\n {syncEnabled ? t('appsettings.enabled', 'Activé') : t('appsettings.disabled', 'Désactivé')}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Entra.SyncIntervalMinutes', 'Sync Interval')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Cloud className=\"w-5 h-5 text-sky-500\" />\r\n {syncInterval ? `${syncInterval} min` : 'N/A'}\r\n </div>\r\n </div>\r\n <div className={`rounded-lg border ${useDeltaSync ? 'border-green-500/50' : 'border-[var(--border-color)]'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Entra.UseDeltaSync', 'Delta Sync')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n {useDeltaSync ? (\r\n <>\r\n <CheckCircle2 className=\"w-5 h-5 text-green-500\" />\r\n {t('common.yes', 'Oui')}\r\n </>\r\n ) : (\r\n <>\r\n <CircleSlash className=\"w-5 h-5 text-gray-500\" />\r\n {t('common.no', 'Non')}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Entra Configuration */}\r\n {renderSection(\r\n t('appsettings.sections.entraConfiguration', 'Microsoft Entra ID'),\r\n t('appsettings.sections.entraConfigurationDescription', 'Azure AD synchronization settings'),\r\n entraSettings,\r\n Cloud,\r\n isConfigured ? 'from-sky-500/10 to-sky-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n isConfigured ? 'bg-sky-500/20 text-sky-600' : 'bg-gray-500/20 text-gray-500',\r\n isConfigured ? 'active' : 'inactive'\r\n )}\r\n\r\n {entraSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('appsettings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default EntraSection;\r\n"],"names":["TABS","Server","Shield","FileText","Mail","Cloud","AppSettingsPage","useTranslation","navigate","useNavigate","location","useLocation","settings","setSettings","useState","loading","setLoading","loadSettings","useCallback","readonlySettings","adminApi","s","err","useEffect","getCurrentTab","path","t","handleTabChange","tabId","tab","jsx","Loader2","jsxs","Breadcrumb","Info","Icon","isActive","Outlet","InfrastructureSection","useOutletContext","databaseSettings","storageSettings","localStorageSettings","azureStorageSettings","storageProvider","databaseServer","databaseName","isAzureActive","isLocalActive","renderSetting","setting","editKey","getDisplayValue","displayVal","renderSection","title","description","items","icon","gradientFrom","iconColor","status","statusLabel","isInactive","borderClass","CheckCircle2","CircleSlash","Database","HardDrive","MicrosoftIcon","GoogleIcon","AuthenticationSection","authSettings","sessionSettings","jwtSettings","microsoftConfigured","googleConfigured","renderOAuthCard","name","isConfigured","IconComponent","color","Key","Clock","LoggingSection","loggingSettings","fileSettings","seqSettings","appInsightsSettings","levelSettings","consoleEnabled","fileEnabled","seqEnabled","appInsightsEnabled","renderSinkCard","enabled","Monitor","BarChart3","EmailSection","emailSettings","emailEnabled","emailProvider","fromEmail","Fragment","Send","EntraSection","entraSettings","syncEnabled","syncInterval","useDeltaSync","RefreshCw"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index--aPwOFjF.js","sources":["../../src/pages/platform/administration/configuration/appsettings/AppSettingsPage.tsx","../../src/pages/platform/administration/configuration/appsettings/InfrastructureSection.tsx","../../src/pages/platform/administration/configuration/appsettings/AuthenticationSection.tsx","../../src/pages/platform/administration/configuration/appsettings/LoggingSection.tsx","../../src/pages/platform/administration/configuration/appsettings/EmailSection.tsx","../../src/pages/platform/administration/configuration/appsettings/EntraSection.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 { Server, Shield, FileText, Mail, Cloud, Loader2, Info } 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: 'infrastructure', labelKey: 'appsettings.tabs.infrastructure', icon: Server, route: '/administration/configuration/appsettings/infrastructure' },\r\n { id: 'authentication', labelKey: 'appsettings.tabs.authentication', icon: Shield, route: '/administration/configuration/appsettings/authentication' },\r\n { id: 'logging', labelKey: 'appsettings.tabs.logging', icon: FileText, route: '/administration/configuration/appsettings/logging' },\r\n { id: 'email', labelKey: 'appsettings.tabs.email', icon: Mail, route: '/administration/configuration/appsettings/email' },\r\n { id: 'entra', labelKey: 'appsettings.tabs.entra', icon: Cloud, route: '/administration/configuration/appsettings/entra' }\r\n];\r\n\r\nexport function AppSettingsPage(): 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 // Filter only AppSettings and Environment sources (readonly)\r\n const readonlySettings = result.filter(s =>\r\n s.source === 'AppSettings' || s.source === 'Environment' || s.source === 'Computed'\r\n );\r\n setSettings(readonlySettings);\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 || 'infrastructure';\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('appsettings.title', 'Application 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('appsettings.title')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)] mt-1\">\r\n {t('appsettings.subtitle')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Info Banner */}\r\n <div className=\"bg-[var(--info-bg)] border border-[var(--info-border)] rounded-[var(--radius-card)] p-4\">\r\n <div className=\"flex items-start gap-3\">\r\n <Info className=\"w-5 h-5 text-[var(--info-text)] flex-shrink-0 mt-0.5\" />\r\n <div>\r\n <h4 className=\"font-medium text-[var(--info-text)]\">\r\n {t('appsettings.readonlyBannerTitle')}\r\n </h4>\r\n <p className=\"text-sm text-[var(--info-text)] opacity-90 mt-1\">\r\n {t('appsettings.readonlyBannerDescription')}\r\n </p>\r\n </div>\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 AppSettingsPage;\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { Database, HardDrive, Cloud, CheckCircle2, CircleSlash } from 'lucide-react';\r\nimport { type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\ntype SectionStatus = 'active' | 'inactive' | 'neutral';\r\n\r\nexport function InfrastructureSection(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { settings } = useOutletContext<SettingsContext>();\r\n\r\n // Filter infrastructure settings\r\n const databaseSettings = settings.filter(s => s.category === 'Database');\r\n const storageSettings = settings.filter(s => s.category === 'Storage');\r\n const localStorageSettings = storageSettings.filter(s => s.key.startsWith('Local') || s.key === 'Provider');\r\n const azureStorageSettings = storageSettings.filter(s => s.key.startsWith('Azure'));\r\n\r\n // Determine active providers\r\n const storageProvider = storageSettings.find(s => s.key === 'Provider')?.value;\r\n const databaseServer = databaseSettings.find(s => s.key === 'Server')?.value;\r\n const databaseName = databaseSettings.find(s => s.key === 'DatabaseName')?.value;\r\n\r\n const isAzureActive = storageProvider === 'Azure';\r\n const isLocalActive = storageProvider === 'Local' || storageProvider === 'FileSystem';\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n\r\n const getDisplayValue = () => {\r\n if (setting.isSensitive) return '********';\r\n const displayVal = setting.displayValue || setting.value;\r\n if (setting.valueType === 'Bool') {\r\n return displayVal === 'true' || displayVal === 'Yes' ? t('common.yes') : t('common.no');\r\n }\r\n return displayVal;\r\n };\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`appsettings.keys.${setting.category}.${setting.key}`, setting.key)}\r\n </span>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`appsettings.descriptions.${setting.category}.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"text-right max-w-[50%]\">\r\n <span className={`font-mono text-sm break-all ${\r\n setting.isSensitive\r\n ? 'text-[var(--text-tertiary)]'\r\n : 'text-[var(--text-primary)]'\r\n }`}>\r\n {getDisplayValue()}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderSection = (\r\n title: string,\r\n description: string,\r\n items: SettingViewModel[],\r\n icon: React.ElementType,\r\n gradientFrom: string,\r\n iconColor: string,\r\n status: SectionStatus = 'neutral',\r\n statusLabel?: string\r\n ) => {\r\n const Icon = icon;\r\n if (items.length === 0) return null;\r\n\r\n const isInactive = status === 'inactive';\r\n const isActive = status === 'active';\r\n\r\n let borderClass = 'border-[var(--border-color)]';\r\n if (isActive) borderClass = 'border-green-500/50 ring-1 ring-green-500/20';\r\n else if (isInactive) borderClass = 'border-gray-400/30';\r\n\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border ${borderClass} bg-[var(--bg-card)] overflow-hidden shadow-sm ${isInactive ? 'opacity-50' : ''}`}>\r\n <div className={`px-6 py-4 bg-gradient-to-r ${gradientFrom} border-b border-[var(--border-color)]`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${iconColor}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {title}\r\n </h3>\r\n {isActive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.active', 'Actif')}\r\n </span>\r\n )}\r\n {isInactive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.notUsed', 'Non utilisé')}\r\n </span>\r\n )}\r\n {statusLabel && (\r\n <span className=\"text-xs text-[var(--text-secondary)] ml-1\">\r\n ({statusLabel})\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {items.map(renderSetting)}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Summary Cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\r\n <div className=\"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.sections.database', 'Database')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Database className=\"w-5 h-5 text-cyan-500\" />\r\n {databaseName || 'N/A'}\r\n </div>\r\n <div className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {databaseServer}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Storage.Provider', 'Storage Provider')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n {isAzureActive ? <Cloud className=\"w-5 h-5 text-sky-500\" /> : <HardDrive className=\"w-5 h-5 text-blue-500\" />}\r\n {storageProvider || 'N/A'}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Database Section */}\r\n {renderSection(\r\n t('appsettings.sections.database', 'Database'),\r\n t('appsettings.sections.databaseDescription', 'SQL Server database configuration'),\r\n databaseSettings,\r\n Database,\r\n 'from-cyan-500/10 to-cyan-600/5',\r\n 'bg-cyan-500/20 text-cyan-600',\r\n 'active'\r\n )}\r\n\r\n {/* Local Storage Section */}\r\n {renderSection(\r\n t('appsettings.sections.localStorage', 'Local Storage'),\r\n t('appsettings.sections.localStorageDescription', 'File system storage configuration'),\r\n localStorageSettings.filter(s => s.key !== 'Provider'),\r\n HardDrive,\r\n isLocalActive ? 'from-green-500/10 to-green-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n isLocalActive ? 'bg-green-500/20 text-green-600' : 'bg-gray-500/20 text-gray-500',\r\n isLocalActive ? 'active' : 'inactive',\r\n isLocalActive ? storageProvider : undefined\r\n )}\r\n\r\n {/* Azure Storage Section */}\r\n {renderSection(\r\n t('appsettings.sections.azureStorage', 'Azure Blob Storage'),\r\n t('appsettings.sections.azureStorageDescription', 'Cloud storage configuration'),\r\n azureStorageSettings,\r\n Cloud,\r\n isAzureActive ? 'from-green-500/10 to-green-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n isAzureActive ? 'bg-green-500/20 text-green-600' : 'bg-gray-500/20 text-gray-500',\r\n isAzureActive ? 'active' : 'inactive',\r\n isAzureActive ? 'Azure' : undefined\r\n )}\r\n\r\n {databaseSettings.length === 0 && storageSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('appsettings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default InfrastructureSection;\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { Key, Clock, CheckCircle2, CircleSlash } from 'lucide-react';\r\nimport { type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\ntype SectionStatus = 'active' | 'inactive' | 'neutral';\r\n\r\n// Microsoft and Google icons as inline SVG\r\nconst MicrosoftIcon = () => (\r\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M11.4 24H0V12.6h11.4V24zM24 24H12.6V12.6H24V24zM11.4 11.4H0V0h11.4v11.4zm12.6 0H12.6V0H24v11.4z\"/>\r\n </svg>\r\n);\r\n\r\nconst GoogleIcon = () => (\r\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"/>\r\n <path d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/>\r\n <path d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"/>\r\n <path d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/>\r\n </svg>\r\n);\r\n\r\nexport function AuthenticationSection(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { settings } = useOutletContext<SettingsContext>();\r\n\r\n // Filter authentication settings\r\n const authSettings = settings.filter(s => s.category === 'Authentication');\r\n const sessionSettings = settings.filter(s => s.category === 'Session');\r\n\r\n // JWT settings\r\n const jwtSettings = authSettings.filter(s =>\r\n s.key.startsWith('Jwt') || s.key.includes('Token')\r\n );\r\n\r\n // OAuth providers\r\n const microsoftConfigured = authSettings.find(s => s.key === 'MicrosoftOAuth')?.value === 'true';\r\n const googleConfigured = authSettings.find(s => s.key === 'GoogleOAuth')?.value === 'true';\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n\r\n const getDisplayValue = () => {\r\n if (setting.isSensitive) return '********';\r\n const displayVal = setting.displayValue || setting.value;\r\n if (setting.valueType === 'Bool') {\r\n return displayVal === 'true' || displayVal === 'Yes' ? t('common.yes') : t('common.no');\r\n }\r\n return displayVal;\r\n };\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`appsettings.keys.Authentication.${setting.key}`, { defaultValue: setting.key })}\r\n </span>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`appsettings.descriptions.Authentication.${setting.key}`, { defaultValue: setting.description })}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"text-right max-w-[50%]\">\r\n <span className={`font-mono text-sm break-all ${\r\n setting.isSensitive\r\n ? 'text-[var(--text-tertiary)]'\r\n : 'text-[var(--text-primary)]'\r\n }`}>\r\n {getDisplayValue()}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderSection = (\r\n title: string,\r\n description: string,\r\n items: SettingViewModel[],\r\n icon: React.ElementType,\r\n gradientFrom: string,\r\n iconColor: string,\r\n status: SectionStatus = 'neutral',\r\n statusLabel?: string\r\n ) => {\r\n const Icon = icon;\r\n if (items.length === 0) return null;\r\n\r\n const isInactive = status === 'inactive';\r\n const isActive = status === 'active';\r\n\r\n let borderClass = 'border-[var(--border-color)]';\r\n if (isActive) borderClass = 'border-green-500/50 ring-1 ring-green-500/20';\r\n else if (isInactive) borderClass = 'border-gray-400/30';\r\n\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border ${borderClass} bg-[var(--bg-card)] overflow-hidden shadow-sm ${isInactive ? 'opacity-50' : ''}`}>\r\n <div className={`px-6 py-4 bg-gradient-to-r ${gradientFrom} border-b border-[var(--border-color)]`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${iconColor}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {title}\r\n </h3>\r\n {isActive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.configured', 'Configuré')}\r\n </span>\r\n )}\r\n {isInactive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.notConfigured', 'Non configuré')}\r\n </span>\r\n )}\r\n {statusLabel && (\r\n <span className=\"text-xs text-[var(--text-secondary)] ml-1\">\r\n ({statusLabel})\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {items.map(renderSetting)}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n // Custom OAuth provider card\r\n const renderOAuthCard = (\r\n name: string,\r\n isConfigured: boolean,\r\n IconComponent: React.FC,\r\n color: string\r\n ) => {\r\n return (\r\n <div className={`rounded-lg border ${isConfigured ? 'border-green-500/50 ring-1 ring-green-500/20' : 'border-gray-400/30 opacity-50'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${color}`}>\r\n <IconComponent />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"font-semibold text-[var(--text-primary)]\">{name}</span>\r\n {isConfigured ? (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.configured', 'Configuré')}\r\n </span>\r\n ) : (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.notConfigured', 'Non configuré')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {isConfigured\r\n ? t('appsettings.oauthConfiguredDesc', 'OAuth authentication is enabled')\r\n : t('appsettings.oauthNotConfiguredDesc', 'ClientId not configured in appsettings.json')\r\n }\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* OAuth Providers Summary */}\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('appsettings.sections.oauthProviders', 'OAuth Providers')}\r\n </h3>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {renderOAuthCard('Microsoft', microsoftConfigured, MicrosoftIcon, 'bg-blue-500/20 text-blue-600')}\r\n {renderOAuthCard('Google', googleConfigured, GoogleIcon, 'bg-red-500/20 text-red-600')}\r\n </div>\r\n </div>\r\n\r\n {/* JWT Configuration */}\r\n {renderSection(\r\n t('appsettings.sections.jwt', 'JWT Configuration'),\r\n t('appsettings.sections.jwtDescription', 'JSON Web Token settings for authentication'),\r\n jwtSettings,\r\n Key,\r\n 'from-violet-500/10 to-violet-600/5',\r\n 'bg-violet-500/20 text-violet-600',\r\n 'active'\r\n )}\r\n\r\n {/* Session Configuration */}\r\n {renderSection(\r\n t('appsettings.sections.session', 'Session'),\r\n t('appsettings.sections.sessionDescription', 'User session timeout and validation settings'),\r\n sessionSettings,\r\n Clock,\r\n 'from-amber-500/10 to-amber-600/5',\r\n 'bg-amber-500/20 text-amber-600',\r\n 'active'\r\n )}\r\n\r\n {authSettings.length === 0 && sessionSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('appsettings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default AuthenticationSection;\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { FileText, Monitor, Database, BarChart3, CheckCircle2, CircleSlash } from 'lucide-react';\r\nimport { type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\ntype SectionStatus = 'active' | 'inactive' | 'neutral';\r\n\r\nexport function LoggingSection(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { settings } = useOutletContext<SettingsContext>();\r\n\r\n // Filter logging settings\r\n const loggingSettings = settings.filter(s => s.category === 'Logging');\r\n\r\n // Categorize logging settings\r\n const fileSettings = loggingSettings.filter(s =>\r\n s.key.includes('File') || s.key.includes('Rolling') || s.key.includes('Retention')\r\n );\r\n const seqSettings = loggingSettings.filter(s => s.key.includes('Seq'));\r\n const appInsightsSettings = loggingSettings.filter(s => s.key.includes('AppInsights'));\r\n const levelSettings = loggingSettings.filter(s => s.key.includes('Level') || s.key.includes('Minimum'));\r\n\r\n // Check which sinks are enabled\r\n const consoleEnabled = loggingSettings.find(s => s.key === 'ConsoleEnabled')?.value === 'true';\r\n const fileEnabled = loggingSettings.find(s => s.key === 'FileEnabled')?.value === 'true';\r\n const seqEnabled = loggingSettings.find(s => s.key === 'SeqEnabled')?.value === 'true';\r\n const appInsightsEnabled = loggingSettings.find(s => s.key === 'AppInsightsEnabled')?.value === 'true';\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n\r\n const getDisplayValue = () => {\r\n if (setting.isSensitive) return '********';\r\n const displayVal = setting.displayValue || setting.value;\r\n if (setting.valueType === 'Bool') {\r\n return displayVal === 'true' || displayVal === 'Yes' ? t('common.yes') : t('common.no');\r\n }\r\n return displayVal;\r\n };\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`appsettings.keys.Logging.${setting.key}`, setting.key)}\r\n </span>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`appsettings.descriptions.Logging.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"text-right max-w-[50%]\">\r\n <span className={`font-mono text-sm break-all ${\r\n setting.isSensitive\r\n ? 'text-[var(--text-tertiary)]'\r\n : 'text-[var(--text-primary)]'\r\n }`}>\r\n {getDisplayValue()}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderSection = (\r\n title: string,\r\n description: string,\r\n items: SettingViewModel[],\r\n icon: React.ElementType,\r\n gradientFrom: string,\r\n iconColor: string,\r\n status: SectionStatus = 'neutral'\r\n ) => {\r\n const Icon = icon;\r\n if (items.length === 0) return null;\r\n\r\n const isInactive = status === 'inactive';\r\n const isActive = status === 'active';\r\n\r\n let borderClass = 'border-[var(--border-color)]';\r\n if (isActive) borderClass = 'border-green-500/50 ring-1 ring-green-500/20';\r\n else if (isInactive) borderClass = 'border-gray-400/30';\r\n\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border ${borderClass} bg-[var(--bg-card)] overflow-hidden shadow-sm ${isInactive ? 'opacity-50' : ''}`}>\r\n <div className={`px-6 py-4 bg-gradient-to-r ${gradientFrom} border-b border-[var(--border-color)]`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${iconColor}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {title}\r\n </h3>\r\n {isActive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.enabled', 'Activé')}\r\n </span>\r\n )}\r\n {isInactive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.disabled', 'Désactivé')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {items.map(renderSetting)}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n // Summary cards for sinks\r\n const renderSinkCard = (\r\n name: string,\r\n enabled: boolean,\r\n icon: React.ElementType,\r\n color: string\r\n ) => {\r\n const Icon = icon;\r\n return (\r\n <div className={`rounded-lg border ${enabled ? 'border-green-500/50' : 'border-gray-400/30 opacity-50'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${color}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <span className=\"font-semibold text-[var(--text-primary)]\">{name}</span>\r\n {enabled ? (\r\n <span className=\"ml-2 inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.enabled', 'Activé')}\r\n </span>\r\n ) : (\r\n <span className=\"ml-2 inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.disabled', 'Désactivé')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Sinks Summary */}\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('appsettings.sections.loggingSinks', 'Logging Sinks')}\r\n </h3>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4\">\r\n {renderSinkCard('Console', consoleEnabled, Monitor, 'bg-gray-500/20 text-gray-600')}\r\n {renderSinkCard('File', fileEnabled, FileText, 'bg-violet-500/20 text-violet-600')}\r\n {renderSinkCard('Seq', seqEnabled, Database, 'bg-blue-500/20 text-blue-600')}\r\n {renderSinkCard('App Insights', appInsightsEnabled, BarChart3, 'bg-purple-500/20 text-purple-600')}\r\n </div>\r\n </div>\r\n\r\n {/* Log Levels */}\r\n {renderSection(\r\n t('appsettings.sections.logLevels', 'Log Levels'),\r\n t('appsettings.sections.logLevelsDescription', 'Minimum log level configuration'),\r\n levelSettings,\r\n BarChart3,\r\n 'from-emerald-500/10 to-emerald-600/5',\r\n 'bg-emerald-500/20 text-emerald-600',\r\n 'neutral'\r\n )}\r\n\r\n {/* File Logging */}\r\n {renderSection(\r\n t('appsettings.sections.fileLogging', 'File Logging'),\r\n t('appsettings.sections.fileLoggingDescription', 'File-based log output configuration'),\r\n fileSettings,\r\n FileText,\r\n fileEnabled ? 'from-violet-500/10 to-violet-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n fileEnabled ? 'bg-violet-500/20 text-violet-600' : 'bg-gray-500/20 text-gray-500',\r\n fileEnabled ? 'active' : 'inactive'\r\n )}\r\n\r\n {/* Seq Logging */}\r\n {seqSettings.length > 0 && renderSection(\r\n t('appsettings.sections.seqLogging', 'Seq'),\r\n t('appsettings.sections.seqLoggingDescription', 'Seq structured logging server'),\r\n seqSettings,\r\n Database,\r\n seqEnabled ? 'from-blue-500/10 to-blue-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n seqEnabled ? 'bg-blue-500/20 text-blue-600' : 'bg-gray-500/20 text-gray-500',\r\n seqEnabled ? 'active' : 'inactive'\r\n )}\r\n\r\n {/* App Insights */}\r\n {appInsightsSettings.length > 0 && renderSection(\r\n t('appsettings.sections.appInsights', 'Application Insights'),\r\n t('appsettings.sections.appInsightsDescription', 'Azure Application Insights telemetry'),\r\n appInsightsSettings,\r\n BarChart3,\r\n appInsightsEnabled ? 'from-purple-500/10 to-purple-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n appInsightsEnabled ? 'bg-purple-500/20 text-purple-600' : 'bg-gray-500/20 text-gray-500',\r\n appInsightsEnabled ? 'active' : 'inactive'\r\n )}\r\n\r\n {loggingSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('appsettings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default LoggingSection;\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { Mail, Send, CheckCircle2, CircleSlash } from 'lucide-react';\r\nimport { type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\ntype SectionStatus = 'active' | 'inactive' | 'neutral';\r\n\r\nexport function EmailSection(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { settings } = useOutletContext<SettingsContext>();\r\n\r\n // Filter email settings\r\n const emailSettings = settings.filter(s => s.category === 'Email');\r\n\r\n // Check status\r\n const emailEnabled = emailSettings.find(s => s.key === 'Enabled')?.value === 'true';\r\n const emailProvider = emailSettings.find(s => s.key === 'Provider')?.value;\r\n const fromEmail = emailSettings.find(s => s.key === 'FromEmail')?.value;\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n\r\n const getDisplayValue = () => {\r\n if (setting.isSensitive) return '********';\r\n const displayVal = setting.displayValue || setting.value;\r\n if (setting.valueType === 'Bool') {\r\n return displayVal === 'true' || displayVal === 'Yes' ? t('common.yes') : t('common.no');\r\n }\r\n return displayVal;\r\n };\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`appsettings.keys.Email.${setting.key}`, setting.key)}\r\n </span>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`appsettings.descriptions.Email.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"text-right max-w-[50%]\">\r\n <span className={`font-mono text-sm break-all ${\r\n setting.isSensitive\r\n ? 'text-[var(--text-tertiary)]'\r\n : 'text-[var(--text-primary)]'\r\n }`}>\r\n {getDisplayValue()}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderSection = (\r\n title: string,\r\n description: string,\r\n items: SettingViewModel[],\r\n icon: React.ElementType,\r\n gradientFrom: string,\r\n iconColor: string,\r\n status: SectionStatus = 'neutral'\r\n ) => {\r\n const Icon = icon;\r\n if (items.length === 0) return null;\r\n\r\n const isInactive = status === 'inactive';\r\n const isActive = status === 'active';\r\n\r\n let borderClass = 'border-[var(--border-color)]';\r\n if (isActive) borderClass = 'border-green-500/50 ring-1 ring-green-500/20';\r\n else if (isInactive) borderClass = 'border-gray-400/30';\r\n\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border ${borderClass} bg-[var(--bg-card)] overflow-hidden shadow-sm ${isInactive ? 'opacity-50' : ''}`}>\r\n <div className={`px-6 py-4 bg-gradient-to-r ${gradientFrom} border-b border-[var(--border-color)]`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${iconColor}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {title}\r\n </h3>\r\n {isActive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.enabled', 'Activé')}\r\n </span>\r\n )}\r\n {isInactive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.disabled', 'Désactivé')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {items.map(renderSetting)}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Summary Card */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n <div className={`rounded-lg border ${emailEnabled ? 'border-green-500/50' : 'border-gray-400/30 opacity-50'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.status', 'Status')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n {emailEnabled ? (\r\n <>\r\n <CheckCircle2 className=\"w-5 h-5 text-green-500\" />\r\n {t('appsettings.enabled', 'Activé')}\r\n </>\r\n ) : (\r\n <>\r\n <CircleSlash className=\"w-5 h-5 text-gray-500\" />\r\n {t('appsettings.disabled', 'Désactivé')}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Email.Provider', 'Provider')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Send className=\"w-5 h-5 text-amber-500\" />\r\n {emailProvider || 'N/A'}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Email.FromEmail', 'From Email')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Mail className=\"w-5 h-5 text-amber-500\" />\r\n <span className=\"truncate\">{fromEmail || 'N/A'}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Email Configuration */}\r\n {renderSection(\r\n t('appsettings.sections.emailConfiguration', 'Email Configuration'),\r\n t('appsettings.sections.emailConfigurationDescription', 'SMTP and email provider settings'),\r\n emailSettings,\r\n Mail,\r\n emailEnabled ? 'from-amber-500/10 to-amber-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n emailEnabled ? 'bg-amber-500/20 text-amber-600' : 'bg-gray-500/20 text-gray-500',\r\n emailEnabled ? 'active' : 'inactive'\r\n )}\r\n\r\n {emailSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('appsettings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default EmailSection;\r\n","import type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useOutletContext } from 'react-router-dom';\r\nimport { Cloud, RefreshCw, CheckCircle2, CircleSlash } from 'lucide-react';\r\nimport { type SettingViewModel } from '@/services/api/adminApi';\r\n\r\ninterface SettingsContext {\r\n settings: SettingViewModel[];\r\n refreshSettings: () => Promise<void>;\r\n}\r\n\r\ntype SectionStatus = 'active' | 'inactive' | 'neutral';\r\n\r\nexport function EntraSection(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { settings } = useOutletContext<SettingsContext>();\r\n\r\n // Filter Entra settings\r\n const entraSettings = settings.filter(s => s.category === 'Entra');\r\n\r\n // Check status\r\n const syncEnabled = entraSettings.find(s => s.key === 'SyncEnabled')?.value === 'true';\r\n const isConfigured = entraSettings.find(s => s.key === 'Configured')?.value === 'true';\r\n const syncInterval = entraSettings.find(s => s.key === 'SyncIntervalMinutes')?.value;\r\n const useDeltaSync = entraSettings.find(s => s.key === 'UseDeltaSync')?.value === 'true';\r\n\r\n const renderSetting = (setting: SettingViewModel) => {\r\n const editKey = `${setting.category}.${setting.key}`;\r\n\r\n const getDisplayValue = () => {\r\n if (setting.isSensitive) return '********';\r\n const displayVal = setting.displayValue || setting.value;\r\n if (setting.valueType === 'Bool') {\r\n return displayVal === 'true' || displayVal === 'Yes' ? t('common.yes') : t('common.no');\r\n }\r\n return displayVal;\r\n };\r\n\r\n return (\r\n <div\r\n key={editKey}\r\n className=\"flex items-center justify-between py-3 border-b border-[var(--border-color)] last:border-0\"\r\n >\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t(`appsettings.keys.Entra.${setting.key}`, setting.key)}\r\n </span>\r\n {setting.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t(`appsettings.descriptions.Entra.${setting.key}`, setting.description)}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"text-right max-w-[50%]\">\r\n <span className={`font-mono text-sm break-all ${\r\n setting.isSensitive\r\n ? 'text-[var(--text-tertiary)]'\r\n : 'text-[var(--text-primary)]'\r\n }`}>\r\n {getDisplayValue()}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderSection = (\r\n title: string,\r\n description: string,\r\n items: SettingViewModel[],\r\n icon: React.ElementType,\r\n gradientFrom: string,\r\n iconColor: string,\r\n status: SectionStatus = 'neutral'\r\n ) => {\r\n const Icon = icon;\r\n if (items.length === 0) return null;\r\n\r\n const isInactive = status === 'inactive';\r\n const isActive = status === 'active';\r\n\r\n let borderClass = 'border-[var(--border-color)]';\r\n if (isActive) borderClass = 'border-green-500/50 ring-1 ring-green-500/20';\r\n else if (isInactive) borderClass = 'border-gray-400/30';\r\n\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border ${borderClass} bg-[var(--bg-card)] overflow-hidden shadow-sm ${isInactive ? 'opacity-50' : ''}`}>\r\n <div className={`px-6 py-4 bg-gradient-to-r ${gradientFrom} border-b border-[var(--border-color)]`}>\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`p-2 rounded-lg ${iconColor}`}>\r\n <Icon className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {title}\r\n </h3>\r\n {isActive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30\">\r\n <CheckCircle2 className=\"w-3 h-3\" />\r\n {t('appsettings.enabled', 'Activé')}\r\n </span>\r\n )}\r\n {isInactive && (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-gray-500/20 text-gray-600 dark:text-gray-400 border border-gray-500/30\">\r\n <CircleSlash className=\"w-3 h-3\" />\r\n {t('appsettings.disabled', 'Désactivé')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"px-6 py-2\">\r\n {items.map(renderSetting)}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Summary Cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-4 gap-4\">\r\n <div className={`rounded-lg border ${isConfigured ? 'border-green-500/50' : 'border-gray-400/30 opacity-50'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.configuration', 'Configuration')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n {isConfigured ? (\r\n <>\r\n <CheckCircle2 className=\"w-5 h-5 text-green-500\" />\r\n {t('appsettings.configured', 'Configuré')}\r\n </>\r\n ) : (\r\n <>\r\n <CircleSlash className=\"w-5 h-5 text-gray-500\" />\r\n {t('appsettings.notConfigured', 'Non configuré')}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n <div className={`rounded-lg border ${syncEnabled ? 'border-green-500/50' : 'border-gray-400/30 opacity-50'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Entra.SyncEnabled', 'Sync Status')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <RefreshCw className={`w-5 h-5 ${syncEnabled ? 'text-green-500' : 'text-gray-500'}`} />\r\n {syncEnabled ? t('appsettings.enabled', 'Activé') : t('appsettings.disabled', 'Désactivé')}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg border border-[var(--border-color)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Entra.SyncIntervalMinutes', 'Sync Interval')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Cloud className=\"w-5 h-5 text-sky-500\" />\r\n {syncInterval ? `${syncInterval} min` : 'N/A'}\r\n </div>\r\n </div>\r\n <div className={`rounded-lg border ${useDeltaSync ? 'border-green-500/50' : 'border-[var(--border-color)]'} bg-[var(--bg-card)] p-4`}>\r\n <div className=\"text-xs text-[var(--text-secondary)] uppercase tracking-wider mb-1\">\r\n {t('appsettings.keys.Entra.UseDeltaSync', 'Delta Sync')}\r\n </div>\r\n <div className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n {useDeltaSync ? (\r\n <>\r\n <CheckCircle2 className=\"w-5 h-5 text-green-500\" />\r\n {t('common.yes', 'Oui')}\r\n </>\r\n ) : (\r\n <>\r\n <CircleSlash className=\"w-5 h-5 text-gray-500\" />\r\n {t('common.no', 'Non')}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Entra Configuration */}\r\n {renderSection(\r\n t('appsettings.sections.entraConfiguration', 'Microsoft Entra ID'),\r\n t('appsettings.sections.entraConfigurationDescription', 'Azure AD synchronization settings'),\r\n entraSettings,\r\n Cloud,\r\n isConfigured ? 'from-sky-500/10 to-sky-600/5' : 'from-gray-500/10 to-gray-600/5',\r\n isConfigured ? 'bg-sky-500/20 text-sky-600' : 'bg-gray-500/20 text-gray-500',\r\n isConfigured ? 'active' : 'inactive'\r\n )}\r\n\r\n {entraSettings.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('appsettings.noSettings')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default EntraSection;\r\n"],"names":["TABS","Server","Shield","FileText","Mail","Cloud","AppSettingsPage","useTranslation","navigate","useNavigate","location","useLocation","settings","setSettings","useState","loading","setLoading","loadSettings","useCallback","readonlySettings","adminApi","s","err","useEffect","getCurrentTab","path","t","handleTabChange","tabId","tab","jsx","Loader2","jsxs","Breadcrumb","Info","Icon","isActive","Outlet","InfrastructureSection","useOutletContext","databaseSettings","storageSettings","localStorageSettings","azureStorageSettings","storageProvider","databaseServer","databaseName","isAzureActive","isLocalActive","renderSetting","setting","editKey","getDisplayValue","displayVal","renderSection","title","description","items","icon","gradientFrom","iconColor","status","statusLabel","isInactive","borderClass","CheckCircle2","CircleSlash","Database","HardDrive","MicrosoftIcon","GoogleIcon","AuthenticationSection","authSettings","sessionSettings","jwtSettings","microsoftConfigured","googleConfigured","renderOAuthCard","name","isConfigured","IconComponent","color","Key","Clock","LoggingSection","loggingSettings","fileSettings","seqSettings","appInsightsSettings","levelSettings","consoleEnabled","fileEnabled","seqEnabled","appInsightsEnabled","renderSinkCard","enabled","Monitor","BarChart3","EmailSection","emailSettings","emailEnabled","emailProvider","fromEmail","Fragment","Send","EntraSection","entraSettings","syncEnabled","syncInterval","useDeltaSync","RefreshCw"],"mappings":"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"}
|