@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-sMr9qND_.js","sources":["../../src/hooks/useTenantFilters.ts","../../src/pages/platform/administration/tenants/TenantsPage.tsx","../../src/hooks/useTenantDetail.ts","../../src/hooks/useTenantMembers.ts","../../src/hooks/useTenantGroups.ts","../../src/hooks/useTenantApplications.ts","../../src/hooks/useTenantOrganisation.ts","../../src/hooks/useTenantRoles.ts","../../src/components/platform/administration/tenants/TenantOverviewTab.tsx","../../src/components/platform/administration/tenants/TenantMembersTab.tsx","../../src/components/platform/administration/tenants/TenantGroupsTab.tsx","../../src/components/platform/administration/tenants/TenantRolesTab.tsx","../../src/components/platform/administration/ApplicationAccessCustomizeDrawer.tsx","../../src/components/platform/administration/tenants/TenantApplicationsTab.tsx","../../src/pages/platform/administration/tenants/TenantDetailPage.tsx","../../src/pages/platform/administration/tenants/TenantCreatePage.tsx","../../src/components/dashboard/TenantActivityPieChart.tsx","../../src/components/dashboard/TenantUsageTrendChart.tsx","../../src/components/dashboard/TenantPopularityChart.tsx","../../src/pages/platform/administration/tenants/TenantsDashboardPage.tsx","../../src/hooks/useTemplateApplications.ts","../../src/pages/platform/administration/tenants/TenantTemplateDetailPage.tsx","../../src/pages/platform/administration/tenants/TenantsTemplatePage.tsx","../../src/pages/platform/administration/tenants/TenantTemplateCreatePage.tsx","../../src/pages/platform/administration/tenants/TenantsBusinessPage.tsx","../../src/pages/platform/administration/tenants/TenantsPersonalPage.tsx","../../src/pages/platform/administration/tenants/TenantsOtherPage.tsx","../../src/pages/platform/administration/tenants/TenantAccessRequestsPage.tsx","../../src/components/platform/administration/TenantEntraTab.tsx","../../src/components/platform/administration/tenants/TenantSupportSettingsTab.tsx","../../src/pages/platform/administration/tenants/TenantSettingsPage.tsx","../../src/pages/platform/administration/tenants/TenantTypeSettingsPage.tsx","../../src/pages/platform/administration/tenants/OrganisationsListPage.tsx","../../src/pages/platform/administration/tenants/OrganisationDetailPage.tsx","../../src/components/platform/administration/organisations/CreateOrganisationForm.tsx","../../src/pages/platform/administration/tenants/OrganisationCreatePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\r\nimport type { TenantStatus, TenantType } from '@/services/api/adminApi';\r\n\r\ninterface FilterState {\r\n search: string;\r\n status: TenantStatus | '';\r\n type: TenantType | '';\r\n}\r\n\r\nconst VALID_STATUSES: TenantStatus[] = ['Pending', 'Active', 'Suspended', 'Archived'];\r\nconst VALID_TYPES: TenantType[] = ['Personal', 'Business', 'System'];\r\n\r\nconst defaultFilters: FilterState = {\r\n search: '',\r\n status: '',\r\n type: 'Business',\r\n};\r\n\r\nexport const validateStatus = (value: string | null): TenantStatus | '' => {\r\n if (!value) return '';\r\n return VALID_STATUSES.includes(value as TenantStatus) ? (value as TenantStatus) : '';\r\n};\r\n\r\nexport const validateType = (value: string | null): TenantType | '' => {\r\n if (!value) return '';\r\n return VALID_TYPES.includes(value as TenantType) ? (value as TenantType) : '';\r\n};\r\n\r\nexport const validatePage = (value: string | null): number => {\r\n const parsed = parseInt(value || '1', 10);\r\n return isNaN(parsed) || parsed < 1 ? 1 : parsed;\r\n};\r\n\r\nexport const getDefaultFilters = (lockedType?: TenantType, excludeTypes?: TenantType[]): FilterState => ({\r\n ...defaultFilters,\r\n type: lockedType || (excludeTypes ? '' as const : 'Business' as const),\r\n});\r\n\r\nexport function useActiveFilterCount(\r\n filters: FilterState,\r\n lockedType?: TenantType,\r\n excludeTypes?: TenantType[]\r\n): number {\r\n return useMemo(() => {\r\n let count = 0;\r\n if (filters.status) count++;\r\n if (!lockedType && !excludeTypes && filters.type) count++;\r\n return count;\r\n }, [filters, lockedType, excludeTypes]);\r\n}\r\n","import { useState, useEffect, useCallback, useMemo } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate, useSearchParams } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Search,\r\n Edit2,\r\n MoreHorizontal,\r\n Building2,\r\n Users,\r\n Boxes,\r\n PlayCircle,\r\n PauseCircle,\r\n Archive,\r\n Loader2,\r\n Building,\r\n User,\r\n Filter,\r\n RotateCcw,\r\n ChevronDown,\r\n Eye,\r\n AlertCircle,\r\n Layers,\r\n Clock,\r\n ArrowUpDown,\r\n ArrowUp,\r\n ArrowDown,\r\n Server\r\n} from 'lucide-react';\r\nimport { adminApi, type TenantListDto, type TenantStatus, type TenantType } from '@/services/api/adminApi';\r\nimport { useTenantTypeSettings } from '@/hooks/useTenantTypeSettings';\r\nimport { getLucideIcon, getColorClasses } from '@/utils/tenantIconMap';\r\nimport { ViewToggle, StatusBadge, Pagination, type ViewMode } from '@/components/ui/DataView';\r\nimport { EntityCard, type EntityCardAction, type EntityCardTag } from '@/components/ui/EntityCard';\r\nimport { PageHeader } from '@/components/ui/PageHeader';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { ConfirmModal, type ConfirmVariant } from '@/components/ui/ConfirmModal';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { useTenantUrl } from '@/utils/tenantUrl';\r\n\r\n// Debounce hook for search\r\nfunction useDebounce<T>(value: T, delay: number): T {\r\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\r\n useEffect(() => {\r\n const handler = setTimeout(() => setDebouncedValue(value), delay);\r\n return () => clearTimeout(handler);\r\n }, [value, delay]);\r\n return debouncedValue;\r\n}\r\n\r\n// Status configuration with CSS variables for theme compliance\r\nconst STATUS_CONFIG: Record<TenantStatus, { color: string; bgColor: string; borderColor: string; statusBadge: 'active' | 'inactive' | 'pending' | 'warning' | 'error' }> = {\r\n Pending: {\r\n color: 'text-[var(--info-text)]',\r\n bgColor: 'bg-[var(--info-bg)]',\r\n borderColor: 'border-[var(--info-border)]',\r\n statusBadge: 'pending'\r\n },\r\n Active: {\r\n color: 'text-[var(--success-text)]',\r\n bgColor: 'bg-[var(--success-bg)]',\r\n borderColor: 'border-[var(--success-border)]',\r\n statusBadge: 'active'\r\n },\r\n Suspended: {\r\n color: 'text-[var(--warning-text)]',\r\n bgColor: 'bg-[var(--warning-bg)]',\r\n borderColor: 'border-[var(--warning-border)]',\r\n statusBadge: 'warning'\r\n },\r\n Archived: {\r\n color: 'text-[var(--text-tertiary)]',\r\n bgColor: 'bg-[var(--bg-tertiary)]',\r\n borderColor: 'border-[var(--border-color)]',\r\n statusBadge: 'inactive'\r\n }\r\n};\r\n\r\nconst TYPE_CONFIG: Record<TenantType, { icon: typeof Building2; label: string }> = {\r\n Personal: { icon: User, label: 'tenants.type.personal' },\r\n Business: { icon: Building, label: 'tenants.type.business' },\r\n System: { icon: Server, label: 'tenants.type.system' }\r\n};\r\n\r\nimport {\r\n validateStatus,\r\n validateType,\r\n validatePage,\r\n getDefaultFilters,\r\n useActiveFilterCount,\r\n} from '@/hooks/useTenantFilters';\r\n\r\ninterface FilterState {\r\n search: string;\r\n status: TenantStatus | '';\r\n type: TenantType | '';\r\n}\r\n\r\n// Props interface for the component\r\ninterface TenantsPageProps {\r\n readonly lockedType?: TenantType;\r\n readonly excludeTypes?: TenantType[];\r\n}\r\n\r\nexport function TenantsPage({ lockedType, excludeTypes }: TenantsPageProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n const { currentTenant, isGlobalView, refreshTenants } = useTenant();\r\n const buildTenantUrl = useTenantUrl();\r\n const { getIconForType } = useTenantTypeSettings();\r\n\r\n // Initialize filters from URL params (only on mount) - F1: validated\r\n const initialFilters: FilterState = useMemo(\r\n () => ({\r\n search: searchParams.get('search') || '',\r\n status: validateStatus(searchParams.get('status')),\r\n type: lockedType || validateType(searchParams.get('type')) || (excludeTypes ? '' : 'Business')\r\n }),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n []\r\n );\r\n\r\n const [tenants, setTenants] = useState<TenantListDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [filters, setFilters] = useState<FilterState>(initialFilters);\r\n const [showFilters, setShowFilters] = useState(false);\r\n const [menuOpen, setMenuOpen] = useState<string | null>(null);\r\n const [actionLoading, setActionLoading] = useState<string | null>(null);\r\n const [confirmAction, setConfirmAction] = useState<{ tenant: TenantListDto; action: 'activate' | 'suspend' | 'archive' } | null>(null);\r\n const [viewMode, setViewMode] = useState<ViewMode>('table');\r\n const [page, setPage] = useState(validatePage(searchParams.get('page')));\r\n const [totalPages, setTotalPages] = useState(1);\r\n const [totalCount, setTotalCount] = useState(0);\r\n const [error, setError] = useState<string | null>(null);\r\n const [sortKey, setSortKey] = useState<string>('name');\r\n const [sortDesc, setSortDesc] = useState(false);\r\n\r\n // Debounce search input\r\n const debouncedSearch = useDebounce(filters.search, 300);\r\n\r\n // Count active filters (exclude lockedType since it's not user-resettable)\r\n const activeFilterCount = useActiveFilterCount(filters, lockedType, excludeTypes);\r\n\r\n const loadTenants = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n setError(null);\r\n const result = await adminApi.tenants.getAll({\r\n page,\r\n pageSize: 20,\r\n search: debouncedSearch || undefined,\r\n status: filters.status || undefined,\r\n type: filters.type || undefined,\r\n sortBy: sortKey,\r\n sortDesc,\r\n excludeTypes,\r\n });\r\n setTenants(result.items);\r\n setTotalCount(result.totalCount);\r\n setTotalPages(result.totalPages);\r\n } catch (err) {\r\n console.error('Failed to load tenants:', err);\r\n setError(t('tenants.loadError'));\r\n setTenants([]);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [page, debouncedSearch, filters.status, filters.type, sortKey, sortDesc, t, currentTenant?.id, isGlobalView, excludeTypes]);\r\n\r\n // Update URL params when filters change\r\n useEffect(() => {\r\n const params = new URLSearchParams();\r\n if (filters.search) params.set('search', filters.search);\r\n if (filters.status) params.set('status', filters.status);\r\n if (filters.type) params.set('type', filters.type);\r\n if (page > 1) params.set('page', page.toString());\r\n setSearchParams(params, { replace: true });\r\n }, [filters, page, setSearchParams]);\r\n\r\n useEffect(() => {\r\n loadTenants();\r\n }, [loadTenants]);\r\n\r\n const handleResetFilters = () => {\r\n setFilters(getDefaultFilters(lockedType, excludeTypes));\r\n setPage(1);\r\n };\r\n\r\n const updateFilter = <K extends keyof FilterState>(key: K, value: FilterState[K]) => {\r\n // If lockedType is set and trying to change type, prevent the change\r\n if (lockedType && key === 'type') {\r\n return;\r\n }\r\n setFilters(prev => ({ ...prev, [key]: value }));\r\n setPage(1);\r\n };\r\n\r\n const handleActivate = (tenant: TenantListDto) => {\r\n setMenuOpen(null);\r\n setConfirmAction({ tenant, action: 'activate' });\r\n };\r\n\r\n const handleSuspend = (tenant: TenantListDto) => {\r\n setMenuOpen(null);\r\n setConfirmAction({ tenant, action: 'suspend' });\r\n };\r\n\r\n const handleArchive = (tenant: TenantListDto) => {\r\n setMenuOpen(null);\r\n setConfirmAction({ tenant, action: 'archive' });\r\n };\r\n\r\n const handleConfirmAction = async () => {\r\n if (!confirmAction) return;\r\n const { tenant, action } = confirmAction;\r\n setActionLoading(tenant.id);\r\n try {\r\n if (action === 'activate') await adminApi.tenants.activate(tenant.id);\r\n else if (action === 'suspend') await adminApi.tenants.suspend(tenant.id);\r\n else if (action === 'archive') await adminApi.tenants.archive(tenant.id);\r\n await refreshTenants();\r\n loadTenants();\r\n } catch (err) {\r\n console.error(`Failed to ${action} tenant:`, err);\r\n } finally {\r\n setActionLoading(null);\r\n setConfirmAction(null);\r\n }\r\n };\r\n\r\n const getConfirmModalMessage = (action: 'activate' | 'suspend' | 'archive', tenantName: string): string => {\r\n switch (action) {\r\n case 'activate':\r\n return t('tenants.confirmActivate', { name: tenantName });\r\n case 'suspend':\r\n return t('tenants.confirmSuspend', { name: tenantName });\r\n case 'archive':\r\n return t('tenants.confirmArchive', { name: tenantName });\r\n }\r\n };\r\n\r\n const getConfirmModalLabel = (action: 'activate' | 'suspend' | 'archive'): string => {\r\n switch (action) {\r\n case 'activate':\r\n return t('tenants.actions.activate');\r\n case 'suspend':\r\n return t('tenants.actions.suspend');\r\n case 'archive':\r\n return t('tenants.actions.archive');\r\n }\r\n };\r\n\r\n const getConfirmModalVariant = (action: 'activate' | 'suspend' | 'archive'): ConfirmVariant => {\r\n switch (action) {\r\n case 'activate':\r\n return 'info';\r\n case 'suspend':\r\n return 'warning';\r\n case 'archive':\r\n return 'danger';\r\n }\r\n };\r\n\r\n const getConfirmModalProps = () => {\r\n if (!confirmAction) return null;\r\n const { tenant, action } = confirmAction;\r\n return {\r\n message: getConfirmModalMessage(action, tenant.name),\r\n label: getConfirmModalLabel(action),\r\n variant: getConfirmModalVariant(action),\r\n };\r\n };\r\n\r\n // Stats computed from tenants\r\n const stats = useMemo(() => ({\r\n active: tenants.filter(t => t.status === 'Active').length,\r\n suspended: tenants.filter(t => t.status === 'Suspended').length,\r\n members: tenants.reduce((sum, t) => sum + (t.memberCount ?? 0), 0),\r\n pendingRequests: tenants.reduce((sum, t) => sum + (t.pendingAccessRequestCount ?? 0), 0)\r\n }), [tenants]);\r\n\r\n // Data is already sorted and paginated by the server\r\n const paginatedTenants = tenants;\r\n\r\n const toggleSort = (key: string) => {\r\n if (sortKey === key) {\r\n setSortDesc(!sortDesc);\r\n } else {\r\n setSortKey(key);\r\n setSortDesc(false);\r\n }\r\n setPage(1);\r\n };\r\n\r\n const SortIcon = ({ column }: { column: string }) => {\r\n if (sortKey !== column) return <ArrowUpDown className=\"w-3.5 h-3.5 text-[var(--text-muted)] opacity-0 group-hover/th:opacity-100 transition-opacity\" />;\r\n return sortDesc\r\n ? <ArrowDown className=\"w-3.5 h-3.5 text-[var(--color-accent-500)]\" />\r\n : <ArrowUp className=\"w-3.5 h-3.5 text-[var(--color-accent-500)]\" />;\r\n };\r\n\r\n const getTenantStatusVariant = (status: TenantStatus): 'success' | 'warning' | 'info' | 'default' => {\r\n if (status === 'Active') return 'success';\r\n if (status === 'Suspended') return 'warning';\r\n if (status === 'Pending') return 'info';\r\n return 'default';\r\n };\r\n\r\n const getPageTitle = (): string => {\r\n if (excludeTypes) return t('tenants.other.title');\r\n switch (lockedType) {\r\n case 'Business':\r\n return t('tenants.enterprise.title');\r\n case 'Personal':\r\n return t('tenants.personal.title');\r\n default:\r\n return t('tenants.title');\r\n }\r\n };\r\n\r\n const getPageSubtitle = (): string => {\r\n if (excludeTypes) return t('tenants.other.subtitle');\r\n switch (lockedType) {\r\n case 'Business':\r\n return t('tenants.enterprise.subtitle');\r\n case 'Personal':\r\n return t('tenants.personal.subtitle');\r\n default:\r\n return t('tenants.subtitle');\r\n }\r\n };\r\n\r\n const getPageIcon = () => {\r\n if (excludeTypes) return Server;\r\n switch (lockedType) {\r\n case 'Business':\r\n return Building;\r\n case 'Personal':\r\n return User;\r\n default:\r\n return Building2;\r\n }\r\n };\r\n\r\n const pageTitle = getPageTitle();\r\n const pageSubtitle = getPageSubtitle();\r\n const PageIcon = getPageIcon();\r\n\r\n const hideTypeColumn = !!lockedType || !!excludeTypes;\r\n // Calculate column count dynamically\r\n const columnCount = 5 + (!hideTypeColumn ? 1 : 0) + 1; // name + status + template + members + requests + actions, optionally type\r\n\r\n const renderTableHeader = (columnLabel: string, columnKey: string, hidden: string = '') => (\r\n <th\r\n className={`text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider cursor-pointer select-none group/th hover:text-[var(--text-primary)] transition-colors ${hidden}`}\r\n onClick={() => toggleSort(columnKey)}\r\n >\r\n <span className=\"inline-flex items-center gap-1.5\">\r\n {columnLabel}\r\n <SortIcon column={columnKey} />\r\n </span>\r\n </th>\r\n );\r\n\r\n const renderTableActionsMenu = (tenant: TenantListDto) => (\r\n <div className=\"flex items-center justify-end gap-1\" onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()} role=\"presentation\">\r\n <div className=\"relative\">\r\n <button\r\n onClick={() => setMenuOpen(menuOpen === tenant.id ? null : tenant.id)}\r\n className=\"p-2 rounded-lg text-[var(--text-tertiary)] hover:bg-[var(--bg-tertiary)] transition-all\"\r\n >\r\n {actionLoading === tenant.id ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <MoreHorizontal className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n\r\n {menuOpen === tenant.id && (\r\n <div className=\"absolute right-0 mt-1 w-48 bg-[var(--bg-card)] border border-[var(--border-color)] shadow-lg z-50\" style={{ borderRadius: 'var(--radius-card)' }}>\r\n <button\r\n onClick={() => {\r\n setMenuOpen(null);\r\n navigate(buildTenantUrl(`/administration/tenants/${tenant.id}`));\r\n }}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <Eye className=\"w-4 h-4\" />\r\n {t('tenants.view')}\r\n </button>\r\n <button\r\n onClick={() => {\r\n setMenuOpen(null);\r\n navigate(buildTenantUrl(`/administration/tenants/${tenant.id}`));\r\n }}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <Edit2 className=\"w-4 h-4\" />\r\n {t('common.edit')}\r\n </button>\r\n <button\r\n onClick={() => {\r\n setMenuOpen(null);\r\n navigate(buildTenantUrl(`/administration/tenants/${tenant.id}/members`));\r\n }}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <Users className=\"w-4 h-4\" />\r\n {t('tenants.actions.viewMembers')}\r\n </button>\r\n <div className=\"border-t border-[var(--border-color)] my-1\" />\r\n {tenant.status !== 'Active' && tenant.status !== 'Archived' && (\r\n <button\r\n onClick={() => handleActivate(tenant)}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm text-[var(--success-text)] hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <PlayCircle className=\"w-4 h-4\" />\r\n {t('tenants.actions.activate')}\r\n </button>\r\n )}\r\n {tenant.status === 'Active' && (\r\n <button\r\n onClick={() => handleSuspend(tenant)}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm text-[var(--warning-text)] hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <PauseCircle className=\"w-4 h-4\" />\r\n {t('tenants.actions.suspend')}\r\n </button>\r\n )}\r\n {tenant.status !== 'Archived' && (\r\n <button\r\n onClick={() => handleArchive(tenant)}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm text-[var(--error-text)] hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <Archive className=\"w-4 h-4\" />\r\n {t('tenants.actions.archive')}\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n\r\n const renderTableRow = (tenant: TenantListDto) => {\r\n const typeInfo = getIconForType(tenant.type);\r\n const RowIcon = getLucideIcon(typeInfo.icon);\r\n const rowColors = getColorClasses(typeInfo.color);\r\n const statusConfig = STATUS_CONFIG[tenant.status];\r\n\r\n return (\r\n <tr\r\n key={tenant.id}\r\n className={`group hover:bg-[var(--bg-hover)] transition-all cursor-pointer ${menuOpen === tenant.id ? 'relative z-10' : ''}`}\r\n onClick={() => navigate(buildTenantUrl(`/administration/tenants/${tenant.id}`))}\r\n >\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`w-10 h-10 flex items-center justify-center ${rowColors.bg}`} style={{ borderRadius: 'var(--radius-card)' }}>\r\n <RowIcon className={`w-5 h-5 ${rowColors.text}`} />\r\n </div>\r\n <div className=\"min-w-0\">\r\n <p className=\"font-medium text-[var(--text-primary)] group-hover:text-[var(--color-accent-600)] transition-colors truncate\">\r\n {tenant.name}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-tertiary)] truncate\">{tenant.slug}</p>\r\n </div>\r\n </div>\r\n </td>\r\n {!hideTypeColumn && (\r\n <td className=\"px-4 py-3 hidden md:table-cell\">\r\n <div className=\"flex items-center gap-2\">\r\n <RowIcon className={`w-4 h-4 ${rowColors.text}`} />\r\n <span className=\"text-sm text-[var(--text-secondary)]\">\r\n {t(TYPE_CONFIG[tenant.type].label)}\r\n </span>\r\n </div>\r\n {tenant.organisation?.name && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5 truncate\">{tenant.organisation.name}</p>\r\n )}\r\n </td>\r\n )}\r\n <td className=\"px-4 py-3\">\r\n <StatusBadge\r\n status={statusConfig.statusBadge}\r\n label={t(`tenants.status.${tenant.status.toLowerCase()}`)}\r\n />\r\n </td>\r\n <td className=\"px-4 py-3 hidden md:table-cell\">\r\n {tenant.templateName ? (\r\n <div className=\"flex items-center gap-2\">\r\n <Layers className=\"w-4 h-4 text-[var(--color-accent-500)]\" />\r\n <span className=\"text-sm text-[var(--text-primary)]\">{tenant.templateName}</span>\r\n </div>\r\n ) : (\r\n <span className=\"text-sm text-[var(--text-tertiary)]\">-</span>\r\n )}\r\n </td>\r\n <td className=\"px-4 py-3 text-center hidden lg:table-cell\">\r\n <span className=\"text-sm text-[var(--text-primary)]\">{tenant.memberCount ?? 0}</span>\r\n </td>\r\n <td className=\"px-4 py-3 text-center hidden lg:table-cell\">\r\n {(tenant.pendingAccessRequestCount ?? 0) > 0 ? (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)]\">\r\n <Clock className=\"w-3 h-3\" />\r\n {tenant.pendingAccessRequestCount}\r\n </span>\r\n ) : (\r\n <span className=\"text-sm text-[var(--text-tertiary)]\">-</span>\r\n )}\r\n </td>\r\n <td className=\"px-4 py-3\">\r\n {renderTableActionsMenu(tenant)}\r\n </td>\r\n </tr>\r\n );\r\n };\r\n\r\n const renderLoadingRow = () => (\r\n <tr>\r\n <td colSpan={columnCount} className=\"text-center py-8\">\r\n <div className=\"w-6 h-6 border-2 border-[var(--color-accent-500)] border-t-transparent rounded-full animate-spin mx-auto\" />\r\n </td>\r\n </tr>\r\n );\r\n\r\n const renderEmptyRow = () => (\r\n <tr>\r\n <td colSpan={columnCount} className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('tenants.empty')}\r\n </td>\r\n </tr>\r\n );\r\n\r\n const renderTableView = () => (\r\n <div className=\"card\">\r\n <table className=\"w-full\">\r\n <thead className=\"bg-[var(--bg-secondary)]\" style={{ borderRadius: 'var(--radius-card) var(--radius-card) 0 0' }}>\r\n <tr>\r\n {renderTableHeader(t('tenants.columns.name'), 'name')}\r\n {!hideTypeColumn && renderTableHeader(t('tenants.columns.type'), 'type', 'hidden md:table-cell')}\r\n {renderTableHeader(t('tenants.columns.status'), 'status')}\r\n {renderTableHeader(t('tenants.columns.template'), 'template', 'hidden md:table-cell')}\r\n <th className=\"text-center px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('tenants.columns.members')}\r\n </th>\r\n <th className=\"text-center px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('tenants.columns.requests')}\r\n </th>\r\n <th className=\"w-24 px-4 py-3\"></th>\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--border-color)]\">\r\n {loading && renderLoadingRow()}\r\n {!loading && paginatedTenants.length === 0 && renderEmptyRow()}\r\n {!loading && paginatedTenants.length > 0 && paginatedTenants.map(renderTableRow)}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n\r\n const buildCardTags = (tenant: TenantListDto): EntityCardTag[] => [\r\n {\r\n label: t(`tenants.type.${tenant.type.toLowerCase()}`),\r\n variant: tenant.type === 'Business' ? 'info' : 'primary'\r\n },\r\n {\r\n label: t(`tenants.status.${tenant.status.toLowerCase()}`),\r\n variant: getTenantStatusVariant(tenant.status)\r\n }\r\n ];\r\n\r\n const buildCardActions = (tenant: TenantListDto): EntityCardAction[] => [\r\n {\r\n label: t('common.edit'),\r\n onClick: () => navigate(buildTenantUrl(`/administration/tenants/${tenant.id}`)),\r\n variant: 'primary',\r\n icon: Edit2\r\n },\r\n {\r\n label: t('tenants.actions.viewMembers'),\r\n onClick: () => navigate(buildTenantUrl(`/administration/tenants/${tenant.id}/members`)),\r\n variant: 'ghost',\r\n icon: Users\r\n }\r\n ];\r\n\r\n const buildCardStats = (tenant: TenantListDto) => (\r\n <div className=\"flex items-center gap-4\">\r\n <div className=\"flex items-center gap-1.5\">\r\n <Users className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span>{tenant.memberCount ?? 0} {t('tenants.members')}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5\">\r\n <Boxes className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span>{tenant.applicationCount ?? 0} {t('tenants.applications')}</span>\r\n </div>\r\n </div>\r\n );\r\n\r\n const mapTenantToCardProps = (tenant: TenantListDto) => {\r\n const isB2B = tenant.type === 'Business';\r\n const avatarColor = isB2B ? '#3b82f6' : '#8b5cf6';\r\n\r\n return {\r\n avatar: {\r\n letter: tenant.name.at(0)?.toUpperCase() ?? '',\r\n color: avatarColor\r\n },\r\n title: tenant.name,\r\n subtitle: tenant.slug,\r\n description: tenant.organisation?.name || undefined,\r\n stats: buildCardStats(tenant),\r\n tags: buildCardTags(tenant),\r\n actions: buildCardActions(tenant),\r\n onClick: () => navigate(buildTenantUrl(`/administration/tenants/${tenant.id}`))\r\n };\r\n };\r\n\r\n // Render cards view - using EntityCard component\r\n const renderCardsView = () => (\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6\">\r\n {loading && (\r\n <div className=\"col-span-full flex flex-col items-center justify-center py-16\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-500)]\" />\r\n <span className=\"mt-3 text-sm text-[var(--text-secondary)]\">{t('common.loading')}</span>\r\n </div>\r\n )}\r\n {!loading && paginatedTenants.length === 0 && (\r\n <div className=\"col-span-full flex flex-col items-center justify-center py-16\">\r\n <div className=\"w-16 h-16 rounded-lg bg-[var(--bg-secondary)] flex items-center justify-center mb-3\">\r\n <Building2 className=\"w-8 h-8 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <span className=\"text-[var(--text-secondary)]\">{t('tenants.noTenants')}</span>\r\n </div>\r\n )}\r\n {!loading && paginatedTenants.length > 0 && (\r\n paginatedTenants.map((tenant) => (\r\n <EntityCard key={tenant.id} {...mapTenantToCardProps(tenant)} />\r\n ))\r\n )}\r\n </div>\r\n );\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: buildTenantUrl('/administration') },\r\n ...(lockedType || excludeTypes\r\n ? [\r\n { label: t('tenants.title'), href: buildTenantUrl('/administration/tenants/list') },\r\n { label: (() => {\r\n if (excludeTypes) return t('tenants.other.title');\r\n return lockedType === 'Business' ? t('tenants.enterprise.title') : t('tenants.personal.title');\r\n })() }\r\n ]\r\n : [{ label: t('tenants.title') }]\r\n ),\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <PageHeader\r\n title={pageTitle}\r\n subtitle={pageSubtitle}\r\n icon={<PageIcon className=\"w-6 h-6 text-[var(--color-accent-500)]\" />}\r\n actions={\r\n <>\r\n {!excludeTypes && (!lockedType || lockedType === 'Personal') && (\r\n <button\r\n onClick={() => navigate(buildTenantUrl('/administration/tenants/create') + '?type=b2c')}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <User className=\"w-4 h-4\" />\r\n {t('tenants.createB2C')}\r\n </button>\r\n )}\r\n {!excludeTypes && (!lockedType || lockedType === 'Business') && (\r\n <button\r\n onClick={() => navigate(buildTenantUrl('/administration/tenants/create') + '?type=b2b')}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors\"\r\n >\r\n <Building className=\"w-4 h-4\" />\r\n {t('tenants.createB2B')}\r\n </button>\r\n )}\r\n </>\r\n }\r\n />\r\n\r\n {/* Error display - F6 */}\r\n {error && (\r\n <div className=\"mb-6 p-4 bg-[var(--error-bg)] border border-[var(--error-border)] rounded-[var(--radius-card)] flex items-center gap-3\">\r\n <AlertCircle className=\"w-5 h-5 text-[var(--error-dot)] flex-shrink-0\" />\r\n <span className=\"text-[var(--error-text)]\">{error}</span>\r\n <button\r\n onClick={loadTenants}\r\n className=\"ml-auto text-sm text-[var(--error-text)] hover:underline\"\r\n >\r\n {t('common.retry')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n {/* Toolbar */}\r\n <div className=\"card p-4 mb-6\">\r\n <div className=\"flex flex-col gap-4\">\r\n {/* Search row */}\r\n <div className=\"flex items-center gap-3 flex-wrap\">\r\n <div className=\"relative flex-1 min-w-[200px] max-w-md\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={filters.search}\r\n onChange={(e) => updateFilter('search', e.target.value)}\r\n placeholder={t('common.search')}\r\n className=\"input !pl-10 w-full\"\r\n />\r\n </div>\r\n\r\n {/* Status filter inline when lockedType or excludeTypes (only 1 filter) */}\r\n {(lockedType || excludeTypes) ? (\r\n <div className=\"relative\">\r\n <select\r\n value={filters.status}\r\n onChange={(e) => updateFilter('status', e.target.value as TenantStatus | '')}\r\n className=\"input appearance-none pr-8 min-w-[160px]\"\r\n >\r\n <option value=\"\">{t('tenants.columns.status')}: {t('common.all')}</option>\r\n <option value=\"Pending\">{t('tenants.status.pending')}</option>\r\n <option value=\"Active\">{t('tenants.status.active')}</option>\r\n <option value=\"Suspended\">{t('tenants.status.suspended')}</option>\r\n <option value=\"Archived\">{t('tenants.status.archived')}</option>\r\n </select>\r\n <ChevronDown className=\"absolute right-2.5 top-1/2 -translate-y-1/2 w-4 h-4 pointer-events-none text-[var(--text-tertiary)]\" />\r\n </div>\r\n ) : (\r\n <>\r\n <button\r\n onClick={() => setShowFilters(!showFilters)}\r\n className={`flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] transition-colors ${activeFilterCount > 0 ? 'ring-2 ring-[var(--color-accent-500)]' : ''}`}\r\n >\r\n <Filter className=\"w-4 h-4\" />\r\n {t('common.filters')}\r\n {activeFilterCount > 0 && (\r\n <span className=\"ml-1 px-1.5 py-0.5 text-xs rounded-full bg-[var(--color-accent-500)] text-white\">\r\n {activeFilterCount}\r\n </span>\r\n )}\r\n <ChevronDown className={`w-4 h-4 transition-transform ${showFilters ? 'rotate-180' : ''}`} />\r\n </button>\r\n\r\n {activeFilterCount > 0 && (\r\n <button\r\n onClick={handleResetFilters}\r\n className=\"flex items-center gap-1.5 px-4 py-2 rounded-[var(--radius-button)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <RotateCcw className=\"w-4 h-4\" />\r\n {t('common.reset')}\r\n </button>\r\n )}\r\n </>\r\n )}\r\n\r\n <div className=\"flex-1\" />\r\n\r\n <ViewToggle\r\n viewMode={viewMode}\r\n onChange={setViewMode}\r\n showTable={true}\r\n showCards={true}\r\n showKanban={false}\r\n tableLabel={t('common.table')}\r\n cardsLabel={t('common.cards')}\r\n />\r\n </div>\r\n\r\n {/* Filters panel (only for non-locked type - multiple filters) */}\r\n {!lockedType && !excludeTypes && showFilters && (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 pt-4 border-t border-[var(--border-color)]\">\r\n <div>\r\n <label className=\"block text-xs font-medium text-[var(--text-tertiary)] mb-1.5\">\r\n {t('tenants.columns.status')}\r\n </label>\r\n <div className=\"relative\">\r\n <select\r\n value={filters.status}\r\n onChange={(e) => updateFilter('status', e.target.value as TenantStatus | '')}\r\n className=\"input w-full appearance-none pr-8\"\r\n >\r\n <option value=\"\">{t('common.all')}</option>\r\n <option value=\"Pending\">{t('tenants.status.pending')}</option>\r\n <option value=\"Active\">{t('tenants.status.active')}</option>\r\n <option value=\"Suspended\">{t('tenants.status.suspended')}</option>\r\n <option value=\"Archived\">{t('tenants.status.archived')}</option>\r\n </select>\r\n <ChevronDown className=\"absolute right-2.5 top-1/2 -translate-y-1/2 w-4 h-4 pointer-events-none text-[var(--text-tertiary)]\" />\r\n </div>\r\n </div>\r\n <div>\r\n <label className=\"block text-xs font-medium text-[var(--text-tertiary)] mb-1.5\">\r\n {t('tenants.columns.type')}\r\n </label>\r\n <div className=\"relative\">\r\n <select\r\n value={filters.type}\r\n onChange={(e) => updateFilter('type', e.target.value as TenantType | '')}\r\n className=\"input w-full appearance-none pr-8\"\r\n >\r\n <option value=\"\">{t('common.all')}</option>\r\n <option value=\"Personal\">{t('tenants.type.personal')}</option>\r\n <option value=\"Business\">{t('tenants.type.business')}</option>\r\n <option value=\"System\">{t('tenants.type.system')}</option>\r\n </select>\r\n <ChevronDown className=\"absolute right-2.5 top-1/2 -translate-y-1/2 w-4 h-4 pointer-events-none text-[var(--text-tertiary)]\" />\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Stats */}\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4 mb-6\">\r\n <div className=\"card p-4 border bg-[var(--success-bg)] border-[var(--success-border)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <Building2 className=\"w-8 h-8 text-[var(--success-text)]\" />\r\n <div>\r\n <p className=\"text-2xl font-bold text-[var(--success-text)]\">{stats.active}</p>\r\n <p className=\"text-sm text-[var(--success-text)]\">{t('tenants.status.active')}</p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"card p-4 border bg-[var(--warning-bg)] border-[var(--warning-border)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <PauseCircle className=\"w-8 h-8 text-[var(--warning-text)]\" />\r\n <div>\r\n <p className=\"text-2xl font-bold text-[var(--warning-text)]\">{stats.suspended}</p>\r\n <p className=\"text-sm text-[var(--warning-text)]\">{t('tenants.status.suspended')}</p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"card p-4 border bg-[var(--bg-secondary)] border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <Users className=\"w-8 h-8 text-[var(--text-secondary)]\" />\r\n <div>\r\n <p className=\"text-2xl font-bold text-[var(--text-primary)]\">{stats.members}</p>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{t('tenants.columns.members')}</p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className={`card p-4 border ${stats.pendingRequests > 0 ? 'bg-[var(--warning-bg)] border-[var(--warning-border)]' : 'bg-[var(--bg-secondary)] border-[var(--border-color)]'}`}>\r\n <div className=\"flex items-center gap-3\">\r\n <Clock className={`w-8 h-8 ${stats.pendingRequests > 0 ? 'text-[var(--warning-text)]' : 'text-[var(--text-secondary)]'}`} />\r\n <div>\r\n <p className={`text-2xl font-bold ${stats.pendingRequests > 0 ? 'text-[var(--warning-text)]' : 'text-[var(--text-primary)]'}`}>{stats.pendingRequests}</p>\r\n <p className={`text-sm ${stats.pendingRequests > 0 ? 'text-[var(--warning-text)]' : 'text-[var(--text-secondary)]'}`}>{t('tenants.columns.requests')}</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Content */}\r\n {viewMode === 'table' ? renderTableView() : renderCardsView()}\r\n\r\n {/* Pagination */}\r\n {totalPages > 1 && (\r\n <div className=\"mt-6\">\r\n <Pagination\r\n page={page}\r\n totalPages={totalPages}\r\n totalCount={totalCount}\r\n pageSize={20}\r\n onPageChange={setPage}\r\n itemLabel={t('tenants.title').toLowerCase()}\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Confirm Modal */}\r\n {(() => {\r\n const props = getConfirmModalProps();\r\n return props ? (\r\n <ConfirmModal\r\n isOpen={!!confirmAction}\r\n title={props.label}\r\n message={props.message}\r\n confirmLabel={props.label}\r\n variant={props.variant}\r\n loading={!!actionLoading}\r\n onConfirm={handleConfirmAction}\r\n onCancel={() => setConfirmAction(null)}\r\n />\r\n ) : null;\r\n })()}\r\n </div>\r\n );\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n adminApi,\r\n type TenantDetailDto,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface UseTenantDetailReturn {\r\n tenant: TenantDetailDto | null;\r\n setTenant: (tenant: TenantDetailDto | null) => void;\r\n loading: boolean;\r\n setLoading: (loading: boolean) => void;\r\n error: string | null;\r\n setError: (error: string | null) => void;\r\n loadTenant: () => Promise<void>;\r\n editingGeneralInfo: boolean;\r\n setEditingGeneralInfo: (editing: boolean) => void;\r\n editName: string;\r\n setEditName: (name: string) => void;\r\n editDescription: string;\r\n setEditDescription: (description: string) => void;\r\n savingGeneralInfo: boolean;\r\n setSavingGeneralInfo: (saving: boolean) => void;\r\n handleSaveGeneralInfo: () => Promise<void>;\r\n openEditGeneralInfo: () => void;\r\n closeEditGeneralInfo: () => void;\r\n}\r\n\r\nexport function useTenantDetail(tenantId: string | undefined): UseTenantDetailReturn {\r\n const { t } = useTranslation(['admin', 'common']);\r\n\r\n const [tenant, setTenant] = useState<TenantDetailDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const [editingGeneralInfo, setEditingGeneralInfo] = useState(false);\r\n const [editName, setEditName] = useState('');\r\n const [editDescription, setEditDescription] = useState('');\r\n const [savingGeneralInfo, setSavingGeneralInfo] = useState(false);\r\n\r\n const loadTenant = useCallback(async () => {\r\n if (!tenantId) return;\r\n try {\r\n setError(null);\r\n const data = await adminApi.tenants.getById(tenantId);\r\n setTenant(data);\r\n } catch (err) {\r\n console.error('Failed to load tenant:', err);\r\n setError(t('admin:tenants.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [tenantId, t]);\r\n\r\n const openEditGeneralInfo = useCallback(() => {\r\n if (!tenant) return;\r\n setEditName(tenant.name);\r\n setEditDescription(tenant.description || '');\r\n setEditingGeneralInfo(true);\r\n }, [tenant]);\r\n\r\n const closeEditGeneralInfo = useCallback(() => {\r\n setEditingGeneralInfo(false);\r\n setEditName('');\r\n setEditDescription('');\r\n }, []);\r\n\r\n const handleSaveGeneralInfo = useCallback(async () => {\r\n if (!tenant) return;\r\n setSavingGeneralInfo(true);\r\n try {\r\n await adminApi.tenants.update(tenant.id, {\r\n name: editName,\r\n description: editDescription || undefined,\r\n });\r\n await loadTenant();\r\n closeEditGeneralInfo();\r\n } catch (err) {\r\n console.error('Failed to update tenant:', err);\r\n } finally {\r\n setSavingGeneralInfo(false);\r\n }\r\n }, [tenant, editName, editDescription, loadTenant, closeEditGeneralInfo]);\r\n\r\n return {\r\n tenant,\r\n setTenant,\r\n loading,\r\n setLoading,\r\n error,\r\n setError,\r\n loadTenant,\r\n editingGeneralInfo,\r\n setEditingGeneralInfo,\r\n editName,\r\n setEditName,\r\n editDescription,\r\n setEditDescription,\r\n savingGeneralInfo,\r\n setSavingGeneralInfo,\r\n handleSaveGeneralInfo,\r\n openEditGeneralInfo,\r\n closeEditGeneralInfo,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport {\r\n adminApi,\r\n type TenantMemberDto,\r\n type RoleListDto,\r\n type UserListDto,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface UseTenantMembersReturn {\r\n members: TenantMemberDto[] | null;\r\n setMembers: (members: TenantMemberDto[] | null) => void;\r\n loadingMembers: boolean;\r\n setLoadingMembers: (loading: boolean) => void;\r\n addingMember: boolean;\r\n setAddingMember: (adding: boolean) => void;\r\n availableUsers: UserListDto[];\r\n setAvailableUsers: (users: UserListDto[]) => void;\r\n loadingUsers: boolean;\r\n setLoadingUsers: (loading: boolean) => void;\r\n userSearchTerm: string;\r\n setUserSearchTerm: (term: string) => void;\r\n selectedUserId: string | null;\r\n setSelectedUserId: (userId: string | null) => void;\r\n addingMemberLoading: boolean;\r\n setAddingMemberLoading: (loading: boolean) => void;\r\n selectedMemberForRoles: TenantMemberDto | null;\r\n setSelectedMemberForRoles: (member: TenantMemberDto | null) => void;\r\n availableRoles: RoleListDto[];\r\n setAvailableRoles: (roles: RoleListDto[]) => void;\r\n selectedRoleIds: string[];\r\n setSelectedRoleIds: (roleIds: string[]) => void;\r\n loadingRoles: boolean;\r\n setLoadingRoles: (loading: boolean) => void;\r\n savingRoles: boolean;\r\n setSavingRoles: (saving: boolean) => void;\r\n loadMembers: () => Promise<void>;\r\n loadAvailableUsers: () => Promise<void>;\r\n handleAddMember: () => Promise<void>;\r\n handleRemoveMember: (userId: string) => Promise<void>;\r\n openRoleModal: (member: TenantMemberDto) => Promise<void>;\r\n closeRoleModal: () => void;\r\n handleSaveRoles: () => Promise<void>;\r\n handleRoleToggle: (roleId: string) => void;\r\n}\r\n\r\nexport function useTenantMembers(tenantId: string | undefined): UseTenantMembersReturn {\r\n const [members, setMembers] = useState<TenantMemberDto[] | null>(null);\r\n const [loadingMembers, setLoadingMembers] = useState(false);\r\n\r\n const [addingMember, setAddingMember] = useState(false);\r\n const [availableUsers, setAvailableUsers] = useState<UserListDto[]>([]);\r\n const [loadingUsers, setLoadingUsers] = useState(false);\r\n const [userSearchTerm, setUserSearchTerm] = useState('');\r\n const [selectedUserId, setSelectedUserId] = useState<string | null>(null);\r\n const [addingMemberLoading, setAddingMemberLoading] = useState(false);\r\n\r\n const [selectedMemberForRoles, setSelectedMemberForRoles] = useState<TenantMemberDto | null>(null);\r\n const [availableRoles, setAvailableRoles] = useState<RoleListDto[]>([]);\r\n const [selectedRoleIds, setSelectedRoleIds] = useState<string[]>([]);\r\n const [loadingRoles, setLoadingRoles] = useState(false);\r\n const [savingRoles, setSavingRoles] = useState(false);\r\n\r\n const loadMembers = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLoadingMembers(true);\r\n try {\r\n const data = await adminApi.tenants.getMembers(tenantId);\r\n setMembers(data);\r\n } catch (err) {\r\n console.error('Failed to load members:', err);\r\n } finally {\r\n setLoadingMembers(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const loadAvailableUsers = useCallback(async () => {\r\n setLoadingUsers(true);\r\n try {\r\n const result = await adminApi.users.getAll({ pageSize: 50 });\r\n const memberUserIds = new Set((members ?? []).map(m => m.userId));\r\n setAvailableUsers(result.items.filter(u => !memberUserIds.has(u.id)));\r\n } catch (err) {\r\n console.error('Failed to load users:', err);\r\n } finally {\r\n setLoadingUsers(false);\r\n }\r\n }, [members]);\r\n\r\n const handleAddMember = useCallback(async () => {\r\n if (!tenantId || !selectedUserId) return;\r\n setAddingMemberLoading(true);\r\n try {\r\n await adminApi.tenants.addMember(tenantId, { userId: selectedUserId });\r\n await loadMembers();\r\n setAddingMember(false);\r\n setSelectedUserId(null);\r\n setUserSearchTerm('');\r\n } catch (err) {\r\n console.error('Failed to add member:', err);\r\n } finally {\r\n setAddingMemberLoading(false);\r\n }\r\n }, [tenantId, selectedUserId, loadMembers]);\r\n\r\n const handleRemoveMember = useCallback(async (userId: string) => {\r\n if (!tenantId) return;\r\n try {\r\n await adminApi.tenants.removeMember(tenantId, userId);\r\n await loadMembers();\r\n } catch (err) {\r\n console.error('Failed to remove member:', err);\r\n }\r\n }, [tenantId, loadMembers]);\r\n\r\n const loadAvailableRoles = useCallback(async () => {\r\n setLoadingRoles(true);\r\n try {\r\n const data = await adminApi.roles.getAssignable();\r\n setAvailableRoles(data);\r\n } catch (err) {\r\n console.error('Failed to load roles:', err);\r\n } finally {\r\n setLoadingRoles(false);\r\n }\r\n }, []);\r\n\r\n const openRoleModal = useCallback(async (member: TenantMemberDto) => {\r\n setSelectedMemberForRoles(member);\r\n setSelectedRoleIds(member.roles.map(r => r.roleId));\r\n if (availableRoles.length === 0) {\r\n await loadAvailableRoles();\r\n }\r\n }, [availableRoles.length, loadAvailableRoles]);\r\n\r\n const closeRoleModal = useCallback(() => {\r\n setSelectedMemberForRoles(null);\r\n setSelectedRoleIds([]);\r\n }, []);\r\n\r\n const handleRoleToggle = useCallback((roleId: string) => {\r\n setSelectedRoleIds(prev =>\r\n prev.includes(roleId)\r\n ? prev.filter(id => id !== roleId)\r\n : [...prev, roleId]\r\n );\r\n }, []);\r\n\r\n const handleSaveRoles = useCallback(async () => {\r\n if (!tenantId || !selectedMemberForRoles) return;\r\n setSavingRoles(true);\r\n try {\r\n await adminApi.tenants.assignMemberRoles(tenantId, selectedMemberForRoles.userId, selectedRoleIds);\r\n await loadMembers();\r\n closeRoleModal();\r\n } catch (err) {\r\n console.error('Failed to save roles:', err);\r\n } finally {\r\n setSavingRoles(false);\r\n }\r\n }, [tenantId, selectedMemberForRoles, selectedRoleIds, loadMembers, closeRoleModal]);\r\n\r\n return {\r\n members,\r\n setMembers,\r\n loadingMembers,\r\n setLoadingMembers,\r\n addingMember,\r\n setAddingMember,\r\n availableUsers,\r\n setAvailableUsers,\r\n loadingUsers,\r\n setLoadingUsers,\r\n userSearchTerm,\r\n setUserSearchTerm,\r\n selectedUserId,\r\n setSelectedUserId,\r\n addingMemberLoading,\r\n setAddingMemberLoading,\r\n selectedMemberForRoles,\r\n setSelectedMemberForRoles,\r\n availableRoles,\r\n setAvailableRoles,\r\n selectedRoleIds,\r\n setSelectedRoleIds,\r\n loadingRoles,\r\n setLoadingRoles,\r\n savingRoles,\r\n setSavingRoles,\r\n loadMembers,\r\n loadAvailableUsers,\r\n handleAddMember,\r\n handleRemoveMember,\r\n openRoleModal,\r\n closeRoleModal,\r\n handleSaveRoles,\r\n handleRoleToggle,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n adminApi,\r\n type TenantGroupDto,\r\n type AvailableGroupDto,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface UseTenantGroupsReturn {\r\n groups: TenantGroupDto[] | null;\r\n setGroups: (groups: TenantGroupDto[] | null) => void;\r\n loadingGroups: boolean;\r\n setLoadingGroups: (loading: boolean) => void;\r\n addingGroup: boolean;\r\n setAddingGroup: (adding: boolean) => void;\r\n availableGroupsForTenant: AvailableGroupDto[];\r\n setAvailableGroupsForTenant: (groups: AvailableGroupDto[]) => void;\r\n loadingAvailableGroups: boolean;\r\n setLoadingAvailableGroups: (loading: boolean) => void;\r\n selectedGroupIds: string[];\r\n setSelectedGroupIds: (groupIds: string[]) => void;\r\n assigningGroups: boolean;\r\n setAssigningGroups: (assigning: boolean) => void;\r\n groupSearchTerm: string;\r\n setGroupSearchTerm: (term: string) => void;\r\n removingGroupId: string | null;\r\n setRemovingGroupId: (groupId: string | null) => void;\r\n loadGroups: () => Promise<void>;\r\n loadAvailableGroups: () => Promise<void>;\r\n handleAssignGroups: () => Promise<void>;\r\n handleRemoveGroup: (groupId: string) => Promise<void>;\r\n}\r\n\r\nexport function useTenantGroups(tenantId: string | undefined): UseTenantGroupsReturn {\r\n const { t } = useTranslation('admin');\r\n\r\n const [groups, setGroups] = useState<TenantGroupDto[] | null>(null);\r\n const [loadingGroups, setLoadingGroups] = useState(false);\r\n\r\n const [addingGroup, setAddingGroup] = useState(false);\r\n const [availableGroupsForTenant, setAvailableGroupsForTenant] = useState<AvailableGroupDto[]>([]);\r\n const [loadingAvailableGroups, setLoadingAvailableGroups] = useState(false);\r\n const [selectedGroupIds, setSelectedGroupIds] = useState<string[]>([]);\r\n const [assigningGroups, setAssigningGroups] = useState(false);\r\n const [groupSearchTerm, setGroupSearchTerm] = useState('');\r\n const [removingGroupId, setRemovingGroupId] = useState<string | null>(null);\r\n\r\n const loadGroups = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLoadingGroups(true);\r\n try {\r\n const data = await adminApi.tenants.getGroups(tenantId);\r\n setGroups(Array.isArray(data) ? data : []);\r\n } catch (err) {\r\n console.error('Failed to load groups:', err);\r\n setGroups([]);\r\n } finally {\r\n setLoadingGroups(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const loadAvailableGroups = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLoadingAvailableGroups(true);\r\n try {\r\n const data = await adminApi.tenants.getAvailableGroups(tenantId);\r\n setAvailableGroupsForTenant(data);\r\n } catch (err) {\r\n console.error('Failed to load available groups:', err);\r\n setAvailableGroupsForTenant([]);\r\n } finally {\r\n setLoadingAvailableGroups(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const handleAssignGroups = useCallback(async () => {\r\n if (!tenantId || selectedGroupIds.length === 0) return;\r\n setAssigningGroups(true);\r\n const succeeded: string[] = [];\r\n const failed: string[] = [];\r\n\r\n for (const groupId of selectedGroupIds) {\r\n try {\r\n await adminApi.tenants.addGroupToTenant(tenantId, groupId);\r\n succeeded.push(groupId);\r\n } catch (err) {\r\n console.error(`Failed to add group ${groupId}:`, err);\r\n failed.push(groupId);\r\n }\r\n }\r\n\r\n await loadGroups();\r\n\r\n if (failed.length === 0) {\r\n setAddingGroup(false);\r\n setSelectedGroupIds([]);\r\n } else if (succeeded.length === 0) {\r\n // Error occurred\r\n } else {\r\n setSelectedGroupIds(failed);\r\n }\r\n\r\n setAssigningGroups(false);\r\n }, [tenantId, selectedGroupIds, loadGroups, t]);\r\n\r\n const handleRemoveGroup = useCallback(async (groupId: string) => {\r\n if (!tenantId) return;\r\n setRemovingGroupId(groupId);\r\n try {\r\n await adminApi.tenants.removeGroupFromTenant(tenantId, groupId);\r\n await loadGroups();\r\n } catch (err: unknown) {\r\n console.error('Failed to remove group:', err);\r\n } finally {\r\n setRemovingGroupId(null);\r\n }\r\n }, [tenantId, loadGroups]);\r\n\r\n return {\r\n groups,\r\n setGroups,\r\n loadingGroups,\r\n setLoadingGroups,\r\n addingGroup,\r\n setAddingGroup,\r\n availableGroupsForTenant,\r\n setAvailableGroupsForTenant,\r\n loadingAvailableGroups,\r\n setLoadingAvailableGroups,\r\n selectedGroupIds,\r\n setSelectedGroupIds,\r\n assigningGroups,\r\n setAssigningGroups,\r\n groupSearchTerm,\r\n setGroupSearchTerm,\r\n removingGroupId,\r\n setRemovingGroupId,\r\n loadGroups,\r\n loadAvailableGroups,\r\n handleAssignGroups,\r\n handleRemoveGroup,\r\n };\r\n}\r\n","import { useState, useCallback, useMemo } from 'react';\r\nimport {\r\n adminApi,\r\n type TenantApplicationDto,\r\n type AvailableApplicationDto,\r\n type ApplicationAccessLevel,\r\n type SaveOverridesRequest,\r\n} from '@/services/api/adminApi';\r\n\r\nconst updateModuleAssignment = (module: BulkModuleNode, moduleId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newIsAssigned = !module.isAssigned;\r\n return {\r\n ...module,\r\n isAssigned: newIsAssigned,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: newIsAssigned })),\r\n };\r\n};\r\n\r\nconst updateSectionAssignment = (module: BulkModuleNode, moduleId: string, sectionId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newSections = module.sections.map(s =>\r\n s.id === sectionId ? { ...s, isAssigned: !s.isAssigned } : s\r\n );\r\n const anySectionAssigned = newSections.some(s => s.isAssigned);\r\n return {\r\n ...module,\r\n isAssigned: anySectionAssigned,\r\n sections: newSections,\r\n };\r\n};\r\n\r\nconst assignAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: true,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: true })),\r\n});\r\n\r\nconst clearAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: false,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: false })),\r\n});\r\n\r\nexport type BulkAccessMode = 'full' | 'custom';\r\n\r\nexport interface BulkModuleNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n sections: BulkSectionNode[];\r\n}\r\n\r\nexport interface BulkSectionNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n}\r\n\r\nexport interface UseTenantApplicationsReturn {\r\n applications: TenantApplicationDto[] | null;\r\n setApplications: (apps: TenantApplicationDto[] | null) => void;\r\n loadingApps: boolean;\r\n setLoadingApps: (loading: boolean) => void;\r\n addingApplication: boolean;\r\n setAddingApplication: (adding: boolean) => void;\r\n availableApps: AvailableApplicationDto[];\r\n setAvailableApps: (apps: AvailableApplicationDto[]) => void;\r\n loadingAvailableApps: boolean;\r\n setLoadingAvailableApps: (loading: boolean) => void;\r\n selectedAppIds: string[];\r\n setSelectedAppIds: (appIds: string[]) => void;\r\n assigningApps: boolean;\r\n setAssigningApps: (assigning: boolean) => void;\r\n appSearchTerm: string;\r\n setAppSearchTerm: (term: string) => void;\r\n selectedAccessLevel: ApplicationAccessLevel;\r\n setSelectedAccessLevel: (level: ApplicationAccessLevel) => void;\r\n bulkAccessMode: BulkAccessMode;\r\n setBulkAccessMode: (mode: BulkAccessMode) => void;\r\n bulkModules: BulkModuleNode[];\r\n setBulkModules: (modules: BulkModuleNode[]) => void;\r\n bulkExpandedModules: Set<string>;\r\n setBulkExpandedModules: (modules: Set<string>) => void;\r\n loadingBulkModules: boolean;\r\n setLoadingBulkModules: (loading: boolean) => void;\r\n showCustomizeDrawer: boolean;\r\n setShowCustomizeDrawer: (show: boolean) => void;\r\n customizingApp: TenantApplicationDto | null;\r\n setCustomizingApp: (app: TenantApplicationDto | null) => void;\r\n loadApplications: () => Promise<void>;\r\n availableAppsError: string | null;\r\n loadAvailableApps: () => Promise<void>;\r\n handleAssignApplications: () => Promise<void>;\r\n handleRemoveApplication: (appId: string) => Promise<void>;\r\n handleUpdateAccessLevel: (appId: string, accessLevel: ApplicationAccessLevel) => Promise<void>;\r\n openCustomizeDrawer: (app: TenantApplicationDto) => void;\r\n closeCustomizeDrawer: () => void;\r\n filteredAvailableApps: AvailableApplicationDto[];\r\n handleAppToggle: (appId: string) => void;\r\n selectAllFilteredApps: () => void;\r\n clearAppSelection: () => void;\r\n loadBulkModulesForApp: (appId: string) => Promise<void>;\r\n toggleBulkModuleExpand: (moduleId: string) => void;\r\n toggleBulkModule: (moduleId: string) => void;\r\n toggleBulkSection: (moduleId: string, sectionId: string) => void;\r\n getBulkModuleCheckState: (module: BulkModuleNode) => 'checked' | 'unchecked' | 'indeterminate';\r\n getBulkStats: () => { totalModules: number; assignedModules: number; totalSections: number; assignedSections: number };\r\n selectAllBulkModules: () => void;\r\n clearBulkModules: () => void;\r\n handleSaveOverrides: (appId: string, request: SaveOverridesRequest) => Promise<void>;\r\n handleResetOverrides: (appId: string) => Promise<void>;\r\n}\r\n\r\nexport interface UseTenantApplicationsOptions {\r\n /** Called after any mutation that changes tenant application assignments (assign, remove, update, override). */\r\n onApplicationsChanged?: () => void;\r\n}\r\n\r\nexport function useTenantApplications(tenantId: string | undefined, options?: UseTenantApplicationsOptions): UseTenantApplicationsReturn {\r\n const [applications, setApplications] = useState<TenantApplicationDto[] | null>(null);\r\n const [loadingApps, setLoadingApps] = useState(false);\r\n\r\n const [addingApplication, setAddingApplication] = useState(false);\r\n const [availableApps, setAvailableApps] = useState<AvailableApplicationDto[]>([]);\r\n const [loadingAvailableApps, setLoadingAvailableApps] = useState(false);\r\n const [selectedAppIds, setSelectedAppIds] = useState<string[]>([]);\r\n const [assigningApps, setAssigningApps] = useState(false);\r\n const [appSearchTerm, setAppSearchTerm] = useState('');\r\n const [availableAppsError, setAvailableAppsError] = useState<string | null>(null);\r\n\r\n const [selectedAccessLevel, setSelectedAccessLevel] = useState<ApplicationAccessLevel>('FullAccess');\r\n const [bulkAccessMode, setBulkAccessMode] = useState<BulkAccessMode>('full');\r\n const [bulkModules, setBulkModules] = useState<BulkModuleNode[]>([]);\r\n const [bulkExpandedModules, setBulkExpandedModules] = useState<Set<string>>(new Set());\r\n const [loadingBulkModules, setLoadingBulkModules] = useState(false);\r\n\r\n const [showCustomizeDrawer, setShowCustomizeDrawer] = useState(false);\r\n const [customizingApp, setCustomizingApp] = useState<TenantApplicationDto | null>(null);\r\n\r\n const loadApplications = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLoadingApps(true);\r\n try {\r\n const data = await adminApi.tenants.getApplications(tenantId);\r\n setApplications(Array.isArray(data) ? data : []);\r\n } catch (err) {\r\n console.error('Failed to load applications:', err);\r\n setApplications([]);\r\n } finally {\r\n setLoadingApps(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const loadAvailableApps = useCallback(async () => {\r\n if (!tenantId) return;\r\n setAddingApplication(true);\r\n setSelectedAppIds([]);\r\n setLoadingAvailableApps(true);\r\n setAvailableAppsError(null);\r\n try {\r\n const availableAppsResult = await adminApi.tenants.getAvailableApplications(tenantId);\r\n setAvailableApps(availableAppsResult.filter(a => !a.isAssigned));\r\n } catch (err) {\r\n console.error('Failed to load available applications:', err);\r\n const isForbidden = err instanceof Error && err.name === 'ForbiddenError';\r\n setAvailableAppsError(isForbidden ? 'forbidden' : 'generic');\r\n } finally {\r\n setLoadingAvailableApps(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const closeAddApplication = useCallback(() => {\r\n setAddingApplication(false);\r\n setSelectedAppIds([]);\r\n setAppSearchTerm('');\r\n setSelectedAccessLevel('FullAccess');\r\n setBulkAccessMode('full');\r\n setBulkModules([]);\r\n setBulkExpandedModules(new Set());\r\n }, []);\r\n\r\n const handleAssignApplications = useCallback(async () => {\r\n if (!tenantId || selectedAppIds.length === 0) return;\r\n setAssigningApps(true);\r\n try {\r\n const request = {\r\n applicationIds: selectedAppIds,\r\n accessLevel: selectedAccessLevel,\r\n accessMode: bulkAccessMode,\r\n moduleIds: bulkAccessMode === 'custom' ? bulkModules.filter(m => m.isAssigned).map(m => m.id) : undefined,\r\n sectionIds: bulkAccessMode === 'custom' ? bulkModules.flatMap(m => m.sections.filter(s => s.isAssigned).map(s => s.id)) : undefined,\r\n };\r\n\r\n await adminApi.tenants.bulkAssignApplications(tenantId, request);\r\n\r\n await loadApplications();\r\n closeAddApplication();\r\n options?.onApplicationsChanged?.();\r\n } catch (err) {\r\n console.error('Failed to assign applications:', err);\r\n } finally {\r\n setAssigningApps(false);\r\n }\r\n }, [tenantId, selectedAppIds, selectedAccessLevel, bulkAccessMode, bulkModules, loadApplications, closeAddApplication, options]);\r\n\r\n const handleRemoveApplication = useCallback(async (appId: string) => {\r\n if (!tenantId) return;\r\n try {\r\n await adminApi.tenants.removeApplication(tenantId, appId);\r\n await loadApplications();\r\n options?.onApplicationsChanged?.();\r\n } catch (err) {\r\n console.error('Failed to remove application:', err);\r\n }\r\n }, [tenantId, loadApplications, options]);\r\n\r\n const handleUpdateAccessLevel = useCallback(async (appId: string, accessLevel: ApplicationAccessLevel) => {\r\n if (!tenantId) return;\r\n try {\r\n await adminApi.tenants.updateApplicationAccessLevel(tenantId, appId, accessLevel);\r\n await loadApplications();\r\n options?.onApplicationsChanged?.();\r\n } catch (err) {\r\n console.error('Failed to update access level:', err);\r\n }\r\n }, [tenantId, loadApplications, options]);\r\n\r\n const openCustomizeDrawer = useCallback((app: TenantApplicationDto) => {\r\n setCustomizingApp(app);\r\n setShowCustomizeDrawer(true);\r\n }, []);\r\n\r\n const closeCustomizeDrawer = useCallback(() => {\r\n setShowCustomizeDrawer(false);\r\n setCustomizingApp(null);\r\n }, []);\r\n\r\n const handleSaveOverrides = useCallback(async (appId: string, request: SaveOverridesRequest) => {\r\n if (!tenantId) return;\r\n try {\r\n await adminApi.tenants.saveOverrides(tenantId, appId, request);\r\n await loadApplications();\r\n options?.onApplicationsChanged?.();\r\n } catch (err) {\r\n console.error('Failed to save overrides:', err);\r\n throw err;\r\n }\r\n }, [tenantId, loadApplications, options]);\r\n\r\n const handleResetOverrides = useCallback(async (appId: string) => {\r\n if (!tenantId) return;\r\n try {\r\n // Reset all overrides by sending empty request\r\n await adminApi.tenants.saveOverrides(tenantId, appId, { modules: [], sections: [] });\r\n await loadApplications();\r\n options?.onApplicationsChanged?.();\r\n } catch (err) {\r\n console.error('Failed to reset overrides:', err);\r\n throw err;\r\n }\r\n }, [tenantId, loadApplications, options]);\r\n\r\n const filteredAvailableApps = useMemo(() => {\r\n if (!appSearchTerm) return availableApps;\r\n\r\n const searchLower = appSearchTerm.toLowerCase();\r\n return availableApps.filter(app =>\r\n app.label.toLowerCase().includes(searchLower) ||\r\n app.code.toLowerCase().includes(searchLower)\r\n );\r\n }, [availableApps, appSearchTerm]);\r\n\r\n const handleAppToggle = useCallback((appId: string) => {\r\n setSelectedAppIds(prev =>\r\n prev.includes(appId)\r\n ? prev.filter(id => id !== appId)\r\n : [...prev, appId]\r\n );\r\n }, []);\r\n\r\n const selectAllFilteredApps = useCallback(() => {\r\n const filteredIds = filteredAvailableApps.map(app => app.id);\r\n setSelectedAppIds(filteredIds);\r\n }, [filteredAvailableApps]);\r\n\r\n const clearAppSelection = useCallback(() => {\r\n setSelectedAppIds([]);\r\n }, []);\r\n\r\n const loadBulkModulesForApp = useCallback(async (appId: string) => {\r\n setLoadingBulkModules(true);\r\n try {\r\n const appModules = await adminApi.applications.getModules(appId);\r\n const moduleNodes: BulkModuleNode[] = [];\r\n\r\n for (const appModule of appModules) {\r\n const sections = await adminApi.applications.getModuleSections(appId, appModule.id);\r\n const sectionNodes: BulkSectionNode[] = sections.map(section => ({\r\n id: section.id,\r\n label: section.label,\r\n code: section.code,\r\n icon: section.icon,\r\n isAssigned: true,\r\n }));\r\n\r\n moduleNodes.push({\r\n id: appModule.id,\r\n label: appModule.label,\r\n code: appModule.code,\r\n icon: appModule.icon,\r\n isAssigned: true,\r\n sections: sectionNodes,\r\n });\r\n }\r\n\r\n setBulkModules(moduleNodes);\r\n } catch (err) {\r\n console.error('Failed to load modules:', err);\r\n } finally {\r\n setLoadingBulkModules(false);\r\n }\r\n }, []);\r\n\r\n const toggleBulkModuleExpand = useCallback((moduleId: string) => {\r\n setBulkExpandedModules(prev => {\r\n const newSet = new Set(prev);\r\n if (newSet.has(moduleId)) {\r\n newSet.delete(moduleId);\r\n } else {\r\n newSet.add(moduleId);\r\n }\r\n return newSet;\r\n });\r\n }, []);\r\n\r\n const toggleBulkModule = useCallback((moduleId: string) => {\r\n setBulkModules(prev => prev.map(m => updateModuleAssignment(m, moduleId)));\r\n }, []);\r\n\r\n const toggleBulkSection = useCallback((moduleId: string, sectionId: string) => {\r\n setBulkModules(prev => prev.map(m => updateSectionAssignment(m, moduleId, sectionId)));\r\n }, []);\r\n\r\n const getBulkModuleCheckState = useCallback((module: BulkModuleNode): 'checked' | 'unchecked' | 'indeterminate' => {\r\n if (module.sections.length === 0) {\r\n return module.isAssigned ? 'checked' : 'unchecked';\r\n }\r\n const assignedCount = module.sections.filter(s => s.isAssigned).length;\r\n if (assignedCount === 0) return 'unchecked';\r\n if (assignedCount === module.sections.length) return 'checked';\r\n return 'indeterminate';\r\n }, []);\r\n\r\n const getBulkStats = useCallback(() => {\r\n const totalModules = bulkModules.length;\r\n const assignedModules = bulkModules.filter(m => m.isAssigned || m.sections.some(s => s.isAssigned)).length;\r\n const totalSections = bulkModules.reduce((sum, m) => sum + m.sections.length, 0);\r\n const assignedSections = bulkModules.reduce((sum, m) => sum + m.sections.filter(s => s.isAssigned).length, 0);\r\n return { totalModules, assignedModules, totalSections, assignedSections };\r\n }, [bulkModules]);\r\n\r\n const selectAllBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => assignAllSections(m)));\r\n }, []);\r\n\r\n const clearBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => clearAllSections(m)));\r\n }, []);\r\n\r\n return {\r\n applications,\r\n setApplications,\r\n loadingApps,\r\n setLoadingApps,\r\n addingApplication,\r\n setAddingApplication,\r\n availableApps,\r\n setAvailableApps,\r\n loadingAvailableApps,\r\n setLoadingAvailableApps,\r\n selectedAppIds,\r\n setSelectedAppIds,\r\n assigningApps,\r\n setAssigningApps,\r\n appSearchTerm,\r\n setAppSearchTerm,\r\n selectedAccessLevel,\r\n setSelectedAccessLevel,\r\n bulkAccessMode,\r\n setBulkAccessMode,\r\n bulkModules,\r\n setBulkModules,\r\n bulkExpandedModules,\r\n setBulkExpandedModules,\r\n loadingBulkModules,\r\n setLoadingBulkModules,\r\n showCustomizeDrawer,\r\n setShowCustomizeDrawer,\r\n customizingApp,\r\n setCustomizingApp,\r\n loadApplications,\r\n availableAppsError,\r\n loadAvailableApps,\r\n handleAssignApplications,\r\n handleRemoveApplication,\r\n handleUpdateAccessLevel,\r\n openCustomizeDrawer,\r\n closeCustomizeDrawer,\r\n filteredAvailableApps,\r\n handleAppToggle,\r\n selectAllFilteredApps,\r\n clearAppSelection,\r\n loadBulkModulesForApp,\r\n toggleBulkModuleExpand,\r\n toggleBulkModule,\r\n toggleBulkSection,\r\n getBulkModuleCheckState,\r\n getBulkStats,\r\n selectAllBulkModules,\r\n clearBulkModules,\r\n handleSaveOverrides,\r\n handleResetOverrides,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n adminApi,\r\n type OrganisationListItemDto,\r\n type CreateOrganisationRequest,\r\n type BusinessIdentifierType,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface UseTenantOrganisationReturn {\r\n showLinkOrgModal: boolean;\r\n setShowLinkOrgModal: (show: boolean) => void;\r\n availableOrgs: OrganisationListItemDto[];\r\n setAvailableOrgs: (orgs: OrganisationListItemDto[]) => void;\r\n loadingOrgs: boolean;\r\n setLoadingOrgs: (loading: boolean) => void;\r\n selectedOrgId: string | null;\r\n setSelectedOrgId: (orgId: string | null) => void;\r\n linkingOrg: boolean;\r\n setLinkingOrg: (linking: boolean) => void;\r\n orgSearchTerm: string;\r\n setOrgSearchTerm: (term: string) => void;\r\n showCreateOrgForm: boolean;\r\n setShowCreateOrgForm: (show: boolean) => void;\r\n creatingOrg: boolean;\r\n setCreatingOrg: (creating: boolean) => void;\r\n newOrgForm: CreateOrganisationRequest;\r\n setNewOrgForm: (form: CreateOrganisationRequest) => void;\r\n lookupLoading: boolean;\r\n setLookupLoading: (loading: boolean) => void;\r\n lookupError: string | null;\r\n setLookupError: (error: string | null) => void;\r\n lookupSuccess: boolean;\r\n setLookupSuccess: (success: boolean) => void;\r\n loadAvailableOrgs: (search?: string) => Promise<void>;\r\n handleLinkOrganisation: () => Promise<void>;\r\n handleUnlinkOrganisation: () => Promise<void>;\r\n handleCreateAndLinkOrganisation: () => Promise<void>;\r\n formatCheNumber: (value: string) => string;\r\n handleBusinessIdChange: (value: string) => void;\r\n handleZefixLookup: () => Promise<void>;\r\n openLinkOrgModal: () => void;\r\n closeLinkOrgModal: () => void;\r\n handleCountryChange: (countryCode: string) => void;\r\n}\r\n\r\nconst COUNTRY_IDENTIFIER_TYPES: Record<string, { types: BusinessIdentifierType[], defaultType: BusinessIdentifierType, country: string }> = {\r\n FR: { types: ['SIREN', 'SIRET'] as BusinessIdentifierType[], defaultType: 'SIREN' as BusinessIdentifierType, country: 'France' },\r\n CH: { types: ['UID_CHE'] as BusinessIdentifierType[], defaultType: 'UID_CHE' as BusinessIdentifierType, country: 'Switzerland' },\r\n DE: { types: ['HRB', 'HRA'] as BusinessIdentifierType[], defaultType: 'HRB' as BusinessIdentifierType, country: 'Germany' },\r\n BE: { types: ['BCE_KBO'] as BusinessIdentifierType[], defaultType: 'BCE_KBO' as BusinessIdentifierType, country: 'Belgium' },\r\n NL: { types: ['KVK'] as BusinessIdentifierType[], defaultType: 'KVK' as BusinessIdentifierType, country: 'Netherlands' },\r\n ES: { types: ['CIF'] as BusinessIdentifierType[], defaultType: 'CIF' as BusinessIdentifierType, country: 'Spain' },\r\n IT: { types: ['PartitaIVA'] as BusinessIdentifierType[], defaultType: 'PartitaIVA' as BusinessIdentifierType, country: 'Italy' },\r\n GB: { types: ['CRN'] as BusinessIdentifierType[], defaultType: 'CRN' as BusinessIdentifierType, country: 'United Kingdom' },\r\n};\r\n\r\nconst DEFAULT_ORG_FORM: CreateOrganisationRequest = {\r\n name: '',\r\n countryCode: 'CH',\r\n businessIdentifierType: 'UID_CHE' as BusinessIdentifierType,\r\n businessIdentifier: 'CHE-',\r\n address: {\r\n street: '',\r\n postalCode: '',\r\n city: '',\r\n state: undefined,\r\n country: 'Switzerland',\r\n countryCode: 'CH',\r\n },\r\n};\r\n\r\nexport function useTenantOrganisation(tenantId: string | undefined): UseTenantOrganisationReturn {\r\n const { t } = useTranslation('admin');\r\n\r\n const [showLinkOrgModal, setShowLinkOrgModal] = useState(false);\r\n const [availableOrgs, setAvailableOrgs] = useState<OrganisationListItemDto[]>([]);\r\n const [loadingOrgs, setLoadingOrgs] = useState(false);\r\n const [selectedOrgId, setSelectedOrgId] = useState<string | null>(null);\r\n const [linkingOrg, setLinkingOrg] = useState(false);\r\n const [orgSearchTerm, setOrgSearchTerm] = useState('');\r\n\r\n const [showCreateOrgForm, setShowCreateOrgForm] = useState(false);\r\n const [creatingOrg, setCreatingOrg] = useState(false);\r\n const [newOrgForm, setNewOrgForm] = useState<CreateOrganisationRequest>(DEFAULT_ORG_FORM);\r\n\r\n const [lookupLoading, setLookupLoading] = useState(false);\r\n const [lookupError, setLookupError] = useState<string | null>(null);\r\n const [lookupSuccess, setLookupSuccess] = useState(false);\r\n\r\n const loadAvailableOrgs = useCallback(async (search?: string) => {\r\n setLoadingOrgs(true);\r\n try {\r\n const response = await adminApi.organisations.getAvailable(search);\r\n const data = Array.isArray(response) ? response : (response as { items?: OrganisationListItemDto[] }).items ?? [];\r\n setAvailableOrgs(data);\r\n } catch (err) {\r\n console.error('Failed to load available organisations:', err);\r\n setAvailableOrgs([]);\r\n } finally {\r\n setLoadingOrgs(false);\r\n }\r\n }, []);\r\n\r\n const openLinkOrgModal = useCallback(() => {\r\n setShowLinkOrgModal(true);\r\n setSelectedOrgId(null);\r\n setOrgSearchTerm('');\r\n loadAvailableOrgs();\r\n }, [loadAvailableOrgs]);\r\n\r\n const closeLinkOrgModal = useCallback(() => {\r\n setShowLinkOrgModal(false);\r\n setSelectedOrgId(null);\r\n setOrgSearchTerm('');\r\n setShowCreateOrgForm(false);\r\n setNewOrgForm(DEFAULT_ORG_FORM);\r\n setLookupLoading(false);\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n }, []);\r\n\r\n const handleLinkOrganisation = useCallback(async () => {\r\n if (!tenantId || !selectedOrgId) return;\r\n setLinkingOrg(true);\r\n try {\r\n await adminApi.tenants.linkOrganisation(tenantId, selectedOrgId);\r\n // Note: Caller should refresh tenant data\r\n closeLinkOrgModal();\r\n } catch (err) {\r\n console.error('Failed to link organisation:', err);\r\n } finally {\r\n setLinkingOrg(false);\r\n }\r\n }, [tenantId, selectedOrgId, closeLinkOrgModal]);\r\n\r\n const handleUnlinkOrganisation = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLinkingOrg(true);\r\n try {\r\n await adminApi.tenants.unlinkOrganisation(tenantId);\r\n // Note: Caller should refresh tenant data\r\n } catch (err) {\r\n console.error('Failed to unlink organisation:', err);\r\n } finally {\r\n setLinkingOrg(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const handleCreateAndLinkOrganisation = useCallback(async () => {\r\n if (!tenantId) return;\r\n if (!newOrgForm.name || !newOrgForm.businessIdentifier || !newOrgForm.address.street || !newOrgForm.address.city || !newOrgForm.address.postalCode) {\r\n return;\r\n }\r\n setCreatingOrg(true);\r\n try {\r\n const createdOrg = await adminApi.organisations.create(newOrgForm);\r\n await adminApi.tenants.linkOrganisation(tenantId, createdOrg.id);\r\n // Note: Caller should refresh tenant data\r\n closeLinkOrgModal();\r\n } catch (err) {\r\n console.error('Failed to create and link organisation:', err);\r\n } finally {\r\n setCreatingOrg(false);\r\n }\r\n }, [tenantId, newOrgForm, closeLinkOrgModal]);\r\n\r\n const formatCheNumber = useCallback((value: string): string => {\r\n const cleaned = value.toUpperCase().replace(/[^A-Z0-9]/g, '');\r\n let digits = cleaned.startsWith('CHE') ? cleaned.slice(3) : cleaned.replace(/[^0-9]/g, '');\r\n digits = digits.slice(0, 9);\r\n\r\n if (digits.length === 0) return 'CHE-';\r\n if (digits.length <= 3) return `CHE-${digits}`;\r\n if (digits.length <= 6) return `CHE-${digits.slice(0, 3)}.${digits.slice(3)}`;\r\n return `CHE-${digits.slice(0, 3)}.${digits.slice(3, 6)}.${digits.slice(6)}`;\r\n }, []);\r\n\r\n const handleBusinessIdChange = useCallback((value: string) => {\r\n if (newOrgForm.countryCode === 'CH') {\r\n setNewOrgForm(prev => ({ ...prev, businessIdentifier: formatCheNumber(value) }));\r\n } else {\r\n setNewOrgForm(prev => ({ ...prev, businessIdentifier: value }));\r\n }\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n }, [newOrgForm.countryCode, formatCheNumber]);\r\n\r\n const handleZefixLookup = useCallback(async () => {\r\n const cleanedId = newOrgForm.businessIdentifier.replace(/[^0-9]/g, '');\r\n if (!newOrgForm.businessIdentifier || cleanedId.length < 9 || newOrgForm.countryCode !== 'CH') {\r\n setLookupError(t('tenants.organisation.lookupIncomplete'));\r\n return;\r\n }\r\n\r\n setLookupLoading(true);\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n\r\n try {\r\n const result = await adminApi.organisations.lookup(\r\n newOrgForm.countryCode,\r\n newOrgForm.businessIdentifier\r\n );\r\n\r\n setNewOrgForm(prev => ({\r\n ...prev,\r\n name: result.name || prev.name,\r\n legalName: result.legalName || prev.legalName,\r\n vatNumber: result.vatNumber || prev.vatNumber,\r\n address: {\r\n ...prev.address,\r\n street: result.street || prev.address.street,\r\n street2: result.street2 || prev.address.street2 || undefined,\r\n postalCode: result.postalCode || prev.address.postalCode,\r\n city: result.city || prev.address.city,\r\n state: result.state || prev.address.state,\r\n country: result.country || prev.address.country,\r\n countryCode: result.countryCode || prev.address.countryCode,\r\n },\r\n }));\r\n\r\n setLookupSuccess(true);\r\n setTimeout(() => setLookupSuccess(false), 3000);\r\n } catch (err: unknown) {\r\n console.error('[Zefix Lookup] Failed:', err);\r\n const errorMessage = err instanceof Error ? err.message : '';\r\n if (errorMessage.includes('503') || errorMessage.includes('not configured') || errorMessage.includes('Service Unavailable')) {\r\n setLookupError(t('tenants.organisation.lookupServiceUnavailable'));\r\n } else if (errorMessage.includes('credentials') || errorMessage.includes('401')) {\r\n setLookupError(t('tenants.organisation.lookupAuthError'));\r\n } else if (errorMessage.includes('404') || errorMessage.includes('not found')) {\r\n setLookupError(t('tenants.organisation.lookupFailed'));\r\n } else {\r\n setLookupError(t('tenants.organisation.lookupFailed'));\r\n }\r\n } finally {\r\n setLookupLoading(false);\r\n }\r\n }, [newOrgForm.businessIdentifier, newOrgForm.countryCode, t]);\r\n\r\n const handleCountryChange = useCallback((countryCode: string) => {\r\n const config = COUNTRY_IDENTIFIER_TYPES[countryCode];\r\n if (config) {\r\n setNewOrgForm(prev => ({\r\n ...prev,\r\n countryCode,\r\n businessIdentifierType: config.defaultType,\r\n businessIdentifier: countryCode === 'CH' ? 'CHE-' : '',\r\n address: {\r\n ...prev.address,\r\n countryCode,\r\n country: config.country,\r\n },\r\n }));\r\n }\r\n }, []);\r\n\r\n return {\r\n showLinkOrgModal,\r\n setShowLinkOrgModal,\r\n availableOrgs,\r\n setAvailableOrgs,\r\n loadingOrgs,\r\n setLoadingOrgs,\r\n selectedOrgId,\r\n setSelectedOrgId,\r\n linkingOrg,\r\n setLinkingOrg,\r\n orgSearchTerm,\r\n setOrgSearchTerm,\r\n showCreateOrgForm,\r\n setShowCreateOrgForm,\r\n creatingOrg,\r\n setCreatingOrg,\r\n newOrgForm,\r\n setNewOrgForm,\r\n lookupLoading,\r\n setLookupLoading,\r\n lookupError,\r\n setLookupError,\r\n lookupSuccess,\r\n setLookupSuccess,\r\n loadAvailableOrgs,\r\n handleLinkOrganisation,\r\n handleUnlinkOrganisation,\r\n handleCreateAndLinkOrganisation,\r\n formatCheNumber,\r\n handleBusinessIdChange,\r\n handleZefixLookup,\r\n openLinkOrgModal,\r\n closeLinkOrgModal,\r\n handleCountryChange,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { adminApi, type TenantRoleDto } from '@/services/api/adminApi';\r\n\r\nexport interface UseTenantRolesReturn {\r\n roles: TenantRoleDto[] | null;\r\n loadingRoles: boolean;\r\n error: string | null;\r\n loadRoles: () => Promise<void>;\r\n}\r\n\r\nexport function useTenantRoles(tenantId: string | undefined): UseTenantRolesReturn {\r\n const [roles, setRoles] = useState<TenantRoleDto[] | null>(null);\r\n const [loadingRoles, setLoadingRoles] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const loadRoles = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLoadingRoles(true);\r\n setError(null);\r\n try {\r\n const data = await adminApi.tenants.getTenantRoles(tenantId);\r\n setRoles(data);\r\n } catch (err) {\r\n console.error('Failed to load tenant roles:', err);\r\n setError('Failed to load roles');\r\n } finally {\r\n setLoadingRoles(false);\r\n }\r\n }, [tenantId]);\r\n\r\n return { roles, loadingRoles, error, loadRoles };\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\n\r\ntype TFunction = ReturnType<typeof useTranslation>['t'];\r\nimport {\r\n Info,\r\n Edit3,\r\n Building2,\r\n Plus,\r\n X,\r\n Settings,\r\n RefreshCw,\r\n PlayCircle,\r\n PauseCircle,\r\n Archive,\r\n Loader2,\r\n Layers,\r\n ArrowRight,\r\n Star,\r\n ExternalLink,\r\n Headphones,\r\n CheckCircle2,\r\n AlertCircle,\r\n} from 'lucide-react';\r\nimport type { TenantDetailDto, TenantStatus, TenantTemplateDto, TenantType } from '@/services/api/adminApi';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { ticketingApi, type TenantTicketingConfigurationDto } from '@/services/api/ticketingApi';\r\n\r\ninterface TenantOverviewTabProps {\r\n readonly tenant: TenantDetailDto;\r\n readonly tenantOwner: { userDisplayName?: string; userEmail?: string } | null;\r\n readonly statusConfig: Record<TenantStatus, { color: string; bgColor: string; borderColor: string }>;\r\n readonly actionLoading: string | null;\r\n readonly onRefresh: () => Promise<void>;\r\n readonly onEditClick: () => void;\r\n readonly onStatusChange: (action: 'activate' | 'suspend' | 'archive') => void;\r\n readonly onMembersTabClick: () => void;\r\n readonly onLinkOrgClick: () => void;\r\n readonly onUnlinkOrg: () => Promise<void>;\r\n}\r\n\r\ninterface EditState {\r\n readonly name: string;\r\n readonly description: string;\r\n readonly type: TenantType;\r\n}\r\n\r\ninterface TemplateModalProps {\r\n readonly show: boolean;\r\n readonly templates: TenantTemplateDto[];\r\n readonly selectedTemplateId: string;\r\n readonly loadingTemplates: boolean;\r\n readonly assigningTemplate: boolean;\r\n readonly onTemplateSelect: (id: string) => void;\r\n readonly onClose: () => void;\r\n readonly onAssign: () => Promise<void>;\r\n readonly tenantTemplateId?: string;\r\n readonly t: TFunction;\r\n}\r\n\r\nfunction TemplateSelectionModal({\r\n show, templates, selectedTemplateId, loadingTemplates, assigningTemplate,\r\n onTemplateSelect, onClose, onAssign, tenantTemplateId, t\r\n}: TemplateModalProps) {\r\n if (!show) return null;\r\n\r\n return (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"card w-full max-w-md p-6 m-4\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <div>\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('tenants.template.selectTitle')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.template.selectSubtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={onClose}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n {loadingTemplates && (\r\n <div className=\"flex justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n )}\r\n {!loadingTemplates && templates.length === 0 && (\r\n <div className=\"p-4 rounded-lg bg-[var(--bg-secondary)] text-center\">\r\n <p className=\"text-sm text-[var(--text-tertiary)]\">{t('tenants.template.noTemplatesAvailable')}</p>\r\n </div>\r\n )}\r\n {!loadingTemplates && templates.length > 0 && (\r\n <div className=\"space-y-2 max-h-[300px] overflow-y-auto mb-6\">\r\n {templates.map(tmpl => (\r\n <button\r\n key={tmpl.id}\r\n onClick={() => onTemplateSelect(tmpl.id)}\r\n className={`w-full p-3 rounded-lg border text-left transition-colors ${\r\n selectedTemplateId === tmpl.id\r\n ? 'border-[var(--primary-color)] bg-[var(--primary-color)]/5'\r\n : 'border-[var(--border-color)] bg-[var(--bg-secondary)] hover:border-[var(--primary-color)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">{tmpl.name}</p>\r\n <p className=\"text-xs text-[var(--text-tertiary)] font-mono\">{tmpl.code}</p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className={`px-2 py-0.5 text-xs rounded-[var(--radius-badge)] ${\r\n tmpl.targetTenantType === 'Business'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--accent-bg)] text-[var(--accent-text)]'\r\n }`}>\r\n {t(`tenants.type.${tmpl.targetTenantType.toLowerCase()}`)}\r\n </span>\r\n {tmpl.isDefault && (\r\n <span className=\"px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--success-bg)] text-[var(--success-text)]\">\r\n {t('tenants.template.default')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n {tmpl.description && (\r\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">{tmpl.description}</p>\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex justify-end gap-3\">\r\n <button\r\n onClick={onClose}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={onAssign}\r\n disabled={assigningTemplate || !selectedTemplateId || selectedTemplateId === tenantTemplateId}\r\n className=\"btn btn-primary\"\r\n >\r\n {assigningTemplate ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n t('tenants.template.confirm')\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction TenantGeneralInfoSection({\r\n tenant,\r\n statusConfig,\r\n onEditClick,\r\n t,\r\n}: {\r\n tenant: TenantDetailDto;\r\n statusConfig: Record<TenantStatus, { color: string; bgColor: string; borderColor: string }>;\r\n onEditClick: () => void;\r\n t: TFunction;\r\n}) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Info className=\"w-5 h-5\" />\r\n {t('tenants.detail.generalInfo')}\r\n </h3>\r\n <button\r\n onClick={onEditClick}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Edit3 className=\"w-4 h-4\" />\r\n {t('common:edit')}\r\n </button>\r\n </div>\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.name')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">{tenant.name}</p>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.slug')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-mono\">{tenant.slug}</p>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.type')}</p>\r\n <span className={`inline-flex px-2 py-0.5 text-xs rounded-[var(--radius-badge)] ${\r\n tenant.type === 'Business'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--accent-bg)] text-[var(--accent-text)]'\r\n }`}>\r\n {t(`tenants.type.${tenant.type.toLowerCase()}`)}\r\n </span>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.status')}</p>\r\n <span className={`inline-flex px-2 py-0.5 text-xs rounded-[var(--radius-badge)] ${statusConfig[tenant.status].bgColor} ${statusConfig[tenant.status].color}`}>\r\n {t(`tenants.status.${tenant.status.toLowerCase()}`)}\r\n </span>\r\n </div>\r\n {tenant.description && (\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)] sm:col-span-2 lg:col-span-4\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.description')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] whitespace-pre-wrap\">{tenant.description}</p>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction TenantTicketingSection({\r\n tenant,\r\n ticketingConfig,\r\n loadingTicketing,\r\n t,\r\n navigate,\r\n}: {\r\n tenant: TenantDetailDto;\r\n ticketingConfig: TenantTicketingConfigurationDto | null;\r\n loadingTicketing: boolean;\r\n t: TFunction;\r\n navigate: ReturnType<typeof useNavigate>;\r\n}) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Headphones className=\"w-5 h-5\" />\r\n {t('tenants.detail.supportManagement.title')}\r\n </h3>\r\n <button\r\n onClick={() => navigate(`/administration/tenants/${tenant.id}/settings?tab=support`)}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Settings className=\"w-4 h-4\" />\r\n {t('tenants.detail.supportManagement.configure')}\r\n </button>\r\n </div>\r\n {loadingTicketing && (\r\n <div className=\"flex justify-center py-4\">\r\n <Loader2 className=\"w-5 h-5 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n )}\r\n {!loadingTicketing && ticketingConfig && (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">\r\n {t('tenants.detail.supportManagement.provider')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">\r\n {ticketingConfig.provider === 'Glpi'\r\n ? t('tenants.detail.supportManagement.providerGlpi')\r\n : t('tenants.detail.supportManagement.providerSmartStack')}\r\n </p>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">\r\n {t('tenants.detail.supportManagement.status')}\r\n </p>\r\n <span className={`inline-flex items-center gap-1.5 px-2 py-0.5 text-xs rounded-[var(--radius-badge)] ${\r\n ticketingConfig.isConfigured\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n }`}>\r\n {ticketingConfig.isConfigured\r\n ? <><CheckCircle2 className=\"w-3 h-3\" />{t('tenants.detail.supportManagement.configured')}</>\r\n : <><AlertCircle className=\"w-3 h-3\" />{t('tenants.detail.supportManagement.notConfigured')}</>}\r\n </span>\r\n </div>\r\n {ticketingConfig.provider === 'Glpi' && ticketingConfig.glpiBaseUrl && (\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">\r\n {t('tenants.detail.supportManagement.glpiUrl')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-mono truncate\" title={ticketingConfig.glpiBaseUrl}>\r\n {ticketingConfig.glpiBaseUrl}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n {!loadingTicketing && !ticketingConfig && (\r\n <div className=\"p-4 rounded-lg bg-[var(--info-bg)] border border-[var(--info-border)] text-center\">\r\n <Headphones className=\"w-5 h-5 text-[var(--info-text)] mx-auto mb-2\" />\r\n <p className=\"text-sm text-[var(--info-text)]\">\r\n {t('tenants.detail.supportManagement.noConfiguration')}\r\n </p>\r\n <p className=\"text-xs text-[var(--info-text)] mt-1 opacity-75\">\r\n {t('tenants.detail.supportManagement.noConfigurationHint')}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction TenantTemplateSection({\r\n tenant,\r\n templates,\r\n onOpenTemplateModal,\r\n onRemoveTemplate,\r\n removingTemplate,\r\n navigate,\r\n t,\r\n}: {\r\n tenant: TenantDetailDto;\r\n templates: TenantTemplateDto[];\r\n onOpenTemplateModal: () => void;\r\n onRemoveTemplate: () => Promise<void>;\r\n removingTemplate: boolean;\r\n navigate: ReturnType<typeof useNavigate>;\r\n t: TFunction;\r\n}) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <div className=\"flex items-center gap-3\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Layers className=\"w-5 h-5\" />\r\n {t('tenants.templateTenant.title')}\r\n </h3>\r\n <button\r\n onClick={() => navigate('/administration/tenants/template')}\r\n className=\"flex items-center gap-1 text-xs text-[var(--text-tertiary)] hover:text-[var(--primary-color)] transition-colors\"\r\n title={t('tenants.templateTenant.viewAll')}\r\n >\r\n <ExternalLink className=\"w-3 h-3\" />\r\n {t('tenants.templateTenant.viewAll')}\r\n </button>\r\n </div>\r\n {tenant.templateId ? (\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={onOpenTemplateModal}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Edit3 className=\"w-4 h-4\" />\r\n {t('tenants.template.change')}\r\n </button>\r\n <button\r\n onClick={onRemoveTemplate}\r\n disabled={removingTemplate}\r\n className=\"btn btn-secondary text-[var(--error-text)] hover:bg-[var(--error-bg)]\"\r\n >\r\n {removingTemplate ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <X className=\"w-4 h-4\" />}\r\n {t('tenants.template.remove')}\r\n </button>\r\n </div>\r\n ) : (\r\n <button\r\n onClick={onOpenTemplateModal}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.template.assign')}\r\n </button>\r\n )}\r\n </div>\r\n {tenant.templateId ? (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.template.name')}</p>\r\n <div className=\"flex items-center gap-2\">\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">{tenant.templateName || '-'}</p>\r\n {templates.find(tmpl => tmpl.id === tenant.templateId)?.isDefault && (\r\n <span className=\"flex items-center gap-1 px-1.5 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--accent-bg)] text-[var(--accent-text)]\">\r\n <Star className=\"w-3 h-3\" />\r\n {t('tenants.template.default')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.template.code')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-mono\">{tenant.templateCode || '-'}</p>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)] flex items-center\">\r\n <button\r\n onClick={() => navigate(`/administration/tenants/template/${tenant.templateId}`)}\r\n className=\"flex items-center gap-2 text-sm text-[var(--primary-color)] hover:underline\"\r\n >\r\n {t('tenants.template.viewDetails')}\r\n <ArrowRight className=\"w-3.5 h-3.5\" />\r\n </button>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"p-4 rounded-lg bg-[var(--warning-bg)] border border-[var(--warning-border)] text-center\">\r\n <Layers className=\"w-5 h-5 text-[var(--warning-text)] mx-auto mb-2\" />\r\n <p className=\"text-sm text-[var(--warning-text)]\">\r\n {t('tenants.templateTenant.noLink')}\r\n </p>\r\n <p className=\"text-xs text-[var(--warning-text)] mt-1 opacity-75\">\r\n {t('tenants.templateTenant.noLinkHint')}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport function TenantOverviewTab({\r\n tenant,\r\n tenantOwner,\r\n statusConfig,\r\n actionLoading,\r\n onRefresh,\r\n onEditClick,\r\n onStatusChange,\r\n onMembersTabClick,\r\n onLinkOrgClick,\r\n onUnlinkOrg,\r\n}: TenantOverviewTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n const [editingGeneralInfo, setEditingGeneralInfo] = useState(false);\r\n const [editState, setEditState] = useState<EditState>({ name: '', description: '', type: 'Business' });\r\n const [savingGeneralInfo, setSavingGeneralInfo] = useState(false);\r\n const [linkingOrg, setLinkingOrg] = useState(false);\r\n\r\n // Template management state\r\n const [showTemplateModal, setShowTemplateModal] = useState(false);\r\n const [templates, setTemplates] = useState<TenantTemplateDto[]>([]);\r\n const [loadingTemplates, setLoadingTemplates] = useState(false);\r\n const [selectedTemplateId, setSelectedTemplateId] = useState<string>('');\r\n const [assigningTemplate, setAssigningTemplate] = useState(false);\r\n const [removingTemplate, setRemovingTemplate] = useState(false);\r\n\r\n // Support management state\r\n const [ticketingConfig, setTicketingConfig] = useState<TenantTicketingConfigurationDto | null>(null);\r\n const [loadingTicketing, setLoadingTicketing] = useState(false);\r\n\r\n const loadTicketingConfig = useCallback(async () => {\r\n setLoadingTicketing(true);\r\n try {\r\n const config = await ticketingApi.getConfiguration(tenant.id);\r\n setTicketingConfig(config);\r\n } catch {\r\n setTicketingConfig(null);\r\n } finally {\r\n setLoadingTicketing(false);\r\n }\r\n }, [tenant.id]);\r\n\r\n useEffect(() => {\r\n loadTicketingConfig();\r\n }, [loadTicketingConfig]);\r\n\r\n const loadTemplates = useCallback(async () => {\r\n setLoadingTemplates(true);\r\n try {\r\n const data = await adminApi.templates.getAll();\r\n setTemplates(data.filter(t => t.isActive));\r\n } catch (err) {\r\n console.error('Failed to load templates:', err);\r\n } finally {\r\n setLoadingTemplates(false);\r\n }\r\n }, []);\r\n\r\n // Eagerly load templates to show default badge\r\n useEffect(() => {\r\n if (tenant.templateId && templates.length === 0) {\r\n loadTemplates();\r\n }\r\n }, [tenant.templateId, templates.length, loadTemplates]);\r\n\r\n const handleOpenTemplateModal = async () => {\r\n setSelectedTemplateId(tenant.templateId || '');\r\n setShowTemplateModal(true);\r\n await loadTemplates();\r\n };\r\n\r\n const handleAssignTemplate = async () => {\r\n if (!selectedTemplateId) return;\r\n setAssigningTemplate(true);\r\n try {\r\n await adminApi.tenants.assignTemplate(tenant.id, selectedTemplateId);\r\n await onRefresh();\r\n setShowTemplateModal(false);\r\n } catch (err) {\r\n console.error('Failed to assign template:', err);\r\n } finally {\r\n setAssigningTemplate(false);\r\n }\r\n };\r\n\r\n const handleRemoveTemplate = async () => {\r\n setRemovingTemplate(true);\r\n try {\r\n await adminApi.tenants.removeTemplate(tenant.id);\r\n await onRefresh();\r\n } catch (err) {\r\n console.error('Failed to remove template:', err);\r\n } finally {\r\n setRemovingTemplate(false);\r\n }\r\n };\r\n\r\n const openEditGeneralInfo = () => {\r\n setEditState({ name: tenant.name, description: tenant.description || '', type: tenant.type as TenantType });\r\n setEditingGeneralInfo(true);\r\n onEditClick();\r\n };\r\n\r\n const closeEditGeneralInfo = () => {\r\n setEditingGeneralInfo(false);\r\n setEditState({ name: '', description: '', type: 'Business' });\r\n };\r\n\r\n const handleSaveGeneralInfo = async () => {\r\n if (!editState.name.trim()) return;\r\n setSavingGeneralInfo(true);\r\n try {\r\n await adminApi.tenants.update(tenant.id, {\r\n name: editState.name,\r\n description: editState.description,\r\n type: editState.type,\r\n });\r\n await onRefresh();\r\n closeEditGeneralInfo();\r\n } catch (err) {\r\n console.error('Failed to save tenant info:', err);\r\n } finally {\r\n setSavingGeneralInfo(false);\r\n }\r\n };\r\n\r\n const handleUnlinkOrganisation = async () => {\r\n setLinkingOrg(true);\r\n try {\r\n await onUnlinkOrg();\r\n } finally {\r\n setLinkingOrg(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <TenantGeneralInfoSection\r\n tenant={tenant}\r\n statusConfig={statusConfig}\r\n onEditClick={openEditGeneralInfo}\r\n t={t}\r\n />\r\n\r\n {/* Owner Card */}\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Info className=\"w-5 h-5\" />\r\n {t('tenants.detail.owner')}\r\n </h3>\r\n <button\r\n onClick={onMembersTabClick}\r\n className=\"btn btn-secondary\"\r\n title={t('tenants.members.transferOwnership.title')}\r\n >\r\n <Edit3 className=\"w-4 h-4\" />\r\n {t('common:edit')}\r\n </button>\r\n </div>\r\n {tenantOwner ? (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('common:name')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">{tenantOwner.userDisplayName || '-'}</p>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('common:email')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">{tenantOwner.userEmail || '-'}</p>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"p-4 rounded-lg bg-[var(--bg-secondary)] text-center\">\r\n <p className=\"text-sm text-[var(--text-tertiary)]\">{t('tenants.detail.noOwner')}</p>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Organisation Card (B2B only) */}\r\n {tenant.type === 'Business' && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Building2 className=\"w-5 h-5\" />\r\n {t('tenants.detail.organisation')}\r\n </h3>\r\n {tenant.organisationId ? (\r\n <button\r\n onClick={handleUnlinkOrganisation}\r\n disabled={linkingOrg}\r\n className=\"btn btn-secondary text-[var(--error-text)] hover:bg-[var(--error-bg)]\"\r\n >\r\n {linkingOrg ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <X className=\"w-4 h-4\" />}\r\n {t('tenants.organisation.unlink')}\r\n </button>\r\n ) : (\r\n <button\r\n onClick={onLinkOrgClick}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.organisation.link')}\r\n </button>\r\n )}\r\n </div>\r\n {tenant.organisationId ? (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.organisationName')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">{tenant.organisation?.name || '-'}</p>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"p-4 rounded-lg bg-[var(--info-bg)] border border-[var(--info-border)] text-center\">\r\n <Info className=\"w-5 h-5 text-[var(--info-text)] mx-auto mb-2\" />\r\n <p className=\"text-sm text-[var(--info-text)]\">\r\n {t('tenants.organisation.noOrganisation')}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n <TenantTicketingSection\r\n tenant={tenant}\r\n ticketingConfig={ticketingConfig}\r\n loadingTicketing={loadingTicketing}\r\n t={t}\r\n navigate={navigate}\r\n />\r\n\r\n <TenantTemplateSection\r\n tenant={tenant}\r\n templates={templates}\r\n onOpenTemplateModal={handleOpenTemplateModal}\r\n onRemoveTemplate={handleRemoveTemplate}\r\n removingTemplate={removingTemplate}\r\n navigate={navigate}\r\n t={t}\r\n />\r\n\r\n {/* Actions Card - Status management */}\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Settings className=\"w-5 h-5\" />\r\n {t('tenants.detail.actions')}\r\n </h3>\r\n </div>\r\n <div className=\"flex flex-wrap gap-3\">\r\n {tenant.status !== 'Active' && tenant.status !== 'Archived' && (\r\n <button\r\n onClick={() => onStatusChange('activate')}\r\n disabled={actionLoading !== null}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--success-dot)] text-white hover:opacity-90 transition-colors disabled:opacity-50\"\r\n >\r\n {actionLoading === 'activate' ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <PlayCircle className=\"w-4 h-4\" />}\r\n {t('tenants.actions.activate')}\r\n </button>\r\n )}\r\n {tenant.status === 'Active' && (\r\n <button\r\n onClick={() => onStatusChange('suspend')}\r\n disabled={actionLoading !== null}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--warning-dot)] text-white hover:opacity-90 transition-colors disabled:opacity-50\"\r\n >\r\n {actionLoading === 'suspend' ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <PauseCircle className=\"w-4 h-4\" />}\r\n {t('tenants.actions.suspend')}\r\n </button>\r\n )}\r\n {tenant.status !== 'Archived' && (\r\n <button\r\n onClick={() => onStatusChange('archive')}\r\n disabled={actionLoading !== null}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--error-dot)] text-white hover:opacity-90 transition-colors disabled:opacity-50\"\r\n >\r\n {actionLoading === 'archive' ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Archive className=\"w-4 h-4\" />}\r\n {t('tenants.actions.archive')}\r\n </button>\r\n )}\r\n <button\r\n onClick={onRefresh}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <RefreshCw className=\"w-4 h-4\" />\r\n {t('common:refresh')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <TemplateSelectionModal\r\n show={showTemplateModal}\r\n templates={templates}\r\n selectedTemplateId={selectedTemplateId}\r\n loadingTemplates={loadingTemplates}\r\n assigningTemplate={assigningTemplate}\r\n onTemplateSelect={setSelectedTemplateId}\r\n onClose={() => setShowTemplateModal(false)}\r\n onAssign={handleAssignTemplate}\r\n tenantTemplateId={tenant.templateId ?? undefined}\r\n t={t}\r\n />\r\n\r\n {/* Edit General Info Modal */}\r\n {editingGeneralInfo && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"card w-full max-w-md p-6 m-4\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <div>\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('tenants.edit.generalInfo')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.edit.generalInfoSubtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={closeEditGeneralInfo}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"space-y-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.form.name')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={editState.name}\r\n onChange={(e) => setEditState(prev => ({ ...prev, name: e.target.value }))}\r\n className=\"input w-full\"\r\n placeholder={t('tenants.create.namePlaceholder')}\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.form.description')}\r\n </label>\r\n <textarea\r\n value={editState.description}\r\n onChange={(e) => setEditState(prev => ({ ...prev, description: e.target.value }))}\r\n className=\"input w-full min-h-[100px] resize-y\"\r\n placeholder={t('tenants.create.descriptionPlaceholder')}\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.form.type')}\r\n </label>\r\n <div className=\"flex gap-3\">\r\n {(['Business', 'Personal'] as const).map((typeOption) => (\r\n <button\r\n key={typeOption}\r\n type=\"button\"\r\n onClick={() => setEditState(prev => ({ ...prev, type: typeOption }))}\r\n className={`flex-1 p-3 rounded-lg border text-center transition-colors ${\r\n editState.type === typeOption\r\n ? 'border-[var(--primary-color)] bg-[var(--primary-color)]/5 text-[var(--primary-color)]'\r\n : 'border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-secondary)] hover:border-[var(--primary-color)]'\r\n }`}\r\n >\r\n <span className=\"text-sm font-medium\">{t(`tenants.type.${typeOption.toLowerCase()}`)}</span>\r\n </button>\r\n ))}\r\n </div>\r\n {editState.type === 'Personal' && tenant.organisationId && (\r\n <p className=\"mt-2 text-xs text-[var(--error-text)]\">\r\n {t('tenants.form.typeWarningOrg')}\r\n </p>\r\n )}\r\n {editState.type !== tenant.type && (\r\n <p className=\"mt-2 text-xs text-[var(--warning-text)]\">\r\n {t('tenants.form.typeChangeWarning')}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={closeEditGeneralInfo}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleSaveGeneralInfo}\r\n disabled={savingGeneralInfo || !editState.name.trim()}\r\n className=\"btn btn-primary\"\r\n >\r\n {savingGeneralInfo ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n t('common:save')\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Link } from 'react-router-dom';\r\nimport {\r\n Shield,\r\n Crown,\r\n User,\r\n Users,\r\n Plus,\r\n X,\r\n UserMinus,\r\n Loader2,\r\n UsersRound,\r\n Link2,\r\n} from 'lucide-react';\r\nimport type { TenantMemberDto, TenantRoleDto, UserListDto } from '@/services/api/adminApi';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { DataTable, type DataTableColumn } from '@/components/ui/DataTable';\r\n\r\ninterface TenantMembersTabProps {\r\n readonly tenantId: string;\r\n readonly members: TenantMemberDto[] | null;\r\n readonly loadingMembers: boolean;\r\n readonly actionLoading: string | null;\r\n readonly onRefresh: () => Promise<void>;\r\n readonly onRemoveMember: (userId: string) => Promise<void>;\r\n}\r\n\r\ninterface ManageRolesState {\r\n readonly member: TenantMemberDto | null;\r\n readonly availableRoles: TenantRoleDto[];\r\n readonly selectedRoleIds: string[];\r\n}\r\n\r\nfunction formatDate(date: string | Date): string {\r\n const d = new Date(date);\r\n return d.toLocaleDateString('en-US', {\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n });\r\n}\r\n\r\n\r\nexport function TenantMembersTab({\r\n tenantId,\r\n members,\r\n loadingMembers,\r\n actionLoading,\r\n onRefresh,\r\n onRemoveMember,\r\n}: TenantMembersTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n // Manage roles modal state\r\n const [manageRolesState, setManageRolesState] = useState<ManageRolesState>({\r\n member: null,\r\n availableRoles: [],\r\n selectedRoleIds: [],\r\n });\r\n const [loadingRoles, setLoadingRoles] = useState(false);\r\n const [savingRoles, setSavingRoles] = useState(false);\r\n\r\n // Add member modal state\r\n const [addingMember, setAddingMember] = useState(false);\r\n const [availableUsers, setAvailableUsers] = useState<UserListDto[]>([]);\r\n const [loadingUsers, setLoadingUsers] = useState(false);\r\n const [userSearchTerm, setUserSearchTerm] = useState('');\r\n const [selectedUserId, setSelectedUserId] = useState<string | null>(null);\r\n const [addingMemberLoading, setAddingMemberLoading] = useState(false);\r\n\r\n const loadAvailableRoles = useCallback(async () => {\r\n setLoadingRoles(true);\r\n try {\r\n const data = await adminApi.tenants.getTenantRoles(tenantId);\r\n return data;\r\n } catch (err) {\r\n console.error('Failed to load roles:', err);\r\n return [];\r\n } finally {\r\n setLoadingRoles(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const openRolesModal = async (member: TenantMemberDto) => {\r\n setManageRolesState(prev => ({\r\n ...prev,\r\n member,\r\n selectedRoleIds: member.roles.map(r => r.roleId),\r\n }));\r\n const roles = await loadAvailableRoles();\r\n setManageRolesState(prev => ({\r\n ...prev,\r\n availableRoles: roles,\r\n }));\r\n };\r\n\r\n const closeRolesModal = () => {\r\n setManageRolesState({\r\n member: null,\r\n availableRoles: [],\r\n selectedRoleIds: [],\r\n });\r\n };\r\n\r\n const handleRoleToggle = (roleId: string) => {\r\n setManageRolesState(prev => ({\r\n ...prev,\r\n selectedRoleIds: prev.selectedRoleIds.includes(roleId)\r\n ? prev.selectedRoleIds.filter(id => id !== roleId)\r\n : [...prev.selectedRoleIds, roleId]\r\n }));\r\n };\r\n\r\n const handleSaveRoles = async () => {\r\n if (!manageRolesState.member) return;\r\n setSavingRoles(true);\r\n try {\r\n await adminApi.tenants.assignMemberRoles(tenantId, manageRolesState.member.userId, manageRolesState.selectedRoleIds);\r\n await onRefresh();\r\n closeRolesModal();\r\n } catch (err) {\r\n console.error('Failed to save roles:', err);\r\n } finally {\r\n setSavingRoles(false);\r\n }\r\n };\r\n\r\n const loadAvailableUsers = async () => {\r\n setLoadingUsers(true);\r\n try {\r\n const data = await adminApi.users.getAll({ globalScope: true });\r\n setAvailableUsers(data.items);\r\n } catch (err) {\r\n console.error('Failed to load available users:', err);\r\n setAvailableUsers([]);\r\n } finally {\r\n setLoadingUsers(false);\r\n }\r\n };\r\n\r\n const openAddMember = () => {\r\n setAddingMember(true);\r\n setSelectedUserId(null);\r\n setUserSearchTerm('');\r\n loadAvailableUsers();\r\n };\r\n\r\n const closeAddMember = () => {\r\n setAddingMember(false);\r\n setSelectedUserId(null);\r\n setUserSearchTerm('');\r\n setAvailableUsers([]);\r\n };\r\n\r\n const handleAddMember = async () => {\r\n if (!selectedUserId) return;\r\n setAddingMemberLoading(true);\r\n try {\r\n await adminApi.tenants.addMember(tenantId, { userId: selectedUserId });\r\n await onRefresh();\r\n closeAddMember();\r\n } catch (err) {\r\n console.error('Failed to add member:', err);\r\n } finally {\r\n setAddingMemberLoading(false);\r\n }\r\n };\r\n\r\n const columns: DataTableColumn<TenantMemberDto>[] = [\r\n {\r\n key: 'userDisplayName',\r\n label: t('common:name'),\r\n sortable: true,\r\n render: (member) => (\r\n <Link\r\n to={`/administration/users/${member.userId}`}\r\n className=\"flex items-center gap-3 hover:text-[var(--color-accent-500)]\"\r\n >\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium ${\r\n member.isOwner\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n : 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]'\r\n }`}>\r\n {member.isOwner ? <Crown className=\"w-4 h-4\" /> : (member.userDisplayName || member.userEmail || '?').charAt(0).toUpperCase()}\r\n </div>\r\n <div className=\"min-w-0\">\r\n <span className=\"font-medium text-[var(--text-primary)] block truncate\">{member.userDisplayName || member.userEmail}</span>\r\n {member.userEmail && member.userDisplayName && (\r\n <span className=\"text-xs text-[var(--text-tertiary)] block truncate\">{member.userEmail}</span>\r\n )}\r\n </div>\r\n </Link>\r\n )\r\n },\r\n {\r\n key: 'roles',\r\n label: t('tenants.members.role'),\r\n render: (member) => (\r\n <div className=\"flex flex-wrap gap-1\">\r\n {member.isOwner && (\r\n <span className=\"inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-[var(--radius-badge)] bg-[var(--warning-bg)] text-[var(--warning-text)]\">\r\n <Crown className=\"w-3 h-3\" />\r\n {t('tenants.members.owner')}\r\n </span>\r\n )}\r\n {member.roles.length > 0 && (\r\n member.roles.map(role => (\r\n <span\r\n key={role.roleId}\r\n className=\"inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-[var(--radius-badge)] bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]\"\r\n >\r\n <Shield className=\"w-3 h-3\" />\r\n {role.roleName}\r\n </span>\r\n ))\r\n )}\r\n {member.roles.length === 0 && !member.isOwner && (\r\n <span className=\"inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-[var(--radius-badge)] bg-[var(--bg-tertiary)] text-[var(--text-secondary)]\">\r\n <User className=\"w-3 h-3\" />\r\n {t('tenants.members.member')}\r\n </span>\r\n )}\r\n </div>\r\n )\r\n },\r\n {\r\n key: 'membershipSource',\r\n label: 'Source',\r\n hideOnMobile: true,\r\n render: (member) => {\r\n const source = member.membershipSource;\r\n if (source === 'Group') {\r\n return (\r\n <div className=\"flex items-center gap-1.5\">\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full bg-purple-500/10 text-purple-600 dark:text-purple-400\">\r\n <UsersRound className=\"w-3 h-3\" />\r\n {t('tenants.members.source.group')}\r\n </span>\r\n {member.primaryGroupName && (\r\n <Link\r\n to={`/administration/users/groups/${member.primaryGroupId}`}\r\n className=\"inline-flex items-center gap-1 text-xs text-[var(--text-tertiary)] hover:text-[var(--color-accent-500)] transition-colors\"\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n <Link2 className=\"w-3 h-3\" />\r\n {member.primaryGroupName}\r\n </Link>\r\n )}\r\n </div>\r\n );\r\n }\r\n if (source === 'Both') {\r\n return (\r\n <div className=\"flex items-center gap-1.5\">\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full bg-blue-500/10 text-blue-600 dark:text-blue-400\">\r\n {t('tenants.members.source.both')}\r\n </span>\r\n {member.primaryGroupName && (\r\n <Link\r\n to={`/administration/users/groups/${member.primaryGroupId}`}\r\n className=\"inline-flex items-center gap-1 text-xs text-[var(--text-tertiary)] hover:text-[var(--color-accent-500)] transition-colors\"\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n <Link2 className=\"w-3 h-3\" />\r\n {member.primaryGroupName}\r\n </Link>\r\n )}\r\n </div>\r\n );\r\n }\r\n return (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full bg-green-500/10 text-green-600 dark:text-green-400\">\r\n {t('tenants.members.source.direct')}\r\n </span>\r\n );\r\n }\r\n },\r\n {\r\n key: 'joinedAt',\r\n label: t('tenants.members.joinedAt'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (member) => (\r\n <span className=\"text-sm text-[var(--text-tertiary)]\">{member.joinedAt ? formatDate(member.joinedAt) : '-'}</span>\r\n )\r\n },\r\n {\r\n key: 'actions',\r\n label: t('common:actionsColumn'),\r\n align: 'right',\r\n render: (member) => (\r\n <div className=\"flex items-center justify-end gap-1\">\r\n <button\r\n onClick={(e) => { e.stopPropagation(); openRolesModal(member); }}\r\n className=\"p-2 rounded-[var(--radius-button)] text-[var(--text-tertiary)] hover:text-[var(--color-accent-500)] hover:bg-[var(--color-accent-500)]/10 transition-colors\"\r\n title={t('tenants.members.manageRoles.title')}\r\n >\r\n <Shield className=\"w-4 h-4\" />\r\n </button>\r\n {!member.isOwner && member.membershipSource !== 'Group' && (\r\n <button\r\n onClick={(e) => { e.stopPropagation(); onRemoveMember(member.userId); }}\r\n disabled={actionLoading === member.userId}\r\n className=\"p-2 rounded-[var(--radius-button)] text-[var(--text-tertiary)] hover:text-[var(--error-text)] hover:bg-[var(--error-bg)] transition-colors disabled:opacity-50\"\r\n title={member.membershipSource === 'Both'\r\n ? t('tenants.members.source.cannotRemoveBoth')\r\n : t('tenants.members.remove')}\r\n >\r\n {actionLoading === member.userId ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <UserMinus className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n )}\r\n {!member.isOwner && member.membershipSource === 'Group' && (\r\n <span\r\n className=\"p-2 text-[var(--text-tertiary)] opacity-40 cursor-not-allowed\"\r\n title={t('tenants.members.source.cannotRemoveGroup')}\r\n >\r\n <UserMinus className=\"w-4 h-4\" />\r\n </span>\r\n )}\r\n </div>\r\n )\r\n }\r\n ];\r\n\r\n return (\r\n <>\r\n <DataTable<TenantMemberDto>\r\n data={members ?? []}\r\n loading={loadingMembers}\r\n columns={columns}\r\n searchable\r\n searchPlaceholder={t('tenants.members.search')}\r\n searchFilter={(member, term) =>\r\n (member.userDisplayName || '').toLowerCase().includes(term.toLowerCase()) ||\r\n (member.userEmail || '').toLowerCase().includes(term.toLowerCase())\r\n }\r\n getRowKey={(member) => member.userId}\r\n emptyMessage={t('tenants.members.empty')}\r\n emptyIcon={<Users className=\"w-12 h-12 mx-auto text-[var(--text-tertiary)]\" />}\r\n headerActions={\r\n <button\r\n onClick={openAddMember}\r\n className=\"btn btn-primary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.members.add')}\r\n </button>\r\n }\r\n pagination={{ pageSize: 10, showSizeSelector: true }}\r\n />\r\n\r\n {/* Manage Roles Modal */}\r\n {manageRolesState.member && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"card w-full max-w-md p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <div>\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('tenants.members.manageRoles.title')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.members.manageRoles.subtitle', { name: manageRolesState.member.userDisplayName || manageRolesState.member.userEmail })}\r\n </p>\r\n </div>\r\n <button\r\n onClick={closeRolesModal}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n {loadingRoles ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto p-3 border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-secondary)]\">\r\n {manageRolesState.availableRoles.length === 0 ? (\r\n <p className=\"text-sm text-[var(--text-tertiary)] text-center py-4\">\r\n {t('tenants.members.manageRoles.noRolesAvailable')}\r\n </p>\r\n ) : (\r\n manageRolesState.availableRoles.map(role => (\r\n <label\r\n key={role.id}\r\n className=\"flex items-center gap-3 cursor-pointer p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={manageRolesState.selectedRoleIds.includes(role.id)}\r\n onChange={() => handleRoleToggle(role.id)}\r\n className=\"w-4 h-4 rounded border-[var(--border-color)] text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <div className=\"flex-1\">\r\n <span className=\"text-[var(--text-primary)] font-medium\">{role.name}</span>\r\n {role.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{role.description}</p>\r\n )}\r\n </div>\r\n </label>\r\n ))\r\n )}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={closeRolesModal}\r\n className=\"px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleSaveRoles}\r\n disabled={savingRoles || loadingRoles}\r\n className=\"px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors disabled:opacity-50\"\r\n >\r\n {savingRoles ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n t('common:save')\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Add Member Modal */}\r\n {addingMember && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"card w-full max-w-md p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <div>\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('tenants.members.addTitle')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.members.addSubtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={closeAddMember}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <input\r\n type=\"text\"\r\n value={userSearchTerm}\r\n onChange={(e) => setUserSearchTerm(e.target.value)}\r\n className=\"input w-full\"\r\n placeholder={t('tenants.members.searchUsers')}\r\n />\r\n </div>\r\n\r\n {loadingUsers ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto p-3 border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-secondary)]\">\r\n {availableUsers\r\n .filter(u =>\r\n userSearchTerm === '' ||\r\n u.fullName.toLowerCase().includes(userSearchTerm.toLowerCase()) ||\r\n u.email.toLowerCase().includes(userSearchTerm.toLowerCase())\r\n )\r\n .map(user => (\r\n <label\r\n key={user.id}\r\n className={`flex items-center gap-3 cursor-pointer p-3 rounded-[var(--radius-button)] transition-colors ${\r\n selectedUserId === user.id\r\n ? 'bg-[var(--color-accent-500)]/10 border border-[var(--color-accent-500)]'\r\n : 'hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <input\r\n type=\"radio\"\r\n name=\"selectedUser\"\r\n checked={selectedUserId === user.id}\r\n onChange={() => setSelectedUserId(user.id)}\r\n className=\"w-4 h-4 text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <div className=\"flex-1\">\r\n <span className=\"text-[var(--text-primary)] font-medium\">{user.fullName}</span>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{user.email}</p>\r\n </div>\r\n </label>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={closeAddMember}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleAddMember}\r\n disabled={!selectedUserId || addingMemberLoading}\r\n className=\"btn btn-primary\"\r\n >\r\n {addingMemberLoading ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n t('common:add')\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n );\r\n}\r\n","import { useState } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport {\r\n UsersRound,\r\n Plus,\r\n X,\r\n Cloud,\r\n Loader2,\r\n Check,\r\n} from 'lucide-react';\r\nimport type { TenantGroupDto, AvailableGroupDto } from '@/services/api/adminApi';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { groupsApi } from '@/services/api/groupsApi';\r\nimport { DataTable, type DataTableColumn } from '@/components/ui/DataTable';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\n\r\ninterface TenantGroupsTabProps {\r\n readonly tenantId: string;\r\n readonly groups: TenantGroupDto[] | null;\r\n readonly loadingGroups: boolean;\r\n readonly removingGroupId: string | null;\r\n readonly onRefresh: () => Promise<void>;\r\n readonly onRemoveGroup: (groupId: string) => Promise<void>;\r\n}\r\n\r\nfunction formatDate(date: string | Date): string {\r\n const d = new Date(date);\r\n return d.toLocaleDateString('en-US', {\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n });\r\n}\r\n\r\nexport function TenantGroupsTab({\r\n tenantId,\r\n groups,\r\n loadingGroups,\r\n removingGroupId,\r\n onRefresh,\r\n onRemoveGroup,\r\n}: TenantGroupsTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n\r\n // Add group modal state\r\n const [addingGroup, setAddingGroup] = useState(false);\r\n const [availableGroupsForTenant, setAvailableGroupsForTenant] = useState<AvailableGroupDto[]>([]);\r\n const [loadingAvailableGroups, setLoadingAvailableGroups] = useState(false);\r\n const [selectedGroupIds, setSelectedGroupIds] = useState<string[]>([]);\r\n const [assigningGroups, setAssigningGroups] = useState(false);\r\n const [groupSearchTerm, setGroupSearchTerm] = useState('');\r\n\r\n // Remove group confirmation state\r\n const [removeConfirm, setRemoveConfirm] = useState<{ show: boolean; group: TenantGroupDto | null; loading: boolean }>({ show: false, group: null, loading: false });\r\n\r\n // Create group modal state\r\n const [showCreateModal, setShowCreateModal] = useState(false);\r\n const [newGroupName, setNewGroupName] = useState('');\r\n const [newGroupDescription, setNewGroupDescription] = useState('');\r\n const [newGroupIsSecurityGroup, setNewGroupIsSecurityGroup] = useState(true);\r\n const [creating, setCreating] = useState(false);\r\n const [createError, setCreateError] = useState<string | null>(null);\r\n\r\n const loadAvailableGroups = async () => {\r\n setLoadingAvailableGroups(true);\r\n try {\r\n const data = await adminApi.tenants.getAvailableGroups(tenantId);\r\n setAvailableGroupsForTenant(data);\r\n } catch (err) {\r\n console.error('Failed to load available groups:', err);\r\n setAvailableGroupsForTenant([]);\r\n } finally {\r\n setLoadingAvailableGroups(false);\r\n }\r\n };\r\n\r\n const openAddGroup = () => {\r\n setAddingGroup(true);\r\n setSelectedGroupIds([]);\r\n setGroupSearchTerm('');\r\n loadAvailableGroups();\r\n };\r\n\r\n const closeAddGroup = () => {\r\n setAddingGroup(false);\r\n setSelectedGroupIds([]);\r\n setGroupSearchTerm('');\r\n };\r\n\r\n const handleGroupToggle = (groupId: string) => {\r\n setSelectedGroupIds(prev =>\r\n prev.includes(groupId)\r\n ? prev.filter(id => id !== groupId)\r\n : [...prev, groupId]\r\n );\r\n };\r\n\r\n const handleAddGroups = async () => {\r\n if (selectedGroupIds.length === 0) return;\r\n setAssigningGroups(true);\r\n const succeeded: string[] = [];\r\n const failed: string[] = [];\r\n\r\n for (const groupId of selectedGroupIds) {\r\n try {\r\n await adminApi.tenants.addGroupToTenant(tenantId, groupId);\r\n succeeded.push(groupId);\r\n } catch (err) {\r\n console.error(`Failed to add group ${groupId}:`, err);\r\n failed.push(groupId);\r\n }\r\n }\r\n\r\n await onRefresh();\r\n\r\n if (failed.length === 0) {\r\n closeAddGroup();\r\n } else if (succeeded.length > 0) {\r\n setSelectedGroupIds(failed);\r\n }\r\n\r\n setAssigningGroups(false);\r\n };\r\n\r\n const handleCreateGroup = async () => {\r\n if (!newGroupName.trim()) return;\r\n\r\n setCreating(true);\r\n setCreateError(null);\r\n try {\r\n // 1. Create the group\r\n const created = await groupsApi.create({\r\n name: newGroupName.trim(),\r\n description: newGroupDescription.trim() || undefined,\r\n isSecurityGroup: newGroupIsSecurityGroup,\r\n });\r\n\r\n // 2. Automatically add it to this tenant\r\n await adminApi.tenants.addGroupToTenant(tenantId, created.id);\r\n\r\n // 3. Refresh and close\r\n await onRefresh();\r\n setShowCreateModal(false);\r\n setNewGroupName('');\r\n setNewGroupDescription('');\r\n setNewGroupIsSecurityGroup(true);\r\n } catch (err) {\r\n console.error('Failed to create group:', err);\r\n const axiosError = err as { response?: { status?: number; data?: { message?: string } } };\r\n if (axiosError.response?.status === 409) {\r\n setCreateError(axiosError.response.data?.message || t('tenants.groups.createError'));\r\n } else {\r\n setCreateError(t('tenants.groups.createError'));\r\n }\r\n } finally {\r\n setCreating(false);\r\n }\r\n };\r\n\r\n const columns: DataTableColumn<TenantGroupDto>[] = [\r\n {\r\n key: 'name',\r\n label: t('common:name'),\r\n sortable: true,\r\n render: (group) => (\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium ${\r\n group.isSyncedFromEntra\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]'\r\n }`}>\r\n <UsersRound className=\"w-4 h-4\" />\r\n </div>\r\n <div>\r\n <span className=\"font-medium text-[var(--color-accent-500)] hover:underline\">{group.name}</span>\r\n {group.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{group.description}</p>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n },\r\n {\r\n key: 'memberCount',\r\n label: t('tenants.groups.memberCount'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (group) => (\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{group.memberCount}</span>\r\n )\r\n },\r\n {\r\n key: 'linkType',\r\n label: t('tenants.groups.linkType'),\r\n render: (group) => (\r\n <span className={`inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-[var(--radius-badge)] ${\r\n group.isDirect\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n }`}>\r\n {group.isDirect\r\n ? t('tenants.groups.directMember')\r\n : t('tenants.groups.indirectMember', { groupName: group.linkedViaGroupName })}\r\n </span>\r\n )\r\n },\r\n {\r\n key: 'source',\r\n label: t('tenants.groups.source'),\r\n hideOnMobile: true,\r\n render: (group) => (\r\n <span className={`inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-[var(--radius-badge)] ${\r\n group.isSyncedFromEntra\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n {group.isSyncedFromEntra ? (\r\n <>\r\n <Cloud className=\"w-3 h-3\" />\r\n Entra ID\r\n </>\r\n ) : (\r\n <>\r\n <UsersRound className=\"w-3 h-3\" />\r\n {t('tenants.groups.local')}\r\n </>\r\n )}\r\n </span>\r\n )\r\n },\r\n {\r\n key: 'addedAt',\r\n label: t('tenants.members.joinedAt'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (group) => (\r\n <span className=\"text-sm text-[var(--text-tertiary)]\">\r\n {group.addedAt ? formatDate(group.addedAt) : '-'}\r\n </span>\r\n )\r\n },\r\n {\r\n key: 'actions',\r\n label: '',\r\n width: '80px',\r\n render: (group) => group.isDirect ? (\r\n <button\r\n onClick={(e) => { e.stopPropagation(); setRemoveConfirm({ show: true, group, loading: false }); }}\r\n disabled={removingGroupId === group.groupId}\r\n className=\"btn btn-ghost text-[var(--error-text)] hover:bg-[var(--error-bg)]\"\r\n title={t('tenants.groups.remove')}\r\n >\r\n {removingGroupId === group.groupId ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <X className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n ) : null\r\n }\r\n ];\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <DataTable<TenantGroupDto>\r\n data={groups ?? []}\r\n loading={loadingGroups}\r\n columns={columns}\r\n searchable\r\n searchPlaceholder={t('tenants.groups.searchPlaceholder')}\r\n searchFilter={(group, term) =>\r\n group.name.toLowerCase().includes(term.toLowerCase()) ||\r\n (group.description || '').toLowerCase().includes(term.toLowerCase())\r\n }\r\n getRowKey={(group) => group.groupId}\r\n onRowClick={(group) => navigate(`/administration/users/groups/${group.groupId}`)}\r\n emptyMessage={t('tenants.groups.noGroups')}\r\n emptyIcon={<UsersRound className=\"w-12 h-12 mx-auto text-[var(--text-tertiary)]\" />}\r\n headerActions={\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => { setCreateError(null); setShowCreateModal(true); }}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('groups.createGroup')}\r\n </button>\r\n <button\r\n onClick={openAddGroup}\r\n className=\"btn btn-primary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.groups.add')}\r\n </button>\r\n </div>\r\n }\r\n pagination={{ pageSize: 10, showSizeSelector: true }}\r\n />\r\n\r\n {/* Add Group Modal */}\r\n {addingGroup && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"card w-full max-w-md p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <div>\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('tenants.groups.addTitle')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.groups.addSubtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={closeAddGroup}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <input\r\n type=\"text\"\r\n value={groupSearchTerm}\r\n onChange={(e) => setGroupSearchTerm(e.target.value)}\r\n className=\"input w-full\"\r\n placeholder={t('tenants.groups.searchGroups')}\r\n />\r\n </div>\r\n\r\n {loadingAvailableGroups ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (() => {\r\n const filteredGroups = availableGroupsForTenant.filter(g =>\r\n groupSearchTerm === '' ||\r\n g.name.toLowerCase().includes(groupSearchTerm.toLowerCase()) ||\r\n (g.description || '').toLowerCase().includes(groupSearchTerm.toLowerCase())\r\n );\r\n\r\n return filteredGroups.length === 0 ? (\r\n <div className=\"p-8 text-center border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-secondary)]\">\r\n <UsersRound className=\"w-12 h-12 mx-auto mb-3 text-[var(--text-tertiary)]\" />\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {availableGroupsForTenant.length === 0\r\n ? t('tenants.groups.noAvailableGroups')\r\n : t('tenants.groups.noMatchingGroups')}\r\n </p>\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto p-3 border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-secondary)]\">\r\n {filteredGroups.map(group => (\r\n <label\r\n key={group.groupId}\r\n className={`flex items-center gap-3 cursor-pointer p-3 rounded-[var(--radius-button)] transition-colors ${\r\n selectedGroupIds.includes(group.groupId)\r\n ? 'bg-[var(--color-accent-500)]/10 border border-[var(--color-accent-500)]'\r\n : 'hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={selectedGroupIds.includes(group.groupId)}\r\n onChange={() => handleGroupToggle(group.groupId)}\r\n className=\"w-4 h-4 rounded border-[var(--border-color)] text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <div className=\"flex-1\">\r\n <span className=\"text-[var(--text-primary)] font-medium\">{group.name}</span>\r\n {group.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{group.description}</p>\r\n )}\r\n </div>\r\n </label>\r\n ))}\r\n </div>\r\n );\r\n })()}\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={closeAddGroup}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleAddGroups}\r\n disabled={selectedGroupIds.length === 0 || assigningGroups}\r\n className=\"btn btn-primary\"\r\n >\r\n {assigningGroups ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n t('common:add')\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Remove Group Confirmation */}\r\n {removeConfirm.group && (\r\n <ConfirmModal\r\n isOpen={removeConfirm.show}\r\n title={t('tenants.groups.remove')}\r\n message={t('tenants.groups.confirmRemove', { name: removeConfirm.group.name })}\r\n variant=\"danger\"\r\n confirmLabel={t('tenants.groups.remove')}\r\n loading={removeConfirm.loading}\r\n onConfirm={async () => {\r\n if (!removeConfirm.group) return;\r\n setRemoveConfirm(prev => ({ ...prev, loading: true }));\r\n try {\r\n await onRemoveGroup(removeConfirm.group.groupId);\r\n } finally {\r\n setRemoveConfirm({ show: false, group: null, loading: false });\r\n }\r\n }}\r\n onCancel={() => setRemoveConfirm({ show: false, group: null, loading: false })}\r\n />\r\n )}\r\n\r\n {/* Create Group Modal */}\r\n {showCreateModal && (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm\">\r\n <div className=\"w-full max-w-md rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)] shadow-xl m-4\">\r\n <div className=\"flex items-center justify-between p-4 border-b border-[var(--border-color)]\">\r\n <div>\r\n <h2 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('tenants.groups.createTitle')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.groups.createSubtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={() => setShowCreateModal(false)}\r\n className=\"p-1 rounded hover:bg-[var(--bg-hover)] text-[var(--text-tertiary)]\"\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n <div className=\"p-4 space-y-4\">\r\n {createError && (\r\n <div className=\"p-3 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-sm text-[var(--error-text)]\">\r\n <span>{createError}</span>\r\n <button onClick={() => setCreateError(null)} className=\"ml-auto\">\r\n <X className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('groups.groupName')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={newGroupName}\r\n onChange={(e) => setNewGroupName(e.target.value)}\r\n placeholder={t('groups.groupNamePlaceholder')}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('common:description')}\r\n </label>\r\n <textarea\r\n value={newGroupDescription}\r\n onChange={(e) => setNewGroupDescription(e.target.value)}\r\n placeholder={t('groups.descriptionPlaceholder')}\r\n rows={3}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setNewGroupIsSecurityGroup(!newGroupIsSecurityGroup)}\r\n className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${\r\n newGroupIsSecurityGroup\r\n ? 'bg-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <span\r\n className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${\r\n newGroupIsSecurityGroup ? 'translate-x-6' : 'translate-x-1'\r\n }`}\r\n />\r\n </button>\r\n <span className=\"text-sm text-[var(--text-primary)]\">\r\n {t('groups.isSecurityGroup')}\r\n </span>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center justify-end gap-3 p-4 border-t border-[var(--border-color)]\">\r\n <button\r\n onClick={() => setShowCreateModal(false)}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleCreateGroup}\r\n disabled={!newGroupName.trim() || creating}\r\n className=\"btn btn-primary disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n {creating ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Check className=\"w-4 h-4\" />\r\n )}\r\n {t('tenants.groups.createAndAdd')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import type { ReactElement } from 'react';\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Shield,\r\n Globe,\r\n AppWindow,\r\n Users,\r\n Lock,\r\n} from 'lucide-react';\r\nimport type { TenantRoleDto } from '@/services/api/adminApi';\r\nimport { DataTable, type DataTableColumn } from '@/components/ui/DataTable';\r\n\r\ninterface TenantRolesTabProps {\r\n readonly roles: TenantRoleDto[] | null;\r\n readonly loadingRoles: boolean;\r\n}\r\n\r\nconst CATEGORY_STYLES: Record<string, { bg: string; text: string }> = {\r\n Global: { bg: 'bg-[var(--error-bg)]', text: 'text-[var(--error-text)]' },\r\n Admin: { bg: 'bg-[var(--warning-bg)]', text: 'text-[var(--warning-text)]' },\r\n Manager: { bg: 'bg-[var(--info-bg)]', text: 'text-[var(--info-text)]' },\r\n Contributor: { bg: 'bg-[var(--success-bg)]', text: 'text-[var(--success-text)]' },\r\n Viewer: { bg: 'bg-[var(--accent-bg)]', text: 'text-[var(--accent-text)]' },\r\n};\r\n\r\nexport function TenantRolesTab({\r\n roles,\r\n loadingRoles,\r\n}: Readonly<TenantRolesTabProps>): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n const columns: DataTableColumn<TenantRoleDto>[] = [\r\n {\r\n key: 'name',\r\n label: t('tenants.roles.columns.name'),\r\n sortable: true,\r\n render: (role) => (\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center ${\r\n role.isSystem\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n : 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]'\r\n }`}>\r\n {role.isSystem ? <Lock className=\"w-4 h-4\" /> : <Shield className=\"w-4 h-4\" />}\r\n </div>\r\n <div>\r\n <span className=\"font-medium text-[var(--text-primary)]\">{role.name}</span>\r\n {role.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5 line-clamp-1\">{role.description}</p>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n },\r\n {\r\n key: 'category',\r\n label: t('tenants.roles.columns.category'),\r\n sortable: true,\r\n render: (role) => {\r\n const style = CATEGORY_STYLES[role.category] ?? { bg: 'bg-[var(--bg-tertiary)]', text: 'text-[var(--text-secondary)]' };\r\n return (\r\n <span className={`inline-flex items-center px-2 py-1 text-xs rounded-[var(--radius-badge)] ${style.bg} ${style.text}`}>\r\n {t(`tenants.roles.categories.${role.category}`, { defaultValue: role.category })}\r\n </span>\r\n );\r\n }\r\n },\r\n {\r\n key: 'applicationName',\r\n label: t('tenants.roles.columns.application'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (role) => (\r\n <span className=\"inline-flex items-center gap-1.5 text-sm text-[var(--text-secondary)]\">\r\n {role.applicationId ? (\r\n <>\r\n <AppWindow className=\"w-3.5 h-3.5\" />\r\n {role.applicationName}\r\n </>\r\n ) : (\r\n <>\r\n <Globe className=\"w-3.5 h-3.5\" />\r\n {t('tenants.roles.scope.global')}\r\n </>\r\n )}\r\n </span>\r\n )\r\n },\r\n {\r\n key: 'permissionsCount',\r\n label: t('tenants.roles.columns.permissions'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (role) => (\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{role.permissionsCount}</span>\r\n )\r\n },\r\n {\r\n key: 'assignedMembersCount',\r\n label: t('tenants.roles.columns.members'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (role) => (\r\n <span className=\"inline-flex items-center gap-1.5 text-sm text-[var(--text-secondary)]\">\r\n <Users className=\"w-3.5 h-3.5\" />\r\n {role.assignedMembersCount}\r\n </span>\r\n )\r\n },\r\n ];\r\n\r\n return (\r\n <DataTable<TenantRoleDto>\r\n data={roles ?? []}\r\n loading={loadingRoles}\r\n columns={columns}\r\n searchable\r\n searchPlaceholder={t('tenants.roles.search')}\r\n searchFilter={(role, term) =>\r\n role.name.toLowerCase().includes(term.toLowerCase()) ||\r\n (role.description || '').toLowerCase().includes(term.toLowerCase()) ||\r\n (role.applicationName || '').toLowerCase().includes(term.toLowerCase())\r\n }\r\n getRowKey={(role) => role.id}\r\n emptyMessage={t('tenants.roles.empty')}\r\n emptyIcon={<Shield className=\"w-12 h-12 mx-auto text-[var(--text-tertiary)]\" />}\r\n pagination={{ pageSize: 10, showSizeSelector: true }}\r\n />\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Loader2,\r\n ChevronRight,\r\n ChevronDown,\r\n Layers,\r\n Check,\r\n Minus,\r\n Save,\r\n AlertCircle,\r\n CheckCircle,\r\n X,\r\n RotateCcw,\r\n Ban,\r\n} from 'lucide-react';\r\nimport * as LucideIcons from 'lucide-react';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type { TenantApplicationDto, OverrideAction } from '@/services/api/adminApi';\r\n\r\ninterface ApplicationAccessCustomizeDrawerProps {\r\n readonly isOpen: boolean;\r\n readonly onClose: () => void;\r\n readonly tenantId: string;\r\n readonly tenantName: string;\r\n readonly application: TenantApplicationDto;\r\n readonly onSaved?: () => void;\r\n /** Mode: 'tenant' for tenant-level customization, 'template' for template-level */\r\n readonly mode?: 'tenant' | 'template';\r\n}\r\n\r\ninterface DrawerModuleNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n source: string;\r\n accessLevel: string;\r\n isEffectivelyActive: boolean;\r\n isChecked: boolean;\r\n originalSource: string;\r\n sections: DrawerSectionNode[];\r\n}\r\n\r\ninterface DrawerSectionNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n source: string;\r\n accessLevel: string;\r\n isEffectivelyActive: boolean;\r\n isChecked: boolean;\r\n originalSource: string;\r\n}\r\n\r\ntype AccessMode = 'full' | 'custom';\r\n\r\nconst SOURCE_COLORS: Record<string, { dot: string; text: string; bg: string; label: string }> = {\r\n Inherited: { dot: 'bg-green-500', text: 'text-green-600 dark:text-green-400', bg: 'bg-green-50 dark:bg-green-900/20', label: 'inheritedLabel' },\r\n Direct: { dot: 'bg-blue-500', text: 'text-blue-600 dark:text-blue-400', bg: 'bg-blue-50 dark:bg-blue-900/20', label: 'directLabel' },\r\n Overridden: { dot: 'bg-orange-500', text: 'text-orange-600 dark:text-orange-400', bg: 'bg-orange-50 dark:bg-orange-900/20', label: 'directLabel' },\r\n Revoked: { dot: 'bg-red-500', text: 'text-red-600 dark:text-red-400', bg: 'bg-red-50 dark:bg-red-900/20', label: 'revokedLabel' },\r\n Unavailable: { dot: 'bg-gray-400', text: 'text-gray-500', bg: '', label: '' },\r\n};\r\n\r\n// Helper to compute module overrides\r\nconst computeModuleOverrides = (modules: DrawerModuleNode[]): { moduleId: string; action: OverrideAction }[] => {\r\n const overrides: { moduleId: string; action: OverrideAction }[] = [];\r\n for (const m of modules) {\r\n const wasActive = m.originalSource !== 'Revoked' && m.originalSource !== 'Unavailable';\r\n const isNowChecked = m.isChecked;\r\n\r\n if (wasActive && !isNowChecked) {\r\n overrides.push({ moduleId: m.id, action: 'revoke' });\r\n } else if (!wasActive && isNowChecked) {\r\n if (m.originalSource === 'Revoked') {\r\n overrides.push({ moduleId: m.id, action: 'remove-override' });\r\n } else {\r\n overrides.push({ moduleId: m.id, action: 'add' });\r\n }\r\n }\r\n }\r\n return overrides;\r\n};\r\n\r\n// Helper to compute section overrides\r\nconst computeSectionOverrides = (modules: DrawerModuleNode[]): { sectionId: string; action: OverrideAction }[] => {\r\n const overrides: { sectionId: string; action: OverrideAction }[] = [];\r\n for (const m of modules) {\r\n for (const s of m.sections) {\r\n const sWasActive = s.originalSource !== 'Revoked' && s.originalSource !== 'Unavailable';\r\n const sIsNowChecked = s.isChecked;\r\n\r\n if (sWasActive && !sIsNowChecked) {\r\n overrides.push({ sectionId: s.id, action: 'revoke' });\r\n } else if (!sWasActive && sIsNowChecked) {\r\n if (s.originalSource === 'Revoked') {\r\n overrides.push({ sectionId: s.id, action: 'remove-override' });\r\n } else {\r\n overrides.push({ sectionId: s.id, action: 'add' });\r\n }\r\n }\r\n }\r\n }\r\n return overrides;\r\n};\r\n\r\n// Pure function to update module check state\r\nconst updateModuleCheckStateHelper = (\r\n prev: DrawerModuleNode[],\r\n moduleId: string,\r\n newChecked: boolean\r\n): DrawerModuleNode[] => {\r\n return prev.map(m => {\r\n if (m.id !== moduleId) return m;\r\n return {\r\n ...m,\r\n isChecked: newChecked,\r\n sections: m.sections.map(s => ({ ...s, isChecked: newChecked })),\r\n };\r\n });\r\n};\r\n\r\n// Pure function to update section check state\r\nconst updateSectionCheckStateHelper = (\r\n prev: DrawerModuleNode[],\r\n moduleId: string,\r\n sectionId: string\r\n): DrawerModuleNode[] => {\r\n return prev.map(m => {\r\n if (m.id !== moduleId) return m;\r\n const newSections = m.sections.map(s =>\r\n s.id === sectionId ? { ...s, isChecked: !s.isChecked } : s\r\n );\r\n return {\r\n ...m,\r\n isChecked: newSections.some(s => s.isChecked),\r\n sections: newSections,\r\n };\r\n });\r\n};\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype TranslationFn = (...args: any[]) => any;\r\n\r\ninterface SectionItemProps {\r\n readonly section: DrawerSectionNode;\r\n readonly moduleId: string;\r\n readonly renderIcon: (iconName: string | null) => React.ReactNode;\r\n readonly isInheritedRevoked: (originalSource: string, isChecked: boolean) => boolean;\r\n readonly toggleSection: (moduleId: string, sectionId: string) => void;\r\n readonly t: TranslationFn;\r\n}\r\n\r\nconst SectionItem = ({ section, moduleId, renderIcon, isInheritedRevoked: checkRevoked, toggleSection, t }: SectionItemProps) => {\r\n const sectionRevoked = checkRevoked(section.originalSource, section.isChecked);\r\n\r\n return (\r\n <div\r\n key={section.id}\r\n className={`flex items-center gap-2 p-2 rounded ${\r\n sectionRevoked\r\n ? 'bg-red-50/60 dark:bg-red-900/10 hover:bg-red-50 dark:hover:bg-red-900/20'\r\n : 'hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <button\r\n onClick={() => toggleSection(moduleId, section.id)}\r\n className={`w-4 h-4 rounded border-2 flex items-center justify-center flex-shrink-0 transition-colors ${\r\n sectionRevoked\r\n ? 'border-red-500 bg-red-500'\r\n : section.isChecked\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-600)]'\r\n }`}\r\n >\r\n {sectionRevoked && <Ban className=\"w-2.5 h-2.5 text-white\" />}\r\n {!sectionRevoked && section.isChecked && <Check className=\"w-2.5 h-2.5 text-white\" />}\r\n </button>\r\n\r\n <div className={`p-1 rounded ${sectionRevoked ? 'bg-red-100 dark:bg-red-900/30' : 'bg-[var(--bg-tertiary)]'}`}>\r\n {renderIcon(section.icon) || (\r\n <Layers className={`w-3 h-3 ${sectionRevoked ? 'text-red-400' : 'text-[var(--text-muted)]'}`} />\r\n )}\r\n </div>\r\n\r\n <span className={`text-sm flex-1 ${sectionRevoked ? 'line-through text-red-500 dark:text-red-400' : 'text-[var(--text-primary)]'}`}>{section.label}</span>\r\n {sectionRevoked && (\r\n <span className=\"text-[10px] px-1.5 py-0.5 rounded-full bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400 font-medium\">\r\n {t('tenants.applications.customize.revokedLabel')}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\ninterface ModuleRowProps {\r\n readonly module: DrawerModuleNode;\r\n readonly isExpanded: boolean;\r\n readonly renderIcon: (iconName: string | null) => React.ReactNode;\r\n readonly isInheritedRevoked: (originalSource: string, isChecked: boolean) => boolean;\r\n readonly getModuleCheckState: (module: DrawerModuleNode) => 'checked' | 'unchecked' | 'indeterminate';\r\n readonly toggleModuleExpand: (moduleId: string) => void;\r\n readonly toggleModule: (moduleId: string) => void;\r\n readonly toggleSection: (moduleId: string, sectionId: string) => void;\r\n readonly mode: 'tenant' | 'template';\r\n readonly t: TranslationFn;\r\n}\r\n\r\nconst ModuleRow = ({\r\n module,\r\n isExpanded,\r\n renderIcon,\r\n isInheritedRevoked: checkRevoked,\r\n getModuleCheckState,\r\n toggleModuleExpand,\r\n toggleModule,\r\n toggleSection,\r\n mode,\r\n t,\r\n}: ModuleRowProps) => {\r\n const checkState = getModuleCheckState(module);\r\n const moduleRevoked = checkRevoked(module.originalSource, module.isChecked);\r\n\r\n return (\r\n <div key={module.id}>\r\n {/* Module Row */}\r\n <div className={`flex items-center gap-2 p-3 ${\r\n moduleRevoked\r\n ? 'bg-red-50/60 dark:bg-red-900/10 hover:bg-red-50 dark:hover:bg-red-900/20'\r\n : 'hover:bg-[var(--bg-hover)]'\r\n }`}>\r\n <button\r\n onClick={() => toggleModuleExpand(module.id)}\r\n className=\"p-1 rounded hover:bg-[var(--bg-tertiary)]\"\r\n >\r\n {isExpanded ? (\r\n <ChevronDown className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n ) : (\r\n <ChevronRight className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n )}\r\n </button>\r\n\r\n <button\r\n onClick={() => toggleModule(module.id)}\r\n className={`w-5 h-5 rounded border-2 flex items-center justify-center flex-shrink-0 transition-colors ${\r\n moduleRevoked\r\n ? 'border-red-500 bg-red-500'\r\n : checkState === 'checked'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]'\r\n : checkState === 'indeterminate'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-600)]'\r\n }`}\r\n >\r\n {moduleRevoked && <Ban className=\"w-3 h-3 text-white\" />}\r\n {!moduleRevoked && checkState === 'checked' && <Check className=\"w-3 h-3 text-white\" />}\r\n {!moduleRevoked && checkState === 'indeterminate' && <Minus className=\"w-3 h-3 text-white\" />}\r\n </button>\r\n\r\n <div className={`p-1.5 rounded ${moduleRevoked ? 'bg-red-100 dark:bg-red-900/30' : 'bg-[var(--bg-tertiary)]'}`}>\r\n {renderIcon(module.icon) || <Layers className={`w-4 h-4 ${moduleRevoked ? 'text-red-400' : 'text-[var(--text-muted)]'}`} />}\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <p className={`font-medium truncate ${moduleRevoked ? 'line-through text-red-500 dark:text-red-400' : 'text-[var(--text-primary)]'}`}>{module.label}</p>\r\n {mode !== 'template' && module.source !== 'Unavailable' && (\r\n moduleRevoked ? (\r\n <span className=\"text-[10px] px-1.5 py-0.5 rounded-full bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400 font-medium\">\r\n {t('tenants.applications.customize.revokedLabel')}\r\n </span>\r\n ) : (\r\n <span className={`text-[10px] px-1.5 py-0.5 rounded-full ${(SOURCE_COLORS[module.source] || SOURCE_COLORS.Inherited).bg} ${(SOURCE_COLORS[module.source] || SOURCE_COLORS.Inherited).text}`}>\r\n {t(`tenants.applications.customize.${(SOURCE_COLORS[module.source] || SOURCE_COLORS.Inherited).label}`)}\r\n </span>\r\n )\r\n )}\r\n </div>\r\n <p className={`text-xs ml-4 ${moduleRevoked ? 'text-red-400 dark:text-red-500' : 'text-[var(--text-muted)]'}`}>\r\n {module.sections.filter(s => s.isChecked).length}/{module.sections.length}{' '}\r\n {t('tenants.applications.customize.sections', 'sections')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Sections (expandable) */}\r\n {isExpanded && module.sections.length > 0 && (\r\n <div className=\"pl-12 pb-2 space-y-1 bg-[var(--bg-secondary)]\">\r\n {module.sections.map(section => (\r\n <SectionItem\r\n key={section.id}\r\n section={section}\r\n moduleId={module.id}\r\n renderIcon={renderIcon}\r\n isInheritedRevoked={checkRevoked}\r\n toggleSection={toggleSection}\r\n t={t}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport function ApplicationAccessCustomizeDrawer({\r\n isOpen,\r\n onClose,\r\n tenantId,\r\n tenantName,\r\n application,\r\n onSaved,\r\n mode = 'tenant',\r\n}: ApplicationAccessCustomizeDrawerProps): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n\r\n const [accessMode, setAccessMode] = useState<AccessMode>('full');\r\n const [modules, setModules] = useState<DrawerModuleNode[]>([]);\r\n const [expandedModules, setExpandedModules] = useState<Set<string>>(new Set());\r\n\r\n const renderIcon = (iconName: string | null) => {\r\n if (!iconName) return null;\r\n const icons = LucideIcons as unknown as Record<string, LucideIcon>;\r\n const IconComponent = icons[iconName];\r\n if (!IconComponent) return null;\r\n return <IconComponent className=\"w-4 h-4\" />;\r\n };\r\n\r\n const loadData = useCallback(async () => {\r\n if (!isOpen) return;\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n if (mode === 'template') {\r\n // Template mode: unchanged - use existing endpoint\r\n const treeData = await adminApi.templates.getApplicationModules(tenantId, application.applicationId);\r\n const moduleNodes: DrawerModuleNode[] = treeData.map(m => ({\r\n id: m.moduleId,\r\n label: m.label,\r\n code: m.code,\r\n icon: m.icon,\r\n source: m.isAssigned ? 'Direct' : 'Unavailable',\r\n accessLevel: 'FullAccess',\r\n isEffectivelyActive: m.isAssigned,\r\n isChecked: m.isAssigned,\r\n originalSource: m.isAssigned ? 'Direct' : 'Unavailable',\r\n sections: m.sections.map(s => ({\r\n id: s.sectionId,\r\n label: s.label,\r\n code: s.code,\r\n icon: s.icon,\r\n source: s.isAssigned ? 'Direct' : 'Unavailable',\r\n accessLevel: 'FullAccess',\r\n isEffectivelyActive: s.isAssigned,\r\n isChecked: s.isAssigned,\r\n originalSource: s.isAssigned ? 'Direct' : 'Unavailable',\r\n })),\r\n }));\r\n setModules(moduleNodes);\r\n setAccessMode(moduleNodes.some(m => m.isChecked) ? 'custom' : 'full');\r\n const expanded = new Set(moduleNodes.filter(m => m.sections.some(s => s.isChecked)).map(m => m.id));\r\n setExpandedModules(expanded);\r\n } else {\r\n // Tenant mode: use effective-tree endpoint\r\n const tree = await adminApi.tenants.getEffectiveTree(tenantId, application.applicationId);\r\n const moduleNodes: DrawerModuleNode[] = tree.map(m => ({\r\n id: m.moduleId,\r\n label: m.label,\r\n code: m.code,\r\n icon: m.icon,\r\n source: m.source,\r\n accessLevel: m.accessLevel,\r\n isEffectivelyActive: m.isEffectivelyActive,\r\n isChecked: m.source !== 'Revoked' && m.source !== 'Unavailable',\r\n originalSource: m.source,\r\n sections: m.sections.map(s => ({\r\n id: s.sectionId,\r\n label: s.label,\r\n code: s.code,\r\n icon: s.icon,\r\n source: s.source,\r\n accessLevel: s.accessLevel,\r\n isEffectivelyActive: s.isEffectivelyActive,\r\n isChecked: s.source !== 'Revoked' && s.source !== 'Unavailable',\r\n originalSource: s.source,\r\n })),\r\n }));\r\n setModules(moduleNodes);\r\n\r\n // Determine access mode\r\n const hasAnyOverride = moduleNodes.some(m =>\r\n m.source === 'Direct' || m.source === 'Overridden' || m.source === 'Revoked' ||\r\n m.sections.some(s => s.source === 'Direct' || s.source === 'Overridden' || s.source === 'Revoked')\r\n );\r\n setAccessMode(hasAnyOverride ? 'custom' : 'full');\r\n\r\n // Expand modules that have interesting content\r\n const expanded = new Set(moduleNodes\r\n .filter(m => m.sections.some(s => s.source !== 'Inherited' || !s.isEffectivelyActive))\r\n .map(m => m.id));\r\n setExpandedModules(expanded);\r\n }\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load data');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [isOpen, application.applicationId, tenantId, mode]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const preCheckAllModules = (mods: DrawerModuleNode[]): DrawerModuleNode[] => {\r\n return mods.map(m => ({\r\n ...m,\r\n isChecked: true,\r\n sections: m.sections.map(s => ({ ...s, isChecked: true })),\r\n }));\r\n };\r\n\r\n const handleAccessModeChange = (newMode: AccessMode) => {\r\n if (newMode === 'custom' && accessMode === 'full') {\r\n const hasAnyChecked = modules.some(m => m.isChecked || m.sections.some(s => s.isChecked));\r\n if (!hasAnyChecked) {\r\n setModules(preCheckAllModules);\r\n }\r\n }\r\n setAccessMode(newMode);\r\n };\r\n\r\n const toggleModuleExpand = (moduleId: string) => {\r\n setExpandedModules(prev => {\r\n const newSet = new Set(prev);\r\n if (newSet.has(moduleId)) {\r\n newSet.delete(moduleId);\r\n } else {\r\n newSet.add(moduleId);\r\n }\r\n return newSet;\r\n });\r\n };\r\n\r\n const toggleModule = (moduleId: string) => {\r\n setModules(prev => {\r\n const target = prev.find(m => m.id === moduleId);\r\n const newChecked = !target?.isChecked;\r\n return updateModuleCheckStateHelper(prev, moduleId, newChecked);\r\n });\r\n };\r\n\r\n const toggleSection = (moduleId: string, sectionId: string) => {\r\n setModules(prev => updateSectionCheckStateHelper(prev, moduleId, sectionId));\r\n };\r\n\r\n /** Returns true if this item was inherited (from template/group) and is now revoked by the user */\r\n const isInheritedRevoked = (originalSource: string, isChecked: boolean) =>\r\n (originalSource === 'Inherited' || originalSource === 'Revoked') && !isChecked;\r\n\r\n const getModuleCheckState = (module: DrawerModuleNode): 'checked' | 'unchecked' | 'indeterminate' => {\r\n if (module.sections.length === 0) {\r\n return module.isChecked ? 'checked' : 'unchecked';\r\n }\r\n const checkedCount = module.sections.filter(s => s.isChecked).length;\r\n if (checkedCount === 0) return 'unchecked';\r\n if (checkedCount === module.sections.length) return 'checked';\r\n return 'indeterminate';\r\n };\r\n\r\n const saveTemplateMode = async () => {\r\n if (accessMode === 'full') {\r\n await adminApi.templates.updateApplicationModules(tenantId, application.applicationId, {\r\n accessMode: 'full',\r\n });\r\n } else {\r\n const moduleIds = modules.filter(m => m.isChecked || m.sections.some(s => s.isChecked)).map(m => m.id);\r\n const sectionIds = modules.flatMap(m => m.sections.filter(s => s.isChecked).map(s => s.id));\r\n await adminApi.templates.updateApplicationModules(tenantId, application.applicationId, {\r\n accessMode: 'custom',\r\n moduleIds,\r\n sectionIds,\r\n });\r\n }\r\n };\r\n\r\n const saveTenantMode = async () => {\r\n const moduleOverrides = computeModuleOverrides(modules);\r\n const sectionOverrides = computeSectionOverrides(modules);\r\n\r\n if (moduleOverrides.length > 0 || sectionOverrides.length > 0) {\r\n await adminApi.tenants.saveOverrides(tenantId, application.applicationId, {\r\n modules: moduleOverrides.length > 0 ? moduleOverrides : undefined,\r\n sections: sectionOverrides.length > 0 ? sectionOverrides : undefined,\r\n });\r\n }\r\n };\r\n\r\n const handleSave = async () => {\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n\r\n try {\r\n if (mode === 'template') {\r\n await saveTemplateMode();\r\n } else {\r\n await saveTenantMode();\r\n }\r\n\r\n setSuccess(t('tenants.applications.customize.saved', 'Access customization saved'));\r\n onSaved?.();\r\n setTimeout(() => onClose(), 1000);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to save');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleReset = async () => {\r\n setSaving(true);\r\n setError(null);\r\n try {\r\n // Remove all tenant-level overrides for modules and sections of this app\r\n const resetAction: OverrideAction = 'remove-override';\r\n const moduleOverrides = modules\r\n .filter(m => m.originalSource === 'Direct' || m.originalSource === 'Overridden' || m.originalSource === 'Revoked')\r\n .map(m => ({ moduleId: m.id, action: resetAction }));\r\n const sectionOverrides = modules.flatMap(m =>\r\n m.sections\r\n .filter(s => s.originalSource === 'Direct' || s.originalSource === 'Overridden' || s.originalSource === 'Revoked')\r\n .map(s => ({ sectionId: s.id, action: resetAction }))\r\n );\r\n\r\n if (moduleOverrides.length > 0 || sectionOverrides.length > 0) {\r\n await adminApi.tenants.saveOverrides(tenantId, application.applicationId, {\r\n modules: moduleOverrides.length > 0 ? moduleOverrides : undefined,\r\n sections: sectionOverrides.length > 0 ? sectionOverrides : undefined,\r\n });\r\n }\r\n\r\n setSuccess(t('tenants.applications.customize.resetSuccess', 'Customizations reset'));\r\n onSaved?.();\r\n setTimeout(() => onClose(), 1000);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to reset');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const getStats = () => {\r\n const totalModules = modules.length;\r\n const checkedModules = modules.filter(m => m.isChecked).length;\r\n const totalSections = modules.reduce((sum, m) => sum + m.sections.length, 0);\r\n const checkedSections = modules.reduce((sum, m) => sum + m.sections.filter(s => s.isChecked).length, 0);\r\n const inheritedCount = modules.filter(m => m.source === 'Inherited').length;\r\n const directCount = modules.filter(m => m.source === 'Direct' || m.source === 'Overridden').length;\r\n const revokedCount = modules.filter(m => m.source === 'Revoked').length;\r\n const revokedInheritedModules = modules.filter(m => isInheritedRevoked(m.originalSource, m.isChecked)).length;\r\n const revokedInheritedSections = modules.reduce((sum, m) => sum + m.sections.filter(s => isInheritedRevoked(s.originalSource, s.isChecked)).length, 0);\r\n return { totalModules, checkedModules, totalSections, checkedSections, inheritedCount, directCount, revokedCount, revokedInheritedModules, revokedInheritedSections };\r\n };\r\n\r\n const stats = getStats();\r\n\r\n // Handle escape key\r\n useEffect(() => {\r\n const handleEscape = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape' && isOpen) {\r\n onClose();\r\n }\r\n };\r\n document.addEventListener('keydown', handleEscape);\r\n return () => document.removeEventListener('keydown', handleEscape);\r\n }, [isOpen, onClose]);\r\n\r\n // Lock body scroll when open\r\n useEffect(() => {\r\n if (isOpen) {\r\n document.body.style.overflow = 'hidden';\r\n } else {\r\n document.body.style.overflow = '';\r\n }\r\n return () => {\r\n document.body.style.overflow = '';\r\n };\r\n }, [isOpen]);\r\n\r\n if (!isOpen) return null;\r\n\r\n return (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\r\n {/* Backdrop */}\r\n <button\r\n type=\"button\"\r\n className=\"absolute inset-0 bg-black/50\"\r\n onClick={onClose}\r\n aria-label=\"Close modal\"\r\n />\r\n\r\n {/* Modal */}\r\n <div className=\"relative w-full max-w-2xl max-h-[90vh] bg-[var(--bg-card)] rounded-[var(--radius-card)] shadow-xl border border-[var(--border-color)] flex flex-col\">\r\n {/* Header */}\r\n <div className=\"flex items-start justify-between p-4 border-b border-[var(--border-color)]\">\r\n <div>\r\n <h2 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('tenants.applications.customize.title', 'Customize Access')}\r\n </h2>\r\n <p className=\"mt-1 text-sm text-[var(--text-muted)]\">\r\n {application.label} - {tenantName}\r\n </p>\r\n </div>\r\n <button\r\n onClick={onClose}\r\n className=\"p-1 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-muted)]\"\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n\r\n {/* Content */}\r\n <div className=\"flex-1 overflow-y-auto p-4\">\r\n {loading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n ) : (\r\n <div className=\"space-y-6\">\r\n {/* Alerts */}\r\n {error && (\r\n <div className=\"flex items-center gap-3 p-3 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertCircle className=\"w-4 h-4 text-[var(--error-text)]\" />\r\n <p className=\"text-sm text-[var(--error-text)]\">{error}</p>\r\n </div>\r\n )}\r\n {success && (\r\n <div className=\"flex items-center gap-3 p-3 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <p className=\"text-sm text-[var(--success-text)]\">{success}</p>\r\n </div>\r\n )}\r\n\r\n {/* Access Mode Selection */}\r\n <div className=\"space-y-3\">\r\n <label className=\"text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('tenants.applications.customize.accessMode', 'Access Mode')}\r\n </label>\r\n\r\n {/* Full Access Option */}\r\n <button\r\n type=\"button\"\r\n onClick={() => handleAccessModeChange('full')}\r\n className={`w-full flex items-start gap-3 p-4 rounded-[var(--radius-card)] border text-left transition-colors ${\r\n accessMode === 'full'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]/5'\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div\r\n className={`w-5 h-5 mt-0.5 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${\r\n accessMode === 'full' ? 'border-[var(--color-accent-600)]' : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {accessMode === 'full' && (\r\n <div className=\"w-2.5 h-2.5 rounded-full bg-[var(--color-accent-600)]\" />\r\n )}\r\n </div>\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('tenants.applications.customize.fullAccess', 'Full Application Access')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-muted)] mt-1\">\r\n {t(\r\n 'tenants.applications.customize.fullAccessHint',\r\n 'Access to all modules and sections of this application'\r\n )}\r\n </p>\r\n </div>\r\n </button>\r\n\r\n {/* Custom Access Option */}\r\n <button\r\n type=\"button\"\r\n onClick={() => handleAccessModeChange('custom')}\r\n className={`w-full flex items-start gap-3 p-4 rounded-[var(--radius-card)] border text-left transition-colors ${\r\n accessMode === 'custom'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]/5'\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div\r\n className={`w-5 h-5 mt-0.5 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${\r\n accessMode === 'custom' ? 'border-[var(--color-accent-600)]' : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {accessMode === 'custom' && (\r\n <div className=\"w-2.5 h-2.5 rounded-full bg-[var(--color-accent-600)]\" />\r\n )}\r\n </div>\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('tenants.applications.customize.customAccess', 'Custom Access')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-muted)] mt-1\">\r\n {t(\r\n 'tenants.applications.customize.customAccessHint',\r\n 'Select specific modules and sections to grant access'\r\n )}\r\n </p>\r\n </div>\r\n </button>\r\n </div>\r\n\r\n {/* Module/Section Tree (only shown in custom mode) */}\r\n {accessMode === 'custom' && (\r\n <div className=\"space-y-3\">\r\n <label className=\"text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('tenants.applications.customize.selectModules', 'Select Modules & Sections')}\r\n </label>\r\n\r\n <div className=\"border border-[var(--border-color)] rounded-[var(--radius-card)] divide-y divide-[var(--border-color)]\">\r\n {modules.map(module => (\r\n <ModuleRow\r\n key={module.id}\r\n module={module}\r\n isExpanded={expandedModules.has(module.id)}\r\n renderIcon={renderIcon}\r\n isInheritedRevoked={isInheritedRevoked}\r\n getModuleCheckState={getModuleCheckState}\r\n toggleModuleExpand={toggleModuleExpand}\r\n toggleModule={toggleModule}\r\n toggleSection={toggleSection}\r\n mode={mode}\r\n t={t}\r\n />\r\n ))}\r\n\r\n {modules.length === 0 && (\r\n <div className=\"p-6 text-center text-sm text-[var(--text-muted)]\">\r\n {t('tenants.applications.customize.noModules', 'No modules available')}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Footer */}\r\n <div className=\"flex-shrink-0 border-t border-[var(--border-color)] p-4 bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"text-sm text-[var(--text-muted)]\">\r\n {accessMode === 'custom' ? (\r\n <div className=\"space-y-0.5\">\r\n <div>\r\n {stats.checkedModules}/{stats.totalModules} {t('tenants.applications.customize.modules', 'modules')},\r\n {' '}{stats.checkedSections}/{stats.totalSections} {t('tenants.applications.customize.sections', 'sections')}\r\n </div>\r\n {(stats.revokedInheritedModules > 0 || stats.revokedInheritedSections > 0) && (\r\n <div className=\"text-red-500 dark:text-red-400 text-xs flex items-center gap-1\">\r\n <Ban className=\"w-3 h-3\" />\r\n {stats.revokedInheritedModules > 0 && (\r\n <span>{stats.revokedInheritedModules} {t('tenants.applications.customize.modules')} {t('tenants.applications.customize.revokedLabel').toLowerCase()}</span>\r\n )}\r\n {stats.revokedInheritedModules > 0 && stats.revokedInheritedSections > 0 && ', '}\r\n {stats.revokedInheritedSections > 0 && (\r\n <span>{stats.revokedInheritedSections} {t('tenants.applications.customize.sections')} {t('tenants.applications.customize.revokedLabel').toLowerCase()}</span>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n t('tenants.applications.customize.fullAccessDesc', 'Full application access')\r\n )}\r\n </div>\r\n <div className=\"flex gap-2\">\r\n {mode !== 'template' && modules.some(m => m.originalSource !== 'Inherited' && m.originalSource !== 'Unavailable') && (\r\n <button\r\n onClick={handleReset}\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-3 py-2 rounded-[var(--radius-button)] font-medium text-orange-600 hover:bg-orange-50 dark:text-orange-400 dark:hover:bg-orange-900/20\"\r\n >\r\n <RotateCcw className=\"w-4 h-4\" />\r\n {t('tenants.applications.customize.resetOverrides', 'Reset to template')}\r\n </button>\r\n )}\r\n <button\r\n onClick={onClose}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] font-medium text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common.cancel', 'Cancel')}\r\n </button>\r\n <button\r\n onClick={handleSave}\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common.save', 'Save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useMemo, useState } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport * as LucideIcons from 'lucide-react';\r\nimport {\r\n Boxes,\r\n Plus,\r\n X,\r\n Check,\r\n Minus,\r\n SlidersHorizontal,\r\n Loader2,\r\n Search,\r\n ChevronRight,\r\n ChevronDown,\r\n CheckCircle,\r\n Layers,\r\n Trash2,\r\n ShieldX,\r\n AlertTriangle,\r\n} from 'lucide-react';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport type {\r\n TenantApplicationDto,\r\n AvailableApplicationDto,\r\n ApplicationAccessLevel,\r\n} from '@/services/api/adminApi';\r\nimport { EntityCard } from '@/components/ui/EntityCard';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport { ApplicationAccessCustomizeDrawer } from '@/components/platform/administration/ApplicationAccessCustomizeDrawer';\r\n\r\nexport interface BulkModuleNode {\r\n readonly id: string;\r\n readonly label: string;\r\n readonly code: string;\r\n readonly icon: string | null;\r\n readonly isAssigned: boolean;\r\n readonly sections: BulkSectionNode[];\r\n}\r\n\r\nexport interface BulkSectionNode {\r\n readonly id: string;\r\n readonly label: string;\r\n readonly code: string;\r\n readonly icon: string | null;\r\n readonly isAssigned: boolean;\r\n}\r\n\r\ninterface TenantApplicationsTabProps {\r\n readonly tenantId: string;\r\n readonly tenantName: string;\r\n /** Mode: 'tenant' for tenant-level, 'template' for template-level module management */\r\n readonly mode?: 'tenant' | 'template';\r\n readonly applications: TenantApplicationDto[] | null;\r\n readonly loadingApps: boolean;\r\n readonly actionLoading: string | null;\r\n readonly onRefresh: () => Promise<void>;\r\n readonly onUpdateAccessLevel: (appId: string, accessLevel: ApplicationAccessLevel) => Promise<void>;\r\n readonly onRemoveApplication?: (appId: string) => Promise<void>;\r\n // Add application modal state\r\n readonly addingApplication: boolean;\r\n readonly availableAppsError?: string | null;\r\n readonly filteredAvailableApps: AvailableApplicationDto[];\r\n readonly loadingAvailableApps: boolean;\r\n readonly selectedAppIds: string[];\r\n readonly assigningApps: boolean;\r\n readonly appSearchTerm: string;\r\n readonly selectedAccessLevel: ApplicationAccessLevel;\r\n readonly bulkAccessMode: 'full' | 'custom';\r\n readonly bulkModules: BulkModuleNode[];\r\n readonly bulkExpandedModules: Set<string>;\r\n readonly loadingBulkModules: boolean;\r\n // Customize drawer state\r\n readonly showCustomizeDrawer: boolean;\r\n readonly customizingApp: TenantApplicationDto | null;\r\n // Actions\r\n readonly onOpenAddApplication: () => void;\r\n readonly onCloseAddApplication: () => void;\r\n readonly onAssignApplications: () => Promise<void>;\r\n readonly onAppToggle: (appId: string) => void;\r\n readonly onSelectAllApps: () => void;\r\n readonly onClearAppSelection: () => void;\r\n readonly onOpenCustomizeDrawer: (app: TenantApplicationDto) => void;\r\n readonly onCloseCustomizeDrawer: () => void;\r\n // Module handlers\r\n readonly onLoadBulkModules: (appId: string) => Promise<void>;\r\n readonly onToggleBulkModuleExpand: (moduleId: string) => void;\r\n readonly onToggleBulkModule: (moduleId: string) => void;\r\n readonly onToggleBulkSection: (moduleId: string, sectionId: string) => void;\r\n readonly onGetBulkModuleCheckState: (module: BulkModuleNode) => 'checked' | 'unchecked' | 'indeterminate';\r\n readonly onGetBulkStats: () => { totalModules: number; assignedModules: number; totalSections: number; assignedSections: number };\r\n readonly onSelectAllBulkModules: () => void;\r\n readonly onClearBulkModules: () => void;\r\n // Setters\r\n readonly setAppSearchTerm: (term: string) => void;\r\n readonly setSelectedAccessLevel: (level: ApplicationAccessLevel) => void;\r\n readonly setBulkAccessMode: (mode: 'full' | 'custom') => void;\r\n}\r\n\r\nfunction formatDate(date: string | Date): string {\r\n const d = new Date(date);\r\n return d.toLocaleDateString('en-US', {\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n });\r\n}\r\n\r\nconst getCheckStateClassName = (checkState: 'checked' | 'unchecked' | 'indeterminate'): string => {\r\n if (checkState === 'checked' || checkState === 'indeterminate') {\r\n return 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]';\r\n }\r\n return 'border-[var(--border-color)] hover:border-[var(--color-accent-600)]';\r\n};\r\n\r\nconst getLoadingView = (): React.ReactNode => (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n);\r\n\r\nconst getEmptyApplicationsView = (t: (key: string) => string): React.ReactNode => (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n <Boxes className=\"w-12 h-12 mx-auto mb-4 text-[var(--text-tertiary)]\" />\r\n <p>{t('tenants.applications.empty')}</p>\r\n </div>\r\n);\r\n\r\nconst ACCESS_LEVEL_OPTIONS: {\r\n level: ApplicationAccessLevel;\r\n labelKey: string;\r\n descKey: string;\r\n selectedBorder: string;\r\n selectedBg: string;\r\n dotBg: string;\r\n}[] = [\r\n {\r\n level: 'FullAccess',\r\n labelKey: 'tenants.applications.accessLevels.fullAccess',\r\n descKey: 'tenants.applications.accessLevels.fullAccessDesc',\r\n selectedBorder: 'border-green-500',\r\n selectedBg: 'bg-green-500/10',\r\n dotBg: 'bg-green-500',\r\n },\r\n {\r\n level: 'RequestAccess',\r\n labelKey: 'tenants.applications.accessLevels.requestAccess',\r\n descKey: 'tenants.applications.accessLevels.requestAccessDesc',\r\n selectedBorder: 'border-amber-500',\r\n selectedBg: 'bg-amber-500/10',\r\n dotBg: 'bg-amber-500',\r\n },\r\n {\r\n level: 'Disabled',\r\n labelKey: 'tenants.applications.accessLevels.disabled',\r\n descKey: 'tenants.applications.accessLevels.disabledDesc',\r\n selectedBorder: 'border-gray-500',\r\n selectedBg: 'bg-gray-500/10',\r\n dotBg: 'bg-gray-500',\r\n },\r\n];\r\n\r\n\r\nfunction AccessLevelSelector({\r\n selectedAccessLevel,\r\n setSelectedAccessLevel,\r\n}: {\r\n selectedAccessLevel: ApplicationAccessLevel;\r\n setSelectedAccessLevel: (level: ApplicationAccessLevel) => void;\r\n}) {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n {ACCESS_LEVEL_OPTIONS.map((opt) => {\r\n const isSelected = selectedAccessLevel === opt.level;\r\n return (\r\n <button\r\n key={opt.level}\r\n type=\"button\"\r\n onClick={() => setSelectedAccessLevel(opt.level)}\r\n className={`w-full flex items-start gap-3 p-4 rounded-[var(--radius-input)] border text-left transition-colors ${\r\n isSelected\r\n ? `${opt.selectedBorder} ${opt.selectedBg}`\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div\r\n className={`w-5 h-5 mt-0.5 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${\r\n isSelected ? opt.selectedBorder : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {isSelected && <div className={`w-2.5 h-2.5 rounded-full ${opt.dotBg}`} />}\r\n </div>\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">{t(opt.labelKey)}</p>\r\n <p className=\"text-sm text-[var(--text-muted)] mt-1\">{t(opt.descKey)}</p>\r\n </div>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n\r\nexport function TenantApplicationsTab({\r\n tenantId,\r\n tenantName,\r\n mode = 'tenant',\r\n applications,\r\n loadingApps,\r\n actionLoading,\r\n onRefresh,\r\n onUpdateAccessLevel,\r\n onRemoveApplication,\r\n addingApplication,\r\n availableAppsError,\r\n filteredAvailableApps,\r\n loadingAvailableApps,\r\n selectedAppIds,\r\n assigningApps,\r\n appSearchTerm,\r\n selectedAccessLevel,\r\n bulkAccessMode,\r\n bulkModules,\r\n bulkExpandedModules,\r\n loadingBulkModules,\r\n showCustomizeDrawer,\r\n customizingApp,\r\n onOpenAddApplication,\r\n onCloseAddApplication,\r\n onAssignApplications,\r\n onAppToggle,\r\n onSelectAllApps,\r\n onClearAppSelection,\r\n onOpenCustomizeDrawer,\r\n onCloseCustomizeDrawer,\r\n onLoadBulkModules,\r\n onToggleBulkModuleExpand,\r\n onToggleBulkModule,\r\n onToggleBulkSection,\r\n onGetBulkModuleCheckState,\r\n onGetBulkStats,\r\n onSelectAllBulkModules,\r\n onClearBulkModules,\r\n setAppSearchTerm,\r\n setSelectedAccessLevel,\r\n setBulkAccessMode,\r\n}: TenantApplicationsTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n const bulkStats = useMemo(() => {\r\n return onGetBulkStats();\r\n }, [bulkModules, onGetBulkStats]);\r\n\r\n const [removeConfirm, setRemoveConfirm] = useState<{\r\n show: boolean;\r\n app: TenantApplicationDto | null;\r\n loading: boolean;\r\n }>({ show: false, app: null, loading: false });\r\n\r\n const inheritedApps = useMemo(\r\n () => (applications ?? []).filter(app => app.source === 'Inherited' || app.source === 'Overridden'),\r\n [applications]\r\n );\r\n\r\n const directApps = useMemo(\r\n () => (applications ?? []).filter(app => app.source === 'Direct' || app.source === 'Revoked'),\r\n [applications]\r\n );\r\n\r\n const renderAppCard = (app: TenantApplicationDto) => {\r\n const accessLevelOption = ACCESS_LEVEL_OPTIONS.find(o => o.level === app.accessLevel);\r\n const isActive = app.accessLevel !== 'Disabled';\r\n\r\n return (\r\n <EntityCard\r\n key={app.applicationId}\r\n avatar={{\r\n letter: (app.label?.at(0) || 'A').toUpperCase(),\r\n color: isActive ? 'var(--color-accent-500)' : '#6b7280'\r\n }}\r\n title={app.label}\r\n subtitle={app.code}\r\n description={app.assignedAt\r\n ? t('tenants.applications.assignedAt', { date: formatDate(app.assignedAt) })\r\n : undefined\r\n }\r\n stats={\r\n <span>\r\n {app.inheritedModuleCount > 0 && (\r\n <><span className=\"text-green-600 dark:text-green-400 font-medium\">{app.inheritedModuleCount}</span> {t('tenants.applications.counts.inherited')}</>\r\n )}\r\n {app.directModuleCount > 0 && (\r\n <>{app.inheritedModuleCount > 0 ? ', ' : ''}<span className=\"text-blue-600 dark:text-blue-400 font-medium\">{app.directModuleCount}</span> {t('tenants.applications.counts.direct')}</>\r\n )}\r\n {app.revokedModuleCount > 0 && (\r\n <>{(app.inheritedModuleCount > 0 || app.directModuleCount > 0) ? ', ' : ''}<span className=\"text-red-600 dark:text-red-400 font-medium\">{app.revokedModuleCount}</span> {t('tenants.applications.counts.revoked')}</>\r\n )}\r\n {app.inheritedModuleCount === 0 && app.directModuleCount === 0 && app.revokedModuleCount === 0 && (\r\n <><span className=\"font-medium text-[var(--text-primary)]\">0</span>/{app.totalModuleCount}</>\r\n )}\r\n {' '}{t('tenants.applications.customize.modules')}\r\n {' / '}\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {app.totalSectionCount}\r\n </span>{' '}\r\n {t('tenants.applications.customize.sections')}\r\n </span>\r\n }\r\n customFooter={\r\n <div className=\"space-y-2 pt-2 mt-2 border-t border-[var(--border-color)]\">\r\n {/* Access level selector */}\r\n <div className=\"flex items-center gap-2\">\r\n <div className={`w-2.5 h-2.5 rounded-full flex-shrink-0 ${accessLevelOption?.dotBg ?? 'bg-green-500'}`} />\r\n <select\r\n value={app.accessLevel}\r\n onChange={e => void onUpdateAccessLevel(app.applicationId, e.target.value as ApplicationAccessLevel)}\r\n disabled={actionLoading === app.applicationId}\r\n className=\"flex-1 px-2 py-1 rounded-[var(--radius-input)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-sm text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)]\"\r\n >\r\n {ACCESS_LEVEL_OPTIONS.map(opt => (\r\n <option key={opt.level} value={opt.level}>\r\n {t(opt.labelKey)}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n {/* Customize + Remove buttons */}\r\n <div className=\"flex gap-2\">\r\n <button\r\n onClick={() => onOpenCustomizeDrawer(app)}\r\n className=\"btn btn-sm flex items-center justify-center gap-1 flex-1 bg-[var(--color-accent-700)] hover:bg-[var(--color-accent-800)] text-white\"\r\n >\r\n <SlidersHorizontal className=\"w-4 h-4\" />\r\n {t('tenants.applications.customize.button')}\r\n </button>\r\n {onRemoveApplication && (\r\n <button\r\n onClick={() => setRemoveConfirm({ show: true, app, loading: false })}\r\n className=\"btn btn-sm flex items-center justify-center px-2 border border-red-300 text-red-500 hover:bg-red-50 hover:border-red-400 dark:border-red-700 dark:hover:bg-red-900/20\"\r\n title={t('tenants.applications.remove')}\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n }\r\n />\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"space-y-4\">\r\n {/* Header with Add button */}\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('tenants.applications.assigned')}\r\n </h3>\r\n <button\r\n onClick={onOpenAddApplication}\r\n className=\"btn btn-primary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.applications.add')}\r\n </button>\r\n </div>\r\n\r\n {loadingApps ? getLoadingView() : null}\r\n {!loadingApps && (!applications || applications.length === 0) ? getEmptyApplicationsView(t) : null}\r\n\r\n {/* Inherited applications section */}\r\n {!loadingApps && inheritedApps.length > 0 && (\r\n <div className=\"space-y-3\">\r\n <h4 className=\"text-base font-medium text-[var(--text-secondary)]\">\r\n {t('tenants.applications.sectionInherited')}\r\n <span className=\"ml-2 text-sm font-normal text-[var(--text-muted)]\">({inheritedApps.length})</span>\r\n </h4>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6\">\r\n {inheritedApps.map(renderAppCard)}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Direct applications section */}\r\n {!loadingApps && directApps.length > 0 && (\r\n <div className=\"space-y-3\">\r\n <h4 className=\"text-base font-medium text-[var(--text-secondary)]\">\r\n {t('tenants.applications.sectionDirect')}\r\n <span className=\"ml-2 text-sm font-normal text-[var(--text-muted)]\">({directApps.length})</span>\r\n </h4>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6\">\r\n {directApps.map(renderAppCard)}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n {addingApplication && (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\r\n <div className=\"w-full max-w-6xl bg-[var(--bg-card)] rounded-[var(--radius-card)] shadow-xl border border-[var(--border-color)] max-h-[90vh] flex flex-col\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between p-4 border-b border-[var(--border-color)] flex-shrink-0\">\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('tenants.applications.modal.title')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {t('tenants.applications.modal.subtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={onCloseAddApplication}\r\n className=\"p-1 hover:bg-[var(--bg-hover)] rounded-[var(--radius-button)]\"\r\n aria-label={t('common:close', 'Close')}\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n\r\n {/* Three Column Content */}\r\n <div className=\"flex-1 overflow-hidden grid grid-cols-1 md:grid-cols-3 divide-x divide-[var(--border-color)]\">\r\n {/* Left Column - Application Selection */}\r\n <div className=\"flex flex-col p-4 overflow-hidden\">\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <label className=\"text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('tenants.applications.modal.selectApps')}\r\n {selectedAppIds.length > 0 && (\r\n <span className=\"ml-2 px-2 py-0.5 text-xs rounded-full bg-[var(--color-accent-600)] text-white\">\r\n {selectedAppIds.length}\r\n </span>\r\n )}\r\n </label>\r\n <div className=\"flex gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={onSelectAllApps}\r\n className=\"text-xs text-[var(--color-accent-600)] hover:underline\"\r\n >\r\n {t('tenants.applications.modal.selectAll')}\r\n </button>\r\n {selectedAppIds.length > 0 && (\r\n <button\r\n type=\"button\"\r\n onClick={onClearAppSelection}\r\n className=\"text-xs text-[var(--text-muted)] hover:underline\"\r\n >\r\n {t('tenants.applications.modal.clearSelection')}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Search */}\r\n <div className=\"relative mb-3\">\r\n <Search className=\"absolute left-3 top-2.5 w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={appSearchTerm}\r\n onChange={e => setAppSearchTerm(e.target.value)}\r\n placeholder={t('tenants.applications.modal.searchPlaceholder')}\r\n className=\"w-full px-3 py-2 pl-10 rounded-[var(--radius-input)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n\r\n {/* Application List */}\r\n <div className=\"flex-1 overflow-y-auto border border-[var(--border-color)] rounded-[var(--radius-input)]\">\r\n {loadingAvailableApps && (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n )}\r\n {!loadingAvailableApps && availableAppsError && (\r\n <div className=\"flex flex-col items-center justify-center py-8 px-4 text-center\">\r\n {availableAppsError === 'forbidden' ? (\r\n <>\r\n <ShieldX className=\"w-8 h-8 text-red-500 mb-2\" />\r\n <p className=\"text-sm font-medium text-red-500 mb-1\">\r\n {t('tenants.applications.modal.errorForbidden')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">\r\n {t('tenants.applications.modal.errorForbiddenHint')}\r\n </p>\r\n </>\r\n ) : (\r\n <>\r\n <AlertTriangle className=\"w-8 h-8 text-amber-500 mb-2\" />\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.applications.modal.errorGeneric')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">\r\n {t('tenants.applications.modal.errorGenericHint')}\r\n </p>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n {!loadingAvailableApps && !availableAppsError && filteredAvailableApps.length === 0 && (\r\n <div className=\"flex flex-col items-center justify-center py-8 px-4 text-center\">\r\n <Boxes className=\"w-8 h-8 text-[var(--text-tertiary)] mb-2\" />\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {t('tenants.applications.modal.noAvailable')}\r\n </p>\r\n </div>\r\n )}\r\n {!loadingAvailableApps && !availableAppsError && filteredAvailableApps.length > 0 && (\r\n filteredAvailableApps.map(app => {\r\n const isSelected = selectedAppIds.includes(app.id);\r\n return (\r\n <button\r\n key={app.id}\r\n onClick={() => onAppToggle(app.id)}\r\n className={`w-full flex items-center gap-3 px-3 py-2.5 text-left hover:bg-[var(--bg-hover)] border-b border-[var(--border-color)] last:border-b-0 ${\r\n isSelected ? 'bg-[var(--color-accent-500)]/10' : ''\r\n }`}\r\n >\r\n <div\r\n className={`w-5 h-5 rounded border-2 flex items-center justify-center flex-shrink-0 ${\r\n isSelected\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]'\r\n : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {isSelected && <CheckCircle className=\"w-3 h-3 text-white\" />}\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"font-medium text-[var(--text-primary)] truncate\">{app.label}</p>\r\n <p className=\"text-xs text-[var(--text-muted)] truncate\">\r\n {app.code}\r\n </p>\r\n </div>\r\n </button>\r\n );\r\n })\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Middle Column - Module Customization */}\r\n <div className=\"flex flex-col p-4 overflow-hidden\">\r\n <label className=\"text-sm font-medium text-[var(--text-secondary)] mb-3\">\r\n {t('tenants.applications.modal.moduleAccess')}\r\n </label>\r\n <p className=\"text-xs text-[var(--text-muted)] mb-4\">\r\n {t('tenants.applications.modal.moduleAccessHint')}\r\n </p>\r\n\r\n {/* Access Mode Toggle */}\r\n <div className=\"space-y-2 mb-4\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setBulkAccessMode('full')}\r\n className={`w-full flex items-start gap-3 p-3 rounded-[var(--radius-input)] border text-left transition-colors ${\r\n bulkAccessMode === 'full'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]/5'\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div\r\n className={`w-4 h-4 mt-0.5 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${\r\n bulkAccessMode === 'full' ? 'border-[var(--color-accent-600)]' : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {bulkAccessMode === 'full' && <div className=\"w-2 h-2 rounded-full bg-[var(--color-accent-600)]\" />}\r\n </div>\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('tenants.applications.customize.fullAccess')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)] mt-0.5\">\r\n {t('tenants.applications.modal.fullAccessModulesHint')}\r\n </p>\r\n </div>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => {\r\n setBulkAccessMode('custom');\r\n if (selectedAppIds.length > 0 && bulkModules.length === 0) {\r\n onLoadBulkModules(selectedAppIds[0]);\r\n }\r\n }}\r\n className={`w-full flex items-start gap-3 p-3 rounded-[var(--radius-input)] border text-left transition-colors ${\r\n bulkAccessMode === 'custom'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]/5'\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div\r\n className={`w-4 h-4 mt-0.5 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${\r\n bulkAccessMode === 'custom' ? 'border-[var(--color-accent-600)]' : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {bulkAccessMode === 'custom' && <div className=\"w-2 h-2 rounded-full bg-[var(--color-accent-600)]\" />}\r\n </div>\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('tenants.applications.customize.customAccess')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)] mt-0.5\">\r\n {t('tenants.applications.modal.customAccessModulesHint')}\r\n </p>\r\n </div>\r\n </button>\r\n </div>\r\n\r\n {/* Module/Section Tree (only shown in custom mode) */}\r\n {bulkAccessMode === 'custom' && (\r\n <div className=\"flex-1 overflow-hidden flex flex-col\">\r\n {selectedAppIds.length === 0 && (\r\n <p className=\"text-sm text-[var(--text-muted)] text-center py-8\">\r\n {t('tenants.applications.modal.selectAppFirst')}\r\n </p>\r\n )}\r\n {selectedAppIds.length > 0 && loadingBulkModules && (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n )}\r\n {selectedAppIds.length > 0 && !loadingBulkModules && (\r\n <>\r\n {selectedAppIds.length > 1 && (\r\n <p className=\"text-xs text-amber-600 mb-2\">\r\n {t('tenants.applications.modal.multipleAppsHint')}\r\n </p>\r\n )}\r\n <div className=\"flex items-center justify-between mb-2\">\r\n <div className=\"text-xs text-[var(--text-muted)]\">\r\n {bulkStats.assignedModules}/{bulkStats.totalModules}{' '}\r\n {t('tenants.applications.customize.modules')},\r\n {' '}{bulkStats.assignedSections}/{bulkStats.totalSections}{' '}\r\n {t('tenants.applications.customize.sections')}\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={onSelectAllBulkModules}\r\n className=\"text-xs text-[var(--color-accent-600)] hover:underline\"\r\n >\r\n {t('tenants.applications.modal.selectAllModules')}\r\n </button>\r\n {bulkStats.assignedSections > 0 && (\r\n <button\r\n type=\"button\"\r\n onClick={onClearBulkModules}\r\n className=\"text-xs text-[var(--text-muted)] hover:underline\"\r\n >\r\n {t('tenants.applications.modal.clearModules')}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto border border-[var(--border-color)] rounded-[var(--radius-input)]\">\r\n {bulkModules.map(module => {\r\n const checkState = onGetBulkModuleCheckState(module);\r\n const isExpanded = bulkExpandedModules.has(module.id);\r\n const icons = LucideIcons as unknown as Record<string, LucideIcon>;\r\n const ModuleIcon = module.icon ? icons[module.icon] : null;\r\n\r\n return (\r\n <div key={module.id} className=\"border-b border-[var(--border-color)] last:border-b-0\">\r\n <div className=\"flex items-center gap-2 p-2 hover:bg-[var(--bg-hover)]\">\r\n <button\r\n type=\"button\"\r\n onClick={() => onToggleBulkModuleExpand(module.id)}\r\n className=\"p-0.5 rounded hover:bg-[var(--bg-tertiary)]\"\r\n >\r\n {isExpanded ? (\r\n <ChevronDown className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n ) : (\r\n <ChevronRight className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n )}\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => onToggleBulkModule(module.id)}\r\n className={`w-4 h-4 rounded border-2 flex items-center justify-center flex-shrink-0 transition-colors ${getCheckStateClassName(checkState)}`}\r\n >\r\n {checkState === 'checked' && <Check className=\"w-2.5 h-2.5 text-white\" />}\r\n {checkState === 'indeterminate' && <Minus className=\"w-2.5 h-2.5 text-white\" />}\r\n </button>\r\n\r\n <div className=\"p-1 rounded bg-[var(--bg-tertiary)]\">\r\n {ModuleIcon ? (\r\n <ModuleIcon className=\"w-3 h-3 text-[var(--text-muted)]\" />\r\n ) : (\r\n <Layers className=\"w-3 h-3 text-[var(--text-muted)]\" />\r\n )}\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] truncate\">{module.label}</p>\r\n </div>\r\n </div>\r\n\r\n {isExpanded && module.sections.length > 0 && (\r\n <div className=\"pl-10 pb-1 space-y-0.5 bg-[var(--bg-secondary)]\">\r\n {module.sections.map(section => {\r\n const SectionIcon = section.icon ? icons[section.icon] : null;\r\n return (\r\n <div key={section.id} className=\"flex items-center gap-2 p-1.5 rounded hover:bg-[var(--bg-hover)]\">\r\n <button\r\n type=\"button\"\r\n onClick={() => onToggleBulkSection(module.id, section.id)}\r\n className={`w-3.5 h-3.5 rounded border-2 flex items-center justify-center flex-shrink-0 transition-colors ${\r\n section.isAssigned\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-600)]'\r\n }`}\r\n >\r\n {section.isAssigned && <Check className=\"w-2 h-2 text-white\" />}\r\n </button>\r\n\r\n <div className=\"p-0.5 rounded bg-[var(--bg-tertiary)]\">\r\n {SectionIcon ? (\r\n <SectionIcon className=\"w-3 h-3 text-[var(--text-muted)]\" />\r\n ) : (\r\n <Layers className=\"w-3 h-3 text-[var(--text-muted)]\" />\r\n )}\r\n </div>\r\n\r\n <span className=\"text-xs text-[var(--text-primary)] truncate\">{section.label}</span>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n\r\n {bulkModules.length === 0 && (\r\n <p className=\"p-4 text-center text-sm text-[var(--text-muted)]\">\r\n {t('tenants.applications.customize.noModules')}\r\n </p>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Right Column - Access Level */}\r\n <div className=\"flex flex-col p-4\">\r\n <label className=\"text-sm font-medium text-[var(--text-secondary)] mb-3\">\r\n {t('tenants.applications.modal.accessLevel')}\r\n </label>\r\n <p className=\"text-xs text-[var(--text-muted)] mb-4\">\r\n {t('tenants.applications.modal.accessLevelHint')}\r\n </p>\r\n <AccessLevelSelector\r\n selectedAccessLevel={selectedAccessLevel}\r\n setSelectedAccessLevel={setSelectedAccessLevel}\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Footer */}\r\n <div className=\"flex items-center justify-between p-4 border-t border-[var(--border-color)] flex-shrink-0 bg-[var(--bg-secondary)]\">\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {selectedAppIds.length > 0\r\n ? t('tenants.applications.modal.selectedCount', { count: selectedAppIds.length })\r\n : t('tenants.applications.modal.noSelection')}\r\n </p>\r\n <div className=\"flex gap-2\">\r\n <button\r\n onClick={onCloseAddApplication}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] font-medium text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={onAssignApplications}\r\n disabled={selectedAppIds.length === 0 || assigningApps}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {assigningApps ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Plus className=\"w-4 h-4\" />}\r\n {t('tenants.applications.modal.assign')}\r\n {selectedAppIds.length > 0 && ` (${selectedAppIds.length})`}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Customize Access Drawer */}\r\n {customizingApp && (\r\n <ApplicationAccessCustomizeDrawer\r\n application={customizingApp}\r\n tenantId={tenantId}\r\n tenantName={tenantName}\r\n isOpen={showCustomizeDrawer}\r\n onClose={onCloseCustomizeDrawer}\r\n mode={mode}\r\n onSaved={async () => {\r\n await onRefresh();\r\n onCloseCustomizeDrawer();\r\n }}\r\n />\r\n )}\r\n\r\n {/* Remove Application Confirmation */}\r\n {removeConfirm.app && (\r\n <ConfirmModal\r\n isOpen={removeConfirm.show}\r\n title={t('tenants.applications.removeConfirm.title')}\r\n message={\r\n <div className=\"space-y-3 text-left\">\r\n <p>{t('tenants.applications.removeConfirm.message', { name: removeConfirm.app.label })}</p>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {t('tenants.applications.removeConfirm.impactTitle')}\r\n </p>\r\n <ul className=\"text-sm text-[var(--text-secondary)] space-y-1\">\r\n <li>\r\n {t('tenants.applications.removeConfirm.impactModules', {\r\n count: removeConfirm.app.totalModuleCount,\r\n })}\r\n </li>\r\n <li>\r\n {t('tenants.applications.removeConfirm.impactSections', {\r\n count: removeConfirm.app.totalSectionCount,\r\n })}\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n }\r\n variant=\"danger\"\r\n confirmLabel={t('tenants.applications.remove')}\r\n loading={removeConfirm.loading}\r\n onConfirm={async () => {\r\n if (!onRemoveApplication || !removeConfirm.app) return;\r\n setRemoveConfirm(prev => ({ ...prev, loading: true }));\r\n try {\r\n await onRemoveApplication(removeConfirm.app.applicationId);\r\n } finally {\r\n setRemoveConfirm({ show: false, app: null, loading: false });\r\n }\r\n }}\r\n onCancel={() => setRemoveConfirm({ show: false, app: null, loading: false })}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useMemo, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useParams, useNavigate } from 'react-router-dom';\r\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\r\nimport { useTenantDetail } from '@/hooks/useTenantDetail';\r\nimport { useTenantMembers } from '@/hooks/useTenantMembers';\r\nimport { useTenantGroups } from '@/hooks/useTenantGroups';\r\nimport { useTenantApplications } from '@/hooks/useTenantApplications';\r\nimport { useTenantOrganisation } from '@/hooks/useTenantOrganisation';\r\nimport { useTenantRoles } from '@/hooks/useTenantRoles';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { useNavigation } from '@/contexts/NavigationContext';\r\nimport {\r\n Building2,\r\n ArrowLeft,\r\n RefreshCw,\r\n Loader2,\r\n AlertTriangle,\r\n PlayCircle,\r\n PauseCircle,\r\n Archive,\r\n Settings,\r\n} from 'lucide-react';\r\nimport { TenantOverviewTab, TenantMembersTab, TenantGroupsTab, TenantRolesTab, TenantApplicationsTab } from '@/components/platform/administration/tenants';\r\nimport { AccessRequestsListTab } from '@/components/platform/administration/access-requests';\r\nimport { useAccessRequests } from '@/hooks/useAccessRequests';\r\nimport { ConfirmModal, type ConfirmVariant } from '@/components/ui/ConfirmModal';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { adminApi, type TenantStatus } from '@/services/api/adminApi';\r\n\r\nconst VALID_TABS = ['overview', 'members', 'groups', 'roles', 'applications', 'requests'] as const;\r\ntype TabType = typeof VALID_TABS[number];\r\n\r\nconst STATUS_CONFIG: Record<TenantStatus, { color: string; bgColor: string; borderColor: string }> = {\r\n Pending: {\r\n color: 'text-[var(--info-text)]',\r\n bgColor: 'bg-[var(--info-bg)]',\r\n borderColor: 'border-[var(--info-border)]'\r\n },\r\n Active: {\r\n color: 'text-[var(--success-text)]',\r\n bgColor: 'bg-[var(--success-bg)]',\r\n borderColor: 'border-[var(--success-border)]'\r\n },\r\n Suspended: {\r\n color: 'text-[var(--warning-text)]',\r\n bgColor: 'bg-[var(--warning-bg)]',\r\n borderColor: 'border-[var(--warning-border)]'\r\n },\r\n Archived: {\r\n color: 'text-[var(--text-tertiary)]',\r\n bgColor: 'bg-[var(--bg-tertiary)]',\r\n borderColor: 'border-[var(--border-color)]'\r\n }\r\n};\r\n\r\nexport function TenantDetailPage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const { id: tenantId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const { activeTab, setActiveTab } = useTabNavigation<TabType>('overview', VALID_TABS);\r\n\r\n const { refreshTenants, currentTenant } = useTenant();\r\n const { refreshMenu } = useNavigation();\r\n\r\n // Hooks for managing tenant data\r\n const tenantDetail = useTenantDetail(tenantId);\r\n const tenantMembers = useTenantMembers(tenantId);\r\n const tenantGroups = useTenantGroups(tenantId);\r\n const handleApplicationsChanged = useCallback(() => {\r\n // Refresh menu if we're editing the current tenant's applications\r\n if (currentTenant && tenantId === currentTenant.id) {\r\n refreshMenu();\r\n }\r\n }, [currentTenant, tenantId, refreshMenu]);\r\n\r\n const tenantAppOptions = useMemo(() => ({\r\n onApplicationsChanged: handleApplicationsChanged,\r\n }), [handleApplicationsChanged]);\r\n\r\n const tenantApplications = useTenantApplications(tenantId, tenantAppOptions);\r\n const tenantRoles = useTenantRoles(tenantId);\r\n const tenantOrganisation = useTenantOrganisation(tenantId);\r\n const accessRequests = useAccessRequests('tenant', tenantId!);\r\n\r\n // Minimal state needed in page\r\n const [actionLoading, setActionLoading] = useState<string | null>(null);\r\n const [confirmModal, setConfirmModal] = useState<{\r\n show: boolean;\r\n title: string;\r\n message: string;\r\n variant: ConfirmVariant;\r\n onConfirm: () => void;\r\n }>({\r\n show: false,\r\n title: '',\r\n message: '',\r\n variant: 'warning',\r\n onConfirm: () => {},\r\n });\r\n\r\n // Track which tabs have been loaded to avoid re-fetching\r\n const [loadedTabs, setLoadedTabs] = useState<Set<string>>(new Set());\r\n\r\n // Load tenant detail on mount\r\n useEffect(() => {\r\n if (!tenantId) {\r\n navigate('/administration/tenants');\r\n return;\r\n }\r\n tenantDetail.loadTenant();\r\n }, [tenantId]);\r\n\r\n // Lazy load tab data only when the tab is first selected\r\n useEffect(() => {\r\n if (!tenantId || loadedTabs.has(activeTab)) return;\r\n\r\n const loadTabData = async () => {\r\n switch (activeTab) {\r\n case 'overview':\r\n // Overview uses tenant detail (already loaded) + members for owner\r\n if (!loadedTabs.has('members')) {\r\n await tenantMembers.loadMembers();\r\n setLoadedTabs(prev => new Set(prev).add('members'));\r\n }\r\n break;\r\n case 'members':\r\n await tenantMembers.loadMembers();\r\n break;\r\n case 'groups':\r\n await tenantGroups.loadGroups();\r\n break;\r\n case 'roles':\r\n await tenantRoles.loadRoles();\r\n break;\r\n case 'applications':\r\n await tenantApplications.loadApplications();\r\n break;\r\n case 'requests':\r\n await accessRequests.loadRequests();\r\n break;\r\n }\r\n setLoadedTabs(prev => new Set(prev).add(activeTab));\r\n };\r\n\r\n loadTabData();\r\n }, [activeTab, tenantId]);\r\n\r\n const handleStatusChange = async (newStatus: TenantStatus) => {\r\n if (!tenantDetail.tenant) return;\r\n\r\n const currentStatus = tenantDetail.tenant.status;\r\n if (currentStatus === newStatus) return;\r\n\r\n const statusMessages: Record<TenantStatus, string> = {\r\n Active: t('admin:tenants.confirmActivate'),\r\n Suspended: t('admin:tenants.confirmSuspend'),\r\n Archived: t('admin:tenants.confirmArchive'),\r\n Pending: t('admin:tenants.confirmPending'),\r\n };\r\n\r\n setConfirmModal({\r\n show: true,\r\n title: t('common:confirm'),\r\n message: statusMessages[newStatus],\r\n variant: newStatus === 'Archived' ? 'danger' : 'warning',\r\n onConfirm: async () => {\r\n setActionLoading(newStatus);\r\n try {\r\n if (newStatus === 'Active') {\r\n await adminApi.tenants.activate(tenantDetail.tenant!.id);\r\n } else if (newStatus === 'Suspended') {\r\n await adminApi.tenants.suspend(tenantDetail.tenant!.id);\r\n } else if (newStatus === 'Archived') {\r\n await adminApi.tenants.archive(tenantDetail.tenant!.id);\r\n }\r\n await refreshTenants();\r\n await tenantDetail.loadTenant();\r\n } catch (error) {\r\n console.error('Failed to update tenant status:', error);\r\n } finally {\r\n setActionLoading(null);\r\n setConfirmModal({ ...confirmModal, show: false });\r\n }\r\n },\r\n });\r\n };\r\n\r\n const handleRefresh = async () => {\r\n setActionLoading('refresh');\r\n try {\r\n const promises: Promise<void>[] = [tenantDetail.loadTenant()];\r\n switch (activeTab) {\r\n case 'overview':\r\n promises.push(tenantMembers.loadMembers());\r\n break;\r\n case 'members':\r\n promises.push(tenantMembers.loadMembers());\r\n break;\r\n case 'groups':\r\n promises.push(tenantGroups.loadGroups());\r\n break;\r\n case 'roles':\r\n promises.push(tenantRoles.loadRoles());\r\n break;\r\n case 'applications':\r\n promises.push(tenantApplications.loadApplications());\r\n break;\r\n case 'requests':\r\n promises.push(accessRequests.loadRequests());\r\n break;\r\n }\r\n await Promise.all(promises);\r\n } finally {\r\n setActionLoading(null);\r\n }\r\n };\r\n\r\n if (tenantDetail.loading) {\r\n return (\r\n <div className=\"p-6 flex items-center justify-center min-h-screen\">\r\n <div className=\"text-center\">\r\n <Loader2 className=\"w-8 h-8 animate-spin mx-auto mb-2 text-[var(--text-secondary)]\" />\r\n <p className=\"text-[var(--text-secondary)]\">{t('common:loading')}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!tenantDetail.tenant) {\r\n return (\r\n <div className=\"p-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n ]}\r\n />\r\n <div className=\"mt-4 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{tenantDetail.error || t('admin:tenants.notFound')}</span>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const tenant = tenantDetail.tenant;\r\n const statusConfig = STATUS_CONFIG[tenant.status];\r\n const getStatusIcon = (status: TenantStatus) => {\r\n switch (status) {\r\n case 'Active': return <PlayCircle className=\"w-4 h-4\" />;\r\n case 'Suspended': return <PauseCircle className=\"w-4 h-4\" />;\r\n case 'Archived': return <Archive className=\"w-4 h-4\" />;\r\n default: return <Building2 className=\"w-4 h-4\" />;\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n { label: tenant.name }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/tenants')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div className=\"flex-1\">\r\n <h1 className=\"text-xl sm:text-2xl font-bold text-[var(--text-primary)]\">{tenant.name}</h1>\r\n <p className=\"text-sm sm:text-base text-[var(--text-secondary)]\">{tenant.slug}</p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className={`px-3 py-1 rounded-[var(--radius-badge)] text-sm flex items-center gap-2 ${statusConfig.bgColor} ${statusConfig.color} border ${statusConfig.borderColor}`}>\r\n {getStatusIcon(tenant.status)}\r\n {t(`admin:tenants.status.${tenant.status.toLowerCase()}`)}\r\n </span>\r\n <span className={`px-3 py-1 rounded-[var(--radius-badge)] text-sm ${\r\n tenant.type === 'Business'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--accent-bg)] text-[var(--accent-text)]'\r\n }`}>\r\n {t(`admin:tenants.type.${tenant.type.toLowerCase()}`)}\r\n </span>\r\n {tenant.status !== 'Active' && tenant.status !== 'Archived' && (\r\n <button\r\n onClick={() => handleStatusChange('Active')}\r\n disabled={actionLoading !== null}\r\n className=\"flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--success-dot)] text-white hover:opacity-90 transition-colors disabled:opacity-50\"\r\n >\r\n {actionLoading === 'Active' ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <PlayCircle className=\"w-4 h-4\" />}\r\n {t('admin:tenants.actions.activate')}\r\n </button>\r\n )}\r\n {tenant.status === 'Active' && (\r\n <button\r\n onClick={() => handleStatusChange('Suspended')}\r\n disabled={actionLoading !== null}\r\n className=\"flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--warning-dot)] text-white hover:opacity-90 transition-colors disabled:opacity-50\"\r\n >\r\n {actionLoading === 'Suspended' ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <PauseCircle className=\"w-4 h-4\" />}\r\n {t('admin:tenants.actions.suspend')}\r\n </button>\r\n )}\r\n <button\r\n onClick={() => navigate(`/administration/tenants/${tenantId}/settings`)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n title={t('admin:tenants.settings.title')}\r\n >\r\n <Settings className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <button\r\n onClick={handleRefresh}\r\n disabled={actionLoading === 'refresh'}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors disabled:opacity-50\"\r\n title={t('common:refresh')}\r\n >\r\n <RefreshCw className={`w-5 h-5 ${actionLoading === 'refresh' ? 'animate-spin' : ''}`} />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Error */}\r\n {tenantDetail.error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{tenantDetail.error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Tab Navigation */}\r\n <div className=\"border-b border-[var(--border-color)]\">\r\n <div className=\"flex gap-1 -mb-px\">\r\n {VALID_TABS.map(tab => (\r\n <button\r\n key={tab}\r\n onClick={() => setActiveTab(tab)}\r\n className={`px-4 py-2 border-b-2 transition-colors ${\r\n activeTab === tab\r\n ? 'border-[var(--primary-color)] text-[var(--primary-color)]'\r\n : 'border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n >\r\n {t(`admin:tenants.tabs.${tab}`)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Tab Content */}\r\n <div>\r\n {activeTab === 'overview' && (\r\n <TenantOverviewTab\r\n tenant={tenant}\r\n tenantOwner={(() => {\r\n const owner = tenantMembers.members?.find(m => m.isOwner);\r\n return owner ? { userDisplayName: owner.userDisplayName ?? undefined, userEmail: owner.userEmail ?? undefined } : null;\r\n })()}\r\n statusConfig={STATUS_CONFIG}\r\n actionLoading={actionLoading}\r\n onRefresh={handleRefresh}\r\n onEditClick={tenantDetail.openEditGeneralInfo}\r\n onStatusChange={(action) => {\r\n const statusMap: Record<string, TenantStatus> = {\r\n activate: 'Active',\r\n suspend: 'Suspended',\r\n archive: 'Archived'\r\n };\r\n handleStatusChange(statusMap[action]);\r\n }}\r\n onMembersTabClick={() => setActiveTab('members')}\r\n onLinkOrgClick={tenantOrganisation.openLinkOrgModal}\r\n onUnlinkOrg={tenantOrganisation.handleUnlinkOrganisation}\r\n />\r\n )}\r\n\r\n {activeTab === 'members' && (\r\n <TenantMembersTab\r\n tenantId={tenantId!}\r\n members={tenantMembers.members}\r\n loadingMembers={tenantMembers.loadingMembers}\r\n actionLoading={actionLoading}\r\n onRefresh={tenantMembers.loadMembers}\r\n onRemoveMember={tenantMembers.handleRemoveMember}\r\n />\r\n )}\r\n\r\n {activeTab === 'groups' && (\r\n <TenantGroupsTab\r\n tenantId={tenantId!}\r\n groups={tenantGroups.groups}\r\n loadingGroups={tenantGroups.loadingGroups}\r\n removingGroupId={tenantGroups.removingGroupId}\r\n onRefresh={tenantGroups.loadGroups}\r\n onRemoveGroup={tenantGroups.handleRemoveGroup}\r\n />\r\n )}\r\n\r\n {activeTab === 'roles' && (\r\n <TenantRolesTab\r\n roles={tenantRoles.roles}\r\n loadingRoles={tenantRoles.loadingRoles}\r\n />\r\n )}\r\n\r\n {activeTab === 'applications' && (\r\n <TenantApplicationsTab\r\n tenantId={tenantId!}\r\n tenantName={tenant.name}\r\n applications={tenantApplications.applications}\r\n loadingApps={tenantApplications.loadingApps}\r\n actionLoading={actionLoading}\r\n onRefresh={tenantApplications.loadApplications}\r\n onUpdateAccessLevel={tenantApplications.handleUpdateAccessLevel}\r\n // Add application modal state\r\n addingApplication={tenantApplications.addingApplication}\r\n availableAppsError={tenantApplications.availableAppsError}\r\n filteredAvailableApps={tenantApplications.filteredAvailableApps}\r\n loadingAvailableApps={tenantApplications.loadingAvailableApps}\r\n selectedAppIds={tenantApplications.selectedAppIds}\r\n assigningApps={tenantApplications.assigningApps}\r\n appSearchTerm={tenantApplications.appSearchTerm}\r\n selectedAccessLevel={tenantApplications.selectedAccessLevel}\r\n bulkAccessMode={tenantApplications.bulkAccessMode}\r\n bulkModules={tenantApplications.bulkModules}\r\n bulkExpandedModules={tenantApplications.bulkExpandedModules}\r\n loadingBulkModules={tenantApplications.loadingBulkModules}\r\n // Customize drawer state\r\n showCustomizeDrawer={tenantApplications.showCustomizeDrawer}\r\n customizingApp={tenantApplications.customizingApp}\r\n // Actions\r\n onOpenAddApplication={tenantApplications.loadAvailableApps}\r\n onCloseAddApplication={() => {\r\n tenantApplications.setAddingApplication(false);\r\n tenantApplications.setSelectedAppIds([]);\r\n tenantApplications.setAppSearchTerm('');\r\n tenantApplications.setSelectedAccessLevel('FullAccess');\r\n tenantApplications.setBulkAccessMode('full');\r\n tenantApplications.setBulkModules([]);\r\n tenantApplications.setBulkExpandedModules(new Set());\r\n }}\r\n onAssignApplications={tenantApplications.handleAssignApplications}\r\n onAppToggle={tenantApplications.handleAppToggle}\r\n onSelectAllApps={tenantApplications.selectAllFilteredApps}\r\n onClearAppSelection={tenantApplications.clearAppSelection}\r\n onOpenCustomizeDrawer={tenantApplications.openCustomizeDrawer}\r\n onCloseCustomizeDrawer={tenantApplications.closeCustomizeDrawer}\r\n // Module handlers\r\n onLoadBulkModules={tenantApplications.loadBulkModulesForApp}\r\n onToggleBulkModuleExpand={tenantApplications.toggleBulkModuleExpand}\r\n onToggleBulkModule={tenantApplications.toggleBulkModule}\r\n onToggleBulkSection={tenantApplications.toggleBulkSection}\r\n onGetBulkModuleCheckState={tenantApplications.getBulkModuleCheckState}\r\n onGetBulkStats={tenantApplications.getBulkStats}\r\n onSelectAllBulkModules={tenantApplications.selectAllBulkModules}\r\n onClearBulkModules={tenantApplications.clearBulkModules}\r\n // Setters\r\n setAppSearchTerm={tenantApplications.setAppSearchTerm}\r\n setSelectedAccessLevel={tenantApplications.setSelectedAccessLevel}\r\n setBulkAccessMode={tenantApplications.setBulkAccessMode}\r\n />\r\n )}\r\n\r\n {activeTab === 'requests' && (\r\n <AccessRequestsListTab\r\n requests={accessRequests.requests}\r\n loading={accessRequests.loading}\r\n onReload={() => accessRequests.loadRequests()}\r\n />\r\n )}\r\n </div>\r\n\r\n {/* Organisation Linking Modal - handled by useTenantOrganisation hook */}\r\n {tenantOrganisation.showLinkOrgModal && (\r\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] p-6 max-w-md w-full mx-4\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)] mb-4\">\r\n {t('admin:tenants.organisation.linkTitle')}\r\n </h2>\r\n <p className=\"text-[var(--text-secondary)] mb-4\">\r\n {t('admin:tenants.organisation.linkDescription')}\r\n </p>\r\n <div className=\"flex gap-2 justify-end\">\r\n <button\r\n onClick={tenantOrganisation.closeLinkOrgModal}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={() => {\r\n tenantOrganisation.openLinkOrgModal();\r\n tenantDetail.loadTenant();\r\n }}\r\n disabled={tenantOrganisation.linkingOrg}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--primary-color)] text-white hover:opacity-90 disabled:opacity-50\"\r\n >\r\n {tenantOrganisation.linkingOrg ? t('common:loading') : t('admin:tenants.organisation.link')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Confirm Modal */}\r\n {confirmModal.show && (\r\n <ConfirmModal\r\n title={confirmModal.title}\r\n message={confirmModal.message}\r\n variant={confirmModal.variant}\r\n isOpen={confirmModal.show}\r\n onConfirm={() => {\r\n confirmModal.onConfirm();\r\n }}\r\n onCancel={() => {\r\n setConfirmModal({ ...confirmModal, show: false });\r\n }}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate, useSearchParams } from 'react-router-dom';\r\nimport {\r\n ArrowLeft,\r\n Building2,\r\n User,\r\n Building,\r\n Loader2,\r\n AlertCircle,\r\n AlertTriangle,\r\n Check,\r\n Hash,\r\n FileText,\r\n UserPlus,\r\n Info,\r\n MapPin,\r\n Phone,\r\n Mail,\r\n Globe,\r\n FileCheck,\r\n Zap,\r\n Search,\r\n Link,\r\n} from 'lucide-react';\r\nimport {\r\n adminApi,\r\n type CreateTenantB2CRequest,\r\n type CreateTenantB2BRequest,\r\n type CreateOrganisationRequest,\r\n type BusinessIdentifierType,\r\n type TenantType,\r\n type OrganisationListItemDto,\r\n} from '@/services/api/adminApi';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\n\r\n// Business Identifier Type options\r\nconst BUSINESS_IDENTIFIER_TYPES: { value: BusinessIdentifierType; label: string; country: string }[] = [\r\n { value: 'UID_CHE', label: 'CHE/IDE (Suisse)', country: 'CH' },\r\n { value: 'VAT', label: 'VAT (EU)', country: 'EU' },\r\n { value: 'SIRET', label: 'SIRET (France)', country: 'FR' },\r\n { value: 'SIREN', label: 'SIREN (France)', country: 'FR' },\r\n { value: 'KVK', label: 'KVK (Netherlands)', country: 'NL' },\r\n { value: 'CRN', label: 'CRN (UK)', country: 'GB' },\r\n { value: 'ABN', label: 'ABN (Australia)', country: 'AU' },\r\n { value: 'Other', label: 'Other', country: '' },\r\n];\r\n\r\ntype OrganisationMode = 'none' | 'create' | 'existing';\r\n\r\nfunction getTenantTypeFromUrl(typeFromUrl: string | null): TenantType {\r\n return typeFromUrl === 'b2b' ? 'Business' : 'Personal';\r\n}\r\n\r\nfunction applyConfigTypeRestrictions(config: { enableB2B: boolean; enableB2C: boolean }): TenantType {\r\n if (!config.enableB2C) return 'Business';\r\n if (!config.enableB2B) return 'Personal';\r\n return 'Personal';\r\n}\r\n\r\nfunction buildOrganisationRequest(\r\n orgName: string,\r\n orgLegalName: string,\r\n orgCountryCode: string,\r\n orgBusinessIdType: BusinessIdentifierType,\r\n orgBusinessId: string,\r\n orgVatNumber: string,\r\n addrStreet: string,\r\n addrStreet2: string,\r\n addrPostalCode: string,\r\n addrCity: string,\r\n addrState: string,\r\n addrCountry: string,\r\n addrCountryCode: string,\r\n orgPhone: string,\r\n orgEmail: string,\r\n orgWebsite: string,\r\n isFromRegistry: boolean = false\r\n): CreateOrganisationRequest {\r\n return {\r\n name: orgName,\r\n legalName: orgLegalName || undefined,\r\n countryCode: orgCountryCode,\r\n businessIdentifierType: orgBusinessIdType,\r\n businessIdentifier: orgBusinessId,\r\n vatNumber: orgVatNumber || undefined,\r\n address: {\r\n street: addrStreet,\r\n street2: addrStreet2 || undefined,\r\n postalCode: addrPostalCode,\r\n city: addrCity,\r\n state: addrState || undefined,\r\n country: addrCountry,\r\n countryCode: addrCountryCode,\r\n },\r\n phone: orgPhone || undefined,\r\n email: orgEmail || undefined,\r\n website: orgWebsite || undefined,\r\n isFromRegistry: isFromRegistry || undefined,\r\n };\r\n}\r\n\r\nexport function TenantCreatePage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const navigate = useNavigate();\r\n const [searchParams] = useSearchParams();\r\n const { refreshTenants } = useTenant();\r\n const typeFromUrl = searchParams.get('type');\r\n const organisationIdFromUrl = searchParams.get('organisationId');\r\n\r\n const [enableB2B, setEnableB2B] = useState<boolean | null>(null);\r\n const [enableB2C, setEnableB2C] = useState<boolean | null>(null);\r\n const [tenantType, setTenantType] = useState<TenantType>(getTenantTypeFromUrl(typeFromUrl));\r\n const [organisationMode, setOrganisationMode] = useState<OrganisationMode>(organisationIdFromUrl ? 'existing' : 'none');\r\n const [loading, setLoading] = useState(false);\r\n const [configLoading, setConfigLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [lookupLoading, setLookupLoading] = useState(false);\r\n const [lookupError, setLookupError] = useState<string | null>(null);\r\n const [lookupSuccess, setLookupSuccess] = useState(false);\r\n const [isFromRegistry, setIsFromRegistry] = useState(false);\r\n\r\n // Existing organisation selection state\r\n const [selectedOrganisation, setSelectedOrganisation] = useState<OrganisationListItemDto | null>(null);\r\n const [availableOrganisations, setAvailableOrganisations] = useState<OrganisationListItemDto[]>([]);\r\n const [orgSearchQuery, setOrgSearchQuery] = useState('');\r\n const [orgSearchLoading, setOrgSearchLoading] = useState(false);\r\n\r\n // Load multitenant config on mount\r\n useEffect(() => {\r\n const loadConfig = async () => {\r\n try {\r\n const config = await adminApi.tenants.getConfig();\r\n setEnableB2B(config.enableB2B);\r\n setEnableB2C(config.enableB2C);\r\n if (!organisationIdFromUrl) {\r\n setTenantType(applyConfigTypeRestrictions(config));\r\n }\r\n } catch (err) {\r\n console.error('Failed to load tenant config:', err);\r\n // Default to both enabled if config fails\r\n setEnableB2B(true);\r\n setEnableB2C(true);\r\n } finally {\r\n setConfigLoading(false);\r\n }\r\n };\r\n loadConfig();\r\n }, []);\r\n\r\n // Load organisation from URL param\r\n useEffect(() => {\r\n if (!organisationIdFromUrl) return;\r\n const loadOrganisation = async () => {\r\n try {\r\n const org = await adminApi.organisations.getById(organisationIdFromUrl);\r\n setSelectedOrganisation({\r\n id: org.id,\r\n name: org.name,\r\n legalName: org.legalName,\r\n countryCode: org.countryCode,\r\n businessIdentifier: org.businessIdentifier,\r\n businessIdentifierType: org.businessIdentifierType as OrganisationListItemDto['businessIdentifierType'],\r\n verificationStatus: org.verificationStatus as OrganisationListItemDto['verificationStatus'],\r\n verifiedAt: org.verifiedAt,\r\n createdAt: org.createdAt,\r\n });\r\n // Pre-fill tenant name from org name\r\n if (!name) {\r\n handleNameChange(org.name);\r\n }\r\n } catch (err) {\r\n console.error('Failed to load organisation:', err);\r\n }\r\n };\r\n loadOrganisation();\r\n }, [organisationIdFromUrl]);\r\n\r\n // Search available organisations\r\n useEffect(() => {\r\n if (organisationMode !== 'existing') return;\r\n const searchOrganisations = async () => {\r\n setOrgSearchLoading(true);\r\n try {\r\n const results = await adminApi.organisations.getAvailable(orgSearchQuery || undefined);\r\n setAvailableOrganisations(results);\r\n } catch (err) {\r\n console.error('Failed to search organisations:', err);\r\n } finally {\r\n setOrgSearchLoading(false);\r\n }\r\n };\r\n const debounce = setTimeout(searchOrganisations, 300);\r\n return () => clearTimeout(debounce);\r\n }, [organisationMode, orgSearchQuery]);\r\n\r\n // Tenant fields\r\n const [name, setName] = useState('');\r\n const [slug, setSlug] = useState('');\r\n const [description, setDescription] = useState('');\r\n\r\n // Organisation fields (B2B only)\r\n const [orgName, setOrgName] = useState('');\r\n const [orgLegalName, setOrgLegalName] = useState('');\r\n const [orgCountryCode, setOrgCountryCode] = useState('CH');\r\n const [orgBusinessIdType, setOrgBusinessIdType] = useState<BusinessIdentifierType>('UID_CHE');\r\n const [orgBusinessId, setOrgBusinessId] = useState('CHE-'); // Pre-fill for Switzerland\r\n\r\n // Format CHE number: CHE-XXX.XXX.XXX\r\n const formatCheNumber = (value: string): string => {\r\n // Remove all non-alphanumeric characters except CHE prefix\r\n const cleaned = value.toUpperCase().replace(/[^A-Z0-9]/g, '');\r\n\r\n // Extract digits after CHE\r\n let digits = cleaned.startsWith('CHE') ? cleaned.slice(3) : cleaned.replace(/[^0-9]/g, '');\r\n digits = digits.slice(0, 9); // Max 9 digits\r\n\r\n // Format as CHE-XXX.XXX.XXX\r\n if (digits.length === 0) return 'CHE-';\r\n if (digits.length <= 3) return `CHE-${digits}`;\r\n if (digits.length <= 6) return `CHE-${digits.slice(0, 3)}.${digits.slice(3)}`;\r\n return `CHE-${digits.slice(0, 3)}.${digits.slice(3, 6)}.${digits.slice(6)}`;\r\n };\r\n\r\n const handleBusinessIdChange = (value: string) => {\r\n // Only format for CHE type\r\n if (orgBusinessIdType === 'UID_CHE' && orgCountryCode === 'CH') {\r\n setOrgBusinessId(formatCheNumber(value));\r\n } else {\r\n setOrgBusinessId(value);\r\n }\r\n setIsFromRegistry(false);\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n };\r\n\r\n // Update business ID when country or type changes\r\n useEffect(() => {\r\n if (orgCountryCode === 'CH' && orgBusinessIdType === 'UID_CHE') {\r\n // If empty or just \"CHE-\", keep the prefix\r\n if (!orgBusinessId || orgBusinessId === 'CHE-') {\r\n setOrgBusinessId('CHE-');\r\n } else {\r\n // Re-format existing value\r\n setOrgBusinessId(formatCheNumber(orgBusinessId));\r\n }\r\n }\r\n }, [orgCountryCode, orgBusinessIdType]);\r\n const [orgVatNumber, setOrgVatNumber] = useState('');\r\n const [orgPhone, setOrgPhone] = useState('');\r\n const [orgEmail, setOrgEmail] = useState('');\r\n const [orgWebsite, setOrgWebsite] = useState('');\r\n\r\n // Address fields\r\n const [addrStreet, setAddrStreet] = useState('');\r\n const [addrStreet2, setAddrStreet2] = useState('');\r\n const [addrPostalCode, setAddrPostalCode] = useState('');\r\n const [addrCity, setAddrCity] = useState('');\r\n const [addrState, setAddrState] = useState('');\r\n const [addrCountry, setAddrCountry] = useState('Switzerland');\r\n const [addrCountryCode, setAddrCountryCode] = useState('CH');\r\n\r\n const generateSlug = (value: string) => {\r\n return value\r\n .toLowerCase()\r\n .normalize('NFD')\r\n .replace(/[\\u0300-\\u036f]/g, '')\r\n .replace(/[^a-z0-9]+/g, '-')\r\n .replace(/(^-)|(-$)/g, '')\r\n .substring(0, 50);\r\n };\r\n\r\n const handleNameChange = (value: string) => {\r\n setName(value);\r\n if (!slug || slug === generateSlug(name)) {\r\n setSlug(generateSlug(value));\r\n }\r\n };\r\n\r\n const validateLookupInput = (): boolean => {\r\n const cleanedId = orgBusinessId.replace(/[^0-9]/g, '');\r\n if (!orgBusinessId || cleanedId.length < 9 || !orgCountryCode) {\r\n setLookupError(t('admin:tenants.create.organisation.lookupIncomplete'));\r\n return false;\r\n }\r\n return true;\r\n };\r\n\r\n const fillOrganisationFields = (result: Awaited<ReturnType<typeof adminApi.organisations.lookup>>) => {\r\n if (result.name) {\r\n setOrgName(result.name);\r\n if (!name) {\r\n handleNameChange(result.name);\r\n }\r\n }\r\n if (result.legalName) setOrgLegalName(result.legalName);\r\n if (result.vatNumber) setOrgVatNumber(result.vatNumber);\r\n if (result.phone) setOrgPhone(result.phone);\r\n if (result.email) setOrgEmail(result.email);\r\n if (result.website) setOrgWebsite(result.website);\r\n };\r\n\r\n const fillAddressFields = (result: Awaited<ReturnType<typeof adminApi.organisations.lookup>>) => {\r\n if (result.street) setAddrStreet(result.street);\r\n if (result.street2) setAddrStreet2(result.street2);\r\n if (result.postalCode) setAddrPostalCode(result.postalCode);\r\n if (result.city) setAddrCity(result.city);\r\n if (result.state) setAddrState(result.state);\r\n if (result.country) setAddrCountry(result.country);\r\n if (result.countryCode) setAddrCountryCode(result.countryCode);\r\n };\r\n\r\n const mapLookupError = (errorMessage: string): string => {\r\n if (errorMessage.includes('404') || errorMessage.includes('not found')) {\r\n return t('admin:tenants.create.organisation.lookupFailed');\r\n }\r\n if (errorMessage.includes('credentials') || errorMessage.includes('401')) {\r\n return t('admin:tenants.create.organisation.lookupAuthError');\r\n }\r\n return t('admin:tenants.create.organisation.lookupFailed');\r\n };\r\n\r\n const handleLookup = async () => {\r\n if (!validateLookupInput()) return;\r\n\r\n setLookupLoading(true);\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n\r\n try {\r\n const result = await adminApi.organisations.lookup(orgCountryCode, orgBusinessId);\r\n\r\n fillOrganisationFields(result);\r\n fillAddressFields(result);\r\n setIsFromRegistry(true);\r\n\r\n setLookupSuccess(true);\r\n setTimeout(() => setLookupSuccess(false), 3000);\r\n } catch (err: unknown) {\r\n console.error('[Zefix Lookup] Failed:', err);\r\n const errorMessage = err instanceof Error ? err.message : '';\r\n setLookupError(mapLookupError(errorMessage));\r\n } finally {\r\n setLookupLoading(false);\r\n }\r\n };\r\n\r\n const submitB2CTenant = async () => {\r\n const request: CreateTenantB2CRequest = {\r\n name,\r\n slug: slug || generateSlug(name),\r\n description: description || undefined,\r\n };\r\n const result = await adminApi.tenants.createB2C(request);\r\n await refreshTenants();\r\n navigate(`/administration/tenants/${result.id}`);\r\n };\r\n\r\n const submitB2BTenant = async () => {\r\n let request: CreateTenantB2BRequest;\r\n\r\n if (organisationMode === 'existing' && selectedOrganisation) {\r\n request = {\r\n name,\r\n slug: slug || generateSlug(name),\r\n description: description || undefined,\r\n organisationId: selectedOrganisation.id,\r\n };\r\n } else if (organisationMode === 'create') {\r\n const organisation = buildOrganisationRequest(\r\n orgName, orgLegalName, orgCountryCode, orgBusinessIdType, orgBusinessId,\r\n orgVatNumber, addrStreet, addrStreet2, addrPostalCode, addrCity, addrState,\r\n addrCountry, addrCountryCode, orgPhone, orgEmail, orgWebsite, isFromRegistry\r\n );\r\n request = {\r\n name,\r\n slug: slug || generateSlug(name),\r\n description: description || undefined,\r\n organisation,\r\n };\r\n } else {\r\n request = {\r\n name,\r\n slug: slug || generateSlug(name),\r\n description: description || undefined,\r\n };\r\n }\r\n\r\n const result = await adminApi.tenants.createB2B(request);\r\n await refreshTenants();\r\n navigate(`/administration/tenants/${result.id}`);\r\n };\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setError(null);\r\n setLoading(true);\r\n\r\n try {\r\n if (tenantType === 'Personal') {\r\n await submitB2CTenant();\r\n } else {\r\n await submitB2BTenant();\r\n }\r\n } catch (err: unknown) {\r\n console.error('Failed to create tenant:', err);\r\n const errorMessage = err instanceof Error ? err.message : t('admin:tenants.errors.createFailed');\r\n setError(errorMessage);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n const getOrganisationFormValidity = (): boolean => {\r\n if (organisationMode === 'existing') return !!selectedOrganisation;\r\n if (organisationMode !== 'create') return true;\r\n return !!(orgName && orgCountryCode && orgBusinessIdType && orgBusinessId &&\r\n addrStreet && addrPostalCode && addrCity && addrCountry && addrCountryCode);\r\n };\r\n\r\n const getB2BFormValidity = (): boolean => {\r\n if (tenantType !== 'Business') return true;\r\n return !!(name && getOrganisationFormValidity());\r\n };\r\n\r\n const isFormValid = !!(name && getB2BFormValidity());\r\n\r\n return (\r\n <div className=\"container mx-auto px-4 py-6 max-w-3xl\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('tenants.create.title') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4 mb-6\">\r\n <button\r\n onClick={() => navigate('/administration/tenants')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-secondary)]\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5\" />\r\n </button>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('admin:tenants.create.title')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.subtitle')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Error */}\r\n {error && (\r\n <div className=\"mb-6 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertCircle className=\"w-5 h-5 flex-shrink-0\" />\r\n <span>{error}</span>\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={() => setError(null)}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:dismiss')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n {/* Type Selection */}\r\n <div className=\"card p-6 mb-6\">\r\n <h2 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('admin:tenants.create.selectType')}\r\n </h2>\r\n\r\n {/* B2C Disabled Notice */}\r\n {!configLoading && enableB2C === false && (\r\n <div className=\"mb-4 p-3 rounded-[var(--radius-card)] bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--info-text)]\">\r\n <Info className=\"w-4 h-4 flex-shrink-0\" />\r\n <span className=\"text-sm\">{t('admin:tenants.create.b2cDisabledNotice')}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* B2B Disabled Notice */}\r\n {!configLoading && enableB2B === false && (\r\n <div className=\"mb-4 p-3 rounded-[var(--radius-card)] bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--info-text)]\">\r\n <Info className=\"w-4 h-4 flex-shrink-0\" />\r\n <span className=\"text-sm\">{t('admin:tenants.create.b2bDisabledNotice')}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {configLoading ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--text-tertiary)]\" />\r\n </div>\r\n ) : (\r\n <div className={`grid gap-4 ${enableB2C && enableB2B ? 'grid-cols-2' : 'grid-cols-1'}`}>\r\n {/* B2C Option - Only show if enabled */}\r\n {enableB2C && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setTenantType('Personal')}\r\n className={`p-4 rounded-[var(--radius-card)] border-2 transition-all text-left ${\r\n tenantType === 'Personal'\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-500)]/5'\r\n : 'border-[var(--border-color)] hover:border-[var(--border-color-hover)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className={`p-2 rounded-[var(--radius-button)] ${\r\n tenantType === 'Personal'\r\n ? 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n <User className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">{t('admin:tenants.type.b2c')}</p>\r\n </div>\r\n {tenantType === 'Personal' && (\r\n <Check className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.b2cDescription')}\r\n </p>\r\n </button>\r\n )}\r\n\r\n {/* B2B Option - Only show if enabled */}\r\n {enableB2B && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setTenantType('Business')}\r\n className={`p-4 rounded-[var(--radius-card)] border-2 transition-all text-left ${\r\n tenantType === 'Business'\r\n ? 'border-[var(--info-border)] bg-[var(--info-bg)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--border-color-hover)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className={`p-2 rounded-[var(--radius-button)] ${\r\n tenantType === 'Business'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n <Building className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">{t('admin:tenants.type.b2b')}</p>\r\n </div>\r\n {tenantType === 'Business' && (\r\n <Check className=\"w-5 h-5 text-[var(--info-text)]\" />\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.b2bDescription')}\r\n </p>\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Form */}\r\n <form onSubmit={handleSubmit} className=\"space-y-6\">\r\n {/* Tenant Details */}\r\n <div className=\"card p-6 space-y-6\">\r\n <h2 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('admin:tenants.create.details')}\r\n </h2>\r\n\r\n {/* Name */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <Building2 className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={name}\r\n onChange={(e) => handleNameChange(e.target.value)}\r\n placeholder={t('admin:tenants.create.namePlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required\r\n />\r\n </div>\r\n\r\n {/* Slug */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <Hash className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.slug')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={slug}\r\n onChange={(e) => setSlug(generateSlug(e.target.value))}\r\n placeholder={t('admin:tenants.create.slugPlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] font-mono placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1\">\r\n {t('admin:tenants.create.slugHelp')}\r\n </p>\r\n </div>\r\n\r\n {/* Description */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <FileText className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.description')}\r\n </label>\r\n <textarea\r\n value={description}\r\n onChange={(e) => setDescription(e.target.value)}\r\n placeholder={t('admin:tenants.create.descriptionPlaceholder')}\r\n rows={3}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* B2B: Organisation Mode Selection */}\r\n {tenantType === 'Business' && (\r\n <div className=\"card p-6 space-y-4\">\r\n <h2 className=\"text-lg font-semibold text-[var(--info-text)] flex items-center gap-2\">\r\n <Building className=\"w-5 h-5\" />\r\n {t('admin:tenants.create.organisation.title')}\r\n </h2>\r\n\r\n <div className=\"grid grid-cols-3 gap-4\">\r\n {/* Quick creation (no organisation) */}\r\n <button\r\n type=\"button\"\r\n onClick={() => setOrganisationMode('none')}\r\n className={`p-4 rounded-[var(--radius-card)] border-2 transition-all text-left ${\r\n organisationMode === 'none'\r\n ? 'border-[var(--success-border)] bg-[var(--success-bg)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--border-color-hover)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className={`p-2 rounded-[var(--radius-button)] ${\r\n organisationMode === 'none'\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n <Zap className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.create.organisation.quickMode')}\r\n </p>\r\n </div>\r\n {organisationMode === 'none' && (\r\n <Check className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.organisation.quickModeDescription')}\r\n </p>\r\n </button>\r\n\r\n {/* Existing organisation */}\r\n <button\r\n type=\"button\"\r\n onClick={() => setOrganisationMode('existing')}\r\n className={`p-4 rounded-[var(--radius-card)] border-2 transition-all text-left ${\r\n organisationMode === 'existing'\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-500)]/5'\r\n : 'border-[var(--border-color)] hover:border-[var(--border-color-hover)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className={`p-2 rounded-[var(--radius-button)] ${\r\n organisationMode === 'existing'\r\n ? 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n <Link className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.create.organisation.existingMode')}\r\n </p>\r\n </div>\r\n {organisationMode === 'existing' && (\r\n <Check className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.organisation.existingModeDescription')}\r\n </p>\r\n </button>\r\n\r\n {/* Create organisation */}\r\n <button\r\n type=\"button\"\r\n onClick={() => setOrganisationMode('create')}\r\n className={`p-4 rounded-[var(--radius-card)] border-2 transition-all text-left ${\r\n organisationMode === 'create'\r\n ? 'border-[var(--info-border)] bg-[var(--info-bg)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--border-color-hover)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className={`p-2 rounded-[var(--radius-button)] ${\r\n organisationMode === 'create'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n <Building className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.create.organisation.createMode')}\r\n </p>\r\n </div>\r\n {organisationMode === 'create' && (\r\n <Check className=\"w-5 h-5 text-[var(--info-text)]\" />\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.organisation.createModeDescription')}\r\n </p>\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* B2B: Existing Organisation Selection */}\r\n {tenantType === 'Business' && organisationMode === 'existing' && (\r\n <div className=\"card p-6 space-y-4\">\r\n <h2 className=\"text-lg font-semibold text-[var(--color-accent-600)] flex items-center gap-2\">\r\n <Link className=\"w-5 h-5\" />\r\n {t('admin:tenants.create.organisation.selectExisting')}\r\n </h2>\r\n\r\n {/* Selected organisation display */}\r\n {selectedOrganisation && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">{selectedOrganisation.name}</p>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {selectedOrganisation.businessIdentifier} — {selectedOrganisation.countryCode}\r\n </p>\r\n {selectedOrganisation.legalName && (\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{selectedOrganisation.legalName}</p>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={() => setSelectedOrganisation(null)}\r\n className=\"text-sm text-[var(--error-text)] hover:opacity-80\"\r\n >\r\n {t('common:remove')}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Search input */}\r\n {!selectedOrganisation && (\r\n <>\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-3 w-5 h-5 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={orgSearchQuery}\r\n onChange={(e) => setOrgSearchQuery(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.searchPlaceholder')}\r\n className=\"w-full pl-10 pr-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n {/* Results */}\r\n {orgSearchLoading && (\r\n <div className=\"flex items-center justify-center py-4\">\r\n <Loader2 className=\"w-5 h-5 animate-spin text-[var(--text-tertiary)]\" />\r\n </div>\r\n )}\r\n {!orgSearchLoading && availableOrganisations.length === 0 && (\r\n <p className=\"text-sm text-[var(--text-secondary)] text-center py-4\">\r\n {t('admin:tenants.create.organisation.noResults')}\r\n </p>\r\n )}\r\n {!orgSearchLoading && availableOrganisations.length > 0 && (\r\n <div className=\"border border-[var(--border-color)] rounded-[var(--radius-card)] overflow-hidden max-h-64 overflow-y-auto\">\r\n {availableOrganisations.map((org) => (\r\n <button\r\n key={org.id}\r\n type=\"button\"\r\n onClick={() => {\r\n setSelectedOrganisation(org);\r\n if (!name) {\r\n handleNameChange(org.name);\r\n }\r\n }}\r\n className=\"w-full text-left px-4 py-3 border-b border-[var(--border-color)] last:border-b-0 hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"font-medium text-sm text-[var(--text-primary)]\">{org.name}</p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">\r\n {org.businessIdentifier} — {org.countryCode}\r\n </p>\r\n </div>\r\n <span className={`text-xs px-2 py-1 rounded-[var(--radius-badge)] ${\r\n org.verificationStatus === 'Verified'\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : org.verificationStatus === 'Pending'\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n : 'bg-[var(--error-bg)] text-[var(--error-text)]'\r\n }`}>\r\n {t(`admin:organisations.status.${org.verificationStatus.toLowerCase()}`, org.verificationStatus)}\r\n </span>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* B2B: Organisation Details (only if creating) */}\r\n {tenantType === 'Business' && organisationMode === 'create' && (\r\n <div className=\"card p-6 space-y-6\">\r\n <h2 className=\"text-lg font-semibold text-[var(--info-text)] flex items-center gap-2\">\r\n <FileCheck className=\"w-5 h-5\" />\r\n {t('admin:tenants.create.organisation.details')}\r\n </h2>\r\n\r\n {/* Organisation Name */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={orgName}\r\n onChange={(e) => setOrgName(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.namePlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.legalName')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={orgLegalName}\r\n onChange={(e) => setOrgLegalName(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.legalNamePlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Business Identifier */}\r\n <div className=\"p-4 bg-[var(--info-bg)] rounded-[var(--radius-card)] border border-[var(--info-border)] space-y-4\">\r\n <h3 className=\"text-sm font-semibold text-[var(--info-text)] flex items-center gap-2\">\r\n <FileCheck className=\"w-4 h-4\" />\r\n {t('admin:tenants.create.organisation.businessId.title')}\r\n </h3>\r\n\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.businessId.type')} *\r\n </label>\r\n <select\r\n value={orgBusinessIdType}\r\n onChange={(e) => {\r\n const newType = e.target.value as BusinessIdentifierType;\r\n setOrgBusinessIdType(newType);\r\n // Auto-set country code based on identifier type\r\n const typeInfo = BUSINESS_IDENTIFIER_TYPES.find(t => t.value === newType);\r\n if (typeInfo?.country) {\r\n setOrgCountryCode(typeInfo.country);\r\n }\r\n }}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n >\r\n {BUSINESS_IDENTIFIER_TYPES.map((type) => (\r\n <option key={type.value} value={type.value}>\r\n {type.label}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.businessId.number')} *\r\n </label>\r\n <div className=\"relative flex\">\r\n <input\r\n type=\"text\"\r\n value={orgBusinessId}\r\n onChange={(e) => handleBusinessIdChange(e.target.value)}\r\n placeholder={orgBusinessIdType === 'UID_CHE' ? 'CHE-123.456.789' : t('admin:tenants.create.organisation.businessId.placeholder')}\r\n className=\"flex-1 px-4 py-2 pr-12 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] font-mono placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={handleLookup}\r\n disabled={lookupLoading || !orgBusinessId || orgBusinessId.replace(/[^0-9]/g, '').length < 9 || orgCountryCode !== 'CH'}\r\n className=\"absolute right-1 top-1 bottom-1 px-2.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center\"\r\n title={t('admin:tenants.create.organisation.lookupTitle')}\r\n >\r\n {lookupLoading ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Search className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n </div>\r\n {lookupError && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1 flex items-center gap-1\">\r\n <AlertTriangle className=\"w-3 h-3\" />\r\n {lookupError}\r\n </p>\r\n )}\r\n {lookupSuccess && (\r\n <p className=\"text-xs text-[var(--success-text)] mt-1 flex items-center gap-1\">\r\n <Check className=\"w-3 h-3\" />\r\n {t('admin:tenants.create.organisation.lookupSuccess')}\r\n </p>\r\n )}\r\n {orgCountryCode === 'CH' && orgBusinessIdType === 'UID_CHE' && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1\">\r\n {orgBusinessId.replace(/[^0-9]/g, '').length < 9\r\n ? t('admin:tenants.create.organisation.lookupHintIncomplete')\r\n : t('admin:tenants.create.organisation.lookupHint')}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.vatNumber')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={orgVatNumber}\r\n onChange={(e) => setOrgVatNumber(e.target.value)}\r\n placeholder=\"CHE-123.456.789 TVA\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] font-mono placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Address */}\r\n <div className=\"p-4 bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] space-y-4\">\r\n <h3 className=\"text-sm font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <MapPin className=\"w-4 h-4\" />\r\n {t('admin:tenants.create.organisation.address.title')} *\r\n </h3>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.street')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrStreet}\r\n onChange={(e) => setAddrStreet(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.address.streetPlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.street2')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrStreet2}\r\n onChange={(e) => setAddrStreet2(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.address.street2Placeholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.postalCode')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrPostalCode}\r\n onChange={(e) => setAddrPostalCode(e.target.value)}\r\n placeholder=\"1000\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n <div className=\"col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.city')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrCity}\r\n onChange={(e) => setAddrCity(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.address.cityPlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.state')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrState}\r\n onChange={(e) => setAddrState(e.target.value)}\r\n placeholder=\"VD\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div className=\"grid grid-cols-2 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.country')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrCountry}\r\n onChange={(e) => setAddrCountry(e.target.value)}\r\n placeholder=\"Switzerland\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.countryCode')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrCountryCode}\r\n onChange={(e) => setAddrCountryCode(e.target.value.toUpperCase().slice(0, 2))}\r\n placeholder=\"CH\"\r\n maxLength={2}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] uppercase\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Contact Info */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <Phone className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.organisation.phone')}\r\n </label>\r\n <input\r\n type=\"tel\"\r\n value={orgPhone}\r\n onChange={(e) => setOrgPhone(e.target.value)}\r\n placeholder=\"+41 21 123 45 67\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <Mail className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.organisation.email')}\r\n </label>\r\n <input\r\n type=\"email\"\r\n value={orgEmail}\r\n onChange={(e) => setOrgEmail(e.target.value)}\r\n placeholder=\"contact@company.ch\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <Globe className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.organisation.website')}\r\n </label>\r\n <input\r\n type=\"url\"\r\n value={orgWebsite}\r\n onChange={(e) => setOrgWebsite(e.target.value)}\r\n placeholder=\"https://www.company.ch\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Actions */}\r\n <div className=\"flex items-center justify-end gap-4 pt-4\">\r\n <button\r\n type=\"button\"\r\n onClick={() => navigate('/administration/tenants')}\r\n className=\"px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={loading || !isFormValid}\r\n className={`inline-flex items-center gap-2 px-6 py-2 text-sm font-medium rounded-[var(--radius-button)] text-white transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${\r\n tenantType === 'Business'\r\n ? organisationMode === 'none'\r\n ? 'bg-[var(--success-dot)] hover:opacity-90'\r\n : 'bg-[var(--info-dot)] hover:opacity-90'\r\n : 'bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)]'\r\n }`}\r\n >\r\n {loading ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <UserPlus className=\"w-4 h-4\" />\r\n )}\r\n {t('admin:tenants.create.submit')}\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n );\r\n}\r\n","import React, { useState } from 'react';\r\nimport {\r\n PieChart,\r\n Pie,\r\n Cell,\r\n ResponsiveContainer,\r\n Sector\r\n} from 'recharts';\r\nimport type { TopTenantDto } from '@/services/api/tenantAnalyticsApi';\r\nimport type { ChartMode } from './UsageTrendChart';\r\n\r\ninterface TenantActivityPieChartProps {\r\n readonly data: TopTenantDto[];\r\n readonly mode?: ChartMode;\r\n}\r\n\r\nconst COLORS = [\r\n '#3b82f6', // blue-500\r\n '#22c55e', // green-500\r\n '#f59e0b', // amber-500\r\n '#ef4444', // red-500\r\n '#8b5cf6', // violet-500\r\n '#06b6d4', // cyan-500\r\n '#ec4899', // pink-500\r\n '#f97316', // orange-500\r\n '#14b8a6', // teal-500\r\n '#6366f1', // indigo-500\r\n];\r\n\r\nconst renderActiveShape = (props: unknown) => {\r\n const {\r\n cx = 0,\r\n cy = 0,\r\n midAngle = 0,\r\n innerRadius = 0,\r\n outerRadius = 0,\r\n startAngle = 0,\r\n endAngle = 0,\r\n fill = '#8884d8',\r\n payload,\r\n percent = 0,\r\n value = 0\r\n } = props as {\r\n cx?: number;\r\n cy?: number;\r\n midAngle?: number;\r\n innerRadius?: number;\r\n outerRadius?: number;\r\n startAngle?: number;\r\n endAngle?: number;\r\n fill?: string;\r\n payload: { tenantName: string; tenantType: string };\r\n percent?: number;\r\n value?: number;\r\n };\r\n\r\n if (!payload) return <g />;\r\n const RADIAN = Math.PI / 180;\r\n const sin = Math.sin(-RADIAN * midAngle);\r\n const cos = Math.cos(-RADIAN * midAngle);\r\n const sx = cx + (outerRadius + 10) * cos;\r\n const sy = cy + (outerRadius + 10) * sin;\r\n const mx = cx + (outerRadius + 30) * cos;\r\n const my = cy + (outerRadius + 30) * sin;\r\n const ex = mx + (cos >= 0 ? 1 : -1) * 22;\r\n const ey = my;\r\n const textAnchor = cos >= 0 ? 'start' : 'end';\r\n\r\n return (\r\n <g>\r\n <text x={cx} y={cy} dy={-10} textAnchor=\"middle\" fill=\"var(--text-primary)\" style={{ fontSize: '14px', fontWeight: 'bold' }}>\r\n {payload.tenantName}\r\n </text>\r\n <text x={cx} y={cy} dy={10} textAnchor=\"middle\" fill=\"var(--text-secondary)\" style={{ fontSize: '12px' }}>\r\n {value.toLocaleString()} {payload.tenantType === '_duration' ? 'min' : 'accès'}\r\n </text>\r\n <Sector\r\n cx={cx}\r\n cy={cy}\r\n innerRadius={innerRadius}\r\n outerRadius={outerRadius}\r\n startAngle={startAngle}\r\n endAngle={endAngle}\r\n fill={fill}\r\n />\r\n <Sector\r\n cx={cx}\r\n cy={cy}\r\n startAngle={startAngle}\r\n endAngle={endAngle}\r\n innerRadius={outerRadius + 6}\r\n outerRadius={outerRadius + 10}\r\n fill={fill}\r\n />\r\n <path d={`M${sx},${sy}L${mx},${my}L${ex},${ey}`} stroke={fill} fill=\"none\" />\r\n <circle cx={ex} cy={ey} r={2} fill={fill} stroke=\"none\" />\r\n <text x={ex + (cos >= 0 ? 1 : -1) * 12} y={ey} textAnchor={textAnchor} fill=\"var(--text-primary)\" style={{ fontSize: '12px' }}>\r\n {`${(percent * 100).toFixed(0)}%`}\r\n </text>\r\n </g>\r\n );\r\n};\r\n\r\nexport const TenantActivityPieChart: React.FC<TenantActivityPieChartProps> = ({ data, mode = 'access' }) => {\r\n const [activeIndex, setActiveIndex] = useState(0);\r\n\r\n if (!data || data.length === 0) {\r\n return (\r\n <div className=\"flex items-center justify-center h-full text-[var(--text-secondary)]\">\r\n Aucune donnée d'activité disponible\r\n </div>\r\n );\r\n }\r\n\r\n const getValue = (tenant: TopTenantDto) =>\r\n mode === 'access' ? tenant.accessCount : tenant.totalDurationMinutes;\r\n\r\n const valueLabel = mode === 'access' ? 'accès' : 'min';\r\n const totalValue = data.reduce((sum, t) => sum + getValue(t), 0);\r\n\r\n const chartData = data.map((tenant, index) => ({\r\n ...tenant,\r\n // Encode mode into tenantType field for activeShape to read\r\n tenantType: mode === 'duration' ? '_duration' : tenant.tenantType,\r\n name: tenant.tenantName,\r\n value: getValue(tenant),\r\n fill: COLORS[index % COLORS.length]\r\n }));\r\n\r\n const onPieEnter = (_: unknown, index: number) => {\r\n setActiveIndex(index);\r\n };\r\n\r\n return (\r\n <div className=\"flex flex-col\">\r\n {/* Summary stats */}\r\n <div className=\"flex items-center gap-2 text-sm h-[34px]\">\r\n <span className=\"text-[var(--text-tertiary)]\">\r\n Vue globale des tenants actifs\r\n </span>\r\n </div>\r\n\r\n <div className=\"flex items-center justify-center gap-2\">\r\n <span className=\"text-lg font-semibold text-blue-600\">\r\n Tenants\r\n </span>\r\n <span className=\"text-[var(--text-secondary)]\">\r\n ({data.length} actifs • {totalValue.toLocaleString()} {valueLabel} total)\r\n </span>\r\n </div>\r\n\r\n {/* Pie Chart */}\r\n <div style={{ width: '100%', height: 350 }}>\r\n <ResponsiveContainer width=\"100%\" height={350}>\r\n <PieChart>\r\n <Pie\r\n {...{\r\n activeIndex,\r\n activeShape: renderActiveShape,\r\n data: chartData,\r\n cx: '50%',\r\n cy: '50%',\r\n innerRadius: 70,\r\n outerRadius: 110,\r\n fill: '#8884d8',\r\n dataKey: 'value',\r\n onMouseEnter: onPieEnter\r\n } as React.ComponentProps<typeof Pie>}\r\n >\r\n {chartData.map((entry) => (\r\n <Cell key={entry.tenantId} fill={entry.fill} />\r\n ))}\r\n </Pie>\r\n </PieChart>\r\n </ResponsiveContainer>\r\n </div>\r\n\r\n {/* Legend */}\r\n <div className=\"grid grid-cols-2 md:grid-cols-3 gap-2 max-h-[200px] overflow-y-auto\">\r\n {chartData.map((item, index) => (\r\n <button\r\n key={item.tenantId}\r\n onClick={() => setActiveIndex(index)}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n setActiveIndex(index);\r\n }\r\n }}\r\n className={`flex items-center gap-2 p-2 rounded-lg hover:bg-[var(--bg-secondary)] transition-colors cursor-pointer focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] ${\r\n activeIndex === index ? 'bg-[var(--bg-secondary)]' : ''\r\n }`}\r\n >\r\n <div\r\n className=\"w-3 h-3 rounded-full flex-shrink-0\"\r\n style={{ backgroundColor: item.fill }}\r\n />\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium truncate text-[var(--text-primary)]\">\r\n {item.tenantName}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">\r\n {getValue(data[index]).toLocaleString()} {valueLabel}\r\n </p>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\nimport {\r\n LineChart,\r\n Line,\r\n XAxis,\r\n YAxis,\r\n CartesianGrid,\r\n Tooltip,\r\n Legend,\r\n ResponsiveContainer\r\n} from 'recharts';\r\nimport { tenantAnalyticsApi } from '@/services/api/tenantAnalyticsApi';\r\nimport type { TenantTrendsDto, TenantSeriesDto } from '@/services/api/tenantAnalyticsApi';\r\nimport type { ChartMode } from './UsageTrendChart';\r\nimport { Loader2 } from 'lucide-react';\r\n\r\ninterface TenantUsageTrendChartProps {\r\n readonly period?: number;\r\n readonly mode?: ChartMode;\r\n}\r\n\r\nconst DEFAULT_COLORS = [\r\n '#3b82f6', // blue\r\n '#22c55e', // green\r\n '#f59e0b', // amber\r\n '#ef4444', // red\r\n '#8b5cf6', // violet\r\n '#06b6d4', // cyan\r\n '#ec4899', // pink\r\n];\r\n\r\ninterface LegendItemProps {\r\n readonly tenant: TenantSeriesDto;\r\n readonly index: number;\r\n readonly mode: ChartMode;\r\n readonly getColor: (tenant: TenantSeriesDto, index: number) => string;\r\n}\r\n\r\nfunction LegendItem({ tenant, index, mode, getColor }: LegendItemProps) {\r\n return (\r\n <div key={tenant.name} className=\"flex items-center gap-2\">\r\n <div\r\n className=\"w-3 h-3 rounded-full\"\r\n style={{ backgroundColor: getColor(tenant, index) }}\r\n />\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{tenant.name}</span>\r\n <span className=\"text-sm font-semibold\" style={{ color: getColor(tenant, index) }}>\r\n {mode === 'access' ? tenant.totalAccess : `${tenant.totalDurationMinutes} min`}\r\n </span>\r\n </div>\r\n );\r\n}\r\n\r\nexport const TenantUsageTrendChart: React.FC<TenantUsageTrendChartProps> = ({ period = 30, mode = 'access' }) => {\r\n const [data, setData] = useState<TenantTrendsDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n const fetchData = async () => {\r\n try {\r\n setLoading(true);\r\n const result = await tenantAnalyticsApi.getTrends(period);\r\n setData(result);\r\n setError(null);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load trends');\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n fetchData();\r\n }, [period]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-[300px]\">\r\n <Loader2 className=\"h-6 w-6 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error || !data) {\r\n return (\r\n <div className=\"flex items-center justify-center h-[300px] text-[var(--text-secondary)]\">\r\n {error || 'Aucune donnée disponible'}\r\n </div>\r\n );\r\n }\r\n\r\n if (!data?.dailyData?.length || !data?.tenants?.length) {\r\n return (\r\n <div className=\"flex items-center justify-center h-[300px] text-[var(--text-secondary)]\">\r\n Aucune donnée de tendance disponible\r\n </div>\r\n );\r\n }\r\n\r\n // Transform data for Recharts based on mode\r\n const chartData = data.dailyData.map((day) => {\r\n const entry: Record<string, string | number> = {\r\n date: new Date(day.date).toLocaleDateString('fr-FR', {\r\n day: '2-digit',\r\n month: 'short'\r\n })\r\n };\r\n data.tenants.forEach((tenant) => {\r\n if (mode === 'access') {\r\n entry[tenant.name] = day.tenantCounts[tenant.name] || 0;\r\n } else {\r\n entry[tenant.name] = day.tenantDurations?.[tenant.name] || 0;\r\n }\r\n });\r\n return entry;\r\n });\r\n\r\n const getColor = (tenant: TenantSeriesDto, index: number): string => {\r\n return tenant.color || DEFAULT_COLORS[index % DEFAULT_COLORS.length];\r\n };\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Chart */}\r\n <div style={{ width: '100%', height: 300 }}>\r\n <ResponsiveContainer width=\"100%\" height={300}>\r\n <LineChart\r\n data={chartData}\r\n margin={{ top: 5, right: 30, left: 20, bottom: 5 }}\r\n >\r\n <CartesianGrid\r\n strokeDasharray=\"3 3\"\r\n stroke=\"var(--border-color)\"\r\n />\r\n <XAxis\r\n dataKey=\"date\"\r\n stroke=\"var(--text-secondary)\"\r\n style={{ fontSize: '11px' }}\r\n tick={{ fill: 'var(--text-secondary)' }}\r\n />\r\n <YAxis\r\n stroke=\"var(--text-secondary)\"\r\n style={{ fontSize: '11px' }}\r\n tick={{ fill: 'var(--text-secondary)' }}\r\n label={{\r\n value: mode === 'access' ? 'Accès' : 'Minutes',\r\n angle: -90,\r\n position: 'insideLeft',\r\n style: { fill: 'var(--text-secondary)', fontSize: '11px' }\r\n }}\r\n />\r\n <Tooltip\r\n contentStyle={{\r\n backgroundColor: 'var(--bg-card)',\r\n border: '1px solid var(--border-color)',\r\n borderRadius: '8px',\r\n color: 'var(--text-primary)'\r\n }}\r\n labelStyle={{ color: 'var(--text-primary)', fontWeight: 'bold', marginBottom: '8px' }}\r\n itemStyle={{ color: 'var(--text-secondary)' }}\r\n />\r\n <Legend\r\n wrapperStyle={{\r\n paddingTop: '20px'\r\n }}\r\n formatter={(value) => (\r\n <span style={{ color: 'var(--text-secondary)', fontSize: '12px' }}>{value}</span>\r\n )}\r\n />\r\n {data.tenants.map((tenant, index) => (\r\n <Line\r\n key={tenant.name}\r\n type=\"monotone\"\r\n dataKey={tenant.name}\r\n stroke={getColor(tenant, index)}\r\n strokeWidth={2}\r\n dot={{ r: 2, fill: getColor(tenant, index) }}\r\n activeDot={{ r: 5, fill: getColor(tenant, index) }}\r\n />\r\n ))}\r\n </LineChart>\r\n </ResponsiveContainer>\r\n </div>\r\n\r\n {/* Legend with totals */}\r\n <div className=\"flex flex-wrap gap-4 justify-center border-t border-[var(--border-color)] pt-4\">\r\n {data.tenants.map((tenant, index) => (\r\n <LegendItem key={tenant.name} tenant={tenant} index={index} mode={mode} getColor={getColor} />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport { Users, Building2 } from 'lucide-react';\r\nimport type { TopTenantDto } from '@/services/api/tenantAnalyticsApi';\r\nimport type { ChartMode } from './UsageTrendChart';\r\n\r\ninterface TenantPopularityChartProps {\r\n readonly data: TopTenantDto[];\r\n readonly mode?: ChartMode;\r\n}\r\n\r\nconst tenantColors = [\r\n '#3b82f6',\r\n '#8b5cf6',\r\n '#22c55e',\r\n '#f59e0b',\r\n '#ef4444',\r\n '#06b6d4',\r\n '#ec4899',\r\n '#10b981',\r\n '#f97316',\r\n '#6366f1'\r\n];\r\n\r\nexport const TenantPopularityChart: React.FC<TenantPopularityChartProps> = ({ data, mode = 'access' }) => {\r\n if (!data || data.length === 0) {\r\n return (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n Aucune donnée de tenant disponible\r\n </div>\r\n );\r\n }\r\n\r\n const getValue = (tenant: TopTenantDto) =>\r\n mode === 'access' ? tenant.accessCount : tenant.totalDurationMinutes;\r\n const valueLabel = mode === 'access' ? 'accès' : 'min';\r\n\r\n const maxCount = Math.max(...data.map(t => getValue(t)), 1);\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n {data.map((tenant, index) => {\r\n const value = getValue(tenant);\r\n const percentage = (value / maxCount) * 100;\r\n\r\n return (\r\n <div\r\n key={tenant.tenantId}\r\n className=\"rounded-lg bg-[var(--bg-secondary)] p-4 hover:shadow-sm transition-shadow border-l-4\"\r\n style={{ borderLeftColor: tenantColors[index % tenantColors.length] }}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className=\"flex-1\">\r\n {/* Tenant type badge */}\r\n <div className=\"text-xs text-[var(--text-tertiary)] mb-1 font-mono\">\r\n <span className=\"text-blue-500\">{tenant.tenantType}</span>\r\n <span className=\"mx-1\">›</span>\r\n <span className=\"text-green-500\">{tenant.tenantSlug}</span>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <h5 className=\"font-semibold text-[var(--text-primary)]\">\r\n {tenant.tenantName}\r\n </h5>\r\n </div>\r\n </div>\r\n <div className=\"text-right\">\r\n <div className=\"text-xl font-bold\" style={{ color: tenantColors[index % tenantColors.length] }}>\r\n {value.toLocaleString()}\r\n </div>\r\n <div className=\"text-xs text-[var(--text-secondary)]\">{valueLabel}</div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"h-2 bg-[var(--bg-primary)] rounded-full overflow-hidden mb-2\">\r\n <div\r\n className=\"h-full rounded-full transition-all duration-500\"\r\n style={{\r\n width: `${percentage}%`,\r\n backgroundColor: tenantColors[index % tenantColors.length]\r\n }}\r\n />\r\n </div>\r\n\r\n <div className=\"flex items-center gap-4 text-xs text-[var(--text-secondary)]\">\r\n <div className=\"flex items-center gap-1\">\r\n <Users className=\"w-3 h-3\" />\r\n <span>{tenant.uniqueUsers} utilisateurs uniques</span>\r\n </div>\r\n <div className=\"flex items-center gap-1\">\r\n <Building2 className=\"w-3 h-3\" />\r\n <span>{tenant.tenantType}</span>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n","import type { ReactElement } from 'react';\r\nimport React, { useEffect, useState, useCallback } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n AlertTriangle,\r\n Building2,\r\n Users,\r\n Activity,\r\n TrendingUp,\r\n Loader2,\r\n RefreshCw,\r\n Clock,\r\n PauseCircle,\r\n CheckCircle,\r\n Timer,\r\n ShieldCheck,\r\n ShieldX,\r\n ClipboardList\r\n} from 'lucide-react';\r\nimport { tenantAnalyticsApi } from '@/services/api/tenantAnalyticsApi';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport type {\r\n TenantDashboardStatsDto,\r\n TopTenantDto\r\n} from '@/services/api/tenantAnalyticsApi';\r\nimport { TenantActivityPieChart } from '@/components/dashboard/TenantActivityPieChart';\r\nimport { TenantUsageTrendChart } from '@/components/dashboard/TenantUsageTrendChart';\r\nimport { TenantPopularityChart } from '@/components/dashboard/TenantPopularityChart';\r\nimport type { ChartMode } from '@/components/dashboard/UsageTrendChart';\r\n\r\nconst KpiCard: React.FC<{\r\n label: string;\r\n value: number | string;\r\n icon: React.ReactNode;\r\n color: 'blue' | 'green' | 'purple' | 'orange' | 'yellow' | 'red';\r\n subtitle?: string;\r\n}> = ({ label, value, icon, color, subtitle }) => {\r\n const iconColors = {\r\n blue: 'text-blue-500',\r\n green: 'text-green-500',\r\n purple: 'text-purple-500',\r\n orange: 'text-orange-500',\r\n yellow: 'text-yellow-500',\r\n red: 'text-red-500'\r\n };\r\n\r\n return (\r\n <div className=\"rounded-[var(--radius-card)] p-4 bg-[var(--bg-card)] border border-[var(--item-color-border)]\">\r\n <div className=\"flex items-center justify-between mb-2\">\r\n <span className=\"text-sm font-medium text-[var(--text-secondary)]\">{label}</span>\r\n <div className={iconColors[color]}>{icon}</div>\r\n </div>\r\n <div className=\"text-2xl font-bold text-[var(--text-primary)]\">{typeof value === 'number' ? value.toLocaleString() : value}</div>\r\n {subtitle && <div className=\"text-xs text-[var(--text-tertiary)] mt-1\">{subtitle}</div>}\r\n </div>\r\n );\r\n};\r\n\r\nexport function TenantsDashboardPage(): ReactElement {\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('admin');\r\n const [stats, setStats] = useState<TenantDashboardStatsDto | null>(null);\r\n const [topTenants, setTopTenants] = useState<TopTenantDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [refreshing, setRefreshing] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [period, setPeriod] = useState(30);\r\n const [chartMode, setChartMode] = useState<ChartMode>('access');\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setError(null);\r\n const [dashboardRes, topTenantsRes] = await Promise.all([\r\n tenantAnalyticsApi.getDashboardStats(period),\r\n tenantAnalyticsApi.getTopTenants(5, period, chartMode === 'access' ? 'access' : 'duration')\r\n ]);\r\n setStats(dashboardRes);\r\n setTopTenants(topTenantsRes);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load dashboard');\r\n } finally {\r\n setLoading(false);\r\n setRefreshing(false);\r\n }\r\n }, [period, chartMode]);\r\n\r\n useEffect(() => {\r\n setLoading(true);\r\n loadData();\r\n }, [loadData]);\r\n\r\n const handleRefresh = () => {\r\n setRefreshing(true);\r\n loadData();\r\n };\r\n\r\n const formatDuration = (seconds: number): string => {\r\n if (seconds < 60) return `${seconds}s`;\r\n const minutes = Math.floor(seconds / 60);\r\n if (minutes < 60) return `${minutes}m`;\r\n const hours = Math.floor(minutes / 60);\r\n return `${hours}h ${minutes % 60}m`;\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex h-96 items-center justify-center\">\r\n <Loader2 className=\"h-8 w-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"bg-[var(--error-bg)] border border-[var(--error-border)] rounded-[var(--radius-card)] p-4 flex items-center gap-3\">\r\n <AlertTriangle className=\"h-5 w-5 text-[var(--error-text)] flex-shrink-0\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-[var(--error-text)] font-medium\">{error}</p>\r\n </div>\r\n <button\r\n onClick={handleRefresh}\r\n className=\"text-[var(--error-text)] hover:opacity-80\"\r\n >\r\n <RefreshCw className=\"h-5 w-5\" />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('tenants.dashboard.title', 'Dashboard') }\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)] flex items-center gap-2\">\r\n <Building2 className=\"h-6 w-6\" />\r\n {t('tenants.dashboard.title', 'Tableau de bord Tenants')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.dashboard.subtitle', \"Analyse d'utilisation et statistiques des tenants\")}\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n {/* Mode Toggle */}\r\n <div className=\"flex items-center gap-1 rounded-lg border border-[var(--item-color-border)] bg-[var(--bg-secondary)] p-1\">\r\n <button\r\n onClick={() => setChartMode('access')}\r\n className={`px-3 py-1.5 text-sm font-medium rounded-md transition-all ${\r\n chartMode === 'access'\r\n ? 'bg-[var(--color-primary-600)] text-white shadow-sm'\r\n : 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <span className=\"flex items-center gap-1.5\">\r\n <Activity className=\"w-3.5 h-3.5\" />\r\n {t('tenants.dashboard.access', 'Accès')}\r\n </span>\r\n </button>\r\n <button\r\n onClick={() => setChartMode('duration')}\r\n className={`px-3 py-1.5 text-sm font-medium rounded-md transition-all ${\r\n chartMode === 'duration'\r\n ? 'bg-[var(--color-primary-600)] text-white shadow-sm'\r\n : 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <span className=\"flex items-center gap-1.5\">\r\n <Clock className=\"w-3.5 h-3.5\" />\r\n {t('tenants.dashboard.duration', 'Durée')}\r\n </span>\r\n </button>\r\n </div>\r\n <select\r\n value={period}\r\n onChange={(e) => setPeriod(Number(e.target.value))}\r\n className=\"rounded-[var(--radius-input)] border border-[var(--item-color-border)] bg-[var(--bg-secondary)] px-4 py-2 text-[var(--text-primary)] focus:border-[var(--color-primary-600)] focus:outline-none\"\r\n >\r\n <option value={7}>7 {t('common.days', 'jours')}</option>\r\n <option value={30}>30 {t('common.days', 'jours')}</option>\r\n <option value={90}>90 {t('common.days', 'jours')}</option>\r\n </select>\r\n <button\r\n onClick={handleRefresh}\r\n disabled={refreshing}\r\n className=\"rounded-[var(--radius-button)] border border-[var(--item-color-border)] bg-[var(--bg-secondary)] px-4 py-2 text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] flex items-center gap-2 transition-colors\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${refreshing ? 'animate-spin' : ''}`} />\r\n {t('common.refresh', 'Actualiser')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* KPI Cards Grid */}\r\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4\">\r\n <KpiCard\r\n label={t('tenants.dashboard.totalTenants', 'Total Tenants')}\r\n value={stats?.totalTenants || 0}\r\n icon={<Building2 className=\"h-5 w-5\" />}\r\n color=\"blue\"\r\n />\r\n <KpiCard\r\n label={t('tenants.dashboard.activeTenants', 'Tenants Actifs')}\r\n value={stats?.activeTenants || 0}\r\n icon={<CheckCircle className=\"h-5 w-5\" />}\r\n color=\"green\"\r\n />\r\n <KpiCard\r\n label={t('tenants.dashboard.suspendedTenants', 'Suspendus')}\r\n value={stats?.suspendedTenants || 0}\r\n icon={<PauseCircle className=\"h-5 w-5\" />}\r\n color=\"orange\"\r\n />\r\n <KpiCard\r\n label={t('tenants.dashboard.totalMembers', 'Total Membres')}\r\n value={stats?.totalMembers || 0}\r\n icon={<Users className=\"h-5 w-5\" />}\r\n color=\"purple\"\r\n />\r\n <KpiCard\r\n label={t('tenants.dashboard.avgSession', 'Session Moy.')}\r\n value={formatDuration(stats?.avgSessionDuration || 0)}\r\n icon={<Timer className=\"h-5 w-5\" />}\r\n color=\"blue\"\r\n subtitle={`${period} ${t('common.days', 'jours')}`}\r\n />\r\n <KpiCard\r\n label={t('tenants.dashboard.growthRate', 'Croissance')}\r\n value={`${stats?.growthRate.toFixed(1) || 0}%`}\r\n icon={<TrendingUp className=\"h-5 w-5\" />}\r\n color={(stats?.growthRate ?? 0) >= 0 ? 'green' : 'red'}\r\n subtitle={t('tenants.dashboard.vsPreviousPeriod', 'vs période précédente')}\r\n />\r\n </div>\r\n\r\n {/* Access Requests Section */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"font-semibold flex items-center gap-2 text-[var(--text-primary)]\">\r\n <ClipboardList className=\"h-5 w-5 text-[var(--color-primary-600)]\" />\r\n {t('tenants.dashboard.accessRequests.title', \"Demandes d'accès\")}\r\n </h3>\r\n <button\r\n onClick={() => navigate('/administration/access-requests')}\r\n className=\"text-sm font-medium text-[var(--color-primary-600)] hover:underline flex items-center gap-1\"\r\n >\r\n {t('tenants.dashboard.accessRequests.manage', 'Gérer')}\r\n <span aria-hidden=\"true\">→</span>\r\n </button>\r\n </div>\r\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\r\n <div className=\"rounded-lg p-4 bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <div className=\"flex items-center justify-between mb-1\">\r\n <span className=\"text-sm font-medium text-[var(--warning-text)]\">\r\n {t('tenants.dashboard.accessRequests.pending', 'En attente')}\r\n </span>\r\n <Clock className=\"h-4 w-4 text-[var(--warning-text)]\" />\r\n </div>\r\n <div className=\"text-2xl font-bold text-[var(--warning-text)]\">\r\n {stats?.pendingAccessRequests || 0}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg p-4 bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <div className=\"flex items-center justify-between mb-1\">\r\n <span className=\"text-sm font-medium text-[var(--success-text)]\">\r\n {t('tenants.dashboard.accessRequests.approved', 'Approuvées')}\r\n </span>\r\n <ShieldCheck className=\"h-4 w-4 text-[var(--success-text)]\" />\r\n </div>\r\n <div className=\"text-2xl font-bold text-[var(--success-text)]\">\r\n {stats?.approvedAccessRequests || 0}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg p-4 bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center justify-between mb-1\">\r\n <span className=\"text-sm font-medium text-[var(--error-text)]\">\r\n {t('tenants.dashboard.accessRequests.denied', 'Refusées')}\r\n </span>\r\n <ShieldX className=\"h-4 w-4 text-[var(--error-text)]\" />\r\n </div>\r\n <div className=\"text-2xl font-bold text-[var(--error-text)]\">\r\n {stats?.deniedAccessRequests || 0}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Two Column: Tenant Activity Pie + Top Tenants List */}\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {/* Tenant Activity Pie Chart */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <h3 className=\"font-semibold mb-4 flex items-center gap-2 text-[var(--text-primary)]\">\r\n <Building2 className=\"h-5 w-5 text-[var(--color-primary-600)]\" />\r\n {chartMode === 'access' ? t('tenants.dashboard.activity', 'Activité') : t('tenants.dashboard.timeSpent', 'Temps passé')} {t('tenants.dashboard.byTenant', 'par Tenant')}\r\n </h3>\r\n {topTenants.length > 0 ? (\r\n <TenantActivityPieChart data={topTenants} mode={chartMode} />\r\n ) : (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('tenants.dashboard.noData', 'Aucune donnée disponible')}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Top Tenants List */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <h3 className=\"font-semibold mb-4 flex items-center gap-2 text-[var(--text-primary)]\">\r\n <Activity className=\"h-5 w-5 text-green-600\" />\r\n {t('tenants.dashboard.topTenantsList', 'Classement des Tenants')}\r\n </h3>\r\n {stats?.topTenants && stats.topTenants.length > 0 ? (\r\n <div className=\"space-y-3\">\r\n {stats.topTenants.slice(0, 5).map((tenant, index) => (\r\n <button\r\n type=\"button\"\r\n key={tenant.tenantId}\r\n className=\"w-full flex items-center gap-3 p-3 rounded-lg bg-[var(--bg-secondary)] hover:bg-[var(--bg-hover)] cursor-pointer transition-colors text-left\"\r\n onClick={() => navigate(`/administration/tenants/${tenant.tenantId}`)}\r\n >\r\n <div\r\n className=\"w-8 h-8 rounded-full flex items-center justify-center text-white font-bold text-sm\"\r\n style={{ backgroundColor: ['#3b82f6', '#22c55e', '#f59e0b', '#ef4444', '#8b5cf6'][index % 5] }}\r\n >\r\n {index + 1}\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"font-medium text-[var(--text-primary)] truncate\">{tenant.tenantName}</p>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">\r\n {tenant.tenantType} • {tenant.uniqueUsers} {t('tenants.dashboard.users', 'utilisateurs')}\r\n </p>\r\n </div>\r\n <div className=\"text-right\">\r\n <p className=\"font-semibold text-[var(--text-primary)]\">\r\n {chartMode === 'access' ? tenant.accessCount : `${tenant.totalDurationMinutes}m`}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">\r\n {chartMode === 'access' ? t('tenants.dashboard.accesses', 'accès') : t('tenants.dashboard.totalTime', 'temps total')}\r\n </p>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n ) : (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('tenants.dashboard.noData', 'Aucune donnée disponible')}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Usage Trends Chart - Full Width with Tenant breakdown */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <h3 className=\"font-semibold mb-4 flex items-center gap-2 text-[var(--text-primary)]\">\r\n <TrendingUp className=\"h-5 w-5\" />\r\n {t('tenants.dashboard.trendTitle', {\r\n defaultValue: `Tendance ${chartMode === 'access' ? \"d'utilisation\" : 'du temps passé'} par Tenant`\r\n })} ({period} {t('common.days', 'jours')})\r\n </h3>\r\n <TenantUsageTrendChart period={period} mode={chartMode} />\r\n </div>\r\n\r\n {/* Tenant Popularity - Full Width */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <h3 className=\"font-semibold mb-4 flex items-center gap-2 text-[var(--text-primary)]\">\r\n <Building2 className=\"h-5 w-5 text-purple-600\" />\r\n {t('tenants.dashboard.popularTenants', {\r\n defaultValue: `Tenants les plus ${chartMode === 'access' ? 'actifs' : 'utilisés'}`\r\n })}\r\n <span className=\"text-xs font-normal text-[var(--text-secondary)] ml-2\">\r\n ({t('tenants.dashboard.byRanking', 'Type > Slug')})\r\n </span>\r\n </h3>\r\n {topTenants.length > 0 ? (\r\n <TenantPopularityChart data={topTenants} mode={chartMode} />\r\n ) : (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('tenants.dashboard.noData', 'Aucune donnée disponible')}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Call to action */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-gradient-to-r from-[var(--color-primary-600)]/10 to-[var(--color-accent-500)]/10 p-6\">\r\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\r\n <div>\r\n <h3 className=\"font-bold text-[var(--text-primary)]\">{t('tenants.dashboard.exploreAll', 'Explorer tous les Tenants')}</h3>\r\n <p className=\"mt-1 text-sm text-[var(--text-secondary)]\">\r\n {t('tenants.dashboard.exploreDescription', 'Voir la liste complète des tenants et gérer leurs paramètres')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={() => navigate('/administration/tenants/list')}\r\n className=\"whitespace-nowrap rounded-[var(--radius-button)] bg-[var(--color-primary-600)] px-4 py-2 font-medium text-white transition-all hover:shadow-md\"\r\n >\r\n {t('tenants.dashboard.viewTenants', 'Voir les Tenants')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useCallback, useMemo } from 'react';\r\nimport {\r\n adminApi,\r\n type TenantApplicationDto,\r\n type AvailableApplicationDto,\r\n type ApplicationAccessLevel,\r\n type SaveOverridesRequest,\r\n} from '@/services/api/adminApi';\r\nimport type {\r\n UseTenantApplicationsReturn,\r\n BulkAccessMode,\r\n BulkModuleNode,\r\n BulkSectionNode,\r\n} from './useTenantApplications';\r\n\r\nconst updateModuleAssignment = (module: BulkModuleNode, moduleId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newIsAssigned = !module.isAssigned;\r\n return {\r\n ...module,\r\n isAssigned: newIsAssigned,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: newIsAssigned })),\r\n };\r\n};\r\n\r\nconst updateSectionAssignment = (module: BulkModuleNode, moduleId: string, sectionId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newSections = module.sections.map(s =>\r\n s.id === sectionId ? { ...s, isAssigned: !s.isAssigned } : s\r\n );\r\n const anySectionAssigned = newSections.some(s => s.isAssigned);\r\n return {\r\n ...module,\r\n isAssigned: anySectionAssigned,\r\n sections: newSections,\r\n };\r\n};\r\n\r\nconst assignAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: true,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: true })),\r\n});\r\n\r\nconst clearAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: false,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: false })),\r\n});\r\n\r\nfunction mapTemplateAppToTenantApp(\r\n app: { applicationId: string; label: string; code: string; description: string | null; icon: string | null; accessLevel: string; assignedAt: string; assignedBy: string | null; assignedModuleCount: number; assignedSectionCount: number; totalModuleCount: number; totalSectionCount: number }\r\n): TenantApplicationDto {\r\n return {\r\n applicationId: app.applicationId,\r\n label: app.label,\r\n code: app.code,\r\n description: app.description,\r\n icon: app.icon,\r\n accessLevel: app.accessLevel as ApplicationAccessLevel,\r\n assignedAt: app.assignedAt,\r\n assignedBy: app.assignedBy,\r\n source: 'Direct',\r\n inheritedModuleCount: 0,\r\n directModuleCount: app.assignedModuleCount,\r\n revokedModuleCount: 0,\r\n inheritedSectionCount: 0,\r\n directSectionCount: app.assignedSectionCount,\r\n revokedSectionCount: 0,\r\n totalModuleCount: app.totalModuleCount,\r\n totalSectionCount: app.totalSectionCount,\r\n };\r\n}\r\n\r\nexport function useTemplateApplications(templateId: string | undefined): UseTenantApplicationsReturn {\r\n const [applications, setApplications] = useState<TenantApplicationDto[] | null>(null);\r\n const [loadingApps, setLoadingApps] = useState(false);\r\n\r\n const [addingApplication, setAddingApplication] = useState(false);\r\n const [availableApps, setAvailableApps] = useState<AvailableApplicationDto[]>([]);\r\n const [loadingAvailableApps, setLoadingAvailableApps] = useState(false);\r\n const [selectedAppIds, setSelectedAppIds] = useState<string[]>([]);\r\n const [assigningApps, setAssigningApps] = useState(false);\r\n const [appSearchTerm, setAppSearchTerm] = useState('');\r\n const [availableAppsError, setAvailableAppsError] = useState<string | null>(null);\r\n\r\n const [selectedAccessLevel, setSelectedAccessLevel] = useState<ApplicationAccessLevel>('FullAccess');\r\n const [bulkAccessMode, setBulkAccessMode] = useState<BulkAccessMode>('full');\r\n const [bulkModules, setBulkModules] = useState<BulkModuleNode[]>([]);\r\n const [bulkExpandedModules, setBulkExpandedModules] = useState<Set<string>>(new Set());\r\n const [loadingBulkModules, setLoadingBulkModules] = useState(false);\r\n\r\n const [showCustomizeDrawer, setShowCustomizeDrawer] = useState(false);\r\n const [customizingApp, setCustomizingApp] = useState<TenantApplicationDto | null>(null);\r\n\r\n const loadApplications = useCallback(async () => {\r\n if (!templateId) return;\r\n setLoadingApps(true);\r\n try {\r\n const data = await adminApi.templates.getApplications(templateId);\r\n const mapped = Array.isArray(data) ? data.map(mapTemplateAppToTenantApp) : [];\r\n setApplications(mapped);\r\n } catch (err) {\r\n console.error('Failed to load template applications:', err);\r\n setApplications([]);\r\n } finally {\r\n setLoadingApps(false);\r\n }\r\n }, [templateId]);\r\n\r\n const loadAvailableApps = useCallback(async () => {\r\n if (!templateId) return;\r\n setAddingApplication(true);\r\n setSelectedAppIds([]);\r\n setLoadingAvailableApps(true);\r\n setAvailableAppsError(null);\r\n try {\r\n const availableAppsResult = await adminApi.templates.getAvailableApplications(templateId);\r\n setAvailableApps(availableAppsResult.filter(a => !a.isAssigned));\r\n } catch (err) {\r\n console.error('Failed to load available applications:', err);\r\n const isForbidden = err instanceof Error && err.name === 'ForbiddenError';\r\n setAvailableAppsError(isForbidden ? 'forbidden' : 'generic');\r\n } finally {\r\n setLoadingAvailableApps(false);\r\n }\r\n }, [templateId]);\r\n\r\n const closeAddApplication = useCallback(() => {\r\n setAddingApplication(false);\r\n setSelectedAppIds([]);\r\n setAppSearchTerm('');\r\n setSelectedAccessLevel('FullAccess');\r\n setBulkAccessMode('full');\r\n setBulkModules([]);\r\n setBulkExpandedModules(new Set());\r\n }, []);\r\n\r\n const handleAssignApplications = useCallback(async () => {\r\n if (!templateId || selectedAppIds.length === 0) return;\r\n setAssigningApps(true);\r\n try {\r\n const request = {\r\n applicationIds: selectedAppIds,\r\n accessLevel: selectedAccessLevel,\r\n accessMode: bulkAccessMode,\r\n moduleIds: bulkAccessMode === 'custom' ? bulkModules.filter(m => m.isAssigned).map(m => m.id) : undefined,\r\n sectionIds: bulkAccessMode === 'custom' ? bulkModules.flatMap(m => m.sections.filter(s => s.isAssigned).map(s => s.id)) : undefined,\r\n };\r\n\r\n await adminApi.templates.bulkAssignApplications(templateId, request);\r\n\r\n await loadApplications();\r\n closeAddApplication();\r\n } catch (err) {\r\n console.error('Failed to assign applications:', err);\r\n } finally {\r\n setAssigningApps(false);\r\n }\r\n }, [templateId, selectedAppIds, selectedAccessLevel, bulkAccessMode, bulkModules, loadApplications, closeAddApplication]);\r\n\r\n const handleRemoveApplication = useCallback(async (appId: string) => {\r\n if (!templateId) return;\r\n try {\r\n await adminApi.templates.removeApplication(templateId, appId);\r\n await loadApplications();\r\n } catch (err) {\r\n console.error('Failed to remove application:', err);\r\n }\r\n }, [templateId, loadApplications]);\r\n\r\n const handleUpdateAccessLevel = useCallback(async (appId: string, accessLevel: ApplicationAccessLevel) => {\r\n if (!templateId) return;\r\n try {\r\n await adminApi.templates.updateApplicationAccessLevel(templateId, appId, accessLevel);\r\n await loadApplications();\r\n } catch (err) {\r\n console.error('Failed to update access level:', err);\r\n }\r\n }, [templateId, loadApplications]);\r\n\r\n const openCustomizeDrawer = useCallback((app: TenantApplicationDto) => {\r\n setCustomizingApp(app);\r\n setShowCustomizeDrawer(true);\r\n }, []);\r\n\r\n const closeCustomizeDrawer = useCallback(() => {\r\n setShowCustomizeDrawer(false);\r\n setCustomizingApp(null);\r\n }, []);\r\n\r\n const filteredAvailableApps = useMemo(() => {\r\n if (!appSearchTerm) return availableApps;\r\n\r\n const searchLower = appSearchTerm.toLowerCase();\r\n return availableApps.filter(app =>\r\n app.label.toLowerCase().includes(searchLower) ||\r\n app.code.toLowerCase().includes(searchLower)\r\n );\r\n }, [availableApps, appSearchTerm]);\r\n\r\n const handleAppToggle = useCallback((appId: string) => {\r\n setSelectedAppIds(prev =>\r\n prev.includes(appId)\r\n ? prev.filter(id => id !== appId)\r\n : [...prev, appId]\r\n );\r\n }, []);\r\n\r\n const selectAllFilteredApps = useCallback(() => {\r\n const filteredIds = filteredAvailableApps.map(app => app.id);\r\n setSelectedAppIds(filteredIds);\r\n }, [filteredAvailableApps]);\r\n\r\n const clearAppSelection = useCallback(() => {\r\n setSelectedAppIds([]);\r\n }, []);\r\n\r\n const loadBulkModulesForApp = useCallback(async (appId: string) => {\r\n setLoadingBulkModules(true);\r\n try {\r\n const appModules = await adminApi.applications.getModules(appId);\r\n const moduleNodes: BulkModuleNode[] = [];\r\n\r\n for (const appModule of appModules) {\r\n const sections = await adminApi.applications.getModuleSections(appId, appModule.id);\r\n const sectionNodes: BulkSectionNode[] = sections.map(section => ({\r\n id: section.id,\r\n label: section.label,\r\n code: section.code,\r\n icon: section.icon,\r\n isAssigned: true,\r\n }));\r\n\r\n moduleNodes.push({\r\n id: appModule.id,\r\n label: appModule.label,\r\n code: appModule.code,\r\n icon: appModule.icon,\r\n isAssigned: true,\r\n sections: sectionNodes,\r\n });\r\n }\r\n\r\n setBulkModules(moduleNodes);\r\n } catch (err) {\r\n console.error('Failed to load modules:', err);\r\n } finally {\r\n setLoadingBulkModules(false);\r\n }\r\n }, []);\r\n\r\n const toggleBulkModuleExpand = useCallback((moduleId: string) => {\r\n setBulkExpandedModules(prev => {\r\n const newSet = new Set(prev);\r\n if (newSet.has(moduleId)) {\r\n newSet.delete(moduleId);\r\n } else {\r\n newSet.add(moduleId);\r\n }\r\n return newSet;\r\n });\r\n }, []);\r\n\r\n const toggleBulkModule = useCallback((moduleId: string) => {\r\n setBulkModules(prev => prev.map(m => updateModuleAssignment(m, moduleId)));\r\n }, []);\r\n\r\n const toggleBulkSection = useCallback((moduleId: string, sectionId: string) => {\r\n setBulkModules(prev => prev.map(m => updateSectionAssignment(m, moduleId, sectionId)));\r\n }, []);\r\n\r\n const getBulkModuleCheckState = useCallback((module: BulkModuleNode): 'checked' | 'unchecked' | 'indeterminate' => {\r\n if (module.sections.length === 0) {\r\n return module.isAssigned ? 'checked' : 'unchecked';\r\n }\r\n const assignedCount = module.sections.filter(s => s.isAssigned).length;\r\n if (assignedCount === 0) return 'unchecked';\r\n if (assignedCount === module.sections.length) return 'checked';\r\n return 'indeterminate';\r\n }, []);\r\n\r\n const getBulkStats = useCallback(() => {\r\n const totalModules = bulkModules.length;\r\n const assignedModules = bulkModules.filter(m => m.isAssigned || m.sections.some(s => s.isAssigned)).length;\r\n const totalSections = bulkModules.reduce((sum, m) => sum + m.sections.length, 0);\r\n const assignedSections = bulkModules.reduce((sum, m) => sum + m.sections.filter(s => s.isAssigned).length, 0);\r\n return { totalModules, assignedModules, totalSections, assignedSections };\r\n }, [bulkModules]);\r\n\r\n const selectAllBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => assignAllSections(m)));\r\n }, []);\r\n\r\n const clearBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => clearAllSections(m)));\r\n }, []);\r\n\r\n return {\r\n applications,\r\n setApplications,\r\n loadingApps,\r\n setLoadingApps,\r\n addingApplication,\r\n setAddingApplication,\r\n availableApps,\r\n setAvailableApps,\r\n loadingAvailableApps,\r\n setLoadingAvailableApps,\r\n selectedAppIds,\r\n setSelectedAppIds,\r\n assigningApps,\r\n setAssigningApps,\r\n appSearchTerm,\r\n setAppSearchTerm,\r\n selectedAccessLevel,\r\n setSelectedAccessLevel,\r\n bulkAccessMode,\r\n setBulkAccessMode,\r\n bulkModules,\r\n setBulkModules,\r\n bulkExpandedModules,\r\n setBulkExpandedModules,\r\n loadingBulkModules,\r\n setLoadingBulkModules,\r\n showCustomizeDrawer,\r\n setShowCustomizeDrawer,\r\n customizingApp,\r\n setCustomizingApp,\r\n loadApplications,\r\n availableAppsError,\r\n loadAvailableApps,\r\n handleAssignApplications,\r\n handleRemoveApplication,\r\n handleUpdateAccessLevel,\r\n openCustomizeDrawer,\r\n closeCustomizeDrawer,\r\n filteredAvailableApps,\r\n handleAppToggle,\r\n selectAllFilteredApps,\r\n clearAppSelection,\r\n loadBulkModulesForApp,\r\n toggleBulkModuleExpand,\r\n toggleBulkModule,\r\n toggleBulkSection,\r\n getBulkModuleCheckState,\r\n getBulkStats,\r\n selectAllBulkModules,\r\n clearBulkModules,\r\n // Template mode does not support overrides — provide no-op stubs to satisfy the shared interface\r\n handleSaveOverrides: async (_appId: string, _request: SaveOverridesRequest) => { /* no-op for template mode */ },\r\n handleResetOverrides: async (_appId: string) => { /* no-op for template mode */ },\r\n };\r\n}\r\n","import { memo, useEffect, useState, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useParams, useNavigate, Link } from 'react-router-dom';\r\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\r\nimport { useTemplateApplications } from '@/hooks/useTemplateApplications';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { TenantApplicationsTab } from '@/components/platform/administration/tenants/TenantApplicationsTab';\r\nimport { ArrowLeft, RefreshCw, Loader2, AlertCircle, Star, User, Building2, Users, AppWindow, LayoutGrid, Brain } from 'lucide-react';\r\nimport { adminApi, type TenantTemplateDetailDto, type TenantBasicDto, type TemplateAiInstanceDto } from '@/services/api/adminApi';\r\n\r\nconst VALID_TABS = ['info', 'applications', 'tenants', 'ai'] as const;\r\ntype TabType = typeof VALID_TABS[number];\r\n\r\n// ============================================================================\r\n// Interfaces\r\n// ============================================================================\r\n\r\ninterface InfoTabProps {\r\n readonly template: TenantTemplateDetailDto;\r\n readonly t: (key: string) => string;\r\n}\r\n\r\ninterface StatCardProps {\r\n readonly icon: React.ReactNode;\r\n readonly label: string;\r\n readonly value: number;\r\n}\r\n\r\ninterface TenantsTabProps {\r\n readonly templateId: string;\r\n readonly t: (key: string) => string;\r\n}\r\n\r\ninterface AiInstancesTabProps {\r\n readonly templateId: string;\r\n readonly t: (key: string) => string;\r\n}\r\n\r\n// ============================================================================\r\n// Main Page\r\n// ============================================================================\r\n\r\nexport function TenantTemplateDetailPage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { id: templateId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const { activeTab, setActiveTab } = useTabNavigation<TabType>('info', VALID_TABS);\r\n\r\n const [template, setTemplate] = useState<TenantTemplateDetailDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const templateApplications = useTemplateApplications(templateId);\r\n\r\n const loadTemplate = useCallback(async () => {\r\n if (!templateId) return;\r\n try {\r\n setLoading(true);\r\n const data = await adminApi.templates.getById(templateId);\r\n setTemplate(data);\r\n setError(null);\r\n } catch {\r\n setError(t('templates.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [templateId, t]);\r\n\r\n useEffect(() => {\r\n if (!templateId) {\r\n navigate('/administration/tenants/template');\r\n return;\r\n }\r\n loadTemplate();\r\n }, [templateId, loadTemplate, navigate]);\r\n\r\n useEffect(() => {\r\n if (template && templateId) {\r\n templateApplications.loadApplications();\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [template, templateId]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"p-6 flex items-center justify-center min-h-[50vh]\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error || !template) {\r\n return (\r\n <div className=\"p-6 space-y-4\">\r\n <button\r\n onClick={() => navigate('/administration/tenants/template')}\r\n className=\"flex items-center gap-2 text-sm text-[var(--text-secondary)] hover:text-[var(--text-primary)]\"\r\n >\r\n <ArrowLeft className=\"w-4 h-4\" />\r\n {t('templates.title')}\r\n </button>\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <AlertCircle className=\"h-5 w-5 text-[var(--error-text)]\" />\r\n <span className=\"text-[var(--error-text)]\">{error || t('templates.notFound')}</span>\r\n </div>\r\n <button\r\n onClick={() => loadTemplate()}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:errors.retry')}\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const TypeIcon = template.targetTenantType === 'Personal' ? User : Building2;\r\n const typeLabel = template.targetTenantType === 'Personal'\r\n ? t('templates.targetPersonal')\r\n : t('templates.targetBusiness');\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('templates.title'), href: '/administration/tenants/template' },\r\n { label: template.name }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/tenants/template')}\r\n aria-label={t('templates.title')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div>\r\n <div className=\"flex items-center gap-3\">\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">{template.name}</h1>\r\n {template.isDefault && (\r\n <span className=\"flex items-center gap-1 px-2 py-0.5 rounded-[var(--radius-badge)] text-xs bg-[var(--accent-bg)] text-[var(--accent-text)]\">\r\n <Star className=\"w-3 h-3\" />\r\n {t('templates.default')}\r\n </span>\r\n )}\r\n </div>\r\n <div className=\"flex items-center gap-2 mt-1\">\r\n <span className=\"text-sm text-[var(--text-tertiary)] font-mono\">{template.code}</span>\r\n <span className=\"text-[var(--text-tertiary)]\">-</span>\r\n <span className=\"flex items-center gap-1 text-sm text-[var(--text-secondary)]\">\r\n <TypeIcon className=\"w-3.5 h-3.5\" />\r\n {typeLabel}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n <button\r\n onClick={loadTemplate}\r\n aria-label={t('common:refresh')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-secondary)]\"\r\n >\r\n <RefreshCw className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n\r\n {/* Tabs */}\r\n <div className=\"border-b border-[var(--border-color)]\">\r\n <div className=\"flex gap-1 -mb-px\">\r\n {VALID_TABS.map(tab => (\r\n <button\r\n key={tab}\r\n onClick={() => setActiveTab(tab)}\r\n className={`px-4 py-2 text-sm border-b-2 transition-colors ${\r\n activeTab === tab\r\n ? 'border-[var(--primary-color)] text-[var(--primary-color)] font-medium'\r\n : 'border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n >\r\n {t(`templates.tabs.${tab}`)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Tab Content */}\r\n {activeTab === 'info' && <InfoTab template={template} t={t} />}\r\n {activeTab === 'applications' && (\r\n <TenantApplicationsTab\r\n tenantId={templateId!}\r\n tenantName={template.name}\r\n mode=\"template\"\r\n applications={templateApplications.applications}\r\n loadingApps={templateApplications.loadingApps}\r\n actionLoading={null}\r\n onRefresh={templateApplications.loadApplications}\r\n onUpdateAccessLevel={templateApplications.handleUpdateAccessLevel}\r\n onRemoveApplication={templateApplications.handleRemoveApplication}\r\n // Add application modal state\r\n addingApplication={templateApplications.addingApplication}\r\n availableAppsError={templateApplications.availableAppsError}\r\n filteredAvailableApps={templateApplications.filteredAvailableApps}\r\n loadingAvailableApps={templateApplications.loadingAvailableApps}\r\n selectedAppIds={templateApplications.selectedAppIds}\r\n assigningApps={templateApplications.assigningApps}\r\n appSearchTerm={templateApplications.appSearchTerm}\r\n selectedAccessLevel={templateApplications.selectedAccessLevel}\r\n bulkAccessMode={templateApplications.bulkAccessMode}\r\n bulkModules={templateApplications.bulkModules}\r\n bulkExpandedModules={templateApplications.bulkExpandedModules}\r\n loadingBulkModules={templateApplications.loadingBulkModules}\r\n // Customize drawer state\r\n showCustomizeDrawer={templateApplications.showCustomizeDrawer}\r\n customizingApp={templateApplications.customizingApp}\r\n // Actions\r\n onOpenAddApplication={templateApplications.loadAvailableApps}\r\n onCloseAddApplication={() => {\r\n templateApplications.setAddingApplication(false);\r\n templateApplications.setSelectedAppIds([]);\r\n templateApplications.setAppSearchTerm('');\r\n templateApplications.setSelectedAccessLevel('FullAccess');\r\n templateApplications.setBulkAccessMode('full');\r\n templateApplications.setBulkModules([]);\r\n templateApplications.setBulkExpandedModules(new Set());\r\n }}\r\n onAssignApplications={templateApplications.handleAssignApplications}\r\n onAppToggle={templateApplications.handleAppToggle}\r\n onSelectAllApps={templateApplications.selectAllFilteredApps}\r\n onClearAppSelection={templateApplications.clearAppSelection}\r\n onOpenCustomizeDrawer={templateApplications.openCustomizeDrawer}\r\n onCloseCustomizeDrawer={templateApplications.closeCustomizeDrawer}\r\n // Module handlers\r\n onLoadBulkModules={templateApplications.loadBulkModulesForApp}\r\n onToggleBulkModuleExpand={templateApplications.toggleBulkModuleExpand}\r\n onToggleBulkModule={templateApplications.toggleBulkModule}\r\n onToggleBulkSection={templateApplications.toggleBulkSection}\r\n onGetBulkModuleCheckState={templateApplications.getBulkModuleCheckState}\r\n onGetBulkStats={templateApplications.getBulkStats}\r\n onSelectAllBulkModules={templateApplications.selectAllBulkModules}\r\n onClearBulkModules={templateApplications.clearBulkModules}\r\n // Setters\r\n setAppSearchTerm={templateApplications.setAppSearchTerm}\r\n setSelectedAccessLevel={templateApplications.setSelectedAccessLevel}\r\n setBulkAccessMode={templateApplications.setBulkAccessMode}\r\n />\r\n )}\r\n {activeTab === 'tenants' && <TenantsTab templateId={templateId!} t={t} />}\r\n {activeTab === 'ai' && <AiInstancesTab templateId={templateId!} t={t} />}\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================================================\r\n// InfoTab\r\n// ============================================================================\r\n\r\nfunction InfoTab({ template, t }: InfoTabProps) {\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"bg-[var(--bg-card)] border border-[var(--border-color)] rounded-[var(--radius-card)] p-5\">\r\n <h3 className=\"font-semibold text-[var(--text-primary)] mb-4\">{t('templates.info.general')}</h3>\r\n <dl className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <div>\r\n <dt className=\"text-sm text-[var(--text-secondary)]\">{t('templates.info.code')}</dt>\r\n <dd className=\"font-mono text-[var(--text-primary)]\">{template.code}</dd>\r\n </div>\r\n <div>\r\n <dt className=\"text-sm text-[var(--text-secondary)]\">{t('templates.info.name')}</dt>\r\n <dd className=\"text-[var(--text-primary)]\">{template.name}</dd>\r\n </div>\r\n <div className=\"md:col-span-2\">\r\n <dt className=\"text-sm text-[var(--text-secondary)]\">{t('templates.info.description')}</dt>\r\n <dd className=\"text-[var(--text-primary)]\">{template.description || '-'}</dd>\r\n </div>\r\n </dl>\r\n </div>\r\n\r\n <div className=\"bg-[var(--bg-card)] border border-[var(--border-color)] rounded-[var(--radius-card)] p-5\">\r\n <h3 className=\"font-semibold text-[var(--text-primary)] mb-4\">{t('templates.info.stats')}</h3>\r\n <div className=\"grid grid-cols-3 gap-4\">\r\n <StatCard icon={<AppWindow className=\"w-5 h-5\" />} label={t('templates.tabs.applications')} value={template.applications.length} />\r\n <StatCard icon={<LayoutGrid className=\"w-5 h-5\" />} label={t('templates.tabs.tenants')} value={template.modules.length} />\r\n <StatCard icon={<Users className=\"w-5 h-5\" />} label={t('templates.tabs.tenants')} value={0} />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================================================\r\n// StatCard (memo for list rendering)\r\n// ============================================================================\r\n\r\nconst StatCard = memo(function StatCard({ icon, label, value }: StatCardProps) {\r\n return (\r\n <div className=\"flex items-center gap-3 p-3 bg-[var(--bg-secondary)] rounded-[var(--radius-card)]\">\r\n <span className=\"text-[var(--text-secondary)]\">{icon}</span>\r\n <div>\r\n <p className=\"text-2xl font-bold text-[var(--text-primary)]\">{value}</p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">{label}</p>\r\n </div>\r\n </div>\r\n );\r\n});\r\n\r\n// ============================================================================\r\n// TenantsTab\r\n// ============================================================================\r\n\r\nfunction TenantsTab({ templateId, t }: TenantsTabProps) {\r\n const [tenants, setTenants] = useState<TenantBasicDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [tabError, setTabError] = useState<string | null>(null);\r\n\r\n const loadTenants = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n setTabError(null);\r\n const data = await adminApi.templates.getTenants(templateId);\r\n setTenants(data);\r\n } catch {\r\n setTabError(t('templates.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [templateId, t]);\r\n\r\n useEffect(() => {\r\n loadTenants();\r\n }, [loadTenants]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (tabError) {\r\n return (\r\n <div className=\"p-4 bg-[var(--error-bg)] border border-[var(--error-border)] rounded-[var(--radius-card)]\">\r\n <div className=\"flex items-center\">\r\n <AlertCircle className=\"h-5 w-5 text-[var(--error-text)]\" />\r\n <span className=\"ml-2 text-[var(--error-text)]\">{tabError}</span>\r\n </div>\r\n <button\r\n onClick={() => loadTenants()}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:errors.retry')}\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"font-semibold text-[var(--text-primary)]\">\r\n {t('templates.tenants.title')} ({tenants.length})\r\n </h3>\r\n\r\n {tenants.length === 0 ? (\r\n <div className=\"p-8 text-center text-[var(--text-secondary)] bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <Users className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n <p>{t('templates.tenants.noTenants')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"bg-[var(--bg-card)] border border-[var(--border-color)] rounded-[var(--radius-card)] divide-y divide-[var(--border-color)]\">\r\n {tenants.map(tenant => (\r\n <Link\r\n key={tenant.id}\r\n to={`/administration/tenants/${tenant.id}`}\r\n className=\"flex items-center justify-between p-3 hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">{tenant.name}</p>\r\n <p className=\"text-xs text-[var(--text-tertiary)] font-mono\">{tenant.slug}</p>\r\n </div>\r\n <span className=\"text-xs text-[var(--text-secondary)] px-2 py-0.5 bg-[var(--bg-secondary)] rounded-[var(--radius-badge)]\">\r\n {t('templates.tenants.explicit')}\r\n </span>\r\n </Link>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================================================\r\n// AiInstancesTab\r\n// ============================================================================\r\n\r\nfunction AiInstancesTab({ templateId, t }: AiInstancesTabProps) {\r\n const [instances, setInstances] = useState<TemplateAiInstanceDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [tabError, setTabError] = useState<string | null>(null);\r\n\r\n const loadInstances = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n setTabError(null);\r\n const data = await adminApi.templates.getAiInstances(templateId);\r\n setInstances(data);\r\n } catch {\r\n setTabError(t('templates.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [templateId, t]);\r\n\r\n const handleRemove = useCallback(async (instanceId: string) => {\r\n if (!window.confirm(t('templates.ai.removeConfirm'))) return;\r\n try {\r\n await adminApi.templates.removeAiInstance(templateId, instanceId);\r\n await loadInstances();\r\n } catch {\r\n setTabError(t('templates.errors.loadFailed'));\r\n }\r\n }, [templateId, t, loadInstances]);\r\n\r\n useEffect(() => {\r\n loadInstances();\r\n }, [loadInstances]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (tabError) {\r\n return (\r\n <div className=\"p-4 bg-[var(--error-bg)] border border-[var(--error-border)] rounded-[var(--radius-card)]\">\r\n <div className=\"flex items-center\">\r\n <AlertCircle className=\"h-5 w-5 text-[var(--error-text)]\" />\r\n <span className=\"ml-2 text-[var(--error-text)]\">{tabError}</span>\r\n </div>\r\n <button\r\n onClick={() => loadInstances()}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:errors.retry')}\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"font-semibold text-[var(--text-primary)]\">\r\n {t('templates.ai.title')} ({instances.length})\r\n </h3>\r\n\r\n {instances.length === 0 ? (\r\n <div className=\"p-8 text-center text-[var(--text-secondary)] bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <Brain className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n <p>{t('templates.ai.noInstances')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"bg-[var(--bg-card)] border border-[var(--border-color)] rounded-[var(--radius-card)] divide-y divide-[var(--border-color)]\">\r\n {instances.map(instance => (\r\n <div\r\n key={instance.id}\r\n className=\"flex items-center justify-between p-3 hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">{instance.instanceName}</p>\r\n <p className=\"text-xs text-[var(--text-tertiary)] font-mono\">{instance.instanceCode}</p>\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n <span className={`text-xs px-2 py-0.5 rounded-[var(--radius-badge)] ${\r\n instance.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)]'\r\n }`}>\r\n {instance.isActive ? t('templates.ai.active') : t('templates.ai.inactive')}\r\n </span>\r\n <button\r\n onClick={() => handleRemove(instance.instanceId)}\r\n className=\"text-xs text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('templates.ai.remove')}\r\n </button>\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useEffect, useState, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { PageHeader } from '@/components/ui/PageHeader';\r\nimport { Settings2, Building, User, Boxes, Users, Loader2, AlertTriangle, Star, ArrowRight, Plus } from 'lucide-react';\r\nimport { adminApi, type TenantTemplateDto } from '@/services/api/adminApi';\r\n\r\nexport function TenantsTemplatePage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n const [templates, setTemplates] = useState<TenantTemplateDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const loadTemplates = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await adminApi.templates.getAll();\r\n setTemplates(data);\r\n setError(null);\r\n } catch {\r\n setError(t('tenants.template.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [t]);\r\n\r\n useEffect(() => {\r\n loadTemplates();\r\n }, [loadTemplates]);\r\n\r\n const handleCardClick = (templateId: string) => {\r\n navigate(`/administration/tenants/template/${templateId}`);\r\n };\r\n\r\n const systemTemplates = templates.filter(t => t.isDefault);\r\n const customTemplates = templates.filter(t => !t.isDefault);\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('tenants.template.title') }\r\n ]}\r\n />\r\n\r\n <PageHeader\r\n title={t('tenants.template.title')}\r\n subtitle={t('tenants.template.subtitle')}\r\n icon={<Settings2 className=\"w-6 h-6\" />}\r\n actions={\r\n <button\r\n onClick={() => navigate('/administration/tenants/template/create')}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.template.createTemplate')}\r\n </button>\r\n }\r\n />\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {loading && (\r\n <div className=\"flex justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n )}\r\n {!loading && templates.length === 0 && (\r\n <div className=\"p-6 text-center text-[var(--text-secondary)] bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n {t('tenants.template.noTemplates')}\r\n </div>\r\n )}\r\n {!loading && templates.length > 0 && (\r\n <div className=\"space-y-8\">\r\n {/* System Templates */}\r\n {systemTemplates.length > 0 && (\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('tenants.template.systemTemplates')}\r\n </h3>\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {systemTemplates.map(template => (\r\n <SystemTemplateCard\r\n key={template.id}\r\n template={template}\r\n onClick={() => handleCardClick(template.id)}\r\n t={t}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Custom Templates */}\r\n {customTemplates.length > 0 && (\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('tenants.template.customTemplates')}\r\n </h3>\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {customTemplates.map(template => (\r\n <CustomTemplateCard\r\n key={template.id}\r\n template={template}\r\n onClick={() => handleCardClick(template.id)}\r\n t={t}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction SystemTemplateCard({\r\n template,\r\n onClick,\r\n t\r\n}: {\r\n template: TenantTemplateDto;\r\n onClick: () => void;\r\n t: (key: string) => string;\r\n}) {\r\n const IconComponent = template.targetTenantType === 'Personal' ? User : Building;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={onClick}\r\n className=\"p-6 border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-card)] hover:bg-[var(--bg-hover)] hover:border-[var(--primary-color)] cursor-pointer transition-all duration-200 shadow-sm hover:shadow-md text-left w-full\"\r\n >\r\n <div className=\"space-y-4\">\r\n {/* Header */}\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2.5 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <IconComponent className=\"w-5 h-5 text-[var(--primary-color)]\" />\r\n </div>\r\n <div className=\"min-w-0 flex-1\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {template.targetTenantType === 'Personal'\r\n ? t('tenants.template.personalTitle')\r\n : t('tenants.template.businessTitle')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-tertiary)] font-mono\">{template.code}</p>\r\n </div>\r\n </div>\r\n <span className=\"flex items-center gap-1 px-2.5 py-1 rounded-[var(--radius-badge)] text-xs bg-[var(--accent-bg)] text-[var(--accent-text)] flex-shrink-0\">\r\n <Star className=\"w-3 h-3\" />\r\n {t('tenants.template.default')}\r\n </span>\r\n </div>\r\n\r\n {/* Description */}\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {template.targetTenantType === 'Personal'\r\n ? t('tenants.template.personalDescription')\r\n : t('tenants.template.businessDescription')}\r\n </p>\r\n\r\n {/* Status Badges */}\r\n <div className=\"flex items-center gap-2\">\r\n <span className={`px-2 py-0.5 rounded-[var(--radius-badge)] text-xs ${\r\n template.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)]'\r\n }`}>\r\n {template.isActive ? t('templates.active') : t('templates.inactive')}\r\n </span>\r\n </div>\r\n\r\n {/* Stats Grid */}\r\n <div className=\"grid grid-cols-2 gap-3 pt-2\">\r\n <div className=\"p-3 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <Boxes className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">{t('tenants.template.applications')}</span>\r\n </div>\r\n <div className=\"text-lg font-bold text-[var(--text-primary)]\">{template.applicationCount}</div>\r\n </div>\r\n <div className=\"p-3 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <Users className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">{t('tenants.template.tenants')}</span>\r\n </div>\r\n <div className=\"text-lg font-bold text-[var(--text-primary)]\">{template.tenantCount}</div>\r\n </div>\r\n </div>\r\n\r\n {/* CTA Button */}\r\n <span\r\n className=\"w-full mt-2 py-2 px-3 rounded-[var(--radius-button)] bg-[var(--primary-color)] text-white text-sm font-medium flex items-center justify-center gap-2 hover:opacity-90 transition-opacity\"\r\n >\r\n {t('tenants.template.configure')}\r\n <ArrowRight className=\"w-3.5 h-3.5\" />\r\n </span>\r\n </div>\r\n </button>\r\n );\r\n}\r\n\r\nfunction CustomTemplateCard({\r\n template,\r\n onClick,\r\n t\r\n}: {\r\n template: TenantTemplateDto;\r\n onClick: () => void;\r\n t: (key: string) => string;\r\n}) {\r\n const IconComponent = template.targetTenantType === 'Personal' ? User : Building;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={onClick}\r\n className=\"p-6 border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-card)] hover:bg-[var(--bg-hover)] hover:border-[var(--primary-color)] cursor-pointer transition-all duration-200 shadow-sm hover:shadow-md text-left w-full\"\r\n >\r\n <div className=\"space-y-4\">\r\n {/* Header */}\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2.5 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <IconComponent className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </div>\r\n <div className=\"min-w-0 flex-1\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {template.name}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-tertiary)] font-mono\">{template.code}</p>\r\n </div>\r\n </div>\r\n <span className={`px-2.5 py-1 rounded-[var(--radius-badge)] text-xs flex-shrink-0 ${\r\n template.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)]'\r\n }`}>\r\n {template.isActive ? t('templates.active') : t('templates.inactive')}\r\n </span>\r\n </div>\r\n\r\n {/* Description */}\r\n {template.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {template.description}\r\n </p>\r\n )}\r\n\r\n {/* Type badge */}\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"px-2 py-0.5 rounded-[var(--radius-badge)] text-xs bg-[var(--info-bg)] text-[var(--info-text)]\">\r\n {template.targetTenantType === 'Personal'\r\n ? t('tenants.type.personal')\r\n : t('tenants.type.business')}\r\n </span>\r\n </div>\r\n\r\n {/* Stats Grid */}\r\n <div className=\"grid grid-cols-2 gap-3 pt-2\">\r\n <div className=\"p-3 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <Boxes className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">{t('tenants.template.applications')}</span>\r\n </div>\r\n <div className=\"text-lg font-bold text-[var(--text-primary)]\">{template.applicationCount}</div>\r\n </div>\r\n <div className=\"p-3 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <Users className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">{t('tenants.template.tenants')}</span>\r\n </div>\r\n <div className=\"text-lg font-bold text-[var(--text-primary)]\">{template.tenantCount}</div>\r\n </div>\r\n </div>\r\n\r\n {/* CTA Button */}\r\n <span\r\n className=\"w-full mt-2 py-2 px-3 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] text-sm font-medium flex items-center justify-center gap-2 hover:bg-[var(--bg-hover)] transition-colors border border-[var(--border-color)]\"\r\n >\r\n {t('tenants.template.configure')}\r\n <ArrowRight className=\"w-3.5 h-3.5\" />\r\n </span>\r\n </div>\r\n </button>\r\n );\r\n}\r\n","import { useState } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { PageHeader } from '@/components/ui/PageHeader';\r\nimport { Settings2, Loader2, AlertTriangle, Check } from 'lucide-react';\r\nimport { adminApi, type TenantType } from '@/services/api/adminApi';\r\n\r\nexport function TenantTemplateCreatePage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n\r\n const [code, setCode] = useState('');\r\n const [name, setName] = useState('');\r\n const [description, setDescription] = useState('');\r\n const [targetTenantType, setTargetTenantType] = useState<TenantType>('Business');\r\n const [saving, setSaving] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (!code.trim() || !name.trim()) return;\r\n\r\n setSaving(true);\r\n setError(null);\r\n try {\r\n const result = await adminApi.templates.create({\r\n code: code.trim(),\r\n name: name.trim(),\r\n description: description.trim() || undefined,\r\n targetTenantType,\r\n });\r\n navigate(`/administration/tenants/template/${result.id}`);\r\n } catch (err) {\r\n console.error('Failed to create template:', err);\r\n const axiosError = err as { response?: { status?: number; data?: { message?: string } } };\r\n if (axiosError.response?.status === 409) {\r\n setError(axiosError.response.data?.message || t('tenants.template.errors.createConflict'));\r\n } else {\r\n setError(t('tenants.template.errors.createFailed'));\r\n }\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('tenants.template.title'), href: '/administration/tenants/template' },\r\n { label: t('tenants.template.createTitle') }\r\n ]}\r\n />\r\n\r\n <PageHeader\r\n title={t('tenants.template.createTitle')}\r\n subtitle={t('tenants.template.createSubtitle')}\r\n icon={<Settings2 className=\"w-6 h-6\" />}\r\n />\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className=\"max-w-2xl space-y-6\">\r\n <div className=\"p-6 rounded-[var(--radius-card)] bg-[var(--bg-card)] border border-[var(--border-color)] space-y-4\">\r\n {/* Code */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.template.code')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={code}\r\n onChange={(e) => setCode(e.target.value)}\r\n placeholder=\"e.g. custom-b2b-premium\"\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required\r\n />\r\n </div>\r\n\r\n {/* Name */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.template.name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={name}\r\n onChange={(e) => setName(e.target.value)}\r\n placeholder={t('tenants.template.namePlaceholder')}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required\r\n />\r\n </div>\r\n\r\n {/* Description */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('common:description')}\r\n </label>\r\n <textarea\r\n value={description}\r\n onChange={(e) => setDescription(e.target.value)}\r\n rows={3}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n\r\n {/* Target Tenant Type */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.template.targetType')} *\r\n </label>\r\n <select\r\n value={targetTenantType}\r\n onChange={(e) => setTargetTenantType(e.target.value as TenantType)}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"Business\">{t('tenants.type.business')}</option>\r\n <option value=\"Personal\">{t('tenants.type.personal')}</option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n {/* Actions */}\r\n <div className=\"flex items-center gap-3\">\r\n <button\r\n type=\"button\"\r\n onClick={() => navigate('/administration/tenants/template')}\r\n className=\"px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={!code.trim() || !name.trim() || saving}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {saving ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Check className=\"w-4 h-4\" />\r\n )}\r\n {t('common:create')}\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n );\r\n}\r\n","import type { ReactElement } from 'react';\nimport { TenantsPage } from './TenantsPage';\r\n\r\nexport function TenantsBusinessPage(): ReactElement {\r\n return <TenantsPage lockedType=\"Business\" />;\r\n}\r\n","import type { ReactElement } from 'react';\nimport { TenantsPage } from './TenantsPage';\r\n\r\nexport function TenantsPersonalPage(): ReactElement {\r\n return <TenantsPage lockedType=\"Personal\" />;\r\n}\r\n","import type { ReactElement } from 'react';\r\nimport { TenantsPage } from './TenantsPage';\r\n\r\nexport function TenantsOtherPage(): ReactElement {\r\n return <TenantsPage excludeTypes={['Business', 'Personal']} />;\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { PageHeader } from '@/components/ui/PageHeader';\r\nimport { AccessRequestsListTab } from '@/components/platform/administration/access-requests/AccessRequestsListTab';\r\nimport { accessRequestsApi } from '@/services/api/accessRequestsApi';\r\nimport type { AccessRequest } from '@/services/api/accessRequestsApi';\r\nimport { ShieldCheck, Loader2, Filter } from 'lucide-react';\r\n\r\nconst STATUS_FILTERS = ['all', 'Pending', 'Approved', 'Denied'] as const;\r\n\r\nexport function TenantAccessRequestsPage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const [requests, setRequests] = useState<AccessRequest[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [statusFilter, setStatusFilter] = useState<string>('all');\r\n\r\n const loadRequests = useCallback(async () => {\r\n setLoading(true);\r\n try {\r\n const status = statusFilter === 'all' ? undefined : statusFilter;\r\n const data = await accessRequestsApi.getAllRequests(status);\r\n setRequests(Array.isArray(data) ? data : []);\r\n } catch {\r\n setRequests([]);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [statusFilter]);\r\n\r\n useEffect(() => {\r\n loadRequests();\r\n }, [loadRequests]);\r\n\r\n const stats = {\r\n pending: requests.filter(r => r.status === 'Pending').length,\r\n approved: requests.filter(r => r.status === 'Approved').length,\r\n denied: requests.filter(r => r.status === 'Denied').length,\r\n };\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('accessRequests.pageTitle') },\r\n ]}\r\n />\r\n\r\n <PageHeader\r\n title={t('accessRequests.pageTitle')}\r\n icon={<ShieldCheck className=\"w-6 h-6\" />}\r\n />\r\n\r\n {/* Stats cards */}\r\n <div className=\"grid grid-cols-3 gap-4\">\r\n <div className=\"rounded-[var(--radius-card)] p-4 bg-[var(--bg-card)] border border-[var(--warning-border)]\">\r\n <div className=\"text-2xl font-bold text-[var(--warning-text)]\">{stats.pending}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">{t('accessRequests.stats.pending')}</div>\r\n </div>\r\n <div className=\"rounded-[var(--radius-card)] p-4 bg-[var(--bg-card)] border border-[var(--success-border)]\">\r\n <div className=\"text-2xl font-bold text-[var(--success-text)]\">{stats.approved}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">{t('accessRequests.stats.approved')}</div>\r\n </div>\r\n <div className=\"rounded-[var(--radius-card)] p-4 bg-[var(--bg-card)] border border-[var(--error-border)]\">\r\n <div className=\"text-2xl font-bold text-[var(--error-text)]\">{stats.denied}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">{t('accessRequests.stats.denied')}</div>\r\n </div>\r\n </div>\r\n\r\n {/* Status filter */}\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n <div className=\"flex gap-1\">\r\n {STATUS_FILTERS.map((status) => (\r\n <button\r\n key={status}\r\n onClick={() => setStatusFilter(status)}\r\n className={`px-3 py-1.5 rounded-[var(--radius-button)] text-sm font-medium transition-colors ${\r\n statusFilter === status\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n {status === 'all'\r\n ? t('accessRequests.filter.all')\r\n : t(`accessRequests.status.${status.toLowerCase()}`)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Requests table */}\r\n {loading ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (\r\n <AccessRequestsListTab\r\n requests={requests}\r\n loading={false}\r\n onReload={loadRequests}\r\n showTenantColumn\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback, useRef, useMemo } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { useSignalRContext, type NotificationDto as SignalRNotificationDto } from '@/contexts/SignalRContext';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport {\r\n Key,\r\n AlertTriangle,\r\n CheckCircle,\r\n Clock,\r\n Loader2,\r\n RefreshCw,\r\n Settings,\r\n Info,\r\n GitMerge,\r\n Users,\r\n Building2,\r\n Zap,\r\n Lock,\r\n Save,\r\n TestTube,\r\n Eye,\r\n EyeOff,\r\n ExternalLink,\r\n Shield,\r\n Copy,\r\n Check,\r\n Filter,\r\n Play,\r\n History,\r\n Square,\r\n} from 'lucide-react';\r\nimport { createEntraApi } from '@/services/api/entraApi';\r\nimport type {\r\n EntraConfigurationDto,\r\n EntraSyncConflictDto,\r\n ResolveConflictRequest,\r\n EntraSyncStatusDto,\r\n TestConnectionResult,\r\n EntraSyncResultDto,\r\n EntraSyncSessionDto,\r\n} from '@/services/api/entraApi';\r\nimport { ConflictCard, ResolutionModal } from '@/components/platform/administration/entra';\r\n\r\ninterface TenantEntraTabProps {\r\n readonly tenantId: string;\r\n readonly tenantName: string;\r\n readonly tenantSlug: string;\r\n}\r\n\r\n// Permission constants\r\nconst ENTRA_PERMISSIONS = {\r\n READ: 'administration.entra.read',\r\n UPDATE: 'administration.entra.update',\r\n SYNC: 'administration.entra.execute',\r\n};\r\n\r\n// Entra sync notification types\r\nconst ENTRA_SYNC_TYPES = {\r\n STARTED: 'EntraSyncStarted',\r\n COMPLETED: 'EntraSyncCompleted',\r\n FAILED: 'EntraSyncFailed',\r\n};\r\n\r\n// Required Graph API permissions\r\nconst REQUIRED_PERMISSIONS = [\r\n { code: 'User.Read.All', descriptionKey: 'userReadAll' },\r\n { code: 'Group.Read.All', descriptionKey: 'groupReadAll' },\r\n { code: 'GroupMember.Read.All', descriptionKey: 'groupMemberReadAll' },\r\n];\r\n\r\n// User types for sync\r\nconst USER_TYPES = [\r\n { id: 'member', labelKey: 'userTypes.member', descriptionKey: 'userTypes.memberDescription', supported: true },\r\n { id: 'guest', labelKey: 'userTypes.guest', descriptionKey: 'userTypes.guestDescription', supported: true },\r\n];\r\n\r\nconst calculateElapsedTime = (startedAt: Date): string => {\r\n const now = Date.now();\r\n const start = startedAt.getTime();\r\n const diffSeconds = Math.floor((now - start) / 1000);\r\n const minutes = Math.floor(diffSeconds / 60);\r\n const seconds = diffSeconds % 60;\r\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\r\n};\r\n\r\nconst handleEntraNotification = (\r\n notification: SignalRNotificationDto,\r\n setActiveSyncSession: any,\r\n loadData: () => void\r\n) => {\r\n if (notification.type === ENTRA_SYNC_TYPES.STARTED) {\r\n setActiveSyncSession({\r\n sessionId: notification.relatedEntityId || '',\r\n startedAt: new Date(notification.createdAt),\r\n });\r\n } else if (notification.type === ENTRA_SYNC_TYPES.COMPLETED || notification.type === ENTRA_SYNC_TYPES.FAILED) {\r\n setActiveSyncSession(null);\r\n loadData();\r\n }\r\n};\r\n\r\n// ============================================\r\n// Sub-tab Navigation\r\n// ============================================\r\n\r\ntype SubTabId = 'config' | 'sync' | 'users' | 'groups';\r\n\r\ninterface SubTab {\r\n id: SubTabId;\r\n label: string;\r\n icon: LucideIcon;\r\n permission: string;\r\n}\r\n\r\n// ============================================\r\n// Reusable Components\r\n// ============================================\r\n\r\ninterface SectionCardProps {\r\n readonly icon: LucideIcon;\r\n readonly title: string;\r\n readonly description?: string;\r\n readonly action?: React.ReactNode;\r\n readonly children: React.ReactNode;\r\n readonly className?: string;\r\n}\r\n\r\nfunction SectionCard({ icon: Icon, title, description, action, children, className = '' }: SectionCardProps) {\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] shadow-sm overflow-hidden ${className}`}>\r\n <div className=\"px-6 py-4 border-b border-[var(--border-subtle)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30\">\r\n <Icon className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <div>\r\n <h2 className=\"text-base font-semibold text-[var(--text-primary)]\">{title}</h2>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n </div>\r\n {action}\r\n </div>\r\n </div>\r\n <div className=\"p-6\">\r\n {children}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\ninterface ToggleProps {\r\n readonly checked: boolean;\r\n readonly onChange: () => void;\r\n readonly label: string;\r\n readonly description?: string;\r\n readonly disabled?: boolean;\r\n}\r\n\r\nfunction Toggle({ checked, onChange, label, description, disabled }: ToggleProps) {\r\n return (\r\n <div className=\"flex items-center justify-between py-3\">\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <label className=\"text-sm font-medium text-[var(--text-primary)]\">{label}</label>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n role=\"switch\"\r\n aria-checked={checked}\r\n onClick={onChange}\r\n disabled={disabled}\r\n className={`relative inline-flex h-6 w-11 flex-shrink-0 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] focus:ring-offset-2 focus:ring-offset-[var(--bg-primary)] disabled:opacity-50 disabled:cursor-not-allowed ${\r\n checked ? 'bg-[var(--color-accent-600)]' : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <span\r\n className={`inline-block h-4 w-4 transform rounded-full bg-white shadow-md transition-transform ${\r\n checked ? 'translate-x-6' : 'translate-x-1'\r\n }`}\r\n />\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\nconst isValidGuid = (value: string): boolean => {\r\n if (!value) return true;\r\n const guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\r\n return guidRegex.test(value);\r\n};\r\n\r\n// ============================================\r\n// Configuration Sub-Tab (Editable)\r\n// ============================================\r\n\r\n// Type for the entra API instance\r\ntype EntraApiInstance = ReturnType<typeof createEntraApi>;\r\n\r\ninterface ConfigTabProps {\r\n readonly config: EntraConfigurationDto | null;\r\n readonly loading: boolean;\r\n readonly canEdit: boolean;\r\n readonly onRefresh: () => void;\r\n readonly onConfigUpdated: () => void;\r\n readonly t: (key: string, options?: Record<string, unknown>) => string;\r\n readonly entraApi: EntraApiInstance;\r\n}\r\n\r\nconst ConfigTabReadOnly = ({ config, loading, canEdit, onRefresh, onEdit, t }: {\r\n config: EntraConfigurationDto | null;\r\n loading: boolean;\r\n canEdit: boolean;\r\n onRefresh: () => void;\r\n onEdit: () => void;\r\n t: (key: string, options?: Record<string, unknown>) => string;\r\n}) => (\r\n <SectionCard\r\n icon={Key}\r\n title={t('admin:tenants.entra.configuration.title')}\r\n description={t('admin:tenants.entra.configuration.description')}\r\n action={\r\n <div className=\"flex flex-col sm:flex-row items-stretch sm:items-center gap-2\">\r\n {canEdit && (\r\n <button\r\n onClick={onEdit}\r\n className=\"inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors\"\r\n >\r\n <Settings className=\"w-4 h-4\" />\r\n <span className=\"sm:inline\">{t('admin:tenants.entra.configuration.edit')}</span>\r\n </button>\r\n )}\r\n <button\r\n onClick={onRefresh}\r\n disabled={loading}\r\n className=\"inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-secondary)] hover:bg-[var(--bg-tertiary)] transition-colors disabled:opacity-50\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\r\n <span className=\"sm:inline\">{t('common:refresh')}</span>\r\n </button>\r\n </div>\r\n }\r\n >\r\n {config ? (\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n {config.isConfigured ? (\r\n <>\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.entra.configuration.configured')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.configuration.connectedTo', { tenantId: config.tenantId })}\r\n </p>\r\n </div>\r\n </>\r\n ) : (\r\n <>\r\n <Info className=\"w-5 h-5 text-[var(--warning-text)]\" />\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.entra.configuration.notConfigured')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.configuration.notConfiguredHint')}\r\n </p>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n\r\n {config.isConfigured && (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4\">\r\n <div className=\"p-3 sm:p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <Clock className=\"w-4 h-4 text-[var(--text-tertiary)] flex-shrink-0\" />\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.entra.configuration.syncStatus')}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {config.syncEnabled\r\n ? t('admin:tenants.entra.configuration.syncEnabled')\r\n : t('admin:tenants.entra.configuration.syncDisabled')}\r\n </p>\r\n </div>\r\n\r\n <div className=\"p-3 sm:p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <Settings className=\"w-4 h-4 text-[var(--text-tertiary)] flex-shrink-0\" />\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.entra.configuration.syncInterval')}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {config.syncIntervalMinutes} {t('common:minutes')}\r\n </p>\r\n </div>\r\n\r\n <div className=\"p-3 sm:p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)] sm:col-span-2 lg:col-span-1\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <GitMerge className=\"w-4 h-4 text-[var(--text-tertiary)] flex-shrink-0\" />\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.entra.configuration.conflictResolution')}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t(`entra:settings.conflictResolutions.${config.defaultConflictResolution?.toLowerCase() ?? 'manualreview'}`)}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.configuration.noData')}\r\n </p>\r\n )}\r\n </SectionCard>\r\n);\r\n\r\nfunction ConfigTab({ config, loading, canEdit, onRefresh, onConfigUpdated, t, entraApi }: ConfigTabProps) {\r\n const [editing, setEditing] = useState(false);\r\n const [saving, setSaving] = useState(false);\r\n const [testing, setTesting] = useState(false);\r\n const [testResult, setTestResult] = useState<TestConnectionResult | null>(null);\r\n const [showSecret, setShowSecret] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n const [copiedPermission, setCopiedPermission] = useState<string | null>(null);\r\n const [hasExistingSecret, setHasExistingSecret] = useState(config?.hasClientSecret ?? false);\r\n const [validationErrors, setValidationErrors] = useState<{ tenantId?: string; clientId?: string }>({});\r\n\r\n const [credentials, setCredentials] = useState({\r\n tenantId: config?.tenantId || '',\r\n clientId: config?.clientId || '',\r\n clientSecret: '',\r\n });\r\n\r\n const [syncSettings, setSyncSettings] = useState({\r\n syncEnabled: config?.syncEnabled ?? false,\r\n syncIntervalMinutes: config?.syncIntervalMinutes ?? 60,\r\n useDeltaSync: config?.useDeltaSync ?? true,\r\n defaultConflictResolution: (config?.defaultConflictResolution ?? 'ManualReview') as 'ManualReview' | 'EntraWins' | 'LocalWins',\r\n autoCreateReferences: config?.autoCreateReferences ?? true,\r\n syncOnlyActiveUsers: config?.syncOnlyActiveUsers ?? true,\r\n syncUserTypes: config?.syncUserTypes ?? 'member',\r\n });\r\n\r\n useEffect(() => {\r\n if (!config) return;\r\n setCredentials({\r\n tenantId: config.tenantId || '',\r\n clientId: config.clientId || '',\r\n clientSecret: '',\r\n });\r\n setHasExistingSecret(config.hasClientSecret);\r\n setSyncSettings({\r\n syncEnabled: config.syncEnabled,\r\n syncIntervalMinutes: config.syncIntervalMinutes,\r\n useDeltaSync: config.useDeltaSync,\r\n defaultConflictResolution: config.defaultConflictResolution as 'ManualReview' | 'EntraWins' | 'LocalWins',\r\n autoCreateReferences: config.autoCreateReferences,\r\n syncOnlyActiveUsers: config.syncOnlyActiveUsers ?? true,\r\n syncUserTypes: config.syncUserTypes ?? 'member',\r\n });\r\n }, [config]);\r\n\r\n const validateField = (field: 'tenantId' | 'clientId', value: string) => {\r\n const errorKey = !isValidGuid(value) ? t('entra:settings.invalidGuidFormat') : undefined;\r\n setValidationErrors(prev => ({ ...prev, [field]: errorKey }));\r\n };\r\n\r\n const handleCredentialChange = (field: keyof typeof credentials, value: string) => {\r\n setCredentials(prev => ({ ...prev, [field]: value }));\r\n if (field === 'tenantId' || field === 'clientId') {\r\n validateField(field, value);\r\n }\r\n };\r\n\r\n const hasValidationErrors = Boolean(validationErrors.tenantId || validationErrors.clientId);\r\n const canTestConnection = !testing && !hasValidationErrors && credentials.tenantId && credentials.clientId && (credentials.clientSecret || hasExistingSecret);\r\n const canSaveCredentials = !saving && !hasValidationErrors && credentials.tenantId && credentials.clientId && credentials.clientSecret;\r\n\r\n const handleCopyPermission = async (code: string) => {\r\n try {\r\n await navigator.clipboard.writeText(code);\r\n setCopiedPermission(code);\r\n setTimeout(() => setCopiedPermission(null), 2000);\r\n } catch (err) {\r\n console.error('Failed to copy:', err instanceof Error ? err.message : 'Unknown error');\r\n }\r\n };\r\n\r\n const handleTestConnection = async () => {\r\n if (!canTestConnection) return;\r\n setTesting(true);\r\n setTestResult(null);\r\n setError(null);\r\n setSuccess(null);\r\n try {\r\n const result = credentials.clientSecret\r\n ? await entraApi.settings.testConnection({\r\n tenantId: credentials.tenantId,\r\n clientId: credentials.clientId,\r\n clientSecret: credentials.clientSecret,\r\n })\r\n : await entraApi.settings.testStoredConnection();\r\n setTestResult(result);\r\n if (result.success) {\r\n setSuccess(t('entra:settings.testSuccess'));\r\n } else {\r\n setError(result.errorMessage || t('entra:settings.testFailed'));\r\n }\r\n } catch (err) {\r\n console.error('Connection test failed:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('entra:settings.testFailed'));\r\n } finally {\r\n setTesting(false);\r\n }\r\n };\r\n\r\n const handleSaveCredentials = async () => {\r\n if (!canSaveCredentials) return;\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n try {\r\n await entraApi.settings.saveCredentials({\r\n tenantId: credentials.tenantId,\r\n clientId: credentials.clientId,\r\n clientSecret: credentials.clientSecret,\r\n });\r\n setSuccess(t('entra:settings.credentialsSaved'));\r\n setHasExistingSecret(true);\r\n setCredentials(prev => ({ ...prev, clientSecret: '' }));\r\n onConfigUpdated();\r\n } catch (err) {\r\n console.error('Failed to save credentials:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('entra:settings.saveError'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleSaveSettings = async () => {\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n try {\r\n await entraApi.settings.saveSyncSettings({\r\n syncEnabled: syncSettings.syncEnabled,\r\n syncIntervalMinutes: syncSettings.syncIntervalMinutes,\r\n useDeltaSync: syncSettings.useDeltaSync,\r\n defaultConflictResolution: syncSettings.defaultConflictResolution,\r\n autoCreateReferences: syncSettings.autoCreateReferences,\r\n syncOnlyActiveUsers: syncSettings.syncOnlyActiveUsers,\r\n syncUserTypes: syncSettings.syncUserTypes,\r\n });\r\n setSuccess(t('entra:settings.settingsSaved'));\r\n onConfigUpdated();\r\n } catch (err) {\r\n console.error('Failed to save settings:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('entra:settings.saveError'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n if (!canEdit || !editing) {\r\n return <ConfigTabReadOnly config={config} loading={loading} canEdit={canEdit} onRefresh={onRefresh} onEdit={() => setEditing(true)} t={t} />;\r\n }\r\n\r\n // Editing view\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Required Permissions Warning */}\r\n <div className=\"rounded-[var(--radius-card)] border-2 border-[var(--warning-border)] bg-[var(--warning-bg)] p-4\">\r\n <div className=\"flex items-start gap-4\">\r\n <Shield className=\"w-5 h-5 text-[var(--warning-text)] mt-0.5\" />\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center justify-between gap-4 mb-2\">\r\n <h3 className=\"font-semibold text-[var(--warning-text)]\">\r\n {t('entra:settings.permissionsWarningTitle')}\r\n </h3>\r\n <a\r\n href=\"https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade\"\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--warning-border)] text-[var(--warning-text)] hover:opacity-80 transition-opacity\"\r\n >\r\n {t('entra:settings.configureInAzure')}\r\n <ExternalLink className=\"w-3.5 h-3.5\" />\r\n </a>\r\n </div>\r\n <p className=\"text-sm text-[var(--warning-text)] opacity-90 mb-3\">\r\n {t('entra:settings.permissionsWarningDescription')}\r\n </p>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {REQUIRED_PERMISSIONS.map((perm) => (\r\n <button\r\n key={perm.code}\r\n onClick={() => handleCopyPermission(perm.code)}\r\n className=\"group inline-flex items-center gap-2 px-3 py-2 rounded-[var(--radius-button)] bg-[var(--bg-primary)] border border-[var(--warning-border)] hover:shadow-sm transition-all\"\r\n >\r\n <code className=\"text-sm font-mono font-medium text-[var(--text-primary)]\">{perm.code}</code>\r\n {copiedPermission === perm.code ? (\r\n <Check className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n ) : (\r\n <Copy className=\"w-4 h-4 text-[var(--warning-text)]\" />\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Error/Success Messages */}\r\n {error && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">{error}</span>\r\n </div>\r\n )}\r\n {success && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n <span className=\"text-sm text-[var(--success-text)]\">{success}</span>\r\n </div>\r\n )}\r\n\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {/* Credentials Section */}\r\n <SectionCard icon={Key} title={t('entra:settings.credentials')} description=\"Azure AD Application\">\r\n <div className=\"space-y-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('entra:settings.tenantId')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n autoComplete=\"off\"\r\n value={credentials.tenantId}\r\n onChange={(e) => handleCredentialChange('tenantId', e.target.value)}\r\n placeholder=\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:border-transparent transition-shadow ${\r\n validationErrors.tenantId ? 'border-[var(--error-border)] focus:ring-[var(--error-border)]' : 'border-[var(--border-color)] focus:ring-[var(--color-accent-500)]'\r\n }`}\r\n />\r\n {validationErrors.tenantId && (\r\n <p className=\"mt-1.5 text-xs text-[var(--error-text)]\">{validationErrors.tenantId}</p>\r\n )}\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('entra:settings.clientId')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n autoComplete=\"off\"\r\n value={credentials.clientId}\r\n onChange={(e) => handleCredentialChange('clientId', e.target.value)}\r\n placeholder=\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:border-transparent transition-shadow ${\r\n validationErrors.clientId ? 'border-[var(--error-border)] focus:ring-[var(--error-border)]' : 'border-[var(--border-color)] focus:ring-[var(--color-accent-500)]'\r\n }`}\r\n />\r\n {validationErrors.clientId && (\r\n <p className=\"mt-1.5 text-xs text-[var(--error-text)]\">{validationErrors.clientId}</p>\r\n )}\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('entra:settings.clientSecret')}\r\n {hasExistingSecret && (\r\n <span className=\"ml-2 inline-flex items-center gap-1 text-xs text-[var(--success-text)]\">\r\n <CheckCircle className=\"w-3 h-3\" />\r\n {t('common:configured')}\r\n </span>\r\n )}\r\n </label>\r\n <div className=\"relative\">\r\n <input\r\n type={showSecret ? 'text' : 'password'}\r\n autoComplete=\"new-password\"\r\n value={credentials.clientSecret}\r\n onChange={(e) => handleCredentialChange('clientSecret', e.target.value)}\r\n placeholder={hasExistingSecret ? '••••••••••••••••' : 'OvA8Q~xxxxxxxxxxxx'}\r\n className=\"w-full px-3 py-2.5 pr-10 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow\"\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowSecret(!showSecret)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 text-[var(--text-tertiary)] hover:text-[var(--text-primary)]\"\r\n >\r\n {showSecret ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex flex-col sm:flex-row items-stretch sm:items-center gap-2 sm:gap-3 pt-2\">\r\n <button\r\n onClick={handleTestConnection}\r\n disabled={testing || hasValidationErrors || !credentials.tenantId || !credentials.clientId || (!credentials.clientSecret && !hasExistingSecret)}\r\n className=\"inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {testing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <TestTube className=\"w-4 h-4\" />}\r\n {t('entra:settings.testConnection')}\r\n </button>\r\n <button\r\n onClick={handleSaveCredentials}\r\n disabled={saving || hasValidationErrors || !credentials.tenantId || !credentials.clientId || !credentials.clientSecret}\r\n className=\"inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common:save')}\r\n </button>\r\n </div>\r\n\r\n {testResult?.success && (\r\n <div className=\"mt-4 p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n <span className=\"font-medium text-[var(--success-text)]\">{t('entra:settings.connectionSuccessful')}</span>\r\n </div>\r\n <div className=\"grid grid-cols-3 gap-3 text-sm\">\r\n {testResult.tenantName && <div><span className=\"text-[var(--text-tertiary)]\">Tenant:</span> {testResult.tenantName}</div>}\r\n {testResult.userCount !== null && <div><span className=\"text-[var(--text-tertiary)]\">Users:</span> {testResult.userCount}</div>}\r\n {testResult.groupCount !== null && <div><span className=\"text-[var(--text-tertiary)]\">Groups:</span> {testResult.groupCount}</div>}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Sync Settings */}\r\n <div className=\"space-y-6\">\r\n <SectionCard icon={Clock} title={t('entra:settings.syncSettings')} description=\"Scheduling & Performance\">\r\n <div className=\"divide-y divide-[var(--border-subtle)]\">\r\n <Toggle\r\n checked={syncSettings.syncEnabled}\r\n onChange={() => setSyncSettings(prev => ({ ...prev, syncEnabled: !prev.syncEnabled }))}\r\n label={t('entra:settings.syncEnabled')}\r\n description={t('entra:settings.syncEnabledHelp')}\r\n />\r\n <div className=\"py-4\">\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {t('entra:settings.syncInterval')}\r\n </label>\r\n <select\r\n value={syncSettings.syncIntervalMinutes}\r\n onChange={(e) => setSyncSettings(prev => ({ ...prev, syncIntervalMinutes: Number(e.target.value) }))}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value={15} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">15 {t('common:minutes')}</option>\r\n <option value={30} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">30 {t('common:minutes')}</option>\r\n <option value={60} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">1 {t('common:hour')}</option>\r\n <option value={120} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">2 {t('common:hours')}</option>\r\n <option value={360} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">6 {t('common:hours')}</option>\r\n <option value={720} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">12 {t('common:hours')}</option>\r\n <option value={1440} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">24 {t('common:hours')}</option>\r\n </select>\r\n </div>\r\n <Toggle\r\n checked={syncSettings.useDeltaSync}\r\n onChange={() => setSyncSettings(prev => ({ ...prev, useDeltaSync: !prev.useDeltaSync }))}\r\n label={t('entra:settings.useDeltaSync')}\r\n description={t('entra:settings.useDeltaSyncHelp')}\r\n />\r\n </div>\r\n </SectionCard>\r\n\r\n <SectionCard icon={GitMerge} title={t('entra:settings.conflictResolution')} description=\"Data Priority\">\r\n <select\r\n value={syncSettings.defaultConflictResolution}\r\n onChange={(e) => setSyncSettings(prev => ({ ...prev, defaultConflictResolution: e.target.value as 'ManualReview' | 'EntraWins' | 'LocalWins' }))}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"ManualReview\" className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">{t('entra:settings.conflictResolutions.manualReview')}</option>\r\n <option value=\"EntraWins\" className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">{t('entra:settings.conflictResolutions.entraWins')}</option>\r\n <option value=\"LocalWins\" className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">{t('entra:settings.conflictResolutions.localWins')}</option>\r\n </select>\r\n </SectionCard>\r\n\r\n <SectionCard icon={Filter} title={t('entra:settings.userSyncFilters')} description=\"User Types\">\r\n <div className=\"space-y-4\">\r\n <Toggle\r\n checked={syncSettings.syncOnlyActiveUsers}\r\n onChange={() => setSyncSettings(prev => ({ ...prev, syncOnlyActiveUsers: !prev.syncOnlyActiveUsers }))}\r\n label={t('entra:settings.syncOnlyActiveUsers')}\r\n description={t('entra:settings.syncOnlyActiveUsersHelp')}\r\n />\r\n <div className=\"space-y-2 pt-2 border-t border-[var(--border-subtle)]\">\r\n {USER_TYPES.map((userType) => {\r\n const selectedTypes = syncSettings.syncUserTypes.split(',').map(s => s.trim()).filter(Boolean);\r\n const isChecked = selectedTypes.includes(userType.id);\r\n return (\r\n <label\r\n key={userType.id}\r\n className={`flex items-center gap-3 p-3 rounded-[var(--radius-button)] border cursor-pointer transition-all ${\r\n isChecked ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20' : 'border-[var(--border-color)] bg-[var(--bg-secondary)] hover:bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={isChecked}\r\n onChange={() => {\r\n let newTypes = isChecked\r\n ? selectedTypes.filter(t => t !== userType.id)\r\n : [...selectedTypes, userType.id];\r\n if (newTypes.length === 0) newTypes = ['member'];\r\n setSyncSettings(prev => ({ ...prev, syncUserTypes: newTypes.join(',') }));\r\n }}\r\n className=\"w-4 h-4 rounded border-[var(--border-color)] text-[var(--color-accent-600)]\"\r\n />\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t(`entra:settings.${userType.labelKey}`)}\r\n </span>\r\n </label>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n </SectionCard>\r\n\r\n <div className=\"flex flex-col-reverse sm:flex-row items-stretch sm:items-center gap-2 sm:gap-3\">\r\n <button\r\n onClick={() => setEditing(false)}\r\n className=\"px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)] transition-colors text-center\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleSaveSettings}\r\n disabled={saving}\r\n className=\"inline-flex items-center justify-center gap-2 px-6 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 transition-colors shadow-sm\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common:save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Sync Status Badge & Icon Helpers\r\n// ============================================\r\n\r\nconst StatusBadgeMap = {\r\n Completed: { bg: 'bg-[var(--success-bg)]', text: 'text-[var(--success-text)]', icon: CheckCircle },\r\n PartiallyCompleted: { bg: 'bg-[var(--warning-bg)]', text: 'text-[var(--warning-text)]', icon: AlertTriangle },\r\n Failed: { bg: 'bg-[var(--error-bg)]', text: 'text-[var(--error-text)]', icon: AlertTriangle },\r\n InProgress: { bg: 'bg-[var(--color-accent-100)]', text: 'text-[var(--color-accent-700)]', icon: Loader2 },\r\n Cancelled: { bg: 'bg-[var(--bg-tertiary)]', text: 'text-[var(--text-tertiary)]', icon: Square },\r\n};\r\n\r\nconst SyncStatusIconMap = {\r\n Success: <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />,\r\n Failed: <AlertTriangle className=\"w-4 h-4 text-[var(--error-text)]\" />,\r\n Running: <Loader2 className=\"w-4 h-4 text-[var(--color-accent-500)] animate-spin\" />,\r\n};\r\n\r\nconst getStatusBadge = (status: string, t: (key: string) => string) => {\r\n const badge = StatusBadgeMap[status as keyof typeof StatusBadgeMap];\r\n if (!badge) {\r\n return <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--bg-tertiary)] text-[var(--text-tertiary)]\">{status}</span>;\r\n }\r\n const Icon = badge.icon;\r\n const label = t(`admin:tenants.entra.history.${status.toLowerCase()}`);\r\n return <span className={`inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full ${badge.bg} ${badge.text}`}><Icon className={badge.icon === Loader2 ? \"w-3 h-3 animate-spin\" : \"w-3 h-3\"} /> {label}</span>;\r\n};\r\n\r\nconst getSyncStatusIcon = (status: string) => {\r\n return SyncStatusIconMap[status as keyof typeof SyncStatusIconMap] || <Clock className=\"w-4 h-4 text-[var(--text-tertiary)]\" />;\r\n};\r\n\r\n// ============================================\r\n// Sync Sub-Tab\r\n// ============================================\r\n\r\ninterface SyncTabProps {\r\n readonly config: EntraConfigurationDto | null;\r\n readonly conflicts: EntraSyncConflictDto[];\r\n readonly syncStatus: EntraSyncStatusDto[];\r\n readonly loading: boolean;\r\n readonly canSync: boolean;\r\n readonly onRefresh: () => void;\r\n readonly onResolveConflict: (conflict: EntraSyncConflictDto) => void;\r\n readonly onSyncAll: () => Promise<EntraSyncResultDto | null>;\r\n readonly onLoadHistory: (page: number, pageSize: number) => Promise<{ sessions: EntraSyncSessionDto[]; totalCount: number } | null>;\r\n readonly onCancelSession: (sessionId: string) => Promise<boolean>;\r\n readonly activeSyncSession: { sessionId: string; startedAt: Date } | null;\r\n readonly t: (key: string, options?: Record<string, unknown>) => string;\r\n}\r\n\r\nconst formatDuration = (startedAt: string, completedAt: string | null): string => {\r\n if (!completedAt) return '-';\r\n const start = new Date(startedAt).getTime();\r\n const end = new Date(completedAt).getTime();\r\n const diffMs = end - start;\r\n if (diffMs < 1000) return `${diffMs}ms`;\r\n if (diffMs < 60000) return `${Math.round(diffMs / 1000)}s`;\r\n return `${Math.round(diffMs / 60000)}m`;\r\n};\r\n\r\nconst useSyncTabState = () => {\r\n const [syncing, setSyncing] = useState(false);\r\n const [lastSyncResult, setLastSyncResult] = useState<EntraSyncResultDto | null>(null);\r\n const [syncError, setSyncError] = useState<string | null>(null);\r\n const [history, setHistory] = useState<EntraSyncSessionDto[]>([]);\r\n const [historyLoading, setHistoryLoading] = useState(false);\r\n const [historyPage, setHistoryPage] = useState(1);\r\n const [historyTotalCount, setHistoryTotalCount] = useState(0);\r\n const [cancellingSessionId, setCancellingSessionId] = useState<string | null>(null);\r\n\r\n return {\r\n syncing, setSyncing, lastSyncResult, setLastSyncResult, syncError, setSyncError,\r\n history, setHistory, historyLoading, setHistoryLoading, historyPage, setHistoryPage,\r\n historyTotalCount, setHistoryTotalCount, cancellingSessionId, setCancellingSessionId\r\n };\r\n};\r\n\r\nfunction SyncTab({ config, conflicts, syncStatus, loading, canSync, onRefresh, onResolveConflict, onSyncAll, onLoadHistory, onCancelSession, activeSyncSession, t }: SyncTabProps) {\r\n const {\r\n syncing, setSyncing, lastSyncResult, setLastSyncResult, syncError, setSyncError,\r\n history, setHistory, historyLoading, setHistoryLoading, historyPage, setHistoryPage,\r\n historyTotalCount, setHistoryTotalCount, cancellingSessionId, setCancellingSessionId\r\n } = useSyncTabState();\r\n const historyPageSize = 5;\r\n\r\n const loadHistory = useCallback(async (page: number) => {\r\n setHistoryLoading(true);\r\n try {\r\n const result = await onLoadHistory(page, historyPageSize);\r\n if (!result) return;\r\n setHistory(result.sessions);\r\n setHistoryTotalCount(result.totalCount);\r\n setHistoryPage(page);\r\n } catch (err) {\r\n console.error('Failed to load history:', err);\r\n } finally {\r\n setHistoryLoading(false);\r\n }\r\n }, [onLoadHistory]);\r\n\r\n useEffect(() => {\r\n if (config?.isConfigured) {\r\n loadHistory(1);\r\n }\r\n }, [config?.isConfigured, loadHistory]);\r\n\r\n const handleSyncNow = async () => {\r\n setSyncing(true);\r\n setSyncError(null);\r\n setLastSyncResult(null);\r\n try {\r\n const result = await onSyncAll();\r\n if (!result) return;\r\n setLastSyncResult(result);\r\n onRefresh();\r\n loadHistory(1);\r\n } catch (err) {\r\n console.error('Sync failed:', err instanceof Error ? err.message : 'Unknown error');\r\n setSyncError(t('admin:tenants.entra.sync.syncFailed'));\r\n } finally {\r\n setSyncing(false);\r\n }\r\n };\r\n\r\n const handleCancelSession = async (sessionId: string) => {\r\n setCancellingSessionId(sessionId);\r\n try {\r\n const success = await onCancelSession(sessionId);\r\n if (success) {\r\n loadHistory(historyPage);\r\n }\r\n } catch (err) {\r\n console.error('Failed to cancel session:', err instanceof Error ? err.message : 'Unknown error');\r\n } finally {\r\n setCancellingSessionId(null);\r\n }\r\n };\r\n\r\n if (!config?.isConfigured) {\r\n return (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <Info className=\"w-5 h-5 text-[var(--warning-text)]\" />\r\n <span className=\"text-sm text-[var(--warning-text)]\">\r\n {t('admin:tenants.entra.sync.configureFirst')}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Sync Actions Card */}\r\n <SectionCard\r\n icon={Play}\r\n title={t('admin:tenants.entra.sync.actionsTitle')}\r\n description={t('admin:tenants.entra.sync.actionsDescription')}\r\n >\r\n <div className=\"space-y-4\">\r\n {/* Sync Button */}\r\n <div className=\"flex flex-col sm:flex-row items-start sm:items-center gap-3 sm:gap-4\">\r\n <button\r\n onClick={handleSyncNow}\r\n disabled={syncing || activeSyncSession !== null || !canSync}\r\n className=\"w-full sm:w-auto inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {syncing || activeSyncSession ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Play className=\"w-4 h-4\" />\r\n )}\r\n {syncing || activeSyncSession ? t('admin:tenants.entra.sync.syncing') : t('admin:tenants.entra.sync.syncNow')}\r\n </button>\r\n {!canSync && (\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">\r\n {t('admin:tenants.entra.sync.noSyncPermission')}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Sync Error */}\r\n {syncError && (\r\n <div className=\"flex items-center gap-3 p-3 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertTriangle className=\"w-4 h-4 text-[var(--error-text)]\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">{syncError}</span>\r\n </div>\r\n )}\r\n\r\n {/* Last Sync Result */}\r\n {lastSyncResult && (\r\n <div className={`p-4 rounded-[var(--radius-card)] border ${lastSyncResult.success ? 'bg-[var(--success-bg)] border-[var(--success-border)]' : 'bg-[var(--error-bg)] border-[var(--error-border)]'}`}>\r\n <div className=\"flex items-center gap-2 mb-3\">\r\n {lastSyncResult.success ? (\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n )}\r\n <span className={`font-medium ${lastSyncResult.success ? 'text-[var(--success-text)]' : 'text-[var(--error-text)]'}`}>\r\n {lastSyncResult.success ? t('admin:tenants.entra.sync.syncSuccess') : t('admin:tenants.entra.sync.syncFailed')}\r\n </span>\r\n </div>\r\n <div className=\"grid grid-cols-3 sm:grid-cols-5 gap-2 sm:gap-3 text-sm\">\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)] text-center sm:text-left\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.created')}</span>\r\n <p className=\"font-semibold text-[var(--success-text)]\">+{lastSyncResult.created}</p>\r\n </div>\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)] text-center sm:text-left\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.updated')}</span>\r\n <p className=\"font-semibold text-[var(--color-accent-600)]\">~{lastSyncResult.updated}</p>\r\n </div>\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)] text-center sm:text-left\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.deleted')}</span>\r\n <p className=\"font-semibold text-[var(--error-text)]\">-{lastSyncResult.deleted}</p>\r\n </div>\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)] text-center sm:text-left\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.skipped')}</span>\r\n <p className=\"font-semibold text-[var(--text-secondary)]\">{lastSyncResult.skipped}</p>\r\n </div>\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)] text-center sm:text-left col-span-3 sm:col-span-1\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.conflicts')}</span>\r\n <p className={`font-semibold ${lastSyncResult.conflicts > 0 ? 'text-[var(--warning-text)]' : 'text-[var(--text-primary)]'}`}>{lastSyncResult.conflicts}</p>\r\n </div>\r\n </div>\r\n {lastSyncResult.errorMessage && (\r\n <p className=\"mt-3 text-sm text-[var(--error-text)]\">{lastSyncResult.errorMessage}</p>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Sync Status Card */}\r\n <SectionCard\r\n icon={Zap}\r\n title={t('admin:tenants.entra.sync.statusTitle')}\r\n description={t('admin:tenants.entra.sync.statusDescription')}\r\n action={\r\n <button\r\n onClick={onRefresh}\r\n disabled={loading}\r\n className=\"inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-secondary)] hover:bg-[var(--bg-tertiary)] transition-colors disabled:opacity-50\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\r\n {t('common:refresh')}\r\n </button>\r\n }\r\n >\r\n {syncStatus.length > 0 ? (\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n {syncStatus.map((status) => (\r\n <div\r\n key={status.resourceType}\r\n className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\"\r\n >\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t(`entra:resourceTypes.${status.resourceType.toLowerCase()}`)}\r\n </span>\r\n {getSyncStatusIcon(status.status)}\r\n </div>\r\n <div className=\"space-y-1 text-xs text-[var(--text-tertiary)]\">\r\n <p>{t('admin:tenants.entra.sync.itemsSynced', { count: status.totalItemsSynced })}</p>\r\n {status.lastFullSyncAt && (\r\n <p>{t('admin:tenants.entra.sync.lastSync', { date: new Date(status.lastFullSyncAt).toLocaleDateString() })}</p>\r\n )}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n ) : (\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.sync.noStatus')}\r\n </p>\r\n )}\r\n </SectionCard>\r\n\r\n <SectionCard\r\n icon={AlertTriangle}\r\n title={t('admin:tenants.entra.conflicts.title')}\r\n description={t('admin:tenants.entra.conflicts.description', { count: conflicts.length })}\r\n >\r\n {conflicts.length === 0 ? (\r\n <div className=\"text-center py-8\">\r\n <div className=\"mx-auto w-12 h-12 rounded-full bg-[var(--success-bg)] flex items-center justify-center mb-3\">\r\n <CheckCircle className=\"w-6 h-6 text-[var(--success-text)]\" />\r\n </div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-1\">\r\n {t('entra:conflicts.noConflicts')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:conflicts.noConflictsDescription')}\r\n </p>\r\n </div>\r\n ) : (\r\n <div className=\"space-y-4\">\r\n {conflicts.map((conflict) => (\r\n <ConflictCard\r\n key={conflict.id}\r\n conflict={conflict}\r\n onResolve={onResolveConflict}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </SectionCard>\r\n\r\n {/* Sync History Card */}\r\n <SectionCard\r\n icon={History}\r\n title={t('admin:tenants.entra.history.title')}\r\n description={t('admin:tenants.entra.history.description')}\r\n action={\r\n <button\r\n onClick={() => loadHistory(historyPage)}\r\n disabled={historyLoading}\r\n className=\"inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-secondary)] hover:bg-[var(--bg-tertiary)] transition-colors disabled:opacity-50\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${historyLoading ? 'animate-spin' : ''}`} />\r\n {t('common:refresh')}\r\n </button>\r\n }\r\n >\r\n {historyLoading && history.length === 0 && (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n )}\r\n {!(historyLoading && history.length === 0) && history.length === 0 && (\r\n <div className=\"text-center py-8\">\r\n <div className=\"mx-auto w-12 h-12 rounded-full bg-[var(--bg-tertiary)] flex items-center justify-center mb-3\">\r\n <History className=\"w-6 h-6 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.history.noHistory')}\r\n </p>\r\n </div>\r\n )}\r\n {history.length > 0 && (\r\n <div className=\"space-y-4\">\r\n {/* Mobile: Card-based layout */}\r\n <div className=\"block sm:hidden space-y-3\">\r\n {history.map((session) => (\r\n <div key={session.id} className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <div className=\"flex items-center gap-2\">\r\n {session.isFullSync ? (\r\n <span className=\"px-2 py-0.5 text-xs rounded bg-[var(--color-accent-100)] text-[var(--color-accent-700)]\">{t('admin:tenants.entra.history.fullSync')}</span>\r\n ) : (\r\n <span className=\"px-2 py-0.5 text-xs rounded bg-[var(--bg-tertiary)] text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.deltaSync')}</span>\r\n )}\r\n {getStatusBadge(session.status, t)}\r\n </div>\r\n {session.status === 'InProgress' && canSync && (\r\n <button\r\n onClick={() => handleCancelSession(session.id)}\r\n disabled={cancellingSessionId === session.id}\r\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs font-medium rounded-[var(--radius-button)] bg-[var(--error-bg)] text-[var(--error-text)]\"\r\n >\r\n {cancellingSessionId === session.id ? <Loader2 className=\"w-3 h-3 animate-spin\" /> : <Square className=\"w-3 h-3\" />}\r\n {t('common:cancel')}\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"text-xs text-[var(--text-tertiary)] mb-2\">\r\n {new Date(session.startedAt).toLocaleString()} • {formatDuration(session.startedAt, session.completedAt)}\r\n </div>\r\n <div className=\"grid grid-cols-3 gap-2 text-center\">\r\n <div className=\"p-1.5 rounded bg-[var(--bg-primary)]\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.created')}</span>\r\n <span className=\"font-medium text-[var(--success-text)]\">+{session.created}</span>\r\n </div>\r\n <div className=\"p-1.5 rounded bg-[var(--bg-primary)]\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.updated')}</span>\r\n <span className=\"font-medium text-[var(--color-accent-600)]\">~{session.updated}</span>\r\n </div>\r\n <div className=\"p-1.5 rounded bg-[var(--bg-primary)]\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.deleted')}</span>\r\n <span className=\"font-medium text-[var(--error-text)]\">-{session.deleted}</span>\r\n </div>\r\n </div>\r\n <div className=\"mt-2 pt-2 border-t border-[var(--border-subtle)] text-xs text-[var(--text-secondary)]\">\r\n {session.triggerType === 'Manual' ? (\r\n <span className=\"flex items-center gap-1\">\r\n <Users className=\"w-3 h-3\" />\r\n {session.triggeredByUserName || t('admin:tenants.entra.history.unknownUser')}\r\n </span>\r\n ) : (\r\n <span className=\"flex items-center gap-1 text-[var(--text-tertiary)]\">\r\n <Clock className=\"w-3 h-3\" />\r\n {t('admin:tenants.entra.history.scheduled')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Desktop: Table layout */}\r\n <div className=\"hidden sm:block overflow-x-auto\">\r\n <table className=\"w-full text-sm\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)]\">\r\n <th className=\"text-left py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.date')}</th>\r\n <th className=\"text-left py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.type')}</th>\r\n <th className=\"text-left py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.status')}</th>\r\n <th className=\"text-right py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.duration')}</th>\r\n <th className=\"text-right py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.sync.created')}</th>\r\n <th className=\"text-right py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.sync.updated')}</th>\r\n <th className=\"text-right py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.sync.deleted')}</th>\r\n <th className=\"text-left py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.triggeredBy')}</th>\r\n <th className=\"text-center py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('common:actionsColumn')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {history.map((session) => (\r\n <tr key={session.id} className=\"border-b border-[var(--border-subtle)] hover:bg-[var(--bg-secondary)]\">\r\n <td className=\"py-2 px-3 text-[var(--text-primary)]\">\r\n {new Date(session.startedAt).toLocaleString()}\r\n </td>\r\n <td className=\"py-2 px-3\">\r\n <span className=\"inline-flex items-center gap-1 text-xs\">\r\n {session.isFullSync ? (\r\n <span className=\"px-2 py-0.5 rounded bg-[var(--color-accent-100)] text-[var(--color-accent-700)]\">{t('admin:tenants.entra.history.fullSync')}</span>\r\n ) : (\r\n <span className=\"px-2 py-0.5 rounded bg-[var(--bg-tertiary)] text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.deltaSync')}</span>\r\n )}\r\n </span>\r\n </td>\r\n <td className=\"py-2 px-3\">\r\n {getStatusBadge(session.status, t)}\r\n </td>\r\n <td className=\"py-2 px-3 text-right text-[var(--text-secondary)]\">\r\n {formatDuration(session.startedAt, session.completedAt)}\r\n </td>\r\n <td className=\"py-2 px-3 text-right text-[var(--success-text)] font-medium\">\r\n +{session.created}\r\n </td>\r\n <td className=\"py-2 px-3 text-right text-[var(--color-accent-600)] font-medium\">\r\n ~{session.updated}\r\n </td>\r\n <td className=\"py-2 px-3 text-right text-[var(--error-text)] font-medium\">\r\n -{session.deleted}\r\n </td>\r\n <td className=\"py-2 px-3 text-[var(--text-secondary)]\">\r\n {session.triggerType === 'Manual' ? (\r\n <span className=\"flex items-center gap-1\">\r\n <Users className=\"w-3 h-3\" />\r\n {session.triggeredByUserName || t('admin:tenants.entra.history.unknownUser')}\r\n </span>\r\n ) : (\r\n <span className=\"flex items-center gap-1 text-[var(--text-tertiary)]\">\r\n <Clock className=\"w-3 h-3\" />\r\n {t('admin:tenants.entra.history.scheduled')}\r\n </span>\r\n )}\r\n </td>\r\n <td className=\"py-2 px-3 text-center\">\r\n {session.status === 'InProgress' && canSync && (\r\n <button\r\n onClick={() => handleCancelSession(session.id)}\r\n disabled={cancellingSessionId === session.id}\r\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs font-medium rounded-[var(--radius-button)] bg-[var(--error-bg)] text-[var(--error-text)] hover:bg-[var(--error-border)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('admin:tenants.entra.history.cancelSync')}\r\n >\r\n {cancellingSessionId === session.id ? (\r\n <Loader2 className=\"w-3 h-3 animate-spin\" />\r\n ) : (\r\n <Square className=\"w-3 h-3\" />\r\n )}\r\n {t('common:cancel')}\r\n </button>\r\n )}\r\n </td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* Pagination */}\r\n {historyTotalCount > historyPageSize && (\r\n <div className=\"flex items-center justify-between pt-4 border-t border-[var(--border-subtle)]\">\r\n <span className=\"text-sm text-[var(--text-tertiary)]\">\r\n {t('admin:tenants.entra.history.showing', {\r\n from: (historyPage - 1) * historyPageSize + 1,\r\n to: Math.min(historyPage * historyPageSize, historyTotalCount),\r\n total: historyTotalCount\r\n })}\r\n </span>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => loadHistory(historyPage - 1)}\r\n disabled={historyPage === 1 || historyLoading}\r\n className=\"px-3 py-1.5 text-sm rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-secondary)] hover:bg-[var(--bg-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n {t('common:previous')}\r\n </button>\r\n <button\r\n onClick={() => loadHistory(historyPage + 1)}\r\n disabled={historyPage * historyPageSize >= historyTotalCount || historyLoading}\r\n className=\"px-3 py-1.5 text-sm rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-secondary)] hover:bg-[var(--bg-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n {t('common:next')}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </SectionCard>\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Users Sub-Tab (Placeholder)\r\n// ============================================\r\n\r\ninterface UsersTabProps {\r\n readonly config: EntraConfigurationDto | null;\r\n readonly t: (key: string, options?: Record<string, unknown>) => string;\r\n}\r\n\r\nfunction UsersTab({ config, t }: UsersTabProps) {\r\n if (!config?.isConfigured) {\r\n return (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <Info className=\"w-5 h-5 text-[var(--warning-text)]\" />\r\n <span className=\"text-sm text-[var(--warning-text)]\">\r\n {t('admin:tenants.entra.users.configureFirst')}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <SectionCard\r\n icon={Users}\r\n title={t('admin:tenants.entra.users.title')}\r\n description={t('admin:tenants.entra.users.description')}\r\n >\r\n <div className=\"text-center py-8\">\r\n <div className=\"mx-auto w-12 h-12 rounded-full bg-[var(--bg-secondary)] flex items-center justify-center mb-3\">\r\n <Users className=\"w-6 h-6 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-1\">\r\n {t('admin:tenants.entra.users.comingSoon')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.users.comingSoonDescription')}\r\n </p>\r\n </div>\r\n </SectionCard>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Groups Sub-Tab (Placeholder)\r\n// ============================================\r\n\r\ninterface GroupsTabProps {\r\n readonly config: EntraConfigurationDto | null;\r\n readonly t: (key: string, options?: Record<string, unknown>) => string;\r\n}\r\n\r\nfunction GroupsTab({ config, t }: GroupsTabProps) {\r\n if (!config?.isConfigured) {\r\n return (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <Info className=\"w-5 h-5 text-[var(--warning-text)]\" />\r\n <span className=\"text-sm text-[var(--warning-text)]\">\r\n {t('admin:tenants.entra.groups.configureFirst')}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <SectionCard\r\n icon={Building2}\r\n title={t('admin:tenants.entra.groups.title')}\r\n description={t('admin:tenants.entra.groups.description')}\r\n >\r\n <div className=\"text-center py-8\">\r\n <div className=\"mx-auto w-12 h-12 rounded-full bg-[var(--bg-secondary)] flex items-center justify-center mb-3\">\r\n <Building2 className=\"w-6 h-6 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-1\">\r\n {t('admin:tenants.entra.groups.comingSoon')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.groups.comingSoonDescription')}\r\n </p>\r\n </div>\r\n </SectionCard>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Main Component\r\n// ============================================\r\n\r\nexport function TenantEntraTab({ tenantId, tenantSlug }: TenantEntraTabProps): ReactElement {\r\n const { t } = useTranslation(['admin', 'entra', 'common']);\r\n const { hasPermission } = useAuth();\r\n const { isConnected, onNotification } = useSignalRContext();\r\n const [activeSubTab, setActiveSubTab] = useState<SubTabId>('config');\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n // Create API instance with tenant context\r\n // This ensures all API calls include the correct X-Tenant-Slug header\r\n const entraApi = useMemo(() => createEntraApi(tenantSlug), [tenantSlug]);\r\n\r\n // Data state\r\n const [config, setConfig] = useState<EntraConfigurationDto | null>(null);\r\n const [conflicts, setConflicts] = useState<EntraSyncConflictDto[]>([]);\r\n const [syncStatus, setSyncStatus] = useState<EntraSyncStatusDto[]>([]);\r\n const [selectedConflict, setSelectedConflict] = useState<EntraSyncConflictDto | null>(null);\r\n const [resolving, setResolving] = useState(false);\r\n\r\n // Real-time sync state\r\n const [activeSyncSession, setActiveSyncSession] = useState<{ sessionId: string; startedAt: Date } | null>(null);\r\n const [syncElapsedTime, setSyncElapsedTime] = useState<string>('00:00');\r\n\r\n // Abort controller\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n const isLoadingRef = useRef(false);\r\n\r\n // Permissions\r\n const canRead = hasPermission(ENTRA_PERMISSIONS.READ);\r\n const canEdit = hasPermission(ENTRA_PERMISSIONS.UPDATE);\r\n const canSync = hasPermission(ENTRA_PERMISSIONS.SYNC);\r\n\r\n // Define sub-tabs\r\n const subTabs: SubTab[] = [\r\n { id: 'config', label: t('admin:tenants.entra.tabs.config'), icon: Key, permission: ENTRA_PERMISSIONS.READ },\r\n { id: 'sync', label: t('admin:tenants.entra.tabs.sync'), icon: Zap, permission: ENTRA_PERMISSIONS.SYNC },\r\n { id: 'users', label: t('admin:tenants.entra.tabs.users'), icon: Users, permission: ENTRA_PERMISSIONS.READ },\r\n { id: 'groups', label: t('admin:tenants.entra.tabs.groups'), icon: Building2, permission: ENTRA_PERMISSIONS.READ },\r\n ];\r\n\r\n const availableTabs = subTabs.filter((tab) => hasPermission(tab.permission));\r\n\r\n useEffect(() => {\r\n if (availableTabs.length > 0 && !availableTabs.find((tab) => tab.id === activeSubTab)) {\r\n setActiveSubTab(availableTabs[0].id);\r\n }\r\n }, [availableTabs, activeSubTab]);\r\n\r\n const loadData = useCallback(async () => {\r\n if (isLoadingRef.current) return;\r\n\r\n if (!canRead) {\r\n setLoading(false);\r\n return;\r\n }\r\n\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n\r\n abortControllerRef.current = new AbortController();\r\n isLoadingRef.current = true;\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n const [configData, conflictsData, syncStatusData] = await Promise.all([\r\n entraApi.settings.getConfiguration(),\r\n entraApi.conflicts.getAll(),\r\n entraApi.dashboard.getSyncStatus(),\r\n ]);\r\n\r\n setConfig(configData ?? null);\r\n setConflicts(Array.isArray(conflictsData) ? conflictsData : []);\r\n setSyncStatus(Array.isArray(syncStatusData) ? syncStatusData : []);\r\n } catch (err) {\r\n if (err instanceof Error && err.name === 'AbortError') return;\r\n console.error('Failed to load Entra data:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('admin:tenants.entra.loadError'));\r\n } finally {\r\n isLoadingRef.current = false;\r\n setLoading(false);\r\n }\r\n }, [entraApi, t, canRead]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n return () => {\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n };\r\n }, [loadData, tenantId]);\r\n\r\n // Subscribe to SignalR notifications for real-time updates\r\n useEffect(() => {\r\n const unsubscribe = onNotification((notification: SignalRNotificationDto) => {\r\n handleEntraNotification(notification, setActiveSyncSession, loadData);\r\n });\r\n\r\n return unsubscribe;\r\n }, [onNotification, loadData]);\r\n\r\n // Timer for active sync session elapsed time\r\n useEffect(() => {\r\n if (!activeSyncSession) {\r\n setSyncElapsedTime('00:00');\r\n return;\r\n }\r\n\r\n setSyncElapsedTime(calculateElapsedTime(activeSyncSession.startedAt));\r\n const interval = setInterval(() => {\r\n setSyncElapsedTime(calculateElapsedTime(activeSyncSession.startedAt));\r\n }, 1000);\r\n\r\n return () => clearInterval(interval);\r\n }, [activeSyncSession]);\r\n\r\n const handleResolve = useCallback(async (resolution: ResolveConflictRequest['resolution'], notes?: string) => {\r\n if (!selectedConflict || resolving) return;\r\n\r\n setResolving(true);\r\n try {\r\n await entraApi.conflicts.resolve(selectedConflict.id, {\r\n resolution,\r\n notes: notes || undefined,\r\n });\r\n setSelectedConflict(null);\r\n await loadData();\r\n } catch (err) {\r\n console.error('Failed to resolve conflict:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('entra:conflicts.resolveError'));\r\n } finally {\r\n setResolving(false);\r\n }\r\n }, [entraApi, selectedConflict, resolving, loadData, t]);\r\n\r\n const handleSyncAll = useCallback(async (): Promise<EntraSyncResultDto | null> => {\r\n try {\r\n const result = await entraApi.sync.syncAll();\r\n return result;\r\n } catch (err) {\r\n console.error('Sync all failed:', err instanceof Error ? err.message : 'Unknown error');\r\n throw err;\r\n }\r\n }, [entraApi]);\r\n\r\n const handleLoadHistory = useCallback(async (page: number, pageSize: number): Promise<{ sessions: EntraSyncSessionDto[]; totalCount: number } | null> => {\r\n try {\r\n const result = await entraApi.sync.getHistory(page, pageSize);\r\n return result;\r\n } catch (err) {\r\n console.error('Failed to load history:', err instanceof Error ? err.message : 'Unknown error');\r\n return null;\r\n }\r\n }, [entraApi]);\r\n\r\n const handleCancelSession = useCallback(async (sessionId: string): Promise<boolean> => {\r\n try {\r\n await entraApi.sync.cancelSession(sessionId);\r\n return true;\r\n } catch (err) {\r\n console.error('Failed to cancel session:', err instanceof Error ? err.message : 'Unknown error');\r\n return false;\r\n }\r\n }, [entraApi]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center py-12\">\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 if (availableTabs.length === 0) {\r\n return (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <Lock className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">\r\n {t('admin:tenants.entra.noPermission')}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {error && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">{error}</span>\r\n <button onClick={() => setError(null)} className=\"ml-auto text-[var(--error-text)] hover:opacity-70\">×</button>\r\n </div>\r\n )}\r\n\r\n {/* Active Sync Banner */}\r\n {activeSyncSession && (\r\n <div className=\"flex flex-col sm:flex-row items-start sm:items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20 border border-[var(--color-accent-200)] dark:border-[var(--color-accent-800)]\">\r\n <div className=\"flex items-center gap-3 flex-1\">\r\n <RefreshCw className=\"w-5 h-5 text-[var(--color-accent-600)] animate-spin flex-shrink-0\" />\r\n <div className=\"min-w-0\">\r\n <p className=\"font-medium text-[var(--color-accent-700)] dark:text-[var(--color-accent-400)]\">\r\n {t('admin:tenants.entra.sync.syncInProgress')}\r\n </p>\r\n <p className=\"text-sm text-[var(--color-accent-600)] dark:text-[var(--color-accent-500)] truncate\">\r\n {t('admin:tenants.entra.sync.syncInProgressDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 self-end sm:self-auto\">\r\n <span className=\"text-lg font-mono font-bold text-[var(--color-accent-700)] dark:text-[var(--color-accent-400)] bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/50 px-3 py-1 rounded\">\r\n ⏱ {syncElapsedTime}\r\n </span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Sub-tab Navigation */}\r\n <div className=\"flex flex-col sm:flex-row items-stretch sm:items-center gap-1 p-1 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <div className=\"flex flex-wrap items-center gap-1 flex-1\">\r\n {availableTabs.map((tab) => {\r\n const Icon = tab.icon;\r\n const isActive = activeSubTab === tab.id;\r\n // Show badge for sync tab when there are conflicts\r\n const showConflictBadge = tab.id === 'sync' && conflicts.length > 0;\r\n return (\r\n <button\r\n key={tab.id}\r\n onClick={() => setActiveSubTab(tab.id)}\r\n className={`flex items-center gap-2 px-3 sm:px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] transition-all flex-1 sm:flex-none justify-center sm:justify-start ${\r\n isActive\r\n ? 'bg-[var(--bg-card)] text-[var(--text-primary)] shadow-sm'\r\n : 'text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <Icon className=\"w-4 h-4\" />\r\n <span className=\"hidden sm:inline\">{tab.label}</span>\r\n {showConflictBadge && (\r\n <span className=\"ml-1 px-1.5 py-0.5 text-xs font-bold rounded-full bg-[var(--warning-bg)] text-[var(--warning-text)]\">\r\n {conflicts.length}\r\n </span>\r\n )}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n {/* Connection status indicator */}\r\n <div className=\"flex items-center justify-center sm:justify-end gap-2 px-2 py-1 border-t sm:border-t-0 sm:border-l border-[var(--border-subtle)] mt-1 sm:mt-0 pt-2 sm:pt-0\">\r\n {isConnected ? (\r\n <span className=\"flex items-center gap-1.5 text-xs text-[var(--success-text)]\" title={t('admin:tenants.entra.realTimeConnected')}>\r\n <span className=\"w-2 h-2 rounded-full bg-[var(--success-text)] animate-pulse\" />\r\n <span className=\"hidden sm:inline\">{t('common:live')}</span>\r\n </span>\r\n ) : (\r\n <span className=\"flex items-center gap-1.5 text-xs text-[var(--text-tertiary)]\" title={t('admin:tenants.entra.realTimeDisconnected')}>\r\n <span className=\"w-2 h-2 rounded-full bg-[var(--text-tertiary)]\" />\r\n <span className=\"hidden sm:inline\">{t('common:offline')}</span>\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Sub-tab Content */}\r\n {activeSubTab === 'config' && (\r\n <ConfigTab\r\n config={config}\r\n loading={loading}\r\n canEdit={canEdit}\r\n onRefresh={loadData}\r\n onConfigUpdated={loadData}\r\n t={t}\r\n entraApi={entraApi}\r\n />\r\n )}\r\n {activeSubTab === 'sync' && (\r\n <SyncTab\r\n config={config}\r\n conflicts={conflicts}\r\n syncStatus={syncStatus}\r\n loading={loading}\r\n canSync={canSync}\r\n onRefresh={loadData}\r\n onResolveConflict={setSelectedConflict}\r\n onSyncAll={handleSyncAll}\r\n onLoadHistory={handleLoadHistory}\r\n onCancelSession={handleCancelSession}\r\n activeSyncSession={activeSyncSession}\r\n t={t}\r\n />\r\n )}\r\n {activeSubTab === 'users' && <UsersTab config={config} t={t} />}\r\n {activeSubTab === 'groups' && <GroupsTab config={config} t={t} />}\r\n\r\n {/* Resolution Modal */}\r\n {selectedConflict && (\r\n <ResolutionModal\r\n conflict={selectedConflict}\r\n onClose={() => setSelectedConflict(null)}\r\n onResolve={handleResolve}\r\n resolving={resolving}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport type { TFunction } from 'i18next';\r\nimport {\r\n Settings,\r\n Save,\r\n Loader2,\r\n CheckCircle,\r\n AlertTriangle,\r\n TestTube,\r\n Eye,\r\n EyeOff,\r\n RefreshCw,\r\n Clock,\r\n Zap,\r\n ExternalLink,\r\n Info,\r\n} from 'lucide-react';\r\nimport { Tooltip } from '@/components/ui/Tooltip';\r\nimport {\r\n ticketingApi,\r\n type TenantTicketingConfigurationDto,\r\n type SaveTicketingConfigurationRequest,\r\n type TicketingSyncResultDto,\r\n} from '@/services/api/ticketingApi';\r\n\r\nfunction validateGlpiConfig(fields: {\r\n glpiBaseUrl: string;\r\n glpiClientId: string;\r\n glpiClientSecret: string;\r\n glpiUsername: string;\r\n glpiPassword: string;\r\n}, config: TenantTicketingConfigurationDto | null, t: TFunction): Record<string, string> {\r\n const errors: Record<string, string> = {};\r\n\r\n if (!fields.glpiBaseUrl.trim()) {\r\n errors.glpiBaseUrl = t('admin:tenants.ticketing.validation.baseUrlRequired');\r\n } else {\r\n try {\r\n new URL(fields.glpiBaseUrl);\r\n } catch {\r\n errors.glpiBaseUrl = t('admin:tenants.ticketing.validation.baseUrlInvalid');\r\n }\r\n }\r\n if (!fields.glpiClientId.trim()) {\r\n errors.glpiClientId = t('admin:tenants.ticketing.validation.clientIdRequired');\r\n }\r\n if (!fields.glpiClientSecret && !config?.hasGlpiClientSecret) {\r\n errors.glpiClientSecret = t('admin:tenants.ticketing.validation.clientSecretRequired');\r\n }\r\n if (!fields.glpiUsername.trim()) {\r\n errors.glpiUsername = t('admin:tenants.ticketing.validation.usernameRequired');\r\n }\r\n if (!fields.glpiPassword && !config?.hasGlpiPassword) {\r\n errors.glpiPassword = t('admin:tenants.ticketing.validation.passwordRequired');\r\n }\r\n\r\n return errors;\r\n}\r\n\r\nfunction buildGlpiSaveRequest(fields: {\r\n glpiBaseUrl: string;\r\n glpiClientId: string;\r\n glpiClientSecret: string;\r\n glpiUsername: string;\r\n glpiPassword: string;\r\n glpiEntityId: string;\r\n glpiRequestTypeId: string;\r\n}, provider: string, syncEnabled: boolean, syncIntervalMinutes: number): SaveTicketingConfigurationRequest {\r\n const request: SaveTicketingConfigurationRequest = {\r\n provider,\r\n syncEnabled,\r\n syncIntervalMinutes,\r\n };\r\n\r\n if (provider === 'GLPI') {\r\n request.glpiBaseUrl = fields.glpiBaseUrl;\r\n request.glpiClientId = fields.glpiClientId;\r\n if (fields.glpiClientSecret) {\r\n request.glpiClientSecret = fields.glpiClientSecret;\r\n }\r\n request.glpiUsername = fields.glpiUsername;\r\n if (fields.glpiPassword) {\r\n request.glpiPassword = fields.glpiPassword;\r\n }\r\n if (fields.glpiEntityId) {\r\n request.glpiEntityId = Number(fields.glpiEntityId);\r\n }\r\n if (fields.glpiRequestTypeId) {\r\n request.glpiRequestTypeId = Number(fields.glpiRequestTypeId);\r\n }\r\n }\r\n\r\n return request;\r\n}\r\n\r\ninterface TenantSupportSettingsTabProps {\r\n readonly tenantId: string;\r\n readonly tenantName: string;\r\n}\r\n\r\n// ============================================\r\n// Reusable Components (same pattern as TenantEntraTab)\r\n// ============================================\r\n\r\ninterface SectionCardProps {\r\n readonly icon: typeof Settings;\r\n readonly title: string;\r\n readonly description?: string;\r\n readonly action?: React.ReactNode;\r\n readonly children: React.ReactNode;\r\n}\r\n\r\nfunction SectionCard({ icon: Icon, title, description, action, children }: SectionCardProps) {\r\n return (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] shadow-sm overflow-hidden\">\r\n <div className=\"px-6 py-4 border-b border-[var(--border-subtle)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30\">\r\n <Icon className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <div>\r\n <h2 className=\"text-base font-semibold text-[var(--text-primary)]\">{title}</h2>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n </div>\r\n {action}\r\n </div>\r\n </div>\r\n <div className=\"p-6\">\r\n {children}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\ninterface ToggleProps {\r\n readonly checked: boolean;\r\n readonly onChange: () => void;\r\n readonly label: string;\r\n readonly description?: string;\r\n readonly disabled?: boolean;\r\n}\r\n\r\nfunction Toggle({ checked, onChange, label, description, disabled }: ToggleProps) {\r\n return (\r\n <div className=\"flex items-center justify-between py-3\">\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <label className=\"text-sm font-medium text-[var(--text-primary)]\">{label}</label>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n role=\"switch\"\r\n aria-checked={checked}\r\n onClick={onChange}\r\n disabled={disabled}\r\n className={`relative inline-flex h-6 w-11 flex-shrink-0 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] focus:ring-offset-2 focus:ring-offset-[var(--bg-primary)] disabled:opacity-50 disabled:cursor-not-allowed ${\r\n checked ? 'bg-[var(--color-accent-600)]' : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <span\r\n className={`inline-block h-4 w-4 transform rounded-full bg-white shadow-md transition-transform ${\r\n checked ? 'translate-x-6' : 'translate-x-1'\r\n }`}\r\n />\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\nfunction InfoBubble({ text }: { text: string }) {\r\n return (\r\n <Tooltip\r\n content={\r\n <span className=\"whitespace-pre-line text-xs leading-relaxed\">{text}</span>\r\n }\r\n position=\"right\"\r\n variant=\"info\"\r\n delay={100}\r\n className=\"!max-w-sm\"\r\n >\r\n <Info className=\"w-4 h-4 text-[var(--text-tertiary)] hover:text-[var(--info-text)] cursor-help transition-colors\" />\r\n </Tooltip>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Main Component\r\n// ============================================\r\n\r\nexport function TenantSupportSettingsTab({ tenantId, tenantName }: TenantSupportSettingsTabProps): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n\r\n // State\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState(false);\r\n const [testing, setTesting] = useState(false);\r\n const [syncing, setSyncing] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n const [showSecrets, setShowSecrets] = useState(false);\r\n const [config, setConfig] = useState<TenantTicketingConfigurationDto | null>(null);\r\n const [lastSyncResult, setLastSyncResult] = useState<TicketingSyncResultDto | null>(null);\r\n const [testResult, setTestResult] = useState<{ success: boolean; errorMessage?: string | null } | null>(null);\r\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\r\n\r\n // Form state\r\n const [provider, setProvider] = useState<string>('SmartStack');\r\n const [glpiBaseUrl, setGlpiBaseUrl] = useState('');\r\n const [glpiClientId, setGlpiClientId] = useState('');\r\n const [glpiClientSecret, setGlpiClientSecret] = useState('');\r\n const [glpiUsername, setGlpiUsername] = useState('');\r\n const [glpiPassword, setGlpiPassword] = useState('');\r\n const [glpiEntityId, setGlpiEntityId] = useState<string>('');\r\n const [glpiRequestTypeId, setGlpiRequestTypeId] = useState<string>('');\r\n const [syncEnabled, setSyncEnabled] = useState(false);\r\n const [syncIntervalMinutes, setSyncIntervalMinutes] = useState(60);\r\n\r\n const isGlpi = provider === 'GLPI';\r\n\r\n const fieldErrorClass = (field: string) =>\r\n fieldErrors[field] ? 'border-[var(--error-border)] ring-1 ring-[var(--error-border)]' : 'border-[var(--border-color)]';\r\n\r\n const loadConfiguration = useCallback(async () => {\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n const data = await ticketingApi.getConfiguration(tenantId);\r\n setConfig(data);\r\n setProvider(data.provider || 'SmartStack');\r\n setGlpiBaseUrl(data.glpiBaseUrl || '');\r\n setGlpiClientId(data.glpiClientId || '');\r\n setGlpiClientSecret('');\r\n setGlpiUsername(data.glpiUsername || '');\r\n setGlpiPassword('');\r\n setGlpiEntityId(data.glpiEntityId != null ? String(data.glpiEntityId) : '');\r\n setGlpiRequestTypeId(data.glpiRequestTypeId != null ? String(data.glpiRequestTypeId) : '');\r\n setSyncEnabled(data.syncEnabled);\r\n setSyncIntervalMinutes(data.syncIntervalMinutes);\r\n } catch {\r\n // Configuration may not exist yet, that's OK\r\n setConfig(null);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [tenantId]);\r\n\r\n useEffect(() => {\r\n loadConfiguration();\r\n }, [loadConfiguration]);\r\n\r\n const validateForm = (): boolean => {\r\n if (!isGlpi) {\r\n setFieldErrors({});\r\n return true;\r\n }\r\n\r\n const errors = validateGlpiConfig({\r\n glpiBaseUrl,\r\n glpiClientId,\r\n glpiClientSecret,\r\n glpiUsername,\r\n glpiPassword,\r\n }, config, t);\r\n\r\n setFieldErrors(errors);\r\n return Object.keys(errors).length === 0;\r\n };\r\n\r\n const handleSave = async () => {\r\n if (!validateForm()) return;\r\n\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n\r\n const request = buildGlpiSaveRequest({\r\n glpiBaseUrl,\r\n glpiClientId,\r\n glpiClientSecret,\r\n glpiUsername,\r\n glpiPassword,\r\n glpiEntityId,\r\n glpiRequestTypeId,\r\n }, provider, syncEnabled, syncIntervalMinutes);\r\n\r\n try {\r\n const updated = await ticketingApi.saveConfiguration(tenantId, request);\r\n setConfig(updated);\r\n setGlpiClientSecret('');\r\n setGlpiPassword('');\r\n setSuccess(t('admin:tenants.ticketing.saveSuccess'));\r\n } catch {\r\n setError(t('admin:tenants.ticketing.saveFailed'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleTestConnection = async () => {\r\n setTesting(true);\r\n setTestResult(null);\r\n setError(null);\r\n setSuccess(null);\r\n try {\r\n const result = await ticketingApi.testConnection(tenantId, {\r\n glpiBaseUrl: glpiBaseUrl,\r\n glpiClientId: glpiClientId,\r\n glpiClientSecret: glpiClientSecret || undefined,\r\n glpiUsername: glpiUsername,\r\n glpiPassword: glpiPassword || undefined,\r\n });\r\n setTestResult(result);\r\n if (result.success) {\r\n setSuccess(t('admin:tenants.ticketing.testSuccess'));\r\n } else {\r\n setError(result.errorMessage || t('admin:tenants.ticketing.testFailed'));\r\n }\r\n } catch {\r\n setError(t('admin:tenants.ticketing.testFailed'));\r\n } finally {\r\n setTesting(false);\r\n }\r\n };\r\n\r\n const handleSyncNow = async () => {\r\n setSyncing(true);\r\n setLastSyncResult(null);\r\n setError(null);\r\n setSuccess(null);\r\n try {\r\n const result = await ticketingApi.triggerSync(tenantId);\r\n setLastSyncResult(result);\r\n if (result.success) {\r\n setSuccess(t('admin:tenants.ticketing.syncSuccess', { count: result.ticketsUpdated }));\r\n } else {\r\n setError(result.errorMessage || t('admin:tenants.ticketing.syncFailed'));\r\n }\r\n await loadConfiguration();\r\n } catch {\r\n setError(t('admin:tenants.ticketing.syncFailed'));\r\n } finally {\r\n setSyncing(false);\r\n }\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center py-12\">\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 {/* Error / Success Messages */}\r\n {error && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">{error}</span>\r\n <button onClick={() => setError(null)} className=\"ml-auto text-[var(--error-text)] hover:opacity-70\">\r\n ×\r\n </button>\r\n </div>\r\n )}\r\n {success && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n <span className=\"text-sm text-[var(--success-text)]\">{success}</span>\r\n <button onClick={() => setSuccess(null)} className=\"ml-auto text-[var(--success-text)] hover:opacity-70\">\r\n ×\r\n </button>\r\n </div>\r\n )}\r\n\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {/* Provider Selection */}\r\n <SectionCard\r\n icon={Settings}\r\n title={t('admin:tenants.ticketing.provider.title')}\r\n description={t('admin:tenants.ticketing.provider.description', { tenantName })}\r\n >\r\n <div className=\"space-y-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.provider.label')}\r\n </label>\r\n <select\r\n value={provider}\r\n onChange={(e) => {\r\n const newProvider = e.target.value;\r\n setProvider(newProvider);\r\n if (newProvider !== 'GLPI') {\r\n setSyncEnabled(false);\r\n }\r\n }}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"SmartStack\" className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">\r\n SmartStack\r\n </option>\r\n <option value=\"GLPI\" className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">\r\n GLPI\r\n </option>\r\n </select>\r\n <p className=\"mt-1.5 text-xs text-[var(--text-tertiary)] whitespace-pre-line\">\r\n {isGlpi\r\n ? t('admin:tenants.ticketing.provider.glpiHint')\r\n : t('admin:tenants.ticketing.provider.smartstackHint')}\r\n </p>\r\n </div>\r\n\r\n {/* GLPI Connection Fields */}\r\n {isGlpi && (\r\n <>\r\n {/* Documentation Link */}\r\n <div className=\"flex items-start gap-3 p-3 rounded-[var(--radius-card)] bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <ExternalLink className=\"w-4 h-4 text-[var(--info-text)] mt-0.5 flex-shrink-0\" />\r\n <div className=\"text-sm text-[var(--info-text)]\">\r\n <span>{t('admin:tenants.ticketing.glpi.docHint')} </span>\r\n <a\r\n href=\"https://glpi-project.org/documentation/\"\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"font-medium underline hover:opacity-80\"\r\n >\r\n {t('admin:tenants.ticketing.glpi.docLink')}\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.baseUrl')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.baseUrlHelp')} />\r\n </label>\r\n <input\r\n type=\"url\"\r\n value={glpiBaseUrl}\r\n onChange={(e) => { setGlpiBaseUrl(e.target.value); setFieldErrors(prev => { const { glpiBaseUrl: _, ...rest } = prev; return rest; }); }}\r\n placeholder=\"https://glpi.example.com\"\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border ${fieldErrorClass('glpiBaseUrl')} bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow`}\r\n />\r\n {fieldErrors.glpiBaseUrl && <p className=\"mt-1 text-xs text-[var(--error-text)]\">{fieldErrors.glpiBaseUrl}</p>}\r\n </div>\r\n\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.clientId')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.clientIdHelp')} />\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={glpiClientId}\r\n onChange={(e) => { setGlpiClientId(e.target.value); setFieldErrors(prev => { const { glpiClientId: _, ...rest } = prev; return rest; }); }}\r\n placeholder={t('admin:tenants.ticketing.glpi.clientIdPlaceholder')}\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border ${fieldErrorClass('glpiClientId')} bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow`}\r\n />\r\n {fieldErrors.glpiClientId && <p className=\"mt-1 text-xs text-[var(--error-text)]\">{fieldErrors.glpiClientId}</p>}\r\n </div>\r\n\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.clientSecret')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.clientSecretHelp')} />\r\n {config?.hasGlpiClientSecret && (\r\n <span className=\"inline-flex items-center gap-1 text-xs text-[var(--success-text)]\">\r\n <CheckCircle className=\"w-3 h-3\" />\r\n {t('common:configured')}\r\n </span>\r\n )}\r\n </label>\r\n <div className=\"relative\">\r\n <input\r\n type={showSecrets ? 'text' : 'password'}\r\n autoComplete=\"new-password\"\r\n value={glpiClientSecret}\r\n onChange={(e) => { setGlpiClientSecret(e.target.value); setFieldErrors(prev => { const { glpiClientSecret: _, ...rest } = prev; return rest; }); }}\r\n placeholder={config?.hasGlpiClientSecret ? '••••••••••••••••' : t('admin:tenants.ticketing.glpi.clientSecretPlaceholder')}\r\n className={`w-full px-3 py-2.5 pr-10 rounded-[var(--radius-input)] border ${fieldErrorClass('glpiClientSecret')} bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow`}\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowSecrets(!showSecrets)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 text-[var(--text-tertiary)] hover:text-[var(--text-primary)]\"\r\n >\r\n {showSecrets ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n {fieldErrors.glpiClientSecret && <p className=\"mt-1 text-xs text-[var(--error-text)]\">{fieldErrors.glpiClientSecret}</p>}\r\n </div>\r\n\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.username')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.usernameHelp')} />\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={glpiUsername}\r\n onChange={(e) => { setGlpiUsername(e.target.value); setFieldErrors(prev => { const { glpiUsername: _, ...rest } = prev; return rest; }); }}\r\n placeholder={t('admin:tenants.ticketing.glpi.usernamePlaceholder')}\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border ${fieldErrorClass('glpiUsername')} bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow`}\r\n />\r\n {fieldErrors.glpiUsername && <p className=\"mt-1 text-xs text-[var(--error-text)]\">{fieldErrors.glpiUsername}</p>}\r\n </div>\r\n\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.password')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.passwordHelp')} />\r\n {config?.hasGlpiPassword && (\r\n <span className=\"inline-flex items-center gap-1 text-xs text-[var(--success-text)]\">\r\n <CheckCircle className=\"w-3 h-3\" />\r\n {t('common:configured')}\r\n </span>\r\n )}\r\n </label>\r\n <div className=\"relative\">\r\n <input\r\n type={showSecrets ? 'text' : 'password'}\r\n autoComplete=\"new-password\"\r\n value={glpiPassword}\r\n onChange={(e) => { setGlpiPassword(e.target.value); setFieldErrors(prev => { const { glpiPassword: _, ...rest } = prev; return rest; }); }}\r\n placeholder={config?.hasGlpiPassword ? '••••••••••••••••' : t('admin:tenants.ticketing.glpi.passwordPlaceholder')}\r\n className={`w-full px-3 py-2.5 pr-10 rounded-[var(--radius-input)] border ${fieldErrorClass('glpiPassword')} bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow`}\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowSecrets(!showSecrets)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 text-[var(--text-tertiary)] hover:text-[var(--text-primary)]\"\r\n >\r\n {showSecrets ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n {fieldErrors.glpiPassword && <p className=\"mt-1 text-xs text-[var(--error-text)]\">{fieldErrors.glpiPassword}</p>}\r\n </div>\r\n\r\n {/* GLPI Entity ID */}\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.entityId')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.entityIdHelp')} />\r\n </label>\r\n <input\r\n type=\"number\"\r\n min=\"0\"\r\n value={glpiEntityId}\r\n onChange={(e) => setGlpiEntityId(e.target.value)}\r\n placeholder={t('admin:tenants.ticketing.glpi.entityIdPlaceholder')}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow\"\r\n />\r\n </div>\r\n\r\n {/* GLPI Request Type ID */}\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.requestTypeId')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.requestTypeIdHelp')} />\r\n </label>\r\n <input\r\n type=\"number\"\r\n min=\"0\"\r\n value={glpiRequestTypeId}\r\n onChange={(e) => setGlpiRequestTypeId(e.target.value)}\r\n placeholder={t('admin:tenants.ticketing.glpi.requestTypeIdPlaceholder')}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow\"\r\n />\r\n </div>\r\n\r\n {/* Test Connection */}\r\n <div className=\"flex flex-col sm:flex-row items-stretch sm:items-center gap-2 sm:gap-3 pt-2\">\r\n <button\r\n onClick={handleTestConnection}\r\n disabled={testing || !glpiBaseUrl || !glpiClientId || (!glpiClientSecret && !config?.hasGlpiClientSecret) || !glpiUsername || (!glpiPassword && !config?.hasGlpiPassword)}\r\n className=\"inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {testing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <TestTube className=\"w-4 h-4\" />}\r\n {t('admin:tenants.ticketing.testConnection')}\r\n </button>\r\n </div>\r\n\r\n {/* Test Connection Result */}\r\n {testResult && (\r\n <div className={`p-4 rounded-[var(--radius-card)] border ${\r\n testResult.success\r\n ? 'bg-[var(--success-bg)] border-[var(--success-border)]'\r\n : 'bg-[var(--error-bg)] border-[var(--error-border)]'\r\n }`}>\r\n <div className=\"flex items-center gap-2\">\r\n {testResult.success ? (\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n )}\r\n <span className={`font-medium ${testResult.success ? 'text-[var(--success-text)]' : 'text-[var(--error-text)]'}`}>\r\n {testResult.success\r\n ? t('admin:tenants.ticketing.connectionSuccessful')\r\n : t('admin:tenants.ticketing.connectionFailed')}\r\n </span>\r\n </div>\r\n {!testResult.success && testResult.errorMessage && (\r\n <p className=\"mt-2 text-sm text-[var(--error-text)]\">{testResult.errorMessage}</p>\r\n )}\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Sync Settings */}\r\n <div className=\"space-y-6\">\r\n <SectionCard\r\n icon={Clock}\r\n title={t('admin:tenants.ticketing.sync.title')}\r\n description={t('admin:tenants.ticketing.sync.description')}\r\n >\r\n <div className=\"divide-y divide-[var(--border-subtle)]\">\r\n <Toggle\r\n checked={syncEnabled}\r\n onChange={() => setSyncEnabled(!syncEnabled)}\r\n label={t('admin:tenants.ticketing.sync.enabledLabel')}\r\n description={t('admin:tenants.ticketing.sync.enabledDescription')}\r\n disabled={!isGlpi}\r\n />\r\n <div className=\"py-4\">\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {t('admin:tenants.ticketing.sync.intervalLabel')}\r\n </label>\r\n <select\r\n value={syncIntervalMinutes}\r\n onChange={(e) => setSyncIntervalMinutes(Number(e.target.value))}\r\n disabled={!isGlpi || !syncEnabled}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n <option value={15} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">15 {t('common:minutes')}</option>\r\n <option value={30} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">30 {t('common:minutes')}</option>\r\n <option value={60} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">1 {t('common:hour')}</option>\r\n <option value={120} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">2 {t('common:hours')}</option>\r\n <option value={360} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">6 {t('common:hours')}</option>\r\n <option value={720} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">12 {t('common:hours')}</option>\r\n <option value={1440} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">24 {t('common:hours')}</option>\r\n </select>\r\n </div>\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Last Sync Status */}\r\n {config?.isConfigured && isGlpi && (\r\n <SectionCard\r\n icon={Zap}\r\n title={t('admin:tenants.ticketing.syncStatus.title')}\r\n description={t('admin:tenants.ticketing.syncStatus.description')}\r\n action={\r\n <button\r\n onClick={handleSyncNow}\r\n disabled={syncing}\r\n className=\"inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {syncing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <RefreshCw className=\"w-4 h-4\" />}\r\n {t('admin:tenants.ticketing.syncStatus.syncNow')}\r\n </button>\r\n }\r\n >\r\n <div className=\"space-y-4\">\r\n {/* Last Sync Info */}\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <Clock className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.ticketing.syncStatus.lastSync')}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {config.lastSyncAt\r\n ? new Date(config.lastSyncAt).toLocaleString()\r\n : t('admin:tenants.ticketing.syncStatus.never')}\r\n </p>\r\n </div>\r\n\r\n <div className={`p-4 rounded-[var(--radius-card)] border ${\r\n config.lastSyncError\r\n ? 'bg-[var(--error-bg)] border-[var(--error-border)]'\r\n : 'bg-[var(--success-bg)] border-[var(--success-border)]'\r\n }`}>\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n {config.lastSyncError ? (\r\n <AlertTriangle className=\"w-4 h-4 text-[var(--error-text)]\" />\r\n ) : (\r\n <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n )}\r\n <span className={`text-sm font-medium ${\r\n config.lastSyncError ? 'text-[var(--error-text)]' : 'text-[var(--success-text)]'\r\n }`}>\r\n {t('admin:tenants.ticketing.syncStatus.status')}\r\n </span>\r\n </div>\r\n <p className={`text-sm ${\r\n config.lastSyncError ? 'text-[var(--error-text)]' : 'text-[var(--success-text)]'\r\n }`}>\r\n {config.lastSyncError || t('admin:tenants.ticketing.syncStatus.healthy')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Last Sync Result */}\r\n {lastSyncResult && (\r\n <div className={`p-4 rounded-[var(--radius-card)] border ${\r\n lastSyncResult.success\r\n ? 'bg-[var(--success-bg)] border-[var(--success-border)]'\r\n : 'bg-[var(--error-bg)] border-[var(--error-border)]'\r\n }`}>\r\n <div className=\"flex items-center gap-2 mb-3\">\r\n {lastSyncResult.success ? (\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n )}\r\n <span className={`font-medium ${lastSyncResult.success ? 'text-[var(--success-text)]' : 'text-[var(--error-text)]'}`}>\r\n {lastSyncResult.success\r\n ? t('admin:tenants.ticketing.syncStatus.syncSuccess')\r\n : t('admin:tenants.ticketing.syncStatus.syncFailed')}\r\n </span>\r\n </div>\r\n <div className=\"grid grid-cols-2 gap-3 text-sm\">\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)]\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">\r\n {t('admin:tenants.ticketing.syncStatus.ticketsUpdated')}\r\n </span>\r\n <p className=\"font-semibold text-[var(--success-text)]\">{lastSyncResult.ticketsUpdated}</p>\r\n </div>\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)]\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">\r\n {t('admin:tenants.ticketing.syncStatus.ticketsFailed')}\r\n </span>\r\n <p className={`font-semibold ${lastSyncResult.ticketsFailed > 0 ? 'text-[var(--error-text)]' : 'text-[var(--text-primary)]'}`}>\r\n {lastSyncResult.ticketsFailed}\r\n </p>\r\n </div>\r\n </div>\r\n {lastSyncResult.errorMessage && (\r\n <p className=\"mt-3 text-sm text-[var(--error-text)]\">{lastSyncResult.errorMessage}</p>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </SectionCard>\r\n )}\r\n\r\n {/* Save Button */}\r\n <div className=\"flex flex-col-reverse sm:flex-row items-stretch sm:items-center gap-2 sm:gap-3\">\r\n <button\r\n onClick={handleSave}\r\n disabled={saving}\r\n className=\"inline-flex items-center justify-center gap-2 px-6 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common:save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useParams, useNavigate } from 'react-router-dom';\r\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\r\nimport { useTenantDetail } from '@/hooks/useTenantDetail';\r\nimport {\r\n ArrowLeft,\r\n Loader2,\r\n AlertTriangle,\r\n Settings,\r\n} from 'lucide-react';\r\nimport { TenantEntraTab } from '@/components/platform/administration/TenantEntraTab';\r\nimport { TenantSupportSettingsTab } from '@/components/platform/administration/tenants/TenantSupportSettingsTab';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\n\r\nconst VALID_TABS = ['entra', 'support'] as const;\r\ntype TabType = typeof VALID_TABS[number];\r\n\r\nexport function TenantSettingsPage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const { id: tenantId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const { activeTab, setActiveTab } = useTabNavigation<TabType>('entra', VALID_TABS);\r\n\r\n const tenantDetail = useTenantDetail(tenantId);\r\n\r\n useEffect(() => {\r\n if (!tenantId) {\r\n navigate('/administration/tenants');\r\n return;\r\n }\r\n tenantDetail.loadTenant();\r\n }, [tenantId]);\r\n\r\n if (tenantDetail.loading) {\r\n return (\r\n <div className=\"p-6 flex items-center justify-center min-h-screen\">\r\n <div className=\"text-center\">\r\n <Loader2 className=\"w-8 h-8 animate-spin mx-auto mb-2 text-[var(--text-secondary)]\" />\r\n <p className=\"text-[var(--text-secondary)]\">{t('common:loading')}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!tenantDetail.tenant) {\r\n return (\r\n <div className=\"p-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants' },\r\n ]}\r\n />\r\n <div className=\"mt-4 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{tenantDetail.error || t('admin:tenants.notFound')}</span>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const tenant = tenantDetail.tenant;\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants' },\r\n { label: tenant.name, href: `/administration/tenants/${tenantId}` },\r\n { label: t('admin:tenants.settings.title') },\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate(`/administration/tenants/${tenantId}`)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <Settings className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-xl sm:text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('admin:tenants.settings.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{tenant.name}</p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Error */}\r\n {tenantDetail.error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{tenantDetail.error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Tab Navigation */}\r\n <div className=\"border-b border-[var(--border-color)]\">\r\n <div className=\"flex gap-1 -mb-px\">\r\n {VALID_TABS.map(tab => (\r\n <button\r\n key={tab}\r\n onClick={() => setActiveTab(tab)}\r\n className={`px-4 py-2 border-b-2 transition-colors ${\r\n activeTab === tab\r\n ? 'border-[var(--primary-color)] text-[var(--primary-color)]'\r\n : 'border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n >\r\n {t(`admin:tenants.settings.tabs.${tab}`)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Tab Content */}\r\n <div>\r\n {activeTab === 'entra' && tenantId && (\r\n <TenantEntraTab\r\n tenantId={tenantId}\r\n tenantName={tenant.name}\r\n tenantSlug={tenant.slug}\r\n />\r\n )}\r\n\r\n {activeTab === 'support' && tenantId && (\r\n <TenantSupportSettingsTab\r\n tenantId={tenantId}\r\n tenantName={tenant.name}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Loader2,\r\n Save,\r\n AlertTriangle,\r\n CheckCircle,\r\n ChevronDown,\r\n Palette,\r\n} from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { PageHeader } from '@/components/ui/PageHeader';\r\nimport { tenantTypeSettingsApi, type TenantTypeSettingsDto, type UpdateTenantTypeSettingsRequest } from '@/services/api/tenantTypeSettingsApi';\r\nimport type { TenantType } from '@/services/api/adminApi';\r\nimport { getLucideIcon, getAvailableIconNames, getColorClasses, getAvailableColors } from '@/utils/tenantIconMap';\r\n\r\ninterface CardEditState {\r\n icon: string;\r\n iconType: 'Lucide' | 'Url' | 'Svg';\r\n color: string;\r\n displayName: string;\r\n description: string;\r\n}\r\n\r\nexport function TenantTypeSettingsPage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n\r\n const [settings, setSettings] = useState<TenantTypeSettingsDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n const [editStates, setEditStates] = useState<Record<string, CardEditState>>({});\r\n const [savingType, setSavingType] = useState<TenantType | null>(null);\r\n\r\n const loadSettings = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n setError(null);\r\n const data = await tenantTypeSettingsApi.getAll();\r\n setSettings(data);\r\n\r\n const states: Record<string, CardEditState> = {};\r\n for (const s of data) {\r\n states[s.type] = {\r\n icon: s.icon,\r\n iconType: s.iconType,\r\n color: s.color,\r\n displayName: s.displayName,\r\n description: s.description ?? '',\r\n };\r\n }\r\n setEditStates(states);\r\n } catch {\r\n setError(t('admin:tenantTypeSettings.loadError'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [t]);\r\n\r\n useEffect(() => {\r\n loadSettings();\r\n }, [loadSettings]);\r\n\r\n const handleSave = async (type: TenantType) => {\r\n const state = editStates[type];\r\n if (!state) return;\r\n\r\n try {\r\n setSavingType(type);\r\n setError(null);\r\n const request: UpdateTenantTypeSettingsRequest = {\r\n icon: state.icon,\r\n iconType: state.iconType,\r\n color: state.color,\r\n displayName: state.displayName,\r\n description: state.description || null,\r\n };\r\n await tenantTypeSettingsApi.update(type, request);\r\n setSuccess(t('admin:tenantTypeSettings.saveSuccess'));\r\n setTimeout(() => setSuccess(null), 3000);\r\n await loadSettings();\r\n } catch {\r\n setError(t('admin:tenantTypeSettings.saveError'));\r\n } finally {\r\n setSavingType(null);\r\n }\r\n };\r\n\r\n const updateEditState = (type: string, field: keyof CardEditState, value: string) => {\r\n setEditStates((prev) => ({\r\n ...prev,\r\n [type]: { ...prev[type], [field]: value },\r\n }));\r\n };\r\n\r\n const hasChanges = (type: string): boolean => {\r\n const original = settings.find((s) => s.type === type);\r\n const current = editStates[type];\r\n if (!original || !current) return false;\r\n return (\r\n original.icon !== current.icon ||\r\n original.color !== current.color ||\r\n original.displayName !== current.displayName ||\r\n (original.description ?? '') !== current.description\r\n );\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"p-6 flex items-center justify-center min-h-[400px]\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants' },\r\n { label: t('admin:tenantTypeSettings.title') },\r\n ]}\r\n />\r\n\r\n <PageHeader\r\n title={t('admin:tenantTypeSettings.title')}\r\n subtitle={t('admin:tenantTypeSettings.subtitle')}\r\n icon={<Palette className=\"w-6 h-6\" />}\r\n />\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-lg bg-red-500/10 border border-red-500/20 flex items-center gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-red-500 flex-shrink-0\" />\r\n <p className=\"text-red-500\">{error}</p>\r\n </div>\r\n )}\r\n\r\n {success && (\r\n <div className=\"p-4 rounded-lg bg-green-500/10 border border-green-500/20 flex items-center gap-3\">\r\n <CheckCircle className=\"w-5 h-5 text-green-500 flex-shrink-0\" />\r\n <p className=\"text-green-500\">{success}</p>\r\n </div>\r\n )}\r\n\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\r\n {settings.map((setting) => {\r\n const state = editStates[setting.type];\r\n if (!state) return null;\r\n\r\n const PreviewIcon = getLucideIcon(state.icon);\r\n const previewColors = getColorClasses(state.color);\r\n\r\n return (\r\n <div\r\n key={setting.type}\r\n className=\"p-6 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)] space-y-5\"\r\n >\r\n {/* Preview */}\r\n <div className=\"flex items-center gap-4\">\r\n <div className={`w-14 h-14 rounded-xl flex items-center justify-center ${previewColors.bg}`}>\r\n <PreviewIcon className={`w-7 h-7 ${previewColors.text}`} />\r\n </div>\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">{state.displayName}</h3>\r\n <p className=\"text-sm text-[var(--text-tertiary)]\">{setting.type}</p>\r\n </div>\r\n </div>\r\n\r\n {/* Display Name */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('admin:tenantTypeSettings.displayName')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={state.displayName}\r\n onChange={(e) => updateEditState(setting.type, 'displayName', e.target.value)}\r\n className=\"w-full px-3 py-2 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n {/* Icon Selector */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('admin:tenantTypeSettings.icon')}\r\n </label>\r\n <div className=\"relative\">\r\n <select\r\n value={state.icon}\r\n onChange={(e) => updateEditState(setting.type, 'icon', e.target.value)}\r\n className=\"w-full px-3 py-2 pr-8 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] appearance-none focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n {getAvailableIconNames().map((name) => (\r\n <option key={name} value={name}>{name}</option>\r\n ))}\r\n </select>\r\n <ChevronDown className=\"absolute right-2 top-1/2 transform -translate-y-1/2 w-4 h-4 text-[var(--text-tertiary)] pointer-events-none\" />\r\n </div>\r\n </div>\r\n\r\n {/* Color Selector */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('admin:tenantTypeSettings.color')}\r\n </label>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {getAvailableColors().map((color) => {\r\n const colorClasses = getColorClasses(color);\r\n return (\r\n <button\r\n key={color}\r\n onClick={() => updateEditState(setting.type, 'color', color)}\r\n className={`w-8 h-8 rounded-full flex items-center justify-center transition-all ${colorClasses.bg} ${\r\n state.color === color ? 'ring-2 ring-offset-2 ring-[var(--color-accent-500)]' : ''\r\n }`}\r\n title={color}\r\n >\r\n <div className={`w-4 h-4 rounded-full ${colorClasses.text.replace('text-', 'bg-')}`} />\r\n </button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n\r\n {/* Description */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('admin:tenantTypeSettings.description')}\r\n </label>\r\n <textarea\r\n value={state.description}\r\n onChange={(e) => updateEditState(setting.type, 'description', e.target.value)}\r\n rows={2}\r\n className=\"w-full px-3 py-2 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n\r\n {/* Save Button */}\r\n <button\r\n onClick={() => handleSave(setting.type as TenantType)}\r\n disabled={!hasChanges(setting.type) || savingType === setting.type}\r\n className=\"w-full flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n {savingType === setting.type ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Save className=\"w-4 h-4\" />\r\n )}\r\n {t('common:save')}\r\n </button>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { Plus, AlertTriangle, Building } from 'lucide-react';\r\nimport { adminApi, type OrganisationListItemDto, type VerificationStatus } from '@/services/api/adminApi';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { DataTable, type DataTableColumn } from '@/components/ui/DataTable';\r\n\r\nconst VERIFICATION_STATUS_CONFIG: Record<VerificationStatus, { bgColor: string; textColor: string }> = {\r\n Pending: {\r\n bgColor: 'bg-[var(--warning-bg)]',\r\n textColor: 'text-[var(--warning-text)]',\r\n },\r\n Verified: {\r\n bgColor: 'bg-[var(--success-bg)]',\r\n textColor: 'text-[var(--success-text)]',\r\n },\r\n Rejected: {\r\n bgColor: 'bg-[var(--error-bg)]',\r\n textColor: 'text-[var(--error-text)]',\r\n },\r\n};\r\n\r\nexport function OrganisationsListPage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const navigate = useNavigate();\r\n\r\n const [organisations, setOrganisations] = useState<OrganisationListItemDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [page, setPage] = useState(1);\r\n const [pageSize] = useState(10);\r\n const [totalPages, setTotalPages] = useState(1);\r\n const [search, setSearch] = useState('');\r\n const [verificationFilter, setVerificationFilter] = useState<VerificationStatus | 'All'>('All');\r\n\r\n const loadOrganisations = useCallback(async (signal?: AbortSignal) => {\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n const result = await adminApi.organisations.getAll({\r\n page,\r\n pageSize,\r\n search: search || undefined,\r\n verificationStatus: verificationFilter !== 'All' ? verificationFilter : undefined,\r\n });\r\n if (!signal?.aborted) {\r\n setOrganisations(result.items);\r\n setTotalPages(Math.ceil(result.totalCount / pageSize));\r\n }\r\n } catch (err) {\r\n if (!signal?.aborted) {\r\n console.error('Failed to load organisations:', err);\r\n setError(t('common:error', 'An error occurred'));\r\n }\r\n } finally {\r\n if (!signal?.aborted) {\r\n setLoading(false);\r\n }\r\n }\r\n }, [page, pageSize, search, verificationFilter, t]);\r\n\r\n useEffect(() => {\r\n const abortController = new AbortController();\r\n loadOrganisations(abortController.signal);\r\n return () => abortController.abort();\r\n }, [loadOrganisations]);\r\n\r\n const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n setSearch(e.target.value);\r\n setPage(1);\r\n };\r\n\r\n const statusFilters: (VerificationStatus | 'All')[] = ['All', 'Pending', 'Verified', 'Rejected'];\r\n\r\n const columns: DataTableColumn<OrganisationListItemDto>[] = [\r\n {\r\n key: 'name',\r\n label: t('admin:organisations.columns.name', 'Name'),\r\n sortable: true,\r\n render: (org) => (\r\n <div>\r\n <div className=\"font-medium text-[var(--text-primary)]\">{org.name}</div>\r\n {org.legalName && (\r\n <div className=\"text-xs text-[var(--text-secondary)]\">{org.legalName}</div>\r\n )}\r\n </div>\r\n ),\r\n },\r\n {\r\n key: 'countryCode',\r\n label: t('admin:organisations.columns.country', 'Country'),\r\n sortable: true,\r\n },\r\n {\r\n key: 'businessIdentifier',\r\n label: t('admin:organisations.columns.identifier', 'Business ID'),\r\n sortable: true,\r\n render: (org) => (\r\n <span className=\"font-mono text-[var(--text-primary)]\">{org.businessIdentifier}</span>\r\n ),\r\n },\r\n {\r\n key: 'verificationStatus',\r\n label: t('admin:organisations.columns.status', 'Status'),\r\n sortable: true,\r\n render: (org) => (\r\n <span\r\n className={`inline-block px-3 py-1 rounded-[var(--radius-badge)] text-xs font-medium ${\r\n VERIFICATION_STATUS_CONFIG[org.verificationStatus].bgColor\r\n } ${VERIFICATION_STATUS_CONFIG[org.verificationStatus].textColor}`}\r\n >\r\n {t(\r\n `admin:organisations.status.${org.verificationStatus.toLowerCase()}`,\r\n org.verificationStatus\r\n )}\r\n </span>\r\n ),\r\n },\r\n {\r\n key: 'createdAt',\r\n label: t('admin:organisations.columns.created', 'Created'),\r\n sortable: true,\r\n render: (org) => (\r\n <span className=\"text-[var(--text-secondary)]\">\r\n {new Date(org.createdAt).toLocaleDateString()}\r\n </span>\r\n ),\r\n },\r\n {\r\n key: 'actions',\r\n label: t('admin:organisations.columns.actions', 'Actions'),\r\n align: 'right',\r\n render: (org) => (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n navigate(`/administration/tenants/create?type=b2b&organisationId=${org.id}`);\r\n }}\r\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-[var(--radius-button)] bg-[var(--info-bg)] text-[var(--info-text)] border border-[var(--info-border)] hover:opacity-80 transition-colors\"\r\n title={t('admin:organisations.createTenant', 'Create B2B tenant for this organisation')}\r\n >\r\n <Building className=\"w-3.5 h-3.5\" />\r\n {t('admin:organisations.createTenantButton', 'Create tenant')}\r\n </button>\r\n ),\r\n },\r\n ];\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('admin:organisations.title', 'Organisations') },\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('admin:organisations.title', 'Organisations')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:organisations.description', 'Manage organisations and verify their details')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={() => navigate('/administration/tenants/organisations/create')}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-500)] text-white hover:bg-[var(--color-accent-600)] transition-colors\"\r\n >\r\n <Plus className=\"w-5 h-5\" />\r\n {t('common:create', 'Create')}\r\n </button>\r\n </div>\r\n\r\n <div className=\"space-y-4\">\r\n <div className=\"flex flex-col sm:flex-row gap-4\">\r\n <div className=\"relative flex-1\">\r\n <input\r\n type=\"text\"\r\n placeholder={t('common:search', 'Search')}\r\n value={search}\r\n onChange={handleSearchChange}\r\n className=\"input w-full pl-10\"\r\n />\r\n </div>\r\n\r\n <div className=\"flex flex-wrap gap-2\">\r\n {statusFilters.map((status) => (\r\n <button\r\n key={status}\r\n onClick={() => {\r\n setVerificationFilter(status);\r\n setPage(1);\r\n }}\r\n className={`px-3 py-1 rounded-[var(--radius-badge)] text-sm transition-colors ${\r\n verificationFilter === status\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n {status === 'All' ? t('common:all', 'All') : t(`admin:organisations.status.${status.toLowerCase()}`, status)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n <button\r\n onClick={() => loadOrganisations()}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:retry', 'Retry')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n <DataTable\r\n data={organisations}\r\n columns={columns}\r\n loading={loading}\r\n getRowKey={(item) => item.id}\r\n onRowClick={(item) => navigate(`/administration/tenants/organisations/${item.id}`)}\r\n emptyMessage={t('admin:organisations.empty', 'No organisations found')}\r\n />\r\n\r\n {!loading && organisations.length > 0 && (\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('common:page', 'Page')} {page} {t('common:of', 'of')} {totalPages}\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <button\r\n onClick={() => setPage(Math.max(1, page - 1))}\r\n disabled={page === 1}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {t('common:previous', 'Previous')}\r\n </button>\r\n <button\r\n onClick={() => setPage(Math.min(totalPages, page + 1))}\r\n disabled={page >= totalPages}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {t('common:next', 'Next')}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useParams, useNavigate, useSearchParams } from 'react-router-dom';\r\nimport { ArrowLeft, Loader2, AlertTriangle, Check, X } from 'lucide-react';\r\nimport { adminApi, type OrganisationDto, type VerificationStatus } from '@/services/api/adminApi';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\n\r\nconst VERIFICATION_STATUS_CONFIG: Record<VerificationStatus, { bgColor: string; textColor: string }> = {\r\n Pending: {\r\n bgColor: 'bg-[var(--warning-bg)]',\r\n textColor: 'text-[var(--warning-text)]',\r\n },\r\n Verified: {\r\n bgColor: 'bg-[var(--success-bg)]',\r\n textColor: 'text-[var(--success-text)]',\r\n },\r\n Rejected: {\r\n bgColor: 'bg-[var(--error-bg)]',\r\n textColor: 'text-[var(--error-text)]',\r\n },\r\n};\r\n\r\ntype TabType = 'info' | 'contact' | 'address';\r\nconst VALID_TABS: TabType[] = ['info', 'contact', 'address'];\r\n\r\nexport function OrganisationDetailPage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const { id: orgId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n\r\n const [organisation, setOrganisation] = useState<OrganisationDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [actionLoading, setActionLoading] = useState(false);\r\n\r\n // Tab management\r\n const getInitialTab = (): TabType => {\r\n const tabParam = searchParams.get('tab');\r\n if (tabParam && VALID_TABS.includes(tabParam as TabType)) {\r\n return tabParam as TabType;\r\n }\r\n return 'info';\r\n };\r\n\r\n const [activeTab, setActiveTab] = useState<TabType>(getInitialTab);\r\n\r\n // Modal states\r\n const [verifyModal, setVerifyModal] = useState<{ show: boolean; notes: string }>({\r\n show: false,\r\n notes: '',\r\n });\r\n const [rejectModal, setRejectModal] = useState<{ show: boolean; reason: string }>({\r\n show: false,\r\n reason: '',\r\n });\r\n\r\n // Sync URL with active tab\r\n useEffect(() => {\r\n if (activeTab === 'info') {\r\n if (searchParams.get('tab')) {\r\n searchParams.delete('tab');\r\n setSearchParams(searchParams, { replace: true });\r\n }\r\n } else if (searchParams.get('tab') !== activeTab) {\r\n setSearchParams({ tab: activeTab }, { replace: true });\r\n }\r\n }, [activeTab, searchParams, setSearchParams]);\r\n\r\n const loadOrganisation = useCallback(async () => {\r\n if (!orgId) {\r\n navigate('/administration/tenants/organisations');\r\n return;\r\n }\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n const data = await adminApi.organisations.getById(orgId);\r\n setOrganisation(data);\r\n } catch (err) {\r\n console.error('Failed to load organisation:', err);\r\n setError(t('admin:organisations.loadError', 'Failed to load organisation'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [orgId, navigate, t]);\r\n\r\n useEffect(() => {\r\n loadOrganisation();\r\n }, [loadOrganisation]);\r\n\r\n const handleVerify = async () => {\r\n if (!organisation) return;\r\n setActionLoading(true);\r\n try {\r\n const updated = await adminApi.organisations.verify(organisation.id, verifyModal.notes || undefined);\r\n setOrganisation(updated);\r\n setVerifyModal({ show: false, notes: '' });\r\n } catch (err) {\r\n console.error('Failed to verify organisation:', err);\r\n setError(t('admin:organisations.verifyError', 'Failed to verify organisation'));\r\n } finally {\r\n setActionLoading(false);\r\n }\r\n };\r\n\r\n const handleReject = async () => {\r\n if (!organisation) return;\r\n setActionLoading(true);\r\n try {\r\n const updated = await adminApi.organisations.reject(organisation.id, rejectModal.reason);\r\n setOrganisation(updated);\r\n setRejectModal({ show: false, reason: '' });\r\n } catch (err) {\r\n console.error('Failed to reject organisation:', err);\r\n setError(t('admin:organisations.rejectError', 'Failed to reject organisation'));\r\n } finally {\r\n setActionLoading(false);\r\n }\r\n };\r\n\r\n const hasContactData = organisation && (organisation.phone || organisation.email || organisation.website);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"p-6 flex items-center justify-center min-h-[400px]\">\r\n <div className=\"text-center\">\r\n <Loader2 className=\"w-8 h-8 animate-spin mx-auto mb-2 text-[var(--text-secondary)]\" />\r\n <p className=\"text-[var(--text-secondary)]\">{t('common:loading', 'Loading')}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!organisation) {\r\n return (\r\n <div className=\"p-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('admin:organisations.title', 'Organisations'), href: '/administration/tenants/organisations' },\r\n ]}\r\n />\r\n <div className=\"mt-4 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error || t('admin:organisations.notFound', 'Organisation not found')}</span>\r\n </div>\r\n <button\r\n onClick={loadOrganisation}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:retry', 'Retry')}\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const statusConfig = VERIFICATION_STATUS_CONFIG[organisation.verificationStatus];\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('admin:organisations.title', 'Organisations'), href: '/administration/tenants/organisations' },\r\n { label: organisation.name },\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/tenants/organisations')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">{organisation.name}</h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{organisation.businessIdentifier}</p>\r\n </div>\r\n </div>\r\n <span className={`px-4 py-2 rounded-[var(--radius-badge)] text-sm font-medium ${statusConfig.bgColor} ${statusConfig.textColor}`}>\r\n {t(`admin:organisations.status.${organisation.verificationStatus.toLowerCase()}`, organisation.verificationStatus)}\r\n </span>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n <button\r\n onClick={loadOrganisation}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:retry', 'Retry')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n <div className=\"border-b border-[var(--border-color)]\">\r\n <div className=\"flex gap-1 -mb-px\">\r\n {VALID_TABS.map((tab) => (\r\n <button\r\n key={tab}\r\n onClick={() => setActiveTab(tab)}\r\n className={`px-4 py-2 border-b-2 transition-colors ${\r\n activeTab === tab\r\n ? 'border-[var(--primary-color)] text-[var(--primary-color)]'\r\n : 'border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n >\r\n {t(`admin:organisations.tabs.${tab}`, tab)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {activeTab === 'info' && (\r\n <div className=\"space-y-4\">\r\n <div className=\"grid grid-cols-2 gap-4\">\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.name', 'Organisation Name')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.name}</p>\r\n </div>\r\n {organisation.legalName && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.legalName', 'Legal Name')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.legalName}</p>\r\n </div>\r\n )}\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.country', 'Country')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.countryCode}</p>\r\n </div>\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {organisation.businessIdentifierType}\r\n </label>\r\n <p className=\"mt-1 font-mono text-[var(--text-primary)]\">{organisation.businessIdentifier}</p>\r\n </div>\r\n {organisation.vatNumber && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.vatNumber', 'VAT Number')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.vatNumber}</p>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {organisation.verificationStatus !== 'Verified' && (\r\n <div className=\"flex gap-2 pt-4\">\r\n {(organisation.verificationStatus === 'Pending' || organisation.verificationStatus === 'Rejected') && (\r\n <button\r\n onClick={() => setVerifyModal({ show: true, notes: '' })}\r\n disabled={actionLoading}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--success-bg)] text-[var(--success-text)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\r\n >\r\n <Check className=\"w-4 h-4\" />\r\n {t('admin:organisations.verify', 'Verify')}\r\n </button>\r\n )}\r\n {organisation.verificationStatus === 'Pending' && (\r\n <button\r\n onClick={() => setRejectModal({ show: true, reason: '' })}\r\n disabled={actionLoading}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--error-bg)] text-[var(--error-text)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\r\n >\r\n <X className=\"w-4 h-4\" />\r\n {t('admin:organisations.reject', 'Reject')}\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {activeTab === 'contact' && (\r\n hasContactData ? (\r\n <div className=\"grid grid-cols-2 gap-4\">\r\n {organisation.phone && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.phone', 'Phone')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.phone}</p>\r\n </div>\r\n )}\r\n {organisation.email && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.email', 'Email')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.email}</p>\r\n </div>\r\n )}\r\n {organisation.website && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.website', 'Website')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)] break-all\">{organisation.website}</p>\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"py-12 text-center text-[var(--text-secondary)]\">\r\n {t('admin:organisations.noContact', 'No contact information available')}\r\n </div>\r\n )\r\n )}\r\n\r\n {activeTab === 'address' && (\r\n organisation.address ? (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <div className=\"space-y-2\">\r\n <div>\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.address', 'Address')}\r\n </label>\r\n <p className=\"text-[var(--text-primary)]\">{organisation.address.street}</p>\r\n {organisation.address.street2 && (\r\n <p className=\"text-[var(--text-primary)]\">{organisation.address.street2}</p>\r\n )}\r\n </div>\r\n <div>\r\n <p className=\"text-[var(--text-primary)]\">\r\n {organisation.address.postalCode} {organisation.address.city}\r\n </p>\r\n {organisation.address.state && (\r\n <p className=\"text-[var(--text-primary)]\">{organisation.address.state}</p>\r\n )}\r\n </div>\r\n <div>\r\n <p className=\"text-[var(--text-primary)]\">\r\n {organisation.address.country} ({organisation.address.countryCode})\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"py-12 text-center text-[var(--text-secondary)]\">\r\n {t('admin:organisations.noAddress', 'No address information available')}\r\n </div>\r\n )\r\n )}\r\n\r\n {verifyModal.show && (\r\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] p-6 max-w-md w-full mx-4\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)] mb-4\">\r\n {t('admin:organisations.verifyTitle', 'Verify Organisation')}\r\n </h2>\r\n <div className=\"mb-4 space-y-3\">\r\n <div>\r\n <label className=\"block text-sm text-[var(--text-secondary)] mb-1\">\r\n {t('admin:organisations.verifyNotes', 'Notes (optional)')}\r\n </label>\r\n <textarea\r\n value={verifyModal.notes}\r\n onChange={(e) => setVerifyModal({ ...verifyModal, notes: e.target.value })}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n rows={3}\r\n placeholder={t('admin:organisations.verifyNotesPlaceholder', 'Add notes about verification')}\r\n />\r\n </div>\r\n </div>\r\n <div className=\"flex gap-2 justify-end\">\r\n <button\r\n onClick={() => setVerifyModal({ show: false, notes: '' })}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common:cancel', 'Cancel')}\r\n </button>\r\n <button\r\n onClick={handleVerify}\r\n disabled={actionLoading}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--success-bg)] text-[var(--success-text)] hover:opacity-90 disabled:opacity-50\"\r\n >\r\n {actionLoading ? t('common:saving', 'Saving') : t('admin:organisations.verify', 'Verify')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {rejectModal.show && (\r\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] p-6 max-w-md w-full mx-4\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)] mb-4\">\r\n {t('admin:organisations.rejectTitle', 'Reject Organisation')}\r\n </h2>\r\n <div className=\"mb-4\">\r\n <label className=\"block text-sm text-[var(--text-secondary)] mb-1\">\r\n {t('admin:organisations.rejectReason', 'Reason')}\r\n </label>\r\n <textarea\r\n value={rejectModal.reason}\r\n onChange={(e) => setRejectModal({ ...rejectModal, reason: e.target.value })}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n rows={3}\r\n placeholder={t('admin:organisations.rejectReasonPlaceholder', 'Explain why this organisation is rejected')}\r\n />\r\n </div>\r\n <div className=\"flex gap-2 justify-end\">\r\n <button\r\n onClick={() => setRejectModal({ show: false, reason: '' })}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common:cancel', 'Cancel')}\r\n </button>\r\n <button\r\n onClick={handleReject}\r\n disabled={actionLoading}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--error-bg)] text-[var(--error-text)] hover:opacity-90 disabled:opacity-50\"\r\n >\r\n {actionLoading ? t('common:saving', 'Saving') : t('admin:organisations.reject', 'Reject')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Loader2,\r\n AlertTriangle,\r\n Check,\r\n Search,\r\n} from 'lucide-react';\r\nimport {\r\n adminApi,\r\n type CreateOrganisationRequest,\r\n type BusinessIdentifierType,\r\n} from '@/services/api/adminApi';\r\n\r\n// Country to business identifier type mapping\r\nconst countryIdentifierTypes: Record<string, {\r\n types: BusinessIdentifierType[];\r\n defaultType: BusinessIdentifierType;\r\n country: string;\r\n vatSuffix?: string;\r\n}> = {\r\n CH: { types: ['UID_CHE'], defaultType: 'UID_CHE', country: 'Switzerland', vatSuffix: 'MWST' },\r\n FR: { types: ['SIREN', 'SIRET'], defaultType: 'SIREN', country: 'France', vatSuffix: 'TVA' },\r\n DE: { types: ['HRB', 'HRA'], defaultType: 'HRB', country: 'Germany', vatSuffix: 'USt' },\r\n BE: { types: ['BCE_KBO'], defaultType: 'BCE_KBO', country: 'Belgium', vatSuffix: 'TVA' },\r\n NL: { types: ['KVK'], defaultType: 'KVK', country: 'Netherlands', vatSuffix: 'BTW' },\r\n ES: { types: ['CIF'], defaultType: 'CIF', country: 'Spain', vatSuffix: 'IVA' },\r\n IT: { types: ['PartitaIVA'], defaultType: 'PartitaIVA', country: 'Italy', vatSuffix: 'IVA' },\r\n GB: { types: ['CRN'], defaultType: 'CRN', country: 'United Kingdom', vatSuffix: 'VAT' },\r\n};\r\n\r\nexport interface OrganisationFormData {\r\n name: string;\r\n legalName?: string;\r\n countryCode: string;\r\n businessIdentifierType: BusinessIdentifierType;\r\n businessIdentifier: string;\r\n vatNumber?: string;\r\n phone?: string;\r\n email?: string;\r\n website?: string;\r\n isFromRegistry: boolean;\r\n address: {\r\n street: string;\r\n street2?: string;\r\n postalCode: string;\r\n city: string;\r\n state?: string | null;\r\n country: string;\r\n countryCode: string;\r\n };\r\n}\r\n\r\ninterface CreateOrganisationFormProps {\r\n /** Form data (controlled) */\r\n readonly data: OrganisationFormData;\r\n /** Callback when form data changes */\r\n readonly onChange: (data: OrganisationFormData) => void;\r\n /** Callback when tenant name should be updated (optional, for TenantCreatePage) */\r\n readonly onTenantNameSuggested?: (name: string) => void;\r\n /** Whether the form is in a compact modal layout */\r\n readonly compact?: boolean;\r\n /** Whether form submission was attempted (shows validation errors) */\r\n readonly submitted?: boolean;\r\n /** Additional class names */\r\n readonly className?: string;\r\n}\r\n\r\n/**\r\n * Shared form component for creating organisations.\r\n * Used by both TenantCreatePage and TenantDetailPage modal.\r\n */\r\nexport function CreateOrganisationForm({\r\n data,\r\n onChange,\r\n onTenantNameSuggested,\r\n compact = false,\r\n submitted = false,\r\n className = '',\r\n}: CreateOrganisationFormProps): ReactElement {\r\n const { t, i18n } = useTranslation(['admin', 'common']);\r\n\r\n // Lookup state\r\n const [lookupLoading, setLookupLoading] = useState(false);\r\n const [lookupError, setLookupError] = useState<string | null>(null);\r\n const [lookupSuccess, setLookupSuccess] = useState(false);\r\n\r\n // Format CHE number: CHE-XXX.XXX.XXX\r\n const formatCheNumber = (value: string): string => {\r\n const cleaned = value.toUpperCase().replace(/[^A-Z0-9]/g, '');\r\n let digits = cleaned.startsWith('CHE') ? cleaned.slice(3) : cleaned.replace(/[^0-9]/g, '');\r\n digits = digits.slice(0, 9);\r\n\r\n if (digits.length === 0) return 'CHE-';\r\n if (digits.length <= 3) return `CHE-${digits}`;\r\n if (digits.length <= 6) return `CHE-${digits.slice(0, 3)}.${digits.slice(3)}`;\r\n return `CHE-${digits.slice(0, 3)}.${digits.slice(3, 6)}.${digits.slice(6)}`;\r\n };\r\n\r\n // Get VAT suffix based on language preference for Switzerland\r\n const getVatSuffix = (): string => {\r\n const lang = i18n.language?.substring(0, 2).toLowerCase();\r\n switch (lang) {\r\n case 'de': return 'MWST';\r\n case 'fr': return 'TVA';\r\n case 'it': return 'IVA';\r\n default: return 'MWST'; // Default to German for Switzerland\r\n }\r\n };\r\n\r\n const handleBusinessIdChange = (value: string) => {\r\n let newValue = value;\r\n if (data.countryCode === 'CH') {\r\n newValue = formatCheNumber(value);\r\n }\r\n onChange({ ...data, businessIdentifier: newValue, isFromRegistry: false });\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n };\r\n\r\n const handleCountryChange = (countryCode: string) => {\r\n const config = countryIdentifierTypes[countryCode];\r\n if (config) {\r\n onChange({\r\n ...data,\r\n countryCode,\r\n businessIdentifierType: config.defaultType,\r\n businessIdentifier: countryCode === 'CH' ? 'CHE-' : '',\r\n isFromRegistry: false,\r\n address: {\r\n ...data.address,\r\n countryCode,\r\n country: config.country,\r\n },\r\n });\r\n }\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n };\r\n\r\n // Pre-fill CHE- when switching to Switzerland\r\n useEffect(() => {\r\n if (data.countryCode === 'CH' && (!data.businessIdentifier || data.businessIdentifier === '')) {\r\n onChange({ ...data, businessIdentifier: 'CHE-' });\r\n }\r\n }, [data.countryCode]);\r\n\r\n const handleLookup = async () => {\r\n const cleanedId = data.businessIdentifier.replace(/[^0-9]/g, '');\r\n if (!data.businessIdentifier || cleanedId.length < 9 || data.countryCode !== 'CH') {\r\n setLookupError(t('admin:tenants.organisation.lookupIncomplete', 'Please enter a complete CHE number (9 digits)'));\r\n return;\r\n }\r\n\r\n setLookupLoading(true);\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n\r\n try {\r\n const result = await adminApi.organisations.lookup(data.countryCode, data.businessIdentifier);\r\n\r\n // Auto-fill form fields\r\n const updatedData: OrganisationFormData = {\r\n ...data,\r\n name: result.name || data.name,\r\n legalName: result.legalName || data.legalName,\r\n vatNumber: result.vatNumber ? `${result.vatNumber} ${getVatSuffix()}` : data.vatNumber,\r\n phone: result.phone || data.phone,\r\n email: result.email || data.email,\r\n website: result.website || data.website,\r\n isFromRegistry: true,\r\n address: {\r\n street: result.street || data.address.street,\r\n street2: result.street2 || data.address.street2,\r\n postalCode: result.postalCode || data.address.postalCode,\r\n city: result.city || data.address.city,\r\n state: result.state || data.address.state,\r\n country: result.country || data.address.country,\r\n countryCode: result.countryCode || data.address.countryCode,\r\n },\r\n };\r\n\r\n onChange(updatedData);\r\n\r\n // Suggest tenant name if callback provided\r\n if (onTenantNameSuggested && result.name) {\r\n onTenantNameSuggested(result.name);\r\n }\r\n\r\n setLookupSuccess(true);\r\n setTimeout(() => setLookupSuccess(false), 3000);\r\n } catch (err: unknown) {\r\n console.error('[Zefix Lookup] Failed:', err);\r\n const errorMessage = err instanceof Error ? err.message : '';\r\n if (errorMessage.includes('404') || errorMessage.includes('not found')) {\r\n setLookupError(t('admin:tenants.organisation.lookupFailed', 'Company not found in registry'));\r\n } else if (errorMessage.includes('credentials') || errorMessage.includes('401')) {\r\n setLookupError(t('admin:tenants.organisation.lookupAuthError', 'Registry service not configured'));\r\n } else {\r\n setLookupError(t('admin:tenants.organisation.lookupFailed', 'Company not found in registry'));\r\n }\r\n } finally {\r\n setLookupLoading(false);\r\n }\r\n };\r\n\r\n const inputClass = compact\r\n ? \"w-full px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-input)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n : \"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\";\r\n\r\n const inputErrorClass = \"border-[var(--error-text)] ring-1 ring-[var(--error-text)]\";\r\n\r\n const fieldClass = (hasError: boolean) =>\r\n hasError ? `${inputClass} ${inputErrorClass}` : inputClass;\r\n\r\n const labelClass = \"block text-sm font-medium text-[var(--text-secondary)] mb-1\";\r\n\r\n return (\r\n <div className={`space-y-4 ${className}`}>\r\n {/* Organisation Name */}\r\n <div>\r\n <label className={labelClass}>\r\n {t('admin:tenants.organisation.form.name', 'Organisation Name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={data.name}\r\n onChange={(e) => onChange({ ...data, name: e.target.value })}\r\n className={fieldClass(submitted && !data.name.trim())}\r\n placeholder={t('admin:tenants.organisation.form.namePlaceholder', 'Enter organisation name')}\r\n />\r\n {submitted && !data.name.trim() && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1\">{t('common:validation.required', 'This field is required')}</p>\r\n )}\r\n </div>\r\n\r\n {/* Country */}\r\n <div>\r\n <label className={labelClass}>\r\n {t('admin:tenants.organisation.form.country', 'Country')} *\r\n </label>\r\n <select\r\n value={data.countryCode}\r\n onChange={(e) => handleCountryChange(e.target.value)}\r\n className={inputClass}\r\n >\r\n {Object.entries(countryIdentifierTypes).map(([code, config]) => (\r\n <option key={code} value={code}>{config.country} ({code})</option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n {/* Business Identifier */}\r\n <div>\r\n <label className={labelClass}>\r\n {data.businessIdentifierType} *\r\n </label>\r\n <div className=\"flex gap-2\">\r\n <input\r\n type=\"text\"\r\n value={data.businessIdentifier}\r\n onChange={(e) => handleBusinessIdChange(e.target.value)}\r\n className={`flex-1 ${inputClass} font-mono`}\r\n placeholder={data.countryCode === 'CH' ? 'CHE-123.456.789' : t('admin:tenants.organisation.form.identifierPlaceholder', 'Enter identifier')}\r\n />\r\n {/* Search button - only show for Switzerland */}\r\n {data.countryCode === 'CH' && (\r\n <button\r\n type=\"button\"\r\n onClick={handleLookup}\r\n disabled={lookupLoading || !data.businessIdentifier || data.businessIdentifier.replace(/[^0-9]/g, '').length < 9}\r\n className=\"px-3 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-500)] text-white hover:bg-[var(--color-accent-600)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center\"\r\n title={t('admin:tenants.organisation.lookupTitle', 'Search in registry')}\r\n >\r\n {lookupLoading ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Search className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n )}\r\n </div>\r\n {/* Feedback messages */}\r\n {lookupError && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1 flex items-center gap-1\">\r\n <AlertTriangle className=\"w-3 h-3\" />\r\n {lookupError}\r\n </p>\r\n )}\r\n {lookupSuccess && (\r\n <p className=\"text-xs text-[var(--success-text)] mt-1 flex items-center gap-1\">\r\n <Check className=\"w-3 h-3\" />\r\n {t('admin:tenants.organisation.lookupSuccess', 'Information retrieved successfully')}\r\n </p>\r\n )}\r\n {data.countryCode === 'CH' && !lookupError && !lookupSuccess && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1\">\r\n {data.businessIdentifier.replace(/[^0-9]/g, '').length < 9\r\n ? t('admin:tenants.organisation.lookupHintIncomplete', 'Enter 9 digits to enable Zefix lookup')\r\n : t('admin:tenants.organisation.lookupHint', 'Click search button to auto-fill from Zefix')}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Address */}\r\n <div className=\"space-y-3\">\r\n <label className={labelClass}>\r\n {t('admin:tenants.organisation.form.address', 'Address')} *\r\n </label>\r\n <div>\r\n <input\r\n type=\"text\"\r\n value={data.address.street}\r\n onChange={(e) => onChange({ ...data, address: { ...data.address, street: e.target.value } })}\r\n className={fieldClass(submitted && !data.address.street.trim())}\r\n placeholder={t('admin:tenants.organisation.form.streetPlaceholder', 'Street address')}\r\n />\r\n {submitted && !data.address.street.trim() && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1\">{t('common:validation.required', 'This field is required')}</p>\r\n )}\r\n </div>\r\n <div className=\"grid grid-cols-3 gap-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n value={data.address.postalCode}\r\n onChange={(e) => onChange({ ...data, address: { ...data.address, postalCode: e.target.value } })}\r\n className={fieldClass(submitted && !data.address.postalCode.trim())}\r\n placeholder={t('admin:tenants.organisation.form.postalCodePlaceholder', 'Postal code')}\r\n />\r\n {submitted && !data.address.postalCode.trim() && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1\">{t('common:validation.required', 'This field is required')}</p>\r\n )}\r\n </div>\r\n <div className=\"col-span-2\">\r\n <input\r\n type=\"text\"\r\n value={data.address.city}\r\n onChange={(e) => onChange({ ...data, address: { ...data.address, city: e.target.value } })}\r\n className={fieldClass(submitted && !data.address.city.trim())}\r\n placeholder={t('admin:tenants.organisation.form.cityPlaceholder', 'City')}\r\n />\r\n {submitted && !data.address.city.trim() && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1\">{t('common:validation.required', 'This field is required')}</p>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* VAT Number */}\r\n <div>\r\n <label className={labelClass}>\r\n {t('admin:tenants.organisation.form.vatNumber', 'VAT Number')} ({t('common:optional', 'optional')})\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={data.vatNumber || ''}\r\n onChange={(e) => onChange({ ...data, vatNumber: e.target.value || undefined })}\r\n className={inputClass}\r\n placeholder={data.countryCode === 'CH' ? `CHE-123.456.789 ${getVatSuffix()}` : 'FRXX123456789'}\r\n />\r\n {data.countryCode === 'CH' && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1\">\r\n {t('admin:tenants.organisation.vatHint', 'VAT suffix will be added automatically based on language (MWST/TVA/IVA)')}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// Helper to create initial form data\r\nexport function createInitialOrganisationData(): OrganisationFormData {\r\n return {\r\n name: '',\r\n countryCode: 'CH',\r\n businessIdentifierType: 'UID_CHE',\r\n businessIdentifier: 'CHE-',\r\n isFromRegistry: false,\r\n address: {\r\n street: '',\r\n postalCode: '',\r\n city: '',\r\n state: null,\r\n country: 'Switzerland',\r\n countryCode: 'CH',\r\n },\r\n };\r\n}\r\n\r\n// Helper to convert form data to API request\r\nexport function toCreateOrganisationRequest(data: OrganisationFormData): CreateOrganisationRequest {\r\n return {\r\n name: data.name,\r\n legalName: data.legalName,\r\n countryCode: data.countryCode,\r\n businessIdentifierType: data.businessIdentifierType,\r\n businessIdentifier: data.businessIdentifier,\r\n vatNumber: data.vatNumber,\r\n phone: data.phone,\r\n email: data.email,\r\n website: data.website,\r\n isFromRegistry: data.isFromRegistry || undefined,\r\n address: {\r\n street: data.address.street,\r\n street2: data.address.street2 ?? undefined,\r\n postalCode: data.address.postalCode,\r\n city: data.address.city,\r\n state: data.address.state ?? undefined,\r\n country: data.address.country,\r\n countryCode: data.address.countryCode,\r\n },\r\n };\r\n}\r\n","import { useState } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { ArrowLeft, Loader2, AlertTriangle } from 'lucide-react';\r\nimport {\r\n CreateOrganisationForm,\r\n createInitialOrganisationData,\r\n toCreateOrganisationRequest,\r\n type OrganisationFormData,\r\n} from '@/components/platform/administration/organisations/CreateOrganisationForm';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\n\r\nexport function OrganisationCreatePage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const navigate = useNavigate();\r\n\r\n const [formData, setFormData] = useState<OrganisationFormData>(createInitialOrganisationData());\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [submitted, setSubmitted] = useState(false);\r\n\r\n const isValid = formData.name.trim() && formData.address.street.trim() && formData.address.city.trim() && formData.address.postalCode.trim();\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSubmitted(true);\r\n\r\n if (!isValid) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n const request = toCreateOrganisationRequest(formData);\r\n const created = await adminApi.organisations.create(request);\r\n navigate(`/administration/tenants/organisations/${created.id}`);\r\n } catch (err) {\r\n console.error('Failed to create organisation:', err);\r\n setError(\r\n err instanceof Error\r\n ? err.message\r\n : t('admin:organisations.createError', 'Failed to create organisation')\r\n );\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('admin:organisations.title', 'Organisations'), href: '/administration/tenants/organisations' },\r\n { label: t('common:create', 'Create') },\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/tenants/organisations')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('admin:organisations.create', 'Create Organisation')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:organisations.createDescription', 'Add a new organisation to the system')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-6\">\r\n <div className=\"p-6 rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)]\">\r\n <CreateOrganisationForm data={formData} onChange={setFormData} submitted={submitted} />\r\n </div>\r\n\r\n <div className=\"flex justify-end gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={() => navigate('/administration/tenants/organisations')}\r\n className=\"px-6 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {t('common:cancel', 'Cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={loading}\r\n className=\"flex items-center gap-2 px-6 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-500)] text-white hover:bg-[var(--color-accent-600)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {loading && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {loading ? t('common:saving', 'Saving') : t('common:create', 'Create')}\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n );\r\n}\r\n"],"names":["VALID_STATUSES","VALID_TYPES","defaultFilters","validateStatus","value","validateType","validatePage","parsed","getDefaultFilters","lockedType","excludeTypes","useActiveFilterCount","filters","useMemo","count","useDebounce","delay","debouncedValue","setDebouncedValue","useState","useEffect","handler","STATUS_CONFIG","TYPE_CONFIG","User","Building","Server","TenantsPage","t","useTranslation","navigate","useNavigate","searchParams","setSearchParams","useSearchParams","currentTenant","isGlobalView","refreshTenants","useTenant","buildTenantUrl","useTenantUrl","getIconForType","useTenantTypeSettings","initialFilters","tenants","setTenants","loading","setLoading","setFilters","showFilters","setShowFilters","menuOpen","setMenuOpen","actionLoading","setActionLoading","confirmAction","setConfirmAction","viewMode","setViewMode","page","setPage","totalPages","setTotalPages","totalCount","setTotalCount","error","setError","sortKey","setSortKey","sortDesc","setSortDesc","debouncedSearch","activeFilterCount","loadTenants","useCallback","result","adminApi","err","params","handleResetFilters","updateFilter","key","prev","handleActivate","tenant","handleSuspend","handleArchive","handleConfirmAction","action","getConfirmModalMessage","tenantName","getConfirmModalLabel","getConfirmModalVariant","getConfirmModalProps","stats","sum","paginatedTenants","toggleSort","SortIcon","column","jsx","ArrowUpDown","ArrowDown","ArrowUp","getTenantStatusVariant","status","getPageTitle","getPageSubtitle","getPageIcon","Building2","pageTitle","pageSubtitle","PageIcon","hideTypeColumn","columnCount","renderTableHeader","columnLabel","columnKey","hidden","jsxs","renderTableActionsMenu","e","Loader2","MoreHorizontal","Eye","Edit2","Users","PlayCircle","PauseCircle","Archive","renderTableRow","typeInfo","RowIcon","getLucideIcon","rowColors","getColorClasses","statusConfig","StatusBadge","Layers","Clock","renderLoadingRow","renderEmptyRow","renderTableView","buildCardTags","buildCardActions","buildCardStats","Boxes","mapTenantToCardProps","avatarColor","renderCardsView","EntityCard","Breadcrumb","PageHeader","Fragment","AlertCircle","Search","ChevronDown","Filter","RotateCcw","ViewToggle","Pagination","props","ConfirmModal","useTenantDetail","tenantId","setTenant","editingGeneralInfo","setEditingGeneralInfo","editName","setEditName","editDescription","setEditDescription","savingGeneralInfo","setSavingGeneralInfo","loadTenant","data","openEditGeneralInfo","closeEditGeneralInfo","handleSaveGeneralInfo","useTenantMembers","members","setMembers","loadingMembers","setLoadingMembers","addingMember","setAddingMember","availableUsers","setAvailableUsers","loadingUsers","setLoadingUsers","userSearchTerm","setUserSearchTerm","selectedUserId","setSelectedUserId","addingMemberLoading","setAddingMemberLoading","selectedMemberForRoles","setSelectedMemberForRoles","availableRoles","setAvailableRoles","selectedRoleIds","setSelectedRoleIds","loadingRoles","setLoadingRoles","savingRoles","setSavingRoles","loadMembers","loadAvailableUsers","memberUserIds","m","u","handleAddMember","handleRemoveMember","userId","loadAvailableRoles","openRoleModal","member","r","closeRoleModal","handleRoleToggle","roleId","id","handleSaveRoles","useTenantGroups","groups","setGroups","loadingGroups","setLoadingGroups","addingGroup","setAddingGroup","availableGroupsForTenant","setAvailableGroupsForTenant","loadingAvailableGroups","setLoadingAvailableGroups","selectedGroupIds","setSelectedGroupIds","assigningGroups","setAssigningGroups","groupSearchTerm","setGroupSearchTerm","removingGroupId","setRemovingGroupId","loadGroups","loadAvailableGroups","handleAssignGroups","succeeded","failed","groupId","handleRemoveGroup","updateModuleAssignment","module","moduleId","newIsAssigned","s","updateSectionAssignment","sectionId","newSections","anySectionAssigned","assignAllSections","clearAllSections","useTenantApplications","options","applications","setApplications","loadingApps","setLoadingApps","addingApplication","setAddingApplication","availableApps","setAvailableApps","loadingAvailableApps","setLoadingAvailableApps","selectedAppIds","setSelectedAppIds","assigningApps","setAssigningApps","appSearchTerm","setAppSearchTerm","availableAppsError","setAvailableAppsError","selectedAccessLevel","setSelectedAccessLevel","bulkAccessMode","setBulkAccessMode","bulkModules","setBulkModules","bulkExpandedModules","setBulkExpandedModules","loadingBulkModules","setLoadingBulkModules","showCustomizeDrawer","setShowCustomizeDrawer","customizingApp","setCustomizingApp","loadApplications","loadAvailableApps","availableAppsResult","a","isForbidden","closeAddApplication","handleAssignApplications","request","handleRemoveApplication","appId","handleUpdateAccessLevel","accessLevel","openCustomizeDrawer","app","closeCustomizeDrawer","handleSaveOverrides","handleResetOverrides","filteredAvailableApps","searchLower","handleAppToggle","selectAllFilteredApps","filteredIds","clearAppSelection","loadBulkModulesForApp","appModules","moduleNodes","appModule","sectionNodes","section","toggleBulkModuleExpand","newSet","toggleBulkModule","toggleBulkSection","getBulkModuleCheckState","assignedCount","getBulkStats","totalModules","assignedModules","totalSections","assignedSections","selectAllBulkModules","clearBulkModules","COUNTRY_IDENTIFIER_TYPES","DEFAULT_ORG_FORM","useTenantOrganisation","showLinkOrgModal","setShowLinkOrgModal","availableOrgs","setAvailableOrgs","loadingOrgs","setLoadingOrgs","selectedOrgId","setSelectedOrgId","linkingOrg","setLinkingOrg","orgSearchTerm","setOrgSearchTerm","showCreateOrgForm","setShowCreateOrgForm","creatingOrg","setCreatingOrg","newOrgForm","setNewOrgForm","lookupLoading","setLookupLoading","lookupError","setLookupError","lookupSuccess","setLookupSuccess","loadAvailableOrgs","search","response","openLinkOrgModal","closeLinkOrgModal","handleLinkOrganisation","handleUnlinkOrganisation","handleCreateAndLinkOrganisation","createdOrg","formatCheNumber","cleaned","digits","handleBusinessIdChange","handleZefixLookup","cleanedId","errorMessage","handleCountryChange","countryCode","config","useTenantRoles","roles","setRoles","loadRoles","TemplateSelectionModal","show","templates","selectedTemplateId","loadingTemplates","assigningTemplate","onTemplateSelect","onClose","onAssign","tenantTemplateId","X","tmpl","TenantGeneralInfoSection","onEditClick","Info","Edit3","TenantTicketingSection","ticketingConfig","loadingTicketing","Headphones","Settings","CheckCircle2","TenantTemplateSection","onOpenTemplateModal","onRemoveTemplate","removingTemplate","ExternalLink","Plus","Star","ArrowRight","TenantOverviewTab","tenantOwner","onRefresh","onStatusChange","onMembersTabClick","onLinkOrgClick","onUnlinkOrg","editState","setEditState","showTemplateModal","setShowTemplateModal","setTemplates","setLoadingTemplates","setSelectedTemplateId","setAssigningTemplate","setRemovingTemplate","setTicketingConfig","setLoadingTicketing","loadTicketingConfig","ticketingApi","loadTemplates","handleOpenTemplateModal","handleAssignTemplate","handleRemoveTemplate","RefreshCw","typeOption","formatDate","date","TenantMembersTab","onRemoveMember","manageRolesState","setManageRolesState","openRolesModal","closeRolesModal","openAddMember","closeAddMember","columns","Link","Crown","role","Shield","source","UsersRound","Link2","UserMinus","DataTable","term","user","TenantGroupsTab","onRemoveGroup","removeConfirm","setRemoveConfirm","showCreateModal","setShowCreateModal","newGroupName","setNewGroupName","newGroupDescription","setNewGroupDescription","newGroupIsSecurityGroup","setNewGroupIsSecurityGroup","creating","setCreating","createError","setCreateError","openAddGroup","closeAddGroup","handleGroupToggle","handleAddGroups","handleCreateGroup","created","groupsApi","axiosError","group","Cloud","filteredGroups","g","Check","CATEGORY_STYLES","TenantRolesTab","Lock","style","AppWindow","Globe","SOURCE_COLORS","computeModuleOverrides","modules","overrides","wasActive","isNowChecked","computeSectionOverrides","sWasActive","sIsNowChecked","updateModuleCheckStateHelper","newChecked","updateSectionCheckStateHelper","SectionItem","renderIcon","checkRevoked","toggleSection","sectionRevoked","Ban","ModuleRow","isExpanded","getModuleCheckState","toggleModuleExpand","toggleModule","mode","checkState","moduleRevoked","ChevronRight","Minus","ApplicationAccessCustomizeDrawer","isOpen","application","onSaved","saving","setSaving","success","setSuccess","accessMode","setAccessMode","setModules","expandedModules","setExpandedModules","iconName","IconComponent","LucideIcons","loadData","expanded","hasAnyOverride","preCheckAllModules","mods","handleAccessModeChange","newMode","isInheritedRevoked","originalSource","isChecked","checkedCount","saveTemplateMode","moduleIds","sectionIds","saveTenantMode","moduleOverrides","sectionOverrides","handleSave","handleReset","resetAction","checkedModules","checkedSections","inheritedCount","directCount","revokedCount","revokedInheritedModules","revokedInheritedSections","handleEscape","CheckCircle","Save","getCheckStateClassName","getLoadingView","getEmptyApplicationsView","ACCESS_LEVEL_OPTIONS","AccessLevelSelector","opt","isSelected","TenantApplicationsTab","onUpdateAccessLevel","onRemoveApplication","onOpenAddApplication","onCloseAddApplication","onAssignApplications","onAppToggle","onSelectAllApps","onClearAppSelection","onOpenCustomizeDrawer","onCloseCustomizeDrawer","onLoadBulkModules","onToggleBulkModuleExpand","onToggleBulkModule","onToggleBulkSection","onGetBulkModuleCheckState","onGetBulkStats","onSelectAllBulkModules","onClearBulkModules","bulkStats","inheritedApps","directApps","renderAppCard","accessLevelOption","o","isActive","SlidersHorizontal","Trash2","ShieldX","AlertTriangle","icons","ModuleIcon","SectionIcon","VALID_TABS","TenantDetailPage","useParams","activeTab","setActiveTab","useTabNavigation","refreshMenu","useNavigation","tenantDetail","tenantMembers","tenantGroups","handleApplicationsChanged","tenantAppOptions","tenantApplications","tenantRoles","tenantOrganisation","accessRequests","useAccessRequests","confirmModal","setConfirmModal","loadedTabs","setLoadedTabs","handleStatusChange","newStatus","statusMessages","handleRefresh","promises","getStatusIcon","ArrowLeft","tab","owner","AccessRequestsListTab","BUSINESS_IDENTIFIER_TYPES","getTenantTypeFromUrl","typeFromUrl","applyConfigTypeRestrictions","buildOrganisationRequest","orgName","orgLegalName","orgCountryCode","orgBusinessIdType","orgBusinessId","orgVatNumber","addrStreet","addrStreet2","addrPostalCode","addrCity","addrState","addrCountry","addrCountryCode","orgPhone","orgEmail","orgWebsite","isFromRegistry","TenantCreatePage","organisationIdFromUrl","enableB2B","setEnableB2B","enableB2C","setEnableB2C","tenantType","setTenantType","organisationMode","setOrganisationMode","configLoading","setConfigLoading","setIsFromRegistry","selectedOrganisation","setSelectedOrganisation","availableOrganisations","setAvailableOrganisations","orgSearchQuery","setOrgSearchQuery","orgSearchLoading","setOrgSearchLoading","org","name","handleNameChange","debounce","results","setName","slug","setSlug","description","setDescription","setOrgName","setOrgLegalName","setOrgCountryCode","setOrgBusinessIdType","setOrgBusinessId","setOrgVatNumber","setOrgPhone","setOrgEmail","setOrgWebsite","setAddrStreet","setAddrStreet2","setAddrPostalCode","setAddrCity","setAddrState","setAddrCountry","setAddrCountryCode","generateSlug","validateLookupInput","fillOrganisationFields","fillAddressFields","mapLookupError","handleLookup","submitB2CTenant","submitB2BTenant","organisation","handleSubmit","isFormValid","Hash","FileText","Zap","FileCheck","newType","type","MapPin","Phone","Mail","UserPlus","COLORS","renderActiveShape","cx","cy","midAngle","innerRadius","outerRadius","startAngle","endAngle","fill","payload","percent","RADIAN","sin","cos","sx","sy","mx","my","ex","ey","textAnchor","Sector","TenantActivityPieChart","activeIndex","setActiveIndex","getValue","valueLabel","totalValue","chartData","index","onPieEnter","_","ResponsiveContainer","PieChart","Pie","entry","Cell","item","DEFAULT_COLORS","LegendItem","getColor","TenantUsageTrendChart","period","setData","tenantAnalyticsApi","day","LineChart","CartesianGrid","XAxis","YAxis","Tooltip","Legend","Line","tenantColors","TenantPopularityChart","maxCount","percentage","KpiCard","label","icon","color","subtitle","iconColors","TenantsDashboardPage","setStats","topTenants","setTopTenants","refreshing","setRefreshing","setPeriod","chartMode","setChartMode","dashboardRes","topTenantsRes","formatDuration","seconds","minutes","Activity","Timer","TrendingUp","ClipboardList","ShieldCheck","mapTemplateAppToTenantApp","useTemplateApplications","templateId","mapped","_appId","_request","TenantTemplateDetailPage","template","setTemplate","templateApplications","loadTemplate","TypeIcon","typeLabel","InfoTab","TenantsTab","AiInstancesTab","StatCard","LayoutGrid","memo","tabError","setTabError","instances","setInstances","loadInstances","handleRemove","instanceId","Brain","instance","TenantsTemplatePage","handleCardClick","systemTemplates","customTemplates","Settings2","SystemTemplateCard","CustomTemplateCard","onClick","TenantTemplateCreatePage","code","setCode","targetTenantType","setTargetTenantType","TenantsBusinessPage","TenantsPersonalPage","TenantsOtherPage","STATUS_FILTERS","TenantAccessRequestsPage","requests","setRequests","statusFilter","setStatusFilter","loadRequests","accessRequestsApi","ENTRA_PERMISSIONS","ENTRA_SYNC_TYPES","REQUIRED_PERMISSIONS","USER_TYPES","calculateElapsedTime","startedAt","now","start","diffSeconds","handleEntraNotification","notification","setActiveSyncSession","SectionCard","Icon","title","children","className","Toggle","checked","onChange","disabled","isValidGuid","ConfigTabReadOnly","canEdit","onEdit","Key","GitMerge","ConfigTab","onConfigUpdated","entraApi","editing","setEditing","testing","setTesting","testResult","setTestResult","showSecret","setShowSecret","copiedPermission","setCopiedPermission","hasExistingSecret","setHasExistingSecret","validationErrors","setValidationErrors","credentials","setCredentials","syncSettings","setSyncSettings","validateField","field","errorKey","handleCredentialChange","hasValidationErrors","canTestConnection","canSaveCredentials","handleCopyPermission","handleTestConnection","handleSaveCredentials","handleSaveSettings","perm","Copy","EyeOff","TestTube","userType","selectedTypes","newTypes","StatusBadgeMap","Square","SyncStatusIconMap","getStatusBadge","badge","getSyncStatusIcon","completedAt","diffMs","useSyncTabState","syncing","setSyncing","lastSyncResult","setLastSyncResult","syncError","setSyncError","history","setHistory","historyLoading","setHistoryLoading","historyPage","setHistoryPage","historyTotalCount","setHistoryTotalCount","cancellingSessionId","setCancellingSessionId","SyncTab","conflicts","syncStatus","canSync","onResolveConflict","onSyncAll","onLoadHistory","onCancelSession","activeSyncSession","historyPageSize","loadHistory","handleSyncNow","handleCancelSession","sessionId","Play","conflict","ConflictCard","History","session","UsersTab","GroupsTab","TenantEntraTab","tenantSlug","hasPermission","useAuth","isConnected","onNotification","useSignalRContext","activeSubTab","setActiveSubTab","createEntraApi","setConfig","setConflicts","setSyncStatus","selectedConflict","setSelectedConflict","resolving","setResolving","syncElapsedTime","setSyncElapsedTime","abortControllerRef","useRef","isLoadingRef","canRead","availableTabs","configData","conflictsData","syncStatusData","interval","handleResolve","resolution","notes","handleSyncAll","handleLoadHistory","pageSize","showConflictBadge","ResolutionModal","validateGlpiConfig","fields","errors","buildGlpiSaveRequest","provider","syncEnabled","syncIntervalMinutes","InfoBubble","text","TenantSupportSettingsTab","showSecrets","setShowSecrets","fieldErrors","setFieldErrors","setProvider","glpiBaseUrl","setGlpiBaseUrl","glpiClientId","setGlpiClientId","glpiClientSecret","setGlpiClientSecret","glpiUsername","setGlpiUsername","glpiPassword","setGlpiPassword","glpiEntityId","setGlpiEntityId","glpiRequestTypeId","setGlpiRequestTypeId","setSyncEnabled","setSyncIntervalMinutes","isGlpi","fieldErrorClass","loadConfiguration","validateForm","updated","newProvider","rest","TenantSettingsPage","TenantTypeSettingsPage","settings","setSettings","editStates","setEditStates","savingType","setSavingType","loadSettings","tenantTypeSettingsApi","states","state","updateEditState","hasChanges","original","current","Palette","setting","PreviewIcon","previewColors","getAvailableIconNames","colorClasses","VERIFICATION_STATUS_CONFIG","OrganisationsListPage","organisations","setOrganisations","setSearch","verificationFilter","setVerificationFilter","loadOrganisations","signal","abortController","handleSearchChange","statusFilters","OrganisationDetailPage","orgId","setOrganisation","getInitialTab","tabParam","verifyModal","setVerifyModal","rejectModal","setRejectModal","loadOrganisation","handleVerify","handleReject","hasContactData","countryIdentifierTypes","CreateOrganisationForm","onTenantNameSuggested","compact","submitted","i18n","getVatSuffix","newValue","updatedData","inputClass","inputErrorClass","fieldClass","hasError","labelClass","createInitialOrganisationData","toCreateOrganisationRequest","OrganisationCreatePage","formData","setFormData","setSubmitted","isValid"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-0VrOtwP0.js","sources":["../../src/hooks/useTenantFilters.ts","../../src/pages/platform/administration/tenants/TenantsPage.tsx","../../src/hooks/useTenantDetail.ts","../../src/hooks/useTenantMembers.ts","../../src/hooks/useTenantGroups.ts","../../src/hooks/useTenantApplications.ts","../../src/hooks/useTenantOrganisation.ts","../../src/hooks/useTenantRoles.ts","../../src/components/platform/administration/tenants/TenantOverviewTab.tsx","../../src/components/platform/administration/tenants/TenantMembersTab.tsx","../../src/components/platform/administration/tenants/TenantGroupsTab.tsx","../../src/components/platform/administration/tenants/TenantRolesTab.tsx","../../src/components/platform/administration/ApplicationAccessCustomizeDrawer.tsx","../../src/components/platform/administration/tenants/TenantApplicationsTab.tsx","../../src/pages/platform/administration/tenants/TenantDetailPage.tsx","../../src/pages/platform/administration/tenants/TenantCreatePage.tsx","../../src/components/dashboard/TenantActivityPieChart.tsx","../../src/components/dashboard/TenantUsageTrendChart.tsx","../../src/components/dashboard/TenantPopularityChart.tsx","../../src/pages/platform/administration/tenants/TenantsDashboardPage.tsx","../../src/hooks/useTemplateApplications.ts","../../src/pages/platform/administration/tenants/TenantTemplateDetailPage.tsx","../../src/pages/platform/administration/tenants/TenantsTemplatePage.tsx","../../src/pages/platform/administration/tenants/TenantTemplateCreatePage.tsx","../../src/pages/platform/administration/tenants/TenantsBusinessPage.tsx","../../src/pages/platform/administration/tenants/TenantsPersonalPage.tsx","../../src/pages/platform/administration/tenants/TenantsOtherPage.tsx","../../src/pages/platform/administration/tenants/TenantAccessRequestsPage.tsx","../../src/components/platform/administration/TenantEntraTab.tsx","../../src/components/platform/administration/tenants/TenantSupportSettingsTab.tsx","../../src/pages/platform/administration/tenants/TenantSettingsPage.tsx","../../src/pages/platform/administration/tenants/TenantTypeSettingsPage.tsx","../../src/pages/platform/administration/tenants/OrganisationsListPage.tsx","../../src/pages/platform/administration/tenants/OrganisationDetailPage.tsx","../../src/components/platform/administration/organisations/CreateOrganisationForm.tsx","../../src/pages/platform/administration/tenants/OrganisationCreatePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\r\nimport type { TenantStatus, TenantType } from '@/services/api/adminApi';\r\n\r\ninterface FilterState {\r\n search: string;\r\n status: TenantStatus | '';\r\n type: TenantType | '';\r\n}\r\n\r\nconst VALID_STATUSES: TenantStatus[] = ['Pending', 'Active', 'Suspended', 'Archived'];\r\nconst VALID_TYPES: TenantType[] = ['Personal', 'Business', 'System'];\r\n\r\nconst defaultFilters: FilterState = {\r\n search: '',\r\n status: '',\r\n type: 'Business',\r\n};\r\n\r\nexport const validateStatus = (value: string | null): TenantStatus | '' => {\r\n if (!value) return '';\r\n return VALID_STATUSES.includes(value as TenantStatus) ? (value as TenantStatus) : '';\r\n};\r\n\r\nexport const validateType = (value: string | null): TenantType | '' => {\r\n if (!value) return '';\r\n return VALID_TYPES.includes(value as TenantType) ? (value as TenantType) : '';\r\n};\r\n\r\nexport const validatePage = (value: string | null): number => {\r\n const parsed = parseInt(value || '1', 10);\r\n return isNaN(parsed) || parsed < 1 ? 1 : parsed;\r\n};\r\n\r\nexport const getDefaultFilters = (lockedType?: TenantType, excludeTypes?: TenantType[]): FilterState => ({\r\n ...defaultFilters,\r\n type: lockedType || (excludeTypes ? '' as const : 'Business' as const),\r\n});\r\n\r\nexport function useActiveFilterCount(\r\n filters: FilterState,\r\n lockedType?: TenantType,\r\n excludeTypes?: TenantType[]\r\n): number {\r\n return useMemo(() => {\r\n let count = 0;\r\n if (filters.status) count++;\r\n if (!lockedType && !excludeTypes && filters.type) count++;\r\n return count;\r\n }, [filters, lockedType, excludeTypes]);\r\n}\r\n","import { useState, useEffect, useCallback, useMemo } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate, useSearchParams } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Search,\r\n Edit2,\r\n MoreHorizontal,\r\n Building2,\r\n Users,\r\n Boxes,\r\n PlayCircle,\r\n PauseCircle,\r\n Archive,\r\n Loader2,\r\n Building,\r\n User,\r\n Filter,\r\n RotateCcw,\r\n ChevronDown,\r\n Eye,\r\n AlertCircle,\r\n Layers,\r\n Clock,\r\n ArrowUpDown,\r\n ArrowUp,\r\n ArrowDown,\r\n Server\r\n} from 'lucide-react';\r\nimport { adminApi, type TenantListDto, type TenantStatus, type TenantType } from '@/services/api/adminApi';\r\nimport { useTenantTypeSettings } from '@/hooks/useTenantTypeSettings';\r\nimport { getLucideIcon, getColorClasses } from '@/utils/tenantIconMap';\r\nimport { ViewToggle, StatusBadge, Pagination, type ViewMode } from '@/components/ui/DataView';\r\nimport { EntityCard, type EntityCardAction, type EntityCardTag } from '@/components/ui/EntityCard';\r\nimport { PageHeader } from '@/components/ui/PageHeader';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { ConfirmModal, type ConfirmVariant } from '@/components/ui/ConfirmModal';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { useTenantUrl } from '@/utils/tenantUrl';\r\n\r\n// Debounce hook for search\r\nfunction useDebounce<T>(value: T, delay: number): T {\r\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\r\n useEffect(() => {\r\n const handler = setTimeout(() => setDebouncedValue(value), delay);\r\n return () => clearTimeout(handler);\r\n }, [value, delay]);\r\n return debouncedValue;\r\n}\r\n\r\n// Status configuration with CSS variables for theme compliance\r\nconst STATUS_CONFIG: Record<TenantStatus, { color: string; bgColor: string; borderColor: string; statusBadge: 'active' | 'inactive' | 'pending' | 'warning' | 'error' }> = {\r\n Pending: {\r\n color: 'text-[var(--info-text)]',\r\n bgColor: 'bg-[var(--info-bg)]',\r\n borderColor: 'border-[var(--info-border)]',\r\n statusBadge: 'pending'\r\n },\r\n Active: {\r\n color: 'text-[var(--success-text)]',\r\n bgColor: 'bg-[var(--success-bg)]',\r\n borderColor: 'border-[var(--success-border)]',\r\n statusBadge: 'active'\r\n },\r\n Suspended: {\r\n color: 'text-[var(--warning-text)]',\r\n bgColor: 'bg-[var(--warning-bg)]',\r\n borderColor: 'border-[var(--warning-border)]',\r\n statusBadge: 'warning'\r\n },\r\n Archived: {\r\n color: 'text-[var(--text-tertiary)]',\r\n bgColor: 'bg-[var(--bg-tertiary)]',\r\n borderColor: 'border-[var(--border-color)]',\r\n statusBadge: 'inactive'\r\n }\r\n};\r\n\r\nconst TYPE_CONFIG: Record<TenantType, { icon: typeof Building2; label: string }> = {\r\n Personal: { icon: User, label: 'tenants.type.personal' },\r\n Business: { icon: Building, label: 'tenants.type.business' },\r\n System: { icon: Server, label: 'tenants.type.system' }\r\n};\r\n\r\nimport {\r\n validateStatus,\r\n validateType,\r\n validatePage,\r\n getDefaultFilters,\r\n useActiveFilterCount,\r\n} from '@/hooks/useTenantFilters';\r\n\r\ninterface FilterState {\r\n search: string;\r\n status: TenantStatus | '';\r\n type: TenantType | '';\r\n}\r\n\r\n// Props interface for the component\r\ninterface TenantsPageProps {\r\n readonly lockedType?: TenantType;\r\n readonly excludeTypes?: TenantType[];\r\n}\r\n\r\nexport function TenantsPage({ lockedType, excludeTypes }: TenantsPageProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n const { currentTenant, isGlobalView, refreshTenants } = useTenant();\r\n const buildTenantUrl = useTenantUrl();\r\n const { getIconForType } = useTenantTypeSettings();\r\n\r\n // Initialize filters from URL params (only on mount) - F1: validated\r\n const initialFilters: FilterState = useMemo(\r\n () => ({\r\n search: searchParams.get('search') || '',\r\n status: validateStatus(searchParams.get('status')),\r\n type: lockedType || validateType(searchParams.get('type')) || (excludeTypes ? '' : 'Business')\r\n }),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n []\r\n );\r\n\r\n const [tenants, setTenants] = useState<TenantListDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [filters, setFilters] = useState<FilterState>(initialFilters);\r\n const [showFilters, setShowFilters] = useState(false);\r\n const [menuOpen, setMenuOpen] = useState<string | null>(null);\r\n const [actionLoading, setActionLoading] = useState<string | null>(null);\r\n const [confirmAction, setConfirmAction] = useState<{ tenant: TenantListDto; action: 'activate' | 'suspend' | 'archive' } | null>(null);\r\n const [viewMode, setViewMode] = useState<ViewMode>('table');\r\n const [page, setPage] = useState(validatePage(searchParams.get('page')));\r\n const [totalPages, setTotalPages] = useState(1);\r\n const [totalCount, setTotalCount] = useState(0);\r\n const [error, setError] = useState<string | null>(null);\r\n const [sortKey, setSortKey] = useState<string>('name');\r\n const [sortDesc, setSortDesc] = useState(false);\r\n\r\n // Debounce search input\r\n const debouncedSearch = useDebounce(filters.search, 300);\r\n\r\n // Count active filters (exclude lockedType since it's not user-resettable)\r\n const activeFilterCount = useActiveFilterCount(filters, lockedType, excludeTypes);\r\n\r\n const loadTenants = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n setError(null);\r\n const result = await adminApi.tenants.getAll({\r\n page,\r\n pageSize: 20,\r\n search: debouncedSearch || undefined,\r\n status: filters.status || undefined,\r\n type: filters.type || undefined,\r\n sortBy: sortKey,\r\n sortDesc,\r\n excludeTypes,\r\n });\r\n setTenants(result.items);\r\n setTotalCount(result.totalCount);\r\n setTotalPages(result.totalPages);\r\n } catch (err) {\r\n console.error('Failed to load tenants:', err);\r\n setError(t('tenants.loadError'));\r\n setTenants([]);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [page, debouncedSearch, filters.status, filters.type, sortKey, sortDesc, t, currentTenant?.id, isGlobalView, excludeTypes]);\r\n\r\n // Update URL params when filters change\r\n useEffect(() => {\r\n const params = new URLSearchParams();\r\n if (filters.search) params.set('search', filters.search);\r\n if (filters.status) params.set('status', filters.status);\r\n if (filters.type) params.set('type', filters.type);\r\n if (page > 1) params.set('page', page.toString());\r\n setSearchParams(params, { replace: true });\r\n }, [filters, page, setSearchParams]);\r\n\r\n useEffect(() => {\r\n loadTenants();\r\n }, [loadTenants]);\r\n\r\n const handleResetFilters = () => {\r\n setFilters(getDefaultFilters(lockedType, excludeTypes));\r\n setPage(1);\r\n };\r\n\r\n const updateFilter = <K extends keyof FilterState>(key: K, value: FilterState[K]) => {\r\n // If lockedType is set and trying to change type, prevent the change\r\n if (lockedType && key === 'type') {\r\n return;\r\n }\r\n setFilters(prev => ({ ...prev, [key]: value }));\r\n setPage(1);\r\n };\r\n\r\n const handleActivate = (tenant: TenantListDto) => {\r\n setMenuOpen(null);\r\n setConfirmAction({ tenant, action: 'activate' });\r\n };\r\n\r\n const handleSuspend = (tenant: TenantListDto) => {\r\n setMenuOpen(null);\r\n setConfirmAction({ tenant, action: 'suspend' });\r\n };\r\n\r\n const handleArchive = (tenant: TenantListDto) => {\r\n setMenuOpen(null);\r\n setConfirmAction({ tenant, action: 'archive' });\r\n };\r\n\r\n const handleConfirmAction = async () => {\r\n if (!confirmAction) return;\r\n const { tenant, action } = confirmAction;\r\n setActionLoading(tenant.id);\r\n try {\r\n if (action === 'activate') await adminApi.tenants.activate(tenant.id);\r\n else if (action === 'suspend') await adminApi.tenants.suspend(tenant.id);\r\n else if (action === 'archive') await adminApi.tenants.archive(tenant.id);\r\n await refreshTenants();\r\n loadTenants();\r\n } catch (err) {\r\n console.error(`Failed to ${action} tenant:`, err);\r\n } finally {\r\n setActionLoading(null);\r\n setConfirmAction(null);\r\n }\r\n };\r\n\r\n const getConfirmModalMessage = (action: 'activate' | 'suspend' | 'archive', tenantName: string): string => {\r\n switch (action) {\r\n case 'activate':\r\n return t('tenants.confirmActivate', { name: tenantName });\r\n case 'suspend':\r\n return t('tenants.confirmSuspend', { name: tenantName });\r\n case 'archive':\r\n return t('tenants.confirmArchive', { name: tenantName });\r\n }\r\n };\r\n\r\n const getConfirmModalLabel = (action: 'activate' | 'suspend' | 'archive'): string => {\r\n switch (action) {\r\n case 'activate':\r\n return t('tenants.actions.activate');\r\n case 'suspend':\r\n return t('tenants.actions.suspend');\r\n case 'archive':\r\n return t('tenants.actions.archive');\r\n }\r\n };\r\n\r\n const getConfirmModalVariant = (action: 'activate' | 'suspend' | 'archive'): ConfirmVariant => {\r\n switch (action) {\r\n case 'activate':\r\n return 'info';\r\n case 'suspend':\r\n return 'warning';\r\n case 'archive':\r\n return 'danger';\r\n }\r\n };\r\n\r\n const getConfirmModalProps = () => {\r\n if (!confirmAction) return null;\r\n const { tenant, action } = confirmAction;\r\n return {\r\n message: getConfirmModalMessage(action, tenant.name),\r\n label: getConfirmModalLabel(action),\r\n variant: getConfirmModalVariant(action),\r\n };\r\n };\r\n\r\n // Stats computed from tenants\r\n const stats = useMemo(() => ({\r\n active: tenants.filter(t => t.status === 'Active').length,\r\n suspended: tenants.filter(t => t.status === 'Suspended').length,\r\n members: tenants.reduce((sum, t) => sum + (t.memberCount ?? 0), 0),\r\n pendingRequests: tenants.reduce((sum, t) => sum + (t.pendingAccessRequestCount ?? 0), 0)\r\n }), [tenants]);\r\n\r\n // Data is already sorted and paginated by the server\r\n const paginatedTenants = tenants;\r\n\r\n const toggleSort = (key: string) => {\r\n if (sortKey === key) {\r\n setSortDesc(!sortDesc);\r\n } else {\r\n setSortKey(key);\r\n setSortDesc(false);\r\n }\r\n setPage(1);\r\n };\r\n\r\n const SortIcon = ({ column }: { column: string }) => {\r\n if (sortKey !== column) return <ArrowUpDown className=\"w-3.5 h-3.5 text-[var(--text-muted)] opacity-0 group-hover/th:opacity-100 transition-opacity\" />;\r\n return sortDesc\r\n ? <ArrowDown className=\"w-3.5 h-3.5 text-[var(--color-accent-500)]\" />\r\n : <ArrowUp className=\"w-3.5 h-3.5 text-[var(--color-accent-500)]\" />;\r\n };\r\n\r\n const getTenantStatusVariant = (status: TenantStatus): 'success' | 'warning' | 'info' | 'default' => {\r\n if (status === 'Active') return 'success';\r\n if (status === 'Suspended') return 'warning';\r\n if (status === 'Pending') return 'info';\r\n return 'default';\r\n };\r\n\r\n const getPageTitle = (): string => {\r\n if (excludeTypes) return t('tenants.other.title');\r\n switch (lockedType) {\r\n case 'Business':\r\n return t('tenants.enterprise.title');\r\n case 'Personal':\r\n return t('tenants.personal.title');\r\n default:\r\n return t('tenants.title');\r\n }\r\n };\r\n\r\n const getPageSubtitle = (): string => {\r\n if (excludeTypes) return t('tenants.other.subtitle');\r\n switch (lockedType) {\r\n case 'Business':\r\n return t('tenants.enterprise.subtitle');\r\n case 'Personal':\r\n return t('tenants.personal.subtitle');\r\n default:\r\n return t('tenants.subtitle');\r\n }\r\n };\r\n\r\n const getPageIcon = () => {\r\n if (excludeTypes) return Server;\r\n switch (lockedType) {\r\n case 'Business':\r\n return Building;\r\n case 'Personal':\r\n return User;\r\n default:\r\n return Building2;\r\n }\r\n };\r\n\r\n const pageTitle = getPageTitle();\r\n const pageSubtitle = getPageSubtitle();\r\n const PageIcon = getPageIcon();\r\n\r\n const hideTypeColumn = !!lockedType || !!excludeTypes;\r\n // Calculate column count dynamically\r\n const columnCount = 5 + (!hideTypeColumn ? 1 : 0) + 1; // name + status + template + members + requests + actions, optionally type\r\n\r\n const renderTableHeader = (columnLabel: string, columnKey: string, hidden: string = '') => (\r\n <th\r\n className={`text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider cursor-pointer select-none group/th hover:text-[var(--text-primary)] transition-colors ${hidden}`}\r\n onClick={() => toggleSort(columnKey)}\r\n >\r\n <span className=\"inline-flex items-center gap-1.5\">\r\n {columnLabel}\r\n <SortIcon column={columnKey} />\r\n </span>\r\n </th>\r\n );\r\n\r\n const renderTableActionsMenu = (tenant: TenantListDto) => (\r\n <div className=\"flex items-center justify-end gap-1\" onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()} role=\"presentation\">\r\n <div className=\"relative\">\r\n <button\r\n onClick={() => setMenuOpen(menuOpen === tenant.id ? null : tenant.id)}\r\n className=\"p-2 rounded-lg text-[var(--text-tertiary)] hover:bg-[var(--bg-tertiary)] transition-all\"\r\n >\r\n {actionLoading === tenant.id ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <MoreHorizontal className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n\r\n {menuOpen === tenant.id && (\r\n <div className=\"absolute right-0 mt-1 w-48 bg-[var(--bg-card)] border border-[var(--border-color)] shadow-lg z-50\" style={{ borderRadius: 'var(--radius-card)' }}>\r\n <button\r\n onClick={() => {\r\n setMenuOpen(null);\r\n navigate(buildTenantUrl(`/administration/tenants/${tenant.id}`));\r\n }}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <Eye className=\"w-4 h-4\" />\r\n {t('tenants.view')}\r\n </button>\r\n <button\r\n onClick={() => {\r\n setMenuOpen(null);\r\n navigate(buildTenantUrl(`/administration/tenants/${tenant.id}`));\r\n }}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <Edit2 className=\"w-4 h-4\" />\r\n {t('common.edit')}\r\n </button>\r\n <button\r\n onClick={() => {\r\n setMenuOpen(null);\r\n navigate(buildTenantUrl(`/administration/tenants/${tenant.id}/members`));\r\n }}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <Users className=\"w-4 h-4\" />\r\n {t('tenants.actions.viewMembers')}\r\n </button>\r\n <div className=\"border-t border-[var(--border-color)] my-1\" />\r\n {tenant.status !== 'Active' && tenant.status !== 'Archived' && (\r\n <button\r\n onClick={() => handleActivate(tenant)}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm text-[var(--success-text)] hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <PlayCircle className=\"w-4 h-4\" />\r\n {t('tenants.actions.activate')}\r\n </button>\r\n )}\r\n {tenant.status === 'Active' && (\r\n <button\r\n onClick={() => handleSuspend(tenant)}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm text-[var(--warning-text)] hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <PauseCircle className=\"w-4 h-4\" />\r\n {t('tenants.actions.suspend')}\r\n </button>\r\n )}\r\n {tenant.status !== 'Archived' && (\r\n <button\r\n onClick={() => handleArchive(tenant)}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-sm text-[var(--error-text)] hover:bg-[var(--bg-secondary)] transition-colors\"\r\n >\r\n <Archive className=\"w-4 h-4\" />\r\n {t('tenants.actions.archive')}\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n\r\n const renderTableRow = (tenant: TenantListDto) => {\r\n const typeInfo = getIconForType(tenant.type);\r\n const RowIcon = getLucideIcon(typeInfo.icon);\r\n const rowColors = getColorClasses(typeInfo.color);\r\n const statusConfig = STATUS_CONFIG[tenant.status];\r\n\r\n return (\r\n <tr\r\n key={tenant.id}\r\n className={`group hover:bg-[var(--bg-hover)] transition-all cursor-pointer ${menuOpen === tenant.id ? 'relative z-10' : ''}`}\r\n onClick={() => navigate(buildTenantUrl(`/administration/tenants/${tenant.id}`))}\r\n >\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`w-10 h-10 flex items-center justify-center ${rowColors.bg}`} style={{ borderRadius: 'var(--radius-card)' }}>\r\n <RowIcon className={`w-5 h-5 ${rowColors.text}`} />\r\n </div>\r\n <div className=\"min-w-0\">\r\n <p className=\"font-medium text-[var(--text-primary)] group-hover:text-[var(--color-accent-600)] transition-colors truncate\">\r\n {tenant.name}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-tertiary)] truncate\">{tenant.slug}</p>\r\n </div>\r\n </div>\r\n </td>\r\n {!hideTypeColumn && (\r\n <td className=\"px-4 py-3 hidden md:table-cell\">\r\n <div className=\"flex items-center gap-2\">\r\n <RowIcon className={`w-4 h-4 ${rowColors.text}`} />\r\n <span className=\"text-sm text-[var(--text-secondary)]\">\r\n {t(TYPE_CONFIG[tenant.type].label)}\r\n </span>\r\n </div>\r\n {tenant.organisation?.name && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5 truncate\">{tenant.organisation.name}</p>\r\n )}\r\n </td>\r\n )}\r\n <td className=\"px-4 py-3\">\r\n <StatusBadge\r\n status={statusConfig.statusBadge}\r\n label={t(`tenants.status.${tenant.status.toLowerCase()}`)}\r\n />\r\n </td>\r\n <td className=\"px-4 py-3 hidden md:table-cell\">\r\n {tenant.templateName ? (\r\n <div className=\"flex items-center gap-2\">\r\n <Layers className=\"w-4 h-4 text-[var(--color-accent-500)]\" />\r\n <span className=\"text-sm text-[var(--text-primary)]\">{tenant.templateName}</span>\r\n </div>\r\n ) : (\r\n <span className=\"text-sm text-[var(--text-tertiary)]\">-</span>\r\n )}\r\n </td>\r\n <td className=\"px-4 py-3 text-center hidden lg:table-cell\">\r\n <span className=\"text-sm text-[var(--text-primary)]\">{tenant.memberCount ?? 0}</span>\r\n </td>\r\n <td className=\"px-4 py-3 text-center hidden lg:table-cell\">\r\n {(tenant.pendingAccessRequestCount ?? 0) > 0 ? (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)]\">\r\n <Clock className=\"w-3 h-3\" />\r\n {tenant.pendingAccessRequestCount}\r\n </span>\r\n ) : (\r\n <span className=\"text-sm text-[var(--text-tertiary)]\">-</span>\r\n )}\r\n </td>\r\n <td className=\"px-4 py-3\">\r\n {renderTableActionsMenu(tenant)}\r\n </td>\r\n </tr>\r\n );\r\n };\r\n\r\n const renderLoadingRow = () => (\r\n <tr>\r\n <td colSpan={columnCount} className=\"text-center py-8\">\r\n <div className=\"w-6 h-6 border-2 border-[var(--color-accent-500)] border-t-transparent rounded-full animate-spin mx-auto\" />\r\n </td>\r\n </tr>\r\n );\r\n\r\n const renderEmptyRow = () => (\r\n <tr>\r\n <td colSpan={columnCount} className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('tenants.empty')}\r\n </td>\r\n </tr>\r\n );\r\n\r\n const renderTableView = () => (\r\n <div className=\"card\">\r\n <table className=\"w-full\">\r\n <thead className=\"bg-[var(--bg-secondary)]\" style={{ borderRadius: 'var(--radius-card) var(--radius-card) 0 0' }}>\r\n <tr>\r\n {renderTableHeader(t('tenants.columns.name'), 'name')}\r\n {!hideTypeColumn && renderTableHeader(t('tenants.columns.type'), 'type', 'hidden md:table-cell')}\r\n {renderTableHeader(t('tenants.columns.status'), 'status')}\r\n {renderTableHeader(t('tenants.columns.template'), 'template', 'hidden md:table-cell')}\r\n <th className=\"text-center px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('tenants.columns.members')}\r\n </th>\r\n <th className=\"text-center px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('tenants.columns.requests')}\r\n </th>\r\n <th className=\"w-24 px-4 py-3\"></th>\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--border-color)]\">\r\n {loading && renderLoadingRow()}\r\n {!loading && paginatedTenants.length === 0 && renderEmptyRow()}\r\n {!loading && paginatedTenants.length > 0 && paginatedTenants.map(renderTableRow)}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n\r\n const buildCardTags = (tenant: TenantListDto): EntityCardTag[] => [\r\n {\r\n label: t(`tenants.type.${tenant.type.toLowerCase()}`),\r\n variant: tenant.type === 'Business' ? 'info' : 'primary'\r\n },\r\n {\r\n label: t(`tenants.status.${tenant.status.toLowerCase()}`),\r\n variant: getTenantStatusVariant(tenant.status)\r\n }\r\n ];\r\n\r\n const buildCardActions = (tenant: TenantListDto): EntityCardAction[] => [\r\n {\r\n label: t('common.edit'),\r\n onClick: () => navigate(buildTenantUrl(`/administration/tenants/${tenant.id}`)),\r\n variant: 'primary',\r\n icon: Edit2\r\n },\r\n {\r\n label: t('tenants.actions.viewMembers'),\r\n onClick: () => navigate(buildTenantUrl(`/administration/tenants/${tenant.id}/members`)),\r\n variant: 'ghost',\r\n icon: Users\r\n }\r\n ];\r\n\r\n const buildCardStats = (tenant: TenantListDto) => (\r\n <div className=\"flex items-center gap-4\">\r\n <div className=\"flex items-center gap-1.5\">\r\n <Users className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span>{tenant.memberCount ?? 0} {t('tenants.members')}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5\">\r\n <Boxes className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span>{tenant.applicationCount ?? 0} {t('tenants.applications')}</span>\r\n </div>\r\n </div>\r\n );\r\n\r\n const mapTenantToCardProps = (tenant: TenantListDto) => {\r\n const isB2B = tenant.type === 'Business';\r\n const avatarColor = isB2B ? '#3b82f6' : '#8b5cf6';\r\n\r\n return {\r\n avatar: {\r\n letter: tenant.name.at(0)?.toUpperCase() ?? '',\r\n color: avatarColor\r\n },\r\n title: tenant.name,\r\n subtitle: tenant.slug,\r\n description: tenant.organisation?.name || undefined,\r\n stats: buildCardStats(tenant),\r\n tags: buildCardTags(tenant),\r\n actions: buildCardActions(tenant),\r\n onClick: () => navigate(buildTenantUrl(`/administration/tenants/${tenant.id}`))\r\n };\r\n };\r\n\r\n // Render cards view - using EntityCard component\r\n const renderCardsView = () => (\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6\">\r\n {loading && (\r\n <div className=\"col-span-full flex flex-col items-center justify-center py-16\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-500)]\" />\r\n <span className=\"mt-3 text-sm text-[var(--text-secondary)]\">{t('common.loading')}</span>\r\n </div>\r\n )}\r\n {!loading && paginatedTenants.length === 0 && (\r\n <div className=\"col-span-full flex flex-col items-center justify-center py-16\">\r\n <div className=\"w-16 h-16 rounded-lg bg-[var(--bg-secondary)] flex items-center justify-center mb-3\">\r\n <Building2 className=\"w-8 h-8 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <span className=\"text-[var(--text-secondary)]\">{t('tenants.noTenants')}</span>\r\n </div>\r\n )}\r\n {!loading && paginatedTenants.length > 0 && (\r\n paginatedTenants.map((tenant) => (\r\n <EntityCard key={tenant.id} {...mapTenantToCardProps(tenant)} />\r\n ))\r\n )}\r\n </div>\r\n );\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: buildTenantUrl('/administration') },\r\n ...(lockedType || excludeTypes\r\n ? [\r\n { label: t('tenants.title'), href: buildTenantUrl('/administration/tenants/list') },\r\n { label: (() => {\r\n if (excludeTypes) return t('tenants.other.title');\r\n return lockedType === 'Business' ? t('tenants.enterprise.title') : t('tenants.personal.title');\r\n })() }\r\n ]\r\n : [{ label: t('tenants.title') }]\r\n ),\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <PageHeader\r\n title={pageTitle}\r\n subtitle={pageSubtitle}\r\n icon={<PageIcon className=\"w-6 h-6 text-[var(--color-accent-500)]\" />}\r\n actions={\r\n <>\r\n {!excludeTypes && (!lockedType || lockedType === 'Personal') && (\r\n <button\r\n onClick={() => navigate(buildTenantUrl('/administration/tenants/create') + '?type=b2c')}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <User className=\"w-4 h-4\" />\r\n {t('tenants.createB2C')}\r\n </button>\r\n )}\r\n {!excludeTypes && (!lockedType || lockedType === 'Business') && (\r\n <button\r\n onClick={() => navigate(buildTenantUrl('/administration/tenants/create') + '?type=b2b')}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors\"\r\n >\r\n <Building className=\"w-4 h-4\" />\r\n {t('tenants.createB2B')}\r\n </button>\r\n )}\r\n </>\r\n }\r\n />\r\n\r\n {/* Error display - F6 */}\r\n {error && (\r\n <div className=\"mb-6 p-4 bg-[var(--error-bg)] border border-[var(--error-border)] rounded-[var(--radius-card)] flex items-center gap-3\">\r\n <AlertCircle className=\"w-5 h-5 text-[var(--error-dot)] flex-shrink-0\" />\r\n <span className=\"text-[var(--error-text)]\">{error}</span>\r\n <button\r\n onClick={loadTenants}\r\n className=\"ml-auto text-sm text-[var(--error-text)] hover:underline\"\r\n >\r\n {t('common.retry')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n {/* Toolbar */}\r\n <div className=\"card p-4 mb-6\">\r\n <div className=\"flex flex-col gap-4\">\r\n {/* Search row */}\r\n <div className=\"flex items-center gap-3 flex-wrap\">\r\n <div className=\"relative flex-1 min-w-[200px] max-w-md\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={filters.search}\r\n onChange={(e) => updateFilter('search', e.target.value)}\r\n placeholder={t('common.search')}\r\n className=\"input !pl-10 w-full\"\r\n />\r\n </div>\r\n\r\n {/* Status filter inline when lockedType or excludeTypes (only 1 filter) */}\r\n {(lockedType || excludeTypes) ? (\r\n <div className=\"relative\">\r\n <select\r\n value={filters.status}\r\n onChange={(e) => updateFilter('status', e.target.value as TenantStatus | '')}\r\n className=\"input appearance-none pr-8 min-w-[160px]\"\r\n >\r\n <option value=\"\">{t('tenants.columns.status')}: {t('common.all')}</option>\r\n <option value=\"Pending\">{t('tenants.status.pending')}</option>\r\n <option value=\"Active\">{t('tenants.status.active')}</option>\r\n <option value=\"Suspended\">{t('tenants.status.suspended')}</option>\r\n <option value=\"Archived\">{t('tenants.status.archived')}</option>\r\n </select>\r\n <ChevronDown className=\"absolute right-2.5 top-1/2 -translate-y-1/2 w-4 h-4 pointer-events-none text-[var(--text-tertiary)]\" />\r\n </div>\r\n ) : (\r\n <>\r\n <button\r\n onClick={() => setShowFilters(!showFilters)}\r\n className={`flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] transition-colors ${activeFilterCount > 0 ? 'ring-2 ring-[var(--color-accent-500)]' : ''}`}\r\n >\r\n <Filter className=\"w-4 h-4\" />\r\n {t('common.filters')}\r\n {activeFilterCount > 0 && (\r\n <span className=\"ml-1 px-1.5 py-0.5 text-xs rounded-full bg-[var(--color-accent-500)] text-white\">\r\n {activeFilterCount}\r\n </span>\r\n )}\r\n <ChevronDown className={`w-4 h-4 transition-transform ${showFilters ? 'rotate-180' : ''}`} />\r\n </button>\r\n\r\n {activeFilterCount > 0 && (\r\n <button\r\n onClick={handleResetFilters}\r\n className=\"flex items-center gap-1.5 px-4 py-2 rounded-[var(--radius-button)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <RotateCcw className=\"w-4 h-4\" />\r\n {t('common.reset')}\r\n </button>\r\n )}\r\n </>\r\n )}\r\n\r\n <div className=\"flex-1\" />\r\n\r\n <ViewToggle\r\n viewMode={viewMode}\r\n onChange={setViewMode}\r\n showTable={true}\r\n showCards={true}\r\n showKanban={false}\r\n tableLabel={t('common.table')}\r\n cardsLabel={t('common.cards')}\r\n />\r\n </div>\r\n\r\n {/* Filters panel (only for non-locked type - multiple filters) */}\r\n {!lockedType && !excludeTypes && showFilters && (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 pt-4 border-t border-[var(--border-color)]\">\r\n <div>\r\n <label className=\"block text-xs font-medium text-[var(--text-tertiary)] mb-1.5\">\r\n {t('tenants.columns.status')}\r\n </label>\r\n <div className=\"relative\">\r\n <select\r\n value={filters.status}\r\n onChange={(e) => updateFilter('status', e.target.value as TenantStatus | '')}\r\n className=\"input w-full appearance-none pr-8\"\r\n >\r\n <option value=\"\">{t('common.all')}</option>\r\n <option value=\"Pending\">{t('tenants.status.pending')}</option>\r\n <option value=\"Active\">{t('tenants.status.active')}</option>\r\n <option value=\"Suspended\">{t('tenants.status.suspended')}</option>\r\n <option value=\"Archived\">{t('tenants.status.archived')}</option>\r\n </select>\r\n <ChevronDown className=\"absolute right-2.5 top-1/2 -translate-y-1/2 w-4 h-4 pointer-events-none text-[var(--text-tertiary)]\" />\r\n </div>\r\n </div>\r\n <div>\r\n <label className=\"block text-xs font-medium text-[var(--text-tertiary)] mb-1.5\">\r\n {t('tenants.columns.type')}\r\n </label>\r\n <div className=\"relative\">\r\n <select\r\n value={filters.type}\r\n onChange={(e) => updateFilter('type', e.target.value as TenantType | '')}\r\n className=\"input w-full appearance-none pr-8\"\r\n >\r\n <option value=\"\">{t('common.all')}</option>\r\n <option value=\"Personal\">{t('tenants.type.personal')}</option>\r\n <option value=\"Business\">{t('tenants.type.business')}</option>\r\n <option value=\"System\">{t('tenants.type.system')}</option>\r\n </select>\r\n <ChevronDown className=\"absolute right-2.5 top-1/2 -translate-y-1/2 w-4 h-4 pointer-events-none text-[var(--text-tertiary)]\" />\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Stats */}\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4 mb-6\">\r\n <div className=\"card p-4 border bg-[var(--success-bg)] border-[var(--success-border)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <Building2 className=\"w-8 h-8 text-[var(--success-text)]\" />\r\n <div>\r\n <p className=\"text-2xl font-bold text-[var(--success-text)]\">{stats.active}</p>\r\n <p className=\"text-sm text-[var(--success-text)]\">{t('tenants.status.active')}</p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"card p-4 border bg-[var(--warning-bg)] border-[var(--warning-border)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <PauseCircle className=\"w-8 h-8 text-[var(--warning-text)]\" />\r\n <div>\r\n <p className=\"text-2xl font-bold text-[var(--warning-text)]\">{stats.suspended}</p>\r\n <p className=\"text-sm text-[var(--warning-text)]\">{t('tenants.status.suspended')}</p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"card p-4 border bg-[var(--bg-secondary)] border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-3\">\r\n <Users className=\"w-8 h-8 text-[var(--text-secondary)]\" />\r\n <div>\r\n <p className=\"text-2xl font-bold text-[var(--text-primary)]\">{stats.members}</p>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{t('tenants.columns.members')}</p>\r\n </div>\r\n </div>\r\n </div>\r\n <div className={`card p-4 border ${stats.pendingRequests > 0 ? 'bg-[var(--warning-bg)] border-[var(--warning-border)]' : 'bg-[var(--bg-secondary)] border-[var(--border-color)]'}`}>\r\n <div className=\"flex items-center gap-3\">\r\n <Clock className={`w-8 h-8 ${stats.pendingRequests > 0 ? 'text-[var(--warning-text)]' : 'text-[var(--text-secondary)]'}`} />\r\n <div>\r\n <p className={`text-2xl font-bold ${stats.pendingRequests > 0 ? 'text-[var(--warning-text)]' : 'text-[var(--text-primary)]'}`}>{stats.pendingRequests}</p>\r\n <p className={`text-sm ${stats.pendingRequests > 0 ? 'text-[var(--warning-text)]' : 'text-[var(--text-secondary)]'}`}>{t('tenants.columns.requests')}</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Content */}\r\n {viewMode === 'table' ? renderTableView() : renderCardsView()}\r\n\r\n {/* Pagination */}\r\n {totalPages > 1 && (\r\n <div className=\"mt-6\">\r\n <Pagination\r\n page={page}\r\n totalPages={totalPages}\r\n totalCount={totalCount}\r\n pageSize={20}\r\n onPageChange={setPage}\r\n itemLabel={t('tenants.title').toLowerCase()}\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Confirm Modal */}\r\n {(() => {\r\n const props = getConfirmModalProps();\r\n return props ? (\r\n <ConfirmModal\r\n isOpen={!!confirmAction}\r\n title={props.label}\r\n message={props.message}\r\n confirmLabel={props.label}\r\n variant={props.variant}\r\n loading={!!actionLoading}\r\n onConfirm={handleConfirmAction}\r\n onCancel={() => setConfirmAction(null)}\r\n />\r\n ) : null;\r\n })()}\r\n </div>\r\n );\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n adminApi,\r\n type TenantDetailDto,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface UseTenantDetailReturn {\r\n tenant: TenantDetailDto | null;\r\n setTenant: (tenant: TenantDetailDto | null) => void;\r\n loading: boolean;\r\n setLoading: (loading: boolean) => void;\r\n error: string | null;\r\n setError: (error: string | null) => void;\r\n loadTenant: () => Promise<void>;\r\n editingGeneralInfo: boolean;\r\n setEditingGeneralInfo: (editing: boolean) => void;\r\n editName: string;\r\n setEditName: (name: string) => void;\r\n editDescription: string;\r\n setEditDescription: (description: string) => void;\r\n savingGeneralInfo: boolean;\r\n setSavingGeneralInfo: (saving: boolean) => void;\r\n handleSaveGeneralInfo: () => Promise<void>;\r\n openEditGeneralInfo: () => void;\r\n closeEditGeneralInfo: () => void;\r\n}\r\n\r\nexport function useTenantDetail(tenantId: string | undefined): UseTenantDetailReturn {\r\n const { t } = useTranslation(['admin', 'common']);\r\n\r\n const [tenant, setTenant] = useState<TenantDetailDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const [editingGeneralInfo, setEditingGeneralInfo] = useState(false);\r\n const [editName, setEditName] = useState('');\r\n const [editDescription, setEditDescription] = useState('');\r\n const [savingGeneralInfo, setSavingGeneralInfo] = useState(false);\r\n\r\n const loadTenant = useCallback(async () => {\r\n if (!tenantId) return;\r\n try {\r\n setError(null);\r\n const data = await adminApi.tenants.getById(tenantId);\r\n setTenant(data);\r\n } catch (err) {\r\n console.error('Failed to load tenant:', err);\r\n setError(t('admin:tenants.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [tenantId, t]);\r\n\r\n const openEditGeneralInfo = useCallback(() => {\r\n if (!tenant) return;\r\n setEditName(tenant.name);\r\n setEditDescription(tenant.description || '');\r\n setEditingGeneralInfo(true);\r\n }, [tenant]);\r\n\r\n const closeEditGeneralInfo = useCallback(() => {\r\n setEditingGeneralInfo(false);\r\n setEditName('');\r\n setEditDescription('');\r\n }, []);\r\n\r\n const handleSaveGeneralInfo = useCallback(async () => {\r\n if (!tenant) return;\r\n setSavingGeneralInfo(true);\r\n try {\r\n await adminApi.tenants.update(tenant.id, {\r\n name: editName,\r\n description: editDescription || undefined,\r\n });\r\n await loadTenant();\r\n closeEditGeneralInfo();\r\n } catch (err) {\r\n console.error('Failed to update tenant:', err);\r\n } finally {\r\n setSavingGeneralInfo(false);\r\n }\r\n }, [tenant, editName, editDescription, loadTenant, closeEditGeneralInfo]);\r\n\r\n return {\r\n tenant,\r\n setTenant,\r\n loading,\r\n setLoading,\r\n error,\r\n setError,\r\n loadTenant,\r\n editingGeneralInfo,\r\n setEditingGeneralInfo,\r\n editName,\r\n setEditName,\r\n editDescription,\r\n setEditDescription,\r\n savingGeneralInfo,\r\n setSavingGeneralInfo,\r\n handleSaveGeneralInfo,\r\n openEditGeneralInfo,\r\n closeEditGeneralInfo,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport {\r\n adminApi,\r\n type TenantMemberDto,\r\n type RoleListDto,\r\n type UserListDto,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface UseTenantMembersReturn {\r\n members: TenantMemberDto[] | null;\r\n setMembers: (members: TenantMemberDto[] | null) => void;\r\n loadingMembers: boolean;\r\n setLoadingMembers: (loading: boolean) => void;\r\n addingMember: boolean;\r\n setAddingMember: (adding: boolean) => void;\r\n availableUsers: UserListDto[];\r\n setAvailableUsers: (users: UserListDto[]) => void;\r\n loadingUsers: boolean;\r\n setLoadingUsers: (loading: boolean) => void;\r\n userSearchTerm: string;\r\n setUserSearchTerm: (term: string) => void;\r\n selectedUserId: string | null;\r\n setSelectedUserId: (userId: string | null) => void;\r\n addingMemberLoading: boolean;\r\n setAddingMemberLoading: (loading: boolean) => void;\r\n selectedMemberForRoles: TenantMemberDto | null;\r\n setSelectedMemberForRoles: (member: TenantMemberDto | null) => void;\r\n availableRoles: RoleListDto[];\r\n setAvailableRoles: (roles: RoleListDto[]) => void;\r\n selectedRoleIds: string[];\r\n setSelectedRoleIds: (roleIds: string[]) => void;\r\n loadingRoles: boolean;\r\n setLoadingRoles: (loading: boolean) => void;\r\n savingRoles: boolean;\r\n setSavingRoles: (saving: boolean) => void;\r\n loadMembers: () => Promise<void>;\r\n loadAvailableUsers: () => Promise<void>;\r\n handleAddMember: () => Promise<void>;\r\n handleRemoveMember: (userId: string) => Promise<void>;\r\n openRoleModal: (member: TenantMemberDto) => Promise<void>;\r\n closeRoleModal: () => void;\r\n handleSaveRoles: () => Promise<void>;\r\n handleRoleToggle: (roleId: string) => void;\r\n}\r\n\r\nexport function useTenantMembers(tenantId: string | undefined): UseTenantMembersReturn {\r\n const [members, setMembers] = useState<TenantMemberDto[] | null>(null);\r\n const [loadingMembers, setLoadingMembers] = useState(false);\r\n\r\n const [addingMember, setAddingMember] = useState(false);\r\n const [availableUsers, setAvailableUsers] = useState<UserListDto[]>([]);\r\n const [loadingUsers, setLoadingUsers] = useState(false);\r\n const [userSearchTerm, setUserSearchTerm] = useState('');\r\n const [selectedUserId, setSelectedUserId] = useState<string | null>(null);\r\n const [addingMemberLoading, setAddingMemberLoading] = useState(false);\r\n\r\n const [selectedMemberForRoles, setSelectedMemberForRoles] = useState<TenantMemberDto | null>(null);\r\n const [availableRoles, setAvailableRoles] = useState<RoleListDto[]>([]);\r\n const [selectedRoleIds, setSelectedRoleIds] = useState<string[]>([]);\r\n const [loadingRoles, setLoadingRoles] = useState(false);\r\n const [savingRoles, setSavingRoles] = useState(false);\r\n\r\n const loadMembers = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLoadingMembers(true);\r\n try {\r\n const data = await adminApi.tenants.getMembers(tenantId);\r\n setMembers(data);\r\n } catch (err) {\r\n console.error('Failed to load members:', err);\r\n } finally {\r\n setLoadingMembers(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const loadAvailableUsers = useCallback(async () => {\r\n setLoadingUsers(true);\r\n try {\r\n const result = await adminApi.users.getAll({ pageSize: 50 });\r\n const memberUserIds = new Set((members ?? []).map(m => m.userId));\r\n setAvailableUsers(result.items.filter(u => !memberUserIds.has(u.id)));\r\n } catch (err) {\r\n console.error('Failed to load users:', err);\r\n } finally {\r\n setLoadingUsers(false);\r\n }\r\n }, [members]);\r\n\r\n const handleAddMember = useCallback(async () => {\r\n if (!tenantId || !selectedUserId) return;\r\n setAddingMemberLoading(true);\r\n try {\r\n await adminApi.tenants.addMember(tenantId, { userId: selectedUserId });\r\n await loadMembers();\r\n setAddingMember(false);\r\n setSelectedUserId(null);\r\n setUserSearchTerm('');\r\n } catch (err) {\r\n console.error('Failed to add member:', err);\r\n } finally {\r\n setAddingMemberLoading(false);\r\n }\r\n }, [tenantId, selectedUserId, loadMembers]);\r\n\r\n const handleRemoveMember = useCallback(async (userId: string) => {\r\n if (!tenantId) return;\r\n try {\r\n await adminApi.tenants.removeMember(tenantId, userId);\r\n await loadMembers();\r\n } catch (err) {\r\n console.error('Failed to remove member:', err);\r\n }\r\n }, [tenantId, loadMembers]);\r\n\r\n const loadAvailableRoles = useCallback(async () => {\r\n setLoadingRoles(true);\r\n try {\r\n const data = await adminApi.roles.getAssignable();\r\n setAvailableRoles(data);\r\n } catch (err) {\r\n console.error('Failed to load roles:', err);\r\n } finally {\r\n setLoadingRoles(false);\r\n }\r\n }, []);\r\n\r\n const openRoleModal = useCallback(async (member: TenantMemberDto) => {\r\n setSelectedMemberForRoles(member);\r\n setSelectedRoleIds(member.roles.map(r => r.roleId));\r\n if (availableRoles.length === 0) {\r\n await loadAvailableRoles();\r\n }\r\n }, [availableRoles.length, loadAvailableRoles]);\r\n\r\n const closeRoleModal = useCallback(() => {\r\n setSelectedMemberForRoles(null);\r\n setSelectedRoleIds([]);\r\n }, []);\r\n\r\n const handleRoleToggle = useCallback((roleId: string) => {\r\n setSelectedRoleIds(prev =>\r\n prev.includes(roleId)\r\n ? prev.filter(id => id !== roleId)\r\n : [...prev, roleId]\r\n );\r\n }, []);\r\n\r\n const handleSaveRoles = useCallback(async () => {\r\n if (!tenantId || !selectedMemberForRoles) return;\r\n setSavingRoles(true);\r\n try {\r\n await adminApi.tenants.assignMemberRoles(tenantId, selectedMemberForRoles.userId, selectedRoleIds);\r\n await loadMembers();\r\n closeRoleModal();\r\n } catch (err) {\r\n console.error('Failed to save roles:', err);\r\n } finally {\r\n setSavingRoles(false);\r\n }\r\n }, [tenantId, selectedMemberForRoles, selectedRoleIds, loadMembers, closeRoleModal]);\r\n\r\n return {\r\n members,\r\n setMembers,\r\n loadingMembers,\r\n setLoadingMembers,\r\n addingMember,\r\n setAddingMember,\r\n availableUsers,\r\n setAvailableUsers,\r\n loadingUsers,\r\n setLoadingUsers,\r\n userSearchTerm,\r\n setUserSearchTerm,\r\n selectedUserId,\r\n setSelectedUserId,\r\n addingMemberLoading,\r\n setAddingMemberLoading,\r\n selectedMemberForRoles,\r\n setSelectedMemberForRoles,\r\n availableRoles,\r\n setAvailableRoles,\r\n selectedRoleIds,\r\n setSelectedRoleIds,\r\n loadingRoles,\r\n setLoadingRoles,\r\n savingRoles,\r\n setSavingRoles,\r\n loadMembers,\r\n loadAvailableUsers,\r\n handleAddMember,\r\n handleRemoveMember,\r\n openRoleModal,\r\n closeRoleModal,\r\n handleSaveRoles,\r\n handleRoleToggle,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n adminApi,\r\n type TenantGroupDto,\r\n type AvailableGroupDto,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface UseTenantGroupsReturn {\r\n groups: TenantGroupDto[] | null;\r\n setGroups: (groups: TenantGroupDto[] | null) => void;\r\n loadingGroups: boolean;\r\n setLoadingGroups: (loading: boolean) => void;\r\n addingGroup: boolean;\r\n setAddingGroup: (adding: boolean) => void;\r\n availableGroupsForTenant: AvailableGroupDto[];\r\n setAvailableGroupsForTenant: (groups: AvailableGroupDto[]) => void;\r\n loadingAvailableGroups: boolean;\r\n setLoadingAvailableGroups: (loading: boolean) => void;\r\n selectedGroupIds: string[];\r\n setSelectedGroupIds: (groupIds: string[]) => void;\r\n assigningGroups: boolean;\r\n setAssigningGroups: (assigning: boolean) => void;\r\n groupSearchTerm: string;\r\n setGroupSearchTerm: (term: string) => void;\r\n removingGroupId: string | null;\r\n setRemovingGroupId: (groupId: string | null) => void;\r\n loadGroups: () => Promise<void>;\r\n loadAvailableGroups: () => Promise<void>;\r\n handleAssignGroups: () => Promise<void>;\r\n handleRemoveGroup: (groupId: string) => Promise<void>;\r\n}\r\n\r\nexport function useTenantGroups(tenantId: string | undefined): UseTenantGroupsReturn {\r\n const { t } = useTranslation('admin');\r\n\r\n const [groups, setGroups] = useState<TenantGroupDto[] | null>(null);\r\n const [loadingGroups, setLoadingGroups] = useState(false);\r\n\r\n const [addingGroup, setAddingGroup] = useState(false);\r\n const [availableGroupsForTenant, setAvailableGroupsForTenant] = useState<AvailableGroupDto[]>([]);\r\n const [loadingAvailableGroups, setLoadingAvailableGroups] = useState(false);\r\n const [selectedGroupIds, setSelectedGroupIds] = useState<string[]>([]);\r\n const [assigningGroups, setAssigningGroups] = useState(false);\r\n const [groupSearchTerm, setGroupSearchTerm] = useState('');\r\n const [removingGroupId, setRemovingGroupId] = useState<string | null>(null);\r\n\r\n const loadGroups = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLoadingGroups(true);\r\n try {\r\n const data = await adminApi.tenants.getGroups(tenantId);\r\n setGroups(Array.isArray(data) ? data : []);\r\n } catch (err) {\r\n console.error('Failed to load groups:', err);\r\n setGroups([]);\r\n } finally {\r\n setLoadingGroups(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const loadAvailableGroups = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLoadingAvailableGroups(true);\r\n try {\r\n const data = await adminApi.tenants.getAvailableGroups(tenantId);\r\n setAvailableGroupsForTenant(data);\r\n } catch (err) {\r\n console.error('Failed to load available groups:', err);\r\n setAvailableGroupsForTenant([]);\r\n } finally {\r\n setLoadingAvailableGroups(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const handleAssignGroups = useCallback(async () => {\r\n if (!tenantId || selectedGroupIds.length === 0) return;\r\n setAssigningGroups(true);\r\n const succeeded: string[] = [];\r\n const failed: string[] = [];\r\n\r\n for (const groupId of selectedGroupIds) {\r\n try {\r\n await adminApi.tenants.addGroupToTenant(tenantId, groupId);\r\n succeeded.push(groupId);\r\n } catch (err) {\r\n console.error(`Failed to add group ${groupId}:`, err);\r\n failed.push(groupId);\r\n }\r\n }\r\n\r\n await loadGroups();\r\n\r\n if (failed.length === 0) {\r\n setAddingGroup(false);\r\n setSelectedGroupIds([]);\r\n } else if (succeeded.length === 0) {\r\n // Error occurred\r\n } else {\r\n setSelectedGroupIds(failed);\r\n }\r\n\r\n setAssigningGroups(false);\r\n }, [tenantId, selectedGroupIds, loadGroups, t]);\r\n\r\n const handleRemoveGroup = useCallback(async (groupId: string) => {\r\n if (!tenantId) return;\r\n setRemovingGroupId(groupId);\r\n try {\r\n await adminApi.tenants.removeGroupFromTenant(tenantId, groupId);\r\n await loadGroups();\r\n } catch (err: unknown) {\r\n console.error('Failed to remove group:', err);\r\n } finally {\r\n setRemovingGroupId(null);\r\n }\r\n }, [tenantId, loadGroups]);\r\n\r\n return {\r\n groups,\r\n setGroups,\r\n loadingGroups,\r\n setLoadingGroups,\r\n addingGroup,\r\n setAddingGroup,\r\n availableGroupsForTenant,\r\n setAvailableGroupsForTenant,\r\n loadingAvailableGroups,\r\n setLoadingAvailableGroups,\r\n selectedGroupIds,\r\n setSelectedGroupIds,\r\n assigningGroups,\r\n setAssigningGroups,\r\n groupSearchTerm,\r\n setGroupSearchTerm,\r\n removingGroupId,\r\n setRemovingGroupId,\r\n loadGroups,\r\n loadAvailableGroups,\r\n handleAssignGroups,\r\n handleRemoveGroup,\r\n };\r\n}\r\n","import { useState, useCallback, useMemo } from 'react';\r\nimport {\r\n adminApi,\r\n type TenantApplicationDto,\r\n type AvailableApplicationDto,\r\n type ApplicationAccessLevel,\r\n type SaveOverridesRequest,\r\n} from '@/services/api/adminApi';\r\n\r\nconst updateModuleAssignment = (module: BulkModuleNode, moduleId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newIsAssigned = !module.isAssigned;\r\n return {\r\n ...module,\r\n isAssigned: newIsAssigned,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: newIsAssigned })),\r\n };\r\n};\r\n\r\nconst updateSectionAssignment = (module: BulkModuleNode, moduleId: string, sectionId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newSections = module.sections.map(s =>\r\n s.id === sectionId ? { ...s, isAssigned: !s.isAssigned } : s\r\n );\r\n const anySectionAssigned = newSections.some(s => s.isAssigned);\r\n return {\r\n ...module,\r\n isAssigned: anySectionAssigned,\r\n sections: newSections,\r\n };\r\n};\r\n\r\nconst assignAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: true,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: true })),\r\n});\r\n\r\nconst clearAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: false,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: false })),\r\n});\r\n\r\nexport type BulkAccessMode = 'full' | 'custom';\r\n\r\nexport interface BulkModuleNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n sections: BulkSectionNode[];\r\n}\r\n\r\nexport interface BulkSectionNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n}\r\n\r\nexport interface UseTenantApplicationsReturn {\r\n applications: TenantApplicationDto[] | null;\r\n setApplications: (apps: TenantApplicationDto[] | null) => void;\r\n loadingApps: boolean;\r\n setLoadingApps: (loading: boolean) => void;\r\n addingApplication: boolean;\r\n setAddingApplication: (adding: boolean) => void;\r\n availableApps: AvailableApplicationDto[];\r\n setAvailableApps: (apps: AvailableApplicationDto[]) => void;\r\n loadingAvailableApps: boolean;\r\n setLoadingAvailableApps: (loading: boolean) => void;\r\n selectedAppIds: string[];\r\n setSelectedAppIds: (appIds: string[]) => void;\r\n assigningApps: boolean;\r\n setAssigningApps: (assigning: boolean) => void;\r\n appSearchTerm: string;\r\n setAppSearchTerm: (term: string) => void;\r\n selectedAccessLevel: ApplicationAccessLevel;\r\n setSelectedAccessLevel: (level: ApplicationAccessLevel) => void;\r\n bulkAccessMode: BulkAccessMode;\r\n setBulkAccessMode: (mode: BulkAccessMode) => void;\r\n bulkModules: BulkModuleNode[];\r\n setBulkModules: (modules: BulkModuleNode[]) => void;\r\n bulkExpandedModules: Set<string>;\r\n setBulkExpandedModules: (modules: Set<string>) => void;\r\n loadingBulkModules: boolean;\r\n setLoadingBulkModules: (loading: boolean) => void;\r\n showCustomizeDrawer: boolean;\r\n setShowCustomizeDrawer: (show: boolean) => void;\r\n customizingApp: TenantApplicationDto | null;\r\n setCustomizingApp: (app: TenantApplicationDto | null) => void;\r\n loadApplications: () => Promise<void>;\r\n availableAppsError: string | null;\r\n loadAvailableApps: () => Promise<void>;\r\n handleAssignApplications: () => Promise<void>;\r\n handleRemoveApplication: (appId: string) => Promise<void>;\r\n handleUpdateAccessLevel: (appId: string, accessLevel: ApplicationAccessLevel) => Promise<void>;\r\n openCustomizeDrawer: (app: TenantApplicationDto) => void;\r\n closeCustomizeDrawer: () => void;\r\n filteredAvailableApps: AvailableApplicationDto[];\r\n handleAppToggle: (appId: string) => void;\r\n selectAllFilteredApps: () => void;\r\n clearAppSelection: () => void;\r\n loadBulkModulesForApp: (appId: string) => Promise<void>;\r\n toggleBulkModuleExpand: (moduleId: string) => void;\r\n toggleBulkModule: (moduleId: string) => void;\r\n toggleBulkSection: (moduleId: string, sectionId: string) => void;\r\n getBulkModuleCheckState: (module: BulkModuleNode) => 'checked' | 'unchecked' | 'indeterminate';\r\n getBulkStats: () => { totalModules: number; assignedModules: number; totalSections: number; assignedSections: number };\r\n selectAllBulkModules: () => void;\r\n clearBulkModules: () => void;\r\n handleSaveOverrides: (appId: string, request: SaveOverridesRequest) => Promise<void>;\r\n handleResetOverrides: (appId: string) => Promise<void>;\r\n}\r\n\r\nexport interface UseTenantApplicationsOptions {\r\n /** Called after any mutation that changes tenant application assignments (assign, remove, update, override). */\r\n onApplicationsChanged?: () => void;\r\n}\r\n\r\nexport function useTenantApplications(tenantId: string | undefined, options?: UseTenantApplicationsOptions): UseTenantApplicationsReturn {\r\n const [applications, setApplications] = useState<TenantApplicationDto[] | null>(null);\r\n const [loadingApps, setLoadingApps] = useState(false);\r\n\r\n const [addingApplication, setAddingApplication] = useState(false);\r\n const [availableApps, setAvailableApps] = useState<AvailableApplicationDto[]>([]);\r\n const [loadingAvailableApps, setLoadingAvailableApps] = useState(false);\r\n const [selectedAppIds, setSelectedAppIds] = useState<string[]>([]);\r\n const [assigningApps, setAssigningApps] = useState(false);\r\n const [appSearchTerm, setAppSearchTerm] = useState('');\r\n const [availableAppsError, setAvailableAppsError] = useState<string | null>(null);\r\n\r\n const [selectedAccessLevel, setSelectedAccessLevel] = useState<ApplicationAccessLevel>('FullAccess');\r\n const [bulkAccessMode, setBulkAccessMode] = useState<BulkAccessMode>('full');\r\n const [bulkModules, setBulkModules] = useState<BulkModuleNode[]>([]);\r\n const [bulkExpandedModules, setBulkExpandedModules] = useState<Set<string>>(new Set());\r\n const [loadingBulkModules, setLoadingBulkModules] = useState(false);\r\n\r\n const [showCustomizeDrawer, setShowCustomizeDrawer] = useState(false);\r\n const [customizingApp, setCustomizingApp] = useState<TenantApplicationDto | null>(null);\r\n\r\n const loadApplications = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLoadingApps(true);\r\n try {\r\n const data = await adminApi.tenants.getApplications(tenantId);\r\n setApplications(Array.isArray(data) ? data : []);\r\n } catch (err) {\r\n console.error('Failed to load applications:', err);\r\n setApplications([]);\r\n } finally {\r\n setLoadingApps(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const loadAvailableApps = useCallback(async () => {\r\n if (!tenantId) return;\r\n setAddingApplication(true);\r\n setSelectedAppIds([]);\r\n setLoadingAvailableApps(true);\r\n setAvailableAppsError(null);\r\n try {\r\n const availableAppsResult = await adminApi.tenants.getAvailableApplications(tenantId);\r\n setAvailableApps(availableAppsResult.filter(a => !a.isAssigned));\r\n } catch (err) {\r\n console.error('Failed to load available applications:', err);\r\n const isForbidden = err instanceof Error && err.name === 'ForbiddenError';\r\n setAvailableAppsError(isForbidden ? 'forbidden' : 'generic');\r\n } finally {\r\n setLoadingAvailableApps(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const closeAddApplication = useCallback(() => {\r\n setAddingApplication(false);\r\n setSelectedAppIds([]);\r\n setAppSearchTerm('');\r\n setSelectedAccessLevel('FullAccess');\r\n setBulkAccessMode('full');\r\n setBulkModules([]);\r\n setBulkExpandedModules(new Set());\r\n }, []);\r\n\r\n const handleAssignApplications = useCallback(async () => {\r\n if (!tenantId || selectedAppIds.length === 0) return;\r\n setAssigningApps(true);\r\n try {\r\n const request = {\r\n applicationIds: selectedAppIds,\r\n accessLevel: selectedAccessLevel,\r\n accessMode: bulkAccessMode,\r\n moduleIds: bulkAccessMode === 'custom' ? bulkModules.filter(m => m.isAssigned).map(m => m.id) : undefined,\r\n sectionIds: bulkAccessMode === 'custom' ? bulkModules.flatMap(m => m.sections.filter(s => s.isAssigned).map(s => s.id)) : undefined,\r\n };\r\n\r\n await adminApi.tenants.bulkAssignApplications(tenantId, request);\r\n\r\n await loadApplications();\r\n closeAddApplication();\r\n options?.onApplicationsChanged?.();\r\n } catch (err) {\r\n console.error('Failed to assign applications:', err);\r\n } finally {\r\n setAssigningApps(false);\r\n }\r\n }, [tenantId, selectedAppIds, selectedAccessLevel, bulkAccessMode, bulkModules, loadApplications, closeAddApplication, options]);\r\n\r\n const handleRemoveApplication = useCallback(async (appId: string) => {\r\n if (!tenantId) return;\r\n try {\r\n await adminApi.tenants.removeApplication(tenantId, appId);\r\n await loadApplications();\r\n options?.onApplicationsChanged?.();\r\n } catch (err) {\r\n console.error('Failed to remove application:', err);\r\n }\r\n }, [tenantId, loadApplications, options]);\r\n\r\n const handleUpdateAccessLevel = useCallback(async (appId: string, accessLevel: ApplicationAccessLevel) => {\r\n if (!tenantId) return;\r\n try {\r\n await adminApi.tenants.updateApplicationAccessLevel(tenantId, appId, accessLevel);\r\n await loadApplications();\r\n options?.onApplicationsChanged?.();\r\n } catch (err) {\r\n console.error('Failed to update access level:', err);\r\n }\r\n }, [tenantId, loadApplications, options]);\r\n\r\n const openCustomizeDrawer = useCallback((app: TenantApplicationDto) => {\r\n setCustomizingApp(app);\r\n setShowCustomizeDrawer(true);\r\n }, []);\r\n\r\n const closeCustomizeDrawer = useCallback(() => {\r\n setShowCustomizeDrawer(false);\r\n setCustomizingApp(null);\r\n }, []);\r\n\r\n const handleSaveOverrides = useCallback(async (appId: string, request: SaveOverridesRequest) => {\r\n if (!tenantId) return;\r\n try {\r\n await adminApi.tenants.saveOverrides(tenantId, appId, request);\r\n await loadApplications();\r\n options?.onApplicationsChanged?.();\r\n } catch (err) {\r\n console.error('Failed to save overrides:', err);\r\n throw err;\r\n }\r\n }, [tenantId, loadApplications, options]);\r\n\r\n const handleResetOverrides = useCallback(async (appId: string) => {\r\n if (!tenantId) return;\r\n try {\r\n // Reset all overrides by sending empty request\r\n await adminApi.tenants.saveOverrides(tenantId, appId, { modules: [], sections: [] });\r\n await loadApplications();\r\n options?.onApplicationsChanged?.();\r\n } catch (err) {\r\n console.error('Failed to reset overrides:', err);\r\n throw err;\r\n }\r\n }, [tenantId, loadApplications, options]);\r\n\r\n const filteredAvailableApps = useMemo(() => {\r\n if (!appSearchTerm) return availableApps;\r\n\r\n const searchLower = appSearchTerm.toLowerCase();\r\n return availableApps.filter(app =>\r\n app.label.toLowerCase().includes(searchLower) ||\r\n app.code.toLowerCase().includes(searchLower)\r\n );\r\n }, [availableApps, appSearchTerm]);\r\n\r\n const handleAppToggle = useCallback((appId: string) => {\r\n setSelectedAppIds(prev =>\r\n prev.includes(appId)\r\n ? prev.filter(id => id !== appId)\r\n : [...prev, appId]\r\n );\r\n }, []);\r\n\r\n const selectAllFilteredApps = useCallback(() => {\r\n const filteredIds = filteredAvailableApps.map(app => app.id);\r\n setSelectedAppIds(filteredIds);\r\n }, [filteredAvailableApps]);\r\n\r\n const clearAppSelection = useCallback(() => {\r\n setSelectedAppIds([]);\r\n }, []);\r\n\r\n const loadBulkModulesForApp = useCallback(async (appId: string) => {\r\n setLoadingBulkModules(true);\r\n try {\r\n const appModules = await adminApi.applications.getModules(appId);\r\n const moduleNodes: BulkModuleNode[] = [];\r\n\r\n for (const appModule of appModules) {\r\n const sections = await adminApi.applications.getModuleSections(appId, appModule.id);\r\n const sectionNodes: BulkSectionNode[] = sections.map(section => ({\r\n id: section.id,\r\n label: section.label,\r\n code: section.code,\r\n icon: section.icon,\r\n isAssigned: true,\r\n }));\r\n\r\n moduleNodes.push({\r\n id: appModule.id,\r\n label: appModule.label,\r\n code: appModule.code,\r\n icon: appModule.icon,\r\n isAssigned: true,\r\n sections: sectionNodes,\r\n });\r\n }\r\n\r\n setBulkModules(moduleNodes);\r\n } catch (err) {\r\n console.error('Failed to load modules:', err);\r\n } finally {\r\n setLoadingBulkModules(false);\r\n }\r\n }, []);\r\n\r\n const toggleBulkModuleExpand = useCallback((moduleId: string) => {\r\n setBulkExpandedModules(prev => {\r\n const newSet = new Set(prev);\r\n if (newSet.has(moduleId)) {\r\n newSet.delete(moduleId);\r\n } else {\r\n newSet.add(moduleId);\r\n }\r\n return newSet;\r\n });\r\n }, []);\r\n\r\n const toggleBulkModule = useCallback((moduleId: string) => {\r\n setBulkModules(prev => prev.map(m => updateModuleAssignment(m, moduleId)));\r\n }, []);\r\n\r\n const toggleBulkSection = useCallback((moduleId: string, sectionId: string) => {\r\n setBulkModules(prev => prev.map(m => updateSectionAssignment(m, moduleId, sectionId)));\r\n }, []);\r\n\r\n const getBulkModuleCheckState = useCallback((module: BulkModuleNode): 'checked' | 'unchecked' | 'indeterminate' => {\r\n if (module.sections.length === 0) {\r\n return module.isAssigned ? 'checked' : 'unchecked';\r\n }\r\n const assignedCount = module.sections.filter(s => s.isAssigned).length;\r\n if (assignedCount === 0) return 'unchecked';\r\n if (assignedCount === module.sections.length) return 'checked';\r\n return 'indeterminate';\r\n }, []);\r\n\r\n const getBulkStats = useCallback(() => {\r\n const totalModules = bulkModules.length;\r\n const assignedModules = bulkModules.filter(m => m.isAssigned || m.sections.some(s => s.isAssigned)).length;\r\n const totalSections = bulkModules.reduce((sum, m) => sum + m.sections.length, 0);\r\n const assignedSections = bulkModules.reduce((sum, m) => sum + m.sections.filter(s => s.isAssigned).length, 0);\r\n return { totalModules, assignedModules, totalSections, assignedSections };\r\n }, [bulkModules]);\r\n\r\n const selectAllBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => assignAllSections(m)));\r\n }, []);\r\n\r\n const clearBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => clearAllSections(m)));\r\n }, []);\r\n\r\n return {\r\n applications,\r\n setApplications,\r\n loadingApps,\r\n setLoadingApps,\r\n addingApplication,\r\n setAddingApplication,\r\n availableApps,\r\n setAvailableApps,\r\n loadingAvailableApps,\r\n setLoadingAvailableApps,\r\n selectedAppIds,\r\n setSelectedAppIds,\r\n assigningApps,\r\n setAssigningApps,\r\n appSearchTerm,\r\n setAppSearchTerm,\r\n selectedAccessLevel,\r\n setSelectedAccessLevel,\r\n bulkAccessMode,\r\n setBulkAccessMode,\r\n bulkModules,\r\n setBulkModules,\r\n bulkExpandedModules,\r\n setBulkExpandedModules,\r\n loadingBulkModules,\r\n setLoadingBulkModules,\r\n showCustomizeDrawer,\r\n setShowCustomizeDrawer,\r\n customizingApp,\r\n setCustomizingApp,\r\n loadApplications,\r\n availableAppsError,\r\n loadAvailableApps,\r\n handleAssignApplications,\r\n handleRemoveApplication,\r\n handleUpdateAccessLevel,\r\n openCustomizeDrawer,\r\n closeCustomizeDrawer,\r\n filteredAvailableApps,\r\n handleAppToggle,\r\n selectAllFilteredApps,\r\n clearAppSelection,\r\n loadBulkModulesForApp,\r\n toggleBulkModuleExpand,\r\n toggleBulkModule,\r\n toggleBulkSection,\r\n getBulkModuleCheckState,\r\n getBulkStats,\r\n selectAllBulkModules,\r\n clearBulkModules,\r\n handleSaveOverrides,\r\n handleResetOverrides,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n adminApi,\r\n type OrganisationListItemDto,\r\n type CreateOrganisationRequest,\r\n type BusinessIdentifierType,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface UseTenantOrganisationReturn {\r\n showLinkOrgModal: boolean;\r\n setShowLinkOrgModal: (show: boolean) => void;\r\n availableOrgs: OrganisationListItemDto[];\r\n setAvailableOrgs: (orgs: OrganisationListItemDto[]) => void;\r\n loadingOrgs: boolean;\r\n setLoadingOrgs: (loading: boolean) => void;\r\n selectedOrgId: string | null;\r\n setSelectedOrgId: (orgId: string | null) => void;\r\n linkingOrg: boolean;\r\n setLinkingOrg: (linking: boolean) => void;\r\n orgSearchTerm: string;\r\n setOrgSearchTerm: (term: string) => void;\r\n showCreateOrgForm: boolean;\r\n setShowCreateOrgForm: (show: boolean) => void;\r\n creatingOrg: boolean;\r\n setCreatingOrg: (creating: boolean) => void;\r\n newOrgForm: CreateOrganisationRequest;\r\n setNewOrgForm: (form: CreateOrganisationRequest) => void;\r\n lookupLoading: boolean;\r\n setLookupLoading: (loading: boolean) => void;\r\n lookupError: string | null;\r\n setLookupError: (error: string | null) => void;\r\n lookupSuccess: boolean;\r\n setLookupSuccess: (success: boolean) => void;\r\n loadAvailableOrgs: (search?: string) => Promise<void>;\r\n handleLinkOrganisation: () => Promise<void>;\r\n handleUnlinkOrganisation: () => Promise<void>;\r\n handleCreateAndLinkOrganisation: () => Promise<void>;\r\n formatCheNumber: (value: string) => string;\r\n handleBusinessIdChange: (value: string) => void;\r\n handleZefixLookup: () => Promise<void>;\r\n openLinkOrgModal: () => void;\r\n closeLinkOrgModal: () => void;\r\n handleCountryChange: (countryCode: string) => void;\r\n}\r\n\r\nconst COUNTRY_IDENTIFIER_TYPES: Record<string, { types: BusinessIdentifierType[], defaultType: BusinessIdentifierType, country: string }> = {\r\n FR: { types: ['SIREN', 'SIRET'] as BusinessIdentifierType[], defaultType: 'SIREN' as BusinessIdentifierType, country: 'France' },\r\n CH: { types: ['UID_CHE'] as BusinessIdentifierType[], defaultType: 'UID_CHE' as BusinessIdentifierType, country: 'Switzerland' },\r\n DE: { types: ['HRB', 'HRA'] as BusinessIdentifierType[], defaultType: 'HRB' as BusinessIdentifierType, country: 'Germany' },\r\n BE: { types: ['BCE_KBO'] as BusinessIdentifierType[], defaultType: 'BCE_KBO' as BusinessIdentifierType, country: 'Belgium' },\r\n NL: { types: ['KVK'] as BusinessIdentifierType[], defaultType: 'KVK' as BusinessIdentifierType, country: 'Netherlands' },\r\n ES: { types: ['CIF'] as BusinessIdentifierType[], defaultType: 'CIF' as BusinessIdentifierType, country: 'Spain' },\r\n IT: { types: ['PartitaIVA'] as BusinessIdentifierType[], defaultType: 'PartitaIVA' as BusinessIdentifierType, country: 'Italy' },\r\n GB: { types: ['CRN'] as BusinessIdentifierType[], defaultType: 'CRN' as BusinessIdentifierType, country: 'United Kingdom' },\r\n};\r\n\r\nconst DEFAULT_ORG_FORM: CreateOrganisationRequest = {\r\n name: '',\r\n countryCode: 'CH',\r\n businessIdentifierType: 'UID_CHE' as BusinessIdentifierType,\r\n businessIdentifier: 'CHE-',\r\n address: {\r\n street: '',\r\n postalCode: '',\r\n city: '',\r\n state: undefined,\r\n country: 'Switzerland',\r\n countryCode: 'CH',\r\n },\r\n};\r\n\r\nexport function useTenantOrganisation(tenantId: string | undefined): UseTenantOrganisationReturn {\r\n const { t } = useTranslation('admin');\r\n\r\n const [showLinkOrgModal, setShowLinkOrgModal] = useState(false);\r\n const [availableOrgs, setAvailableOrgs] = useState<OrganisationListItemDto[]>([]);\r\n const [loadingOrgs, setLoadingOrgs] = useState(false);\r\n const [selectedOrgId, setSelectedOrgId] = useState<string | null>(null);\r\n const [linkingOrg, setLinkingOrg] = useState(false);\r\n const [orgSearchTerm, setOrgSearchTerm] = useState('');\r\n\r\n const [showCreateOrgForm, setShowCreateOrgForm] = useState(false);\r\n const [creatingOrg, setCreatingOrg] = useState(false);\r\n const [newOrgForm, setNewOrgForm] = useState<CreateOrganisationRequest>(DEFAULT_ORG_FORM);\r\n\r\n const [lookupLoading, setLookupLoading] = useState(false);\r\n const [lookupError, setLookupError] = useState<string | null>(null);\r\n const [lookupSuccess, setLookupSuccess] = useState(false);\r\n\r\n const loadAvailableOrgs = useCallback(async (search?: string) => {\r\n setLoadingOrgs(true);\r\n try {\r\n const response = await adminApi.organisations.getAvailable(search);\r\n const data = Array.isArray(response) ? response : (response as { items?: OrganisationListItemDto[] }).items ?? [];\r\n setAvailableOrgs(data);\r\n } catch (err) {\r\n console.error('Failed to load available organisations:', err);\r\n setAvailableOrgs([]);\r\n } finally {\r\n setLoadingOrgs(false);\r\n }\r\n }, []);\r\n\r\n const openLinkOrgModal = useCallback(() => {\r\n setShowLinkOrgModal(true);\r\n setSelectedOrgId(null);\r\n setOrgSearchTerm('');\r\n loadAvailableOrgs();\r\n }, [loadAvailableOrgs]);\r\n\r\n const closeLinkOrgModal = useCallback(() => {\r\n setShowLinkOrgModal(false);\r\n setSelectedOrgId(null);\r\n setOrgSearchTerm('');\r\n setShowCreateOrgForm(false);\r\n setNewOrgForm(DEFAULT_ORG_FORM);\r\n setLookupLoading(false);\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n }, []);\r\n\r\n const handleLinkOrganisation = useCallback(async () => {\r\n if (!tenantId || !selectedOrgId) return;\r\n setLinkingOrg(true);\r\n try {\r\n await adminApi.tenants.linkOrganisation(tenantId, selectedOrgId);\r\n // Note: Caller should refresh tenant data\r\n closeLinkOrgModal();\r\n } catch (err) {\r\n console.error('Failed to link organisation:', err);\r\n } finally {\r\n setLinkingOrg(false);\r\n }\r\n }, [tenantId, selectedOrgId, closeLinkOrgModal]);\r\n\r\n const handleUnlinkOrganisation = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLinkingOrg(true);\r\n try {\r\n await adminApi.tenants.unlinkOrganisation(tenantId);\r\n // Note: Caller should refresh tenant data\r\n } catch (err) {\r\n console.error('Failed to unlink organisation:', err);\r\n } finally {\r\n setLinkingOrg(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const handleCreateAndLinkOrganisation = useCallback(async () => {\r\n if (!tenantId) return;\r\n if (!newOrgForm.name || !newOrgForm.businessIdentifier || !newOrgForm.address.street || !newOrgForm.address.city || !newOrgForm.address.postalCode) {\r\n return;\r\n }\r\n setCreatingOrg(true);\r\n try {\r\n const createdOrg = await adminApi.organisations.create(newOrgForm);\r\n await adminApi.tenants.linkOrganisation(tenantId, createdOrg.id);\r\n // Note: Caller should refresh tenant data\r\n closeLinkOrgModal();\r\n } catch (err) {\r\n console.error('Failed to create and link organisation:', err);\r\n } finally {\r\n setCreatingOrg(false);\r\n }\r\n }, [tenantId, newOrgForm, closeLinkOrgModal]);\r\n\r\n const formatCheNumber = useCallback((value: string): string => {\r\n const cleaned = value.toUpperCase().replace(/[^A-Z0-9]/g, '');\r\n let digits = cleaned.startsWith('CHE') ? cleaned.slice(3) : cleaned.replace(/[^0-9]/g, '');\r\n digits = digits.slice(0, 9);\r\n\r\n if (digits.length === 0) return 'CHE-';\r\n if (digits.length <= 3) return `CHE-${digits}`;\r\n if (digits.length <= 6) return `CHE-${digits.slice(0, 3)}.${digits.slice(3)}`;\r\n return `CHE-${digits.slice(0, 3)}.${digits.slice(3, 6)}.${digits.slice(6)}`;\r\n }, []);\r\n\r\n const handleBusinessIdChange = useCallback((value: string) => {\r\n if (newOrgForm.countryCode === 'CH') {\r\n setNewOrgForm(prev => ({ ...prev, businessIdentifier: formatCheNumber(value) }));\r\n } else {\r\n setNewOrgForm(prev => ({ ...prev, businessIdentifier: value }));\r\n }\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n }, [newOrgForm.countryCode, formatCheNumber]);\r\n\r\n const handleZefixLookup = useCallback(async () => {\r\n const cleanedId = newOrgForm.businessIdentifier.replace(/[^0-9]/g, '');\r\n if (!newOrgForm.businessIdentifier || cleanedId.length < 9 || newOrgForm.countryCode !== 'CH') {\r\n setLookupError(t('tenants.organisation.lookupIncomplete'));\r\n return;\r\n }\r\n\r\n setLookupLoading(true);\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n\r\n try {\r\n const result = await adminApi.organisations.lookup(\r\n newOrgForm.countryCode,\r\n newOrgForm.businessIdentifier\r\n );\r\n\r\n setNewOrgForm(prev => ({\r\n ...prev,\r\n name: result.name || prev.name,\r\n legalName: result.legalName || prev.legalName,\r\n vatNumber: result.vatNumber || prev.vatNumber,\r\n address: {\r\n ...prev.address,\r\n street: result.street || prev.address.street,\r\n street2: result.street2 || prev.address.street2 || undefined,\r\n postalCode: result.postalCode || prev.address.postalCode,\r\n city: result.city || prev.address.city,\r\n state: result.state || prev.address.state,\r\n country: result.country || prev.address.country,\r\n countryCode: result.countryCode || prev.address.countryCode,\r\n },\r\n }));\r\n\r\n setLookupSuccess(true);\r\n setTimeout(() => setLookupSuccess(false), 3000);\r\n } catch (err: unknown) {\r\n console.error('[Zefix Lookup] Failed:', err);\r\n const errorMessage = err instanceof Error ? err.message : '';\r\n if (errorMessage.includes('503') || errorMessage.includes('not configured') || errorMessage.includes('Service Unavailable')) {\r\n setLookupError(t('tenants.organisation.lookupServiceUnavailable'));\r\n } else if (errorMessage.includes('credentials') || errorMessage.includes('401')) {\r\n setLookupError(t('tenants.organisation.lookupAuthError'));\r\n } else if (errorMessage.includes('404') || errorMessage.includes('not found')) {\r\n setLookupError(t('tenants.organisation.lookupFailed'));\r\n } else {\r\n setLookupError(t('tenants.organisation.lookupFailed'));\r\n }\r\n } finally {\r\n setLookupLoading(false);\r\n }\r\n }, [newOrgForm.businessIdentifier, newOrgForm.countryCode, t]);\r\n\r\n const handleCountryChange = useCallback((countryCode: string) => {\r\n const config = COUNTRY_IDENTIFIER_TYPES[countryCode];\r\n if (config) {\r\n setNewOrgForm(prev => ({\r\n ...prev,\r\n countryCode,\r\n businessIdentifierType: config.defaultType,\r\n businessIdentifier: countryCode === 'CH' ? 'CHE-' : '',\r\n address: {\r\n ...prev.address,\r\n countryCode,\r\n country: config.country,\r\n },\r\n }));\r\n }\r\n }, []);\r\n\r\n return {\r\n showLinkOrgModal,\r\n setShowLinkOrgModal,\r\n availableOrgs,\r\n setAvailableOrgs,\r\n loadingOrgs,\r\n setLoadingOrgs,\r\n selectedOrgId,\r\n setSelectedOrgId,\r\n linkingOrg,\r\n setLinkingOrg,\r\n orgSearchTerm,\r\n setOrgSearchTerm,\r\n showCreateOrgForm,\r\n setShowCreateOrgForm,\r\n creatingOrg,\r\n setCreatingOrg,\r\n newOrgForm,\r\n setNewOrgForm,\r\n lookupLoading,\r\n setLookupLoading,\r\n lookupError,\r\n setLookupError,\r\n lookupSuccess,\r\n setLookupSuccess,\r\n loadAvailableOrgs,\r\n handleLinkOrganisation,\r\n handleUnlinkOrganisation,\r\n handleCreateAndLinkOrganisation,\r\n formatCheNumber,\r\n handleBusinessIdChange,\r\n handleZefixLookup,\r\n openLinkOrgModal,\r\n closeLinkOrgModal,\r\n handleCountryChange,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { adminApi, type TenantRoleDto } from '@/services/api/adminApi';\r\n\r\nexport interface UseTenantRolesReturn {\r\n roles: TenantRoleDto[] | null;\r\n loadingRoles: boolean;\r\n error: string | null;\r\n loadRoles: () => Promise<void>;\r\n}\r\n\r\nexport function useTenantRoles(tenantId: string | undefined): UseTenantRolesReturn {\r\n const [roles, setRoles] = useState<TenantRoleDto[] | null>(null);\r\n const [loadingRoles, setLoadingRoles] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const loadRoles = useCallback(async () => {\r\n if (!tenantId) return;\r\n setLoadingRoles(true);\r\n setError(null);\r\n try {\r\n const data = await adminApi.tenants.getTenantRoles(tenantId);\r\n setRoles(data);\r\n } catch (err) {\r\n console.error('Failed to load tenant roles:', err);\r\n setError('Failed to load roles');\r\n } finally {\r\n setLoadingRoles(false);\r\n }\r\n }, [tenantId]);\r\n\r\n return { roles, loadingRoles, error, loadRoles };\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\n\r\ntype TFunction = ReturnType<typeof useTranslation>['t'];\r\nimport {\r\n Info,\r\n Edit3,\r\n Building2,\r\n Plus,\r\n X,\r\n Settings,\r\n RefreshCw,\r\n PlayCircle,\r\n PauseCircle,\r\n Archive,\r\n Loader2,\r\n Layers,\r\n ArrowRight,\r\n Star,\r\n ExternalLink,\r\n Headphones,\r\n CheckCircle2,\r\n AlertCircle,\r\n} from 'lucide-react';\r\nimport type { TenantDetailDto, TenantStatus, TenantTemplateDto, TenantType } from '@/services/api/adminApi';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { ticketingApi, type TenantTicketingConfigurationDto } from '@/services/api/ticketingApi';\r\n\r\ninterface TenantOverviewTabProps {\r\n readonly tenant: TenantDetailDto;\r\n readonly tenantOwner: { userDisplayName?: string; userEmail?: string } | null;\r\n readonly statusConfig: Record<TenantStatus, { color: string; bgColor: string; borderColor: string }>;\r\n readonly actionLoading: string | null;\r\n readonly onRefresh: () => Promise<void>;\r\n readonly onEditClick: () => void;\r\n readonly onStatusChange: (action: 'activate' | 'suspend' | 'archive') => void;\r\n readonly onMembersTabClick: () => void;\r\n readonly onLinkOrgClick: () => void;\r\n readonly onUnlinkOrg: () => Promise<void>;\r\n}\r\n\r\ninterface EditState {\r\n readonly name: string;\r\n readonly description: string;\r\n readonly type: TenantType;\r\n}\r\n\r\ninterface TemplateModalProps {\r\n readonly show: boolean;\r\n readonly templates: TenantTemplateDto[];\r\n readonly selectedTemplateId: string;\r\n readonly loadingTemplates: boolean;\r\n readonly assigningTemplate: boolean;\r\n readonly onTemplateSelect: (id: string) => void;\r\n readonly onClose: () => void;\r\n readonly onAssign: () => Promise<void>;\r\n readonly tenantTemplateId?: string;\r\n readonly t: TFunction;\r\n}\r\n\r\nfunction TemplateSelectionModal({\r\n show, templates, selectedTemplateId, loadingTemplates, assigningTemplate,\r\n onTemplateSelect, onClose, onAssign, tenantTemplateId, t\r\n}: TemplateModalProps) {\r\n if (!show) return null;\r\n\r\n return (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"card w-full max-w-md p-6 m-4\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <div>\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('tenants.template.selectTitle')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.template.selectSubtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={onClose}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n {loadingTemplates && (\r\n <div className=\"flex justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n )}\r\n {!loadingTemplates && templates.length === 0 && (\r\n <div className=\"p-4 rounded-lg bg-[var(--bg-secondary)] text-center\">\r\n <p className=\"text-sm text-[var(--text-tertiary)]\">{t('tenants.template.noTemplatesAvailable')}</p>\r\n </div>\r\n )}\r\n {!loadingTemplates && templates.length > 0 && (\r\n <div className=\"space-y-2 max-h-[300px] overflow-y-auto mb-6\">\r\n {templates.map(tmpl => (\r\n <button\r\n key={tmpl.id}\r\n onClick={() => onTemplateSelect(tmpl.id)}\r\n className={`w-full p-3 rounded-lg border text-left transition-colors ${\r\n selectedTemplateId === tmpl.id\r\n ? 'border-[var(--primary-color)] bg-[var(--primary-color)]/5'\r\n : 'border-[var(--border-color)] bg-[var(--bg-secondary)] hover:border-[var(--primary-color)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">{tmpl.name}</p>\r\n <p className=\"text-xs text-[var(--text-tertiary)] font-mono\">{tmpl.code}</p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className={`px-2 py-0.5 text-xs rounded-[var(--radius-badge)] ${\r\n tmpl.targetTenantType === 'Business'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--accent-bg)] text-[var(--accent-text)]'\r\n }`}>\r\n {t(`tenants.type.${tmpl.targetTenantType.toLowerCase()}`)}\r\n </span>\r\n {tmpl.isDefault && (\r\n <span className=\"px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--success-bg)] text-[var(--success-text)]\">\r\n {t('tenants.template.default')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n {tmpl.description && (\r\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">{tmpl.description}</p>\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex justify-end gap-3\">\r\n <button\r\n onClick={onClose}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={onAssign}\r\n disabled={assigningTemplate || !selectedTemplateId || selectedTemplateId === tenantTemplateId}\r\n className=\"btn btn-primary\"\r\n >\r\n {assigningTemplate ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n t('tenants.template.confirm')\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction TenantGeneralInfoSection({\r\n tenant,\r\n statusConfig,\r\n onEditClick,\r\n t,\r\n}: {\r\n tenant: TenantDetailDto;\r\n statusConfig: Record<TenantStatus, { color: string; bgColor: string; borderColor: string }>;\r\n onEditClick: () => void;\r\n t: TFunction;\r\n}) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Info className=\"w-5 h-5\" />\r\n {t('tenants.detail.generalInfo')}\r\n </h3>\r\n <button\r\n onClick={onEditClick}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Edit3 className=\"w-4 h-4\" />\r\n {t('common:edit')}\r\n </button>\r\n </div>\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.name')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">{tenant.name}</p>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.slug')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-mono\">{tenant.slug}</p>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.type')}</p>\r\n <span className={`inline-flex px-2 py-0.5 text-xs rounded-[var(--radius-badge)] ${\r\n tenant.type === 'Business'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--accent-bg)] text-[var(--accent-text)]'\r\n }`}>\r\n {t(`tenants.type.${tenant.type.toLowerCase()}`)}\r\n </span>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.status')}</p>\r\n <span className={`inline-flex px-2 py-0.5 text-xs rounded-[var(--radius-badge)] ${statusConfig[tenant.status].bgColor} ${statusConfig[tenant.status].color}`}>\r\n {t(`tenants.status.${tenant.status.toLowerCase()}`)}\r\n </span>\r\n </div>\r\n {tenant.description && (\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)] sm:col-span-2 lg:col-span-4\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.description')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] whitespace-pre-wrap\">{tenant.description}</p>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction TenantTicketingSection({\r\n tenant,\r\n ticketingConfig,\r\n loadingTicketing,\r\n t,\r\n navigate,\r\n}: {\r\n tenant: TenantDetailDto;\r\n ticketingConfig: TenantTicketingConfigurationDto | null;\r\n loadingTicketing: boolean;\r\n t: TFunction;\r\n navigate: ReturnType<typeof useNavigate>;\r\n}) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Headphones className=\"w-5 h-5\" />\r\n {t('tenants.detail.supportManagement.title')}\r\n </h3>\r\n <button\r\n onClick={() => navigate(`/administration/tenants/${tenant.id}/settings?tab=support`)}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Settings className=\"w-4 h-4\" />\r\n {t('tenants.detail.supportManagement.configure')}\r\n </button>\r\n </div>\r\n {loadingTicketing && (\r\n <div className=\"flex justify-center py-4\">\r\n <Loader2 className=\"w-5 h-5 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n )}\r\n {!loadingTicketing && ticketingConfig && (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">\r\n {t('tenants.detail.supportManagement.provider')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">\r\n {ticketingConfig.provider === 'Glpi'\r\n ? t('tenants.detail.supportManagement.providerGlpi')\r\n : t('tenants.detail.supportManagement.providerSmartStack')}\r\n </p>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">\r\n {t('tenants.detail.supportManagement.status')}\r\n </p>\r\n <span className={`inline-flex items-center gap-1.5 px-2 py-0.5 text-xs rounded-[var(--radius-badge)] ${\r\n ticketingConfig.isConfigured\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n }`}>\r\n {ticketingConfig.isConfigured\r\n ? <><CheckCircle2 className=\"w-3 h-3\" />{t('tenants.detail.supportManagement.configured')}</>\r\n : <><AlertCircle className=\"w-3 h-3\" />{t('tenants.detail.supportManagement.notConfigured')}</>}\r\n </span>\r\n </div>\r\n {ticketingConfig.provider === 'Glpi' && ticketingConfig.glpiBaseUrl && (\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">\r\n {t('tenants.detail.supportManagement.glpiUrl')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-mono truncate\" title={ticketingConfig.glpiBaseUrl}>\r\n {ticketingConfig.glpiBaseUrl}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n {!loadingTicketing && !ticketingConfig && (\r\n <div className=\"p-4 rounded-lg bg-[var(--info-bg)] border border-[var(--info-border)] text-center\">\r\n <Headphones className=\"w-5 h-5 text-[var(--info-text)] mx-auto mb-2\" />\r\n <p className=\"text-sm text-[var(--info-text)]\">\r\n {t('tenants.detail.supportManagement.noConfiguration')}\r\n </p>\r\n <p className=\"text-xs text-[var(--info-text)] mt-1 opacity-75\">\r\n {t('tenants.detail.supportManagement.noConfigurationHint')}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction TenantTemplateSection({\r\n tenant,\r\n templates,\r\n onOpenTemplateModal,\r\n onRemoveTemplate,\r\n removingTemplate,\r\n navigate,\r\n t,\r\n}: {\r\n tenant: TenantDetailDto;\r\n templates: TenantTemplateDto[];\r\n onOpenTemplateModal: () => void;\r\n onRemoveTemplate: () => Promise<void>;\r\n removingTemplate: boolean;\r\n navigate: ReturnType<typeof useNavigate>;\r\n t: TFunction;\r\n}) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <div className=\"flex items-center gap-3\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Layers className=\"w-5 h-5\" />\r\n {t('tenants.templateTenant.title')}\r\n </h3>\r\n <button\r\n onClick={() => navigate('/administration/tenants/template')}\r\n className=\"flex items-center gap-1 text-xs text-[var(--text-tertiary)] hover:text-[var(--primary-color)] transition-colors\"\r\n title={t('tenants.templateTenant.viewAll')}\r\n >\r\n <ExternalLink className=\"w-3 h-3\" />\r\n {t('tenants.templateTenant.viewAll')}\r\n </button>\r\n </div>\r\n {tenant.templateId ? (\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={onOpenTemplateModal}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Edit3 className=\"w-4 h-4\" />\r\n {t('tenants.template.change')}\r\n </button>\r\n <button\r\n onClick={onRemoveTemplate}\r\n disabled={removingTemplate}\r\n className=\"btn btn-secondary text-[var(--error-text)] hover:bg-[var(--error-bg)]\"\r\n >\r\n {removingTemplate ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <X className=\"w-4 h-4\" />}\r\n {t('tenants.template.remove')}\r\n </button>\r\n </div>\r\n ) : (\r\n <button\r\n onClick={onOpenTemplateModal}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.template.assign')}\r\n </button>\r\n )}\r\n </div>\r\n {tenant.templateId ? (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.template.name')}</p>\r\n <div className=\"flex items-center gap-2\">\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">{tenant.templateName || '-'}</p>\r\n {templates.find(tmpl => tmpl.id === tenant.templateId)?.isDefault && (\r\n <span className=\"flex items-center gap-1 px-1.5 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--accent-bg)] text-[var(--accent-text)]\">\r\n <Star className=\"w-3 h-3\" />\r\n {t('tenants.template.default')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.template.code')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-mono\">{tenant.templateCode || '-'}</p>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)] flex items-center\">\r\n <button\r\n onClick={() => navigate(`/administration/tenants/template/${tenant.templateId}`)}\r\n className=\"flex items-center gap-2 text-sm text-[var(--primary-color)] hover:underline\"\r\n >\r\n {t('tenants.template.viewDetails')}\r\n <ArrowRight className=\"w-3.5 h-3.5\" />\r\n </button>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"p-4 rounded-lg bg-[var(--warning-bg)] border border-[var(--warning-border)] text-center\">\r\n <Layers className=\"w-5 h-5 text-[var(--warning-text)] mx-auto mb-2\" />\r\n <p className=\"text-sm text-[var(--warning-text)]\">\r\n {t('tenants.templateTenant.noLink')}\r\n </p>\r\n <p className=\"text-xs text-[var(--warning-text)] mt-1 opacity-75\">\r\n {t('tenants.templateTenant.noLinkHint')}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport function TenantOverviewTab({\r\n tenant,\r\n tenantOwner,\r\n statusConfig,\r\n actionLoading,\r\n onRefresh,\r\n onEditClick,\r\n onStatusChange,\r\n onMembersTabClick,\r\n onLinkOrgClick,\r\n onUnlinkOrg,\r\n}: TenantOverviewTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n const [editingGeneralInfo, setEditingGeneralInfo] = useState(false);\r\n const [editState, setEditState] = useState<EditState>({ name: '', description: '', type: 'Business' });\r\n const [savingGeneralInfo, setSavingGeneralInfo] = useState(false);\r\n const [linkingOrg, setLinkingOrg] = useState(false);\r\n\r\n // Template management state\r\n const [showTemplateModal, setShowTemplateModal] = useState(false);\r\n const [templates, setTemplates] = useState<TenantTemplateDto[]>([]);\r\n const [loadingTemplates, setLoadingTemplates] = useState(false);\r\n const [selectedTemplateId, setSelectedTemplateId] = useState<string>('');\r\n const [assigningTemplate, setAssigningTemplate] = useState(false);\r\n const [removingTemplate, setRemovingTemplate] = useState(false);\r\n\r\n // Support management state\r\n const [ticketingConfig, setTicketingConfig] = useState<TenantTicketingConfigurationDto | null>(null);\r\n const [loadingTicketing, setLoadingTicketing] = useState(false);\r\n\r\n const loadTicketingConfig = useCallback(async () => {\r\n setLoadingTicketing(true);\r\n try {\r\n const config = await ticketingApi.getConfiguration(tenant.id);\r\n setTicketingConfig(config);\r\n } catch {\r\n setTicketingConfig(null);\r\n } finally {\r\n setLoadingTicketing(false);\r\n }\r\n }, [tenant.id]);\r\n\r\n useEffect(() => {\r\n loadTicketingConfig();\r\n }, [loadTicketingConfig]);\r\n\r\n const loadTemplates = useCallback(async () => {\r\n setLoadingTemplates(true);\r\n try {\r\n const data = await adminApi.templates.getAll();\r\n setTemplates(data.filter(t => t.isActive));\r\n } catch (err) {\r\n console.error('Failed to load templates:', err);\r\n } finally {\r\n setLoadingTemplates(false);\r\n }\r\n }, []);\r\n\r\n // Eagerly load templates to show default badge\r\n useEffect(() => {\r\n if (tenant.templateId && templates.length === 0) {\r\n loadTemplates();\r\n }\r\n }, [tenant.templateId, templates.length, loadTemplates]);\r\n\r\n const handleOpenTemplateModal = async () => {\r\n setSelectedTemplateId(tenant.templateId || '');\r\n setShowTemplateModal(true);\r\n await loadTemplates();\r\n };\r\n\r\n const handleAssignTemplate = async () => {\r\n if (!selectedTemplateId) return;\r\n setAssigningTemplate(true);\r\n try {\r\n await adminApi.tenants.assignTemplate(tenant.id, selectedTemplateId);\r\n await onRefresh();\r\n setShowTemplateModal(false);\r\n } catch (err) {\r\n console.error('Failed to assign template:', err);\r\n } finally {\r\n setAssigningTemplate(false);\r\n }\r\n };\r\n\r\n const handleRemoveTemplate = async () => {\r\n setRemovingTemplate(true);\r\n try {\r\n await adminApi.tenants.removeTemplate(tenant.id);\r\n await onRefresh();\r\n } catch (err) {\r\n console.error('Failed to remove template:', err);\r\n } finally {\r\n setRemovingTemplate(false);\r\n }\r\n };\r\n\r\n const openEditGeneralInfo = () => {\r\n setEditState({ name: tenant.name, description: tenant.description || '', type: tenant.type as TenantType });\r\n setEditingGeneralInfo(true);\r\n onEditClick();\r\n };\r\n\r\n const closeEditGeneralInfo = () => {\r\n setEditingGeneralInfo(false);\r\n setEditState({ name: '', description: '', type: 'Business' });\r\n };\r\n\r\n const handleSaveGeneralInfo = async () => {\r\n if (!editState.name.trim()) return;\r\n setSavingGeneralInfo(true);\r\n try {\r\n await adminApi.tenants.update(tenant.id, {\r\n name: editState.name,\r\n description: editState.description,\r\n type: editState.type,\r\n });\r\n await onRefresh();\r\n closeEditGeneralInfo();\r\n } catch (err) {\r\n console.error('Failed to save tenant info:', err);\r\n } finally {\r\n setSavingGeneralInfo(false);\r\n }\r\n };\r\n\r\n const handleUnlinkOrganisation = async () => {\r\n setLinkingOrg(true);\r\n try {\r\n await onUnlinkOrg();\r\n } finally {\r\n setLinkingOrg(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <TenantGeneralInfoSection\r\n tenant={tenant}\r\n statusConfig={statusConfig}\r\n onEditClick={openEditGeneralInfo}\r\n t={t}\r\n />\r\n\r\n {/* Owner Card */}\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Info className=\"w-5 h-5\" />\r\n {t('tenants.detail.owner')}\r\n </h3>\r\n <button\r\n onClick={onMembersTabClick}\r\n className=\"btn btn-secondary\"\r\n title={t('tenants.members.transferOwnership.title')}\r\n >\r\n <Edit3 className=\"w-4 h-4\" />\r\n {t('common:edit')}\r\n </button>\r\n </div>\r\n {tenantOwner ? (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('common:name')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">{tenantOwner.userDisplayName || '-'}</p>\r\n </div>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('common:email')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">{tenantOwner.userEmail || '-'}</p>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"p-4 rounded-lg bg-[var(--bg-secondary)] text-center\">\r\n <p className=\"text-sm text-[var(--text-tertiary)]\">{t('tenants.detail.noOwner')}</p>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Organisation Card (B2B only) */}\r\n {tenant.type === 'Business' && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Building2 className=\"w-5 h-5\" />\r\n {t('tenants.detail.organisation')}\r\n </h3>\r\n {tenant.organisationId ? (\r\n <button\r\n onClick={handleUnlinkOrganisation}\r\n disabled={linkingOrg}\r\n className=\"btn btn-secondary text-[var(--error-text)] hover:bg-[var(--error-bg)]\"\r\n >\r\n {linkingOrg ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <X className=\"w-4 h-4\" />}\r\n {t('tenants.organisation.unlink')}\r\n </button>\r\n ) : (\r\n <button\r\n onClick={onLinkOrgClick}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.organisation.link')}\r\n </button>\r\n )}\r\n </div>\r\n {tenant.organisationId ? (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <p className=\"text-xs text-[var(--text-tertiary)] uppercase tracking-wider mb-1\">{t('tenants.detail.organisationName')}</p>\r\n <p className=\"text-sm text-[var(--text-primary)] font-medium\">{tenant.organisation?.name || '-'}</p>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"p-4 rounded-lg bg-[var(--info-bg)] border border-[var(--info-border)] text-center\">\r\n <Info className=\"w-5 h-5 text-[var(--info-text)] mx-auto mb-2\" />\r\n <p className=\"text-sm text-[var(--info-text)]\">\r\n {t('tenants.organisation.noOrganisation')}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n <TenantTicketingSection\r\n tenant={tenant}\r\n ticketingConfig={ticketingConfig}\r\n loadingTicketing={loadingTicketing}\r\n t={t}\r\n navigate={navigate}\r\n />\r\n\r\n <TenantTemplateSection\r\n tenant={tenant}\r\n templates={templates}\r\n onOpenTemplateModal={handleOpenTemplateModal}\r\n onRemoveTemplate={handleRemoveTemplate}\r\n removingTemplate={removingTemplate}\r\n navigate={navigate}\r\n t={t}\r\n />\r\n\r\n {/* Actions Card - Status management */}\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Settings className=\"w-5 h-5\" />\r\n {t('tenants.detail.actions')}\r\n </h3>\r\n </div>\r\n <div className=\"flex flex-wrap gap-3\">\r\n {tenant.status !== 'Active' && tenant.status !== 'Archived' && (\r\n <button\r\n onClick={() => onStatusChange('activate')}\r\n disabled={actionLoading !== null}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--success-dot)] text-white hover:opacity-90 transition-colors disabled:opacity-50\"\r\n >\r\n {actionLoading === 'activate' ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <PlayCircle className=\"w-4 h-4\" />}\r\n {t('tenants.actions.activate')}\r\n </button>\r\n )}\r\n {tenant.status === 'Active' && (\r\n <button\r\n onClick={() => onStatusChange('suspend')}\r\n disabled={actionLoading !== null}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--warning-dot)] text-white hover:opacity-90 transition-colors disabled:opacity-50\"\r\n >\r\n {actionLoading === 'suspend' ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <PauseCircle className=\"w-4 h-4\" />}\r\n {t('tenants.actions.suspend')}\r\n </button>\r\n )}\r\n {tenant.status !== 'Archived' && (\r\n <button\r\n onClick={() => onStatusChange('archive')}\r\n disabled={actionLoading !== null}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--error-dot)] text-white hover:opacity-90 transition-colors disabled:opacity-50\"\r\n >\r\n {actionLoading === 'archive' ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Archive className=\"w-4 h-4\" />}\r\n {t('tenants.actions.archive')}\r\n </button>\r\n )}\r\n <button\r\n onClick={onRefresh}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <RefreshCw className=\"w-4 h-4\" />\r\n {t('common:refresh')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <TemplateSelectionModal\r\n show={showTemplateModal}\r\n templates={templates}\r\n selectedTemplateId={selectedTemplateId}\r\n loadingTemplates={loadingTemplates}\r\n assigningTemplate={assigningTemplate}\r\n onTemplateSelect={setSelectedTemplateId}\r\n onClose={() => setShowTemplateModal(false)}\r\n onAssign={handleAssignTemplate}\r\n tenantTemplateId={tenant.templateId ?? undefined}\r\n t={t}\r\n />\r\n\r\n {/* Edit General Info Modal */}\r\n {editingGeneralInfo && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"card w-full max-w-md p-6 m-4\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <div>\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('tenants.edit.generalInfo')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.edit.generalInfoSubtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={closeEditGeneralInfo}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"space-y-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.form.name')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={editState.name}\r\n onChange={(e) => setEditState(prev => ({ ...prev, name: e.target.value }))}\r\n className=\"input w-full\"\r\n placeholder={t('tenants.create.namePlaceholder')}\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.form.description')}\r\n </label>\r\n <textarea\r\n value={editState.description}\r\n onChange={(e) => setEditState(prev => ({ ...prev, description: e.target.value }))}\r\n className=\"input w-full min-h-[100px] resize-y\"\r\n placeholder={t('tenants.create.descriptionPlaceholder')}\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.form.type')}\r\n </label>\r\n <div className=\"flex gap-3\">\r\n {(['Business', 'Personal'] as const).map((typeOption) => (\r\n <button\r\n key={typeOption}\r\n type=\"button\"\r\n onClick={() => setEditState(prev => ({ ...prev, type: typeOption }))}\r\n className={`flex-1 p-3 rounded-lg border text-center transition-colors ${\r\n editState.type === typeOption\r\n ? 'border-[var(--primary-color)] bg-[var(--primary-color)]/5 text-[var(--primary-color)]'\r\n : 'border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-secondary)] hover:border-[var(--primary-color)]'\r\n }`}\r\n >\r\n <span className=\"text-sm font-medium\">{t(`tenants.type.${typeOption.toLowerCase()}`)}</span>\r\n </button>\r\n ))}\r\n </div>\r\n {editState.type === 'Personal' && tenant.organisationId && (\r\n <p className=\"mt-2 text-xs text-[var(--error-text)]\">\r\n {t('tenants.form.typeWarningOrg')}\r\n </p>\r\n )}\r\n {editState.type !== tenant.type && (\r\n <p className=\"mt-2 text-xs text-[var(--warning-text)]\">\r\n {t('tenants.form.typeChangeWarning')}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={closeEditGeneralInfo}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleSaveGeneralInfo}\r\n disabled={savingGeneralInfo || !editState.name.trim()}\r\n className=\"btn btn-primary\"\r\n >\r\n {savingGeneralInfo ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n t('common:save')\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Link } from 'react-router-dom';\r\nimport {\r\n Shield,\r\n Crown,\r\n User,\r\n Users,\r\n Plus,\r\n X,\r\n UserMinus,\r\n Loader2,\r\n UsersRound,\r\n Link2,\r\n} from 'lucide-react';\r\nimport type { TenantMemberDto, TenantRoleDto, UserListDto } from '@/services/api/adminApi';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { DataTable, type DataTableColumn } from '@/components/ui/DataTable';\r\n\r\ninterface TenantMembersTabProps {\r\n readonly tenantId: string;\r\n readonly members: TenantMemberDto[] | null;\r\n readonly loadingMembers: boolean;\r\n readonly actionLoading: string | null;\r\n readonly onRefresh: () => Promise<void>;\r\n readonly onRemoveMember: (userId: string) => Promise<void>;\r\n}\r\n\r\ninterface ManageRolesState {\r\n readonly member: TenantMemberDto | null;\r\n readonly availableRoles: TenantRoleDto[];\r\n readonly selectedRoleIds: string[];\r\n}\r\n\r\nfunction formatDate(date: string | Date): string {\r\n const d = new Date(date);\r\n return d.toLocaleDateString('en-US', {\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n });\r\n}\r\n\r\n\r\nexport function TenantMembersTab({\r\n tenantId,\r\n members,\r\n loadingMembers,\r\n actionLoading,\r\n onRefresh,\r\n onRemoveMember,\r\n}: TenantMembersTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n // Manage roles modal state\r\n const [manageRolesState, setManageRolesState] = useState<ManageRolesState>({\r\n member: null,\r\n availableRoles: [],\r\n selectedRoleIds: [],\r\n });\r\n const [loadingRoles, setLoadingRoles] = useState(false);\r\n const [savingRoles, setSavingRoles] = useState(false);\r\n\r\n // Add member modal state\r\n const [addingMember, setAddingMember] = useState(false);\r\n const [availableUsers, setAvailableUsers] = useState<UserListDto[]>([]);\r\n const [loadingUsers, setLoadingUsers] = useState(false);\r\n const [userSearchTerm, setUserSearchTerm] = useState('');\r\n const [selectedUserId, setSelectedUserId] = useState<string | null>(null);\r\n const [addingMemberLoading, setAddingMemberLoading] = useState(false);\r\n\r\n const loadAvailableRoles = useCallback(async () => {\r\n setLoadingRoles(true);\r\n try {\r\n const data = await adminApi.tenants.getTenantRoles(tenantId);\r\n return data;\r\n } catch (err) {\r\n console.error('Failed to load roles:', err);\r\n return [];\r\n } finally {\r\n setLoadingRoles(false);\r\n }\r\n }, [tenantId]);\r\n\r\n const openRolesModal = async (member: TenantMemberDto) => {\r\n setManageRolesState(prev => ({\r\n ...prev,\r\n member,\r\n selectedRoleIds: member.roles.map(r => r.roleId),\r\n }));\r\n const roles = await loadAvailableRoles();\r\n setManageRolesState(prev => ({\r\n ...prev,\r\n availableRoles: roles,\r\n }));\r\n };\r\n\r\n const closeRolesModal = () => {\r\n setManageRolesState({\r\n member: null,\r\n availableRoles: [],\r\n selectedRoleIds: [],\r\n });\r\n };\r\n\r\n const handleRoleToggle = (roleId: string) => {\r\n setManageRolesState(prev => ({\r\n ...prev,\r\n selectedRoleIds: prev.selectedRoleIds.includes(roleId)\r\n ? prev.selectedRoleIds.filter(id => id !== roleId)\r\n : [...prev.selectedRoleIds, roleId]\r\n }));\r\n };\r\n\r\n const handleSaveRoles = async () => {\r\n if (!manageRolesState.member) return;\r\n setSavingRoles(true);\r\n try {\r\n await adminApi.tenants.assignMemberRoles(tenantId, manageRolesState.member.userId, manageRolesState.selectedRoleIds);\r\n await onRefresh();\r\n closeRolesModal();\r\n } catch (err) {\r\n console.error('Failed to save roles:', err);\r\n } finally {\r\n setSavingRoles(false);\r\n }\r\n };\r\n\r\n const loadAvailableUsers = async () => {\r\n setLoadingUsers(true);\r\n try {\r\n const data = await adminApi.users.getAll({ globalScope: true });\r\n setAvailableUsers(data.items);\r\n } catch (err) {\r\n console.error('Failed to load available users:', err);\r\n setAvailableUsers([]);\r\n } finally {\r\n setLoadingUsers(false);\r\n }\r\n };\r\n\r\n const openAddMember = () => {\r\n setAddingMember(true);\r\n setSelectedUserId(null);\r\n setUserSearchTerm('');\r\n loadAvailableUsers();\r\n };\r\n\r\n const closeAddMember = () => {\r\n setAddingMember(false);\r\n setSelectedUserId(null);\r\n setUserSearchTerm('');\r\n setAvailableUsers([]);\r\n };\r\n\r\n const handleAddMember = async () => {\r\n if (!selectedUserId) return;\r\n setAddingMemberLoading(true);\r\n try {\r\n await adminApi.tenants.addMember(tenantId, { userId: selectedUserId });\r\n await onRefresh();\r\n closeAddMember();\r\n } catch (err) {\r\n console.error('Failed to add member:', err);\r\n } finally {\r\n setAddingMemberLoading(false);\r\n }\r\n };\r\n\r\n const columns: DataTableColumn<TenantMemberDto>[] = [\r\n {\r\n key: 'userDisplayName',\r\n label: t('common:name'),\r\n sortable: true,\r\n render: (member) => (\r\n <Link\r\n to={`/administration/users/${member.userId}`}\r\n className=\"flex items-center gap-3 hover:text-[var(--color-accent-500)]\"\r\n >\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium ${\r\n member.isOwner\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n : 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]'\r\n }`}>\r\n {member.isOwner ? <Crown className=\"w-4 h-4\" /> : (member.userDisplayName || member.userEmail || '?').charAt(0).toUpperCase()}\r\n </div>\r\n <div className=\"min-w-0\">\r\n <span className=\"font-medium text-[var(--text-primary)] block truncate\">{member.userDisplayName || member.userEmail}</span>\r\n {member.userEmail && member.userDisplayName && (\r\n <span className=\"text-xs text-[var(--text-tertiary)] block truncate\">{member.userEmail}</span>\r\n )}\r\n </div>\r\n </Link>\r\n )\r\n },\r\n {\r\n key: 'roles',\r\n label: t('tenants.members.role'),\r\n render: (member) => (\r\n <div className=\"flex flex-wrap gap-1\">\r\n {member.isOwner && (\r\n <span className=\"inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-[var(--radius-badge)] bg-[var(--warning-bg)] text-[var(--warning-text)]\">\r\n <Crown className=\"w-3 h-3\" />\r\n {t('tenants.members.owner')}\r\n </span>\r\n )}\r\n {member.roles.length > 0 && (\r\n member.roles.map(role => (\r\n <span\r\n key={role.roleId}\r\n className=\"inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-[var(--radius-badge)] bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]\"\r\n >\r\n <Shield className=\"w-3 h-3\" />\r\n {role.roleName}\r\n </span>\r\n ))\r\n )}\r\n {member.roles.length === 0 && !member.isOwner && (\r\n <span className=\"inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-[var(--radius-badge)] bg-[var(--bg-tertiary)] text-[var(--text-secondary)]\">\r\n <User className=\"w-3 h-3\" />\r\n {t('tenants.members.member')}\r\n </span>\r\n )}\r\n </div>\r\n )\r\n },\r\n {\r\n key: 'membershipSource',\r\n label: 'Source',\r\n hideOnMobile: true,\r\n render: (member) => {\r\n const source = member.membershipSource;\r\n if (source === 'Group') {\r\n return (\r\n <div className=\"flex items-center gap-1.5\">\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full bg-purple-500/10 text-purple-600 dark:text-purple-400\">\r\n <UsersRound className=\"w-3 h-3\" />\r\n {t('tenants.members.source.group')}\r\n </span>\r\n {member.primaryGroupName && (\r\n <Link\r\n to={`/administration/users/groups/${member.primaryGroupId}`}\r\n className=\"inline-flex items-center gap-1 text-xs text-[var(--text-tertiary)] hover:text-[var(--color-accent-500)] transition-colors\"\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n <Link2 className=\"w-3 h-3\" />\r\n {member.primaryGroupName}\r\n </Link>\r\n )}\r\n </div>\r\n );\r\n }\r\n if (source === 'Both') {\r\n return (\r\n <div className=\"flex items-center gap-1.5\">\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full bg-blue-500/10 text-blue-600 dark:text-blue-400\">\r\n {t('tenants.members.source.both')}\r\n </span>\r\n {member.primaryGroupName && (\r\n <Link\r\n to={`/administration/users/groups/${member.primaryGroupId}`}\r\n className=\"inline-flex items-center gap-1 text-xs text-[var(--text-tertiary)] hover:text-[var(--color-accent-500)] transition-colors\"\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n <Link2 className=\"w-3 h-3\" />\r\n {member.primaryGroupName}\r\n </Link>\r\n )}\r\n </div>\r\n );\r\n }\r\n return (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full bg-green-500/10 text-green-600 dark:text-green-400\">\r\n {t('tenants.members.source.direct')}\r\n </span>\r\n );\r\n }\r\n },\r\n {\r\n key: 'joinedAt',\r\n label: t('tenants.members.joinedAt'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (member) => (\r\n <span className=\"text-sm text-[var(--text-tertiary)]\">{member.joinedAt ? formatDate(member.joinedAt) : '-'}</span>\r\n )\r\n },\r\n {\r\n key: 'actions',\r\n label: t('common:actionsColumn'),\r\n align: 'right',\r\n render: (member) => (\r\n <div className=\"flex items-center justify-end gap-1\">\r\n <button\r\n onClick={(e) => { e.stopPropagation(); openRolesModal(member); }}\r\n className=\"p-2 rounded-[var(--radius-button)] text-[var(--text-tertiary)] hover:text-[var(--color-accent-500)] hover:bg-[var(--color-accent-500)]/10 transition-colors\"\r\n title={t('tenants.members.manageRoles.title')}\r\n >\r\n <Shield className=\"w-4 h-4\" />\r\n </button>\r\n {!member.isOwner && member.membershipSource !== 'Group' && (\r\n <button\r\n onClick={(e) => { e.stopPropagation(); onRemoveMember(member.userId); }}\r\n disabled={actionLoading === member.userId}\r\n className=\"p-2 rounded-[var(--radius-button)] text-[var(--text-tertiary)] hover:text-[var(--error-text)] hover:bg-[var(--error-bg)] transition-colors disabled:opacity-50\"\r\n title={member.membershipSource === 'Both'\r\n ? t('tenants.members.source.cannotRemoveBoth')\r\n : t('tenants.members.remove')}\r\n >\r\n {actionLoading === member.userId ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <UserMinus className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n )}\r\n {!member.isOwner && member.membershipSource === 'Group' && (\r\n <span\r\n className=\"p-2 text-[var(--text-tertiary)] opacity-40 cursor-not-allowed\"\r\n title={t('tenants.members.source.cannotRemoveGroup')}\r\n >\r\n <UserMinus className=\"w-4 h-4\" />\r\n </span>\r\n )}\r\n </div>\r\n )\r\n }\r\n ];\r\n\r\n return (\r\n <>\r\n <DataTable<TenantMemberDto>\r\n data={members ?? []}\r\n loading={loadingMembers}\r\n columns={columns}\r\n searchable\r\n searchPlaceholder={t('tenants.members.search')}\r\n searchFilter={(member, term) =>\r\n (member.userDisplayName || '').toLowerCase().includes(term.toLowerCase()) ||\r\n (member.userEmail || '').toLowerCase().includes(term.toLowerCase())\r\n }\r\n getRowKey={(member) => member.userId}\r\n emptyMessage={t('tenants.members.empty')}\r\n emptyIcon={<Users className=\"w-12 h-12 mx-auto text-[var(--text-tertiary)]\" />}\r\n headerActions={\r\n <button\r\n onClick={openAddMember}\r\n className=\"btn btn-primary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.members.add')}\r\n </button>\r\n }\r\n pagination={{ pageSize: 10, showSizeSelector: true }}\r\n />\r\n\r\n {/* Manage Roles Modal */}\r\n {manageRolesState.member && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"card w-full max-w-md p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <div>\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('tenants.members.manageRoles.title')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.members.manageRoles.subtitle', { name: manageRolesState.member.userDisplayName || manageRolesState.member.userEmail })}\r\n </p>\r\n </div>\r\n <button\r\n onClick={closeRolesModal}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n {loadingRoles ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto p-3 border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-secondary)]\">\r\n {manageRolesState.availableRoles.length === 0 ? (\r\n <p className=\"text-sm text-[var(--text-tertiary)] text-center py-4\">\r\n {t('tenants.members.manageRoles.noRolesAvailable')}\r\n </p>\r\n ) : (\r\n manageRolesState.availableRoles.map(role => (\r\n <label\r\n key={role.id}\r\n className=\"flex items-center gap-3 cursor-pointer p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={manageRolesState.selectedRoleIds.includes(role.id)}\r\n onChange={() => handleRoleToggle(role.id)}\r\n className=\"w-4 h-4 rounded border-[var(--border-color)] text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <div className=\"flex-1\">\r\n <span className=\"text-[var(--text-primary)] font-medium\">{role.name}</span>\r\n {role.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{role.description}</p>\r\n )}\r\n </div>\r\n </label>\r\n ))\r\n )}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={closeRolesModal}\r\n className=\"px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleSaveRoles}\r\n disabled={savingRoles || loadingRoles}\r\n className=\"px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors disabled:opacity-50\"\r\n >\r\n {savingRoles ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n t('common:save')\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Add Member Modal */}\r\n {addingMember && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"card w-full max-w-md p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <div>\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('tenants.members.addTitle')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.members.addSubtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={closeAddMember}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <input\r\n type=\"text\"\r\n value={userSearchTerm}\r\n onChange={(e) => setUserSearchTerm(e.target.value)}\r\n className=\"input w-full\"\r\n placeholder={t('tenants.members.searchUsers')}\r\n />\r\n </div>\r\n\r\n {loadingUsers ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto p-3 border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-secondary)]\">\r\n {availableUsers\r\n .filter(u =>\r\n userSearchTerm === '' ||\r\n u.fullName.toLowerCase().includes(userSearchTerm.toLowerCase()) ||\r\n u.email.toLowerCase().includes(userSearchTerm.toLowerCase())\r\n )\r\n .map(user => (\r\n <label\r\n key={user.id}\r\n className={`flex items-center gap-3 cursor-pointer p-3 rounded-[var(--radius-button)] transition-colors ${\r\n selectedUserId === user.id\r\n ? 'bg-[var(--color-accent-500)]/10 border border-[var(--color-accent-500)]'\r\n : 'hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <input\r\n type=\"radio\"\r\n name=\"selectedUser\"\r\n checked={selectedUserId === user.id}\r\n onChange={() => setSelectedUserId(user.id)}\r\n className=\"w-4 h-4 text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <div className=\"flex-1\">\r\n <span className=\"text-[var(--text-primary)] font-medium\">{user.fullName}</span>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{user.email}</p>\r\n </div>\r\n </label>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={closeAddMember}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleAddMember}\r\n disabled={!selectedUserId || addingMemberLoading}\r\n className=\"btn btn-primary\"\r\n >\r\n {addingMemberLoading ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n t('common:add')\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n );\r\n}\r\n","import { useState } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport {\r\n UsersRound,\r\n Plus,\r\n X,\r\n Cloud,\r\n Loader2,\r\n Check,\r\n} from 'lucide-react';\r\nimport type { TenantGroupDto, AvailableGroupDto } from '@/services/api/adminApi';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { groupsApi } from '@/services/api/groupsApi';\r\nimport { DataTable, type DataTableColumn } from '@/components/ui/DataTable';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\n\r\ninterface TenantGroupsTabProps {\r\n readonly tenantId: string;\r\n readonly groups: TenantGroupDto[] | null;\r\n readonly loadingGroups: boolean;\r\n readonly removingGroupId: string | null;\r\n readonly onRefresh: () => Promise<void>;\r\n readonly onRemoveGroup: (groupId: string) => Promise<void>;\r\n}\r\n\r\nfunction formatDate(date: string | Date): string {\r\n const d = new Date(date);\r\n return d.toLocaleDateString('en-US', {\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n });\r\n}\r\n\r\nexport function TenantGroupsTab({\r\n tenantId,\r\n groups,\r\n loadingGroups,\r\n removingGroupId,\r\n onRefresh,\r\n onRemoveGroup,\r\n}: TenantGroupsTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n\r\n // Add group modal state\r\n const [addingGroup, setAddingGroup] = useState(false);\r\n const [availableGroupsForTenant, setAvailableGroupsForTenant] = useState<AvailableGroupDto[]>([]);\r\n const [loadingAvailableGroups, setLoadingAvailableGroups] = useState(false);\r\n const [selectedGroupIds, setSelectedGroupIds] = useState<string[]>([]);\r\n const [assigningGroups, setAssigningGroups] = useState(false);\r\n const [groupSearchTerm, setGroupSearchTerm] = useState('');\r\n\r\n // Remove group confirmation state\r\n const [removeConfirm, setRemoveConfirm] = useState<{ show: boolean; group: TenantGroupDto | null; loading: boolean }>({ show: false, group: null, loading: false });\r\n\r\n // Create group modal state\r\n const [showCreateModal, setShowCreateModal] = useState(false);\r\n const [newGroupName, setNewGroupName] = useState('');\r\n const [newGroupDescription, setNewGroupDescription] = useState('');\r\n const [newGroupIsSecurityGroup, setNewGroupIsSecurityGroup] = useState(true);\r\n const [creating, setCreating] = useState(false);\r\n const [createError, setCreateError] = useState<string | null>(null);\r\n\r\n const loadAvailableGroups = async () => {\r\n setLoadingAvailableGroups(true);\r\n try {\r\n const data = await adminApi.tenants.getAvailableGroups(tenantId);\r\n setAvailableGroupsForTenant(data);\r\n } catch (err) {\r\n console.error('Failed to load available groups:', err);\r\n setAvailableGroupsForTenant([]);\r\n } finally {\r\n setLoadingAvailableGroups(false);\r\n }\r\n };\r\n\r\n const openAddGroup = () => {\r\n setAddingGroup(true);\r\n setSelectedGroupIds([]);\r\n setGroupSearchTerm('');\r\n loadAvailableGroups();\r\n };\r\n\r\n const closeAddGroup = () => {\r\n setAddingGroup(false);\r\n setSelectedGroupIds([]);\r\n setGroupSearchTerm('');\r\n };\r\n\r\n const handleGroupToggle = (groupId: string) => {\r\n setSelectedGroupIds(prev =>\r\n prev.includes(groupId)\r\n ? prev.filter(id => id !== groupId)\r\n : [...prev, groupId]\r\n );\r\n };\r\n\r\n const handleAddGroups = async () => {\r\n if (selectedGroupIds.length === 0) return;\r\n setAssigningGroups(true);\r\n const succeeded: string[] = [];\r\n const failed: string[] = [];\r\n\r\n for (const groupId of selectedGroupIds) {\r\n try {\r\n await adminApi.tenants.addGroupToTenant(tenantId, groupId);\r\n succeeded.push(groupId);\r\n } catch (err) {\r\n console.error(`Failed to add group ${groupId}:`, err);\r\n failed.push(groupId);\r\n }\r\n }\r\n\r\n await onRefresh();\r\n\r\n if (failed.length === 0) {\r\n closeAddGroup();\r\n } else if (succeeded.length > 0) {\r\n setSelectedGroupIds(failed);\r\n }\r\n\r\n setAssigningGroups(false);\r\n };\r\n\r\n const handleCreateGroup = async () => {\r\n if (!newGroupName.trim()) return;\r\n\r\n setCreating(true);\r\n setCreateError(null);\r\n try {\r\n // 1. Create the group\r\n const created = await groupsApi.create({\r\n name: newGroupName.trim(),\r\n description: newGroupDescription.trim() || undefined,\r\n isSecurityGroup: newGroupIsSecurityGroup,\r\n });\r\n\r\n // 2. Automatically add it to this tenant\r\n await adminApi.tenants.addGroupToTenant(tenantId, created.id);\r\n\r\n // 3. Refresh and close\r\n await onRefresh();\r\n setShowCreateModal(false);\r\n setNewGroupName('');\r\n setNewGroupDescription('');\r\n setNewGroupIsSecurityGroup(true);\r\n } catch (err) {\r\n console.error('Failed to create group:', err);\r\n const axiosError = err as { response?: { status?: number; data?: { message?: string } } };\r\n if (axiosError.response?.status === 409) {\r\n setCreateError(axiosError.response.data?.message || t('tenants.groups.createError'));\r\n } else {\r\n setCreateError(t('tenants.groups.createError'));\r\n }\r\n } finally {\r\n setCreating(false);\r\n }\r\n };\r\n\r\n const columns: DataTableColumn<TenantGroupDto>[] = [\r\n {\r\n key: 'name',\r\n label: t('common:name'),\r\n sortable: true,\r\n render: (group) => (\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium ${\r\n group.isSyncedFromEntra\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]'\r\n }`}>\r\n <UsersRound className=\"w-4 h-4\" />\r\n </div>\r\n <div>\r\n <span className=\"font-medium text-[var(--color-accent-500)] hover:underline\">{group.name}</span>\r\n {group.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{group.description}</p>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n },\r\n {\r\n key: 'memberCount',\r\n label: t('tenants.groups.memberCount'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (group) => (\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{group.memberCount}</span>\r\n )\r\n },\r\n {\r\n key: 'linkType',\r\n label: t('tenants.groups.linkType'),\r\n render: (group) => (\r\n <span className={`inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-[var(--radius-badge)] ${\r\n group.isDirect\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n }`}>\r\n {group.isDirect\r\n ? t('tenants.groups.directMember')\r\n : t('tenants.groups.indirectMember', { groupName: group.linkedViaGroupName })}\r\n </span>\r\n )\r\n },\r\n {\r\n key: 'source',\r\n label: t('tenants.groups.source'),\r\n hideOnMobile: true,\r\n render: (group) => (\r\n <span className={`inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-[var(--radius-badge)] ${\r\n group.isSyncedFromEntra\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n {group.isSyncedFromEntra ? (\r\n <>\r\n <Cloud className=\"w-3 h-3\" />\r\n Entra ID\r\n </>\r\n ) : (\r\n <>\r\n <UsersRound className=\"w-3 h-3\" />\r\n {t('tenants.groups.local')}\r\n </>\r\n )}\r\n </span>\r\n )\r\n },\r\n {\r\n key: 'addedAt',\r\n label: t('tenants.members.joinedAt'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (group) => (\r\n <span className=\"text-sm text-[var(--text-tertiary)]\">\r\n {group.addedAt ? formatDate(group.addedAt) : '-'}\r\n </span>\r\n )\r\n },\r\n {\r\n key: 'actions',\r\n label: '',\r\n width: '80px',\r\n render: (group) => group.isDirect ? (\r\n <button\r\n onClick={(e) => { e.stopPropagation(); setRemoveConfirm({ show: true, group, loading: false }); }}\r\n disabled={removingGroupId === group.groupId}\r\n className=\"btn btn-ghost text-[var(--error-text)] hover:bg-[var(--error-bg)]\"\r\n title={t('tenants.groups.remove')}\r\n >\r\n {removingGroupId === group.groupId ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <X className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n ) : null\r\n }\r\n ];\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <DataTable<TenantGroupDto>\r\n data={groups ?? []}\r\n loading={loadingGroups}\r\n columns={columns}\r\n searchable\r\n searchPlaceholder={t('tenants.groups.searchPlaceholder')}\r\n searchFilter={(group, term) =>\r\n group.name.toLowerCase().includes(term.toLowerCase()) ||\r\n (group.description || '').toLowerCase().includes(term.toLowerCase())\r\n }\r\n getRowKey={(group) => group.groupId}\r\n onRowClick={(group) => navigate(`/administration/users/groups/${group.groupId}`)}\r\n emptyMessage={t('tenants.groups.noGroups')}\r\n emptyIcon={<UsersRound className=\"w-12 h-12 mx-auto text-[var(--text-tertiary)]\" />}\r\n headerActions={\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => { setCreateError(null); setShowCreateModal(true); }}\r\n className=\"btn btn-secondary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('groups.createGroup')}\r\n </button>\r\n <button\r\n onClick={openAddGroup}\r\n className=\"btn btn-primary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.groups.add')}\r\n </button>\r\n </div>\r\n }\r\n pagination={{ pageSize: 10, showSizeSelector: true }}\r\n />\r\n\r\n {/* Add Group Modal */}\r\n {addingGroup && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"card w-full max-w-md p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <div>\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('tenants.groups.addTitle')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.groups.addSubtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={closeAddGroup}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <input\r\n type=\"text\"\r\n value={groupSearchTerm}\r\n onChange={(e) => setGroupSearchTerm(e.target.value)}\r\n className=\"input w-full\"\r\n placeholder={t('tenants.groups.searchGroups')}\r\n />\r\n </div>\r\n\r\n {loadingAvailableGroups ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (() => {\r\n const filteredGroups = availableGroupsForTenant.filter(g =>\r\n groupSearchTerm === '' ||\r\n g.name.toLowerCase().includes(groupSearchTerm.toLowerCase()) ||\r\n (g.description || '').toLowerCase().includes(groupSearchTerm.toLowerCase())\r\n );\r\n\r\n return filteredGroups.length === 0 ? (\r\n <div className=\"p-8 text-center border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-secondary)]\">\r\n <UsersRound className=\"w-12 h-12 mx-auto mb-3 text-[var(--text-tertiary)]\" />\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {availableGroupsForTenant.length === 0\r\n ? t('tenants.groups.noAvailableGroups')\r\n : t('tenants.groups.noMatchingGroups')}\r\n </p>\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto p-3 border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-secondary)]\">\r\n {filteredGroups.map(group => (\r\n <label\r\n key={group.groupId}\r\n className={`flex items-center gap-3 cursor-pointer p-3 rounded-[var(--radius-button)] transition-colors ${\r\n selectedGroupIds.includes(group.groupId)\r\n ? 'bg-[var(--color-accent-500)]/10 border border-[var(--color-accent-500)]'\r\n : 'hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={selectedGroupIds.includes(group.groupId)}\r\n onChange={() => handleGroupToggle(group.groupId)}\r\n className=\"w-4 h-4 rounded border-[var(--border-color)] text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <div className=\"flex-1\">\r\n <span className=\"text-[var(--text-primary)] font-medium\">{group.name}</span>\r\n {group.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{group.description}</p>\r\n )}\r\n </div>\r\n </label>\r\n ))}\r\n </div>\r\n );\r\n })()}\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={closeAddGroup}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleAddGroups}\r\n disabled={selectedGroupIds.length === 0 || assigningGroups}\r\n className=\"btn btn-primary\"\r\n >\r\n {assigningGroups ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n t('common:add')\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Remove Group Confirmation */}\r\n {removeConfirm.group && (\r\n <ConfirmModal\r\n isOpen={removeConfirm.show}\r\n title={t('tenants.groups.remove')}\r\n message={t('tenants.groups.confirmRemove', { name: removeConfirm.group.name })}\r\n variant=\"danger\"\r\n confirmLabel={t('tenants.groups.remove')}\r\n loading={removeConfirm.loading}\r\n onConfirm={async () => {\r\n if (!removeConfirm.group) return;\r\n setRemoveConfirm(prev => ({ ...prev, loading: true }));\r\n try {\r\n await onRemoveGroup(removeConfirm.group.groupId);\r\n } finally {\r\n setRemoveConfirm({ show: false, group: null, loading: false });\r\n }\r\n }}\r\n onCancel={() => setRemoveConfirm({ show: false, group: null, loading: false })}\r\n />\r\n )}\r\n\r\n {/* Create Group Modal */}\r\n {showCreateModal && (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm\">\r\n <div className=\"w-full max-w-md rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)] shadow-xl m-4\">\r\n <div className=\"flex items-center justify-between p-4 border-b border-[var(--border-color)]\">\r\n <div>\r\n <h2 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('tenants.groups.createTitle')}\r\n </h2>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.groups.createSubtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={() => setShowCreateModal(false)}\r\n className=\"p-1 rounded hover:bg-[var(--bg-hover)] text-[var(--text-tertiary)]\"\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n <div className=\"p-4 space-y-4\">\r\n {createError && (\r\n <div className=\"p-3 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-sm text-[var(--error-text)]\">\r\n <span>{createError}</span>\r\n <button onClick={() => setCreateError(null)} className=\"ml-auto\">\r\n <X className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('groups.groupName')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={newGroupName}\r\n onChange={(e) => setNewGroupName(e.target.value)}\r\n placeholder={t('groups.groupNamePlaceholder')}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('common:description')}\r\n </label>\r\n <textarea\r\n value={newGroupDescription}\r\n onChange={(e) => setNewGroupDescription(e.target.value)}\r\n placeholder={t('groups.descriptionPlaceholder')}\r\n rows={3}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setNewGroupIsSecurityGroup(!newGroupIsSecurityGroup)}\r\n className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${\r\n newGroupIsSecurityGroup\r\n ? 'bg-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <span\r\n className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${\r\n newGroupIsSecurityGroup ? 'translate-x-6' : 'translate-x-1'\r\n }`}\r\n />\r\n </button>\r\n <span className=\"text-sm text-[var(--text-primary)]\">\r\n {t('groups.isSecurityGroup')}\r\n </span>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center justify-end gap-3 p-4 border-t border-[var(--border-color)]\">\r\n <button\r\n onClick={() => setShowCreateModal(false)}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleCreateGroup}\r\n disabled={!newGroupName.trim() || creating}\r\n className=\"btn btn-primary disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n {creating ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Check className=\"w-4 h-4\" />\r\n )}\r\n {t('tenants.groups.createAndAdd')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import type { ReactElement } from 'react';\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Shield,\r\n Globe,\r\n AppWindow,\r\n Users,\r\n Lock,\r\n} from 'lucide-react';\r\nimport type { TenantRoleDto } from '@/services/api/adminApi';\r\nimport { DataTable, type DataTableColumn } from '@/components/ui/DataTable';\r\n\r\ninterface TenantRolesTabProps {\r\n readonly roles: TenantRoleDto[] | null;\r\n readonly loadingRoles: boolean;\r\n}\r\n\r\nconst CATEGORY_STYLES: Record<string, { bg: string; text: string }> = {\r\n Global: { bg: 'bg-[var(--error-bg)]', text: 'text-[var(--error-text)]' },\r\n Admin: { bg: 'bg-[var(--warning-bg)]', text: 'text-[var(--warning-text)]' },\r\n Manager: { bg: 'bg-[var(--info-bg)]', text: 'text-[var(--info-text)]' },\r\n Contributor: { bg: 'bg-[var(--success-bg)]', text: 'text-[var(--success-text)]' },\r\n Viewer: { bg: 'bg-[var(--accent-bg)]', text: 'text-[var(--accent-text)]' },\r\n};\r\n\r\nexport function TenantRolesTab({\r\n roles,\r\n loadingRoles,\r\n}: Readonly<TenantRolesTabProps>): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n const columns: DataTableColumn<TenantRoleDto>[] = [\r\n {\r\n key: 'name',\r\n label: t('tenants.roles.columns.name'),\r\n sortable: true,\r\n render: (role) => (\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center ${\r\n role.isSystem\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n : 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]'\r\n }`}>\r\n {role.isSystem ? <Lock className=\"w-4 h-4\" /> : <Shield className=\"w-4 h-4\" />}\r\n </div>\r\n <div>\r\n <span className=\"font-medium text-[var(--text-primary)]\">{role.name}</span>\r\n {role.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5 line-clamp-1\">{role.description}</p>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n },\r\n {\r\n key: 'category',\r\n label: t('tenants.roles.columns.category'),\r\n sortable: true,\r\n render: (role) => {\r\n const style = CATEGORY_STYLES[role.category] ?? { bg: 'bg-[var(--bg-tertiary)]', text: 'text-[var(--text-secondary)]' };\r\n return (\r\n <span className={`inline-flex items-center px-2 py-1 text-xs rounded-[var(--radius-badge)] ${style.bg} ${style.text}`}>\r\n {t(`tenants.roles.categories.${role.category}`, { defaultValue: role.category })}\r\n </span>\r\n );\r\n }\r\n },\r\n {\r\n key: 'applicationName',\r\n label: t('tenants.roles.columns.application'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (role) => (\r\n <span className=\"inline-flex items-center gap-1.5 text-sm text-[var(--text-secondary)]\">\r\n {role.applicationId ? (\r\n <>\r\n <AppWindow className=\"w-3.5 h-3.5\" />\r\n {role.applicationName}\r\n </>\r\n ) : (\r\n <>\r\n <Globe className=\"w-3.5 h-3.5\" />\r\n {t('tenants.roles.scope.global')}\r\n </>\r\n )}\r\n </span>\r\n )\r\n },\r\n {\r\n key: 'permissionsCount',\r\n label: t('tenants.roles.columns.permissions'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (role) => (\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{role.permissionsCount}</span>\r\n )\r\n },\r\n {\r\n key: 'assignedMembersCount',\r\n label: t('tenants.roles.columns.members'),\r\n sortable: true,\r\n hideOnMobile: true,\r\n render: (role) => (\r\n <span className=\"inline-flex items-center gap-1.5 text-sm text-[var(--text-secondary)]\">\r\n <Users className=\"w-3.5 h-3.5\" />\r\n {role.assignedMembersCount}\r\n </span>\r\n )\r\n },\r\n ];\r\n\r\n return (\r\n <DataTable<TenantRoleDto>\r\n data={roles ?? []}\r\n loading={loadingRoles}\r\n columns={columns}\r\n searchable\r\n searchPlaceholder={t('tenants.roles.search')}\r\n searchFilter={(role, term) =>\r\n role.name.toLowerCase().includes(term.toLowerCase()) ||\r\n (role.description || '').toLowerCase().includes(term.toLowerCase()) ||\r\n (role.applicationName || '').toLowerCase().includes(term.toLowerCase())\r\n }\r\n getRowKey={(role) => role.id}\r\n emptyMessage={t('tenants.roles.empty')}\r\n emptyIcon={<Shield className=\"w-12 h-12 mx-auto text-[var(--text-tertiary)]\" />}\r\n pagination={{ pageSize: 10, showSizeSelector: true }}\r\n />\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Loader2,\r\n ChevronRight,\r\n ChevronDown,\r\n Layers,\r\n Check,\r\n Minus,\r\n Save,\r\n AlertCircle,\r\n CheckCircle,\r\n X,\r\n RotateCcw,\r\n Ban,\r\n} from 'lucide-react';\r\nimport * as LucideIcons from 'lucide-react';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type { TenantApplicationDto, OverrideAction } from '@/services/api/adminApi';\r\n\r\ninterface ApplicationAccessCustomizeDrawerProps {\r\n readonly isOpen: boolean;\r\n readonly onClose: () => void;\r\n readonly tenantId: string;\r\n readonly tenantName: string;\r\n readonly application: TenantApplicationDto;\r\n readonly onSaved?: () => void;\r\n /** Mode: 'tenant' for tenant-level customization, 'template' for template-level */\r\n readonly mode?: 'tenant' | 'template';\r\n}\r\n\r\ninterface DrawerModuleNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n source: string;\r\n accessLevel: string;\r\n isEffectivelyActive: boolean;\r\n isChecked: boolean;\r\n originalSource: string;\r\n sections: DrawerSectionNode[];\r\n}\r\n\r\ninterface DrawerSectionNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n source: string;\r\n accessLevel: string;\r\n isEffectivelyActive: boolean;\r\n isChecked: boolean;\r\n originalSource: string;\r\n}\r\n\r\ntype AccessMode = 'full' | 'custom';\r\n\r\nconst SOURCE_COLORS: Record<string, { dot: string; text: string; bg: string; label: string }> = {\r\n Inherited: { dot: 'bg-green-500', text: 'text-green-600 dark:text-green-400', bg: 'bg-green-50 dark:bg-green-900/20', label: 'inheritedLabel' },\r\n Direct: { dot: 'bg-blue-500', text: 'text-blue-600 dark:text-blue-400', bg: 'bg-blue-50 dark:bg-blue-900/20', label: 'directLabel' },\r\n Overridden: { dot: 'bg-orange-500', text: 'text-orange-600 dark:text-orange-400', bg: 'bg-orange-50 dark:bg-orange-900/20', label: 'directLabel' },\r\n Revoked: { dot: 'bg-red-500', text: 'text-red-600 dark:text-red-400', bg: 'bg-red-50 dark:bg-red-900/20', label: 'revokedLabel' },\r\n Unavailable: { dot: 'bg-gray-400', text: 'text-gray-500', bg: '', label: '' },\r\n};\r\n\r\n// Helper to compute module overrides\r\nconst computeModuleOverrides = (modules: DrawerModuleNode[]): { moduleId: string; action: OverrideAction }[] => {\r\n const overrides: { moduleId: string; action: OverrideAction }[] = [];\r\n for (const m of modules) {\r\n const wasActive = m.originalSource !== 'Revoked' && m.originalSource !== 'Unavailable';\r\n const isNowChecked = m.isChecked;\r\n\r\n if (wasActive && !isNowChecked) {\r\n overrides.push({ moduleId: m.id, action: 'revoke' });\r\n } else if (!wasActive && isNowChecked) {\r\n if (m.originalSource === 'Revoked') {\r\n overrides.push({ moduleId: m.id, action: 'remove-override' });\r\n } else {\r\n overrides.push({ moduleId: m.id, action: 'add' });\r\n }\r\n }\r\n }\r\n return overrides;\r\n};\r\n\r\n// Helper to compute section overrides\r\nconst computeSectionOverrides = (modules: DrawerModuleNode[]): { sectionId: string; action: OverrideAction }[] => {\r\n const overrides: { sectionId: string; action: OverrideAction }[] = [];\r\n for (const m of modules) {\r\n for (const s of m.sections) {\r\n const sWasActive = s.originalSource !== 'Revoked' && s.originalSource !== 'Unavailable';\r\n const sIsNowChecked = s.isChecked;\r\n\r\n if (sWasActive && !sIsNowChecked) {\r\n overrides.push({ sectionId: s.id, action: 'revoke' });\r\n } else if (!sWasActive && sIsNowChecked) {\r\n if (s.originalSource === 'Revoked') {\r\n overrides.push({ sectionId: s.id, action: 'remove-override' });\r\n } else {\r\n overrides.push({ sectionId: s.id, action: 'add' });\r\n }\r\n }\r\n }\r\n }\r\n return overrides;\r\n};\r\n\r\n// Pure function to update module check state\r\nconst updateModuleCheckStateHelper = (\r\n prev: DrawerModuleNode[],\r\n moduleId: string,\r\n newChecked: boolean\r\n): DrawerModuleNode[] => {\r\n return prev.map(m => {\r\n if (m.id !== moduleId) return m;\r\n return {\r\n ...m,\r\n isChecked: newChecked,\r\n sections: m.sections.map(s => ({ ...s, isChecked: newChecked })),\r\n };\r\n });\r\n};\r\n\r\n// Pure function to update section check state\r\nconst updateSectionCheckStateHelper = (\r\n prev: DrawerModuleNode[],\r\n moduleId: string,\r\n sectionId: string\r\n): DrawerModuleNode[] => {\r\n return prev.map(m => {\r\n if (m.id !== moduleId) return m;\r\n const newSections = m.sections.map(s =>\r\n s.id === sectionId ? { ...s, isChecked: !s.isChecked } : s\r\n );\r\n return {\r\n ...m,\r\n isChecked: newSections.some(s => s.isChecked),\r\n sections: newSections,\r\n };\r\n });\r\n};\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype TranslationFn = (...args: any[]) => any;\r\n\r\ninterface SectionItemProps {\r\n readonly section: DrawerSectionNode;\r\n readonly moduleId: string;\r\n readonly renderIcon: (iconName: string | null) => React.ReactNode;\r\n readonly isInheritedRevoked: (originalSource: string, isChecked: boolean) => boolean;\r\n readonly toggleSection: (moduleId: string, sectionId: string) => void;\r\n readonly t: TranslationFn;\r\n}\r\n\r\nconst SectionItem = ({ section, moduleId, renderIcon, isInheritedRevoked: checkRevoked, toggleSection, t }: SectionItemProps) => {\r\n const sectionRevoked = checkRevoked(section.originalSource, section.isChecked);\r\n\r\n return (\r\n <div\r\n key={section.id}\r\n className={`flex items-center gap-2 p-2 rounded ${\r\n sectionRevoked\r\n ? 'bg-red-50/60 dark:bg-red-900/10 hover:bg-red-50 dark:hover:bg-red-900/20'\r\n : 'hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <button\r\n onClick={() => toggleSection(moduleId, section.id)}\r\n className={`w-4 h-4 rounded border-2 flex items-center justify-center flex-shrink-0 transition-colors ${\r\n sectionRevoked\r\n ? 'border-red-500 bg-red-500'\r\n : section.isChecked\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-600)]'\r\n }`}\r\n >\r\n {sectionRevoked && <Ban className=\"w-2.5 h-2.5 text-white\" />}\r\n {!sectionRevoked && section.isChecked && <Check className=\"w-2.5 h-2.5 text-white\" />}\r\n </button>\r\n\r\n <div className={`p-1 rounded ${sectionRevoked ? 'bg-red-100 dark:bg-red-900/30' : 'bg-[var(--bg-tertiary)]'}`}>\r\n {renderIcon(section.icon) || (\r\n <Layers className={`w-3 h-3 ${sectionRevoked ? 'text-red-400' : 'text-[var(--text-muted)]'}`} />\r\n )}\r\n </div>\r\n\r\n <span className={`text-sm flex-1 ${sectionRevoked ? 'line-through text-red-500 dark:text-red-400' : 'text-[var(--text-primary)]'}`}>{section.label}</span>\r\n {sectionRevoked && (\r\n <span className=\"text-[10px] px-1.5 py-0.5 rounded-full bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400 font-medium\">\r\n {t('tenants.applications.customize.revokedLabel')}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\ninterface ModuleRowProps {\r\n readonly module: DrawerModuleNode;\r\n readonly isExpanded: boolean;\r\n readonly renderIcon: (iconName: string | null) => React.ReactNode;\r\n readonly isInheritedRevoked: (originalSource: string, isChecked: boolean) => boolean;\r\n readonly getModuleCheckState: (module: DrawerModuleNode) => 'checked' | 'unchecked' | 'indeterminate';\r\n readonly toggleModuleExpand: (moduleId: string) => void;\r\n readonly toggleModule: (moduleId: string) => void;\r\n readonly toggleSection: (moduleId: string, sectionId: string) => void;\r\n readonly mode: 'tenant' | 'template';\r\n readonly t: TranslationFn;\r\n}\r\n\r\nconst ModuleRow = ({\r\n module,\r\n isExpanded,\r\n renderIcon,\r\n isInheritedRevoked: checkRevoked,\r\n getModuleCheckState,\r\n toggleModuleExpand,\r\n toggleModule,\r\n toggleSection,\r\n mode,\r\n t,\r\n}: ModuleRowProps) => {\r\n const checkState = getModuleCheckState(module);\r\n const moduleRevoked = checkRevoked(module.originalSource, module.isChecked);\r\n\r\n return (\r\n <div key={module.id}>\r\n {/* Module Row */}\r\n <div className={`flex items-center gap-2 p-3 ${\r\n moduleRevoked\r\n ? 'bg-red-50/60 dark:bg-red-900/10 hover:bg-red-50 dark:hover:bg-red-900/20'\r\n : 'hover:bg-[var(--bg-hover)]'\r\n }`}>\r\n <button\r\n onClick={() => toggleModuleExpand(module.id)}\r\n className=\"p-1 rounded hover:bg-[var(--bg-tertiary)]\"\r\n >\r\n {isExpanded ? (\r\n <ChevronDown className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n ) : (\r\n <ChevronRight className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n )}\r\n </button>\r\n\r\n <button\r\n onClick={() => toggleModule(module.id)}\r\n className={`w-5 h-5 rounded border-2 flex items-center justify-center flex-shrink-0 transition-colors ${\r\n moduleRevoked\r\n ? 'border-red-500 bg-red-500'\r\n : checkState === 'checked'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]'\r\n : checkState === 'indeterminate'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-600)]'\r\n }`}\r\n >\r\n {moduleRevoked && <Ban className=\"w-3 h-3 text-white\" />}\r\n {!moduleRevoked && checkState === 'checked' && <Check className=\"w-3 h-3 text-white\" />}\r\n {!moduleRevoked && checkState === 'indeterminate' && <Minus className=\"w-3 h-3 text-white\" />}\r\n </button>\r\n\r\n <div className={`p-1.5 rounded ${moduleRevoked ? 'bg-red-100 dark:bg-red-900/30' : 'bg-[var(--bg-tertiary)]'}`}>\r\n {renderIcon(module.icon) || <Layers className={`w-4 h-4 ${moduleRevoked ? 'text-red-400' : 'text-[var(--text-muted)]'}`} />}\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <p className={`font-medium truncate ${moduleRevoked ? 'line-through text-red-500 dark:text-red-400' : 'text-[var(--text-primary)]'}`}>{module.label}</p>\r\n {mode !== 'template' && module.source !== 'Unavailable' && (\r\n moduleRevoked ? (\r\n <span className=\"text-[10px] px-1.5 py-0.5 rounded-full bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400 font-medium\">\r\n {t('tenants.applications.customize.revokedLabel')}\r\n </span>\r\n ) : (\r\n <span className={`text-[10px] px-1.5 py-0.5 rounded-full ${(SOURCE_COLORS[module.source] || SOURCE_COLORS.Inherited).bg} ${(SOURCE_COLORS[module.source] || SOURCE_COLORS.Inherited).text}`}>\r\n {t(`tenants.applications.customize.${(SOURCE_COLORS[module.source] || SOURCE_COLORS.Inherited).label}`)}\r\n </span>\r\n )\r\n )}\r\n </div>\r\n <p className={`text-xs ml-4 ${moduleRevoked ? 'text-red-400 dark:text-red-500' : 'text-[var(--text-muted)]'}`}>\r\n {module.sections.filter(s => s.isChecked).length}/{module.sections.length}{' '}\r\n {t('tenants.applications.customize.sections', 'sections')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Sections (expandable) */}\r\n {isExpanded && module.sections.length > 0 && (\r\n <div className=\"pl-12 pb-2 space-y-1 bg-[var(--bg-secondary)]\">\r\n {module.sections.map(section => (\r\n <SectionItem\r\n key={section.id}\r\n section={section}\r\n moduleId={module.id}\r\n renderIcon={renderIcon}\r\n isInheritedRevoked={checkRevoked}\r\n toggleSection={toggleSection}\r\n t={t}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport function ApplicationAccessCustomizeDrawer({\r\n isOpen,\r\n onClose,\r\n tenantId,\r\n tenantName,\r\n application,\r\n onSaved,\r\n mode = 'tenant',\r\n}: ApplicationAccessCustomizeDrawerProps): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n\r\n const [accessMode, setAccessMode] = useState<AccessMode>('full');\r\n const [modules, setModules] = useState<DrawerModuleNode[]>([]);\r\n const [expandedModules, setExpandedModules] = useState<Set<string>>(new Set());\r\n\r\n const renderIcon = (iconName: string | null) => {\r\n if (!iconName) return null;\r\n const icons = LucideIcons as unknown as Record<string, LucideIcon>;\r\n const IconComponent = icons[iconName];\r\n if (!IconComponent) return null;\r\n return <IconComponent className=\"w-4 h-4\" />;\r\n };\r\n\r\n const loadData = useCallback(async () => {\r\n if (!isOpen) return;\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n if (mode === 'template') {\r\n // Template mode: unchanged - use existing endpoint\r\n const treeData = await adminApi.templates.getApplicationModules(tenantId, application.applicationId);\r\n const moduleNodes: DrawerModuleNode[] = treeData.map(m => ({\r\n id: m.moduleId,\r\n label: m.label,\r\n code: m.code,\r\n icon: m.icon,\r\n source: m.isAssigned ? 'Direct' : 'Unavailable',\r\n accessLevel: 'FullAccess',\r\n isEffectivelyActive: m.isAssigned,\r\n isChecked: m.isAssigned,\r\n originalSource: m.isAssigned ? 'Direct' : 'Unavailable',\r\n sections: m.sections.map(s => ({\r\n id: s.sectionId,\r\n label: s.label,\r\n code: s.code,\r\n icon: s.icon,\r\n source: s.isAssigned ? 'Direct' : 'Unavailable',\r\n accessLevel: 'FullAccess',\r\n isEffectivelyActive: s.isAssigned,\r\n isChecked: s.isAssigned,\r\n originalSource: s.isAssigned ? 'Direct' : 'Unavailable',\r\n })),\r\n }));\r\n setModules(moduleNodes);\r\n setAccessMode(moduleNodes.some(m => m.isChecked) ? 'custom' : 'full');\r\n const expanded = new Set(moduleNodes.filter(m => m.sections.some(s => s.isChecked)).map(m => m.id));\r\n setExpandedModules(expanded);\r\n } else {\r\n // Tenant mode: use effective-tree endpoint\r\n const tree = await adminApi.tenants.getEffectiveTree(tenantId, application.applicationId);\r\n const moduleNodes: DrawerModuleNode[] = tree.map(m => ({\r\n id: m.moduleId,\r\n label: m.label,\r\n code: m.code,\r\n icon: m.icon,\r\n source: m.source,\r\n accessLevel: m.accessLevel,\r\n isEffectivelyActive: m.isEffectivelyActive,\r\n isChecked: m.source !== 'Revoked' && m.source !== 'Unavailable',\r\n originalSource: m.source,\r\n sections: m.sections.map(s => ({\r\n id: s.sectionId,\r\n label: s.label,\r\n code: s.code,\r\n icon: s.icon,\r\n source: s.source,\r\n accessLevel: s.accessLevel,\r\n isEffectivelyActive: s.isEffectivelyActive,\r\n isChecked: s.source !== 'Revoked' && s.source !== 'Unavailable',\r\n originalSource: s.source,\r\n })),\r\n }));\r\n setModules(moduleNodes);\r\n\r\n // Determine access mode\r\n const hasAnyOverride = moduleNodes.some(m =>\r\n m.source === 'Direct' || m.source === 'Overridden' || m.source === 'Revoked' ||\r\n m.sections.some(s => s.source === 'Direct' || s.source === 'Overridden' || s.source === 'Revoked')\r\n );\r\n setAccessMode(hasAnyOverride ? 'custom' : 'full');\r\n\r\n // Expand modules that have interesting content\r\n const expanded = new Set(moduleNodes\r\n .filter(m => m.sections.some(s => s.source !== 'Inherited' || !s.isEffectivelyActive))\r\n .map(m => m.id));\r\n setExpandedModules(expanded);\r\n }\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load data');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [isOpen, application.applicationId, tenantId, mode]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const preCheckAllModules = (mods: DrawerModuleNode[]): DrawerModuleNode[] => {\r\n return mods.map(m => ({\r\n ...m,\r\n isChecked: true,\r\n sections: m.sections.map(s => ({ ...s, isChecked: true })),\r\n }));\r\n };\r\n\r\n const handleAccessModeChange = (newMode: AccessMode) => {\r\n if (newMode === 'custom' && accessMode === 'full') {\r\n const hasAnyChecked = modules.some(m => m.isChecked || m.sections.some(s => s.isChecked));\r\n if (!hasAnyChecked) {\r\n setModules(preCheckAllModules);\r\n }\r\n }\r\n setAccessMode(newMode);\r\n };\r\n\r\n const toggleModuleExpand = (moduleId: string) => {\r\n setExpandedModules(prev => {\r\n const newSet = new Set(prev);\r\n if (newSet.has(moduleId)) {\r\n newSet.delete(moduleId);\r\n } else {\r\n newSet.add(moduleId);\r\n }\r\n return newSet;\r\n });\r\n };\r\n\r\n const toggleModule = (moduleId: string) => {\r\n setModules(prev => {\r\n const target = prev.find(m => m.id === moduleId);\r\n const newChecked = !target?.isChecked;\r\n return updateModuleCheckStateHelper(prev, moduleId, newChecked);\r\n });\r\n };\r\n\r\n const toggleSection = (moduleId: string, sectionId: string) => {\r\n setModules(prev => updateSectionCheckStateHelper(prev, moduleId, sectionId));\r\n };\r\n\r\n /** Returns true if this item was inherited (from template/group) and is now revoked by the user */\r\n const isInheritedRevoked = (originalSource: string, isChecked: boolean) =>\r\n (originalSource === 'Inherited' || originalSource === 'Revoked') && !isChecked;\r\n\r\n const getModuleCheckState = (module: DrawerModuleNode): 'checked' | 'unchecked' | 'indeterminate' => {\r\n if (module.sections.length === 0) {\r\n return module.isChecked ? 'checked' : 'unchecked';\r\n }\r\n const checkedCount = module.sections.filter(s => s.isChecked).length;\r\n if (checkedCount === 0) return 'unchecked';\r\n if (checkedCount === module.sections.length) return 'checked';\r\n return 'indeterminate';\r\n };\r\n\r\n const saveTemplateMode = async () => {\r\n if (accessMode === 'full') {\r\n await adminApi.templates.updateApplicationModules(tenantId, application.applicationId, {\r\n accessMode: 'full',\r\n });\r\n } else {\r\n const moduleIds = modules.filter(m => m.isChecked || m.sections.some(s => s.isChecked)).map(m => m.id);\r\n const sectionIds = modules.flatMap(m => m.sections.filter(s => s.isChecked).map(s => s.id));\r\n await adminApi.templates.updateApplicationModules(tenantId, application.applicationId, {\r\n accessMode: 'custom',\r\n moduleIds,\r\n sectionIds,\r\n });\r\n }\r\n };\r\n\r\n const saveTenantMode = async () => {\r\n const moduleOverrides = computeModuleOverrides(modules);\r\n const sectionOverrides = computeSectionOverrides(modules);\r\n\r\n if (moduleOverrides.length > 0 || sectionOverrides.length > 0) {\r\n await adminApi.tenants.saveOverrides(tenantId, application.applicationId, {\r\n modules: moduleOverrides.length > 0 ? moduleOverrides : undefined,\r\n sections: sectionOverrides.length > 0 ? sectionOverrides : undefined,\r\n });\r\n }\r\n };\r\n\r\n const handleSave = async () => {\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n\r\n try {\r\n if (mode === 'template') {\r\n await saveTemplateMode();\r\n } else {\r\n await saveTenantMode();\r\n }\r\n\r\n setSuccess(t('tenants.applications.customize.saved', 'Access customization saved'));\r\n onSaved?.();\r\n setTimeout(() => onClose(), 1000);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to save');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleReset = async () => {\r\n setSaving(true);\r\n setError(null);\r\n try {\r\n // Remove all tenant-level overrides for modules and sections of this app\r\n const resetAction: OverrideAction = 'remove-override';\r\n const moduleOverrides = modules\r\n .filter(m => m.originalSource === 'Direct' || m.originalSource === 'Overridden' || m.originalSource === 'Revoked')\r\n .map(m => ({ moduleId: m.id, action: resetAction }));\r\n const sectionOverrides = modules.flatMap(m =>\r\n m.sections\r\n .filter(s => s.originalSource === 'Direct' || s.originalSource === 'Overridden' || s.originalSource === 'Revoked')\r\n .map(s => ({ sectionId: s.id, action: resetAction }))\r\n );\r\n\r\n if (moduleOverrides.length > 0 || sectionOverrides.length > 0) {\r\n await adminApi.tenants.saveOverrides(tenantId, application.applicationId, {\r\n modules: moduleOverrides.length > 0 ? moduleOverrides : undefined,\r\n sections: sectionOverrides.length > 0 ? sectionOverrides : undefined,\r\n });\r\n }\r\n\r\n setSuccess(t('tenants.applications.customize.resetSuccess', 'Customizations reset'));\r\n onSaved?.();\r\n setTimeout(() => onClose(), 1000);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to reset');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const getStats = () => {\r\n const totalModules = modules.length;\r\n const checkedModules = modules.filter(m => m.isChecked).length;\r\n const totalSections = modules.reduce((sum, m) => sum + m.sections.length, 0);\r\n const checkedSections = modules.reduce((sum, m) => sum + m.sections.filter(s => s.isChecked).length, 0);\r\n const inheritedCount = modules.filter(m => m.source === 'Inherited').length;\r\n const directCount = modules.filter(m => m.source === 'Direct' || m.source === 'Overridden').length;\r\n const revokedCount = modules.filter(m => m.source === 'Revoked').length;\r\n const revokedInheritedModules = modules.filter(m => isInheritedRevoked(m.originalSource, m.isChecked)).length;\r\n const revokedInheritedSections = modules.reduce((sum, m) => sum + m.sections.filter(s => isInheritedRevoked(s.originalSource, s.isChecked)).length, 0);\r\n return { totalModules, checkedModules, totalSections, checkedSections, inheritedCount, directCount, revokedCount, revokedInheritedModules, revokedInheritedSections };\r\n };\r\n\r\n const stats = getStats();\r\n\r\n // Handle escape key\r\n useEffect(() => {\r\n const handleEscape = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape' && isOpen) {\r\n onClose();\r\n }\r\n };\r\n document.addEventListener('keydown', handleEscape);\r\n return () => document.removeEventListener('keydown', handleEscape);\r\n }, [isOpen, onClose]);\r\n\r\n // Lock body scroll when open\r\n useEffect(() => {\r\n if (isOpen) {\r\n document.body.style.overflow = 'hidden';\r\n } else {\r\n document.body.style.overflow = '';\r\n }\r\n return () => {\r\n document.body.style.overflow = '';\r\n };\r\n }, [isOpen]);\r\n\r\n if (!isOpen) return null;\r\n\r\n return (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\r\n {/* Backdrop */}\r\n <button\r\n type=\"button\"\r\n className=\"absolute inset-0 bg-black/50\"\r\n onClick={onClose}\r\n aria-label=\"Close modal\"\r\n />\r\n\r\n {/* Modal */}\r\n <div className=\"relative w-full max-w-2xl max-h-[90vh] bg-[var(--bg-card)] rounded-[var(--radius-card)] shadow-xl border border-[var(--border-color)] flex flex-col\">\r\n {/* Header */}\r\n <div className=\"flex items-start justify-between p-4 border-b border-[var(--border-color)]\">\r\n <div>\r\n <h2 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('tenants.applications.customize.title', 'Customize Access')}\r\n </h2>\r\n <p className=\"mt-1 text-sm text-[var(--text-muted)]\">\r\n {application.label} - {tenantName}\r\n </p>\r\n </div>\r\n <button\r\n onClick={onClose}\r\n className=\"p-1 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-muted)]\"\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n\r\n {/* Content */}\r\n <div className=\"flex-1 overflow-y-auto p-4\">\r\n {loading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n ) : (\r\n <div className=\"space-y-6\">\r\n {/* Alerts */}\r\n {error && (\r\n <div className=\"flex items-center gap-3 p-3 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertCircle className=\"w-4 h-4 text-[var(--error-text)]\" />\r\n <p className=\"text-sm text-[var(--error-text)]\">{error}</p>\r\n </div>\r\n )}\r\n {success && (\r\n <div className=\"flex items-center gap-3 p-3 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <p className=\"text-sm text-[var(--success-text)]\">{success}</p>\r\n </div>\r\n )}\r\n\r\n {/* Access Mode Selection */}\r\n <div className=\"space-y-3\">\r\n <label className=\"text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('tenants.applications.customize.accessMode', 'Access Mode')}\r\n </label>\r\n\r\n {/* Full Access Option */}\r\n <button\r\n type=\"button\"\r\n onClick={() => handleAccessModeChange('full')}\r\n className={`w-full flex items-start gap-3 p-4 rounded-[var(--radius-card)] border text-left transition-colors ${\r\n accessMode === 'full'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]/5'\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div\r\n className={`w-5 h-5 mt-0.5 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${\r\n accessMode === 'full' ? 'border-[var(--color-accent-600)]' : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {accessMode === 'full' && (\r\n <div className=\"w-2.5 h-2.5 rounded-full bg-[var(--color-accent-600)]\" />\r\n )}\r\n </div>\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('tenants.applications.customize.fullAccess', 'Full Application Access')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-muted)] mt-1\">\r\n {t(\r\n 'tenants.applications.customize.fullAccessHint',\r\n 'Access to all modules and sections of this application'\r\n )}\r\n </p>\r\n </div>\r\n </button>\r\n\r\n {/* Custom Access Option */}\r\n <button\r\n type=\"button\"\r\n onClick={() => handleAccessModeChange('custom')}\r\n className={`w-full flex items-start gap-3 p-4 rounded-[var(--radius-card)] border text-left transition-colors ${\r\n accessMode === 'custom'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]/5'\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div\r\n className={`w-5 h-5 mt-0.5 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${\r\n accessMode === 'custom' ? 'border-[var(--color-accent-600)]' : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {accessMode === 'custom' && (\r\n <div className=\"w-2.5 h-2.5 rounded-full bg-[var(--color-accent-600)]\" />\r\n )}\r\n </div>\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('tenants.applications.customize.customAccess', 'Custom Access')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-muted)] mt-1\">\r\n {t(\r\n 'tenants.applications.customize.customAccessHint',\r\n 'Select specific modules and sections to grant access'\r\n )}\r\n </p>\r\n </div>\r\n </button>\r\n </div>\r\n\r\n {/* Module/Section Tree (only shown in custom mode) */}\r\n {accessMode === 'custom' && (\r\n <div className=\"space-y-3\">\r\n <label className=\"text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('tenants.applications.customize.selectModules', 'Select Modules & Sections')}\r\n </label>\r\n\r\n <div className=\"border border-[var(--border-color)] rounded-[var(--radius-card)] divide-y divide-[var(--border-color)]\">\r\n {modules.map(module => (\r\n <ModuleRow\r\n key={module.id}\r\n module={module}\r\n isExpanded={expandedModules.has(module.id)}\r\n renderIcon={renderIcon}\r\n isInheritedRevoked={isInheritedRevoked}\r\n getModuleCheckState={getModuleCheckState}\r\n toggleModuleExpand={toggleModuleExpand}\r\n toggleModule={toggleModule}\r\n toggleSection={toggleSection}\r\n mode={mode}\r\n t={t}\r\n />\r\n ))}\r\n\r\n {modules.length === 0 && (\r\n <div className=\"p-6 text-center text-sm text-[var(--text-muted)]\">\r\n {t('tenants.applications.customize.noModules', 'No modules available')}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Footer */}\r\n <div className=\"flex-shrink-0 border-t border-[var(--border-color)] p-4 bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"text-sm text-[var(--text-muted)]\">\r\n {accessMode === 'custom' ? (\r\n <div className=\"space-y-0.5\">\r\n <div>\r\n {stats.checkedModules}/{stats.totalModules} {t('tenants.applications.customize.modules', 'modules')},\r\n {' '}{stats.checkedSections}/{stats.totalSections} {t('tenants.applications.customize.sections', 'sections')}\r\n </div>\r\n {(stats.revokedInheritedModules > 0 || stats.revokedInheritedSections > 0) && (\r\n <div className=\"text-red-500 dark:text-red-400 text-xs flex items-center gap-1\">\r\n <Ban className=\"w-3 h-3\" />\r\n {stats.revokedInheritedModules > 0 && (\r\n <span>{stats.revokedInheritedModules} {t('tenants.applications.customize.modules')} {t('tenants.applications.customize.revokedLabel').toLowerCase()}</span>\r\n )}\r\n {stats.revokedInheritedModules > 0 && stats.revokedInheritedSections > 0 && ', '}\r\n {stats.revokedInheritedSections > 0 && (\r\n <span>{stats.revokedInheritedSections} {t('tenants.applications.customize.sections')} {t('tenants.applications.customize.revokedLabel').toLowerCase()}</span>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n t('tenants.applications.customize.fullAccessDesc', 'Full application access')\r\n )}\r\n </div>\r\n <div className=\"flex gap-2\">\r\n {mode !== 'template' && modules.some(m => m.originalSource !== 'Inherited' && m.originalSource !== 'Unavailable') && (\r\n <button\r\n onClick={handleReset}\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-3 py-2 rounded-[var(--radius-button)] font-medium text-orange-600 hover:bg-orange-50 dark:text-orange-400 dark:hover:bg-orange-900/20\"\r\n >\r\n <RotateCcw className=\"w-4 h-4\" />\r\n {t('tenants.applications.customize.resetOverrides', 'Reset to template')}\r\n </button>\r\n )}\r\n <button\r\n onClick={onClose}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] font-medium text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common.cancel', 'Cancel')}\r\n </button>\r\n <button\r\n onClick={handleSave}\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common.save', 'Save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useMemo, useState } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport * as LucideIcons from 'lucide-react';\r\nimport {\r\n Boxes,\r\n Plus,\r\n X,\r\n Check,\r\n Minus,\r\n SlidersHorizontal,\r\n Loader2,\r\n Search,\r\n ChevronRight,\r\n ChevronDown,\r\n CheckCircle,\r\n Layers,\r\n Trash2,\r\n ShieldX,\r\n AlertTriangle,\r\n} from 'lucide-react';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport type {\r\n TenantApplicationDto,\r\n AvailableApplicationDto,\r\n ApplicationAccessLevel,\r\n} from '@/services/api/adminApi';\r\nimport { EntityCard } from '@/components/ui/EntityCard';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport { ApplicationAccessCustomizeDrawer } from '@/components/platform/administration/ApplicationAccessCustomizeDrawer';\r\n\r\nexport interface BulkModuleNode {\r\n readonly id: string;\r\n readonly label: string;\r\n readonly code: string;\r\n readonly icon: string | null;\r\n readonly isAssigned: boolean;\r\n readonly sections: BulkSectionNode[];\r\n}\r\n\r\nexport interface BulkSectionNode {\r\n readonly id: string;\r\n readonly label: string;\r\n readonly code: string;\r\n readonly icon: string | null;\r\n readonly isAssigned: boolean;\r\n}\r\n\r\ninterface TenantApplicationsTabProps {\r\n readonly tenantId: string;\r\n readonly tenantName: string;\r\n /** Mode: 'tenant' for tenant-level, 'template' for template-level module management */\r\n readonly mode?: 'tenant' | 'template';\r\n readonly applications: TenantApplicationDto[] | null;\r\n readonly loadingApps: boolean;\r\n readonly actionLoading: string | null;\r\n readonly onRefresh: () => Promise<void>;\r\n readonly onUpdateAccessLevel: (appId: string, accessLevel: ApplicationAccessLevel) => Promise<void>;\r\n readonly onRemoveApplication?: (appId: string) => Promise<void>;\r\n // Add application modal state\r\n readonly addingApplication: boolean;\r\n readonly availableAppsError?: string | null;\r\n readonly filteredAvailableApps: AvailableApplicationDto[];\r\n readonly loadingAvailableApps: boolean;\r\n readonly selectedAppIds: string[];\r\n readonly assigningApps: boolean;\r\n readonly appSearchTerm: string;\r\n readonly selectedAccessLevel: ApplicationAccessLevel;\r\n readonly bulkAccessMode: 'full' | 'custom';\r\n readonly bulkModules: BulkModuleNode[];\r\n readonly bulkExpandedModules: Set<string>;\r\n readonly loadingBulkModules: boolean;\r\n // Customize drawer state\r\n readonly showCustomizeDrawer: boolean;\r\n readonly customizingApp: TenantApplicationDto | null;\r\n // Actions\r\n readonly onOpenAddApplication: () => void;\r\n readonly onCloseAddApplication: () => void;\r\n readonly onAssignApplications: () => Promise<void>;\r\n readonly onAppToggle: (appId: string) => void;\r\n readonly onSelectAllApps: () => void;\r\n readonly onClearAppSelection: () => void;\r\n readonly onOpenCustomizeDrawer: (app: TenantApplicationDto) => void;\r\n readonly onCloseCustomizeDrawer: () => void;\r\n // Module handlers\r\n readonly onLoadBulkModules: (appId: string) => Promise<void>;\r\n readonly onToggleBulkModuleExpand: (moduleId: string) => void;\r\n readonly onToggleBulkModule: (moduleId: string) => void;\r\n readonly onToggleBulkSection: (moduleId: string, sectionId: string) => void;\r\n readonly onGetBulkModuleCheckState: (module: BulkModuleNode) => 'checked' | 'unchecked' | 'indeterminate';\r\n readonly onGetBulkStats: () => { totalModules: number; assignedModules: number; totalSections: number; assignedSections: number };\r\n readonly onSelectAllBulkModules: () => void;\r\n readonly onClearBulkModules: () => void;\r\n // Setters\r\n readonly setAppSearchTerm: (term: string) => void;\r\n readonly setSelectedAccessLevel: (level: ApplicationAccessLevel) => void;\r\n readonly setBulkAccessMode: (mode: 'full' | 'custom') => void;\r\n}\r\n\r\nfunction formatDate(date: string | Date): string {\r\n const d = new Date(date);\r\n return d.toLocaleDateString('en-US', {\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n });\r\n}\r\n\r\nconst getCheckStateClassName = (checkState: 'checked' | 'unchecked' | 'indeterminate'): string => {\r\n if (checkState === 'checked' || checkState === 'indeterminate') {\r\n return 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]';\r\n }\r\n return 'border-[var(--border-color)] hover:border-[var(--color-accent-600)]';\r\n};\r\n\r\nconst getLoadingView = (): React.ReactNode => (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n);\r\n\r\nconst getEmptyApplicationsView = (t: (key: string) => string): React.ReactNode => (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n <Boxes className=\"w-12 h-12 mx-auto mb-4 text-[var(--text-tertiary)]\" />\r\n <p>{t('tenants.applications.empty')}</p>\r\n </div>\r\n);\r\n\r\nconst ACCESS_LEVEL_OPTIONS: {\r\n level: ApplicationAccessLevel;\r\n labelKey: string;\r\n descKey: string;\r\n selectedBorder: string;\r\n selectedBg: string;\r\n dotBg: string;\r\n}[] = [\r\n {\r\n level: 'FullAccess',\r\n labelKey: 'tenants.applications.accessLevels.fullAccess',\r\n descKey: 'tenants.applications.accessLevels.fullAccessDesc',\r\n selectedBorder: 'border-green-500',\r\n selectedBg: 'bg-green-500/10',\r\n dotBg: 'bg-green-500',\r\n },\r\n {\r\n level: 'RequestAccess',\r\n labelKey: 'tenants.applications.accessLevels.requestAccess',\r\n descKey: 'tenants.applications.accessLevels.requestAccessDesc',\r\n selectedBorder: 'border-amber-500',\r\n selectedBg: 'bg-amber-500/10',\r\n dotBg: 'bg-amber-500',\r\n },\r\n {\r\n level: 'Disabled',\r\n labelKey: 'tenants.applications.accessLevels.disabled',\r\n descKey: 'tenants.applications.accessLevels.disabledDesc',\r\n selectedBorder: 'border-gray-500',\r\n selectedBg: 'bg-gray-500/10',\r\n dotBg: 'bg-gray-500',\r\n },\r\n];\r\n\r\n\r\nfunction AccessLevelSelector({\r\n selectedAccessLevel,\r\n setSelectedAccessLevel,\r\n}: {\r\n selectedAccessLevel: ApplicationAccessLevel;\r\n setSelectedAccessLevel: (level: ApplicationAccessLevel) => void;\r\n}) {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n {ACCESS_LEVEL_OPTIONS.map((opt) => {\r\n const isSelected = selectedAccessLevel === opt.level;\r\n return (\r\n <button\r\n key={opt.level}\r\n type=\"button\"\r\n onClick={() => setSelectedAccessLevel(opt.level)}\r\n className={`w-full flex items-start gap-3 p-4 rounded-[var(--radius-input)] border text-left transition-colors ${\r\n isSelected\r\n ? `${opt.selectedBorder} ${opt.selectedBg}`\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div\r\n className={`w-5 h-5 mt-0.5 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${\r\n isSelected ? opt.selectedBorder : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {isSelected && <div className={`w-2.5 h-2.5 rounded-full ${opt.dotBg}`} />}\r\n </div>\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">{t(opt.labelKey)}</p>\r\n <p className=\"text-sm text-[var(--text-muted)] mt-1\">{t(opt.descKey)}</p>\r\n </div>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n\r\nexport function TenantApplicationsTab({\r\n tenantId,\r\n tenantName,\r\n mode = 'tenant',\r\n applications,\r\n loadingApps,\r\n actionLoading,\r\n onRefresh,\r\n onUpdateAccessLevel,\r\n onRemoveApplication,\r\n addingApplication,\r\n availableAppsError,\r\n filteredAvailableApps,\r\n loadingAvailableApps,\r\n selectedAppIds,\r\n assigningApps,\r\n appSearchTerm,\r\n selectedAccessLevel,\r\n bulkAccessMode,\r\n bulkModules,\r\n bulkExpandedModules,\r\n loadingBulkModules,\r\n showCustomizeDrawer,\r\n customizingApp,\r\n onOpenAddApplication,\r\n onCloseAddApplication,\r\n onAssignApplications,\r\n onAppToggle,\r\n onSelectAllApps,\r\n onClearAppSelection,\r\n onOpenCustomizeDrawer,\r\n onCloseCustomizeDrawer,\r\n onLoadBulkModules,\r\n onToggleBulkModuleExpand,\r\n onToggleBulkModule,\r\n onToggleBulkSection,\r\n onGetBulkModuleCheckState,\r\n onGetBulkStats,\r\n onSelectAllBulkModules,\r\n onClearBulkModules,\r\n setAppSearchTerm,\r\n setSelectedAccessLevel,\r\n setBulkAccessMode,\r\n}: TenantApplicationsTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n const bulkStats = useMemo(() => {\r\n return onGetBulkStats();\r\n }, [bulkModules, onGetBulkStats]);\r\n\r\n const [removeConfirm, setRemoveConfirm] = useState<{\r\n show: boolean;\r\n app: TenantApplicationDto | null;\r\n loading: boolean;\r\n }>({ show: false, app: null, loading: false });\r\n\r\n const inheritedApps = useMemo(\r\n () => (applications ?? []).filter(app => app.source === 'Inherited' || app.source === 'Overridden'),\r\n [applications]\r\n );\r\n\r\n const directApps = useMemo(\r\n () => (applications ?? []).filter(app => app.source === 'Direct' || app.source === 'Revoked'),\r\n [applications]\r\n );\r\n\r\n const renderAppCard = (app: TenantApplicationDto) => {\r\n const accessLevelOption = ACCESS_LEVEL_OPTIONS.find(o => o.level === app.accessLevel);\r\n const isActive = app.accessLevel !== 'Disabled';\r\n\r\n return (\r\n <EntityCard\r\n key={app.applicationId}\r\n avatar={{\r\n letter: (app.label?.at(0) || 'A').toUpperCase(),\r\n color: isActive ? 'var(--color-accent-500)' : '#6b7280'\r\n }}\r\n title={app.label}\r\n subtitle={app.code}\r\n description={app.assignedAt\r\n ? t('tenants.applications.assignedAt', { date: formatDate(app.assignedAt) })\r\n : undefined\r\n }\r\n stats={\r\n <span>\r\n {app.inheritedModuleCount > 0 && (\r\n <><span className=\"text-green-600 dark:text-green-400 font-medium\">{app.inheritedModuleCount}</span> {t('tenants.applications.counts.inherited')}</>\r\n )}\r\n {app.directModuleCount > 0 && (\r\n <>{app.inheritedModuleCount > 0 ? ', ' : ''}<span className=\"text-blue-600 dark:text-blue-400 font-medium\">{app.directModuleCount}</span> {t('tenants.applications.counts.direct')}</>\r\n )}\r\n {app.revokedModuleCount > 0 && (\r\n <>{(app.inheritedModuleCount > 0 || app.directModuleCount > 0) ? ', ' : ''}<span className=\"text-red-600 dark:text-red-400 font-medium\">{app.revokedModuleCount}</span> {t('tenants.applications.counts.revoked')}</>\r\n )}\r\n {app.inheritedModuleCount === 0 && app.directModuleCount === 0 && app.revokedModuleCount === 0 && (\r\n <><span className=\"font-medium text-[var(--text-primary)]\">0</span>/{app.totalModuleCount}</>\r\n )}\r\n {' '}{t('tenants.applications.customize.modules')}\r\n {' / '}\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {app.totalSectionCount}\r\n </span>{' '}\r\n {t('tenants.applications.customize.sections')}\r\n </span>\r\n }\r\n customFooter={\r\n <div className=\"space-y-2 pt-2 mt-2 border-t border-[var(--border-color)]\">\r\n {/* Access level selector */}\r\n <div className=\"flex items-center gap-2\">\r\n <div className={`w-2.5 h-2.5 rounded-full flex-shrink-0 ${accessLevelOption?.dotBg ?? 'bg-green-500'}`} />\r\n <select\r\n value={app.accessLevel}\r\n onChange={e => void onUpdateAccessLevel(app.applicationId, e.target.value as ApplicationAccessLevel)}\r\n disabled={actionLoading === app.applicationId}\r\n className=\"flex-1 px-2 py-1 rounded-[var(--radius-input)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-sm text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)]\"\r\n >\r\n {ACCESS_LEVEL_OPTIONS.map(opt => (\r\n <option key={opt.level} value={opt.level}>\r\n {t(opt.labelKey)}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n {/* Customize + Remove buttons */}\r\n <div className=\"flex gap-2\">\r\n <button\r\n onClick={() => onOpenCustomizeDrawer(app)}\r\n className=\"btn btn-sm flex items-center justify-center gap-1 flex-1 bg-[var(--color-accent-700)] hover:bg-[var(--color-accent-800)] text-white\"\r\n >\r\n <SlidersHorizontal className=\"w-4 h-4\" />\r\n {t('tenants.applications.customize.button')}\r\n </button>\r\n {onRemoveApplication && (\r\n <button\r\n onClick={() => setRemoveConfirm({ show: true, app, loading: false })}\r\n className=\"btn btn-sm flex items-center justify-center px-2 border border-red-300 text-red-500 hover:bg-red-50 hover:border-red-400 dark:border-red-700 dark:hover:bg-red-900/20\"\r\n title={t('tenants.applications.remove')}\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n }\r\n />\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"space-y-4\">\r\n {/* Header with Add button */}\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('tenants.applications.assigned')}\r\n </h3>\r\n <button\r\n onClick={onOpenAddApplication}\r\n className=\"btn btn-primary\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.applications.add')}\r\n </button>\r\n </div>\r\n\r\n {loadingApps ? getLoadingView() : null}\r\n {!loadingApps && (!applications || applications.length === 0) ? getEmptyApplicationsView(t) : null}\r\n\r\n {/* Inherited applications section */}\r\n {!loadingApps && inheritedApps.length > 0 && (\r\n <div className=\"space-y-3\">\r\n <h4 className=\"text-base font-medium text-[var(--text-secondary)]\">\r\n {t('tenants.applications.sectionInherited')}\r\n <span className=\"ml-2 text-sm font-normal text-[var(--text-muted)]\">({inheritedApps.length})</span>\r\n </h4>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6\">\r\n {inheritedApps.map(renderAppCard)}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Direct applications section */}\r\n {!loadingApps && directApps.length > 0 && (\r\n <div className=\"space-y-3\">\r\n <h4 className=\"text-base font-medium text-[var(--text-secondary)]\">\r\n {t('tenants.applications.sectionDirect')}\r\n <span className=\"ml-2 text-sm font-normal text-[var(--text-muted)]\">({directApps.length})</span>\r\n </h4>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6\">\r\n {directApps.map(renderAppCard)}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n {addingApplication && (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\r\n <div className=\"w-full max-w-6xl bg-[var(--bg-card)] rounded-[var(--radius-card)] shadow-xl border border-[var(--border-color)] max-h-[90vh] flex flex-col\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between p-4 border-b border-[var(--border-color)] flex-shrink-0\">\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('tenants.applications.modal.title')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {t('tenants.applications.modal.subtitle')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={onCloseAddApplication}\r\n className=\"p-1 hover:bg-[var(--bg-hover)] rounded-[var(--radius-button)]\"\r\n aria-label={t('common:close', 'Close')}\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n\r\n {/* Three Column Content */}\r\n <div className=\"flex-1 overflow-hidden grid grid-cols-1 md:grid-cols-3 divide-x divide-[var(--border-color)]\">\r\n {/* Left Column - Application Selection */}\r\n <div className=\"flex flex-col p-4 overflow-hidden\">\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <label className=\"text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('tenants.applications.modal.selectApps')}\r\n {selectedAppIds.length > 0 && (\r\n <span className=\"ml-2 px-2 py-0.5 text-xs rounded-full bg-[var(--color-accent-600)] text-white\">\r\n {selectedAppIds.length}\r\n </span>\r\n )}\r\n </label>\r\n <div className=\"flex gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={onSelectAllApps}\r\n className=\"text-xs text-[var(--color-accent-600)] hover:underline\"\r\n >\r\n {t('tenants.applications.modal.selectAll')}\r\n </button>\r\n {selectedAppIds.length > 0 && (\r\n <button\r\n type=\"button\"\r\n onClick={onClearAppSelection}\r\n className=\"text-xs text-[var(--text-muted)] hover:underline\"\r\n >\r\n {t('tenants.applications.modal.clearSelection')}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Search */}\r\n <div className=\"relative mb-3\">\r\n <Search className=\"absolute left-3 top-2.5 w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={appSearchTerm}\r\n onChange={e => setAppSearchTerm(e.target.value)}\r\n placeholder={t('tenants.applications.modal.searchPlaceholder')}\r\n className=\"w-full px-3 py-2 pl-10 rounded-[var(--radius-input)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n\r\n {/* Application List */}\r\n <div className=\"flex-1 overflow-y-auto border border-[var(--border-color)] rounded-[var(--radius-input)]\">\r\n {loadingAvailableApps && (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n )}\r\n {!loadingAvailableApps && availableAppsError && (\r\n <div className=\"flex flex-col items-center justify-center py-8 px-4 text-center\">\r\n {availableAppsError === 'forbidden' ? (\r\n <>\r\n <ShieldX className=\"w-8 h-8 text-red-500 mb-2\" />\r\n <p className=\"text-sm font-medium text-red-500 mb-1\">\r\n {t('tenants.applications.modal.errorForbidden')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">\r\n {t('tenants.applications.modal.errorForbiddenHint')}\r\n </p>\r\n </>\r\n ) : (\r\n <>\r\n <AlertTriangle className=\"w-8 h-8 text-amber-500 mb-2\" />\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.applications.modal.errorGeneric')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">\r\n {t('tenants.applications.modal.errorGenericHint')}\r\n </p>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n {!loadingAvailableApps && !availableAppsError && filteredAvailableApps.length === 0 && (\r\n <div className=\"flex flex-col items-center justify-center py-8 px-4 text-center\">\r\n <Boxes className=\"w-8 h-8 text-[var(--text-tertiary)] mb-2\" />\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {t('tenants.applications.modal.noAvailable')}\r\n </p>\r\n </div>\r\n )}\r\n {!loadingAvailableApps && !availableAppsError && filteredAvailableApps.length > 0 && (\r\n filteredAvailableApps.map(app => {\r\n const isSelected = selectedAppIds.includes(app.id);\r\n return (\r\n <button\r\n key={app.id}\r\n onClick={() => onAppToggle(app.id)}\r\n className={`w-full flex items-center gap-3 px-3 py-2.5 text-left hover:bg-[var(--bg-hover)] border-b border-[var(--border-color)] last:border-b-0 ${\r\n isSelected ? 'bg-[var(--color-accent-500)]/10' : ''\r\n }`}\r\n >\r\n <div\r\n className={`w-5 h-5 rounded border-2 flex items-center justify-center flex-shrink-0 ${\r\n isSelected\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]'\r\n : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {isSelected && <CheckCircle className=\"w-3 h-3 text-white\" />}\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"font-medium text-[var(--text-primary)] truncate\">{app.label}</p>\r\n <p className=\"text-xs text-[var(--text-muted)] truncate\">\r\n {app.code}\r\n </p>\r\n </div>\r\n </button>\r\n );\r\n })\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Middle Column - Module Customization */}\r\n <div className=\"flex flex-col p-4 overflow-hidden\">\r\n <label className=\"text-sm font-medium text-[var(--text-secondary)] mb-3\">\r\n {t('tenants.applications.modal.moduleAccess')}\r\n </label>\r\n <p className=\"text-xs text-[var(--text-muted)] mb-4\">\r\n {t('tenants.applications.modal.moduleAccessHint')}\r\n </p>\r\n\r\n {/* Access Mode Toggle */}\r\n <div className=\"space-y-2 mb-4\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setBulkAccessMode('full')}\r\n className={`w-full flex items-start gap-3 p-3 rounded-[var(--radius-input)] border text-left transition-colors ${\r\n bulkAccessMode === 'full'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]/5'\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div\r\n className={`w-4 h-4 mt-0.5 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${\r\n bulkAccessMode === 'full' ? 'border-[var(--color-accent-600)]' : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {bulkAccessMode === 'full' && <div className=\"w-2 h-2 rounded-full bg-[var(--color-accent-600)]\" />}\r\n </div>\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('tenants.applications.customize.fullAccess')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)] mt-0.5\">\r\n {t('tenants.applications.modal.fullAccessModulesHint')}\r\n </p>\r\n </div>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => {\r\n setBulkAccessMode('custom');\r\n if (selectedAppIds.length > 0 && bulkModules.length === 0) {\r\n onLoadBulkModules(selectedAppIds[0]);\r\n }\r\n }}\r\n className={`w-full flex items-start gap-3 p-3 rounded-[var(--radius-input)] border text-left transition-colors ${\r\n bulkAccessMode === 'custom'\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]/5'\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div\r\n className={`w-4 h-4 mt-0.5 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${\r\n bulkAccessMode === 'custom' ? 'border-[var(--color-accent-600)]' : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n {bulkAccessMode === 'custom' && <div className=\"w-2 h-2 rounded-full bg-[var(--color-accent-600)]\" />}\r\n </div>\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('tenants.applications.customize.customAccess')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)] mt-0.5\">\r\n {t('tenants.applications.modal.customAccessModulesHint')}\r\n </p>\r\n </div>\r\n </button>\r\n </div>\r\n\r\n {/* Module/Section Tree (only shown in custom mode) */}\r\n {bulkAccessMode === 'custom' && (\r\n <div className=\"flex-1 overflow-hidden flex flex-col\">\r\n {selectedAppIds.length === 0 && (\r\n <p className=\"text-sm text-[var(--text-muted)] text-center py-8\">\r\n {t('tenants.applications.modal.selectAppFirst')}\r\n </p>\r\n )}\r\n {selectedAppIds.length > 0 && loadingBulkModules && (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-600)]\" />\r\n </div>\r\n )}\r\n {selectedAppIds.length > 0 && !loadingBulkModules && (\r\n <>\r\n {selectedAppIds.length > 1 && (\r\n <p className=\"text-xs text-amber-600 mb-2\">\r\n {t('tenants.applications.modal.multipleAppsHint')}\r\n </p>\r\n )}\r\n <div className=\"flex items-center justify-between mb-2\">\r\n <div className=\"text-xs text-[var(--text-muted)]\">\r\n {bulkStats.assignedModules}/{bulkStats.totalModules}{' '}\r\n {t('tenants.applications.customize.modules')},\r\n {' '}{bulkStats.assignedSections}/{bulkStats.totalSections}{' '}\r\n {t('tenants.applications.customize.sections')}\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={onSelectAllBulkModules}\r\n className=\"text-xs text-[var(--color-accent-600)] hover:underline\"\r\n >\r\n {t('tenants.applications.modal.selectAllModules')}\r\n </button>\r\n {bulkStats.assignedSections > 0 && (\r\n <button\r\n type=\"button\"\r\n onClick={onClearBulkModules}\r\n className=\"text-xs text-[var(--text-muted)] hover:underline\"\r\n >\r\n {t('tenants.applications.modal.clearModules')}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto border border-[var(--border-color)] rounded-[var(--radius-input)]\">\r\n {bulkModules.map(module => {\r\n const checkState = onGetBulkModuleCheckState(module);\r\n const isExpanded = bulkExpandedModules.has(module.id);\r\n const icons = LucideIcons as unknown as Record<string, LucideIcon>;\r\n const ModuleIcon = module.icon ? icons[module.icon] : null;\r\n\r\n return (\r\n <div key={module.id} className=\"border-b border-[var(--border-color)] last:border-b-0\">\r\n <div className=\"flex items-center gap-2 p-2 hover:bg-[var(--bg-hover)]\">\r\n <button\r\n type=\"button\"\r\n onClick={() => onToggleBulkModuleExpand(module.id)}\r\n className=\"p-0.5 rounded hover:bg-[var(--bg-tertiary)]\"\r\n >\r\n {isExpanded ? (\r\n <ChevronDown className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n ) : (\r\n <ChevronRight className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n )}\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => onToggleBulkModule(module.id)}\r\n className={`w-4 h-4 rounded border-2 flex items-center justify-center flex-shrink-0 transition-colors ${getCheckStateClassName(checkState)}`}\r\n >\r\n {checkState === 'checked' && <Check className=\"w-2.5 h-2.5 text-white\" />}\r\n {checkState === 'indeterminate' && <Minus className=\"w-2.5 h-2.5 text-white\" />}\r\n </button>\r\n\r\n <div className=\"p-1 rounded bg-[var(--bg-tertiary)]\">\r\n {ModuleIcon ? (\r\n <ModuleIcon className=\"w-3 h-3 text-[var(--text-muted)]\" />\r\n ) : (\r\n <Layers className=\"w-3 h-3 text-[var(--text-muted)]\" />\r\n )}\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] truncate\">{module.label}</p>\r\n </div>\r\n </div>\r\n\r\n {isExpanded && module.sections.length > 0 && (\r\n <div className=\"pl-10 pb-1 space-y-0.5 bg-[var(--bg-secondary)]\">\r\n {module.sections.map(section => {\r\n const SectionIcon = section.icon ? icons[section.icon] : null;\r\n return (\r\n <div key={section.id} className=\"flex items-center gap-2 p-1.5 rounded hover:bg-[var(--bg-hover)]\">\r\n <button\r\n type=\"button\"\r\n onClick={() => onToggleBulkSection(module.id, section.id)}\r\n className={`w-3.5 h-3.5 rounded border-2 flex items-center justify-center flex-shrink-0 transition-colors ${\r\n section.isAssigned\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-600)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-accent-600)]'\r\n }`}\r\n >\r\n {section.isAssigned && <Check className=\"w-2 h-2 text-white\" />}\r\n </button>\r\n\r\n <div className=\"p-0.5 rounded bg-[var(--bg-tertiary)]\">\r\n {SectionIcon ? (\r\n <SectionIcon className=\"w-3 h-3 text-[var(--text-muted)]\" />\r\n ) : (\r\n <Layers className=\"w-3 h-3 text-[var(--text-muted)]\" />\r\n )}\r\n </div>\r\n\r\n <span className=\"text-xs text-[var(--text-primary)] truncate\">{section.label}</span>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n\r\n {bulkModules.length === 0 && (\r\n <p className=\"p-4 text-center text-sm text-[var(--text-muted)]\">\r\n {t('tenants.applications.customize.noModules')}\r\n </p>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Right Column - Access Level */}\r\n <div className=\"flex flex-col p-4\">\r\n <label className=\"text-sm font-medium text-[var(--text-secondary)] mb-3\">\r\n {t('tenants.applications.modal.accessLevel')}\r\n </label>\r\n <p className=\"text-xs text-[var(--text-muted)] mb-4\">\r\n {t('tenants.applications.modal.accessLevelHint')}\r\n </p>\r\n <AccessLevelSelector\r\n selectedAccessLevel={selectedAccessLevel}\r\n setSelectedAccessLevel={setSelectedAccessLevel}\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Footer */}\r\n <div className=\"flex items-center justify-between p-4 border-t border-[var(--border-color)] flex-shrink-0 bg-[var(--bg-secondary)]\">\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {selectedAppIds.length > 0\r\n ? t('tenants.applications.modal.selectedCount', { count: selectedAppIds.length })\r\n : t('tenants.applications.modal.noSelection')}\r\n </p>\r\n <div className=\"flex gap-2\">\r\n <button\r\n onClick={onCloseAddApplication}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] font-medium text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={onAssignApplications}\r\n disabled={selectedAppIds.length === 0 || assigningApps}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {assigningApps ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Plus className=\"w-4 h-4\" />}\r\n {t('tenants.applications.modal.assign')}\r\n {selectedAppIds.length > 0 && ` (${selectedAppIds.length})`}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Customize Access Drawer */}\r\n {customizingApp && (\r\n <ApplicationAccessCustomizeDrawer\r\n application={customizingApp}\r\n tenantId={tenantId}\r\n tenantName={tenantName}\r\n isOpen={showCustomizeDrawer}\r\n onClose={onCloseCustomizeDrawer}\r\n mode={mode}\r\n onSaved={async () => {\r\n await onRefresh();\r\n onCloseCustomizeDrawer();\r\n }}\r\n />\r\n )}\r\n\r\n {/* Remove Application Confirmation */}\r\n {removeConfirm.app && (\r\n <ConfirmModal\r\n isOpen={removeConfirm.show}\r\n title={t('tenants.applications.removeConfirm.title')}\r\n message={\r\n <div className=\"space-y-3 text-left\">\r\n <p>{t('tenants.applications.removeConfirm.message', { name: removeConfirm.app.label })}</p>\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {t('tenants.applications.removeConfirm.impactTitle')}\r\n </p>\r\n <ul className=\"text-sm text-[var(--text-secondary)] space-y-1\">\r\n <li>\r\n {t('tenants.applications.removeConfirm.impactModules', {\r\n count: removeConfirm.app.totalModuleCount,\r\n })}\r\n </li>\r\n <li>\r\n {t('tenants.applications.removeConfirm.impactSections', {\r\n count: removeConfirm.app.totalSectionCount,\r\n })}\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n }\r\n variant=\"danger\"\r\n confirmLabel={t('tenants.applications.remove')}\r\n loading={removeConfirm.loading}\r\n onConfirm={async () => {\r\n if (!onRemoveApplication || !removeConfirm.app) return;\r\n setRemoveConfirm(prev => ({ ...prev, loading: true }));\r\n try {\r\n await onRemoveApplication(removeConfirm.app.applicationId);\r\n } finally {\r\n setRemoveConfirm({ show: false, app: null, loading: false });\r\n }\r\n }}\r\n onCancel={() => setRemoveConfirm({ show: false, app: null, loading: false })}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useMemo, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useParams, useNavigate } from 'react-router-dom';\r\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\r\nimport { useTenantDetail } from '@/hooks/useTenantDetail';\r\nimport { useTenantMembers } from '@/hooks/useTenantMembers';\r\nimport { useTenantGroups } from '@/hooks/useTenantGroups';\r\nimport { useTenantApplications } from '@/hooks/useTenantApplications';\r\nimport { useTenantOrganisation } from '@/hooks/useTenantOrganisation';\r\nimport { useTenantRoles } from '@/hooks/useTenantRoles';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { useNavigation } from '@/contexts/NavigationContext';\r\nimport {\r\n Building2,\r\n ArrowLeft,\r\n RefreshCw,\r\n Loader2,\r\n AlertTriangle,\r\n PlayCircle,\r\n PauseCircle,\r\n Archive,\r\n Settings,\r\n} from 'lucide-react';\r\nimport { TenantOverviewTab, TenantMembersTab, TenantGroupsTab, TenantRolesTab, TenantApplicationsTab } from '@/components/platform/administration/tenants';\r\nimport { AccessRequestsListTab } from '@/components/platform/administration/access-requests';\r\nimport { useAccessRequests } from '@/hooks/useAccessRequests';\r\nimport { ConfirmModal, type ConfirmVariant } from '@/components/ui/ConfirmModal';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { adminApi, type TenantStatus } from '@/services/api/adminApi';\r\n\r\nconst VALID_TABS = ['overview', 'members', 'groups', 'roles', 'applications', 'requests'] as const;\r\ntype TabType = typeof VALID_TABS[number];\r\n\r\nconst STATUS_CONFIG: Record<TenantStatus, { color: string; bgColor: string; borderColor: string }> = {\r\n Pending: {\r\n color: 'text-[var(--info-text)]',\r\n bgColor: 'bg-[var(--info-bg)]',\r\n borderColor: 'border-[var(--info-border)]'\r\n },\r\n Active: {\r\n color: 'text-[var(--success-text)]',\r\n bgColor: 'bg-[var(--success-bg)]',\r\n borderColor: 'border-[var(--success-border)]'\r\n },\r\n Suspended: {\r\n color: 'text-[var(--warning-text)]',\r\n bgColor: 'bg-[var(--warning-bg)]',\r\n borderColor: 'border-[var(--warning-border)]'\r\n },\r\n Archived: {\r\n color: 'text-[var(--text-tertiary)]',\r\n bgColor: 'bg-[var(--bg-tertiary)]',\r\n borderColor: 'border-[var(--border-color)]'\r\n }\r\n};\r\n\r\nexport function TenantDetailPage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const { id: tenantId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const { activeTab, setActiveTab } = useTabNavigation<TabType>('overview', VALID_TABS);\r\n\r\n const { refreshTenants, currentTenant } = useTenant();\r\n const { refreshMenu } = useNavigation();\r\n\r\n // Hooks for managing tenant data\r\n const tenantDetail = useTenantDetail(tenantId);\r\n const tenantMembers = useTenantMembers(tenantId);\r\n const tenantGroups = useTenantGroups(tenantId);\r\n const handleApplicationsChanged = useCallback(() => {\r\n // Refresh menu if we're editing the current tenant's applications\r\n if (currentTenant && tenantId === currentTenant.id) {\r\n refreshMenu();\r\n }\r\n }, [currentTenant, tenantId, refreshMenu]);\r\n\r\n const tenantAppOptions = useMemo(() => ({\r\n onApplicationsChanged: handleApplicationsChanged,\r\n }), [handleApplicationsChanged]);\r\n\r\n const tenantApplications = useTenantApplications(tenantId, tenantAppOptions);\r\n const tenantRoles = useTenantRoles(tenantId);\r\n const tenantOrganisation = useTenantOrganisation(tenantId);\r\n const accessRequests = useAccessRequests('tenant', tenantId!);\r\n\r\n // Minimal state needed in page\r\n const [actionLoading, setActionLoading] = useState<string | null>(null);\r\n const [confirmModal, setConfirmModal] = useState<{\r\n show: boolean;\r\n title: string;\r\n message: string;\r\n variant: ConfirmVariant;\r\n onConfirm: () => void;\r\n }>({\r\n show: false,\r\n title: '',\r\n message: '',\r\n variant: 'warning',\r\n onConfirm: () => {},\r\n });\r\n\r\n // Track which tabs have been loaded to avoid re-fetching\r\n const [loadedTabs, setLoadedTabs] = useState<Set<string>>(new Set());\r\n\r\n // Load tenant detail on mount\r\n useEffect(() => {\r\n if (!tenantId) {\r\n navigate('/administration/tenants');\r\n return;\r\n }\r\n tenantDetail.loadTenant();\r\n }, [tenantId]);\r\n\r\n // Lazy load tab data only when the tab is first selected\r\n useEffect(() => {\r\n if (!tenantId || loadedTabs.has(activeTab)) return;\r\n\r\n const loadTabData = async () => {\r\n switch (activeTab) {\r\n case 'overview':\r\n // Overview uses tenant detail (already loaded) + members for owner\r\n if (!loadedTabs.has('members')) {\r\n await tenantMembers.loadMembers();\r\n setLoadedTabs(prev => new Set(prev).add('members'));\r\n }\r\n break;\r\n case 'members':\r\n await tenantMembers.loadMembers();\r\n break;\r\n case 'groups':\r\n await tenantGroups.loadGroups();\r\n break;\r\n case 'roles':\r\n await tenantRoles.loadRoles();\r\n break;\r\n case 'applications':\r\n await tenantApplications.loadApplications();\r\n break;\r\n case 'requests':\r\n await accessRequests.loadRequests();\r\n break;\r\n }\r\n setLoadedTabs(prev => new Set(prev).add(activeTab));\r\n };\r\n\r\n loadTabData();\r\n }, [activeTab, tenantId]);\r\n\r\n const handleStatusChange = async (newStatus: TenantStatus) => {\r\n if (!tenantDetail.tenant) return;\r\n\r\n const currentStatus = tenantDetail.tenant.status;\r\n if (currentStatus === newStatus) return;\r\n\r\n const statusMessages: Record<TenantStatus, string> = {\r\n Active: t('admin:tenants.confirmActivate'),\r\n Suspended: t('admin:tenants.confirmSuspend'),\r\n Archived: t('admin:tenants.confirmArchive'),\r\n Pending: t('admin:tenants.confirmPending'),\r\n };\r\n\r\n setConfirmModal({\r\n show: true,\r\n title: t('common:confirm'),\r\n message: statusMessages[newStatus],\r\n variant: newStatus === 'Archived' ? 'danger' : 'warning',\r\n onConfirm: async () => {\r\n setActionLoading(newStatus);\r\n try {\r\n if (newStatus === 'Active') {\r\n await adminApi.tenants.activate(tenantDetail.tenant!.id);\r\n } else if (newStatus === 'Suspended') {\r\n await adminApi.tenants.suspend(tenantDetail.tenant!.id);\r\n } else if (newStatus === 'Archived') {\r\n await adminApi.tenants.archive(tenantDetail.tenant!.id);\r\n }\r\n await refreshTenants();\r\n await tenantDetail.loadTenant();\r\n } catch (error) {\r\n console.error('Failed to update tenant status:', error);\r\n } finally {\r\n setActionLoading(null);\r\n setConfirmModal({ ...confirmModal, show: false });\r\n }\r\n },\r\n });\r\n };\r\n\r\n const handleRefresh = async () => {\r\n setActionLoading('refresh');\r\n try {\r\n const promises: Promise<void>[] = [tenantDetail.loadTenant()];\r\n switch (activeTab) {\r\n case 'overview':\r\n promises.push(tenantMembers.loadMembers());\r\n break;\r\n case 'members':\r\n promises.push(tenantMembers.loadMembers());\r\n break;\r\n case 'groups':\r\n promises.push(tenantGroups.loadGroups());\r\n break;\r\n case 'roles':\r\n promises.push(tenantRoles.loadRoles());\r\n break;\r\n case 'applications':\r\n promises.push(tenantApplications.loadApplications());\r\n break;\r\n case 'requests':\r\n promises.push(accessRequests.loadRequests());\r\n break;\r\n }\r\n await Promise.all(promises);\r\n } finally {\r\n setActionLoading(null);\r\n }\r\n };\r\n\r\n if (tenantDetail.loading) {\r\n return (\r\n <div className=\"p-6 flex items-center justify-center min-h-screen\">\r\n <div className=\"text-center\">\r\n <Loader2 className=\"w-8 h-8 animate-spin mx-auto mb-2 text-[var(--text-secondary)]\" />\r\n <p className=\"text-[var(--text-secondary)]\">{t('common:loading')}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!tenantDetail.tenant) {\r\n return (\r\n <div className=\"p-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n ]}\r\n />\r\n <div className=\"mt-4 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{tenantDetail.error || t('admin:tenants.notFound')}</span>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const tenant = tenantDetail.tenant;\r\n const statusConfig = STATUS_CONFIG[tenant.status];\r\n const getStatusIcon = (status: TenantStatus) => {\r\n switch (status) {\r\n case 'Active': return <PlayCircle className=\"w-4 h-4\" />;\r\n case 'Suspended': return <PauseCircle className=\"w-4 h-4\" />;\r\n case 'Archived': return <Archive className=\"w-4 h-4\" />;\r\n default: return <Building2 className=\"w-4 h-4\" />;\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n { label: tenant.name }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/tenants')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div className=\"flex-1\">\r\n <h1 className=\"text-xl sm:text-2xl font-bold text-[var(--text-primary)]\">{tenant.name}</h1>\r\n <p className=\"text-sm sm:text-base text-[var(--text-secondary)]\">{tenant.slug}</p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className={`px-3 py-1 rounded-[var(--radius-badge)] text-sm flex items-center gap-2 ${statusConfig.bgColor} ${statusConfig.color} border ${statusConfig.borderColor}`}>\r\n {getStatusIcon(tenant.status)}\r\n {t(`admin:tenants.status.${tenant.status.toLowerCase()}`)}\r\n </span>\r\n <span className={`px-3 py-1 rounded-[var(--radius-badge)] text-sm ${\r\n tenant.type === 'Business'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--accent-bg)] text-[var(--accent-text)]'\r\n }`}>\r\n {t(`admin:tenants.type.${tenant.type.toLowerCase()}`)}\r\n </span>\r\n {tenant.status !== 'Active' && tenant.status !== 'Archived' && (\r\n <button\r\n onClick={() => handleStatusChange('Active')}\r\n disabled={actionLoading !== null}\r\n className=\"flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--success-dot)] text-white hover:opacity-90 transition-colors disabled:opacity-50\"\r\n >\r\n {actionLoading === 'Active' ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <PlayCircle className=\"w-4 h-4\" />}\r\n {t('admin:tenants.actions.activate')}\r\n </button>\r\n )}\r\n {tenant.status === 'Active' && (\r\n <button\r\n onClick={() => handleStatusChange('Suspended')}\r\n disabled={actionLoading !== null}\r\n className=\"flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--warning-dot)] text-white hover:opacity-90 transition-colors disabled:opacity-50\"\r\n >\r\n {actionLoading === 'Suspended' ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <PauseCircle className=\"w-4 h-4\" />}\r\n {t('admin:tenants.actions.suspend')}\r\n </button>\r\n )}\r\n <button\r\n onClick={() => navigate(`/administration/tenants/${tenantId}/settings`)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n title={t('admin:tenants.settings.title')}\r\n >\r\n <Settings className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <button\r\n onClick={handleRefresh}\r\n disabled={actionLoading === 'refresh'}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors disabled:opacity-50\"\r\n title={t('common:refresh')}\r\n >\r\n <RefreshCw className={`w-5 h-5 ${actionLoading === 'refresh' ? 'animate-spin' : ''}`} />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Error */}\r\n {tenantDetail.error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{tenantDetail.error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Tab Navigation */}\r\n <div className=\"border-b border-[var(--border-color)]\">\r\n <div className=\"flex gap-1 -mb-px\">\r\n {VALID_TABS.map(tab => (\r\n <button\r\n key={tab}\r\n onClick={() => setActiveTab(tab)}\r\n className={`px-4 py-2 border-b-2 transition-colors ${\r\n activeTab === tab\r\n ? 'border-[var(--primary-color)] text-[var(--primary-color)]'\r\n : 'border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n >\r\n {t(`admin:tenants.tabs.${tab}`)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Tab Content */}\r\n <div>\r\n {activeTab === 'overview' && (\r\n <TenantOverviewTab\r\n tenant={tenant}\r\n tenantOwner={(() => {\r\n const owner = tenantMembers.members?.find(m => m.isOwner);\r\n return owner ? { userDisplayName: owner.userDisplayName ?? undefined, userEmail: owner.userEmail ?? undefined } : null;\r\n })()}\r\n statusConfig={STATUS_CONFIG}\r\n actionLoading={actionLoading}\r\n onRefresh={handleRefresh}\r\n onEditClick={tenantDetail.openEditGeneralInfo}\r\n onStatusChange={(action) => {\r\n const statusMap: Record<string, TenantStatus> = {\r\n activate: 'Active',\r\n suspend: 'Suspended',\r\n archive: 'Archived'\r\n };\r\n handleStatusChange(statusMap[action]);\r\n }}\r\n onMembersTabClick={() => setActiveTab('members')}\r\n onLinkOrgClick={tenantOrganisation.openLinkOrgModal}\r\n onUnlinkOrg={tenantOrganisation.handleUnlinkOrganisation}\r\n />\r\n )}\r\n\r\n {activeTab === 'members' && (\r\n <TenantMembersTab\r\n tenantId={tenantId!}\r\n members={tenantMembers.members}\r\n loadingMembers={tenantMembers.loadingMembers}\r\n actionLoading={actionLoading}\r\n onRefresh={tenantMembers.loadMembers}\r\n onRemoveMember={tenantMembers.handleRemoveMember}\r\n />\r\n )}\r\n\r\n {activeTab === 'groups' && (\r\n <TenantGroupsTab\r\n tenantId={tenantId!}\r\n groups={tenantGroups.groups}\r\n loadingGroups={tenantGroups.loadingGroups}\r\n removingGroupId={tenantGroups.removingGroupId}\r\n onRefresh={tenantGroups.loadGroups}\r\n onRemoveGroup={tenantGroups.handleRemoveGroup}\r\n />\r\n )}\r\n\r\n {activeTab === 'roles' && (\r\n <TenantRolesTab\r\n roles={tenantRoles.roles}\r\n loadingRoles={tenantRoles.loadingRoles}\r\n />\r\n )}\r\n\r\n {activeTab === 'applications' && (\r\n <TenantApplicationsTab\r\n tenantId={tenantId!}\r\n tenantName={tenant.name}\r\n applications={tenantApplications.applications}\r\n loadingApps={tenantApplications.loadingApps}\r\n actionLoading={actionLoading}\r\n onRefresh={tenantApplications.loadApplications}\r\n onUpdateAccessLevel={tenantApplications.handleUpdateAccessLevel}\r\n // Add application modal state\r\n addingApplication={tenantApplications.addingApplication}\r\n availableAppsError={tenantApplications.availableAppsError}\r\n filteredAvailableApps={tenantApplications.filteredAvailableApps}\r\n loadingAvailableApps={tenantApplications.loadingAvailableApps}\r\n selectedAppIds={tenantApplications.selectedAppIds}\r\n assigningApps={tenantApplications.assigningApps}\r\n appSearchTerm={tenantApplications.appSearchTerm}\r\n selectedAccessLevel={tenantApplications.selectedAccessLevel}\r\n bulkAccessMode={tenantApplications.bulkAccessMode}\r\n bulkModules={tenantApplications.bulkModules}\r\n bulkExpandedModules={tenantApplications.bulkExpandedModules}\r\n loadingBulkModules={tenantApplications.loadingBulkModules}\r\n // Customize drawer state\r\n showCustomizeDrawer={tenantApplications.showCustomizeDrawer}\r\n customizingApp={tenantApplications.customizingApp}\r\n // Actions\r\n onOpenAddApplication={tenantApplications.loadAvailableApps}\r\n onCloseAddApplication={() => {\r\n tenantApplications.setAddingApplication(false);\r\n tenantApplications.setSelectedAppIds([]);\r\n tenantApplications.setAppSearchTerm('');\r\n tenantApplications.setSelectedAccessLevel('FullAccess');\r\n tenantApplications.setBulkAccessMode('full');\r\n tenantApplications.setBulkModules([]);\r\n tenantApplications.setBulkExpandedModules(new Set());\r\n }}\r\n onAssignApplications={tenantApplications.handleAssignApplications}\r\n onAppToggle={tenantApplications.handleAppToggle}\r\n onSelectAllApps={tenantApplications.selectAllFilteredApps}\r\n onClearAppSelection={tenantApplications.clearAppSelection}\r\n onOpenCustomizeDrawer={tenantApplications.openCustomizeDrawer}\r\n onCloseCustomizeDrawer={tenantApplications.closeCustomizeDrawer}\r\n // Module handlers\r\n onLoadBulkModules={tenantApplications.loadBulkModulesForApp}\r\n onToggleBulkModuleExpand={tenantApplications.toggleBulkModuleExpand}\r\n onToggleBulkModule={tenantApplications.toggleBulkModule}\r\n onToggleBulkSection={tenantApplications.toggleBulkSection}\r\n onGetBulkModuleCheckState={tenantApplications.getBulkModuleCheckState}\r\n onGetBulkStats={tenantApplications.getBulkStats}\r\n onSelectAllBulkModules={tenantApplications.selectAllBulkModules}\r\n onClearBulkModules={tenantApplications.clearBulkModules}\r\n // Setters\r\n setAppSearchTerm={tenantApplications.setAppSearchTerm}\r\n setSelectedAccessLevel={tenantApplications.setSelectedAccessLevel}\r\n setBulkAccessMode={tenantApplications.setBulkAccessMode}\r\n />\r\n )}\r\n\r\n {activeTab === 'requests' && (\r\n <AccessRequestsListTab\r\n requests={accessRequests.requests}\r\n loading={accessRequests.loading}\r\n onReload={() => accessRequests.loadRequests()}\r\n />\r\n )}\r\n </div>\r\n\r\n {/* Organisation Linking Modal - handled by useTenantOrganisation hook */}\r\n {tenantOrganisation.showLinkOrgModal && (\r\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] p-6 max-w-md w-full mx-4\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)] mb-4\">\r\n {t('admin:tenants.organisation.linkTitle')}\r\n </h2>\r\n <p className=\"text-[var(--text-secondary)] mb-4\">\r\n {t('admin:tenants.organisation.linkDescription')}\r\n </p>\r\n <div className=\"flex gap-2 justify-end\">\r\n <button\r\n onClick={tenantOrganisation.closeLinkOrgModal}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={() => {\r\n tenantOrganisation.openLinkOrgModal();\r\n tenantDetail.loadTenant();\r\n }}\r\n disabled={tenantOrganisation.linkingOrg}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--primary-color)] text-white hover:opacity-90 disabled:opacity-50\"\r\n >\r\n {tenantOrganisation.linkingOrg ? t('common:loading') : t('admin:tenants.organisation.link')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Confirm Modal */}\r\n {confirmModal.show && (\r\n <ConfirmModal\r\n title={confirmModal.title}\r\n message={confirmModal.message}\r\n variant={confirmModal.variant}\r\n isOpen={confirmModal.show}\r\n onConfirm={() => {\r\n confirmModal.onConfirm();\r\n }}\r\n onCancel={() => {\r\n setConfirmModal({ ...confirmModal, show: false });\r\n }}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate, useSearchParams } from 'react-router-dom';\r\nimport {\r\n ArrowLeft,\r\n Building2,\r\n User,\r\n Building,\r\n Loader2,\r\n AlertCircle,\r\n AlertTriangle,\r\n Check,\r\n Hash,\r\n FileText,\r\n UserPlus,\r\n Info,\r\n MapPin,\r\n Phone,\r\n Mail,\r\n Globe,\r\n FileCheck,\r\n Zap,\r\n Search,\r\n Link,\r\n} from 'lucide-react';\r\nimport {\r\n adminApi,\r\n type CreateTenantB2CRequest,\r\n type CreateTenantB2BRequest,\r\n type CreateOrganisationRequest,\r\n type BusinessIdentifierType,\r\n type TenantType,\r\n type OrganisationListItemDto,\r\n} from '@/services/api/adminApi';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\n\r\n// Business Identifier Type options\r\nconst BUSINESS_IDENTIFIER_TYPES: { value: BusinessIdentifierType; label: string; country: string }[] = [\r\n { value: 'UID_CHE', label: 'CHE/IDE (Suisse)', country: 'CH' },\r\n { value: 'VAT', label: 'VAT (EU)', country: 'EU' },\r\n { value: 'SIRET', label: 'SIRET (France)', country: 'FR' },\r\n { value: 'SIREN', label: 'SIREN (France)', country: 'FR' },\r\n { value: 'KVK', label: 'KVK (Netherlands)', country: 'NL' },\r\n { value: 'CRN', label: 'CRN (UK)', country: 'GB' },\r\n { value: 'ABN', label: 'ABN (Australia)', country: 'AU' },\r\n { value: 'Other', label: 'Other', country: '' },\r\n];\r\n\r\ntype OrganisationMode = 'none' | 'create' | 'existing';\r\n\r\nfunction getTenantTypeFromUrl(typeFromUrl: string | null): TenantType {\r\n return typeFromUrl === 'b2b' ? 'Business' : 'Personal';\r\n}\r\n\r\nfunction applyConfigTypeRestrictions(config: { enableB2B: boolean; enableB2C: boolean }): TenantType {\r\n if (!config.enableB2C) return 'Business';\r\n if (!config.enableB2B) return 'Personal';\r\n return 'Personal';\r\n}\r\n\r\nfunction buildOrganisationRequest(\r\n orgName: string,\r\n orgLegalName: string,\r\n orgCountryCode: string,\r\n orgBusinessIdType: BusinessIdentifierType,\r\n orgBusinessId: string,\r\n orgVatNumber: string,\r\n addrStreet: string,\r\n addrStreet2: string,\r\n addrPostalCode: string,\r\n addrCity: string,\r\n addrState: string,\r\n addrCountry: string,\r\n addrCountryCode: string,\r\n orgPhone: string,\r\n orgEmail: string,\r\n orgWebsite: string,\r\n isFromRegistry: boolean = false\r\n): CreateOrganisationRequest {\r\n return {\r\n name: orgName,\r\n legalName: orgLegalName || undefined,\r\n countryCode: orgCountryCode,\r\n businessIdentifierType: orgBusinessIdType,\r\n businessIdentifier: orgBusinessId,\r\n vatNumber: orgVatNumber || undefined,\r\n address: {\r\n street: addrStreet,\r\n street2: addrStreet2 || undefined,\r\n postalCode: addrPostalCode,\r\n city: addrCity,\r\n state: addrState || undefined,\r\n country: addrCountry,\r\n countryCode: addrCountryCode,\r\n },\r\n phone: orgPhone || undefined,\r\n email: orgEmail || undefined,\r\n website: orgWebsite || undefined,\r\n isFromRegistry: isFromRegistry || undefined,\r\n };\r\n}\r\n\r\nexport function TenantCreatePage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const navigate = useNavigate();\r\n const [searchParams] = useSearchParams();\r\n const { refreshTenants } = useTenant();\r\n const typeFromUrl = searchParams.get('type');\r\n const organisationIdFromUrl = searchParams.get('organisationId');\r\n\r\n const [enableB2B, setEnableB2B] = useState<boolean | null>(null);\r\n const [enableB2C, setEnableB2C] = useState<boolean | null>(null);\r\n const [tenantType, setTenantType] = useState<TenantType>(getTenantTypeFromUrl(typeFromUrl));\r\n const [organisationMode, setOrganisationMode] = useState<OrganisationMode>(organisationIdFromUrl ? 'existing' : 'none');\r\n const [loading, setLoading] = useState(false);\r\n const [configLoading, setConfigLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [lookupLoading, setLookupLoading] = useState(false);\r\n const [lookupError, setLookupError] = useState<string | null>(null);\r\n const [lookupSuccess, setLookupSuccess] = useState(false);\r\n const [isFromRegistry, setIsFromRegistry] = useState(false);\r\n\r\n // Existing organisation selection state\r\n const [selectedOrganisation, setSelectedOrganisation] = useState<OrganisationListItemDto | null>(null);\r\n const [availableOrganisations, setAvailableOrganisations] = useState<OrganisationListItemDto[]>([]);\r\n const [orgSearchQuery, setOrgSearchQuery] = useState('');\r\n const [orgSearchLoading, setOrgSearchLoading] = useState(false);\r\n\r\n // Load multitenant config on mount\r\n useEffect(() => {\r\n const loadConfig = async () => {\r\n try {\r\n const config = await adminApi.tenants.getConfig();\r\n setEnableB2B(config.enableB2B);\r\n setEnableB2C(config.enableB2C);\r\n if (!organisationIdFromUrl) {\r\n setTenantType(applyConfigTypeRestrictions(config));\r\n }\r\n } catch (err) {\r\n console.error('Failed to load tenant config:', err);\r\n // Default to both enabled if config fails\r\n setEnableB2B(true);\r\n setEnableB2C(true);\r\n } finally {\r\n setConfigLoading(false);\r\n }\r\n };\r\n loadConfig();\r\n }, []);\r\n\r\n // Load organisation from URL param\r\n useEffect(() => {\r\n if (!organisationIdFromUrl) return;\r\n const loadOrganisation = async () => {\r\n try {\r\n const org = await adminApi.organisations.getById(organisationIdFromUrl);\r\n setSelectedOrganisation({\r\n id: org.id,\r\n name: org.name,\r\n legalName: org.legalName,\r\n countryCode: org.countryCode,\r\n businessIdentifier: org.businessIdentifier,\r\n businessIdentifierType: org.businessIdentifierType as OrganisationListItemDto['businessIdentifierType'],\r\n verificationStatus: org.verificationStatus as OrganisationListItemDto['verificationStatus'],\r\n verifiedAt: org.verifiedAt,\r\n createdAt: org.createdAt,\r\n });\r\n // Pre-fill tenant name from org name\r\n if (!name) {\r\n handleNameChange(org.name);\r\n }\r\n } catch (err) {\r\n console.error('Failed to load organisation:', err);\r\n }\r\n };\r\n loadOrganisation();\r\n }, [organisationIdFromUrl]);\r\n\r\n // Search available organisations\r\n useEffect(() => {\r\n if (organisationMode !== 'existing') return;\r\n const searchOrganisations = async () => {\r\n setOrgSearchLoading(true);\r\n try {\r\n const results = await adminApi.organisations.getAvailable(orgSearchQuery || undefined);\r\n setAvailableOrganisations(results);\r\n } catch (err) {\r\n console.error('Failed to search organisations:', err);\r\n } finally {\r\n setOrgSearchLoading(false);\r\n }\r\n };\r\n const debounce = setTimeout(searchOrganisations, 300);\r\n return () => clearTimeout(debounce);\r\n }, [organisationMode, orgSearchQuery]);\r\n\r\n // Tenant fields\r\n const [name, setName] = useState('');\r\n const [slug, setSlug] = useState('');\r\n const [description, setDescription] = useState('');\r\n\r\n // Organisation fields (B2B only)\r\n const [orgName, setOrgName] = useState('');\r\n const [orgLegalName, setOrgLegalName] = useState('');\r\n const [orgCountryCode, setOrgCountryCode] = useState('CH');\r\n const [orgBusinessIdType, setOrgBusinessIdType] = useState<BusinessIdentifierType>('UID_CHE');\r\n const [orgBusinessId, setOrgBusinessId] = useState('CHE-'); // Pre-fill for Switzerland\r\n\r\n // Format CHE number: CHE-XXX.XXX.XXX\r\n const formatCheNumber = (value: string): string => {\r\n // Remove all non-alphanumeric characters except CHE prefix\r\n const cleaned = value.toUpperCase().replace(/[^A-Z0-9]/g, '');\r\n\r\n // Extract digits after CHE\r\n let digits = cleaned.startsWith('CHE') ? cleaned.slice(3) : cleaned.replace(/[^0-9]/g, '');\r\n digits = digits.slice(0, 9); // Max 9 digits\r\n\r\n // Format as CHE-XXX.XXX.XXX\r\n if (digits.length === 0) return 'CHE-';\r\n if (digits.length <= 3) return `CHE-${digits}`;\r\n if (digits.length <= 6) return `CHE-${digits.slice(0, 3)}.${digits.slice(3)}`;\r\n return `CHE-${digits.slice(0, 3)}.${digits.slice(3, 6)}.${digits.slice(6)}`;\r\n };\r\n\r\n const handleBusinessIdChange = (value: string) => {\r\n // Only format for CHE type\r\n if (orgBusinessIdType === 'UID_CHE' && orgCountryCode === 'CH') {\r\n setOrgBusinessId(formatCheNumber(value));\r\n } else {\r\n setOrgBusinessId(value);\r\n }\r\n setIsFromRegistry(false);\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n };\r\n\r\n // Update business ID when country or type changes\r\n useEffect(() => {\r\n if (orgCountryCode === 'CH' && orgBusinessIdType === 'UID_CHE') {\r\n // If empty or just \"CHE-\", keep the prefix\r\n if (!orgBusinessId || orgBusinessId === 'CHE-') {\r\n setOrgBusinessId('CHE-');\r\n } else {\r\n // Re-format existing value\r\n setOrgBusinessId(formatCheNumber(orgBusinessId));\r\n }\r\n }\r\n }, [orgCountryCode, orgBusinessIdType]);\r\n const [orgVatNumber, setOrgVatNumber] = useState('');\r\n const [orgPhone, setOrgPhone] = useState('');\r\n const [orgEmail, setOrgEmail] = useState('');\r\n const [orgWebsite, setOrgWebsite] = useState('');\r\n\r\n // Address fields\r\n const [addrStreet, setAddrStreet] = useState('');\r\n const [addrStreet2, setAddrStreet2] = useState('');\r\n const [addrPostalCode, setAddrPostalCode] = useState('');\r\n const [addrCity, setAddrCity] = useState('');\r\n const [addrState, setAddrState] = useState('');\r\n const [addrCountry, setAddrCountry] = useState('Switzerland');\r\n const [addrCountryCode, setAddrCountryCode] = useState('CH');\r\n\r\n const generateSlug = (value: string) => {\r\n return value\r\n .toLowerCase()\r\n .normalize('NFD')\r\n .replace(/[\\u0300-\\u036f]/g, '')\r\n .replace(/[^a-z0-9]+/g, '-')\r\n .replace(/(^-)|(-$)/g, '')\r\n .substring(0, 50);\r\n };\r\n\r\n const handleNameChange = (value: string) => {\r\n setName(value);\r\n if (!slug || slug === generateSlug(name)) {\r\n setSlug(generateSlug(value));\r\n }\r\n };\r\n\r\n const validateLookupInput = (): boolean => {\r\n const cleanedId = orgBusinessId.replace(/[^0-9]/g, '');\r\n if (!orgBusinessId || cleanedId.length < 9 || !orgCountryCode) {\r\n setLookupError(t('admin:tenants.create.organisation.lookupIncomplete'));\r\n return false;\r\n }\r\n return true;\r\n };\r\n\r\n const fillOrganisationFields = (result: Awaited<ReturnType<typeof adminApi.organisations.lookup>>) => {\r\n if (result.name) {\r\n setOrgName(result.name);\r\n if (!name) {\r\n handleNameChange(result.name);\r\n }\r\n }\r\n if (result.legalName) setOrgLegalName(result.legalName);\r\n if (result.vatNumber) setOrgVatNumber(result.vatNumber);\r\n if (result.phone) setOrgPhone(result.phone);\r\n if (result.email) setOrgEmail(result.email);\r\n if (result.website) setOrgWebsite(result.website);\r\n };\r\n\r\n const fillAddressFields = (result: Awaited<ReturnType<typeof adminApi.organisations.lookup>>) => {\r\n if (result.street) setAddrStreet(result.street);\r\n if (result.street2) setAddrStreet2(result.street2);\r\n if (result.postalCode) setAddrPostalCode(result.postalCode);\r\n if (result.city) setAddrCity(result.city);\r\n if (result.state) setAddrState(result.state);\r\n if (result.country) setAddrCountry(result.country);\r\n if (result.countryCode) setAddrCountryCode(result.countryCode);\r\n };\r\n\r\n const mapLookupError = (errorMessage: string): string => {\r\n if (errorMessage.includes('404') || errorMessage.includes('not found')) {\r\n return t('admin:tenants.create.organisation.lookupFailed');\r\n }\r\n if (errorMessage.includes('credentials') || errorMessage.includes('401')) {\r\n return t('admin:tenants.create.organisation.lookupAuthError');\r\n }\r\n return t('admin:tenants.create.organisation.lookupFailed');\r\n };\r\n\r\n const handleLookup = async () => {\r\n if (!validateLookupInput()) return;\r\n\r\n setLookupLoading(true);\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n\r\n try {\r\n const result = await adminApi.organisations.lookup(orgCountryCode, orgBusinessId);\r\n\r\n fillOrganisationFields(result);\r\n fillAddressFields(result);\r\n setIsFromRegistry(true);\r\n\r\n setLookupSuccess(true);\r\n setTimeout(() => setLookupSuccess(false), 3000);\r\n } catch (err: unknown) {\r\n console.error('[Zefix Lookup] Failed:', err);\r\n const errorMessage = err instanceof Error ? err.message : '';\r\n setLookupError(mapLookupError(errorMessage));\r\n } finally {\r\n setLookupLoading(false);\r\n }\r\n };\r\n\r\n const submitB2CTenant = async () => {\r\n const request: CreateTenantB2CRequest = {\r\n name,\r\n slug: slug || generateSlug(name),\r\n description: description || undefined,\r\n };\r\n const result = await adminApi.tenants.createB2C(request);\r\n await refreshTenants();\r\n navigate(`/administration/tenants/${result.id}`);\r\n };\r\n\r\n const submitB2BTenant = async () => {\r\n let request: CreateTenantB2BRequest;\r\n\r\n if (organisationMode === 'existing' && selectedOrganisation) {\r\n request = {\r\n name,\r\n slug: slug || generateSlug(name),\r\n description: description || undefined,\r\n organisationId: selectedOrganisation.id,\r\n };\r\n } else if (organisationMode === 'create') {\r\n const organisation = buildOrganisationRequest(\r\n orgName, orgLegalName, orgCountryCode, orgBusinessIdType, orgBusinessId,\r\n orgVatNumber, addrStreet, addrStreet2, addrPostalCode, addrCity, addrState,\r\n addrCountry, addrCountryCode, orgPhone, orgEmail, orgWebsite, isFromRegistry\r\n );\r\n request = {\r\n name,\r\n slug: slug || generateSlug(name),\r\n description: description || undefined,\r\n organisation,\r\n };\r\n } else {\r\n request = {\r\n name,\r\n slug: slug || generateSlug(name),\r\n description: description || undefined,\r\n };\r\n }\r\n\r\n const result = await adminApi.tenants.createB2B(request);\r\n await refreshTenants();\r\n navigate(`/administration/tenants/${result.id}`);\r\n };\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setError(null);\r\n setLoading(true);\r\n\r\n try {\r\n if (tenantType === 'Personal') {\r\n await submitB2CTenant();\r\n } else {\r\n await submitB2BTenant();\r\n }\r\n } catch (err: unknown) {\r\n console.error('Failed to create tenant:', err);\r\n const errorMessage = err instanceof Error ? err.message : t('admin:tenants.errors.createFailed');\r\n setError(errorMessage);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n const getOrganisationFormValidity = (): boolean => {\r\n if (organisationMode === 'existing') return !!selectedOrganisation;\r\n if (organisationMode !== 'create') return true;\r\n return !!(orgName && orgCountryCode && orgBusinessIdType && orgBusinessId &&\r\n addrStreet && addrPostalCode && addrCity && addrCountry && addrCountryCode);\r\n };\r\n\r\n const getB2BFormValidity = (): boolean => {\r\n if (tenantType !== 'Business') return true;\r\n return !!(name && getOrganisationFormValidity());\r\n };\r\n\r\n const isFormValid = !!(name && getB2BFormValidity());\r\n\r\n return (\r\n <div className=\"container mx-auto px-4 py-6 max-w-3xl\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('tenants.create.title') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4 mb-6\">\r\n <button\r\n onClick={() => navigate('/administration/tenants')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-secondary)]\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5\" />\r\n </button>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('admin:tenants.create.title')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.subtitle')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Error */}\r\n {error && (\r\n <div className=\"mb-6 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertCircle className=\"w-5 h-5 flex-shrink-0\" />\r\n <span>{error}</span>\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={() => setError(null)}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:dismiss')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n {/* Type Selection */}\r\n <div className=\"card p-6 mb-6\">\r\n <h2 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('admin:tenants.create.selectType')}\r\n </h2>\r\n\r\n {/* B2C Disabled Notice */}\r\n {!configLoading && enableB2C === false && (\r\n <div className=\"mb-4 p-3 rounded-[var(--radius-card)] bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--info-text)]\">\r\n <Info className=\"w-4 h-4 flex-shrink-0\" />\r\n <span className=\"text-sm\">{t('admin:tenants.create.b2cDisabledNotice')}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* B2B Disabled Notice */}\r\n {!configLoading && enableB2B === false && (\r\n <div className=\"mb-4 p-3 rounded-[var(--radius-card)] bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--info-text)]\">\r\n <Info className=\"w-4 h-4 flex-shrink-0\" />\r\n <span className=\"text-sm\">{t('admin:tenants.create.b2bDisabledNotice')}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {configLoading ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--text-tertiary)]\" />\r\n </div>\r\n ) : (\r\n <div className={`grid gap-4 ${enableB2C && enableB2B ? 'grid-cols-2' : 'grid-cols-1'}`}>\r\n {/* B2C Option - Only show if enabled */}\r\n {enableB2C && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setTenantType('Personal')}\r\n className={`p-4 rounded-[var(--radius-card)] border-2 transition-all text-left ${\r\n tenantType === 'Personal'\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-500)]/5'\r\n : 'border-[var(--border-color)] hover:border-[var(--border-color-hover)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className={`p-2 rounded-[var(--radius-button)] ${\r\n tenantType === 'Personal'\r\n ? 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n <User className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">{t('admin:tenants.type.b2c')}</p>\r\n </div>\r\n {tenantType === 'Personal' && (\r\n <Check className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.b2cDescription')}\r\n </p>\r\n </button>\r\n )}\r\n\r\n {/* B2B Option - Only show if enabled */}\r\n {enableB2B && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setTenantType('Business')}\r\n className={`p-4 rounded-[var(--radius-card)] border-2 transition-all text-left ${\r\n tenantType === 'Business'\r\n ? 'border-[var(--info-border)] bg-[var(--info-bg)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--border-color-hover)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className={`p-2 rounded-[var(--radius-button)] ${\r\n tenantType === 'Business'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n <Building className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">{t('admin:tenants.type.b2b')}</p>\r\n </div>\r\n {tenantType === 'Business' && (\r\n <Check className=\"w-5 h-5 text-[var(--info-text)]\" />\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.b2bDescription')}\r\n </p>\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Form */}\r\n <form onSubmit={handleSubmit} className=\"space-y-6\">\r\n {/* Tenant Details */}\r\n <div className=\"card p-6 space-y-6\">\r\n <h2 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('admin:tenants.create.details')}\r\n </h2>\r\n\r\n {/* Name */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <Building2 className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={name}\r\n onChange={(e) => handleNameChange(e.target.value)}\r\n placeholder={t('admin:tenants.create.namePlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required\r\n />\r\n </div>\r\n\r\n {/* Slug */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <Hash className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.slug')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={slug}\r\n onChange={(e) => setSlug(generateSlug(e.target.value))}\r\n placeholder={t('admin:tenants.create.slugPlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] font-mono placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1\">\r\n {t('admin:tenants.create.slugHelp')}\r\n </p>\r\n </div>\r\n\r\n {/* Description */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <FileText className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.description')}\r\n </label>\r\n <textarea\r\n value={description}\r\n onChange={(e) => setDescription(e.target.value)}\r\n placeholder={t('admin:tenants.create.descriptionPlaceholder')}\r\n rows={3}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* B2B: Organisation Mode Selection */}\r\n {tenantType === 'Business' && (\r\n <div className=\"card p-6 space-y-4\">\r\n <h2 className=\"text-lg font-semibold text-[var(--info-text)] flex items-center gap-2\">\r\n <Building className=\"w-5 h-5\" />\r\n {t('admin:tenants.create.organisation.title')}\r\n </h2>\r\n\r\n <div className=\"grid grid-cols-3 gap-4\">\r\n {/* Quick creation (no organisation) */}\r\n <button\r\n type=\"button\"\r\n onClick={() => setOrganisationMode('none')}\r\n className={`p-4 rounded-[var(--radius-card)] border-2 transition-all text-left ${\r\n organisationMode === 'none'\r\n ? 'border-[var(--success-border)] bg-[var(--success-bg)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--border-color-hover)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className={`p-2 rounded-[var(--radius-button)] ${\r\n organisationMode === 'none'\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n <Zap className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.create.organisation.quickMode')}\r\n </p>\r\n </div>\r\n {organisationMode === 'none' && (\r\n <Check className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.organisation.quickModeDescription')}\r\n </p>\r\n </button>\r\n\r\n {/* Existing organisation */}\r\n <button\r\n type=\"button\"\r\n onClick={() => setOrganisationMode('existing')}\r\n className={`p-4 rounded-[var(--radius-card)] border-2 transition-all text-left ${\r\n organisationMode === 'existing'\r\n ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-500)]/5'\r\n : 'border-[var(--border-color)] hover:border-[var(--border-color-hover)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className={`p-2 rounded-[var(--radius-button)] ${\r\n organisationMode === 'existing'\r\n ? 'bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n <Link className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.create.organisation.existingMode')}\r\n </p>\r\n </div>\r\n {organisationMode === 'existing' && (\r\n <Check className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.organisation.existingModeDescription')}\r\n </p>\r\n </button>\r\n\r\n {/* Create organisation */}\r\n <button\r\n type=\"button\"\r\n onClick={() => setOrganisationMode('create')}\r\n className={`p-4 rounded-[var(--radius-card)] border-2 transition-all text-left ${\r\n organisationMode === 'create'\r\n ? 'border-[var(--info-border)] bg-[var(--info-bg)]'\r\n : 'border-[var(--border-color)] hover:border-[var(--border-color-hover)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className={`p-2 rounded-[var(--radius-button)] ${\r\n organisationMode === 'create'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)]'\r\n }`}>\r\n <Building className=\"w-5 h-5\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.create.organisation.createMode')}\r\n </p>\r\n </div>\r\n {organisationMode === 'create' && (\r\n <Check className=\"w-5 h-5 text-[var(--info-text)]\" />\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.create.organisation.createModeDescription')}\r\n </p>\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* B2B: Existing Organisation Selection */}\r\n {tenantType === 'Business' && organisationMode === 'existing' && (\r\n <div className=\"card p-6 space-y-4\">\r\n <h2 className=\"text-lg font-semibold text-[var(--color-accent-600)] flex items-center gap-2\">\r\n <Link className=\"w-5 h-5\" />\r\n {t('admin:tenants.create.organisation.selectExisting')}\r\n </h2>\r\n\r\n {/* Selected organisation display */}\r\n {selectedOrganisation && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">{selectedOrganisation.name}</p>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {selectedOrganisation.businessIdentifier} — {selectedOrganisation.countryCode}\r\n </p>\r\n {selectedOrganisation.legalName && (\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{selectedOrganisation.legalName}</p>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={() => setSelectedOrganisation(null)}\r\n className=\"text-sm text-[var(--error-text)] hover:opacity-80\"\r\n >\r\n {t('common:remove')}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Search input */}\r\n {!selectedOrganisation && (\r\n <>\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-3 w-5 h-5 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={orgSearchQuery}\r\n onChange={(e) => setOrgSearchQuery(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.searchPlaceholder')}\r\n className=\"w-full pl-10 pr-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n {/* Results */}\r\n {orgSearchLoading && (\r\n <div className=\"flex items-center justify-center py-4\">\r\n <Loader2 className=\"w-5 h-5 animate-spin text-[var(--text-tertiary)]\" />\r\n </div>\r\n )}\r\n {!orgSearchLoading && availableOrganisations.length === 0 && (\r\n <p className=\"text-sm text-[var(--text-secondary)] text-center py-4\">\r\n {t('admin:tenants.create.organisation.noResults')}\r\n </p>\r\n )}\r\n {!orgSearchLoading && availableOrganisations.length > 0 && (\r\n <div className=\"border border-[var(--border-color)] rounded-[var(--radius-card)] overflow-hidden max-h-64 overflow-y-auto\">\r\n {availableOrganisations.map((org) => (\r\n <button\r\n key={org.id}\r\n type=\"button\"\r\n onClick={() => {\r\n setSelectedOrganisation(org);\r\n if (!name) {\r\n handleNameChange(org.name);\r\n }\r\n }}\r\n className=\"w-full text-left px-4 py-3 border-b border-[var(--border-color)] last:border-b-0 hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"font-medium text-sm text-[var(--text-primary)]\">{org.name}</p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">\r\n {org.businessIdentifier} — {org.countryCode}\r\n </p>\r\n </div>\r\n <span className={`text-xs px-2 py-1 rounded-[var(--radius-badge)] ${\r\n org.verificationStatus === 'Verified'\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : org.verificationStatus === 'Pending'\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n : 'bg-[var(--error-bg)] text-[var(--error-text)]'\r\n }`}>\r\n {t(`admin:organisations.status.${org.verificationStatus.toLowerCase()}`, org.verificationStatus)}\r\n </span>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* B2B: Organisation Details (only if creating) */}\r\n {tenantType === 'Business' && organisationMode === 'create' && (\r\n <div className=\"card p-6 space-y-6\">\r\n <h2 className=\"text-lg font-semibold text-[var(--info-text)] flex items-center gap-2\">\r\n <FileCheck className=\"w-5 h-5\" />\r\n {t('admin:tenants.create.organisation.details')}\r\n </h2>\r\n\r\n {/* Organisation Name */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={orgName}\r\n onChange={(e) => setOrgName(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.namePlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.legalName')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={orgLegalName}\r\n onChange={(e) => setOrgLegalName(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.legalNamePlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Business Identifier */}\r\n <div className=\"p-4 bg-[var(--info-bg)] rounded-[var(--radius-card)] border border-[var(--info-border)] space-y-4\">\r\n <h3 className=\"text-sm font-semibold text-[var(--info-text)] flex items-center gap-2\">\r\n <FileCheck className=\"w-4 h-4\" />\r\n {t('admin:tenants.create.organisation.businessId.title')}\r\n </h3>\r\n\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.businessId.type')} *\r\n </label>\r\n <select\r\n value={orgBusinessIdType}\r\n onChange={(e) => {\r\n const newType = e.target.value as BusinessIdentifierType;\r\n setOrgBusinessIdType(newType);\r\n // Auto-set country code based on identifier type\r\n const typeInfo = BUSINESS_IDENTIFIER_TYPES.find(t => t.value === newType);\r\n if (typeInfo?.country) {\r\n setOrgCountryCode(typeInfo.country);\r\n }\r\n }}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n >\r\n {BUSINESS_IDENTIFIER_TYPES.map((type) => (\r\n <option key={type.value} value={type.value}>\r\n {type.label}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.businessId.number')} *\r\n </label>\r\n <div className=\"relative flex\">\r\n <input\r\n type=\"text\"\r\n value={orgBusinessId}\r\n onChange={(e) => handleBusinessIdChange(e.target.value)}\r\n placeholder={orgBusinessIdType === 'UID_CHE' ? 'CHE-123.456.789' : t('admin:tenants.create.organisation.businessId.placeholder')}\r\n className=\"flex-1 px-4 py-2 pr-12 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] font-mono placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={handleLookup}\r\n disabled={lookupLoading || !orgBusinessId || orgBusinessId.replace(/[^0-9]/g, '').length < 9 || orgCountryCode !== 'CH'}\r\n className=\"absolute right-1 top-1 bottom-1 px-2.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center\"\r\n title={t('admin:tenants.create.organisation.lookupTitle')}\r\n >\r\n {lookupLoading ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Search className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n </div>\r\n {lookupError && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1 flex items-center gap-1\">\r\n <AlertTriangle className=\"w-3 h-3\" />\r\n {lookupError}\r\n </p>\r\n )}\r\n {lookupSuccess && (\r\n <p className=\"text-xs text-[var(--success-text)] mt-1 flex items-center gap-1\">\r\n <Check className=\"w-3 h-3\" />\r\n {t('admin:tenants.create.organisation.lookupSuccess')}\r\n </p>\r\n )}\r\n {orgCountryCode === 'CH' && orgBusinessIdType === 'UID_CHE' && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1\">\r\n {orgBusinessId.replace(/[^0-9]/g, '').length < 9\r\n ? t('admin:tenants.create.organisation.lookupHintIncomplete')\r\n : t('admin:tenants.create.organisation.lookupHint')}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.vatNumber')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={orgVatNumber}\r\n onChange={(e) => setOrgVatNumber(e.target.value)}\r\n placeholder=\"CHE-123.456.789 TVA\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] font-mono placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Address */}\r\n <div className=\"p-4 bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] space-y-4\">\r\n <h3 className=\"text-sm font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <MapPin className=\"w-4 h-4\" />\r\n {t('admin:tenants.create.organisation.address.title')} *\r\n </h3>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.street')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrStreet}\r\n onChange={(e) => setAddrStreet(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.address.streetPlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.street2')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrStreet2}\r\n onChange={(e) => setAddrStreet2(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.address.street2Placeholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.postalCode')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrPostalCode}\r\n onChange={(e) => setAddrPostalCode(e.target.value)}\r\n placeholder=\"1000\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n <div className=\"col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.city')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrCity}\r\n onChange={(e) => setAddrCity(e.target.value)}\r\n placeholder={t('admin:tenants.create.organisation.address.cityPlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.state')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrState}\r\n onChange={(e) => setAddrState(e.target.value)}\r\n placeholder=\"VD\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div className=\"grid grid-cols-2 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.country')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrCountry}\r\n onChange={(e) => setAddrCountry(e.target.value)}\r\n placeholder=\"Switzerland\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('admin:tenants.create.organisation.address.countryCode')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={addrCountryCode}\r\n onChange={(e) => setAddrCountryCode(e.target.value.toUpperCase().slice(0, 2))}\r\n placeholder=\"CH\"\r\n maxLength={2}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] uppercase\"\r\n required={organisationMode === 'create'}\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Contact Info */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <Phone className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.organisation.phone')}\r\n </label>\r\n <input\r\n type=\"tel\"\r\n value={orgPhone}\r\n onChange={(e) => setOrgPhone(e.target.value)}\r\n placeholder=\"+41 21 123 45 67\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <Mail className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.organisation.email')}\r\n </label>\r\n <input\r\n type=\"email\"\r\n value={orgEmail}\r\n onChange={(e) => setOrgEmail(e.target.value)}\r\n placeholder=\"contact@company.ch\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n <Globe className=\"w-4 h-4 inline mr-2\" />\r\n {t('admin:tenants.create.organisation.website')}\r\n </label>\r\n <input\r\n type=\"url\"\r\n value={orgWebsite}\r\n onChange={(e) => setOrgWebsite(e.target.value)}\r\n placeholder=\"https://www.company.ch\"\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Actions */}\r\n <div className=\"flex items-center justify-end gap-4 pt-4\">\r\n <button\r\n type=\"button\"\r\n onClick={() => navigate('/administration/tenants')}\r\n className=\"px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={loading || !isFormValid}\r\n className={`inline-flex items-center gap-2 px-6 py-2 text-sm font-medium rounded-[var(--radius-button)] text-white transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${\r\n tenantType === 'Business'\r\n ? organisationMode === 'none'\r\n ? 'bg-[var(--success-dot)] hover:opacity-90'\r\n : 'bg-[var(--info-dot)] hover:opacity-90'\r\n : 'bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)]'\r\n }`}\r\n >\r\n {loading ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <UserPlus className=\"w-4 h-4\" />\r\n )}\r\n {t('admin:tenants.create.submit')}\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n );\r\n}\r\n","import React, { useState } from 'react';\r\nimport {\r\n PieChart,\r\n Pie,\r\n Cell,\r\n ResponsiveContainer,\r\n Sector\r\n} from 'recharts';\r\nimport type { TopTenantDto } from '@/services/api/tenantAnalyticsApi';\r\nimport type { ChartMode } from './UsageTrendChart';\r\n\r\ninterface TenantActivityPieChartProps {\r\n readonly data: TopTenantDto[];\r\n readonly mode?: ChartMode;\r\n}\r\n\r\nconst COLORS = [\r\n '#3b82f6', // blue-500\r\n '#22c55e', // green-500\r\n '#f59e0b', // amber-500\r\n '#ef4444', // red-500\r\n '#8b5cf6', // violet-500\r\n '#06b6d4', // cyan-500\r\n '#ec4899', // pink-500\r\n '#f97316', // orange-500\r\n '#14b8a6', // teal-500\r\n '#6366f1', // indigo-500\r\n];\r\n\r\nconst renderActiveShape = (props: unknown) => {\r\n const {\r\n cx = 0,\r\n cy = 0,\r\n midAngle = 0,\r\n innerRadius = 0,\r\n outerRadius = 0,\r\n startAngle = 0,\r\n endAngle = 0,\r\n fill = '#8884d8',\r\n payload,\r\n percent = 0,\r\n value = 0\r\n } = props as {\r\n cx?: number;\r\n cy?: number;\r\n midAngle?: number;\r\n innerRadius?: number;\r\n outerRadius?: number;\r\n startAngle?: number;\r\n endAngle?: number;\r\n fill?: string;\r\n payload: { tenantName: string; tenantType: string };\r\n percent?: number;\r\n value?: number;\r\n };\r\n\r\n if (!payload) return <g />;\r\n const RADIAN = Math.PI / 180;\r\n const sin = Math.sin(-RADIAN * midAngle);\r\n const cos = Math.cos(-RADIAN * midAngle);\r\n const sx = cx + (outerRadius + 10) * cos;\r\n const sy = cy + (outerRadius + 10) * sin;\r\n const mx = cx + (outerRadius + 30) * cos;\r\n const my = cy + (outerRadius + 30) * sin;\r\n const ex = mx + (cos >= 0 ? 1 : -1) * 22;\r\n const ey = my;\r\n const textAnchor = cos >= 0 ? 'start' : 'end';\r\n\r\n return (\r\n <g>\r\n <text x={cx} y={cy} dy={-10} textAnchor=\"middle\" fill=\"var(--text-primary)\" style={{ fontSize: '14px', fontWeight: 'bold' }}>\r\n {payload.tenantName}\r\n </text>\r\n <text x={cx} y={cy} dy={10} textAnchor=\"middle\" fill=\"var(--text-secondary)\" style={{ fontSize: '12px' }}>\r\n {value.toLocaleString()} {payload.tenantType === '_duration' ? 'min' : 'accès'}\r\n </text>\r\n <Sector\r\n cx={cx}\r\n cy={cy}\r\n innerRadius={innerRadius}\r\n outerRadius={outerRadius}\r\n startAngle={startAngle}\r\n endAngle={endAngle}\r\n fill={fill}\r\n />\r\n <Sector\r\n cx={cx}\r\n cy={cy}\r\n startAngle={startAngle}\r\n endAngle={endAngle}\r\n innerRadius={outerRadius + 6}\r\n outerRadius={outerRadius + 10}\r\n fill={fill}\r\n />\r\n <path d={`M${sx},${sy}L${mx},${my}L${ex},${ey}`} stroke={fill} fill=\"none\" />\r\n <circle cx={ex} cy={ey} r={2} fill={fill} stroke=\"none\" />\r\n <text x={ex + (cos >= 0 ? 1 : -1) * 12} y={ey} textAnchor={textAnchor} fill=\"var(--text-primary)\" style={{ fontSize: '12px' }}>\r\n {`${(percent * 100).toFixed(0)}%`}\r\n </text>\r\n </g>\r\n );\r\n};\r\n\r\nexport const TenantActivityPieChart: React.FC<TenantActivityPieChartProps> = ({ data, mode = 'access' }) => {\r\n const [activeIndex, setActiveIndex] = useState(0);\r\n\r\n if (!data || data.length === 0) {\r\n return (\r\n <div className=\"flex items-center justify-center h-full text-[var(--text-secondary)]\">\r\n Aucune donnée d'activité disponible\r\n </div>\r\n );\r\n }\r\n\r\n const getValue = (tenant: TopTenantDto) =>\r\n mode === 'access' ? tenant.accessCount : tenant.totalDurationMinutes;\r\n\r\n const valueLabel = mode === 'access' ? 'accès' : 'min';\r\n const totalValue = data.reduce((sum, t) => sum + getValue(t), 0);\r\n\r\n const chartData = data.map((tenant, index) => ({\r\n ...tenant,\r\n // Encode mode into tenantType field for activeShape to read\r\n tenantType: mode === 'duration' ? '_duration' : tenant.tenantType,\r\n name: tenant.tenantName,\r\n value: getValue(tenant),\r\n fill: COLORS[index % COLORS.length]\r\n }));\r\n\r\n const onPieEnter = (_: unknown, index: number) => {\r\n setActiveIndex(index);\r\n };\r\n\r\n return (\r\n <div className=\"flex flex-col\">\r\n {/* Summary stats */}\r\n <div className=\"flex items-center gap-2 text-sm h-[34px]\">\r\n <span className=\"text-[var(--text-tertiary)]\">\r\n Vue globale des tenants actifs\r\n </span>\r\n </div>\r\n\r\n <div className=\"flex items-center justify-center gap-2\">\r\n <span className=\"text-lg font-semibold text-blue-600\">\r\n Tenants\r\n </span>\r\n <span className=\"text-[var(--text-secondary)]\">\r\n ({data.length} actifs • {totalValue.toLocaleString()} {valueLabel} total)\r\n </span>\r\n </div>\r\n\r\n {/* Pie Chart */}\r\n <div style={{ width: '100%', height: 350 }}>\r\n <ResponsiveContainer width=\"100%\" height={350}>\r\n <PieChart>\r\n <Pie\r\n {...{\r\n activeIndex,\r\n activeShape: renderActiveShape,\r\n data: chartData,\r\n cx: '50%',\r\n cy: '50%',\r\n innerRadius: 70,\r\n outerRadius: 110,\r\n fill: '#8884d8',\r\n dataKey: 'value',\r\n onMouseEnter: onPieEnter\r\n } as React.ComponentProps<typeof Pie>}\r\n >\r\n {chartData.map((entry) => (\r\n <Cell key={entry.tenantId} fill={entry.fill} />\r\n ))}\r\n </Pie>\r\n </PieChart>\r\n </ResponsiveContainer>\r\n </div>\r\n\r\n {/* Legend */}\r\n <div className=\"grid grid-cols-2 md:grid-cols-3 gap-2 max-h-[200px] overflow-y-auto\">\r\n {chartData.map((item, index) => (\r\n <button\r\n key={item.tenantId}\r\n onClick={() => setActiveIndex(index)}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n setActiveIndex(index);\r\n }\r\n }}\r\n className={`flex items-center gap-2 p-2 rounded-lg hover:bg-[var(--bg-secondary)] transition-colors cursor-pointer focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] ${\r\n activeIndex === index ? 'bg-[var(--bg-secondary)]' : ''\r\n }`}\r\n >\r\n <div\r\n className=\"w-3 h-3 rounded-full flex-shrink-0\"\r\n style={{ backgroundColor: item.fill }}\r\n />\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium truncate text-[var(--text-primary)]\">\r\n {item.tenantName}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">\r\n {getValue(data[index]).toLocaleString()} {valueLabel}\r\n </p>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\nimport {\r\n LineChart,\r\n Line,\r\n XAxis,\r\n YAxis,\r\n CartesianGrid,\r\n Tooltip,\r\n Legend,\r\n ResponsiveContainer\r\n} from 'recharts';\r\nimport { tenantAnalyticsApi } from '@/services/api/tenantAnalyticsApi';\r\nimport type { TenantTrendsDto, TenantSeriesDto } from '@/services/api/tenantAnalyticsApi';\r\nimport type { ChartMode } from './UsageTrendChart';\r\nimport { Loader2 } from 'lucide-react';\r\n\r\ninterface TenantUsageTrendChartProps {\r\n readonly period?: number;\r\n readonly mode?: ChartMode;\r\n}\r\n\r\nconst DEFAULT_COLORS = [\r\n '#3b82f6', // blue\r\n '#22c55e', // green\r\n '#f59e0b', // amber\r\n '#ef4444', // red\r\n '#8b5cf6', // violet\r\n '#06b6d4', // cyan\r\n '#ec4899', // pink\r\n];\r\n\r\ninterface LegendItemProps {\r\n readonly tenant: TenantSeriesDto;\r\n readonly index: number;\r\n readonly mode: ChartMode;\r\n readonly getColor: (tenant: TenantSeriesDto, index: number) => string;\r\n}\r\n\r\nfunction LegendItem({ tenant, index, mode, getColor }: LegendItemProps) {\r\n return (\r\n <div key={tenant.name} className=\"flex items-center gap-2\">\r\n <div\r\n className=\"w-3 h-3 rounded-full\"\r\n style={{ backgroundColor: getColor(tenant, index) }}\r\n />\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{tenant.name}</span>\r\n <span className=\"text-sm font-semibold\" style={{ color: getColor(tenant, index) }}>\r\n {mode === 'access' ? tenant.totalAccess : `${tenant.totalDurationMinutes} min`}\r\n </span>\r\n </div>\r\n );\r\n}\r\n\r\nexport const TenantUsageTrendChart: React.FC<TenantUsageTrendChartProps> = ({ period = 30, mode = 'access' }) => {\r\n const [data, setData] = useState<TenantTrendsDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n const fetchData = async () => {\r\n try {\r\n setLoading(true);\r\n const result = await tenantAnalyticsApi.getTrends(period);\r\n setData(result);\r\n setError(null);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load trends');\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n fetchData();\r\n }, [period]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-[300px]\">\r\n <Loader2 className=\"h-6 w-6 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error || !data) {\r\n return (\r\n <div className=\"flex items-center justify-center h-[300px] text-[var(--text-secondary)]\">\r\n {error || 'Aucune donnée disponible'}\r\n </div>\r\n );\r\n }\r\n\r\n if (!data?.dailyData?.length || !data?.tenants?.length) {\r\n return (\r\n <div className=\"flex items-center justify-center h-[300px] text-[var(--text-secondary)]\">\r\n Aucune donnée de tendance disponible\r\n </div>\r\n );\r\n }\r\n\r\n // Transform data for Recharts based on mode\r\n const chartData = data.dailyData.map((day) => {\r\n const entry: Record<string, string | number> = {\r\n date: new Date(day.date).toLocaleDateString('fr-FR', {\r\n day: '2-digit',\r\n month: 'short'\r\n })\r\n };\r\n data.tenants.forEach((tenant) => {\r\n if (mode === 'access') {\r\n entry[tenant.name] = day.tenantCounts[tenant.name] || 0;\r\n } else {\r\n entry[tenant.name] = day.tenantDurations?.[tenant.name] || 0;\r\n }\r\n });\r\n return entry;\r\n });\r\n\r\n const getColor = (tenant: TenantSeriesDto, index: number): string => {\r\n return tenant.color || DEFAULT_COLORS[index % DEFAULT_COLORS.length];\r\n };\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Chart */}\r\n <div style={{ width: '100%', height: 300 }}>\r\n <ResponsiveContainer width=\"100%\" height={300}>\r\n <LineChart\r\n data={chartData}\r\n margin={{ top: 5, right: 30, left: 20, bottom: 5 }}\r\n >\r\n <CartesianGrid\r\n strokeDasharray=\"3 3\"\r\n stroke=\"var(--border-color)\"\r\n />\r\n <XAxis\r\n dataKey=\"date\"\r\n stroke=\"var(--text-secondary)\"\r\n style={{ fontSize: '11px' }}\r\n tick={{ fill: 'var(--text-secondary)' }}\r\n />\r\n <YAxis\r\n stroke=\"var(--text-secondary)\"\r\n style={{ fontSize: '11px' }}\r\n tick={{ fill: 'var(--text-secondary)' }}\r\n label={{\r\n value: mode === 'access' ? 'Accès' : 'Minutes',\r\n angle: -90,\r\n position: 'insideLeft',\r\n style: { fill: 'var(--text-secondary)', fontSize: '11px' }\r\n }}\r\n />\r\n <Tooltip\r\n contentStyle={{\r\n backgroundColor: 'var(--bg-card)',\r\n border: '1px solid var(--border-color)',\r\n borderRadius: '8px',\r\n color: 'var(--text-primary)'\r\n }}\r\n labelStyle={{ color: 'var(--text-primary)', fontWeight: 'bold', marginBottom: '8px' }}\r\n itemStyle={{ color: 'var(--text-secondary)' }}\r\n />\r\n <Legend\r\n wrapperStyle={{\r\n paddingTop: '20px'\r\n }}\r\n formatter={(value) => (\r\n <span style={{ color: 'var(--text-secondary)', fontSize: '12px' }}>{value}</span>\r\n )}\r\n />\r\n {data.tenants.map((tenant, index) => (\r\n <Line\r\n key={tenant.name}\r\n type=\"monotone\"\r\n dataKey={tenant.name}\r\n stroke={getColor(tenant, index)}\r\n strokeWidth={2}\r\n dot={{ r: 2, fill: getColor(tenant, index) }}\r\n activeDot={{ r: 5, fill: getColor(tenant, index) }}\r\n />\r\n ))}\r\n </LineChart>\r\n </ResponsiveContainer>\r\n </div>\r\n\r\n {/* Legend with totals */}\r\n <div className=\"flex flex-wrap gap-4 justify-center border-t border-[var(--border-color)] pt-4\">\r\n {data.tenants.map((tenant, index) => (\r\n <LegendItem key={tenant.name} tenant={tenant} index={index} mode={mode} getColor={getColor} />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport { Users, Building2 } from 'lucide-react';\r\nimport type { TopTenantDto } from '@/services/api/tenantAnalyticsApi';\r\nimport type { ChartMode } from './UsageTrendChart';\r\n\r\ninterface TenantPopularityChartProps {\r\n readonly data: TopTenantDto[];\r\n readonly mode?: ChartMode;\r\n}\r\n\r\nconst tenantColors = [\r\n '#3b82f6',\r\n '#8b5cf6',\r\n '#22c55e',\r\n '#f59e0b',\r\n '#ef4444',\r\n '#06b6d4',\r\n '#ec4899',\r\n '#10b981',\r\n '#f97316',\r\n '#6366f1'\r\n];\r\n\r\nexport const TenantPopularityChart: React.FC<TenantPopularityChartProps> = ({ data, mode = 'access' }) => {\r\n if (!data || data.length === 0) {\r\n return (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n Aucune donnée de tenant disponible\r\n </div>\r\n );\r\n }\r\n\r\n const getValue = (tenant: TopTenantDto) =>\r\n mode === 'access' ? tenant.accessCount : tenant.totalDurationMinutes;\r\n const valueLabel = mode === 'access' ? 'accès' : 'min';\r\n\r\n const maxCount = Math.max(...data.map(t => getValue(t)), 1);\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n {data.map((tenant, index) => {\r\n const value = getValue(tenant);\r\n const percentage = (value / maxCount) * 100;\r\n\r\n return (\r\n <div\r\n key={tenant.tenantId}\r\n className=\"rounded-lg bg-[var(--bg-secondary)] p-4 hover:shadow-sm transition-shadow border-l-4\"\r\n style={{ borderLeftColor: tenantColors[index % tenantColors.length] }}\r\n >\r\n <div className=\"flex items-center gap-3 mb-2\">\r\n <div className=\"flex-1\">\r\n {/* Tenant type badge */}\r\n <div className=\"text-xs text-[var(--text-tertiary)] mb-1 font-mono\">\r\n <span className=\"text-blue-500\">{tenant.tenantType}</span>\r\n <span className=\"mx-1\">›</span>\r\n <span className=\"text-green-500\">{tenant.tenantSlug}</span>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <h5 className=\"font-semibold text-[var(--text-primary)]\">\r\n {tenant.tenantName}\r\n </h5>\r\n </div>\r\n </div>\r\n <div className=\"text-right\">\r\n <div className=\"text-xl font-bold\" style={{ color: tenantColors[index % tenantColors.length] }}>\r\n {value.toLocaleString()}\r\n </div>\r\n <div className=\"text-xs text-[var(--text-secondary)]\">{valueLabel}</div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"h-2 bg-[var(--bg-primary)] rounded-full overflow-hidden mb-2\">\r\n <div\r\n className=\"h-full rounded-full transition-all duration-500\"\r\n style={{\r\n width: `${percentage}%`,\r\n backgroundColor: tenantColors[index % tenantColors.length]\r\n }}\r\n />\r\n </div>\r\n\r\n <div className=\"flex items-center gap-4 text-xs text-[var(--text-secondary)]\">\r\n <div className=\"flex items-center gap-1\">\r\n <Users className=\"w-3 h-3\" />\r\n <span>{tenant.uniqueUsers} utilisateurs uniques</span>\r\n </div>\r\n <div className=\"flex items-center gap-1\">\r\n <Building2 className=\"w-3 h-3\" />\r\n <span>{tenant.tenantType}</span>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n","import type { ReactElement } from 'react';\r\nimport React, { useEffect, useState, useCallback } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n AlertTriangle,\r\n Building2,\r\n Users,\r\n Activity,\r\n TrendingUp,\r\n Loader2,\r\n RefreshCw,\r\n Clock,\r\n PauseCircle,\r\n CheckCircle,\r\n Timer,\r\n ShieldCheck,\r\n ShieldX,\r\n ClipboardList\r\n} from 'lucide-react';\r\nimport { tenantAnalyticsApi } from '@/services/api/tenantAnalyticsApi';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport type {\r\n TenantDashboardStatsDto,\r\n TopTenantDto\r\n} from '@/services/api/tenantAnalyticsApi';\r\nimport { TenantActivityPieChart } from '@/components/dashboard/TenantActivityPieChart';\r\nimport { TenantUsageTrendChart } from '@/components/dashboard/TenantUsageTrendChart';\r\nimport { TenantPopularityChart } from '@/components/dashboard/TenantPopularityChart';\r\nimport type { ChartMode } from '@/components/dashboard/UsageTrendChart';\r\n\r\nconst KpiCard: React.FC<{\r\n label: string;\r\n value: number | string;\r\n icon: React.ReactNode;\r\n color: 'blue' | 'green' | 'purple' | 'orange' | 'yellow' | 'red';\r\n subtitle?: string;\r\n}> = ({ label, value, icon, color, subtitle }) => {\r\n const iconColors = {\r\n blue: 'text-blue-500',\r\n green: 'text-green-500',\r\n purple: 'text-purple-500',\r\n orange: 'text-orange-500',\r\n yellow: 'text-yellow-500',\r\n red: 'text-red-500'\r\n };\r\n\r\n return (\r\n <div className=\"rounded-[var(--radius-card)] p-4 bg-[var(--bg-card)] border border-[var(--item-color-border)]\">\r\n <div className=\"flex items-center justify-between mb-2\">\r\n <span className=\"text-sm font-medium text-[var(--text-secondary)]\">{label}</span>\r\n <div className={iconColors[color]}>{icon}</div>\r\n </div>\r\n <div className=\"text-2xl font-bold text-[var(--text-primary)]\">{typeof value === 'number' ? value.toLocaleString() : value}</div>\r\n {subtitle && <div className=\"text-xs text-[var(--text-tertiary)] mt-1\">{subtitle}</div>}\r\n </div>\r\n );\r\n};\r\n\r\nexport function TenantsDashboardPage(): ReactElement {\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('admin');\r\n const [stats, setStats] = useState<TenantDashboardStatsDto | null>(null);\r\n const [topTenants, setTopTenants] = useState<TopTenantDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [refreshing, setRefreshing] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [period, setPeriod] = useState(30);\r\n const [chartMode, setChartMode] = useState<ChartMode>('access');\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setError(null);\r\n const [dashboardRes, topTenantsRes] = await Promise.all([\r\n tenantAnalyticsApi.getDashboardStats(period),\r\n tenantAnalyticsApi.getTopTenants(5, period, chartMode === 'access' ? 'access' : 'duration')\r\n ]);\r\n setStats(dashboardRes);\r\n setTopTenants(topTenantsRes);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load dashboard');\r\n } finally {\r\n setLoading(false);\r\n setRefreshing(false);\r\n }\r\n }, [period, chartMode]);\r\n\r\n useEffect(() => {\r\n setLoading(true);\r\n loadData();\r\n }, [loadData]);\r\n\r\n const handleRefresh = () => {\r\n setRefreshing(true);\r\n loadData();\r\n };\r\n\r\n const formatDuration = (seconds: number): string => {\r\n if (seconds < 60) return `${seconds}s`;\r\n const minutes = Math.floor(seconds / 60);\r\n if (minutes < 60) return `${minutes}m`;\r\n const hours = Math.floor(minutes / 60);\r\n return `${hours}h ${minutes % 60}m`;\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex h-96 items-center justify-center\">\r\n <Loader2 className=\"h-8 w-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"bg-[var(--error-bg)] border border-[var(--error-border)] rounded-[var(--radius-card)] p-4 flex items-center gap-3\">\r\n <AlertTriangle className=\"h-5 w-5 text-[var(--error-text)] flex-shrink-0\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-[var(--error-text)] font-medium\">{error}</p>\r\n </div>\r\n <button\r\n onClick={handleRefresh}\r\n className=\"text-[var(--error-text)] hover:opacity-80\"\r\n >\r\n <RefreshCw className=\"h-5 w-5\" />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('tenants.dashboard.title', 'Dashboard') }\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)] flex items-center gap-2\">\r\n <Building2 className=\"h-6 w-6\" />\r\n {t('tenants.dashboard.title', 'Tableau de bord Tenants')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)] mt-1\">\r\n {t('tenants.dashboard.subtitle', \"Analyse d'utilisation et statistiques des tenants\")}\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n {/* Mode Toggle */}\r\n <div className=\"flex items-center gap-1 rounded-lg border border-[var(--item-color-border)] bg-[var(--bg-secondary)] p-1\">\r\n <button\r\n onClick={() => setChartMode('access')}\r\n className={`px-3 py-1.5 text-sm font-medium rounded-md transition-all ${\r\n chartMode === 'access'\r\n ? 'bg-[var(--color-primary-600)] text-white shadow-sm'\r\n : 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <span className=\"flex items-center gap-1.5\">\r\n <Activity className=\"w-3.5 h-3.5\" />\r\n {t('tenants.dashboard.access', 'Accès')}\r\n </span>\r\n </button>\r\n <button\r\n onClick={() => setChartMode('duration')}\r\n className={`px-3 py-1.5 text-sm font-medium rounded-md transition-all ${\r\n chartMode === 'duration'\r\n ? 'bg-[var(--color-primary-600)] text-white shadow-sm'\r\n : 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <span className=\"flex items-center gap-1.5\">\r\n <Clock className=\"w-3.5 h-3.5\" />\r\n {t('tenants.dashboard.duration', 'Durée')}\r\n </span>\r\n </button>\r\n </div>\r\n <select\r\n value={period}\r\n onChange={(e) => setPeriod(Number(e.target.value))}\r\n className=\"rounded-[var(--radius-input)] border border-[var(--item-color-border)] bg-[var(--bg-secondary)] px-4 py-2 text-[var(--text-primary)] focus:border-[var(--color-primary-600)] focus:outline-none\"\r\n >\r\n <option value={7}>7 {t('common.days', 'jours')}</option>\r\n <option value={30}>30 {t('common.days', 'jours')}</option>\r\n <option value={90}>90 {t('common.days', 'jours')}</option>\r\n </select>\r\n <button\r\n onClick={handleRefresh}\r\n disabled={refreshing}\r\n className=\"rounded-[var(--radius-button)] border border-[var(--item-color-border)] bg-[var(--bg-secondary)] px-4 py-2 text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] flex items-center gap-2 transition-colors\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${refreshing ? 'animate-spin' : ''}`} />\r\n {t('common.refresh', 'Actualiser')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* KPI Cards Grid */}\r\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4\">\r\n <KpiCard\r\n label={t('tenants.dashboard.totalTenants', 'Total Tenants')}\r\n value={stats?.totalTenants || 0}\r\n icon={<Building2 className=\"h-5 w-5\" />}\r\n color=\"blue\"\r\n />\r\n <KpiCard\r\n label={t('tenants.dashboard.activeTenants', 'Tenants Actifs')}\r\n value={stats?.activeTenants || 0}\r\n icon={<CheckCircle className=\"h-5 w-5\" />}\r\n color=\"green\"\r\n />\r\n <KpiCard\r\n label={t('tenants.dashboard.suspendedTenants', 'Suspendus')}\r\n value={stats?.suspendedTenants || 0}\r\n icon={<PauseCircle className=\"h-5 w-5\" />}\r\n color=\"orange\"\r\n />\r\n <KpiCard\r\n label={t('tenants.dashboard.totalMembers', 'Total Membres')}\r\n value={stats?.totalMembers || 0}\r\n icon={<Users className=\"h-5 w-5\" />}\r\n color=\"purple\"\r\n />\r\n <KpiCard\r\n label={t('tenants.dashboard.avgSession', 'Session Moy.')}\r\n value={formatDuration(stats?.avgSessionDuration || 0)}\r\n icon={<Timer className=\"h-5 w-5\" />}\r\n color=\"blue\"\r\n subtitle={`${period} ${t('common.days', 'jours')}`}\r\n />\r\n <KpiCard\r\n label={t('tenants.dashboard.growthRate', 'Croissance')}\r\n value={`${stats?.growthRate.toFixed(1) || 0}%`}\r\n icon={<TrendingUp className=\"h-5 w-5\" />}\r\n color={(stats?.growthRate ?? 0) >= 0 ? 'green' : 'red'}\r\n subtitle={t('tenants.dashboard.vsPreviousPeriod', 'vs période précédente')}\r\n />\r\n </div>\r\n\r\n {/* Access Requests Section */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"font-semibold flex items-center gap-2 text-[var(--text-primary)]\">\r\n <ClipboardList className=\"h-5 w-5 text-[var(--color-primary-600)]\" />\r\n {t('tenants.dashboard.accessRequests.title', \"Demandes d'accès\")}\r\n </h3>\r\n <button\r\n onClick={() => navigate('/administration/access-requests')}\r\n className=\"text-sm font-medium text-[var(--color-primary-600)] hover:underline flex items-center gap-1\"\r\n >\r\n {t('tenants.dashboard.accessRequests.manage', 'Gérer')}\r\n <span aria-hidden=\"true\">→</span>\r\n </button>\r\n </div>\r\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\r\n <div className=\"rounded-lg p-4 bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <div className=\"flex items-center justify-between mb-1\">\r\n <span className=\"text-sm font-medium text-[var(--warning-text)]\">\r\n {t('tenants.dashboard.accessRequests.pending', 'En attente')}\r\n </span>\r\n <Clock className=\"h-4 w-4 text-[var(--warning-text)]\" />\r\n </div>\r\n <div className=\"text-2xl font-bold text-[var(--warning-text)]\">\r\n {stats?.pendingAccessRequests || 0}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg p-4 bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <div className=\"flex items-center justify-between mb-1\">\r\n <span className=\"text-sm font-medium text-[var(--success-text)]\">\r\n {t('tenants.dashboard.accessRequests.approved', 'Approuvées')}\r\n </span>\r\n <ShieldCheck className=\"h-4 w-4 text-[var(--success-text)]\" />\r\n </div>\r\n <div className=\"text-2xl font-bold text-[var(--success-text)]\">\r\n {stats?.approvedAccessRequests || 0}\r\n </div>\r\n </div>\r\n <div className=\"rounded-lg p-4 bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center justify-between mb-1\">\r\n <span className=\"text-sm font-medium text-[var(--error-text)]\">\r\n {t('tenants.dashboard.accessRequests.denied', 'Refusées')}\r\n </span>\r\n <ShieldX className=\"h-4 w-4 text-[var(--error-text)]\" />\r\n </div>\r\n <div className=\"text-2xl font-bold text-[var(--error-text)]\">\r\n {stats?.deniedAccessRequests || 0}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Two Column: Tenant Activity Pie + Top Tenants List */}\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {/* Tenant Activity Pie Chart */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <h3 className=\"font-semibold mb-4 flex items-center gap-2 text-[var(--text-primary)]\">\r\n <Building2 className=\"h-5 w-5 text-[var(--color-primary-600)]\" />\r\n {chartMode === 'access' ? t('tenants.dashboard.activity', 'Activité') : t('tenants.dashboard.timeSpent', 'Temps passé')} {t('tenants.dashboard.byTenant', 'par Tenant')}\r\n </h3>\r\n {topTenants.length > 0 ? (\r\n <TenantActivityPieChart data={topTenants} mode={chartMode} />\r\n ) : (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('tenants.dashboard.noData', 'Aucune donnée disponible')}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Top Tenants List */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <h3 className=\"font-semibold mb-4 flex items-center gap-2 text-[var(--text-primary)]\">\r\n <Activity className=\"h-5 w-5 text-green-600\" />\r\n {t('tenants.dashboard.topTenantsList', 'Classement des Tenants')}\r\n </h3>\r\n {stats?.topTenants && stats.topTenants.length > 0 ? (\r\n <div className=\"space-y-3\">\r\n {stats.topTenants.slice(0, 5).map((tenant, index) => (\r\n <button\r\n type=\"button\"\r\n key={tenant.tenantId}\r\n className=\"w-full flex items-center gap-3 p-3 rounded-lg bg-[var(--bg-secondary)] hover:bg-[var(--bg-hover)] cursor-pointer transition-colors text-left\"\r\n onClick={() => navigate(`/administration/tenants/${tenant.tenantId}`)}\r\n >\r\n <div\r\n className=\"w-8 h-8 rounded-full flex items-center justify-center text-white font-bold text-sm\"\r\n style={{ backgroundColor: ['#3b82f6', '#22c55e', '#f59e0b', '#ef4444', '#8b5cf6'][index % 5] }}\r\n >\r\n {index + 1}\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"font-medium text-[var(--text-primary)] truncate\">{tenant.tenantName}</p>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">\r\n {tenant.tenantType} • {tenant.uniqueUsers} {t('tenants.dashboard.users', 'utilisateurs')}\r\n </p>\r\n </div>\r\n <div className=\"text-right\">\r\n <p className=\"font-semibold text-[var(--text-primary)]\">\r\n {chartMode === 'access' ? tenant.accessCount : `${tenant.totalDurationMinutes}m`}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">\r\n {chartMode === 'access' ? t('tenants.dashboard.accesses', 'accès') : t('tenants.dashboard.totalTime', 'temps total')}\r\n </p>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n ) : (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('tenants.dashboard.noData', 'Aucune donnée disponible')}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Usage Trends Chart - Full Width with Tenant breakdown */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <h3 className=\"font-semibold mb-4 flex items-center gap-2 text-[var(--text-primary)]\">\r\n <TrendingUp className=\"h-5 w-5\" />\r\n {t('tenants.dashboard.trendTitle', {\r\n defaultValue: `Tendance ${chartMode === 'access' ? \"d'utilisation\" : 'du temps passé'} par Tenant`\r\n })} ({period} {t('common.days', 'jours')})\r\n </h3>\r\n <TenantUsageTrendChart period={period} mode={chartMode} />\r\n </div>\r\n\r\n {/* Tenant Popularity - Full Width */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <h3 className=\"font-semibold mb-4 flex items-center gap-2 text-[var(--text-primary)]\">\r\n <Building2 className=\"h-5 w-5 text-purple-600\" />\r\n {t('tenants.dashboard.popularTenants', {\r\n defaultValue: `Tenants les plus ${chartMode === 'access' ? 'actifs' : 'utilisés'}`\r\n })}\r\n <span className=\"text-xs font-normal text-[var(--text-secondary)] ml-2\">\r\n ({t('tenants.dashboard.byRanking', 'Type > Slug')})\r\n </span>\r\n </h3>\r\n {topTenants.length > 0 ? (\r\n <TenantPopularityChart data={topTenants} mode={chartMode} />\r\n ) : (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n {t('tenants.dashboard.noData', 'Aucune donnée disponible')}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Call to action */}\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-gradient-to-r from-[var(--color-primary-600)]/10 to-[var(--color-accent-500)]/10 p-6\">\r\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\r\n <div>\r\n <h3 className=\"font-bold text-[var(--text-primary)]\">{t('tenants.dashboard.exploreAll', 'Explorer tous les Tenants')}</h3>\r\n <p className=\"mt-1 text-sm text-[var(--text-secondary)]\">\r\n {t('tenants.dashboard.exploreDescription', 'Voir la liste complète des tenants et gérer leurs paramètres')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={() => navigate('/administration/tenants/list')}\r\n className=\"whitespace-nowrap rounded-[var(--radius-button)] bg-[var(--color-primary-600)] px-4 py-2 font-medium text-white transition-all hover:shadow-md\"\r\n >\r\n {t('tenants.dashboard.viewTenants', 'Voir les Tenants')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useCallback, useMemo } from 'react';\r\nimport {\r\n adminApi,\r\n type TenantApplicationDto,\r\n type AvailableApplicationDto,\r\n type ApplicationAccessLevel,\r\n type SaveOverridesRequest,\r\n} from '@/services/api/adminApi';\r\nimport type {\r\n UseTenantApplicationsReturn,\r\n BulkAccessMode,\r\n BulkModuleNode,\r\n BulkSectionNode,\r\n} from './useTenantApplications';\r\n\r\nconst updateModuleAssignment = (module: BulkModuleNode, moduleId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newIsAssigned = !module.isAssigned;\r\n return {\r\n ...module,\r\n isAssigned: newIsAssigned,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: newIsAssigned })),\r\n };\r\n};\r\n\r\nconst updateSectionAssignment = (module: BulkModuleNode, moduleId: string, sectionId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newSections = module.sections.map(s =>\r\n s.id === sectionId ? { ...s, isAssigned: !s.isAssigned } : s\r\n );\r\n const anySectionAssigned = newSections.some(s => s.isAssigned);\r\n return {\r\n ...module,\r\n isAssigned: anySectionAssigned,\r\n sections: newSections,\r\n };\r\n};\r\n\r\nconst assignAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: true,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: true })),\r\n});\r\n\r\nconst clearAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: false,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: false })),\r\n});\r\n\r\nfunction mapTemplateAppToTenantApp(\r\n app: { applicationId: string; label: string; code: string; description: string | null; icon: string | null; accessLevel: string; assignedAt: string; assignedBy: string | null; assignedModuleCount: number; assignedSectionCount: number; totalModuleCount: number; totalSectionCount: number }\r\n): TenantApplicationDto {\r\n return {\r\n applicationId: app.applicationId,\r\n label: app.label,\r\n code: app.code,\r\n description: app.description,\r\n icon: app.icon,\r\n accessLevel: app.accessLevel as ApplicationAccessLevel,\r\n assignedAt: app.assignedAt,\r\n assignedBy: app.assignedBy,\r\n source: 'Direct',\r\n inheritedModuleCount: 0,\r\n directModuleCount: app.assignedModuleCount,\r\n revokedModuleCount: 0,\r\n inheritedSectionCount: 0,\r\n directSectionCount: app.assignedSectionCount,\r\n revokedSectionCount: 0,\r\n totalModuleCount: app.totalModuleCount,\r\n totalSectionCount: app.totalSectionCount,\r\n };\r\n}\r\n\r\nexport function useTemplateApplications(templateId: string | undefined): UseTenantApplicationsReturn {\r\n const [applications, setApplications] = useState<TenantApplicationDto[] | null>(null);\r\n const [loadingApps, setLoadingApps] = useState(false);\r\n\r\n const [addingApplication, setAddingApplication] = useState(false);\r\n const [availableApps, setAvailableApps] = useState<AvailableApplicationDto[]>([]);\r\n const [loadingAvailableApps, setLoadingAvailableApps] = useState(false);\r\n const [selectedAppIds, setSelectedAppIds] = useState<string[]>([]);\r\n const [assigningApps, setAssigningApps] = useState(false);\r\n const [appSearchTerm, setAppSearchTerm] = useState('');\r\n const [availableAppsError, setAvailableAppsError] = useState<string | null>(null);\r\n\r\n const [selectedAccessLevel, setSelectedAccessLevel] = useState<ApplicationAccessLevel>('FullAccess');\r\n const [bulkAccessMode, setBulkAccessMode] = useState<BulkAccessMode>('full');\r\n const [bulkModules, setBulkModules] = useState<BulkModuleNode[]>([]);\r\n const [bulkExpandedModules, setBulkExpandedModules] = useState<Set<string>>(new Set());\r\n const [loadingBulkModules, setLoadingBulkModules] = useState(false);\r\n\r\n const [showCustomizeDrawer, setShowCustomizeDrawer] = useState(false);\r\n const [customizingApp, setCustomizingApp] = useState<TenantApplicationDto | null>(null);\r\n\r\n const loadApplications = useCallback(async () => {\r\n if (!templateId) return;\r\n setLoadingApps(true);\r\n try {\r\n const data = await adminApi.templates.getApplications(templateId);\r\n const mapped = Array.isArray(data) ? data.map(mapTemplateAppToTenantApp) : [];\r\n setApplications(mapped);\r\n } catch (err) {\r\n console.error('Failed to load template applications:', err);\r\n setApplications([]);\r\n } finally {\r\n setLoadingApps(false);\r\n }\r\n }, [templateId]);\r\n\r\n const loadAvailableApps = useCallback(async () => {\r\n if (!templateId) return;\r\n setAddingApplication(true);\r\n setSelectedAppIds([]);\r\n setLoadingAvailableApps(true);\r\n setAvailableAppsError(null);\r\n try {\r\n const availableAppsResult = await adminApi.templates.getAvailableApplications(templateId);\r\n setAvailableApps(availableAppsResult.filter(a => !a.isAssigned));\r\n } catch (err) {\r\n console.error('Failed to load available applications:', err);\r\n const isForbidden = err instanceof Error && err.name === 'ForbiddenError';\r\n setAvailableAppsError(isForbidden ? 'forbidden' : 'generic');\r\n } finally {\r\n setLoadingAvailableApps(false);\r\n }\r\n }, [templateId]);\r\n\r\n const closeAddApplication = useCallback(() => {\r\n setAddingApplication(false);\r\n setSelectedAppIds([]);\r\n setAppSearchTerm('');\r\n setSelectedAccessLevel('FullAccess');\r\n setBulkAccessMode('full');\r\n setBulkModules([]);\r\n setBulkExpandedModules(new Set());\r\n }, []);\r\n\r\n const handleAssignApplications = useCallback(async () => {\r\n if (!templateId || selectedAppIds.length === 0) return;\r\n setAssigningApps(true);\r\n try {\r\n const request = {\r\n applicationIds: selectedAppIds,\r\n accessLevel: selectedAccessLevel,\r\n accessMode: bulkAccessMode,\r\n moduleIds: bulkAccessMode === 'custom' ? bulkModules.filter(m => m.isAssigned).map(m => m.id) : undefined,\r\n sectionIds: bulkAccessMode === 'custom' ? bulkModules.flatMap(m => m.sections.filter(s => s.isAssigned).map(s => s.id)) : undefined,\r\n };\r\n\r\n await adminApi.templates.bulkAssignApplications(templateId, request);\r\n\r\n await loadApplications();\r\n closeAddApplication();\r\n } catch (err) {\r\n console.error('Failed to assign applications:', err);\r\n } finally {\r\n setAssigningApps(false);\r\n }\r\n }, [templateId, selectedAppIds, selectedAccessLevel, bulkAccessMode, bulkModules, loadApplications, closeAddApplication]);\r\n\r\n const handleRemoveApplication = useCallback(async (appId: string) => {\r\n if (!templateId) return;\r\n try {\r\n await adminApi.templates.removeApplication(templateId, appId);\r\n await loadApplications();\r\n } catch (err) {\r\n console.error('Failed to remove application:', err);\r\n }\r\n }, [templateId, loadApplications]);\r\n\r\n const handleUpdateAccessLevel = useCallback(async (appId: string, accessLevel: ApplicationAccessLevel) => {\r\n if (!templateId) return;\r\n try {\r\n await adminApi.templates.updateApplicationAccessLevel(templateId, appId, accessLevel);\r\n await loadApplications();\r\n } catch (err) {\r\n console.error('Failed to update access level:', err);\r\n }\r\n }, [templateId, loadApplications]);\r\n\r\n const openCustomizeDrawer = useCallback((app: TenantApplicationDto) => {\r\n setCustomizingApp(app);\r\n setShowCustomizeDrawer(true);\r\n }, []);\r\n\r\n const closeCustomizeDrawer = useCallback(() => {\r\n setShowCustomizeDrawer(false);\r\n setCustomizingApp(null);\r\n }, []);\r\n\r\n const filteredAvailableApps = useMemo(() => {\r\n if (!appSearchTerm) return availableApps;\r\n\r\n const searchLower = appSearchTerm.toLowerCase();\r\n return availableApps.filter(app =>\r\n app.label.toLowerCase().includes(searchLower) ||\r\n app.code.toLowerCase().includes(searchLower)\r\n );\r\n }, [availableApps, appSearchTerm]);\r\n\r\n const handleAppToggle = useCallback((appId: string) => {\r\n setSelectedAppIds(prev =>\r\n prev.includes(appId)\r\n ? prev.filter(id => id !== appId)\r\n : [...prev, appId]\r\n );\r\n }, []);\r\n\r\n const selectAllFilteredApps = useCallback(() => {\r\n const filteredIds = filteredAvailableApps.map(app => app.id);\r\n setSelectedAppIds(filteredIds);\r\n }, [filteredAvailableApps]);\r\n\r\n const clearAppSelection = useCallback(() => {\r\n setSelectedAppIds([]);\r\n }, []);\r\n\r\n const loadBulkModulesForApp = useCallback(async (appId: string) => {\r\n setLoadingBulkModules(true);\r\n try {\r\n const appModules = await adminApi.applications.getModules(appId);\r\n const moduleNodes: BulkModuleNode[] = [];\r\n\r\n for (const appModule of appModules) {\r\n const sections = await adminApi.applications.getModuleSections(appId, appModule.id);\r\n const sectionNodes: BulkSectionNode[] = sections.map(section => ({\r\n id: section.id,\r\n label: section.label,\r\n code: section.code,\r\n icon: section.icon,\r\n isAssigned: true,\r\n }));\r\n\r\n moduleNodes.push({\r\n id: appModule.id,\r\n label: appModule.label,\r\n code: appModule.code,\r\n icon: appModule.icon,\r\n isAssigned: true,\r\n sections: sectionNodes,\r\n });\r\n }\r\n\r\n setBulkModules(moduleNodes);\r\n } catch (err) {\r\n console.error('Failed to load modules:', err);\r\n } finally {\r\n setLoadingBulkModules(false);\r\n }\r\n }, []);\r\n\r\n const toggleBulkModuleExpand = useCallback((moduleId: string) => {\r\n setBulkExpandedModules(prev => {\r\n const newSet = new Set(prev);\r\n if (newSet.has(moduleId)) {\r\n newSet.delete(moduleId);\r\n } else {\r\n newSet.add(moduleId);\r\n }\r\n return newSet;\r\n });\r\n }, []);\r\n\r\n const toggleBulkModule = useCallback((moduleId: string) => {\r\n setBulkModules(prev => prev.map(m => updateModuleAssignment(m, moduleId)));\r\n }, []);\r\n\r\n const toggleBulkSection = useCallback((moduleId: string, sectionId: string) => {\r\n setBulkModules(prev => prev.map(m => updateSectionAssignment(m, moduleId, sectionId)));\r\n }, []);\r\n\r\n const getBulkModuleCheckState = useCallback((module: BulkModuleNode): 'checked' | 'unchecked' | 'indeterminate' => {\r\n if (module.sections.length === 0) {\r\n return module.isAssigned ? 'checked' : 'unchecked';\r\n }\r\n const assignedCount = module.sections.filter(s => s.isAssigned).length;\r\n if (assignedCount === 0) return 'unchecked';\r\n if (assignedCount === module.sections.length) return 'checked';\r\n return 'indeterminate';\r\n }, []);\r\n\r\n const getBulkStats = useCallback(() => {\r\n const totalModules = bulkModules.length;\r\n const assignedModules = bulkModules.filter(m => m.isAssigned || m.sections.some(s => s.isAssigned)).length;\r\n const totalSections = bulkModules.reduce((sum, m) => sum + m.sections.length, 0);\r\n const assignedSections = bulkModules.reduce((sum, m) => sum + m.sections.filter(s => s.isAssigned).length, 0);\r\n return { totalModules, assignedModules, totalSections, assignedSections };\r\n }, [bulkModules]);\r\n\r\n const selectAllBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => assignAllSections(m)));\r\n }, []);\r\n\r\n const clearBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => clearAllSections(m)));\r\n }, []);\r\n\r\n return {\r\n applications,\r\n setApplications,\r\n loadingApps,\r\n setLoadingApps,\r\n addingApplication,\r\n setAddingApplication,\r\n availableApps,\r\n setAvailableApps,\r\n loadingAvailableApps,\r\n setLoadingAvailableApps,\r\n selectedAppIds,\r\n setSelectedAppIds,\r\n assigningApps,\r\n setAssigningApps,\r\n appSearchTerm,\r\n setAppSearchTerm,\r\n selectedAccessLevel,\r\n setSelectedAccessLevel,\r\n bulkAccessMode,\r\n setBulkAccessMode,\r\n bulkModules,\r\n setBulkModules,\r\n bulkExpandedModules,\r\n setBulkExpandedModules,\r\n loadingBulkModules,\r\n setLoadingBulkModules,\r\n showCustomizeDrawer,\r\n setShowCustomizeDrawer,\r\n customizingApp,\r\n setCustomizingApp,\r\n loadApplications,\r\n availableAppsError,\r\n loadAvailableApps,\r\n handleAssignApplications,\r\n handleRemoveApplication,\r\n handleUpdateAccessLevel,\r\n openCustomizeDrawer,\r\n closeCustomizeDrawer,\r\n filteredAvailableApps,\r\n handleAppToggle,\r\n selectAllFilteredApps,\r\n clearAppSelection,\r\n loadBulkModulesForApp,\r\n toggleBulkModuleExpand,\r\n toggleBulkModule,\r\n toggleBulkSection,\r\n getBulkModuleCheckState,\r\n getBulkStats,\r\n selectAllBulkModules,\r\n clearBulkModules,\r\n // Template mode does not support overrides — provide no-op stubs to satisfy the shared interface\r\n handleSaveOverrides: async (_appId: string, _request: SaveOverridesRequest) => { /* no-op for template mode */ },\r\n handleResetOverrides: async (_appId: string) => { /* no-op for template mode */ },\r\n };\r\n}\r\n","import { memo, useEffect, useState, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useParams, useNavigate, Link } from 'react-router-dom';\r\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\r\nimport { useTemplateApplications } from '@/hooks/useTemplateApplications';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { TenantApplicationsTab } from '@/components/platform/administration/tenants/TenantApplicationsTab';\r\nimport { ArrowLeft, RefreshCw, Loader2, AlertCircle, Star, User, Building2, Users, AppWindow, LayoutGrid, Brain } from 'lucide-react';\r\nimport { adminApi, type TenantTemplateDetailDto, type TenantBasicDto, type TemplateAiInstanceDto } from '@/services/api/adminApi';\r\n\r\nconst VALID_TABS = ['info', 'applications', 'tenants', 'ai'] as const;\r\ntype TabType = typeof VALID_TABS[number];\r\n\r\n// ============================================================================\r\n// Interfaces\r\n// ============================================================================\r\n\r\ninterface InfoTabProps {\r\n readonly template: TenantTemplateDetailDto;\r\n readonly t: (key: string) => string;\r\n}\r\n\r\ninterface StatCardProps {\r\n readonly icon: React.ReactNode;\r\n readonly label: string;\r\n readonly value: number;\r\n}\r\n\r\ninterface TenantsTabProps {\r\n readonly templateId: string;\r\n readonly t: (key: string) => string;\r\n}\r\n\r\ninterface AiInstancesTabProps {\r\n readonly templateId: string;\r\n readonly t: (key: string) => string;\r\n}\r\n\r\n// ============================================================================\r\n// Main Page\r\n// ============================================================================\r\n\r\nexport function TenantTemplateDetailPage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { id: templateId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const { activeTab, setActiveTab } = useTabNavigation<TabType>('info', VALID_TABS);\r\n\r\n const [template, setTemplate] = useState<TenantTemplateDetailDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const templateApplications = useTemplateApplications(templateId);\r\n\r\n const loadTemplate = useCallback(async () => {\r\n if (!templateId) return;\r\n try {\r\n setLoading(true);\r\n const data = await adminApi.templates.getById(templateId);\r\n setTemplate(data);\r\n setError(null);\r\n } catch {\r\n setError(t('templates.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [templateId, t]);\r\n\r\n useEffect(() => {\r\n if (!templateId) {\r\n navigate('/administration/tenants/template');\r\n return;\r\n }\r\n loadTemplate();\r\n }, [templateId, loadTemplate, navigate]);\r\n\r\n useEffect(() => {\r\n if (template && templateId) {\r\n templateApplications.loadApplications();\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [template, templateId]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"p-6 flex items-center justify-center min-h-[50vh]\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error || !template) {\r\n return (\r\n <div className=\"p-6 space-y-4\">\r\n <button\r\n onClick={() => navigate('/administration/tenants/template')}\r\n className=\"flex items-center gap-2 text-sm text-[var(--text-secondary)] hover:text-[var(--text-primary)]\"\r\n >\r\n <ArrowLeft className=\"w-4 h-4\" />\r\n {t('templates.title')}\r\n </button>\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <AlertCircle className=\"h-5 w-5 text-[var(--error-text)]\" />\r\n <span className=\"text-[var(--error-text)]\">{error || t('templates.notFound')}</span>\r\n </div>\r\n <button\r\n onClick={() => loadTemplate()}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:errors.retry')}\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const TypeIcon = template.targetTenantType === 'Personal' ? User : Building2;\r\n const typeLabel = template.targetTenantType === 'Personal'\r\n ? t('templates.targetPersonal')\r\n : t('templates.targetBusiness');\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('templates.title'), href: '/administration/tenants/template' },\r\n { label: template.name }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/tenants/template')}\r\n aria-label={t('templates.title')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div>\r\n <div className=\"flex items-center gap-3\">\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">{template.name}</h1>\r\n {template.isDefault && (\r\n <span className=\"flex items-center gap-1 px-2 py-0.5 rounded-[var(--radius-badge)] text-xs bg-[var(--accent-bg)] text-[var(--accent-text)]\">\r\n <Star className=\"w-3 h-3\" />\r\n {t('templates.default')}\r\n </span>\r\n )}\r\n </div>\r\n <div className=\"flex items-center gap-2 mt-1\">\r\n <span className=\"text-sm text-[var(--text-tertiary)] font-mono\">{template.code}</span>\r\n <span className=\"text-[var(--text-tertiary)]\">-</span>\r\n <span className=\"flex items-center gap-1 text-sm text-[var(--text-secondary)]\">\r\n <TypeIcon className=\"w-3.5 h-3.5\" />\r\n {typeLabel}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n <button\r\n onClick={loadTemplate}\r\n aria-label={t('common:refresh')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-secondary)]\"\r\n >\r\n <RefreshCw className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n\r\n {/* Tabs */}\r\n <div className=\"border-b border-[var(--border-color)]\">\r\n <div className=\"flex gap-1 -mb-px\">\r\n {VALID_TABS.map(tab => (\r\n <button\r\n key={tab}\r\n onClick={() => setActiveTab(tab)}\r\n className={`px-4 py-2 text-sm border-b-2 transition-colors ${\r\n activeTab === tab\r\n ? 'border-[var(--primary-color)] text-[var(--primary-color)] font-medium'\r\n : 'border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n >\r\n {t(`templates.tabs.${tab}`)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Tab Content */}\r\n {activeTab === 'info' && <InfoTab template={template} t={t} />}\r\n {activeTab === 'applications' && (\r\n <TenantApplicationsTab\r\n tenantId={templateId!}\r\n tenantName={template.name}\r\n mode=\"template\"\r\n applications={templateApplications.applications}\r\n loadingApps={templateApplications.loadingApps}\r\n actionLoading={null}\r\n onRefresh={templateApplications.loadApplications}\r\n onUpdateAccessLevel={templateApplications.handleUpdateAccessLevel}\r\n onRemoveApplication={templateApplications.handleRemoveApplication}\r\n // Add application modal state\r\n addingApplication={templateApplications.addingApplication}\r\n availableAppsError={templateApplications.availableAppsError}\r\n filteredAvailableApps={templateApplications.filteredAvailableApps}\r\n loadingAvailableApps={templateApplications.loadingAvailableApps}\r\n selectedAppIds={templateApplications.selectedAppIds}\r\n assigningApps={templateApplications.assigningApps}\r\n appSearchTerm={templateApplications.appSearchTerm}\r\n selectedAccessLevel={templateApplications.selectedAccessLevel}\r\n bulkAccessMode={templateApplications.bulkAccessMode}\r\n bulkModules={templateApplications.bulkModules}\r\n bulkExpandedModules={templateApplications.bulkExpandedModules}\r\n loadingBulkModules={templateApplications.loadingBulkModules}\r\n // Customize drawer state\r\n showCustomizeDrawer={templateApplications.showCustomizeDrawer}\r\n customizingApp={templateApplications.customizingApp}\r\n // Actions\r\n onOpenAddApplication={templateApplications.loadAvailableApps}\r\n onCloseAddApplication={() => {\r\n templateApplications.setAddingApplication(false);\r\n templateApplications.setSelectedAppIds([]);\r\n templateApplications.setAppSearchTerm('');\r\n templateApplications.setSelectedAccessLevel('FullAccess');\r\n templateApplications.setBulkAccessMode('full');\r\n templateApplications.setBulkModules([]);\r\n templateApplications.setBulkExpandedModules(new Set());\r\n }}\r\n onAssignApplications={templateApplications.handleAssignApplications}\r\n onAppToggle={templateApplications.handleAppToggle}\r\n onSelectAllApps={templateApplications.selectAllFilteredApps}\r\n onClearAppSelection={templateApplications.clearAppSelection}\r\n onOpenCustomizeDrawer={templateApplications.openCustomizeDrawer}\r\n onCloseCustomizeDrawer={templateApplications.closeCustomizeDrawer}\r\n // Module handlers\r\n onLoadBulkModules={templateApplications.loadBulkModulesForApp}\r\n onToggleBulkModuleExpand={templateApplications.toggleBulkModuleExpand}\r\n onToggleBulkModule={templateApplications.toggleBulkModule}\r\n onToggleBulkSection={templateApplications.toggleBulkSection}\r\n onGetBulkModuleCheckState={templateApplications.getBulkModuleCheckState}\r\n onGetBulkStats={templateApplications.getBulkStats}\r\n onSelectAllBulkModules={templateApplications.selectAllBulkModules}\r\n onClearBulkModules={templateApplications.clearBulkModules}\r\n // Setters\r\n setAppSearchTerm={templateApplications.setAppSearchTerm}\r\n setSelectedAccessLevel={templateApplications.setSelectedAccessLevel}\r\n setBulkAccessMode={templateApplications.setBulkAccessMode}\r\n />\r\n )}\r\n {activeTab === 'tenants' && <TenantsTab templateId={templateId!} t={t} />}\r\n {activeTab === 'ai' && <AiInstancesTab templateId={templateId!} t={t} />}\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================================================\r\n// InfoTab\r\n// ============================================================================\r\n\r\nfunction InfoTab({ template, t }: InfoTabProps) {\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"bg-[var(--bg-card)] border border-[var(--border-color)] rounded-[var(--radius-card)] p-5\">\r\n <h3 className=\"font-semibold text-[var(--text-primary)] mb-4\">{t('templates.info.general')}</h3>\r\n <dl className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <div>\r\n <dt className=\"text-sm text-[var(--text-secondary)]\">{t('templates.info.code')}</dt>\r\n <dd className=\"font-mono text-[var(--text-primary)]\">{template.code}</dd>\r\n </div>\r\n <div>\r\n <dt className=\"text-sm text-[var(--text-secondary)]\">{t('templates.info.name')}</dt>\r\n <dd className=\"text-[var(--text-primary)]\">{template.name}</dd>\r\n </div>\r\n <div className=\"md:col-span-2\">\r\n <dt className=\"text-sm text-[var(--text-secondary)]\">{t('templates.info.description')}</dt>\r\n <dd className=\"text-[var(--text-primary)]\">{template.description || '-'}</dd>\r\n </div>\r\n </dl>\r\n </div>\r\n\r\n <div className=\"bg-[var(--bg-card)] border border-[var(--border-color)] rounded-[var(--radius-card)] p-5\">\r\n <h3 className=\"font-semibold text-[var(--text-primary)] mb-4\">{t('templates.info.stats')}</h3>\r\n <div className=\"grid grid-cols-3 gap-4\">\r\n <StatCard icon={<AppWindow className=\"w-5 h-5\" />} label={t('templates.tabs.applications')} value={template.applications.length} />\r\n <StatCard icon={<LayoutGrid className=\"w-5 h-5\" />} label={t('templates.tabs.tenants')} value={template.modules.length} />\r\n <StatCard icon={<Users className=\"w-5 h-5\" />} label={t('templates.tabs.tenants')} value={0} />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================================================\r\n// StatCard (memo for list rendering)\r\n// ============================================================================\r\n\r\nconst StatCard = memo(function StatCard({ icon, label, value }: StatCardProps) {\r\n return (\r\n <div className=\"flex items-center gap-3 p-3 bg-[var(--bg-secondary)] rounded-[var(--radius-card)]\">\r\n <span className=\"text-[var(--text-secondary)]\">{icon}</span>\r\n <div>\r\n <p className=\"text-2xl font-bold text-[var(--text-primary)]\">{value}</p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">{label}</p>\r\n </div>\r\n </div>\r\n );\r\n});\r\n\r\n// ============================================================================\r\n// TenantsTab\r\n// ============================================================================\r\n\r\nfunction TenantsTab({ templateId, t }: TenantsTabProps) {\r\n const [tenants, setTenants] = useState<TenantBasicDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [tabError, setTabError] = useState<string | null>(null);\r\n\r\n const loadTenants = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n setTabError(null);\r\n const data = await adminApi.templates.getTenants(templateId);\r\n setTenants(data);\r\n } catch {\r\n setTabError(t('templates.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [templateId, t]);\r\n\r\n useEffect(() => {\r\n loadTenants();\r\n }, [loadTenants]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (tabError) {\r\n return (\r\n <div className=\"p-4 bg-[var(--error-bg)] border border-[var(--error-border)] rounded-[var(--radius-card)]\">\r\n <div className=\"flex items-center\">\r\n <AlertCircle className=\"h-5 w-5 text-[var(--error-text)]\" />\r\n <span className=\"ml-2 text-[var(--error-text)]\">{tabError}</span>\r\n </div>\r\n <button\r\n onClick={() => loadTenants()}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:errors.retry')}\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"font-semibold text-[var(--text-primary)]\">\r\n {t('templates.tenants.title')} ({tenants.length})\r\n </h3>\r\n\r\n {tenants.length === 0 ? (\r\n <div className=\"p-8 text-center text-[var(--text-secondary)] bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <Users className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n <p>{t('templates.tenants.noTenants')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"bg-[var(--bg-card)] border border-[var(--border-color)] rounded-[var(--radius-card)] divide-y divide-[var(--border-color)]\">\r\n {tenants.map(tenant => (\r\n <Link\r\n key={tenant.id}\r\n to={`/administration/tenants/${tenant.id}`}\r\n className=\"flex items-center justify-between p-3 hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">{tenant.name}</p>\r\n <p className=\"text-xs text-[var(--text-tertiary)] font-mono\">{tenant.slug}</p>\r\n </div>\r\n <span className=\"text-xs text-[var(--text-secondary)] px-2 py-0.5 bg-[var(--bg-secondary)] rounded-[var(--radius-badge)]\">\r\n {t('templates.tenants.explicit')}\r\n </span>\r\n </Link>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================================================\r\n// AiInstancesTab\r\n// ============================================================================\r\n\r\nfunction AiInstancesTab({ templateId, t }: AiInstancesTabProps) {\r\n const [instances, setInstances] = useState<TemplateAiInstanceDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [tabError, setTabError] = useState<string | null>(null);\r\n\r\n const loadInstances = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n setTabError(null);\r\n const data = await adminApi.templates.getAiInstances(templateId);\r\n setInstances(data);\r\n } catch {\r\n setTabError(t('templates.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [templateId, t]);\r\n\r\n const handleRemove = useCallback(async (instanceId: string) => {\r\n if (!window.confirm(t('templates.ai.removeConfirm'))) return;\r\n try {\r\n await adminApi.templates.removeAiInstance(templateId, instanceId);\r\n await loadInstances();\r\n } catch {\r\n setTabError(t('templates.errors.loadFailed'));\r\n }\r\n }, [templateId, t, loadInstances]);\r\n\r\n useEffect(() => {\r\n loadInstances();\r\n }, [loadInstances]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (tabError) {\r\n return (\r\n <div className=\"p-4 bg-[var(--error-bg)] border border-[var(--error-border)] rounded-[var(--radius-card)]\">\r\n <div className=\"flex items-center\">\r\n <AlertCircle className=\"h-5 w-5 text-[var(--error-text)]\" />\r\n <span className=\"ml-2 text-[var(--error-text)]\">{tabError}</span>\r\n </div>\r\n <button\r\n onClick={() => loadInstances()}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:errors.retry')}\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"font-semibold text-[var(--text-primary)]\">\r\n {t('templates.ai.title')} ({instances.length})\r\n </h3>\r\n\r\n {instances.length === 0 ? (\r\n <div className=\"p-8 text-center text-[var(--text-secondary)] bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <Brain className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n <p>{t('templates.ai.noInstances')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"bg-[var(--bg-card)] border border-[var(--border-color)] rounded-[var(--radius-card)] divide-y divide-[var(--border-color)]\">\r\n {instances.map(instance => (\r\n <div\r\n key={instance.id}\r\n className=\"flex items-center justify-between p-3 hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">{instance.instanceName}</p>\r\n <p className=\"text-xs text-[var(--text-tertiary)] font-mono\">{instance.instanceCode}</p>\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n <span className={`text-xs px-2 py-0.5 rounded-[var(--radius-badge)] ${\r\n instance.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)]'\r\n }`}>\r\n {instance.isActive ? t('templates.ai.active') : t('templates.ai.inactive')}\r\n </span>\r\n <button\r\n onClick={() => handleRemove(instance.instanceId)}\r\n className=\"text-xs text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('templates.ai.remove')}\r\n </button>\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useEffect, useState, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { PageHeader } from '@/components/ui/PageHeader';\r\nimport { Settings2, Building, User, Boxes, Users, Loader2, AlertTriangle, Star, ArrowRight, Plus } from 'lucide-react';\r\nimport { adminApi, type TenantTemplateDto } from '@/services/api/adminApi';\r\n\r\nexport function TenantsTemplatePage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n const [templates, setTemplates] = useState<TenantTemplateDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const loadTemplates = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await adminApi.templates.getAll();\r\n setTemplates(data);\r\n setError(null);\r\n } catch {\r\n setError(t('tenants.template.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [t]);\r\n\r\n useEffect(() => {\r\n loadTemplates();\r\n }, [loadTemplates]);\r\n\r\n const handleCardClick = (templateId: string) => {\r\n navigate(`/administration/tenants/template/${templateId}`);\r\n };\r\n\r\n const systemTemplates = templates.filter(t => t.isDefault);\r\n const customTemplates = templates.filter(t => !t.isDefault);\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('tenants.template.title') }\r\n ]}\r\n />\r\n\r\n <PageHeader\r\n title={t('tenants.template.title')}\r\n subtitle={t('tenants.template.subtitle')}\r\n icon={<Settings2 className=\"w-6 h-6\" />}\r\n actions={\r\n <button\r\n onClick={() => navigate('/administration/tenants/template/create')}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('tenants.template.createTemplate')}\r\n </button>\r\n }\r\n />\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {loading && (\r\n <div className=\"flex justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--text-secondary)]\" />\r\n </div>\r\n )}\r\n {!loading && templates.length === 0 && (\r\n <div className=\"p-6 text-center text-[var(--text-secondary)] bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n {t('tenants.template.noTemplates')}\r\n </div>\r\n )}\r\n {!loading && templates.length > 0 && (\r\n <div className=\"space-y-8\">\r\n {/* System Templates */}\r\n {systemTemplates.length > 0 && (\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('tenants.template.systemTemplates')}\r\n </h3>\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {systemTemplates.map(template => (\r\n <SystemTemplateCard\r\n key={template.id}\r\n template={template}\r\n onClick={() => handleCardClick(template.id)}\r\n t={t}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Custom Templates */}\r\n {customTemplates.length > 0 && (\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('tenants.template.customTemplates')}\r\n </h3>\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {customTemplates.map(template => (\r\n <CustomTemplateCard\r\n key={template.id}\r\n template={template}\r\n onClick={() => handleCardClick(template.id)}\r\n t={t}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction SystemTemplateCard({\r\n template,\r\n onClick,\r\n t\r\n}: {\r\n template: TenantTemplateDto;\r\n onClick: () => void;\r\n t: (key: string) => string;\r\n}) {\r\n const IconComponent = template.targetTenantType === 'Personal' ? User : Building;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={onClick}\r\n className=\"p-6 border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-card)] hover:bg-[var(--bg-hover)] hover:border-[var(--primary-color)] cursor-pointer transition-all duration-200 shadow-sm hover:shadow-md text-left w-full\"\r\n >\r\n <div className=\"space-y-4\">\r\n {/* Header */}\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2.5 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <IconComponent className=\"w-5 h-5 text-[var(--primary-color)]\" />\r\n </div>\r\n <div className=\"min-w-0 flex-1\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {template.targetTenantType === 'Personal'\r\n ? t('tenants.template.personalTitle')\r\n : t('tenants.template.businessTitle')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-tertiary)] font-mono\">{template.code}</p>\r\n </div>\r\n </div>\r\n <span className=\"flex items-center gap-1 px-2.5 py-1 rounded-[var(--radius-badge)] text-xs bg-[var(--accent-bg)] text-[var(--accent-text)] flex-shrink-0\">\r\n <Star className=\"w-3 h-3\" />\r\n {t('tenants.template.default')}\r\n </span>\r\n </div>\r\n\r\n {/* Description */}\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {template.targetTenantType === 'Personal'\r\n ? t('tenants.template.personalDescription')\r\n : t('tenants.template.businessDescription')}\r\n </p>\r\n\r\n {/* Status Badges */}\r\n <div className=\"flex items-center gap-2\">\r\n <span className={`px-2 py-0.5 rounded-[var(--radius-badge)] text-xs ${\r\n template.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)]'\r\n }`}>\r\n {template.isActive ? t('templates.active') : t('templates.inactive')}\r\n </span>\r\n </div>\r\n\r\n {/* Stats Grid */}\r\n <div className=\"grid grid-cols-2 gap-3 pt-2\">\r\n <div className=\"p-3 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <Boxes className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">{t('tenants.template.applications')}</span>\r\n </div>\r\n <div className=\"text-lg font-bold text-[var(--text-primary)]\">{template.applicationCount}</div>\r\n </div>\r\n <div className=\"p-3 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <Users className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">{t('tenants.template.tenants')}</span>\r\n </div>\r\n <div className=\"text-lg font-bold text-[var(--text-primary)]\">{template.tenantCount}</div>\r\n </div>\r\n </div>\r\n\r\n {/* CTA Button */}\r\n <span\r\n className=\"w-full mt-2 py-2 px-3 rounded-[var(--radius-button)] bg-[var(--primary-color)] text-white text-sm font-medium flex items-center justify-center gap-2 hover:opacity-90 transition-opacity\"\r\n >\r\n {t('tenants.template.configure')}\r\n <ArrowRight className=\"w-3.5 h-3.5\" />\r\n </span>\r\n </div>\r\n </button>\r\n );\r\n}\r\n\r\nfunction CustomTemplateCard({\r\n template,\r\n onClick,\r\n t\r\n}: {\r\n template: TenantTemplateDto;\r\n onClick: () => void;\r\n t: (key: string) => string;\r\n}) {\r\n const IconComponent = template.targetTenantType === 'Personal' ? User : Building;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={onClick}\r\n className=\"p-6 border border-[var(--border-color)] rounded-[var(--radius-card)] bg-[var(--bg-card)] hover:bg-[var(--bg-hover)] hover:border-[var(--primary-color)] cursor-pointer transition-all duration-200 shadow-sm hover:shadow-md text-left w-full\"\r\n >\r\n <div className=\"space-y-4\">\r\n {/* Header */}\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2.5 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <IconComponent className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </div>\r\n <div className=\"min-w-0 flex-1\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {template.name}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-tertiary)] font-mono\">{template.code}</p>\r\n </div>\r\n </div>\r\n <span className={`px-2.5 py-1 rounded-[var(--radius-badge)] text-xs flex-shrink-0 ${\r\n template.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)]'\r\n }`}>\r\n {template.isActive ? t('templates.active') : t('templates.inactive')}\r\n </span>\r\n </div>\r\n\r\n {/* Description */}\r\n {template.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {template.description}\r\n </p>\r\n )}\r\n\r\n {/* Type badge */}\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"px-2 py-0.5 rounded-[var(--radius-badge)] text-xs bg-[var(--info-bg)] text-[var(--info-text)]\">\r\n {template.targetTenantType === 'Personal'\r\n ? t('tenants.type.personal')\r\n : t('tenants.type.business')}\r\n </span>\r\n </div>\r\n\r\n {/* Stats Grid */}\r\n <div className=\"grid grid-cols-2 gap-3 pt-2\">\r\n <div className=\"p-3 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <Boxes className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">{t('tenants.template.applications')}</span>\r\n </div>\r\n <div className=\"text-lg font-bold text-[var(--text-primary)]\">{template.applicationCount}</div>\r\n </div>\r\n <div className=\"p-3 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <Users className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">{t('tenants.template.tenants')}</span>\r\n </div>\r\n <div className=\"text-lg font-bold text-[var(--text-primary)]\">{template.tenantCount}</div>\r\n </div>\r\n </div>\r\n\r\n {/* CTA Button */}\r\n <span\r\n className=\"w-full mt-2 py-2 px-3 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] text-sm font-medium flex items-center justify-center gap-2 hover:bg-[var(--bg-hover)] transition-colors border border-[var(--border-color)]\"\r\n >\r\n {t('tenants.template.configure')}\r\n <ArrowRight className=\"w-3.5 h-3.5\" />\r\n </span>\r\n </div>\r\n </button>\r\n );\r\n}\r\n","import { useState } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { PageHeader } from '@/components/ui/PageHeader';\r\nimport { Settings2, Loader2, AlertTriangle, Check } from 'lucide-react';\r\nimport { adminApi, type TenantType } from '@/services/api/adminApi';\r\n\r\nexport function TenantTemplateCreatePage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n\r\n const [code, setCode] = useState('');\r\n const [name, setName] = useState('');\r\n const [description, setDescription] = useState('');\r\n const [targetTenantType, setTargetTenantType] = useState<TenantType>('Business');\r\n const [saving, setSaving] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (!code.trim() || !name.trim()) return;\r\n\r\n setSaving(true);\r\n setError(null);\r\n try {\r\n const result = await adminApi.templates.create({\r\n code: code.trim(),\r\n name: name.trim(),\r\n description: description.trim() || undefined,\r\n targetTenantType,\r\n });\r\n navigate(`/administration/tenants/template/${result.id}`);\r\n } catch (err) {\r\n console.error('Failed to create template:', err);\r\n const axiosError = err as { response?: { status?: number; data?: { message?: string } } };\r\n if (axiosError.response?.status === 409) {\r\n setError(axiosError.response.data?.message || t('tenants.template.errors.createConflict'));\r\n } else {\r\n setError(t('tenants.template.errors.createFailed'));\r\n }\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('tenants.template.title'), href: '/administration/tenants/template' },\r\n { label: t('tenants.template.createTitle') }\r\n ]}\r\n />\r\n\r\n <PageHeader\r\n title={t('tenants.template.createTitle')}\r\n subtitle={t('tenants.template.createSubtitle')}\r\n icon={<Settings2 className=\"w-6 h-6\" />}\r\n />\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className=\"max-w-2xl space-y-6\">\r\n <div className=\"p-6 rounded-[var(--radius-card)] bg-[var(--bg-card)] border border-[var(--border-color)] space-y-4\">\r\n {/* Code */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.template.code')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={code}\r\n onChange={(e) => setCode(e.target.value)}\r\n placeholder=\"e.g. custom-b2b-premium\"\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required\r\n />\r\n </div>\r\n\r\n {/* Name */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.template.name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={name}\r\n onChange={(e) => setName(e.target.value)}\r\n placeholder={t('tenants.template.namePlaceholder')}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n required\r\n />\r\n </div>\r\n\r\n {/* Description */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('common:description')}\r\n </label>\r\n <textarea\r\n value={description}\r\n onChange={(e) => setDescription(e.target.value)}\r\n rows={3}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n\r\n {/* Target Tenant Type */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1\">\r\n {t('tenants.template.targetType')} *\r\n </label>\r\n <select\r\n value={targetTenantType}\r\n onChange={(e) => setTargetTenantType(e.target.value as TenantType)}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"Business\">{t('tenants.type.business')}</option>\r\n <option value=\"Personal\">{t('tenants.type.personal')}</option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n {/* Actions */}\r\n <div className=\"flex items-center gap-3\">\r\n <button\r\n type=\"button\"\r\n onClick={() => navigate('/administration/tenants/template')}\r\n className=\"px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={!code.trim() || !name.trim() || saving}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {saving ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Check className=\"w-4 h-4\" />\r\n )}\r\n {t('common:create')}\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n );\r\n}\r\n","import type { ReactElement } from 'react';\nimport { TenantsPage } from './TenantsPage';\r\n\r\nexport function TenantsBusinessPage(): ReactElement {\r\n return <TenantsPage lockedType=\"Business\" />;\r\n}\r\n","import type { ReactElement } from 'react';\nimport { TenantsPage } from './TenantsPage';\r\n\r\nexport function TenantsPersonalPage(): ReactElement {\r\n return <TenantsPage lockedType=\"Personal\" />;\r\n}\r\n","import type { ReactElement } from 'react';\r\nimport { TenantsPage } from './TenantsPage';\r\n\r\nexport function TenantsOtherPage(): ReactElement {\r\n return <TenantsPage excludeTypes={['Business', 'Personal']} />;\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { PageHeader } from '@/components/ui/PageHeader';\r\nimport { AccessRequestsListTab } from '@/components/platform/administration/access-requests/AccessRequestsListTab';\r\nimport { accessRequestsApi } from '@/services/api/accessRequestsApi';\r\nimport type { AccessRequest } from '@/services/api/accessRequestsApi';\r\nimport { ShieldCheck, Loader2, Filter } from 'lucide-react';\r\n\r\nconst STATUS_FILTERS = ['all', 'Pending', 'Approved', 'Denied'] as const;\r\n\r\nexport function TenantAccessRequestsPage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const [requests, setRequests] = useState<AccessRequest[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [statusFilter, setStatusFilter] = useState<string>('all');\r\n\r\n const loadRequests = useCallback(async () => {\r\n setLoading(true);\r\n try {\r\n const status = statusFilter === 'all' ? undefined : statusFilter;\r\n const data = await accessRequestsApi.getAllRequests(status);\r\n setRequests(Array.isArray(data) ? data : []);\r\n } catch {\r\n setRequests([]);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [statusFilter]);\r\n\r\n useEffect(() => {\r\n loadRequests();\r\n }, [loadRequests]);\r\n\r\n const stats = {\r\n pending: requests.filter(r => r.status === 'Pending').length,\r\n approved: requests.filter(r => r.status === 'Approved').length,\r\n denied: requests.filter(r => r.status === 'Denied').length,\r\n };\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('accessRequests.pageTitle') },\r\n ]}\r\n />\r\n\r\n <PageHeader\r\n title={t('accessRequests.pageTitle')}\r\n icon={<ShieldCheck className=\"w-6 h-6\" />}\r\n />\r\n\r\n {/* Stats cards */}\r\n <div className=\"grid grid-cols-3 gap-4\">\r\n <div className=\"rounded-[var(--radius-card)] p-4 bg-[var(--bg-card)] border border-[var(--warning-border)]\">\r\n <div className=\"text-2xl font-bold text-[var(--warning-text)]\">{stats.pending}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">{t('accessRequests.stats.pending')}</div>\r\n </div>\r\n <div className=\"rounded-[var(--radius-card)] p-4 bg-[var(--bg-card)] border border-[var(--success-border)]\">\r\n <div className=\"text-2xl font-bold text-[var(--success-text)]\">{stats.approved}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">{t('accessRequests.stats.approved')}</div>\r\n </div>\r\n <div className=\"rounded-[var(--radius-card)] p-4 bg-[var(--bg-card)] border border-[var(--error-border)]\">\r\n <div className=\"text-2xl font-bold text-[var(--error-text)]\">{stats.denied}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">{t('accessRequests.stats.denied')}</div>\r\n </div>\r\n </div>\r\n\r\n {/* Status filter */}\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n <div className=\"flex gap-1\">\r\n {STATUS_FILTERS.map((status) => (\r\n <button\r\n key={status}\r\n onClick={() => setStatusFilter(status)}\r\n className={`px-3 py-1.5 rounded-[var(--radius-button)] text-sm font-medium transition-colors ${\r\n statusFilter === status\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n {status === 'all'\r\n ? t('accessRequests.filter.all')\r\n : t(`accessRequests.status.${status.toLowerCase()}`)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Requests table */}\r\n {loading ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (\r\n <AccessRequestsListTab\r\n requests={requests}\r\n loading={false}\r\n onReload={loadRequests}\r\n showTenantColumn\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback, useRef, useMemo } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { useSignalRContext, type NotificationDto as SignalRNotificationDto } from '@/contexts/SignalRContext';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport {\r\n Key,\r\n AlertTriangle,\r\n CheckCircle,\r\n Clock,\r\n Loader2,\r\n RefreshCw,\r\n Settings,\r\n Info,\r\n GitMerge,\r\n Users,\r\n Building2,\r\n Zap,\r\n Lock,\r\n Save,\r\n TestTube,\r\n Eye,\r\n EyeOff,\r\n ExternalLink,\r\n Shield,\r\n Copy,\r\n Check,\r\n Filter,\r\n Play,\r\n History,\r\n Square,\r\n} from 'lucide-react';\r\nimport { createEntraApi } from '@/services/api/entraApi';\r\nimport type {\r\n EntraConfigurationDto,\r\n EntraSyncConflictDto,\r\n ResolveConflictRequest,\r\n EntraSyncStatusDto,\r\n TestConnectionResult,\r\n EntraSyncResultDto,\r\n EntraSyncSessionDto,\r\n} from '@/services/api/entraApi';\r\nimport { ConflictCard, ResolutionModal } from '@/components/platform/administration/entra';\r\n\r\ninterface TenantEntraTabProps {\r\n readonly tenantId: string;\r\n readonly tenantName: string;\r\n readonly tenantSlug: string;\r\n}\r\n\r\n// Permission constants\r\nconst ENTRA_PERMISSIONS = {\r\n READ: 'administration.entra.read',\r\n UPDATE: 'administration.entra.update',\r\n SYNC: 'administration.entra.execute',\r\n};\r\n\r\n// Entra sync notification types\r\nconst ENTRA_SYNC_TYPES = {\r\n STARTED: 'EntraSyncStarted',\r\n COMPLETED: 'EntraSyncCompleted',\r\n FAILED: 'EntraSyncFailed',\r\n};\r\n\r\n// Required Graph API permissions\r\nconst REQUIRED_PERMISSIONS = [\r\n { code: 'User.Read.All', descriptionKey: 'userReadAll' },\r\n { code: 'Group.Read.All', descriptionKey: 'groupReadAll' },\r\n { code: 'GroupMember.Read.All', descriptionKey: 'groupMemberReadAll' },\r\n];\r\n\r\n// User types for sync\r\nconst USER_TYPES = [\r\n { id: 'member', labelKey: 'userTypes.member', descriptionKey: 'userTypes.memberDescription', supported: true },\r\n { id: 'guest', labelKey: 'userTypes.guest', descriptionKey: 'userTypes.guestDescription', supported: true },\r\n];\r\n\r\nconst calculateElapsedTime = (startedAt: Date): string => {\r\n const now = Date.now();\r\n const start = startedAt.getTime();\r\n const diffSeconds = Math.floor((now - start) / 1000);\r\n const minutes = Math.floor(diffSeconds / 60);\r\n const seconds = diffSeconds % 60;\r\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\r\n};\r\n\r\nconst handleEntraNotification = (\r\n notification: SignalRNotificationDto,\r\n setActiveSyncSession: any,\r\n loadData: () => void\r\n) => {\r\n if (notification.type === ENTRA_SYNC_TYPES.STARTED) {\r\n setActiveSyncSession({\r\n sessionId: notification.relatedEntityId || '',\r\n startedAt: new Date(notification.createdAt),\r\n });\r\n } else if (notification.type === ENTRA_SYNC_TYPES.COMPLETED || notification.type === ENTRA_SYNC_TYPES.FAILED) {\r\n setActiveSyncSession(null);\r\n loadData();\r\n }\r\n};\r\n\r\n// ============================================\r\n// Sub-tab Navigation\r\n// ============================================\r\n\r\ntype SubTabId = 'config' | 'sync' | 'users' | 'groups';\r\n\r\ninterface SubTab {\r\n id: SubTabId;\r\n label: string;\r\n icon: LucideIcon;\r\n permission: string;\r\n}\r\n\r\n// ============================================\r\n// Reusable Components\r\n// ============================================\r\n\r\ninterface SectionCardProps {\r\n readonly icon: LucideIcon;\r\n readonly title: string;\r\n readonly description?: string;\r\n readonly action?: React.ReactNode;\r\n readonly children: React.ReactNode;\r\n readonly className?: string;\r\n}\r\n\r\nfunction SectionCard({ icon: Icon, title, description, action, children, className = '' }: SectionCardProps) {\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] shadow-sm overflow-hidden ${className}`}>\r\n <div className=\"px-6 py-4 border-b border-[var(--border-subtle)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30\">\r\n <Icon className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <div>\r\n <h2 className=\"text-base font-semibold text-[var(--text-primary)]\">{title}</h2>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n </div>\r\n {action}\r\n </div>\r\n </div>\r\n <div className=\"p-6\">\r\n {children}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\ninterface ToggleProps {\r\n readonly checked: boolean;\r\n readonly onChange: () => void;\r\n readonly label: string;\r\n readonly description?: string;\r\n readonly disabled?: boolean;\r\n}\r\n\r\nfunction Toggle({ checked, onChange, label, description, disabled }: ToggleProps) {\r\n return (\r\n <div className=\"flex items-center justify-between py-3\">\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <label className=\"text-sm font-medium text-[var(--text-primary)]\">{label}</label>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n role=\"switch\"\r\n aria-checked={checked}\r\n onClick={onChange}\r\n disabled={disabled}\r\n className={`relative inline-flex h-6 w-11 flex-shrink-0 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] focus:ring-offset-2 focus:ring-offset-[var(--bg-primary)] disabled:opacity-50 disabled:cursor-not-allowed ${\r\n checked ? 'bg-[var(--color-accent-600)]' : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <span\r\n className={`inline-block h-4 w-4 transform rounded-full bg-white shadow-md transition-transform ${\r\n checked ? 'translate-x-6' : 'translate-x-1'\r\n }`}\r\n />\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\nconst isValidGuid = (value: string): boolean => {\r\n if (!value) return true;\r\n const guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\r\n return guidRegex.test(value);\r\n};\r\n\r\n// ============================================\r\n// Configuration Sub-Tab (Editable)\r\n// ============================================\r\n\r\n// Type for the entra API instance\r\ntype EntraApiInstance = ReturnType<typeof createEntraApi>;\r\n\r\ninterface ConfigTabProps {\r\n readonly config: EntraConfigurationDto | null;\r\n readonly loading: boolean;\r\n readonly canEdit: boolean;\r\n readonly onRefresh: () => void;\r\n readonly onConfigUpdated: () => void;\r\n readonly t: (key: string, options?: Record<string, unknown>) => string;\r\n readonly entraApi: EntraApiInstance;\r\n}\r\n\r\nconst ConfigTabReadOnly = ({ config, loading, canEdit, onRefresh, onEdit, t }: {\r\n config: EntraConfigurationDto | null;\r\n loading: boolean;\r\n canEdit: boolean;\r\n onRefresh: () => void;\r\n onEdit: () => void;\r\n t: (key: string, options?: Record<string, unknown>) => string;\r\n}) => (\r\n <SectionCard\r\n icon={Key}\r\n title={t('admin:tenants.entra.configuration.title')}\r\n description={t('admin:tenants.entra.configuration.description')}\r\n action={\r\n <div className=\"flex flex-col sm:flex-row items-stretch sm:items-center gap-2\">\r\n {canEdit && (\r\n <button\r\n onClick={onEdit}\r\n className=\"inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors\"\r\n >\r\n <Settings className=\"w-4 h-4\" />\r\n <span className=\"sm:inline\">{t('admin:tenants.entra.configuration.edit')}</span>\r\n </button>\r\n )}\r\n <button\r\n onClick={onRefresh}\r\n disabled={loading}\r\n className=\"inline-flex items-center justify-center gap-2 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-secondary)] hover:bg-[var(--bg-tertiary)] transition-colors disabled:opacity-50\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\r\n <span className=\"sm:inline\">{t('common:refresh')}</span>\r\n </button>\r\n </div>\r\n }\r\n >\r\n {config ? (\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n {config.isConfigured ? (\r\n <>\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.entra.configuration.configured')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.configuration.connectedTo', { tenantId: config.tenantId })}\r\n </p>\r\n </div>\r\n </>\r\n ) : (\r\n <>\r\n <Info className=\"w-5 h-5 text-[var(--warning-text)]\" />\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.entra.configuration.notConfigured')}\r\n </p>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.configuration.notConfiguredHint')}\r\n </p>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n\r\n {config.isConfigured && (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4\">\r\n <div className=\"p-3 sm:p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <Clock className=\"w-4 h-4 text-[var(--text-tertiary)] flex-shrink-0\" />\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.entra.configuration.syncStatus')}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {config.syncEnabled\r\n ? t('admin:tenants.entra.configuration.syncEnabled')\r\n : t('admin:tenants.entra.configuration.syncDisabled')}\r\n </p>\r\n </div>\r\n\r\n <div className=\"p-3 sm:p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <Settings className=\"w-4 h-4 text-[var(--text-tertiary)] flex-shrink-0\" />\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.entra.configuration.syncInterval')}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {config.syncIntervalMinutes} {t('common:minutes')}\r\n </p>\r\n </div>\r\n\r\n <div className=\"p-3 sm:p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)] sm:col-span-2 lg:col-span-1\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <GitMerge className=\"w-4 h-4 text-[var(--text-tertiary)] flex-shrink-0\" />\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.entra.configuration.conflictResolution')}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t(`entra:settings.conflictResolutions.${config.defaultConflictResolution?.toLowerCase() ?? 'manualreview'}`)}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.configuration.noData')}\r\n </p>\r\n )}\r\n </SectionCard>\r\n);\r\n\r\nfunction ConfigTab({ config, loading, canEdit, onRefresh, onConfigUpdated, t, entraApi }: ConfigTabProps) {\r\n const [editing, setEditing] = useState(false);\r\n const [saving, setSaving] = useState(false);\r\n const [testing, setTesting] = useState(false);\r\n const [testResult, setTestResult] = useState<TestConnectionResult | null>(null);\r\n const [showSecret, setShowSecret] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n const [copiedPermission, setCopiedPermission] = useState<string | null>(null);\r\n const [hasExistingSecret, setHasExistingSecret] = useState(config?.hasClientSecret ?? false);\r\n const [validationErrors, setValidationErrors] = useState<{ tenantId?: string; clientId?: string }>({});\r\n\r\n const [credentials, setCredentials] = useState({\r\n tenantId: config?.tenantId || '',\r\n clientId: config?.clientId || '',\r\n clientSecret: '',\r\n });\r\n\r\n const [syncSettings, setSyncSettings] = useState({\r\n syncEnabled: config?.syncEnabled ?? false,\r\n syncIntervalMinutes: config?.syncIntervalMinutes ?? 60,\r\n useDeltaSync: config?.useDeltaSync ?? true,\r\n defaultConflictResolution: (config?.defaultConflictResolution ?? 'ManualReview') as 'ManualReview' | 'EntraWins' | 'LocalWins',\r\n autoCreateReferences: config?.autoCreateReferences ?? true,\r\n syncOnlyActiveUsers: config?.syncOnlyActiveUsers ?? true,\r\n syncUserTypes: config?.syncUserTypes ?? 'member',\r\n });\r\n\r\n useEffect(() => {\r\n if (!config) return;\r\n setCredentials({\r\n tenantId: config.tenantId || '',\r\n clientId: config.clientId || '',\r\n clientSecret: '',\r\n });\r\n setHasExistingSecret(config.hasClientSecret);\r\n setSyncSettings({\r\n syncEnabled: config.syncEnabled,\r\n syncIntervalMinutes: config.syncIntervalMinutes,\r\n useDeltaSync: config.useDeltaSync,\r\n defaultConflictResolution: config.defaultConflictResolution as 'ManualReview' | 'EntraWins' | 'LocalWins',\r\n autoCreateReferences: config.autoCreateReferences,\r\n syncOnlyActiveUsers: config.syncOnlyActiveUsers ?? true,\r\n syncUserTypes: config.syncUserTypes ?? 'member',\r\n });\r\n }, [config]);\r\n\r\n const validateField = (field: 'tenantId' | 'clientId', value: string) => {\r\n const errorKey = !isValidGuid(value) ? t('entra:settings.invalidGuidFormat') : undefined;\r\n setValidationErrors(prev => ({ ...prev, [field]: errorKey }));\r\n };\r\n\r\n const handleCredentialChange = (field: keyof typeof credentials, value: string) => {\r\n setCredentials(prev => ({ ...prev, [field]: value }));\r\n if (field === 'tenantId' || field === 'clientId') {\r\n validateField(field, value);\r\n }\r\n };\r\n\r\n const hasValidationErrors = Boolean(validationErrors.tenantId || validationErrors.clientId);\r\n const canTestConnection = !testing && !hasValidationErrors && credentials.tenantId && credentials.clientId && (credentials.clientSecret || hasExistingSecret);\r\n const canSaveCredentials = !saving && !hasValidationErrors && credentials.tenantId && credentials.clientId && credentials.clientSecret;\r\n\r\n const handleCopyPermission = async (code: string) => {\r\n try {\r\n await navigator.clipboard.writeText(code);\r\n setCopiedPermission(code);\r\n setTimeout(() => setCopiedPermission(null), 2000);\r\n } catch (err) {\r\n console.error('Failed to copy:', err instanceof Error ? err.message : 'Unknown error');\r\n }\r\n };\r\n\r\n const handleTestConnection = async () => {\r\n if (!canTestConnection) return;\r\n setTesting(true);\r\n setTestResult(null);\r\n setError(null);\r\n setSuccess(null);\r\n try {\r\n const result = credentials.clientSecret\r\n ? await entraApi.settings.testConnection({\r\n tenantId: credentials.tenantId,\r\n clientId: credentials.clientId,\r\n clientSecret: credentials.clientSecret,\r\n })\r\n : await entraApi.settings.testStoredConnection();\r\n setTestResult(result);\r\n if (result.success) {\r\n setSuccess(t('entra:settings.testSuccess'));\r\n } else {\r\n setError(result.errorMessage || t('entra:settings.testFailed'));\r\n }\r\n } catch (err) {\r\n console.error('Connection test failed:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('entra:settings.testFailed'));\r\n } finally {\r\n setTesting(false);\r\n }\r\n };\r\n\r\n const handleSaveCredentials = async () => {\r\n if (!canSaveCredentials) return;\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n try {\r\n await entraApi.settings.saveCredentials({\r\n tenantId: credentials.tenantId,\r\n clientId: credentials.clientId,\r\n clientSecret: credentials.clientSecret,\r\n });\r\n setSuccess(t('entra:settings.credentialsSaved'));\r\n setHasExistingSecret(true);\r\n setCredentials(prev => ({ ...prev, clientSecret: '' }));\r\n onConfigUpdated();\r\n } catch (err) {\r\n console.error('Failed to save credentials:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('entra:settings.saveError'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleSaveSettings = async () => {\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n try {\r\n await entraApi.settings.saveSyncSettings({\r\n syncEnabled: syncSettings.syncEnabled,\r\n syncIntervalMinutes: syncSettings.syncIntervalMinutes,\r\n useDeltaSync: syncSettings.useDeltaSync,\r\n defaultConflictResolution: syncSettings.defaultConflictResolution,\r\n autoCreateReferences: syncSettings.autoCreateReferences,\r\n syncOnlyActiveUsers: syncSettings.syncOnlyActiveUsers,\r\n syncUserTypes: syncSettings.syncUserTypes,\r\n });\r\n setSuccess(t('entra:settings.settingsSaved'));\r\n onConfigUpdated();\r\n } catch (err) {\r\n console.error('Failed to save settings:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('entra:settings.saveError'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n if (!canEdit || !editing) {\r\n return <ConfigTabReadOnly config={config} loading={loading} canEdit={canEdit} onRefresh={onRefresh} onEdit={() => setEditing(true)} t={t} />;\r\n }\r\n\r\n // Editing view\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Required Permissions Warning */}\r\n <div className=\"rounded-[var(--radius-card)] border-2 border-[var(--warning-border)] bg-[var(--warning-bg)] p-4\">\r\n <div className=\"flex items-start gap-4\">\r\n <Shield className=\"w-5 h-5 text-[var(--warning-text)] mt-0.5\" />\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center justify-between gap-4 mb-2\">\r\n <h3 className=\"font-semibold text-[var(--warning-text)]\">\r\n {t('entra:settings.permissionsWarningTitle')}\r\n </h3>\r\n <a\r\n href=\"https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade\"\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--warning-border)] text-[var(--warning-text)] hover:opacity-80 transition-opacity\"\r\n >\r\n {t('entra:settings.configureInAzure')}\r\n <ExternalLink className=\"w-3.5 h-3.5\" />\r\n </a>\r\n </div>\r\n <p className=\"text-sm text-[var(--warning-text)] opacity-90 mb-3\">\r\n {t('entra:settings.permissionsWarningDescription')}\r\n </p>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {REQUIRED_PERMISSIONS.map((perm) => (\r\n <button\r\n key={perm.code}\r\n onClick={() => handleCopyPermission(perm.code)}\r\n className=\"group inline-flex items-center gap-2 px-3 py-2 rounded-[var(--radius-button)] bg-[var(--bg-primary)] border border-[var(--warning-border)] hover:shadow-sm transition-all\"\r\n >\r\n <code className=\"text-sm font-mono font-medium text-[var(--text-primary)]\">{perm.code}</code>\r\n {copiedPermission === perm.code ? (\r\n <Check className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n ) : (\r\n <Copy className=\"w-4 h-4 text-[var(--warning-text)]\" />\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Error/Success Messages */}\r\n {error && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">{error}</span>\r\n </div>\r\n )}\r\n {success && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n <span className=\"text-sm text-[var(--success-text)]\">{success}</span>\r\n </div>\r\n )}\r\n\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {/* Credentials Section */}\r\n <SectionCard icon={Key} title={t('entra:settings.credentials')} description=\"Azure AD Application\">\r\n <div className=\"space-y-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('entra:settings.tenantId')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n autoComplete=\"off\"\r\n value={credentials.tenantId}\r\n onChange={(e) => handleCredentialChange('tenantId', e.target.value)}\r\n placeholder=\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:border-transparent transition-shadow ${\r\n validationErrors.tenantId ? 'border-[var(--error-border)] focus:ring-[var(--error-border)]' : 'border-[var(--border-color)] focus:ring-[var(--color-accent-500)]'\r\n }`}\r\n />\r\n {validationErrors.tenantId && (\r\n <p className=\"mt-1.5 text-xs text-[var(--error-text)]\">{validationErrors.tenantId}</p>\r\n )}\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('entra:settings.clientId')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n autoComplete=\"off\"\r\n value={credentials.clientId}\r\n onChange={(e) => handleCredentialChange('clientId', e.target.value)}\r\n placeholder=\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:border-transparent transition-shadow ${\r\n validationErrors.clientId ? 'border-[var(--error-border)] focus:ring-[var(--error-border)]' : 'border-[var(--border-color)] focus:ring-[var(--color-accent-500)]'\r\n }`}\r\n />\r\n {validationErrors.clientId && (\r\n <p className=\"mt-1.5 text-xs text-[var(--error-text)]\">{validationErrors.clientId}</p>\r\n )}\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('entra:settings.clientSecret')}\r\n {hasExistingSecret && (\r\n <span className=\"ml-2 inline-flex items-center gap-1 text-xs text-[var(--success-text)]\">\r\n <CheckCircle className=\"w-3 h-3\" />\r\n {t('common:configured')}\r\n </span>\r\n )}\r\n </label>\r\n <div className=\"relative\">\r\n <input\r\n type={showSecret ? 'text' : 'password'}\r\n autoComplete=\"new-password\"\r\n value={credentials.clientSecret}\r\n onChange={(e) => handleCredentialChange('clientSecret', e.target.value)}\r\n placeholder={hasExistingSecret ? '••••••••••••••••' : 'OvA8Q~xxxxxxxxxxxx'}\r\n className=\"w-full px-3 py-2.5 pr-10 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow\"\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowSecret(!showSecret)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 text-[var(--text-tertiary)] hover:text-[var(--text-primary)]\"\r\n >\r\n {showSecret ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex flex-col sm:flex-row items-stretch sm:items-center gap-2 sm:gap-3 pt-2\">\r\n <button\r\n onClick={handleTestConnection}\r\n disabled={testing || hasValidationErrors || !credentials.tenantId || !credentials.clientId || (!credentials.clientSecret && !hasExistingSecret)}\r\n className=\"inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {testing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <TestTube className=\"w-4 h-4\" />}\r\n {t('entra:settings.testConnection')}\r\n </button>\r\n <button\r\n onClick={handleSaveCredentials}\r\n disabled={saving || hasValidationErrors || !credentials.tenantId || !credentials.clientId || !credentials.clientSecret}\r\n className=\"inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common:save')}\r\n </button>\r\n </div>\r\n\r\n {testResult?.success && (\r\n <div className=\"mt-4 p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n <span className=\"font-medium text-[var(--success-text)]\">{t('entra:settings.connectionSuccessful')}</span>\r\n </div>\r\n <div className=\"grid grid-cols-3 gap-3 text-sm\">\r\n {testResult.tenantName && <div><span className=\"text-[var(--text-tertiary)]\">Tenant:</span> {testResult.tenantName}</div>}\r\n {testResult.userCount !== null && <div><span className=\"text-[var(--text-tertiary)]\">Users:</span> {testResult.userCount}</div>}\r\n {testResult.groupCount !== null && <div><span className=\"text-[var(--text-tertiary)]\">Groups:</span> {testResult.groupCount}</div>}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Sync Settings */}\r\n <div className=\"space-y-6\">\r\n <SectionCard icon={Clock} title={t('entra:settings.syncSettings')} description=\"Scheduling & Performance\">\r\n <div className=\"divide-y divide-[var(--border-subtle)]\">\r\n <Toggle\r\n checked={syncSettings.syncEnabled}\r\n onChange={() => setSyncSettings(prev => ({ ...prev, syncEnabled: !prev.syncEnabled }))}\r\n label={t('entra:settings.syncEnabled')}\r\n description={t('entra:settings.syncEnabledHelp')}\r\n />\r\n <div className=\"py-4\">\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {t('entra:settings.syncInterval')}\r\n </label>\r\n <select\r\n value={syncSettings.syncIntervalMinutes}\r\n onChange={(e) => setSyncSettings(prev => ({ ...prev, syncIntervalMinutes: Number(e.target.value) }))}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value={15} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">15 {t('common:minutes')}</option>\r\n <option value={30} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">30 {t('common:minutes')}</option>\r\n <option value={60} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">1 {t('common:hour')}</option>\r\n <option value={120} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">2 {t('common:hours')}</option>\r\n <option value={360} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">6 {t('common:hours')}</option>\r\n <option value={720} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">12 {t('common:hours')}</option>\r\n <option value={1440} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">24 {t('common:hours')}</option>\r\n </select>\r\n </div>\r\n <Toggle\r\n checked={syncSettings.useDeltaSync}\r\n onChange={() => setSyncSettings(prev => ({ ...prev, useDeltaSync: !prev.useDeltaSync }))}\r\n label={t('entra:settings.useDeltaSync')}\r\n description={t('entra:settings.useDeltaSyncHelp')}\r\n />\r\n </div>\r\n </SectionCard>\r\n\r\n <SectionCard icon={GitMerge} title={t('entra:settings.conflictResolution')} description=\"Data Priority\">\r\n <select\r\n value={syncSettings.defaultConflictResolution}\r\n onChange={(e) => setSyncSettings(prev => ({ ...prev, defaultConflictResolution: e.target.value as 'ManualReview' | 'EntraWins' | 'LocalWins' }))}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"ManualReview\" className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">{t('entra:settings.conflictResolutions.manualReview')}</option>\r\n <option value=\"EntraWins\" className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">{t('entra:settings.conflictResolutions.entraWins')}</option>\r\n <option value=\"LocalWins\" className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">{t('entra:settings.conflictResolutions.localWins')}</option>\r\n </select>\r\n </SectionCard>\r\n\r\n <SectionCard icon={Filter} title={t('entra:settings.userSyncFilters')} description=\"User Types\">\r\n <div className=\"space-y-4\">\r\n <Toggle\r\n checked={syncSettings.syncOnlyActiveUsers}\r\n onChange={() => setSyncSettings(prev => ({ ...prev, syncOnlyActiveUsers: !prev.syncOnlyActiveUsers }))}\r\n label={t('entra:settings.syncOnlyActiveUsers')}\r\n description={t('entra:settings.syncOnlyActiveUsersHelp')}\r\n />\r\n <div className=\"space-y-2 pt-2 border-t border-[var(--border-subtle)]\">\r\n {USER_TYPES.map((userType) => {\r\n const selectedTypes = syncSettings.syncUserTypes.split(',').map(s => s.trim()).filter(Boolean);\r\n const isChecked = selectedTypes.includes(userType.id);\r\n return (\r\n <label\r\n key={userType.id}\r\n className={`flex items-center gap-3 p-3 rounded-[var(--radius-button)] border cursor-pointer transition-all ${\r\n isChecked ? 'border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20' : 'border-[var(--border-color)] bg-[var(--bg-secondary)] hover:bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={isChecked}\r\n onChange={() => {\r\n let newTypes = isChecked\r\n ? selectedTypes.filter(t => t !== userType.id)\r\n : [...selectedTypes, userType.id];\r\n if (newTypes.length === 0) newTypes = ['member'];\r\n setSyncSettings(prev => ({ ...prev, syncUserTypes: newTypes.join(',') }));\r\n }}\r\n className=\"w-4 h-4 rounded border-[var(--border-color)] text-[var(--color-accent-600)]\"\r\n />\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t(`entra:settings.${userType.labelKey}`)}\r\n </span>\r\n </label>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n </SectionCard>\r\n\r\n <div className=\"flex flex-col-reverse sm:flex-row items-stretch sm:items-center gap-2 sm:gap-3\">\r\n <button\r\n onClick={() => setEditing(false)}\r\n className=\"px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)] transition-colors text-center\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n onClick={handleSaveSettings}\r\n disabled={saving}\r\n className=\"inline-flex items-center justify-center gap-2 px-6 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 transition-colors shadow-sm\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common:save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Sync Status Badge & Icon Helpers\r\n// ============================================\r\n\r\nconst StatusBadgeMap = {\r\n Completed: { bg: 'bg-[var(--success-bg)]', text: 'text-[var(--success-text)]', icon: CheckCircle },\r\n PartiallyCompleted: { bg: 'bg-[var(--warning-bg)]', text: 'text-[var(--warning-text)]', icon: AlertTriangle },\r\n Failed: { bg: 'bg-[var(--error-bg)]', text: 'text-[var(--error-text)]', icon: AlertTriangle },\r\n InProgress: { bg: 'bg-[var(--color-accent-100)]', text: 'text-[var(--color-accent-700)]', icon: Loader2 },\r\n Cancelled: { bg: 'bg-[var(--bg-tertiary)]', text: 'text-[var(--text-tertiary)]', icon: Square },\r\n};\r\n\r\nconst SyncStatusIconMap = {\r\n Success: <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />,\r\n Failed: <AlertTriangle className=\"w-4 h-4 text-[var(--error-text)]\" />,\r\n Running: <Loader2 className=\"w-4 h-4 text-[var(--color-accent-500)] animate-spin\" />,\r\n};\r\n\r\nconst getStatusBadge = (status: string, t: (key: string) => string) => {\r\n const badge = StatusBadgeMap[status as keyof typeof StatusBadgeMap];\r\n if (!badge) {\r\n return <span className=\"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--bg-tertiary)] text-[var(--text-tertiary)]\">{status}</span>;\r\n }\r\n const Icon = badge.icon;\r\n const label = t(`admin:tenants.entra.history.${status.toLowerCase()}`);\r\n return <span className={`inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full ${badge.bg} ${badge.text}`}><Icon className={badge.icon === Loader2 ? \"w-3 h-3 animate-spin\" : \"w-3 h-3\"} /> {label}</span>;\r\n};\r\n\r\nconst getSyncStatusIcon = (status: string) => {\r\n return SyncStatusIconMap[status as keyof typeof SyncStatusIconMap] || <Clock className=\"w-4 h-4 text-[var(--text-tertiary)]\" />;\r\n};\r\n\r\n// ============================================\r\n// Sync Sub-Tab\r\n// ============================================\r\n\r\ninterface SyncTabProps {\r\n readonly config: EntraConfigurationDto | null;\r\n readonly conflicts: EntraSyncConflictDto[];\r\n readonly syncStatus: EntraSyncStatusDto[];\r\n readonly loading: boolean;\r\n readonly canSync: boolean;\r\n readonly onRefresh: () => void;\r\n readonly onResolveConflict: (conflict: EntraSyncConflictDto) => void;\r\n readonly onSyncAll: () => Promise<EntraSyncResultDto | null>;\r\n readonly onLoadHistory: (page: number, pageSize: number) => Promise<{ sessions: EntraSyncSessionDto[]; totalCount: number } | null>;\r\n readonly onCancelSession: (sessionId: string) => Promise<boolean>;\r\n readonly activeSyncSession: { sessionId: string; startedAt: Date } | null;\r\n readonly t: (key: string, options?: Record<string, unknown>) => string;\r\n}\r\n\r\nconst formatDuration = (startedAt: string, completedAt: string | null): string => {\r\n if (!completedAt) return '-';\r\n const start = new Date(startedAt).getTime();\r\n const end = new Date(completedAt).getTime();\r\n const diffMs = end - start;\r\n if (diffMs < 1000) return `${diffMs}ms`;\r\n if (diffMs < 60000) return `${Math.round(diffMs / 1000)}s`;\r\n return `${Math.round(diffMs / 60000)}m`;\r\n};\r\n\r\nconst useSyncTabState = () => {\r\n const [syncing, setSyncing] = useState(false);\r\n const [lastSyncResult, setLastSyncResult] = useState<EntraSyncResultDto | null>(null);\r\n const [syncError, setSyncError] = useState<string | null>(null);\r\n const [history, setHistory] = useState<EntraSyncSessionDto[]>([]);\r\n const [historyLoading, setHistoryLoading] = useState(false);\r\n const [historyPage, setHistoryPage] = useState(1);\r\n const [historyTotalCount, setHistoryTotalCount] = useState(0);\r\n const [cancellingSessionId, setCancellingSessionId] = useState<string | null>(null);\r\n\r\n return {\r\n syncing, setSyncing, lastSyncResult, setLastSyncResult, syncError, setSyncError,\r\n history, setHistory, historyLoading, setHistoryLoading, historyPage, setHistoryPage,\r\n historyTotalCount, setHistoryTotalCount, cancellingSessionId, setCancellingSessionId\r\n };\r\n};\r\n\r\nfunction SyncTab({ config, conflicts, syncStatus, loading, canSync, onRefresh, onResolveConflict, onSyncAll, onLoadHistory, onCancelSession, activeSyncSession, t }: SyncTabProps) {\r\n const {\r\n syncing, setSyncing, lastSyncResult, setLastSyncResult, syncError, setSyncError,\r\n history, setHistory, historyLoading, setHistoryLoading, historyPage, setHistoryPage,\r\n historyTotalCount, setHistoryTotalCount, cancellingSessionId, setCancellingSessionId\r\n } = useSyncTabState();\r\n const historyPageSize = 5;\r\n\r\n const loadHistory = useCallback(async (page: number) => {\r\n setHistoryLoading(true);\r\n try {\r\n const result = await onLoadHistory(page, historyPageSize);\r\n if (!result) return;\r\n setHistory(result.sessions);\r\n setHistoryTotalCount(result.totalCount);\r\n setHistoryPage(page);\r\n } catch (err) {\r\n console.error('Failed to load history:', err);\r\n } finally {\r\n setHistoryLoading(false);\r\n }\r\n }, [onLoadHistory]);\r\n\r\n useEffect(() => {\r\n if (config?.isConfigured) {\r\n loadHistory(1);\r\n }\r\n }, [config?.isConfigured, loadHistory]);\r\n\r\n const handleSyncNow = async () => {\r\n setSyncing(true);\r\n setSyncError(null);\r\n setLastSyncResult(null);\r\n try {\r\n const result = await onSyncAll();\r\n if (!result) return;\r\n setLastSyncResult(result);\r\n onRefresh();\r\n loadHistory(1);\r\n } catch (err) {\r\n console.error('Sync failed:', err instanceof Error ? err.message : 'Unknown error');\r\n setSyncError(t('admin:tenants.entra.sync.syncFailed'));\r\n } finally {\r\n setSyncing(false);\r\n }\r\n };\r\n\r\n const handleCancelSession = async (sessionId: string) => {\r\n setCancellingSessionId(sessionId);\r\n try {\r\n const success = await onCancelSession(sessionId);\r\n if (success) {\r\n loadHistory(historyPage);\r\n }\r\n } catch (err) {\r\n console.error('Failed to cancel session:', err instanceof Error ? err.message : 'Unknown error');\r\n } finally {\r\n setCancellingSessionId(null);\r\n }\r\n };\r\n\r\n if (!config?.isConfigured) {\r\n return (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <Info className=\"w-5 h-5 text-[var(--warning-text)]\" />\r\n <span className=\"text-sm text-[var(--warning-text)]\">\r\n {t('admin:tenants.entra.sync.configureFirst')}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Sync Actions Card */}\r\n <SectionCard\r\n icon={Play}\r\n title={t('admin:tenants.entra.sync.actionsTitle')}\r\n description={t('admin:tenants.entra.sync.actionsDescription')}\r\n >\r\n <div className=\"space-y-4\">\r\n {/* Sync Button */}\r\n <div className=\"flex flex-col sm:flex-row items-start sm:items-center gap-3 sm:gap-4\">\r\n <button\r\n onClick={handleSyncNow}\r\n disabled={syncing || activeSyncSession !== null || !canSync}\r\n className=\"w-full sm:w-auto inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {syncing || activeSyncSession ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Play className=\"w-4 h-4\" />\r\n )}\r\n {syncing || activeSyncSession ? t('admin:tenants.entra.sync.syncing') : t('admin:tenants.entra.sync.syncNow')}\r\n </button>\r\n {!canSync && (\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">\r\n {t('admin:tenants.entra.sync.noSyncPermission')}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Sync Error */}\r\n {syncError && (\r\n <div className=\"flex items-center gap-3 p-3 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertTriangle className=\"w-4 h-4 text-[var(--error-text)]\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">{syncError}</span>\r\n </div>\r\n )}\r\n\r\n {/* Last Sync Result */}\r\n {lastSyncResult && (\r\n <div className={`p-4 rounded-[var(--radius-card)] border ${lastSyncResult.success ? 'bg-[var(--success-bg)] border-[var(--success-border)]' : 'bg-[var(--error-bg)] border-[var(--error-border)]'}`}>\r\n <div className=\"flex items-center gap-2 mb-3\">\r\n {lastSyncResult.success ? (\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n )}\r\n <span className={`font-medium ${lastSyncResult.success ? 'text-[var(--success-text)]' : 'text-[var(--error-text)]'}`}>\r\n {lastSyncResult.success ? t('admin:tenants.entra.sync.syncSuccess') : t('admin:tenants.entra.sync.syncFailed')}\r\n </span>\r\n </div>\r\n <div className=\"grid grid-cols-3 sm:grid-cols-5 gap-2 sm:gap-3 text-sm\">\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)] text-center sm:text-left\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.created')}</span>\r\n <p className=\"font-semibold text-[var(--success-text)]\">+{lastSyncResult.created}</p>\r\n </div>\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)] text-center sm:text-left\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.updated')}</span>\r\n <p className=\"font-semibold text-[var(--color-accent-600)]\">~{lastSyncResult.updated}</p>\r\n </div>\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)] text-center sm:text-left\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.deleted')}</span>\r\n <p className=\"font-semibold text-[var(--error-text)]\">-{lastSyncResult.deleted}</p>\r\n </div>\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)] text-center sm:text-left\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.skipped')}</span>\r\n <p className=\"font-semibold text-[var(--text-secondary)]\">{lastSyncResult.skipped}</p>\r\n </div>\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)] text-center sm:text-left col-span-3 sm:col-span-1\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.conflicts')}</span>\r\n <p className={`font-semibold ${lastSyncResult.conflicts > 0 ? 'text-[var(--warning-text)]' : 'text-[var(--text-primary)]'}`}>{lastSyncResult.conflicts}</p>\r\n </div>\r\n </div>\r\n {lastSyncResult.errorMessage && (\r\n <p className=\"mt-3 text-sm text-[var(--error-text)]\">{lastSyncResult.errorMessage}</p>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Sync Status Card */}\r\n <SectionCard\r\n icon={Zap}\r\n title={t('admin:tenants.entra.sync.statusTitle')}\r\n description={t('admin:tenants.entra.sync.statusDescription')}\r\n action={\r\n <button\r\n onClick={onRefresh}\r\n disabled={loading}\r\n className=\"inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-secondary)] hover:bg-[var(--bg-tertiary)] transition-colors disabled:opacity-50\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\r\n {t('common:refresh')}\r\n </button>\r\n }\r\n >\r\n {syncStatus.length > 0 ? (\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n {syncStatus.map((status) => (\r\n <div\r\n key={status.resourceType}\r\n className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\"\r\n >\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t(`entra:resourceTypes.${status.resourceType.toLowerCase()}`)}\r\n </span>\r\n {getSyncStatusIcon(status.status)}\r\n </div>\r\n <div className=\"space-y-1 text-xs text-[var(--text-tertiary)]\">\r\n <p>{t('admin:tenants.entra.sync.itemsSynced', { count: status.totalItemsSynced })}</p>\r\n {status.lastFullSyncAt && (\r\n <p>{t('admin:tenants.entra.sync.lastSync', { date: new Date(status.lastFullSyncAt).toLocaleDateString() })}</p>\r\n )}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n ) : (\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.sync.noStatus')}\r\n </p>\r\n )}\r\n </SectionCard>\r\n\r\n <SectionCard\r\n icon={AlertTriangle}\r\n title={t('admin:tenants.entra.conflicts.title')}\r\n description={t('admin:tenants.entra.conflicts.description', { count: conflicts.length })}\r\n >\r\n {conflicts.length === 0 ? (\r\n <div className=\"text-center py-8\">\r\n <div className=\"mx-auto w-12 h-12 rounded-full bg-[var(--success-bg)] flex items-center justify-center mb-3\">\r\n <CheckCircle className=\"w-6 h-6 text-[var(--success-text)]\" />\r\n </div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-1\">\r\n {t('entra:conflicts.noConflicts')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:conflicts.noConflictsDescription')}\r\n </p>\r\n </div>\r\n ) : (\r\n <div className=\"space-y-4\">\r\n {conflicts.map((conflict) => (\r\n <ConflictCard\r\n key={conflict.id}\r\n conflict={conflict}\r\n onResolve={onResolveConflict}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </SectionCard>\r\n\r\n {/* Sync History Card */}\r\n <SectionCard\r\n icon={History}\r\n title={t('admin:tenants.entra.history.title')}\r\n description={t('admin:tenants.entra.history.description')}\r\n action={\r\n <button\r\n onClick={() => loadHistory(historyPage)}\r\n disabled={historyLoading}\r\n className=\"inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-secondary)] hover:bg-[var(--bg-tertiary)] transition-colors disabled:opacity-50\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${historyLoading ? 'animate-spin' : ''}`} />\r\n {t('common:refresh')}\r\n </button>\r\n }\r\n >\r\n {historyLoading && history.length === 0 && (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n )}\r\n {!(historyLoading && history.length === 0) && history.length === 0 && (\r\n <div className=\"text-center py-8\">\r\n <div className=\"mx-auto w-12 h-12 rounded-full bg-[var(--bg-tertiary)] flex items-center justify-center mb-3\">\r\n <History className=\"w-6 h-6 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.history.noHistory')}\r\n </p>\r\n </div>\r\n )}\r\n {history.length > 0 && (\r\n <div className=\"space-y-4\">\r\n {/* Mobile: Card-based layout */}\r\n <div className=\"block sm:hidden space-y-3\">\r\n {history.map((session) => (\r\n <div key={session.id} className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <div className=\"flex items-center gap-2\">\r\n {session.isFullSync ? (\r\n <span className=\"px-2 py-0.5 text-xs rounded bg-[var(--color-accent-100)] text-[var(--color-accent-700)]\">{t('admin:tenants.entra.history.fullSync')}</span>\r\n ) : (\r\n <span className=\"px-2 py-0.5 text-xs rounded bg-[var(--bg-tertiary)] text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.deltaSync')}</span>\r\n )}\r\n {getStatusBadge(session.status, t)}\r\n </div>\r\n {session.status === 'InProgress' && canSync && (\r\n <button\r\n onClick={() => handleCancelSession(session.id)}\r\n disabled={cancellingSessionId === session.id}\r\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs font-medium rounded-[var(--radius-button)] bg-[var(--error-bg)] text-[var(--error-text)]\"\r\n >\r\n {cancellingSessionId === session.id ? <Loader2 className=\"w-3 h-3 animate-spin\" /> : <Square className=\"w-3 h-3\" />}\r\n {t('common:cancel')}\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"text-xs text-[var(--text-tertiary)] mb-2\">\r\n {new Date(session.startedAt).toLocaleString()} • {formatDuration(session.startedAt, session.completedAt)}\r\n </div>\r\n <div className=\"grid grid-cols-3 gap-2 text-center\">\r\n <div className=\"p-1.5 rounded bg-[var(--bg-primary)]\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.created')}</span>\r\n <span className=\"font-medium text-[var(--success-text)]\">+{session.created}</span>\r\n </div>\r\n <div className=\"p-1.5 rounded bg-[var(--bg-primary)]\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.updated')}</span>\r\n <span className=\"font-medium text-[var(--color-accent-600)]\">~{session.updated}</span>\r\n </div>\r\n <div className=\"p-1.5 rounded bg-[var(--bg-primary)]\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">{t('admin:tenants.entra.sync.deleted')}</span>\r\n <span className=\"font-medium text-[var(--error-text)]\">-{session.deleted}</span>\r\n </div>\r\n </div>\r\n <div className=\"mt-2 pt-2 border-t border-[var(--border-subtle)] text-xs text-[var(--text-secondary)]\">\r\n {session.triggerType === 'Manual' ? (\r\n <span className=\"flex items-center gap-1\">\r\n <Users className=\"w-3 h-3\" />\r\n {session.triggeredByUserName || t('admin:tenants.entra.history.unknownUser')}\r\n </span>\r\n ) : (\r\n <span className=\"flex items-center gap-1 text-[var(--text-tertiary)]\">\r\n <Clock className=\"w-3 h-3\" />\r\n {t('admin:tenants.entra.history.scheduled')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Desktop: Table layout */}\r\n <div className=\"hidden sm:block overflow-x-auto\">\r\n <table className=\"w-full text-sm\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)]\">\r\n <th className=\"text-left py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.date')}</th>\r\n <th className=\"text-left py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.type')}</th>\r\n <th className=\"text-left py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.status')}</th>\r\n <th className=\"text-right py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.duration')}</th>\r\n <th className=\"text-right py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.sync.created')}</th>\r\n <th className=\"text-right py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.sync.updated')}</th>\r\n <th className=\"text-right py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.sync.deleted')}</th>\r\n <th className=\"text-left py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.triggeredBy')}</th>\r\n <th className=\"text-center py-2 px-3 font-medium text-[var(--text-secondary)]\">{t('common:actionsColumn')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {history.map((session) => (\r\n <tr key={session.id} className=\"border-b border-[var(--border-subtle)] hover:bg-[var(--bg-secondary)]\">\r\n <td className=\"py-2 px-3 text-[var(--text-primary)]\">\r\n {new Date(session.startedAt).toLocaleString()}\r\n </td>\r\n <td className=\"py-2 px-3\">\r\n <span className=\"inline-flex items-center gap-1 text-xs\">\r\n {session.isFullSync ? (\r\n <span className=\"px-2 py-0.5 rounded bg-[var(--color-accent-100)] text-[var(--color-accent-700)]\">{t('admin:tenants.entra.history.fullSync')}</span>\r\n ) : (\r\n <span className=\"px-2 py-0.5 rounded bg-[var(--bg-tertiary)] text-[var(--text-secondary)]\">{t('admin:tenants.entra.history.deltaSync')}</span>\r\n )}\r\n </span>\r\n </td>\r\n <td className=\"py-2 px-3\">\r\n {getStatusBadge(session.status, t)}\r\n </td>\r\n <td className=\"py-2 px-3 text-right text-[var(--text-secondary)]\">\r\n {formatDuration(session.startedAt, session.completedAt)}\r\n </td>\r\n <td className=\"py-2 px-3 text-right text-[var(--success-text)] font-medium\">\r\n +{session.created}\r\n </td>\r\n <td className=\"py-2 px-3 text-right text-[var(--color-accent-600)] font-medium\">\r\n ~{session.updated}\r\n </td>\r\n <td className=\"py-2 px-3 text-right text-[var(--error-text)] font-medium\">\r\n -{session.deleted}\r\n </td>\r\n <td className=\"py-2 px-3 text-[var(--text-secondary)]\">\r\n {session.triggerType === 'Manual' ? (\r\n <span className=\"flex items-center gap-1\">\r\n <Users className=\"w-3 h-3\" />\r\n {session.triggeredByUserName || t('admin:tenants.entra.history.unknownUser')}\r\n </span>\r\n ) : (\r\n <span className=\"flex items-center gap-1 text-[var(--text-tertiary)]\">\r\n <Clock className=\"w-3 h-3\" />\r\n {t('admin:tenants.entra.history.scheduled')}\r\n </span>\r\n )}\r\n </td>\r\n <td className=\"py-2 px-3 text-center\">\r\n {session.status === 'InProgress' && canSync && (\r\n <button\r\n onClick={() => handleCancelSession(session.id)}\r\n disabled={cancellingSessionId === session.id}\r\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs font-medium rounded-[var(--radius-button)] bg-[var(--error-bg)] text-[var(--error-text)] hover:bg-[var(--error-border)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n title={t('admin:tenants.entra.history.cancelSync')}\r\n >\r\n {cancellingSessionId === session.id ? (\r\n <Loader2 className=\"w-3 h-3 animate-spin\" />\r\n ) : (\r\n <Square className=\"w-3 h-3\" />\r\n )}\r\n {t('common:cancel')}\r\n </button>\r\n )}\r\n </td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* Pagination */}\r\n {historyTotalCount > historyPageSize && (\r\n <div className=\"flex items-center justify-between pt-4 border-t border-[var(--border-subtle)]\">\r\n <span className=\"text-sm text-[var(--text-tertiary)]\">\r\n {t('admin:tenants.entra.history.showing', {\r\n from: (historyPage - 1) * historyPageSize + 1,\r\n to: Math.min(historyPage * historyPageSize, historyTotalCount),\r\n total: historyTotalCount\r\n })}\r\n </span>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => loadHistory(historyPage - 1)}\r\n disabled={historyPage === 1 || historyLoading}\r\n className=\"px-3 py-1.5 text-sm rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-secondary)] hover:bg-[var(--bg-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n {t('common:previous')}\r\n </button>\r\n <button\r\n onClick={() => loadHistory(historyPage + 1)}\r\n disabled={historyPage * historyPageSize >= historyTotalCount || historyLoading}\r\n className=\"px-3 py-1.5 text-sm rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-secondary)] hover:bg-[var(--bg-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n {t('common:next')}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </SectionCard>\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Users Sub-Tab (Placeholder)\r\n// ============================================\r\n\r\ninterface UsersTabProps {\r\n readonly config: EntraConfigurationDto | null;\r\n readonly t: (key: string, options?: Record<string, unknown>) => string;\r\n}\r\n\r\nfunction UsersTab({ config, t }: UsersTabProps) {\r\n if (!config?.isConfigured) {\r\n return (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <Info className=\"w-5 h-5 text-[var(--warning-text)]\" />\r\n <span className=\"text-sm text-[var(--warning-text)]\">\r\n {t('admin:tenants.entra.users.configureFirst')}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <SectionCard\r\n icon={Users}\r\n title={t('admin:tenants.entra.users.title')}\r\n description={t('admin:tenants.entra.users.description')}\r\n >\r\n <div className=\"text-center py-8\">\r\n <div className=\"mx-auto w-12 h-12 rounded-full bg-[var(--bg-secondary)] flex items-center justify-center mb-3\">\r\n <Users className=\"w-6 h-6 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-1\">\r\n {t('admin:tenants.entra.users.comingSoon')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.users.comingSoonDescription')}\r\n </p>\r\n </div>\r\n </SectionCard>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Groups Sub-Tab (Placeholder)\r\n// ============================================\r\n\r\ninterface GroupsTabProps {\r\n readonly config: EntraConfigurationDto | null;\r\n readonly t: (key: string, options?: Record<string, unknown>) => string;\r\n}\r\n\r\nfunction GroupsTab({ config, t }: GroupsTabProps) {\r\n if (!config?.isConfigured) {\r\n return (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <Info className=\"w-5 h-5 text-[var(--warning-text)]\" />\r\n <span className=\"text-sm text-[var(--warning-text)]\">\r\n {t('admin:tenants.entra.groups.configureFirst')}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <SectionCard\r\n icon={Building2}\r\n title={t('admin:tenants.entra.groups.title')}\r\n description={t('admin:tenants.entra.groups.description')}\r\n >\r\n <div className=\"text-center py-8\">\r\n <div className=\"mx-auto w-12 h-12 rounded-full bg-[var(--bg-secondary)] flex items-center justify-center mb-3\">\r\n <Building2 className=\"w-6 h-6 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-1\">\r\n {t('admin:tenants.entra.groups.comingSoon')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:tenants.entra.groups.comingSoonDescription')}\r\n </p>\r\n </div>\r\n </SectionCard>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Main Component\r\n// ============================================\r\n\r\nexport function TenantEntraTab({ tenantId, tenantSlug }: TenantEntraTabProps): ReactElement {\r\n const { t } = useTranslation(['admin', 'entra', 'common']);\r\n const { hasPermission } = useAuth();\r\n const { isConnected, onNotification } = useSignalRContext();\r\n const [activeSubTab, setActiveSubTab] = useState<SubTabId>('config');\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n // Create API instance with tenant context\r\n // This ensures all API calls include the correct X-Tenant-Slug header\r\n const entraApi = useMemo(() => createEntraApi(tenantSlug), [tenantSlug]);\r\n\r\n // Data state\r\n const [config, setConfig] = useState<EntraConfigurationDto | null>(null);\r\n const [conflicts, setConflicts] = useState<EntraSyncConflictDto[]>([]);\r\n const [syncStatus, setSyncStatus] = useState<EntraSyncStatusDto[]>([]);\r\n const [selectedConflict, setSelectedConflict] = useState<EntraSyncConflictDto | null>(null);\r\n const [resolving, setResolving] = useState(false);\r\n\r\n // Real-time sync state\r\n const [activeSyncSession, setActiveSyncSession] = useState<{ sessionId: string; startedAt: Date } | null>(null);\r\n const [syncElapsedTime, setSyncElapsedTime] = useState<string>('00:00');\r\n\r\n // Abort controller\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n const isLoadingRef = useRef(false);\r\n\r\n // Permissions\r\n const canRead = hasPermission(ENTRA_PERMISSIONS.READ);\r\n const canEdit = hasPermission(ENTRA_PERMISSIONS.UPDATE);\r\n const canSync = hasPermission(ENTRA_PERMISSIONS.SYNC);\r\n\r\n // Define sub-tabs\r\n const subTabs: SubTab[] = [\r\n { id: 'config', label: t('admin:tenants.entra.tabs.config'), icon: Key, permission: ENTRA_PERMISSIONS.READ },\r\n { id: 'sync', label: t('admin:tenants.entra.tabs.sync'), icon: Zap, permission: ENTRA_PERMISSIONS.SYNC },\r\n { id: 'users', label: t('admin:tenants.entra.tabs.users'), icon: Users, permission: ENTRA_PERMISSIONS.READ },\r\n { id: 'groups', label: t('admin:tenants.entra.tabs.groups'), icon: Building2, permission: ENTRA_PERMISSIONS.READ },\r\n ];\r\n\r\n const availableTabs = subTabs.filter((tab) => hasPermission(tab.permission));\r\n\r\n useEffect(() => {\r\n if (availableTabs.length > 0 && !availableTabs.find((tab) => tab.id === activeSubTab)) {\r\n setActiveSubTab(availableTabs[0].id);\r\n }\r\n }, [availableTabs, activeSubTab]);\r\n\r\n const loadData = useCallback(async () => {\r\n if (isLoadingRef.current) return;\r\n\r\n if (!canRead) {\r\n setLoading(false);\r\n return;\r\n }\r\n\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n\r\n abortControllerRef.current = new AbortController();\r\n isLoadingRef.current = true;\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n const [configData, conflictsData, syncStatusData] = await Promise.all([\r\n entraApi.settings.getConfiguration(),\r\n entraApi.conflicts.getAll(),\r\n entraApi.dashboard.getSyncStatus(),\r\n ]);\r\n\r\n setConfig(configData ?? null);\r\n setConflicts(Array.isArray(conflictsData) ? conflictsData : []);\r\n setSyncStatus(Array.isArray(syncStatusData) ? syncStatusData : []);\r\n } catch (err) {\r\n if (err instanceof Error && err.name === 'AbortError') return;\r\n console.error('Failed to load Entra data:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('admin:tenants.entra.loadError'));\r\n } finally {\r\n isLoadingRef.current = false;\r\n setLoading(false);\r\n }\r\n }, [entraApi, t, canRead]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n return () => {\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n };\r\n }, [loadData, tenantId]);\r\n\r\n // Subscribe to SignalR notifications for real-time updates\r\n useEffect(() => {\r\n const unsubscribe = onNotification((notification: SignalRNotificationDto) => {\r\n handleEntraNotification(notification, setActiveSyncSession, loadData);\r\n });\r\n\r\n return unsubscribe;\r\n }, [onNotification, loadData]);\r\n\r\n // Timer for active sync session elapsed time\r\n useEffect(() => {\r\n if (!activeSyncSession) {\r\n setSyncElapsedTime('00:00');\r\n return;\r\n }\r\n\r\n setSyncElapsedTime(calculateElapsedTime(activeSyncSession.startedAt));\r\n const interval = setInterval(() => {\r\n setSyncElapsedTime(calculateElapsedTime(activeSyncSession.startedAt));\r\n }, 1000);\r\n\r\n return () => clearInterval(interval);\r\n }, [activeSyncSession]);\r\n\r\n const handleResolve = useCallback(async (resolution: ResolveConflictRequest['resolution'], notes?: string) => {\r\n if (!selectedConflict || resolving) return;\r\n\r\n setResolving(true);\r\n try {\r\n await entraApi.conflicts.resolve(selectedConflict.id, {\r\n resolution,\r\n notes: notes || undefined,\r\n });\r\n setSelectedConflict(null);\r\n await loadData();\r\n } catch (err) {\r\n console.error('Failed to resolve conflict:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('entra:conflicts.resolveError'));\r\n } finally {\r\n setResolving(false);\r\n }\r\n }, [entraApi, selectedConflict, resolving, loadData, t]);\r\n\r\n const handleSyncAll = useCallback(async (): Promise<EntraSyncResultDto | null> => {\r\n try {\r\n const result = await entraApi.sync.syncAll();\r\n return result;\r\n } catch (err) {\r\n console.error('Sync all failed:', err instanceof Error ? err.message : 'Unknown error');\r\n throw err;\r\n }\r\n }, [entraApi]);\r\n\r\n const handleLoadHistory = useCallback(async (page: number, pageSize: number): Promise<{ sessions: EntraSyncSessionDto[]; totalCount: number } | null> => {\r\n try {\r\n const result = await entraApi.sync.getHistory(page, pageSize);\r\n return result;\r\n } catch (err) {\r\n console.error('Failed to load history:', err instanceof Error ? err.message : 'Unknown error');\r\n return null;\r\n }\r\n }, [entraApi]);\r\n\r\n const handleCancelSession = useCallback(async (sessionId: string): Promise<boolean> => {\r\n try {\r\n await entraApi.sync.cancelSession(sessionId);\r\n return true;\r\n } catch (err) {\r\n console.error('Failed to cancel session:', err instanceof Error ? err.message : 'Unknown error');\r\n return false;\r\n }\r\n }, [entraApi]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center py-12\">\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 if (availableTabs.length === 0) {\r\n return (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <Lock className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">\r\n {t('admin:tenants.entra.noPermission')}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {error && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">{error}</span>\r\n <button onClick={() => setError(null)} className=\"ml-auto text-[var(--error-text)] hover:opacity-70\">×</button>\r\n </div>\r\n )}\r\n\r\n {/* Active Sync Banner */}\r\n {activeSyncSession && (\r\n <div className=\"flex flex-col sm:flex-row items-start sm:items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20 border border-[var(--color-accent-200)] dark:border-[var(--color-accent-800)]\">\r\n <div className=\"flex items-center gap-3 flex-1\">\r\n <RefreshCw className=\"w-5 h-5 text-[var(--color-accent-600)] animate-spin flex-shrink-0\" />\r\n <div className=\"min-w-0\">\r\n <p className=\"font-medium text-[var(--color-accent-700)] dark:text-[var(--color-accent-400)]\">\r\n {t('admin:tenants.entra.sync.syncInProgress')}\r\n </p>\r\n <p className=\"text-sm text-[var(--color-accent-600)] dark:text-[var(--color-accent-500)] truncate\">\r\n {t('admin:tenants.entra.sync.syncInProgressDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 self-end sm:self-auto\">\r\n <span className=\"text-lg font-mono font-bold text-[var(--color-accent-700)] dark:text-[var(--color-accent-400)] bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/50 px-3 py-1 rounded\">\r\n ⏱ {syncElapsedTime}\r\n </span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Sub-tab Navigation */}\r\n <div className=\"flex flex-col sm:flex-row items-stretch sm:items-center gap-1 p-1 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <div className=\"flex flex-wrap items-center gap-1 flex-1\">\r\n {availableTabs.map((tab) => {\r\n const Icon = tab.icon;\r\n const isActive = activeSubTab === tab.id;\r\n // Show badge for sync tab when there are conflicts\r\n const showConflictBadge = tab.id === 'sync' && conflicts.length > 0;\r\n return (\r\n <button\r\n key={tab.id}\r\n onClick={() => setActiveSubTab(tab.id)}\r\n className={`flex items-center gap-2 px-3 sm:px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] transition-all flex-1 sm:flex-none justify-center sm:justify-start ${\r\n isActive\r\n ? 'bg-[var(--bg-card)] text-[var(--text-primary)] shadow-sm'\r\n : 'text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <Icon className=\"w-4 h-4\" />\r\n <span className=\"hidden sm:inline\">{tab.label}</span>\r\n {showConflictBadge && (\r\n <span className=\"ml-1 px-1.5 py-0.5 text-xs font-bold rounded-full bg-[var(--warning-bg)] text-[var(--warning-text)]\">\r\n {conflicts.length}\r\n </span>\r\n )}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n {/* Connection status indicator */}\r\n <div className=\"flex items-center justify-center sm:justify-end gap-2 px-2 py-1 border-t sm:border-t-0 sm:border-l border-[var(--border-subtle)] mt-1 sm:mt-0 pt-2 sm:pt-0\">\r\n {isConnected ? (\r\n <span className=\"flex items-center gap-1.5 text-xs text-[var(--success-text)]\" title={t('admin:tenants.entra.realTimeConnected')}>\r\n <span className=\"w-2 h-2 rounded-full bg-[var(--success-text)] animate-pulse\" />\r\n <span className=\"hidden sm:inline\">{t('common:live')}</span>\r\n </span>\r\n ) : (\r\n <span className=\"flex items-center gap-1.5 text-xs text-[var(--text-tertiary)]\" title={t('admin:tenants.entra.realTimeDisconnected')}>\r\n <span className=\"w-2 h-2 rounded-full bg-[var(--text-tertiary)]\" />\r\n <span className=\"hidden sm:inline\">{t('common:offline')}</span>\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Sub-tab Content */}\r\n {activeSubTab === 'config' && (\r\n <ConfigTab\r\n config={config}\r\n loading={loading}\r\n canEdit={canEdit}\r\n onRefresh={loadData}\r\n onConfigUpdated={loadData}\r\n t={t}\r\n entraApi={entraApi}\r\n />\r\n )}\r\n {activeSubTab === 'sync' && (\r\n <SyncTab\r\n config={config}\r\n conflicts={conflicts}\r\n syncStatus={syncStatus}\r\n loading={loading}\r\n canSync={canSync}\r\n onRefresh={loadData}\r\n onResolveConflict={setSelectedConflict}\r\n onSyncAll={handleSyncAll}\r\n onLoadHistory={handleLoadHistory}\r\n onCancelSession={handleCancelSession}\r\n activeSyncSession={activeSyncSession}\r\n t={t}\r\n />\r\n )}\r\n {activeSubTab === 'users' && <UsersTab config={config} t={t} />}\r\n {activeSubTab === 'groups' && <GroupsTab config={config} t={t} />}\r\n\r\n {/* Resolution Modal */}\r\n {selectedConflict && (\r\n <ResolutionModal\r\n conflict={selectedConflict}\r\n onClose={() => setSelectedConflict(null)}\r\n onResolve={handleResolve}\r\n resolving={resolving}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport type { TFunction } from 'i18next';\r\nimport {\r\n Settings,\r\n Save,\r\n Loader2,\r\n CheckCircle,\r\n AlertTriangle,\r\n TestTube,\r\n Eye,\r\n EyeOff,\r\n RefreshCw,\r\n Clock,\r\n Zap,\r\n ExternalLink,\r\n Info,\r\n} from 'lucide-react';\r\nimport { Tooltip } from '@/components/ui/Tooltip';\r\nimport {\r\n ticketingApi,\r\n type TenantTicketingConfigurationDto,\r\n type SaveTicketingConfigurationRequest,\r\n type TicketingSyncResultDto,\r\n} from '@/services/api/ticketingApi';\r\n\r\nfunction validateGlpiConfig(fields: {\r\n glpiBaseUrl: string;\r\n glpiClientId: string;\r\n glpiClientSecret: string;\r\n glpiUsername: string;\r\n glpiPassword: string;\r\n}, config: TenantTicketingConfigurationDto | null, t: TFunction): Record<string, string> {\r\n const errors: Record<string, string> = {};\r\n\r\n if (!fields.glpiBaseUrl.trim()) {\r\n errors.glpiBaseUrl = t('admin:tenants.ticketing.validation.baseUrlRequired');\r\n } else {\r\n try {\r\n new URL(fields.glpiBaseUrl);\r\n } catch {\r\n errors.glpiBaseUrl = t('admin:tenants.ticketing.validation.baseUrlInvalid');\r\n }\r\n }\r\n if (!fields.glpiClientId.trim()) {\r\n errors.glpiClientId = t('admin:tenants.ticketing.validation.clientIdRequired');\r\n }\r\n if (!fields.glpiClientSecret && !config?.hasGlpiClientSecret) {\r\n errors.glpiClientSecret = t('admin:tenants.ticketing.validation.clientSecretRequired');\r\n }\r\n if (!fields.glpiUsername.trim()) {\r\n errors.glpiUsername = t('admin:tenants.ticketing.validation.usernameRequired');\r\n }\r\n if (!fields.glpiPassword && !config?.hasGlpiPassword) {\r\n errors.glpiPassword = t('admin:tenants.ticketing.validation.passwordRequired');\r\n }\r\n\r\n return errors;\r\n}\r\n\r\nfunction buildGlpiSaveRequest(fields: {\r\n glpiBaseUrl: string;\r\n glpiClientId: string;\r\n glpiClientSecret: string;\r\n glpiUsername: string;\r\n glpiPassword: string;\r\n glpiEntityId: string;\r\n glpiRequestTypeId: string;\r\n}, provider: string, syncEnabled: boolean, syncIntervalMinutes: number): SaveTicketingConfigurationRequest {\r\n const request: SaveTicketingConfigurationRequest = {\r\n provider,\r\n syncEnabled,\r\n syncIntervalMinutes,\r\n };\r\n\r\n if (provider === 'GLPI') {\r\n request.glpiBaseUrl = fields.glpiBaseUrl;\r\n request.glpiClientId = fields.glpiClientId;\r\n if (fields.glpiClientSecret) {\r\n request.glpiClientSecret = fields.glpiClientSecret;\r\n }\r\n request.glpiUsername = fields.glpiUsername;\r\n if (fields.glpiPassword) {\r\n request.glpiPassword = fields.glpiPassword;\r\n }\r\n if (fields.glpiEntityId) {\r\n request.glpiEntityId = Number(fields.glpiEntityId);\r\n }\r\n if (fields.glpiRequestTypeId) {\r\n request.glpiRequestTypeId = Number(fields.glpiRequestTypeId);\r\n }\r\n }\r\n\r\n return request;\r\n}\r\n\r\ninterface TenantSupportSettingsTabProps {\r\n readonly tenantId: string;\r\n readonly tenantName: string;\r\n}\r\n\r\n// ============================================\r\n// Reusable Components (same pattern as TenantEntraTab)\r\n// ============================================\r\n\r\ninterface SectionCardProps {\r\n readonly icon: typeof Settings;\r\n readonly title: string;\r\n readonly description?: string;\r\n readonly action?: React.ReactNode;\r\n readonly children: React.ReactNode;\r\n}\r\n\r\nfunction SectionCard({ icon: Icon, title, description, action, children }: SectionCardProps) {\r\n return (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] shadow-sm overflow-hidden\">\r\n <div className=\"px-6 py-4 border-b border-[var(--border-subtle)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30\">\r\n <Icon className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <div>\r\n <h2 className=\"text-base font-semibold text-[var(--text-primary)]\">{title}</h2>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n </div>\r\n {action}\r\n </div>\r\n </div>\r\n <div className=\"p-6\">\r\n {children}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\ninterface ToggleProps {\r\n readonly checked: boolean;\r\n readonly onChange: () => void;\r\n readonly label: string;\r\n readonly description?: string;\r\n readonly disabled?: boolean;\r\n}\r\n\r\nfunction Toggle({ checked, onChange, label, description, disabled }: ToggleProps) {\r\n return (\r\n <div className=\"flex items-center justify-between py-3\">\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <label className=\"text-sm font-medium text-[var(--text-primary)]\">{label}</label>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n role=\"switch\"\r\n aria-checked={checked}\r\n onClick={onChange}\r\n disabled={disabled}\r\n className={`relative inline-flex h-6 w-11 flex-shrink-0 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] focus:ring-offset-2 focus:ring-offset-[var(--bg-primary)] disabled:opacity-50 disabled:cursor-not-allowed ${\r\n checked ? 'bg-[var(--color-accent-600)]' : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <span\r\n className={`inline-block h-4 w-4 transform rounded-full bg-white shadow-md transition-transform ${\r\n checked ? 'translate-x-6' : 'translate-x-1'\r\n }`}\r\n />\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\nfunction InfoBubble({ text }: { text: string }) {\r\n return (\r\n <Tooltip\r\n content={\r\n <span className=\"whitespace-pre-line text-xs leading-relaxed\">{text}</span>\r\n }\r\n position=\"right\"\r\n variant=\"info\"\r\n delay={100}\r\n className=\"!max-w-sm\"\r\n >\r\n <Info className=\"w-4 h-4 text-[var(--text-tertiary)] hover:text-[var(--info-text)] cursor-help transition-colors\" />\r\n </Tooltip>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Main Component\r\n// ============================================\r\n\r\nexport function TenantSupportSettingsTab({ tenantId, tenantName }: TenantSupportSettingsTabProps): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n\r\n // State\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState(false);\r\n const [testing, setTesting] = useState(false);\r\n const [syncing, setSyncing] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n const [showSecrets, setShowSecrets] = useState(false);\r\n const [config, setConfig] = useState<TenantTicketingConfigurationDto | null>(null);\r\n const [lastSyncResult, setLastSyncResult] = useState<TicketingSyncResultDto | null>(null);\r\n const [testResult, setTestResult] = useState<{ success: boolean; errorMessage?: string | null } | null>(null);\r\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\r\n\r\n // Form state\r\n const [provider, setProvider] = useState<string>('SmartStack');\r\n const [glpiBaseUrl, setGlpiBaseUrl] = useState('');\r\n const [glpiClientId, setGlpiClientId] = useState('');\r\n const [glpiClientSecret, setGlpiClientSecret] = useState('');\r\n const [glpiUsername, setGlpiUsername] = useState('');\r\n const [glpiPassword, setGlpiPassword] = useState('');\r\n const [glpiEntityId, setGlpiEntityId] = useState<string>('');\r\n const [glpiRequestTypeId, setGlpiRequestTypeId] = useState<string>('');\r\n const [syncEnabled, setSyncEnabled] = useState(false);\r\n const [syncIntervalMinutes, setSyncIntervalMinutes] = useState(60);\r\n\r\n const isGlpi = provider === 'GLPI';\r\n\r\n const fieldErrorClass = (field: string) =>\r\n fieldErrors[field] ? 'border-[var(--error-border)] ring-1 ring-[var(--error-border)]' : 'border-[var(--border-color)]';\r\n\r\n const loadConfiguration = useCallback(async () => {\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n const data = await ticketingApi.getConfiguration(tenantId);\r\n setConfig(data);\r\n setProvider(data.provider || 'SmartStack');\r\n setGlpiBaseUrl(data.glpiBaseUrl || '');\r\n setGlpiClientId(data.glpiClientId || '');\r\n setGlpiClientSecret('');\r\n setGlpiUsername(data.glpiUsername || '');\r\n setGlpiPassword('');\r\n setGlpiEntityId(data.glpiEntityId != null ? String(data.glpiEntityId) : '');\r\n setGlpiRequestTypeId(data.glpiRequestTypeId != null ? String(data.glpiRequestTypeId) : '');\r\n setSyncEnabled(data.syncEnabled);\r\n setSyncIntervalMinutes(data.syncIntervalMinutes);\r\n } catch {\r\n // Configuration may not exist yet, that's OK\r\n setConfig(null);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [tenantId]);\r\n\r\n useEffect(() => {\r\n loadConfiguration();\r\n }, [loadConfiguration]);\r\n\r\n const validateForm = (): boolean => {\r\n if (!isGlpi) {\r\n setFieldErrors({});\r\n return true;\r\n }\r\n\r\n const errors = validateGlpiConfig({\r\n glpiBaseUrl,\r\n glpiClientId,\r\n glpiClientSecret,\r\n glpiUsername,\r\n glpiPassword,\r\n }, config, t);\r\n\r\n setFieldErrors(errors);\r\n return Object.keys(errors).length === 0;\r\n };\r\n\r\n const handleSave = async () => {\r\n if (!validateForm()) return;\r\n\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n\r\n const request = buildGlpiSaveRequest({\r\n glpiBaseUrl,\r\n glpiClientId,\r\n glpiClientSecret,\r\n glpiUsername,\r\n glpiPassword,\r\n glpiEntityId,\r\n glpiRequestTypeId,\r\n }, provider, syncEnabled, syncIntervalMinutes);\r\n\r\n try {\r\n const updated = await ticketingApi.saveConfiguration(tenantId, request);\r\n setConfig(updated);\r\n setGlpiClientSecret('');\r\n setGlpiPassword('');\r\n setSuccess(t('admin:tenants.ticketing.saveSuccess'));\r\n } catch {\r\n setError(t('admin:tenants.ticketing.saveFailed'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleTestConnection = async () => {\r\n setTesting(true);\r\n setTestResult(null);\r\n setError(null);\r\n setSuccess(null);\r\n try {\r\n const result = await ticketingApi.testConnection(tenantId, {\r\n glpiBaseUrl: glpiBaseUrl,\r\n glpiClientId: glpiClientId,\r\n glpiClientSecret: glpiClientSecret || undefined,\r\n glpiUsername: glpiUsername,\r\n glpiPassword: glpiPassword || undefined,\r\n });\r\n setTestResult(result);\r\n if (result.success) {\r\n setSuccess(t('admin:tenants.ticketing.testSuccess'));\r\n } else {\r\n setError(result.errorMessage || t('admin:tenants.ticketing.testFailed'));\r\n }\r\n } catch {\r\n setError(t('admin:tenants.ticketing.testFailed'));\r\n } finally {\r\n setTesting(false);\r\n }\r\n };\r\n\r\n const handleSyncNow = async () => {\r\n setSyncing(true);\r\n setLastSyncResult(null);\r\n setError(null);\r\n setSuccess(null);\r\n try {\r\n const result = await ticketingApi.triggerSync(tenantId);\r\n setLastSyncResult(result);\r\n if (result.success) {\r\n setSuccess(t('admin:tenants.ticketing.syncSuccess', { count: result.ticketsUpdated }));\r\n } else {\r\n setError(result.errorMessage || t('admin:tenants.ticketing.syncFailed'));\r\n }\r\n await loadConfiguration();\r\n } catch {\r\n setError(t('admin:tenants.ticketing.syncFailed'));\r\n } finally {\r\n setSyncing(false);\r\n }\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center py-12\">\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 {/* Error / Success Messages */}\r\n {error && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">{error}</span>\r\n <button onClick={() => setError(null)} className=\"ml-auto text-[var(--error-text)] hover:opacity-70\">\r\n ×\r\n </button>\r\n </div>\r\n )}\r\n {success && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n <span className=\"text-sm text-[var(--success-text)]\">{success}</span>\r\n <button onClick={() => setSuccess(null)} className=\"ml-auto text-[var(--success-text)] hover:opacity-70\">\r\n ×\r\n </button>\r\n </div>\r\n )}\r\n\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {/* Provider Selection */}\r\n <SectionCard\r\n icon={Settings}\r\n title={t('admin:tenants.ticketing.provider.title')}\r\n description={t('admin:tenants.ticketing.provider.description', { tenantName })}\r\n >\r\n <div className=\"space-y-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.provider.label')}\r\n </label>\r\n <select\r\n value={provider}\r\n onChange={(e) => {\r\n const newProvider = e.target.value;\r\n setProvider(newProvider);\r\n if (newProvider !== 'GLPI') {\r\n setSyncEnabled(false);\r\n }\r\n }}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"SmartStack\" className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">\r\n SmartStack\r\n </option>\r\n <option value=\"GLPI\" className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">\r\n GLPI\r\n </option>\r\n </select>\r\n <p className=\"mt-1.5 text-xs text-[var(--text-tertiary)] whitespace-pre-line\">\r\n {isGlpi\r\n ? t('admin:tenants.ticketing.provider.glpiHint')\r\n : t('admin:tenants.ticketing.provider.smartstackHint')}\r\n </p>\r\n </div>\r\n\r\n {/* GLPI Connection Fields */}\r\n {isGlpi && (\r\n <>\r\n {/* Documentation Link */}\r\n <div className=\"flex items-start gap-3 p-3 rounded-[var(--radius-card)] bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <ExternalLink className=\"w-4 h-4 text-[var(--info-text)] mt-0.5 flex-shrink-0\" />\r\n <div className=\"text-sm text-[var(--info-text)]\">\r\n <span>{t('admin:tenants.ticketing.glpi.docHint')} </span>\r\n <a\r\n href=\"https://glpi-project.org/documentation/\"\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"font-medium underline hover:opacity-80\"\r\n >\r\n {t('admin:tenants.ticketing.glpi.docLink')}\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.baseUrl')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.baseUrlHelp')} />\r\n </label>\r\n <input\r\n type=\"url\"\r\n value={glpiBaseUrl}\r\n onChange={(e) => { setGlpiBaseUrl(e.target.value); setFieldErrors(prev => { const { glpiBaseUrl: _, ...rest } = prev; return rest; }); }}\r\n placeholder=\"https://glpi.example.com\"\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border ${fieldErrorClass('glpiBaseUrl')} bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow`}\r\n />\r\n {fieldErrors.glpiBaseUrl && <p className=\"mt-1 text-xs text-[var(--error-text)]\">{fieldErrors.glpiBaseUrl}</p>}\r\n </div>\r\n\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.clientId')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.clientIdHelp')} />\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={glpiClientId}\r\n onChange={(e) => { setGlpiClientId(e.target.value); setFieldErrors(prev => { const { glpiClientId: _, ...rest } = prev; return rest; }); }}\r\n placeholder={t('admin:tenants.ticketing.glpi.clientIdPlaceholder')}\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border ${fieldErrorClass('glpiClientId')} bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow`}\r\n />\r\n {fieldErrors.glpiClientId && <p className=\"mt-1 text-xs text-[var(--error-text)]\">{fieldErrors.glpiClientId}</p>}\r\n </div>\r\n\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.clientSecret')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.clientSecretHelp')} />\r\n {config?.hasGlpiClientSecret && (\r\n <span className=\"inline-flex items-center gap-1 text-xs text-[var(--success-text)]\">\r\n <CheckCircle className=\"w-3 h-3\" />\r\n {t('common:configured')}\r\n </span>\r\n )}\r\n </label>\r\n <div className=\"relative\">\r\n <input\r\n type={showSecrets ? 'text' : 'password'}\r\n autoComplete=\"new-password\"\r\n value={glpiClientSecret}\r\n onChange={(e) => { setGlpiClientSecret(e.target.value); setFieldErrors(prev => { const { glpiClientSecret: _, ...rest } = prev; return rest; }); }}\r\n placeholder={config?.hasGlpiClientSecret ? '••••••••••••••••' : t('admin:tenants.ticketing.glpi.clientSecretPlaceholder')}\r\n className={`w-full px-3 py-2.5 pr-10 rounded-[var(--radius-input)] border ${fieldErrorClass('glpiClientSecret')} bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow`}\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowSecrets(!showSecrets)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 text-[var(--text-tertiary)] hover:text-[var(--text-primary)]\"\r\n >\r\n {showSecrets ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n {fieldErrors.glpiClientSecret && <p className=\"mt-1 text-xs text-[var(--error-text)]\">{fieldErrors.glpiClientSecret}</p>}\r\n </div>\r\n\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.username')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.usernameHelp')} />\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={glpiUsername}\r\n onChange={(e) => { setGlpiUsername(e.target.value); setFieldErrors(prev => { const { glpiUsername: _, ...rest } = prev; return rest; }); }}\r\n placeholder={t('admin:tenants.ticketing.glpi.usernamePlaceholder')}\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border ${fieldErrorClass('glpiUsername')} bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow`}\r\n />\r\n {fieldErrors.glpiUsername && <p className=\"mt-1 text-xs text-[var(--error-text)]\">{fieldErrors.glpiUsername}</p>}\r\n </div>\r\n\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.password')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.passwordHelp')} />\r\n {config?.hasGlpiPassword && (\r\n <span className=\"inline-flex items-center gap-1 text-xs text-[var(--success-text)]\">\r\n <CheckCircle className=\"w-3 h-3\" />\r\n {t('common:configured')}\r\n </span>\r\n )}\r\n </label>\r\n <div className=\"relative\">\r\n <input\r\n type={showSecrets ? 'text' : 'password'}\r\n autoComplete=\"new-password\"\r\n value={glpiPassword}\r\n onChange={(e) => { setGlpiPassword(e.target.value); setFieldErrors(prev => { const { glpiPassword: _, ...rest } = prev; return rest; }); }}\r\n placeholder={config?.hasGlpiPassword ? '••••••••••••••••' : t('admin:tenants.ticketing.glpi.passwordPlaceholder')}\r\n className={`w-full px-3 py-2.5 pr-10 rounded-[var(--radius-input)] border ${fieldErrorClass('glpiPassword')} bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] font-mono text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow`}\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowSecrets(!showSecrets)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 text-[var(--text-tertiary)] hover:text-[var(--text-primary)]\"\r\n >\r\n {showSecrets ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n {fieldErrors.glpiPassword && <p className=\"mt-1 text-xs text-[var(--error-text)]\">{fieldErrors.glpiPassword}</p>}\r\n </div>\r\n\r\n {/* GLPI Entity ID */}\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.entityId')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.entityIdHelp')} />\r\n </label>\r\n <input\r\n type=\"number\"\r\n min=\"0\"\r\n value={glpiEntityId}\r\n onChange={(e) => setGlpiEntityId(e.target.value)}\r\n placeholder={t('admin:tenants.ticketing.glpi.entityIdPlaceholder')}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow\"\r\n />\r\n </div>\r\n\r\n {/* GLPI Request Type ID */}\r\n <div>\r\n <label className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {t('admin:tenants.ticketing.glpi.requestTypeId')}\r\n <InfoBubble text={t('admin:tenants.ticketing.glpi.requestTypeIdHelp')} />\r\n </label>\r\n <input\r\n type=\"number\"\r\n min=\"0\"\r\n value={glpiRequestTypeId}\r\n onChange={(e) => setGlpiRequestTypeId(e.target.value)}\r\n placeholder={t('admin:tenants.ticketing.glpi.requestTypeIdPlaceholder')}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder-[var(--text-muted)] text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow\"\r\n />\r\n </div>\r\n\r\n {/* Test Connection */}\r\n <div className=\"flex flex-col sm:flex-row items-stretch sm:items-center gap-2 sm:gap-3 pt-2\">\r\n <button\r\n onClick={handleTestConnection}\r\n disabled={testing || !glpiBaseUrl || !glpiClientId || (!glpiClientSecret && !config?.hasGlpiClientSecret) || !glpiUsername || (!glpiPassword && !config?.hasGlpiPassword)}\r\n className=\"inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {testing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <TestTube className=\"w-4 h-4\" />}\r\n {t('admin:tenants.ticketing.testConnection')}\r\n </button>\r\n </div>\r\n\r\n {/* Test Connection Result */}\r\n {testResult && (\r\n <div className={`p-4 rounded-[var(--radius-card)] border ${\r\n testResult.success\r\n ? 'bg-[var(--success-bg)] border-[var(--success-border)]'\r\n : 'bg-[var(--error-bg)] border-[var(--error-border)]'\r\n }`}>\r\n <div className=\"flex items-center gap-2\">\r\n {testResult.success ? (\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n )}\r\n <span className={`font-medium ${testResult.success ? 'text-[var(--success-text)]' : 'text-[var(--error-text)]'}`}>\r\n {testResult.success\r\n ? t('admin:tenants.ticketing.connectionSuccessful')\r\n : t('admin:tenants.ticketing.connectionFailed')}\r\n </span>\r\n </div>\r\n {!testResult.success && testResult.errorMessage && (\r\n <p className=\"mt-2 text-sm text-[var(--error-text)]\">{testResult.errorMessage}</p>\r\n )}\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Sync Settings */}\r\n <div className=\"space-y-6\">\r\n <SectionCard\r\n icon={Clock}\r\n title={t('admin:tenants.ticketing.sync.title')}\r\n description={t('admin:tenants.ticketing.sync.description')}\r\n >\r\n <div className=\"divide-y divide-[var(--border-subtle)]\">\r\n <Toggle\r\n checked={syncEnabled}\r\n onChange={() => setSyncEnabled(!syncEnabled)}\r\n label={t('admin:tenants.ticketing.sync.enabledLabel')}\r\n description={t('admin:tenants.ticketing.sync.enabledDescription')}\r\n disabled={!isGlpi}\r\n />\r\n <div className=\"py-4\">\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {t('admin:tenants.ticketing.sync.intervalLabel')}\r\n </label>\r\n <select\r\n value={syncIntervalMinutes}\r\n onChange={(e) => setSyncIntervalMinutes(Number(e.target.value))}\r\n disabled={!isGlpi || !syncEnabled}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n <option value={15} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">15 {t('common:minutes')}</option>\r\n <option value={30} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">30 {t('common:minutes')}</option>\r\n <option value={60} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">1 {t('common:hour')}</option>\r\n <option value={120} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">2 {t('common:hours')}</option>\r\n <option value={360} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">6 {t('common:hours')}</option>\r\n <option value={720} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">12 {t('common:hours')}</option>\r\n <option value={1440} className=\"bg-[var(--bg-secondary)] text-[var(--text-primary)]\">24 {t('common:hours')}</option>\r\n </select>\r\n </div>\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Last Sync Status */}\r\n {config?.isConfigured && isGlpi && (\r\n <SectionCard\r\n icon={Zap}\r\n title={t('admin:tenants.ticketing.syncStatus.title')}\r\n description={t('admin:tenants.ticketing.syncStatus.description')}\r\n action={\r\n <button\r\n onClick={handleSyncNow}\r\n disabled={syncing}\r\n className=\"inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {syncing ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <RefreshCw className=\"w-4 h-4\" />}\r\n {t('admin:tenants.ticketing.syncStatus.syncNow')}\r\n </button>\r\n }\r\n >\r\n <div className=\"space-y-4\">\r\n {/* Last Sync Info */}\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <Clock className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('admin:tenants.ticketing.syncStatus.lastSync')}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {config.lastSyncAt\r\n ? new Date(config.lastSyncAt).toLocaleString()\r\n : t('admin:tenants.ticketing.syncStatus.never')}\r\n </p>\r\n </div>\r\n\r\n <div className={`p-4 rounded-[var(--radius-card)] border ${\r\n config.lastSyncError\r\n ? 'bg-[var(--error-bg)] border-[var(--error-border)]'\r\n : 'bg-[var(--success-bg)] border-[var(--success-border)]'\r\n }`}>\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n {config.lastSyncError ? (\r\n <AlertTriangle className=\"w-4 h-4 text-[var(--error-text)]\" />\r\n ) : (\r\n <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n )}\r\n <span className={`text-sm font-medium ${\r\n config.lastSyncError ? 'text-[var(--error-text)]' : 'text-[var(--success-text)]'\r\n }`}>\r\n {t('admin:tenants.ticketing.syncStatus.status')}\r\n </span>\r\n </div>\r\n <p className={`text-sm ${\r\n config.lastSyncError ? 'text-[var(--error-text)]' : 'text-[var(--success-text)]'\r\n }`}>\r\n {config.lastSyncError || t('admin:tenants.ticketing.syncStatus.healthy')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Last Sync Result */}\r\n {lastSyncResult && (\r\n <div className={`p-4 rounded-[var(--radius-card)] border ${\r\n lastSyncResult.success\r\n ? 'bg-[var(--success-bg)] border-[var(--success-border)]'\r\n : 'bg-[var(--error-bg)] border-[var(--error-border)]'\r\n }`}>\r\n <div className=\"flex items-center gap-2 mb-3\">\r\n {lastSyncResult.success ? (\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n )}\r\n <span className={`font-medium ${lastSyncResult.success ? 'text-[var(--success-text)]' : 'text-[var(--error-text)]'}`}>\r\n {lastSyncResult.success\r\n ? t('admin:tenants.ticketing.syncStatus.syncSuccess')\r\n : t('admin:tenants.ticketing.syncStatus.syncFailed')}\r\n </span>\r\n </div>\r\n <div className=\"grid grid-cols-2 gap-3 text-sm\">\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)]\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">\r\n {t('admin:tenants.ticketing.syncStatus.ticketsUpdated')}\r\n </span>\r\n <p className=\"font-semibold text-[var(--success-text)]\">{lastSyncResult.ticketsUpdated}</p>\r\n </div>\r\n <div className=\"p-2 rounded bg-[var(--bg-primary)] border border-[var(--border-subtle)]\">\r\n <span className=\"text-xs text-[var(--text-tertiary)] block\">\r\n {t('admin:tenants.ticketing.syncStatus.ticketsFailed')}\r\n </span>\r\n <p className={`font-semibold ${lastSyncResult.ticketsFailed > 0 ? 'text-[var(--error-text)]' : 'text-[var(--text-primary)]'}`}>\r\n {lastSyncResult.ticketsFailed}\r\n </p>\r\n </div>\r\n </div>\r\n {lastSyncResult.errorMessage && (\r\n <p className=\"mt-3 text-sm text-[var(--error-text)]\">{lastSyncResult.errorMessage}</p>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </SectionCard>\r\n )}\r\n\r\n {/* Save Button */}\r\n <div className=\"flex flex-col-reverse sm:flex-row items-stretch sm:items-center gap-2 sm:gap-3\">\r\n <button\r\n onClick={handleSave}\r\n disabled={saving}\r\n className=\"inline-flex items-center justify-center gap-2 px-6 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common:save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useParams, useNavigate } from 'react-router-dom';\r\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\r\nimport { useTenantDetail } from '@/hooks/useTenantDetail';\r\nimport {\r\n ArrowLeft,\r\n Loader2,\r\n AlertTriangle,\r\n Settings,\r\n} from 'lucide-react';\r\nimport { TenantEntraTab } from '@/components/platform/administration/TenantEntraTab';\r\nimport { TenantSupportSettingsTab } from '@/components/platform/administration/tenants/TenantSupportSettingsTab';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\n\r\nconst VALID_TABS = ['entra', 'support'] as const;\r\ntype TabType = typeof VALID_TABS[number];\r\n\r\nexport function TenantSettingsPage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const { id: tenantId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const { activeTab, setActiveTab } = useTabNavigation<TabType>('entra', VALID_TABS);\r\n\r\n const tenantDetail = useTenantDetail(tenantId);\r\n\r\n useEffect(() => {\r\n if (!tenantId) {\r\n navigate('/administration/tenants');\r\n return;\r\n }\r\n tenantDetail.loadTenant();\r\n }, [tenantId]);\r\n\r\n if (tenantDetail.loading) {\r\n return (\r\n <div className=\"p-6 flex items-center justify-center min-h-screen\">\r\n <div className=\"text-center\">\r\n <Loader2 className=\"w-8 h-8 animate-spin mx-auto mb-2 text-[var(--text-secondary)]\" />\r\n <p className=\"text-[var(--text-secondary)]\">{t('common:loading')}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!tenantDetail.tenant) {\r\n return (\r\n <div className=\"p-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants' },\r\n ]}\r\n />\r\n <div className=\"mt-4 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{tenantDetail.error || t('admin:tenants.notFound')}</span>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const tenant = tenantDetail.tenant;\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants' },\r\n { label: tenant.name, href: `/administration/tenants/${tenantId}` },\r\n { label: t('admin:tenants.settings.title') },\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate(`/administration/tenants/${tenantId}`)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)]\">\r\n <Settings className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-xl sm:text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('admin:tenants.settings.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{tenant.name}</p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Error */}\r\n {tenantDetail.error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{tenantDetail.error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Tab Navigation */}\r\n <div className=\"border-b border-[var(--border-color)]\">\r\n <div className=\"flex gap-1 -mb-px\">\r\n {VALID_TABS.map(tab => (\r\n <button\r\n key={tab}\r\n onClick={() => setActiveTab(tab)}\r\n className={`px-4 py-2 border-b-2 transition-colors ${\r\n activeTab === tab\r\n ? 'border-[var(--primary-color)] text-[var(--primary-color)]'\r\n : 'border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n >\r\n {t(`admin:tenants.settings.tabs.${tab}`)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Tab Content */}\r\n <div>\r\n {activeTab === 'entra' && tenantId && (\r\n <TenantEntraTab\r\n tenantId={tenantId}\r\n tenantName={tenant.name}\r\n tenantSlug={tenant.slug}\r\n />\r\n )}\r\n\r\n {activeTab === 'support' && tenantId && (\r\n <TenantSupportSettingsTab\r\n tenantId={tenantId}\r\n tenantName={tenant.name}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Loader2,\r\n Save,\r\n AlertTriangle,\r\n CheckCircle,\r\n ChevronDown,\r\n Palette,\r\n} from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { PageHeader } from '@/components/ui/PageHeader';\r\nimport { tenantTypeSettingsApi, type TenantTypeSettingsDto, type UpdateTenantTypeSettingsRequest } from '@/services/api/tenantTypeSettingsApi';\r\nimport type { TenantType } from '@/services/api/adminApi';\r\nimport { getLucideIcon, getAvailableIconNames, getColorClasses, getAvailableColors } from '@/utils/tenantIconMap';\r\n\r\ninterface CardEditState {\r\n icon: string;\r\n iconType: 'Lucide' | 'Url' | 'Svg';\r\n color: string;\r\n displayName: string;\r\n description: string;\r\n}\r\n\r\nexport function TenantTypeSettingsPage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n\r\n const [settings, setSettings] = useState<TenantTypeSettingsDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n const [editStates, setEditStates] = useState<Record<string, CardEditState>>({});\r\n const [savingType, setSavingType] = useState<TenantType | null>(null);\r\n\r\n const loadSettings = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n setError(null);\r\n const data = await tenantTypeSettingsApi.getAll();\r\n setSettings(data);\r\n\r\n const states: Record<string, CardEditState> = {};\r\n for (const s of data) {\r\n states[s.type] = {\r\n icon: s.icon,\r\n iconType: s.iconType,\r\n color: s.color,\r\n displayName: s.displayName,\r\n description: s.description ?? '',\r\n };\r\n }\r\n setEditStates(states);\r\n } catch {\r\n setError(t('admin:tenantTypeSettings.loadError'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [t]);\r\n\r\n useEffect(() => {\r\n loadSettings();\r\n }, [loadSettings]);\r\n\r\n const handleSave = async (type: TenantType) => {\r\n const state = editStates[type];\r\n if (!state) return;\r\n\r\n try {\r\n setSavingType(type);\r\n setError(null);\r\n const request: UpdateTenantTypeSettingsRequest = {\r\n icon: state.icon,\r\n iconType: state.iconType,\r\n color: state.color,\r\n displayName: state.displayName,\r\n description: state.description || null,\r\n };\r\n await tenantTypeSettingsApi.update(type, request);\r\n setSuccess(t('admin:tenantTypeSettings.saveSuccess'));\r\n setTimeout(() => setSuccess(null), 3000);\r\n await loadSettings();\r\n } catch {\r\n setError(t('admin:tenantTypeSettings.saveError'));\r\n } finally {\r\n setSavingType(null);\r\n }\r\n };\r\n\r\n const updateEditState = (type: string, field: keyof CardEditState, value: string) => {\r\n setEditStates((prev) => ({\r\n ...prev,\r\n [type]: { ...prev[type], [field]: value },\r\n }));\r\n };\r\n\r\n const hasChanges = (type: string): boolean => {\r\n const original = settings.find((s) => s.type === type);\r\n const current = editStates[type];\r\n if (!original || !current) return false;\r\n return (\r\n original.icon !== current.icon ||\r\n original.color !== current.color ||\r\n original.displayName !== current.displayName ||\r\n (original.description ?? '') !== current.description\r\n );\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"p-6 flex items-center justify-center min-h-[400px]\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants' },\r\n { label: t('admin:tenantTypeSettings.title') },\r\n ]}\r\n />\r\n\r\n <PageHeader\r\n title={t('admin:tenantTypeSettings.title')}\r\n subtitle={t('admin:tenantTypeSettings.subtitle')}\r\n icon={<Palette className=\"w-6 h-6\" />}\r\n />\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-lg bg-red-500/10 border border-red-500/20 flex items-center gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-red-500 flex-shrink-0\" />\r\n <p className=\"text-red-500\">{error}</p>\r\n </div>\r\n )}\r\n\r\n {success && (\r\n <div className=\"p-4 rounded-lg bg-green-500/10 border border-green-500/20 flex items-center gap-3\">\r\n <CheckCircle className=\"w-5 h-5 text-green-500 flex-shrink-0\" />\r\n <p className=\"text-green-500\">{success}</p>\r\n </div>\r\n )}\r\n\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\r\n {settings.map((setting) => {\r\n const state = editStates[setting.type];\r\n if (!state) return null;\r\n\r\n const PreviewIcon = getLucideIcon(state.icon);\r\n const previewColors = getColorClasses(state.color);\r\n\r\n return (\r\n <div\r\n key={setting.type}\r\n className=\"p-6 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)] space-y-5\"\r\n >\r\n {/* Preview */}\r\n <div className=\"flex items-center gap-4\">\r\n <div className={`w-14 h-14 rounded-xl flex items-center justify-center ${previewColors.bg}`}>\r\n <PreviewIcon className={`w-7 h-7 ${previewColors.text}`} />\r\n </div>\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">{state.displayName}</h3>\r\n <p className=\"text-sm text-[var(--text-tertiary)]\">{setting.type}</p>\r\n </div>\r\n </div>\r\n\r\n {/* Display Name */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('admin:tenantTypeSettings.displayName')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={state.displayName}\r\n onChange={(e) => updateEditState(setting.type, 'displayName', e.target.value)}\r\n className=\"w-full px-3 py-2 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n {/* Icon Selector */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('admin:tenantTypeSettings.icon')}\r\n </label>\r\n <div className=\"relative\">\r\n <select\r\n value={state.icon}\r\n onChange={(e) => updateEditState(setting.type, 'icon', e.target.value)}\r\n className=\"w-full px-3 py-2 pr-8 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] appearance-none focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n {getAvailableIconNames().map((name) => (\r\n <option key={name} value={name}>{name}</option>\r\n ))}\r\n </select>\r\n <ChevronDown className=\"absolute right-2 top-1/2 transform -translate-y-1/2 w-4 h-4 text-[var(--text-tertiary)] pointer-events-none\" />\r\n </div>\r\n </div>\r\n\r\n {/* Color Selector */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('admin:tenantTypeSettings.color')}\r\n </label>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {getAvailableColors().map((color) => {\r\n const colorClasses = getColorClasses(color);\r\n return (\r\n <button\r\n key={color}\r\n onClick={() => updateEditState(setting.type, 'color', color)}\r\n className={`w-8 h-8 rounded-full flex items-center justify-center transition-all ${colorClasses.bg} ${\r\n state.color === color ? 'ring-2 ring-offset-2 ring-[var(--color-accent-500)]' : ''\r\n }`}\r\n title={color}\r\n >\r\n <div className={`w-4 h-4 rounded-full ${colorClasses.text.replace('text-', 'bg-')}`} />\r\n </button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n\r\n {/* Description */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('admin:tenantTypeSettings.description')}\r\n </label>\r\n <textarea\r\n value={state.description}\r\n onChange={(e) => updateEditState(setting.type, 'description', e.target.value)}\r\n rows={2}\r\n className=\"w-full px-3 py-2 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n\r\n {/* Save Button */}\r\n <button\r\n onClick={() => handleSave(setting.type as TenantType)}\r\n disabled={!hasChanges(setting.type) || savingType === setting.type}\r\n className=\"w-full flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n {savingType === setting.type ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Save className=\"w-4 h-4\" />\r\n )}\r\n {t('common:save')}\r\n </button>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { Plus, AlertTriangle, Building } from 'lucide-react';\r\nimport { adminApi, type OrganisationListItemDto, type VerificationStatus } from '@/services/api/adminApi';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { DataTable, type DataTableColumn } from '@/components/ui/DataTable';\r\n\r\nconst VERIFICATION_STATUS_CONFIG: Record<VerificationStatus, { bgColor: string; textColor: string }> = {\r\n Pending: {\r\n bgColor: 'bg-[var(--warning-bg)]',\r\n textColor: 'text-[var(--warning-text)]',\r\n },\r\n Verified: {\r\n bgColor: 'bg-[var(--success-bg)]',\r\n textColor: 'text-[var(--success-text)]',\r\n },\r\n Rejected: {\r\n bgColor: 'bg-[var(--error-bg)]',\r\n textColor: 'text-[var(--error-text)]',\r\n },\r\n};\r\n\r\nexport function OrganisationsListPage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const navigate = useNavigate();\r\n\r\n const [organisations, setOrganisations] = useState<OrganisationListItemDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [page, setPage] = useState(1);\r\n const [pageSize] = useState(10);\r\n const [totalPages, setTotalPages] = useState(1);\r\n const [search, setSearch] = useState('');\r\n const [verificationFilter, setVerificationFilter] = useState<VerificationStatus | 'All'>('All');\r\n\r\n const loadOrganisations = useCallback(async (signal?: AbortSignal) => {\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n const result = await adminApi.organisations.getAll({\r\n page,\r\n pageSize,\r\n search: search || undefined,\r\n verificationStatus: verificationFilter !== 'All' ? verificationFilter : undefined,\r\n });\r\n if (!signal?.aborted) {\r\n setOrganisations(result.items);\r\n setTotalPages(Math.ceil(result.totalCount / pageSize));\r\n }\r\n } catch (err) {\r\n if (!signal?.aborted) {\r\n console.error('Failed to load organisations:', err);\r\n setError(t('common:error', 'An error occurred'));\r\n }\r\n } finally {\r\n if (!signal?.aborted) {\r\n setLoading(false);\r\n }\r\n }\r\n }, [page, pageSize, search, verificationFilter, t]);\r\n\r\n useEffect(() => {\r\n const abortController = new AbortController();\r\n loadOrganisations(abortController.signal);\r\n return () => abortController.abort();\r\n }, [loadOrganisations]);\r\n\r\n const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n setSearch(e.target.value);\r\n setPage(1);\r\n };\r\n\r\n const statusFilters: (VerificationStatus | 'All')[] = ['All', 'Pending', 'Verified', 'Rejected'];\r\n\r\n const columns: DataTableColumn<OrganisationListItemDto>[] = [\r\n {\r\n key: 'name',\r\n label: t('admin:organisations.columns.name', 'Name'),\r\n sortable: true,\r\n render: (org) => (\r\n <div>\r\n <div className=\"font-medium text-[var(--text-primary)]\">{org.name}</div>\r\n {org.legalName && (\r\n <div className=\"text-xs text-[var(--text-secondary)]\">{org.legalName}</div>\r\n )}\r\n </div>\r\n ),\r\n },\r\n {\r\n key: 'countryCode',\r\n label: t('admin:organisations.columns.country', 'Country'),\r\n sortable: true,\r\n },\r\n {\r\n key: 'businessIdentifier',\r\n label: t('admin:organisations.columns.identifier', 'Business ID'),\r\n sortable: true,\r\n render: (org) => (\r\n <span className=\"font-mono text-[var(--text-primary)]\">{org.businessIdentifier}</span>\r\n ),\r\n },\r\n {\r\n key: 'verificationStatus',\r\n label: t('admin:organisations.columns.status', 'Status'),\r\n sortable: true,\r\n render: (org) => (\r\n <span\r\n className={`inline-block px-3 py-1 rounded-[var(--radius-badge)] text-xs font-medium ${\r\n VERIFICATION_STATUS_CONFIG[org.verificationStatus].bgColor\r\n } ${VERIFICATION_STATUS_CONFIG[org.verificationStatus].textColor}`}\r\n >\r\n {t(\r\n `admin:organisations.status.${org.verificationStatus.toLowerCase()}`,\r\n org.verificationStatus\r\n )}\r\n </span>\r\n ),\r\n },\r\n {\r\n key: 'createdAt',\r\n label: t('admin:organisations.columns.created', 'Created'),\r\n sortable: true,\r\n render: (org) => (\r\n <span className=\"text-[var(--text-secondary)]\">\r\n {new Date(org.createdAt).toLocaleDateString()}\r\n </span>\r\n ),\r\n },\r\n {\r\n key: 'actions',\r\n label: t('admin:organisations.columns.actions', 'Actions'),\r\n align: 'right',\r\n render: (org) => (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n navigate(`/administration/tenants/create?type=b2b&organisationId=${org.id}`);\r\n }}\r\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-[var(--radius-button)] bg-[var(--info-bg)] text-[var(--info-text)] border border-[var(--info-border)] hover:opacity-80 transition-colors\"\r\n title={t('admin:organisations.createTenant', 'Create B2B tenant for this organisation')}\r\n >\r\n <Building className=\"w-3.5 h-3.5\" />\r\n {t('admin:organisations.createTenantButton', 'Create tenant')}\r\n </button>\r\n ),\r\n },\r\n ];\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('admin:organisations.title', 'Organisations') },\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('admin:organisations.title', 'Organisations')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:organisations.description', 'Manage organisations and verify their details')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={() => navigate('/administration/tenants/organisations/create')}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-500)] text-white hover:bg-[var(--color-accent-600)] transition-colors\"\r\n >\r\n <Plus className=\"w-5 h-5\" />\r\n {t('common:create', 'Create')}\r\n </button>\r\n </div>\r\n\r\n <div className=\"space-y-4\">\r\n <div className=\"flex flex-col sm:flex-row gap-4\">\r\n <div className=\"relative flex-1\">\r\n <input\r\n type=\"text\"\r\n placeholder={t('common:search', 'Search')}\r\n value={search}\r\n onChange={handleSearchChange}\r\n className=\"input w-full pl-10\"\r\n />\r\n </div>\r\n\r\n <div className=\"flex flex-wrap gap-2\">\r\n {statusFilters.map((status) => (\r\n <button\r\n key={status}\r\n onClick={() => {\r\n setVerificationFilter(status);\r\n setPage(1);\r\n }}\r\n className={`px-3 py-1 rounded-[var(--radius-badge)] text-sm transition-colors ${\r\n verificationFilter === status\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n {status === 'All' ? t('common:all', 'All') : t(`admin:organisations.status.${status.toLowerCase()}`, status)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n <button\r\n onClick={() => loadOrganisations()}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:retry', 'Retry')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n <DataTable\r\n data={organisations}\r\n columns={columns}\r\n loading={loading}\r\n getRowKey={(item) => item.id}\r\n onRowClick={(item) => navigate(`/administration/tenants/organisations/${item.id}`)}\r\n emptyMessage={t('admin:organisations.empty', 'No organisations found')}\r\n />\r\n\r\n {!loading && organisations.length > 0 && (\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('common:page', 'Page')} {page} {t('common:of', 'of')} {totalPages}\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <button\r\n onClick={() => setPage(Math.max(1, page - 1))}\r\n disabled={page === 1}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {t('common:previous', 'Previous')}\r\n </button>\r\n <button\r\n onClick={() => setPage(Math.min(totalPages, page + 1))}\r\n disabled={page >= totalPages}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {t('common:next', 'Next')}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useParams, useNavigate, useSearchParams } from 'react-router-dom';\r\nimport { ArrowLeft, Loader2, AlertTriangle, Check, X } from 'lucide-react';\r\nimport { adminApi, type OrganisationDto, type VerificationStatus } from '@/services/api/adminApi';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\n\r\nconst VERIFICATION_STATUS_CONFIG: Record<VerificationStatus, { bgColor: string; textColor: string }> = {\r\n Pending: {\r\n bgColor: 'bg-[var(--warning-bg)]',\r\n textColor: 'text-[var(--warning-text)]',\r\n },\r\n Verified: {\r\n bgColor: 'bg-[var(--success-bg)]',\r\n textColor: 'text-[var(--success-text)]',\r\n },\r\n Rejected: {\r\n bgColor: 'bg-[var(--error-bg)]',\r\n textColor: 'text-[var(--error-text)]',\r\n },\r\n};\r\n\r\ntype TabType = 'info' | 'contact' | 'address';\r\nconst VALID_TABS: TabType[] = ['info', 'contact', 'address'];\r\n\r\nexport function OrganisationDetailPage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const { id: orgId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n\r\n const [organisation, setOrganisation] = useState<OrganisationDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [actionLoading, setActionLoading] = useState(false);\r\n\r\n // Tab management\r\n const getInitialTab = (): TabType => {\r\n const tabParam = searchParams.get('tab');\r\n if (tabParam && VALID_TABS.includes(tabParam as TabType)) {\r\n return tabParam as TabType;\r\n }\r\n return 'info';\r\n };\r\n\r\n const [activeTab, setActiveTab] = useState<TabType>(getInitialTab);\r\n\r\n // Modal states\r\n const [verifyModal, setVerifyModal] = useState<{ show: boolean; notes: string }>({\r\n show: false,\r\n notes: '',\r\n });\r\n const [rejectModal, setRejectModal] = useState<{ show: boolean; reason: string }>({\r\n show: false,\r\n reason: '',\r\n });\r\n\r\n // Sync URL with active tab\r\n useEffect(() => {\r\n if (activeTab === 'info') {\r\n if (searchParams.get('tab')) {\r\n searchParams.delete('tab');\r\n setSearchParams(searchParams, { replace: true });\r\n }\r\n } else if (searchParams.get('tab') !== activeTab) {\r\n setSearchParams({ tab: activeTab }, { replace: true });\r\n }\r\n }, [activeTab, searchParams, setSearchParams]);\r\n\r\n const loadOrganisation = useCallback(async () => {\r\n if (!orgId) {\r\n navigate('/administration/tenants/organisations');\r\n return;\r\n }\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n const data = await adminApi.organisations.getById(orgId);\r\n setOrganisation(data);\r\n } catch (err) {\r\n console.error('Failed to load organisation:', err);\r\n setError(t('admin:organisations.loadError', 'Failed to load organisation'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [orgId, navigate, t]);\r\n\r\n useEffect(() => {\r\n loadOrganisation();\r\n }, [loadOrganisation]);\r\n\r\n const handleVerify = async () => {\r\n if (!organisation) return;\r\n setActionLoading(true);\r\n try {\r\n const updated = await adminApi.organisations.verify(organisation.id, verifyModal.notes || undefined);\r\n setOrganisation(updated);\r\n setVerifyModal({ show: false, notes: '' });\r\n } catch (err) {\r\n console.error('Failed to verify organisation:', err);\r\n setError(t('admin:organisations.verifyError', 'Failed to verify organisation'));\r\n } finally {\r\n setActionLoading(false);\r\n }\r\n };\r\n\r\n const handleReject = async () => {\r\n if (!organisation) return;\r\n setActionLoading(true);\r\n try {\r\n const updated = await adminApi.organisations.reject(organisation.id, rejectModal.reason);\r\n setOrganisation(updated);\r\n setRejectModal({ show: false, reason: '' });\r\n } catch (err) {\r\n console.error('Failed to reject organisation:', err);\r\n setError(t('admin:organisations.rejectError', 'Failed to reject organisation'));\r\n } finally {\r\n setActionLoading(false);\r\n }\r\n };\r\n\r\n const hasContactData = organisation && (organisation.phone || organisation.email || organisation.website);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"p-6 flex items-center justify-center min-h-[400px]\">\r\n <div className=\"text-center\">\r\n <Loader2 className=\"w-8 h-8 animate-spin mx-auto mb-2 text-[var(--text-secondary)]\" />\r\n <p className=\"text-[var(--text-secondary)]\">{t('common:loading', 'Loading')}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!organisation) {\r\n return (\r\n <div className=\"p-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('admin:organisations.title', 'Organisations'), href: '/administration/tenants/organisations' },\r\n ]}\r\n />\r\n <div className=\"mt-4 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error || t('admin:organisations.notFound', 'Organisation not found')}</span>\r\n </div>\r\n <button\r\n onClick={loadOrganisation}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:retry', 'Retry')}\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const statusConfig = VERIFICATION_STATUS_CONFIG[organisation.verificationStatus];\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('admin:organisations.title', 'Organisations'), href: '/administration/tenants/organisations' },\r\n { label: organisation.name },\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/tenants/organisations')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">{organisation.name}</h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{organisation.businessIdentifier}</p>\r\n </div>\r\n </div>\r\n <span className={`px-4 py-2 rounded-[var(--radius-badge)] text-sm font-medium ${statusConfig.bgColor} ${statusConfig.textColor}`}>\r\n {t(`admin:organisations.status.${organisation.verificationStatus.toLowerCase()}`, organisation.verificationStatus)}\r\n </span>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n <button\r\n onClick={loadOrganisation}\r\n className=\"mt-2 text-sm text-[var(--error-text)] hover:opacity-80 underline\"\r\n >\r\n {t('common:retry', 'Retry')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n <div className=\"border-b border-[var(--border-color)]\">\r\n <div className=\"flex gap-1 -mb-px\">\r\n {VALID_TABS.map((tab) => (\r\n <button\r\n key={tab}\r\n onClick={() => setActiveTab(tab)}\r\n className={`px-4 py-2 border-b-2 transition-colors ${\r\n activeTab === tab\r\n ? 'border-[var(--primary-color)] text-[var(--primary-color)]'\r\n : 'border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n >\r\n {t(`admin:organisations.tabs.${tab}`, tab)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {activeTab === 'info' && (\r\n <div className=\"space-y-4\">\r\n <div className=\"grid grid-cols-2 gap-4\">\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.name', 'Organisation Name')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.name}</p>\r\n </div>\r\n {organisation.legalName && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.legalName', 'Legal Name')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.legalName}</p>\r\n </div>\r\n )}\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.country', 'Country')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.countryCode}</p>\r\n </div>\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {organisation.businessIdentifierType}\r\n </label>\r\n <p className=\"mt-1 font-mono text-[var(--text-primary)]\">{organisation.businessIdentifier}</p>\r\n </div>\r\n {organisation.vatNumber && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.vatNumber', 'VAT Number')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.vatNumber}</p>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {organisation.verificationStatus !== 'Verified' && (\r\n <div className=\"flex gap-2 pt-4\">\r\n {(organisation.verificationStatus === 'Pending' || organisation.verificationStatus === 'Rejected') && (\r\n <button\r\n onClick={() => setVerifyModal({ show: true, notes: '' })}\r\n disabled={actionLoading}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--success-bg)] text-[var(--success-text)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\r\n >\r\n <Check className=\"w-4 h-4\" />\r\n {t('admin:organisations.verify', 'Verify')}\r\n </button>\r\n )}\r\n {organisation.verificationStatus === 'Pending' && (\r\n <button\r\n onClick={() => setRejectModal({ show: true, reason: '' })}\r\n disabled={actionLoading}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--error-bg)] text-[var(--error-text)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\r\n >\r\n <X className=\"w-4 h-4\" />\r\n {t('admin:organisations.reject', 'Reject')}\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {activeTab === 'contact' && (\r\n hasContactData ? (\r\n <div className=\"grid grid-cols-2 gap-4\">\r\n {organisation.phone && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.phone', 'Phone')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.phone}</p>\r\n </div>\r\n )}\r\n {organisation.email && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.email', 'Email')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)]\">{organisation.email}</p>\r\n </div>\r\n )}\r\n {organisation.website && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.website', 'Website')}\r\n </label>\r\n <p className=\"mt-1 text-[var(--text-primary)] break-all\">{organisation.website}</p>\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"py-12 text-center text-[var(--text-secondary)]\">\r\n {t('admin:organisations.noContact', 'No contact information available')}\r\n </div>\r\n )\r\n )}\r\n\r\n {activeTab === 'address' && (\r\n organisation.address ? (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n <div className=\"space-y-2\">\r\n <div>\r\n <label className=\"text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide\">\r\n {t('admin:organisations.form.address', 'Address')}\r\n </label>\r\n <p className=\"text-[var(--text-primary)]\">{organisation.address.street}</p>\r\n {organisation.address.street2 && (\r\n <p className=\"text-[var(--text-primary)]\">{organisation.address.street2}</p>\r\n )}\r\n </div>\r\n <div>\r\n <p className=\"text-[var(--text-primary)]\">\r\n {organisation.address.postalCode} {organisation.address.city}\r\n </p>\r\n {organisation.address.state && (\r\n <p className=\"text-[var(--text-primary)]\">{organisation.address.state}</p>\r\n )}\r\n </div>\r\n <div>\r\n <p className=\"text-[var(--text-primary)]\">\r\n {organisation.address.country} ({organisation.address.countryCode})\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"py-12 text-center text-[var(--text-secondary)]\">\r\n {t('admin:organisations.noAddress', 'No address information available')}\r\n </div>\r\n )\r\n )}\r\n\r\n {verifyModal.show && (\r\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] p-6 max-w-md w-full mx-4\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)] mb-4\">\r\n {t('admin:organisations.verifyTitle', 'Verify Organisation')}\r\n </h2>\r\n <div className=\"mb-4 space-y-3\">\r\n <div>\r\n <label className=\"block text-sm text-[var(--text-secondary)] mb-1\">\r\n {t('admin:organisations.verifyNotes', 'Notes (optional)')}\r\n </label>\r\n <textarea\r\n value={verifyModal.notes}\r\n onChange={(e) => setVerifyModal({ ...verifyModal, notes: e.target.value })}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n rows={3}\r\n placeholder={t('admin:organisations.verifyNotesPlaceholder', 'Add notes about verification')}\r\n />\r\n </div>\r\n </div>\r\n <div className=\"flex gap-2 justify-end\">\r\n <button\r\n onClick={() => setVerifyModal({ show: false, notes: '' })}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common:cancel', 'Cancel')}\r\n </button>\r\n <button\r\n onClick={handleVerify}\r\n disabled={actionLoading}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--success-bg)] text-[var(--success-text)] hover:opacity-90 disabled:opacity-50\"\r\n >\r\n {actionLoading ? t('common:saving', 'Saving') : t('admin:organisations.verify', 'Verify')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {rejectModal.show && (\r\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] p-6 max-w-md w-full mx-4\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)] mb-4\">\r\n {t('admin:organisations.rejectTitle', 'Reject Organisation')}\r\n </h2>\r\n <div className=\"mb-4\">\r\n <label className=\"block text-sm text-[var(--text-secondary)] mb-1\">\r\n {t('admin:organisations.rejectReason', 'Reason')}\r\n </label>\r\n <textarea\r\n value={rejectModal.reason}\r\n onChange={(e) => setRejectModal({ ...rejectModal, reason: e.target.value })}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n rows={3}\r\n placeholder={t('admin:organisations.rejectReasonPlaceholder', 'Explain why this organisation is rejected')}\r\n />\r\n </div>\r\n <div className=\"flex gap-2 justify-end\">\r\n <button\r\n onClick={() => setRejectModal({ show: false, reason: '' })}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common:cancel', 'Cancel')}\r\n </button>\r\n <button\r\n onClick={handleReject}\r\n disabled={actionLoading}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--error-bg)] text-[var(--error-text)] hover:opacity-90 disabled:opacity-50\"\r\n >\r\n {actionLoading ? t('common:saving', 'Saving') : t('admin:organisations.reject', 'Reject')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Loader2,\r\n AlertTriangle,\r\n Check,\r\n Search,\r\n} from 'lucide-react';\r\nimport {\r\n adminApi,\r\n type CreateOrganisationRequest,\r\n type BusinessIdentifierType,\r\n} from '@/services/api/adminApi';\r\n\r\n// Country to business identifier type mapping\r\nconst countryIdentifierTypes: Record<string, {\r\n types: BusinessIdentifierType[];\r\n defaultType: BusinessIdentifierType;\r\n country: string;\r\n vatSuffix?: string;\r\n}> = {\r\n CH: { types: ['UID_CHE'], defaultType: 'UID_CHE', country: 'Switzerland', vatSuffix: 'MWST' },\r\n FR: { types: ['SIREN', 'SIRET'], defaultType: 'SIREN', country: 'France', vatSuffix: 'TVA' },\r\n DE: { types: ['HRB', 'HRA'], defaultType: 'HRB', country: 'Germany', vatSuffix: 'USt' },\r\n BE: { types: ['BCE_KBO'], defaultType: 'BCE_KBO', country: 'Belgium', vatSuffix: 'TVA' },\r\n NL: { types: ['KVK'], defaultType: 'KVK', country: 'Netherlands', vatSuffix: 'BTW' },\r\n ES: { types: ['CIF'], defaultType: 'CIF', country: 'Spain', vatSuffix: 'IVA' },\r\n IT: { types: ['PartitaIVA'], defaultType: 'PartitaIVA', country: 'Italy', vatSuffix: 'IVA' },\r\n GB: { types: ['CRN'], defaultType: 'CRN', country: 'United Kingdom', vatSuffix: 'VAT' },\r\n};\r\n\r\nexport interface OrganisationFormData {\r\n name: string;\r\n legalName?: string;\r\n countryCode: string;\r\n businessIdentifierType: BusinessIdentifierType;\r\n businessIdentifier: string;\r\n vatNumber?: string;\r\n phone?: string;\r\n email?: string;\r\n website?: string;\r\n isFromRegistry: boolean;\r\n address: {\r\n street: string;\r\n street2?: string;\r\n postalCode: string;\r\n city: string;\r\n state?: string | null;\r\n country: string;\r\n countryCode: string;\r\n };\r\n}\r\n\r\ninterface CreateOrganisationFormProps {\r\n /** Form data (controlled) */\r\n readonly data: OrganisationFormData;\r\n /** Callback when form data changes */\r\n readonly onChange: (data: OrganisationFormData) => void;\r\n /** Callback when tenant name should be updated (optional, for TenantCreatePage) */\r\n readonly onTenantNameSuggested?: (name: string) => void;\r\n /** Whether the form is in a compact modal layout */\r\n readonly compact?: boolean;\r\n /** Whether form submission was attempted (shows validation errors) */\r\n readonly submitted?: boolean;\r\n /** Additional class names */\r\n readonly className?: string;\r\n}\r\n\r\n/**\r\n * Shared form component for creating organisations.\r\n * Used by both TenantCreatePage and TenantDetailPage modal.\r\n */\r\nexport function CreateOrganisationForm({\r\n data,\r\n onChange,\r\n onTenantNameSuggested,\r\n compact = false,\r\n submitted = false,\r\n className = '',\r\n}: CreateOrganisationFormProps): ReactElement {\r\n const { t, i18n } = useTranslation(['admin', 'common']);\r\n\r\n // Lookup state\r\n const [lookupLoading, setLookupLoading] = useState(false);\r\n const [lookupError, setLookupError] = useState<string | null>(null);\r\n const [lookupSuccess, setLookupSuccess] = useState(false);\r\n\r\n // Format CHE number: CHE-XXX.XXX.XXX\r\n const formatCheNumber = (value: string): string => {\r\n const cleaned = value.toUpperCase().replace(/[^A-Z0-9]/g, '');\r\n let digits = cleaned.startsWith('CHE') ? cleaned.slice(3) : cleaned.replace(/[^0-9]/g, '');\r\n digits = digits.slice(0, 9);\r\n\r\n if (digits.length === 0) return 'CHE-';\r\n if (digits.length <= 3) return `CHE-${digits}`;\r\n if (digits.length <= 6) return `CHE-${digits.slice(0, 3)}.${digits.slice(3)}`;\r\n return `CHE-${digits.slice(0, 3)}.${digits.slice(3, 6)}.${digits.slice(6)}`;\r\n };\r\n\r\n // Get VAT suffix based on language preference for Switzerland\r\n const getVatSuffix = (): string => {\r\n const lang = i18n.language?.substring(0, 2).toLowerCase();\r\n switch (lang) {\r\n case 'de': return 'MWST';\r\n case 'fr': return 'TVA';\r\n case 'it': return 'IVA';\r\n default: return 'MWST'; // Default to German for Switzerland\r\n }\r\n };\r\n\r\n const handleBusinessIdChange = (value: string) => {\r\n let newValue = value;\r\n if (data.countryCode === 'CH') {\r\n newValue = formatCheNumber(value);\r\n }\r\n onChange({ ...data, businessIdentifier: newValue, isFromRegistry: false });\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n };\r\n\r\n const handleCountryChange = (countryCode: string) => {\r\n const config = countryIdentifierTypes[countryCode];\r\n if (config) {\r\n onChange({\r\n ...data,\r\n countryCode,\r\n businessIdentifierType: config.defaultType,\r\n businessIdentifier: countryCode === 'CH' ? 'CHE-' : '',\r\n isFromRegistry: false,\r\n address: {\r\n ...data.address,\r\n countryCode,\r\n country: config.country,\r\n },\r\n });\r\n }\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n };\r\n\r\n // Pre-fill CHE- when switching to Switzerland\r\n useEffect(() => {\r\n if (data.countryCode === 'CH' && (!data.businessIdentifier || data.businessIdentifier === '')) {\r\n onChange({ ...data, businessIdentifier: 'CHE-' });\r\n }\r\n }, [data.countryCode]);\r\n\r\n const handleLookup = async () => {\r\n const cleanedId = data.businessIdentifier.replace(/[^0-9]/g, '');\r\n if (!data.businessIdentifier || cleanedId.length < 9 || data.countryCode !== 'CH') {\r\n setLookupError(t('admin:tenants.organisation.lookupIncomplete', 'Please enter a complete CHE number (9 digits)'));\r\n return;\r\n }\r\n\r\n setLookupLoading(true);\r\n setLookupError(null);\r\n setLookupSuccess(false);\r\n\r\n try {\r\n const result = await adminApi.organisations.lookup(data.countryCode, data.businessIdentifier);\r\n\r\n // Auto-fill form fields\r\n const updatedData: OrganisationFormData = {\r\n ...data,\r\n name: result.name || data.name,\r\n legalName: result.legalName || data.legalName,\r\n vatNumber: result.vatNumber ? `${result.vatNumber} ${getVatSuffix()}` : data.vatNumber,\r\n phone: result.phone || data.phone,\r\n email: result.email || data.email,\r\n website: result.website || data.website,\r\n isFromRegistry: true,\r\n address: {\r\n street: result.street || data.address.street,\r\n street2: result.street2 || data.address.street2,\r\n postalCode: result.postalCode || data.address.postalCode,\r\n city: result.city || data.address.city,\r\n state: result.state || data.address.state,\r\n country: result.country || data.address.country,\r\n countryCode: result.countryCode || data.address.countryCode,\r\n },\r\n };\r\n\r\n onChange(updatedData);\r\n\r\n // Suggest tenant name if callback provided\r\n if (onTenantNameSuggested && result.name) {\r\n onTenantNameSuggested(result.name);\r\n }\r\n\r\n setLookupSuccess(true);\r\n setTimeout(() => setLookupSuccess(false), 3000);\r\n } catch (err: unknown) {\r\n console.error('[Zefix Lookup] Failed:', err);\r\n const errorMessage = err instanceof Error ? err.message : '';\r\n if (errorMessage.includes('404') || errorMessage.includes('not found')) {\r\n setLookupError(t('admin:tenants.organisation.lookupFailed', 'Company not found in registry'));\r\n } else if (errorMessage.includes('credentials') || errorMessage.includes('401')) {\r\n setLookupError(t('admin:tenants.organisation.lookupAuthError', 'Registry service not configured'));\r\n } else {\r\n setLookupError(t('admin:tenants.organisation.lookupFailed', 'Company not found in registry'));\r\n }\r\n } finally {\r\n setLookupLoading(false);\r\n }\r\n };\r\n\r\n const inputClass = compact\r\n ? \"w-full px-3 py-2 border border-[var(--border-color)] rounded-[var(--radius-input)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n : \"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\";\r\n\r\n const inputErrorClass = \"border-[var(--error-text)] ring-1 ring-[var(--error-text)]\";\r\n\r\n const fieldClass = (hasError: boolean) =>\r\n hasError ? `${inputClass} ${inputErrorClass}` : inputClass;\r\n\r\n const labelClass = \"block text-sm font-medium text-[var(--text-secondary)] mb-1\";\r\n\r\n return (\r\n <div className={`space-y-4 ${className}`}>\r\n {/* Organisation Name */}\r\n <div>\r\n <label className={labelClass}>\r\n {t('admin:tenants.organisation.form.name', 'Organisation Name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={data.name}\r\n onChange={(e) => onChange({ ...data, name: e.target.value })}\r\n className={fieldClass(submitted && !data.name.trim())}\r\n placeholder={t('admin:tenants.organisation.form.namePlaceholder', 'Enter organisation name')}\r\n />\r\n {submitted && !data.name.trim() && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1\">{t('common:validation.required', 'This field is required')}</p>\r\n )}\r\n </div>\r\n\r\n {/* Country */}\r\n <div>\r\n <label className={labelClass}>\r\n {t('admin:tenants.organisation.form.country', 'Country')} *\r\n </label>\r\n <select\r\n value={data.countryCode}\r\n onChange={(e) => handleCountryChange(e.target.value)}\r\n className={inputClass}\r\n >\r\n {Object.entries(countryIdentifierTypes).map(([code, config]) => (\r\n <option key={code} value={code}>{config.country} ({code})</option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n {/* Business Identifier */}\r\n <div>\r\n <label className={labelClass}>\r\n {data.businessIdentifierType} *\r\n </label>\r\n <div className=\"flex gap-2\">\r\n <input\r\n type=\"text\"\r\n value={data.businessIdentifier}\r\n onChange={(e) => handleBusinessIdChange(e.target.value)}\r\n className={`flex-1 ${inputClass} font-mono`}\r\n placeholder={data.countryCode === 'CH' ? 'CHE-123.456.789' : t('admin:tenants.organisation.form.identifierPlaceholder', 'Enter identifier')}\r\n />\r\n {/* Search button - only show for Switzerland */}\r\n {data.countryCode === 'CH' && (\r\n <button\r\n type=\"button\"\r\n onClick={handleLookup}\r\n disabled={lookupLoading || !data.businessIdentifier || data.businessIdentifier.replace(/[^0-9]/g, '').length < 9}\r\n className=\"px-3 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-500)] text-white hover:bg-[var(--color-accent-600)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center\"\r\n title={t('admin:tenants.organisation.lookupTitle', 'Search in registry')}\r\n >\r\n {lookupLoading ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Search className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n )}\r\n </div>\r\n {/* Feedback messages */}\r\n {lookupError && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1 flex items-center gap-1\">\r\n <AlertTriangle className=\"w-3 h-3\" />\r\n {lookupError}\r\n </p>\r\n )}\r\n {lookupSuccess && (\r\n <p className=\"text-xs text-[var(--success-text)] mt-1 flex items-center gap-1\">\r\n <Check className=\"w-3 h-3\" />\r\n {t('admin:tenants.organisation.lookupSuccess', 'Information retrieved successfully')}\r\n </p>\r\n )}\r\n {data.countryCode === 'CH' && !lookupError && !lookupSuccess && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1\">\r\n {data.businessIdentifier.replace(/[^0-9]/g, '').length < 9\r\n ? t('admin:tenants.organisation.lookupHintIncomplete', 'Enter 9 digits to enable Zefix lookup')\r\n : t('admin:tenants.organisation.lookupHint', 'Click search button to auto-fill from Zefix')}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Address */}\r\n <div className=\"space-y-3\">\r\n <label className={labelClass}>\r\n {t('admin:tenants.organisation.form.address', 'Address')} *\r\n </label>\r\n <div>\r\n <input\r\n type=\"text\"\r\n value={data.address.street}\r\n onChange={(e) => onChange({ ...data, address: { ...data.address, street: e.target.value } })}\r\n className={fieldClass(submitted && !data.address.street.trim())}\r\n placeholder={t('admin:tenants.organisation.form.streetPlaceholder', 'Street address')}\r\n />\r\n {submitted && !data.address.street.trim() && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1\">{t('common:validation.required', 'This field is required')}</p>\r\n )}\r\n </div>\r\n <div className=\"grid grid-cols-3 gap-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n value={data.address.postalCode}\r\n onChange={(e) => onChange({ ...data, address: { ...data.address, postalCode: e.target.value } })}\r\n className={fieldClass(submitted && !data.address.postalCode.trim())}\r\n placeholder={t('admin:tenants.organisation.form.postalCodePlaceholder', 'Postal code')}\r\n />\r\n {submitted && !data.address.postalCode.trim() && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1\">{t('common:validation.required', 'This field is required')}</p>\r\n )}\r\n </div>\r\n <div className=\"col-span-2\">\r\n <input\r\n type=\"text\"\r\n value={data.address.city}\r\n onChange={(e) => onChange({ ...data, address: { ...data.address, city: e.target.value } })}\r\n className={fieldClass(submitted && !data.address.city.trim())}\r\n placeholder={t('admin:tenants.organisation.form.cityPlaceholder', 'City')}\r\n />\r\n {submitted && !data.address.city.trim() && (\r\n <p className=\"text-xs text-[var(--error-text)] mt-1\">{t('common:validation.required', 'This field is required')}</p>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* VAT Number */}\r\n <div>\r\n <label className={labelClass}>\r\n {t('admin:tenants.organisation.form.vatNumber', 'VAT Number')} ({t('common:optional', 'optional')})\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={data.vatNumber || ''}\r\n onChange={(e) => onChange({ ...data, vatNumber: e.target.value || undefined })}\r\n className={inputClass}\r\n placeholder={data.countryCode === 'CH' ? `CHE-123.456.789 ${getVatSuffix()}` : 'FRXX123456789'}\r\n />\r\n {data.countryCode === 'CH' && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1\">\r\n {t('admin:tenants.organisation.vatHint', 'VAT suffix will be added automatically based on language (MWST/TVA/IVA)')}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// Helper to create initial form data\r\nexport function createInitialOrganisationData(): OrganisationFormData {\r\n return {\r\n name: '',\r\n countryCode: 'CH',\r\n businessIdentifierType: 'UID_CHE',\r\n businessIdentifier: 'CHE-',\r\n isFromRegistry: false,\r\n address: {\r\n street: '',\r\n postalCode: '',\r\n city: '',\r\n state: null,\r\n country: 'Switzerland',\r\n countryCode: 'CH',\r\n },\r\n };\r\n}\r\n\r\n// Helper to convert form data to API request\r\nexport function toCreateOrganisationRequest(data: OrganisationFormData): CreateOrganisationRequest {\r\n return {\r\n name: data.name,\r\n legalName: data.legalName,\r\n countryCode: data.countryCode,\r\n businessIdentifierType: data.businessIdentifierType,\r\n businessIdentifier: data.businessIdentifier,\r\n vatNumber: data.vatNumber,\r\n phone: data.phone,\r\n email: data.email,\r\n website: data.website,\r\n isFromRegistry: data.isFromRegistry || undefined,\r\n address: {\r\n street: data.address.street,\r\n street2: data.address.street2 ?? undefined,\r\n postalCode: data.address.postalCode,\r\n city: data.address.city,\r\n state: data.address.state ?? undefined,\r\n country: data.address.country,\r\n countryCode: data.address.countryCode,\r\n },\r\n };\r\n}\r\n","import { useState } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { ArrowLeft, Loader2, AlertTriangle } from 'lucide-react';\r\nimport {\r\n CreateOrganisationForm,\r\n createInitialOrganisationData,\r\n toCreateOrganisationRequest,\r\n type OrganisationFormData,\r\n} from '@/components/platform/administration/organisations/CreateOrganisationForm';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\n\r\nexport function OrganisationCreatePage(): ReactElement {\r\n const { t } = useTranslation(['admin', 'common']);\r\n const navigate = useNavigate();\r\n\r\n const [formData, setFormData] = useState<OrganisationFormData>(createInitialOrganisationData());\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [submitted, setSubmitted] = useState(false);\r\n\r\n const isValid = formData.name.trim() && formData.address.street.trim() && formData.address.city.trim() && formData.address.postalCode.trim();\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSubmitted(true);\r\n\r\n if (!isValid) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n const request = toCreateOrganisationRequest(formData);\r\n const created = await adminApi.organisations.create(request);\r\n navigate(`/administration/tenants/organisations/${created.id}`);\r\n } catch (err) {\r\n console.error('Failed to create organisation:', err);\r\n setError(\r\n err instanceof Error\r\n ? err.message\r\n : t('admin:organisations.createError', 'Failed to create organisation')\r\n );\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('admin:header.title'), href: '/administration' },\r\n { label: t('admin:tenants.title'), href: '/administration/tenants/list' },\r\n { label: t('admin:organisations.title', 'Organisations'), href: '/administration/tenants/organisations' },\r\n { label: t('common:create', 'Create') },\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/tenants/organisations')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('admin:organisations.create', 'Create Organisation')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('admin:organisations.createDescription', 'Add a new organisation to the system')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-6\">\r\n <div className=\"p-6 rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)]\">\r\n <CreateOrganisationForm data={formData} onChange={setFormData} submitted={submitted} />\r\n </div>\r\n\r\n <div className=\"flex justify-end gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={() => navigate('/administration/tenants/organisations')}\r\n className=\"px-6 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {t('common:cancel', 'Cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={loading}\r\n className=\"flex items-center gap-2 px-6 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-500)] text-white hover:bg-[var(--color-accent-600)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {loading && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {loading ? t('common:saving', 'Saving') : t('common:create', 'Create')}\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n );\r\n}\r\n"],"names":["VALID_STATUSES","VALID_TYPES","defaultFilters","validateStatus","value","validateType","validatePage","parsed","getDefaultFilters","lockedType","excludeTypes","useActiveFilterCount","filters","useMemo","count","useDebounce","delay","debouncedValue","setDebouncedValue","useState","useEffect","handler","STATUS_CONFIG","TYPE_CONFIG","User","Building","Server","TenantsPage","t","useTranslation","navigate","useNavigate","searchParams","setSearchParams","useSearchParams","currentTenant","isGlobalView","refreshTenants","useTenant","buildTenantUrl","useTenantUrl","getIconForType","useTenantTypeSettings","initialFilters","tenants","setTenants","loading","setLoading","setFilters","showFilters","setShowFilters","menuOpen","setMenuOpen","actionLoading","setActionLoading","confirmAction","setConfirmAction","viewMode","setViewMode","page","setPage","totalPages","setTotalPages","totalCount","setTotalCount","error","setError","sortKey","setSortKey","sortDesc","setSortDesc","debouncedSearch","activeFilterCount","loadTenants","useCallback","result","adminApi","err","params","handleResetFilters","updateFilter","key","prev","handleActivate","tenant","handleSuspend","handleArchive","handleConfirmAction","action","getConfirmModalMessage","tenantName","getConfirmModalLabel","getConfirmModalVariant","getConfirmModalProps","stats","sum","paginatedTenants","toggleSort","SortIcon","column","jsx","ArrowUpDown","ArrowDown","ArrowUp","getTenantStatusVariant","status","getPageTitle","getPageSubtitle","getPageIcon","Building2","pageTitle","pageSubtitle","PageIcon","hideTypeColumn","columnCount","renderTableHeader","columnLabel","columnKey","hidden","jsxs","renderTableActionsMenu","e","Loader2","MoreHorizontal","Eye","Edit2","Users","PlayCircle","PauseCircle","Archive","renderTableRow","typeInfo","RowIcon","getLucideIcon","rowColors","getColorClasses","statusConfig","StatusBadge","Layers","Clock","renderLoadingRow","renderEmptyRow","renderTableView","buildCardTags","buildCardActions","buildCardStats","Boxes","mapTenantToCardProps","avatarColor","renderCardsView","EntityCard","Breadcrumb","PageHeader","Fragment","AlertCircle","Search","ChevronDown","Filter","RotateCcw","ViewToggle","Pagination","props","ConfirmModal","useTenantDetail","tenantId","setTenant","editingGeneralInfo","setEditingGeneralInfo","editName","setEditName","editDescription","setEditDescription","savingGeneralInfo","setSavingGeneralInfo","loadTenant","data","openEditGeneralInfo","closeEditGeneralInfo","handleSaveGeneralInfo","useTenantMembers","members","setMembers","loadingMembers","setLoadingMembers","addingMember","setAddingMember","availableUsers","setAvailableUsers","loadingUsers","setLoadingUsers","userSearchTerm","setUserSearchTerm","selectedUserId","setSelectedUserId","addingMemberLoading","setAddingMemberLoading","selectedMemberForRoles","setSelectedMemberForRoles","availableRoles","setAvailableRoles","selectedRoleIds","setSelectedRoleIds","loadingRoles","setLoadingRoles","savingRoles","setSavingRoles","loadMembers","loadAvailableUsers","memberUserIds","m","u","handleAddMember","handleRemoveMember","userId","loadAvailableRoles","openRoleModal","member","r","closeRoleModal","handleRoleToggle","roleId","id","handleSaveRoles","useTenantGroups","groups","setGroups","loadingGroups","setLoadingGroups","addingGroup","setAddingGroup","availableGroupsForTenant","setAvailableGroupsForTenant","loadingAvailableGroups","setLoadingAvailableGroups","selectedGroupIds","setSelectedGroupIds","assigningGroups","setAssigningGroups","groupSearchTerm","setGroupSearchTerm","removingGroupId","setRemovingGroupId","loadGroups","loadAvailableGroups","handleAssignGroups","succeeded","failed","groupId","handleRemoveGroup","updateModuleAssignment","module","moduleId","newIsAssigned","s","updateSectionAssignment","sectionId","newSections","anySectionAssigned","assignAllSections","clearAllSections","useTenantApplications","options","applications","setApplications","loadingApps","setLoadingApps","addingApplication","setAddingApplication","availableApps","setAvailableApps","loadingAvailableApps","setLoadingAvailableApps","selectedAppIds","setSelectedAppIds","assigningApps","setAssigningApps","appSearchTerm","setAppSearchTerm","availableAppsError","setAvailableAppsError","selectedAccessLevel","setSelectedAccessLevel","bulkAccessMode","setBulkAccessMode","bulkModules","setBulkModules","bulkExpandedModules","setBulkExpandedModules","loadingBulkModules","setLoadingBulkModules","showCustomizeDrawer","setShowCustomizeDrawer","customizingApp","setCustomizingApp","loadApplications","loadAvailableApps","availableAppsResult","a","isForbidden","closeAddApplication","handleAssignApplications","request","handleRemoveApplication","appId","handleUpdateAccessLevel","accessLevel","openCustomizeDrawer","app","closeCustomizeDrawer","handleSaveOverrides","handleResetOverrides","filteredAvailableApps","searchLower","handleAppToggle","selectAllFilteredApps","filteredIds","clearAppSelection","loadBulkModulesForApp","appModules","moduleNodes","appModule","sectionNodes","section","toggleBulkModuleExpand","newSet","toggleBulkModule","toggleBulkSection","getBulkModuleCheckState","assignedCount","getBulkStats","totalModules","assignedModules","totalSections","assignedSections","selectAllBulkModules","clearBulkModules","COUNTRY_IDENTIFIER_TYPES","DEFAULT_ORG_FORM","useTenantOrganisation","showLinkOrgModal","setShowLinkOrgModal","availableOrgs","setAvailableOrgs","loadingOrgs","setLoadingOrgs","selectedOrgId","setSelectedOrgId","linkingOrg","setLinkingOrg","orgSearchTerm","setOrgSearchTerm","showCreateOrgForm","setShowCreateOrgForm","creatingOrg","setCreatingOrg","newOrgForm","setNewOrgForm","lookupLoading","setLookupLoading","lookupError","setLookupError","lookupSuccess","setLookupSuccess","loadAvailableOrgs","search","response","openLinkOrgModal","closeLinkOrgModal","handleLinkOrganisation","handleUnlinkOrganisation","handleCreateAndLinkOrganisation","createdOrg","formatCheNumber","cleaned","digits","handleBusinessIdChange","handleZefixLookup","cleanedId","errorMessage","handleCountryChange","countryCode","config","useTenantRoles","roles","setRoles","loadRoles","TemplateSelectionModal","show","templates","selectedTemplateId","loadingTemplates","assigningTemplate","onTemplateSelect","onClose","onAssign","tenantTemplateId","X","tmpl","TenantGeneralInfoSection","onEditClick","Info","Edit3","TenantTicketingSection","ticketingConfig","loadingTicketing","Headphones","Settings","CheckCircle2","TenantTemplateSection","onOpenTemplateModal","onRemoveTemplate","removingTemplate","ExternalLink","Plus","Star","ArrowRight","TenantOverviewTab","tenantOwner","onRefresh","onStatusChange","onMembersTabClick","onLinkOrgClick","onUnlinkOrg","editState","setEditState","showTemplateModal","setShowTemplateModal","setTemplates","setLoadingTemplates","setSelectedTemplateId","setAssigningTemplate","setRemovingTemplate","setTicketingConfig","setLoadingTicketing","loadTicketingConfig","ticketingApi","loadTemplates","handleOpenTemplateModal","handleAssignTemplate","handleRemoveTemplate","RefreshCw","typeOption","formatDate","date","TenantMembersTab","onRemoveMember","manageRolesState","setManageRolesState","openRolesModal","closeRolesModal","openAddMember","closeAddMember","columns","Link","Crown","role","Shield","source","UsersRound","Link2","UserMinus","DataTable","term","user","TenantGroupsTab","onRemoveGroup","removeConfirm","setRemoveConfirm","showCreateModal","setShowCreateModal","newGroupName","setNewGroupName","newGroupDescription","setNewGroupDescription","newGroupIsSecurityGroup","setNewGroupIsSecurityGroup","creating","setCreating","createError","setCreateError","openAddGroup","closeAddGroup","handleGroupToggle","handleAddGroups","handleCreateGroup","created","groupsApi","axiosError","group","Cloud","filteredGroups","g","Check","CATEGORY_STYLES","TenantRolesTab","Lock","style","AppWindow","Globe","SOURCE_COLORS","computeModuleOverrides","modules","overrides","wasActive","isNowChecked","computeSectionOverrides","sWasActive","sIsNowChecked","updateModuleCheckStateHelper","newChecked","updateSectionCheckStateHelper","SectionItem","renderIcon","checkRevoked","toggleSection","sectionRevoked","Ban","ModuleRow","isExpanded","getModuleCheckState","toggleModuleExpand","toggleModule","mode","checkState","moduleRevoked","ChevronRight","Minus","ApplicationAccessCustomizeDrawer","isOpen","application","onSaved","saving","setSaving","success","setSuccess","accessMode","setAccessMode","setModules","expandedModules","setExpandedModules","iconName","IconComponent","LucideIcons","loadData","expanded","hasAnyOverride","preCheckAllModules","mods","handleAccessModeChange","newMode","isInheritedRevoked","originalSource","isChecked","checkedCount","saveTemplateMode","moduleIds","sectionIds","saveTenantMode","moduleOverrides","sectionOverrides","handleSave","handleReset","resetAction","checkedModules","checkedSections","inheritedCount","directCount","revokedCount","revokedInheritedModules","revokedInheritedSections","handleEscape","CheckCircle","Save","getCheckStateClassName","getLoadingView","getEmptyApplicationsView","ACCESS_LEVEL_OPTIONS","AccessLevelSelector","opt","isSelected","TenantApplicationsTab","onUpdateAccessLevel","onRemoveApplication","onOpenAddApplication","onCloseAddApplication","onAssignApplications","onAppToggle","onSelectAllApps","onClearAppSelection","onOpenCustomizeDrawer","onCloseCustomizeDrawer","onLoadBulkModules","onToggleBulkModuleExpand","onToggleBulkModule","onToggleBulkSection","onGetBulkModuleCheckState","onGetBulkStats","onSelectAllBulkModules","onClearBulkModules","bulkStats","inheritedApps","directApps","renderAppCard","accessLevelOption","o","isActive","SlidersHorizontal","Trash2","ShieldX","AlertTriangle","icons","ModuleIcon","SectionIcon","VALID_TABS","TenantDetailPage","useParams","activeTab","setActiveTab","useTabNavigation","refreshMenu","useNavigation","tenantDetail","tenantMembers","tenantGroups","handleApplicationsChanged","tenantAppOptions","tenantApplications","tenantRoles","tenantOrganisation","accessRequests","useAccessRequests","confirmModal","setConfirmModal","loadedTabs","setLoadedTabs","handleStatusChange","newStatus","statusMessages","handleRefresh","promises","getStatusIcon","ArrowLeft","tab","owner","AccessRequestsListTab","BUSINESS_IDENTIFIER_TYPES","getTenantTypeFromUrl","typeFromUrl","applyConfigTypeRestrictions","buildOrganisationRequest","orgName","orgLegalName","orgCountryCode","orgBusinessIdType","orgBusinessId","orgVatNumber","addrStreet","addrStreet2","addrPostalCode","addrCity","addrState","addrCountry","addrCountryCode","orgPhone","orgEmail","orgWebsite","isFromRegistry","TenantCreatePage","organisationIdFromUrl","enableB2B","setEnableB2B","enableB2C","setEnableB2C","tenantType","setTenantType","organisationMode","setOrganisationMode","configLoading","setConfigLoading","setIsFromRegistry","selectedOrganisation","setSelectedOrganisation","availableOrganisations","setAvailableOrganisations","orgSearchQuery","setOrgSearchQuery","orgSearchLoading","setOrgSearchLoading","org","name","handleNameChange","debounce","results","setName","slug","setSlug","description","setDescription","setOrgName","setOrgLegalName","setOrgCountryCode","setOrgBusinessIdType","setOrgBusinessId","setOrgVatNumber","setOrgPhone","setOrgEmail","setOrgWebsite","setAddrStreet","setAddrStreet2","setAddrPostalCode","setAddrCity","setAddrState","setAddrCountry","setAddrCountryCode","generateSlug","validateLookupInput","fillOrganisationFields","fillAddressFields","mapLookupError","handleLookup","submitB2CTenant","submitB2BTenant","organisation","handleSubmit","isFormValid","Hash","FileText","Zap","FileCheck","newType","type","MapPin","Phone","Mail","UserPlus","COLORS","renderActiveShape","cx","cy","midAngle","innerRadius","outerRadius","startAngle","endAngle","fill","payload","percent","RADIAN","sin","cos","sx","sy","mx","my","ex","ey","textAnchor","Sector","TenantActivityPieChart","activeIndex","setActiveIndex","getValue","valueLabel","totalValue","chartData","index","onPieEnter","_","ResponsiveContainer","PieChart","Pie","entry","Cell","item","DEFAULT_COLORS","LegendItem","getColor","TenantUsageTrendChart","period","setData","tenantAnalyticsApi","day","LineChart","CartesianGrid","XAxis","YAxis","Tooltip","Legend","Line","tenantColors","TenantPopularityChart","maxCount","percentage","KpiCard","label","icon","color","subtitle","iconColors","TenantsDashboardPage","setStats","topTenants","setTopTenants","refreshing","setRefreshing","setPeriod","chartMode","setChartMode","dashboardRes","topTenantsRes","formatDuration","seconds","minutes","Activity","Timer","TrendingUp","ClipboardList","ShieldCheck","mapTemplateAppToTenantApp","useTemplateApplications","templateId","mapped","_appId","_request","TenantTemplateDetailPage","template","setTemplate","templateApplications","loadTemplate","TypeIcon","typeLabel","InfoTab","TenantsTab","AiInstancesTab","StatCard","LayoutGrid","memo","tabError","setTabError","instances","setInstances","loadInstances","handleRemove","instanceId","Brain","instance","TenantsTemplatePage","handleCardClick","systemTemplates","customTemplates","Settings2","SystemTemplateCard","CustomTemplateCard","onClick","TenantTemplateCreatePage","code","setCode","targetTenantType","setTargetTenantType","TenantsBusinessPage","TenantsPersonalPage","TenantsOtherPage","STATUS_FILTERS","TenantAccessRequestsPage","requests","setRequests","statusFilter","setStatusFilter","loadRequests","accessRequestsApi","ENTRA_PERMISSIONS","ENTRA_SYNC_TYPES","REQUIRED_PERMISSIONS","USER_TYPES","calculateElapsedTime","startedAt","now","start","diffSeconds","handleEntraNotification","notification","setActiveSyncSession","SectionCard","Icon","title","children","className","Toggle","checked","onChange","disabled","isValidGuid","ConfigTabReadOnly","canEdit","onEdit","Key","GitMerge","ConfigTab","onConfigUpdated","entraApi","editing","setEditing","testing","setTesting","testResult","setTestResult","showSecret","setShowSecret","copiedPermission","setCopiedPermission","hasExistingSecret","setHasExistingSecret","validationErrors","setValidationErrors","credentials","setCredentials","syncSettings","setSyncSettings","validateField","field","errorKey","handleCredentialChange","hasValidationErrors","canTestConnection","canSaveCredentials","handleCopyPermission","handleTestConnection","handleSaveCredentials","handleSaveSettings","perm","Copy","EyeOff","TestTube","userType","selectedTypes","newTypes","StatusBadgeMap","Square","SyncStatusIconMap","getStatusBadge","badge","getSyncStatusIcon","completedAt","diffMs","useSyncTabState","syncing","setSyncing","lastSyncResult","setLastSyncResult","syncError","setSyncError","history","setHistory","historyLoading","setHistoryLoading","historyPage","setHistoryPage","historyTotalCount","setHistoryTotalCount","cancellingSessionId","setCancellingSessionId","SyncTab","conflicts","syncStatus","canSync","onResolveConflict","onSyncAll","onLoadHistory","onCancelSession","activeSyncSession","historyPageSize","loadHistory","handleSyncNow","handleCancelSession","sessionId","Play","conflict","ConflictCard","History","session","UsersTab","GroupsTab","TenantEntraTab","tenantSlug","hasPermission","useAuth","isConnected","onNotification","useSignalRContext","activeSubTab","setActiveSubTab","createEntraApi","setConfig","setConflicts","setSyncStatus","selectedConflict","setSelectedConflict","resolving","setResolving","syncElapsedTime","setSyncElapsedTime","abortControllerRef","useRef","isLoadingRef","canRead","availableTabs","configData","conflictsData","syncStatusData","interval","handleResolve","resolution","notes","handleSyncAll","handleLoadHistory","pageSize","showConflictBadge","ResolutionModal","validateGlpiConfig","fields","errors","buildGlpiSaveRequest","provider","syncEnabled","syncIntervalMinutes","InfoBubble","text","TenantSupportSettingsTab","showSecrets","setShowSecrets","fieldErrors","setFieldErrors","setProvider","glpiBaseUrl","setGlpiBaseUrl","glpiClientId","setGlpiClientId","glpiClientSecret","setGlpiClientSecret","glpiUsername","setGlpiUsername","glpiPassword","setGlpiPassword","glpiEntityId","setGlpiEntityId","glpiRequestTypeId","setGlpiRequestTypeId","setSyncEnabled","setSyncIntervalMinutes","isGlpi","fieldErrorClass","loadConfiguration","validateForm","updated","newProvider","rest","TenantSettingsPage","TenantTypeSettingsPage","settings","setSettings","editStates","setEditStates","savingType","setSavingType","loadSettings","tenantTypeSettingsApi","states","state","updateEditState","hasChanges","original","current","Palette","setting","PreviewIcon","previewColors","getAvailableIconNames","colorClasses","VERIFICATION_STATUS_CONFIG","OrganisationsListPage","organisations","setOrganisations","setSearch","verificationFilter","setVerificationFilter","loadOrganisations","signal","abortController","handleSearchChange","statusFilters","OrganisationDetailPage","orgId","setOrganisation","getInitialTab","tabParam","verifyModal","setVerifyModal","rejectModal","setRejectModal","loadOrganisation","handleVerify","handleReject","hasContactData","countryIdentifierTypes","CreateOrganisationForm","onTenantNameSuggested","compact","submitted","i18n","getVatSuffix","newValue","updatedData","inputClass","inputErrorClass","fieldClass","hasError","labelClass","createInitialOrganisationData","toCreateOrganisationRequest","OrganisationCreatePage","formData","setFormData","setSubmitted","isValid"],"mappings":"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"}
|