@atlashub/smartstack 3.30.0 → 3.32.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.
Files changed (280) hide show
  1. package/dist/chunks/{AgentSkillsPage-DJb49NMA.js → AgentSkillsPage-BMxOA-nm.js} +2 -2
  2. package/dist/chunks/{AgentSkillsPage-DJb49NMA.js.map → AgentSkillsPage-BMxOA-nm.js.map} +1 -1
  3. package/dist/chunks/{AgentSkillsPage-CVq3qZoe.js → AgentSkillsPage-DSwfoazB.js} +2 -2
  4. package/dist/chunks/{AgentSkillsPage-CVq3qZoe.js.map → AgentSkillsPage-DSwfoazB.js.map} +1 -1
  5. package/dist/chunks/{AgentWorkloadPage-oHEi-sFh.js → AgentWorkloadPage-B_emq8kd.js} +2 -2
  6. package/dist/chunks/{AgentWorkloadPage-oHEi-sFh.js.map → AgentWorkloadPage-B_emq8kd.js.map} +1 -1
  7. package/dist/chunks/{AgentWorkloadPage-D_nk3gKj.js → AgentWorkloadPage-_USTeYWz.js} +2 -2
  8. package/dist/chunks/{AgentWorkloadPage-D_nk3gKj.js.map → AgentWorkloadPage-_USTeYWz.js.map} +1 -1
  9. package/dist/chunks/{ApiCatalogDetailPage-Cr0q2HnB.js → ApiCatalogDetailPage-BC_HxVu5.js} +3 -3
  10. package/dist/chunks/{ApiCatalogDetailPage-Cr0q2HnB.js.map → ApiCatalogDetailPage-BC_HxVu5.js.map} +1 -1
  11. package/dist/chunks/{ApiCatalogDetailPage-DX8buBkV.js → ApiCatalogDetailPage-BI7zyZAd.js} +2 -2
  12. package/dist/chunks/{ApiCatalogDetailPage-DX8buBkV.js.map → ApiCatalogDetailPage-BI7zyZAd.js.map} +1 -1
  13. package/dist/chunks/{ApiCatalogPage-DqboIzZE.js → ApiCatalogPage-CutaHo5K.js} +2 -2
  14. package/dist/chunks/{ApiCatalogPage-DqboIzZE.js.map → ApiCatalogPage-CutaHo5K.js.map} +1 -1
  15. package/dist/chunks/{ApiCatalogPage-DN7sazvI.js → ApiCatalogPage-M80MorHU.js} +2 -2
  16. package/dist/chunks/{ApiCatalogPage-DN7sazvI.js.map → ApiCatalogPage-M80MorHU.js.map} +1 -1
  17. package/dist/chunks/{ApplicationDetailPage--9YwwS5A.js → ApplicationDetailPage-DVY0wua0.js} +2 -2
  18. package/dist/chunks/{ApplicationDetailPage--9YwwS5A.js.map → ApplicationDetailPage-DVY0wua0.js.map} +1 -1
  19. package/dist/chunks/{ApplicationDetailPage-CCNjr64K.js → ApplicationDetailPage-DzszwaIZ.js} +4 -4
  20. package/dist/chunks/{ApplicationDetailPage-CCNjr64K.js.map → ApplicationDetailPage-DzszwaIZ.js.map} +1 -1
  21. package/dist/chunks/{ApplicationsDashboardPage-Bs-Xgca4.js → ApplicationsDashboardPage-B3ptvnJz.js} +3 -3
  22. package/dist/chunks/{ApplicationsDashboardPage-Bs-Xgca4.js.map → ApplicationsDashboardPage-B3ptvnJz.js.map} +1 -1
  23. package/dist/chunks/{ApplicationsDashboardPage-BSsHN3Yj.js → ApplicationsDashboardPage-D0pxqbEc.js} +2 -2
  24. package/dist/chunks/{ApplicationsDashboardPage-BSsHN3Yj.js.map → ApplicationsDashboardPage-D0pxqbEc.js.map} +1 -1
  25. package/dist/chunks/{ApplicationsGridPage-DDysNWJ5.js → ApplicationsGridPage-Ca23FBSP.js} +2 -2
  26. package/dist/chunks/{ApplicationsGridPage-DDysNWJ5.js.map → ApplicationsGridPage-Ca23FBSP.js.map} +1 -1
  27. package/dist/chunks/{ApplicationsGridPage-s1WEzOXS.js → ApplicationsGridPage-qi2UCD24.js} +2 -2
  28. package/dist/chunks/{ApplicationsGridPage-s1WEzOXS.js.map → ApplicationsGridPage-qi2UCD24.js.map} +1 -1
  29. package/dist/chunks/{ApplicationsListPage-B3CSMiV0.js → ApplicationsListPage-CEUmBXN0.js} +2 -2
  30. package/dist/chunks/{ApplicationsListPage-B3CSMiV0.js.map → ApplicationsListPage-CEUmBXN0.js.map} +1 -1
  31. package/dist/chunks/{ApplicationsListPage-B6ZCecIl.js → ApplicationsListPage-cE82bv8j.js} +2 -2
  32. package/dist/chunks/{ApplicationsListPage-B6ZCecIl.js.map → ApplicationsListPage-cE82bv8j.js.map} +1 -1
  33. package/dist/chunks/{ApplicationsPage-ztPwoAGt.js → ApplicationsPage-DW1BrVVN.js} +4 -4
  34. package/dist/chunks/{ApplicationsPage-ztPwoAGt.js.map → ApplicationsPage-DW1BrVVN.js.map} +1 -1
  35. package/dist/chunks/{ApplicationsPage-BBaiBM--.js → ApplicationsPage-RAqTs5HI.js} +2 -2
  36. package/dist/chunks/{ApplicationsPage-BBaiBM--.js.map → ApplicationsPage-RAqTs5HI.js.map} +1 -1
  37. package/dist/chunks/{AssignmentRulesPage-CK4L4rBO.js → AssignmentRulesPage-C0qnk3oR.js} +2 -2
  38. package/dist/chunks/{AssignmentRulesPage-CK4L4rBO.js.map → AssignmentRulesPage-C0qnk3oR.js.map} +1 -1
  39. package/dist/chunks/{AssignmentRulesPage-DFSVFFXr.js → AssignmentRulesPage-CVgFmhEs.js} +2 -2
  40. package/dist/chunks/{AssignmentRulesPage-DFSVFFXr.js.map → AssignmentRulesPage-CVgFmhEs.js.map} +1 -1
  41. package/dist/chunks/{AssignmentsPage-JCLpyg94.js → AssignmentsPage-Bv9HYtYN.js} +2 -2
  42. package/dist/chunks/{AssignmentsPage-JCLpyg94.js.map → AssignmentsPage-Bv9HYtYN.js.map} +1 -1
  43. package/dist/chunks/{AssignmentsPage-Bp7oQD7Q.js → AssignmentsPage-z1q1C9Uz.js} +2 -2
  44. package/dist/chunks/{AssignmentsPage-Bp7oQD7Q.js.map → AssignmentsPage-z1q1C9Uz.js.map} +1 -1
  45. package/dist/chunks/{AuthCallbackPage-Bl9xlJ3h.js → AuthCallbackPage-CcteN6Kv.js} +2 -2
  46. package/dist/chunks/{AuthCallbackPage-Bl9xlJ3h.js.map → AuthCallbackPage-CcteN6Kv.js.map} +1 -1
  47. package/dist/chunks/{AuthCallbackPage-CzMHz4jy.js → AuthCallbackPage-DL5PJUYJ.js} +2 -2
  48. package/dist/chunks/{AuthCallbackPage-CzMHz4jy.js.map → AuthCallbackPage-DL5PJUYJ.js.map} +1 -1
  49. package/dist/chunks/{ConfirmEmailPage-D_8T1vqV.js → ConfirmEmailPage-BP8VUz-A.js} +2 -2
  50. package/dist/chunks/{ConfirmEmailPage-D_8T1vqV.js.map → ConfirmEmailPage-BP8VUz-A.js.map} +1 -1
  51. package/dist/chunks/{ConfirmEmailPage-M7mJgXvn.js → ConfirmEmailPage-CeflKXpN.js} +2 -2
  52. package/dist/chunks/{ConfirmEmailPage-M7mJgXvn.js.map → ConfirmEmailPage-CeflKXpN.js.map} +1 -1
  53. package/dist/chunks/{CreateSupportTicketPage-BNEGavlu.js → CreateSupportTicketPage-BAdvWb_8.js} +2 -2
  54. package/dist/chunks/{CreateSupportTicketPage-BNEGavlu.js.map → CreateSupportTicketPage-BAdvWb_8.js.map} +1 -1
  55. package/dist/chunks/{CreateSupportTicketPage-C2X2mfds.js → CreateSupportTicketPage-DDiv79-p.js} +2 -2
  56. package/dist/chunks/{CreateSupportTicketPage-C2X2mfds.js.map → CreateSupportTicketPage-DDiv79-p.js.map} +1 -1
  57. package/dist/chunks/{DashboardPage-4oy2YqvT.js → DashboardPage-B_uyyRRE.js} +2 -2
  58. package/dist/chunks/{DashboardPage-4oy2YqvT.js.map → DashboardPage-B_uyyRRE.js.map} +1 -1
  59. package/dist/chunks/{DashboardPage-CPArUG-S.js → DashboardPage-CpoduSu7.js} +2 -2
  60. package/dist/chunks/{DashboardPage-CPArUG-S.js.map → DashboardPage-CpoduSu7.js.map} +1 -1
  61. package/dist/chunks/{DashboardPage-CO-8B8EI.js → DashboardPage-D4pyUgdM.js} +3 -3
  62. package/dist/chunks/{DashboardPage-CO-8B8EI.js.map → DashboardPage-D4pyUgdM.js.map} +1 -1
  63. package/dist/chunks/{DashboardPage-D5MRMxEV.js → DashboardPage-Kp-MCxW4.js} +3 -3
  64. package/dist/chunks/{DashboardPage-D5MRMxEV.js.map → DashboardPage-Kp-MCxW4.js.map} +1 -1
  65. package/dist/chunks/{EscalationConfigPage-DnjLFXnL.js → EscalationConfigPage-D-WCN6YS.js} +2 -2
  66. package/dist/chunks/{EscalationConfigPage-DnjLFXnL.js.map → EscalationConfigPage-D-WCN6YS.js.map} +1 -1
  67. package/dist/chunks/{EscalationConfigPage-CwdnfJbJ.js → EscalationConfigPage-UrLJarSI.js} +2 -2
  68. package/dist/chunks/{EscalationConfigPage-CwdnfJbJ.js.map → EscalationConfigPage-UrLJarSI.js.map} +1 -1
  69. package/dist/chunks/{ForceChangePasswordPage-sh-3h_H9.js → ForceChangePasswordPage-BIh1SF5C.js} +2 -2
  70. package/dist/chunks/{ForceChangePasswordPage-sh-3h_H9.js.map → ForceChangePasswordPage-BIh1SF5C.js.map} +1 -1
  71. package/dist/chunks/{ForceChangePasswordPage-ZEIfyqwE.js → ForceChangePasswordPage-FFZZRpU7.js} +2 -2
  72. package/dist/chunks/{ForceChangePasswordPage-ZEIfyqwE.js.map → ForceChangePasswordPage-FFZZRpU7.js.map} +1 -1
  73. package/dist/chunks/{ForgotPasswordPage-B4M6-xeM.js → ForgotPasswordPage-BKqRF7SF.js} +2 -2
  74. package/dist/chunks/{ForgotPasswordPage-B4M6-xeM.js.map → ForgotPasswordPage-BKqRF7SF.js.map} +1 -1
  75. package/dist/chunks/{ForgotPasswordPage-MIu-U7p0.js → ForgotPasswordPage-BXp8qQUX.js} +2 -2
  76. package/dist/chunks/{ForgotPasswordPage-MIu-U7p0.js.map → ForgotPasswordPage-BXp8qQUX.js.map} +1 -1
  77. package/dist/chunks/{GroupDetailPage-4XK3Bs_r.js → GroupDetailPage-a0hBx-LO.js} +5 -5
  78. package/dist/chunks/{GroupDetailPage-4XK3Bs_r.js.map → GroupDetailPage-a0hBx-LO.js.map} +1 -1
  79. package/dist/chunks/{GroupDetailPage-C-kvtd2T.js → GroupDetailPage-eGGJCqgq.js} +2 -2
  80. package/dist/chunks/{GroupDetailPage-C-kvtd2T.js.map → GroupDetailPage-eGGJCqgq.js.map} +1 -1
  81. package/dist/chunks/{MyAccessRequestsPage-CP41FzHi.js → MyAccessRequestsPage-BgQSyy5d.js} +2 -2
  82. package/dist/chunks/{MyAccessRequestsPage-CP41FzHi.js.map → MyAccessRequestsPage-BgQSyy5d.js.map} +1 -1
  83. package/dist/chunks/{MyAccessRequestsPage-DzrXTrVi.js → MyAccessRequestsPage-Dmb0rUHO.js} +2 -2
  84. package/dist/chunks/{MyAccessRequestsPage-DzrXTrVi.js.map → MyAccessRequestsPage-Dmb0rUHO.js.map} +1 -1
  85. package/dist/chunks/{MyTenantsPage-V_SwYio2.js → MyTenantsPage-BZTeqyDr.js} +3 -3
  86. package/dist/chunks/{MyTenantsPage-V_SwYio2.js.map → MyTenantsPage-BZTeqyDr.js.map} +1 -1
  87. package/dist/chunks/{MyTenantsPage-CZRkMbh8.js → MyTenantsPage-kCHBF2uA.js} +2 -2
  88. package/dist/chunks/{MyTenantsPage-CZRkMbh8.js.map → MyTenantsPage-kCHBF2uA.js.map} +1 -1
  89. package/dist/chunks/{MyTicketsPage-DOUhaLal.js → MyTicketsPage-BwNIqpCE.js} +2 -2
  90. package/dist/chunks/{MyTicketsPage-DOUhaLal.js.map → MyTicketsPage-BwNIqpCE.js.map} +1 -1
  91. package/dist/chunks/{MyTicketsPage-DnvAIeyr.js → MyTicketsPage-CTpjkA5t.js} +2 -2
  92. package/dist/chunks/{MyTicketsPage-DnvAIeyr.js.map → MyTicketsPage-CTpjkA5t.js.map} +1 -1
  93. package/dist/chunks/{NavigationAppsPage-DfTa4jCG.js → NavigationAppsPage-DO5bTibb.js} +2 -2
  94. package/dist/chunks/{NavigationAppsPage-DfTa4jCG.js.map → NavigationAppsPage-DO5bTibb.js.map} +1 -1
  95. package/dist/chunks/{NavigationAppsPage-DXvpLsbt.js → NavigationAppsPage-vx_n07SD.js} +2 -2
  96. package/dist/chunks/{NavigationAppsPage-DXvpLsbt.js.map → NavigationAppsPage-vx_n07SD.js.map} +1 -1
  97. package/dist/chunks/{NotificationsPage-I1yCk7tk.js → NotificationsPage-Br9sb9AQ.js} +2 -2
  98. package/dist/chunks/{NotificationsPage-I1yCk7tk.js.map → NotificationsPage-Br9sb9AQ.js.map} +1 -1
  99. package/dist/chunks/{NotificationsPage-D76MdAs-.js → NotificationsPage-CRhd752L.js} +2 -2
  100. package/dist/chunks/{NotificationsPage-D76MdAs-.js.map → NotificationsPage-CRhd752L.js.map} +1 -1
  101. package/dist/chunks/{OnboardingWizardPage-DtWUPCh3.js → OnboardingWizardPage-BIl3Usew.js} +2 -2
  102. package/dist/chunks/{OnboardingWizardPage-DtWUPCh3.js.map → OnboardingWizardPage-BIl3Usew.js.map} +1 -1
  103. package/dist/chunks/{OnboardingWizardPage-BRUzcl1A.js → OnboardingWizardPage-CjqxWX7h.js} +2 -2
  104. package/dist/chunks/{OnboardingWizardPage-BRUzcl1A.js.map → OnboardingWizardPage-CjqxWX7h.js.map} +1 -1
  105. package/dist/chunks/{PermissionDetailPage-DJJGbXoX.js → PermissionDetailPage-COIuJXH-.js} +2 -2
  106. package/dist/chunks/{PermissionDetailPage-DJJGbXoX.js.map → PermissionDetailPage-COIuJXH-.js.map} +1 -1
  107. package/dist/chunks/{PermissionDetailPage-CUNKbl7t.js → PermissionDetailPage-P_d6xnY0.js} +2 -2
  108. package/dist/chunks/{PermissionDetailPage-CUNKbl7t.js.map → PermissionDetailPage-P_d6xnY0.js.map} +1 -1
  109. package/dist/chunks/{PermissionsPage-B8wmawPV.js → PermissionsPage-BhjnMyFY.js} +2 -2
  110. package/dist/chunks/{PermissionsPage-B8wmawPV.js.map → PermissionsPage-BhjnMyFY.js.map} +1 -1
  111. package/dist/chunks/{PermissionsPage-Dbjcctuh.js → PermissionsPage-CHYy8XFr.js} +2 -2
  112. package/dist/chunks/{PermissionsPage-Dbjcctuh.js.map → PermissionsPage-CHYy8XFr.js.map} +1 -1
  113. package/dist/chunks/{PortalDashboardPage-zii0ll57.js → PortalDashboardPage-BwQ4NQrH.js} +2 -2
  114. package/dist/chunks/{PortalDashboardPage-zii0ll57.js.map → PortalDashboardPage-BwQ4NQrH.js.map} +1 -1
  115. package/dist/chunks/{PortalDashboardPage-BeNfBZmb.js → PortalDashboardPage-hLJcfGnT.js} +2 -2
  116. package/dist/chunks/{PortalDashboardPage-BeNfBZmb.js.map → PortalDashboardPage-hLJcfGnT.js.map} +1 -1
  117. package/dist/chunks/{PreferencesPage-BmvrBaAD.js → PreferencesPage-DYYqisR0.js} +2 -2
  118. package/dist/chunks/{PreferencesPage-BmvrBaAD.js.map → PreferencesPage-DYYqisR0.js.map} +1 -1
  119. package/dist/chunks/{PreferencesPage-BCpuIGzv.js → PreferencesPage-DzpM-lpD.js} +2 -2
  120. package/dist/chunks/{PreferencesPage-BCpuIGzv.js.map → PreferencesPage-DzpM-lpD.js.map} +1 -1
  121. package/dist/chunks/{ProfilePage-eowQd59_.js → ProfilePage-D98bvXeT.js} +2 -2
  122. package/dist/chunks/{ProfilePage-eowQd59_.js.map → ProfilePage-D98bvXeT.js.map} +1 -1
  123. package/dist/chunks/{ProfilePage-mf5wI0-n.js → ProfilePage-DWRDN0fo.js} +2 -2
  124. package/dist/chunks/{ProfilePage-mf5wI0-n.js.map → ProfilePage-DWRDN0fo.js.map} +1 -1
  125. package/dist/chunks/{ReferencesManagementPage-CLsaUNqA.js → ReferencesManagementPage-B0Cq9BHS.js} +2 -2
  126. package/dist/chunks/{ReferencesManagementPage-CLsaUNqA.js.map → ReferencesManagementPage-B0Cq9BHS.js.map} +1 -1
  127. package/dist/chunks/{ReferencesManagementPage-8UPgkVE8.js → ReferencesManagementPage-CxbfOBs2.js} +3 -3
  128. package/dist/chunks/{ReferencesManagementPage-8UPgkVE8.js.map → ReferencesManagementPage-CxbfOBs2.js.map} +1 -1
  129. package/dist/chunks/{RegisterPage-57X-ILDb.js → RegisterPage-DMeq3GzW.js} +2 -2
  130. package/dist/chunks/{RegisterPage-57X-ILDb.js.map → RegisterPage-DMeq3GzW.js.map} +1 -1
  131. package/dist/chunks/{RegisterPage-CNyHSbqs.js → RegisterPage-DvG2Php7.js} +2 -2
  132. package/dist/chunks/{RegisterPage-CNyHSbqs.js.map → RegisterPage-DvG2Php7.js.map} +1 -1
  133. package/dist/chunks/{ResetPasswordPage-JW8-mh_k.js → ResetPasswordPage-DOTswepm.js} +2 -2
  134. package/dist/chunks/{ResetPasswordPage-JW8-mh_k.js.map → ResetPasswordPage-DOTswepm.js.map} +1 -1
  135. package/dist/chunks/{ResetPasswordPage-CyV8l-Zo.js → ResetPasswordPage-ntMMFvDo.js} +2 -2
  136. package/dist/chunks/{ResetPasswordPage-CyV8l-Zo.js.map → ResetPasswordPage-ntMMFvDo.js.map} +1 -1
  137. package/dist/chunks/{ResolutionModal-wddG59kg.js → ResolutionModal-CKt73sIZ.js} +2 -2
  138. package/dist/chunks/{ResolutionModal-wddG59kg.js.map → ResolutionModal-CKt73sIZ.js.map} +1 -1
  139. package/dist/chunks/{ResolutionModal-CjwE73NX.js → ResolutionModal-XGHCELez.js} +2 -2
  140. package/dist/chunks/{ResolutionModal-CjwE73NX.js.map → ResolutionModal-XGHCELez.js.map} +1 -1
  141. package/dist/chunks/{RoleDetailPage-CrioVHFI.js → RoleDetailPage-BtnYTVN6.js} +3 -3
  142. package/dist/chunks/{RoleDetailPage-CrioVHFI.js.map → RoleDetailPage-BtnYTVN6.js.map} +1 -1
  143. package/dist/chunks/{RoleDetailPage-TUOGR1ow.js → RoleDetailPage-DAp65p0d.js} +2 -2
  144. package/dist/chunks/{RoleDetailPage-TUOGR1ow.js.map → RoleDetailPage-DAp65p0d.js.map} +1 -1
  145. package/dist/chunks/{RolesPage-CAcols3D.js → RolesPage-DyEhJHxw.js} +2 -2
  146. package/dist/chunks/{RolesPage-CAcols3D.js.map → RolesPage-DyEhJHxw.js.map} +1 -1
  147. package/dist/chunks/{RolesPage-sJBWaNff.js → RolesPage-FmZCLEYo.js} +2 -2
  148. package/dist/chunks/{RolesPage-sJBWaNff.js.map → RolesPage-FmZCLEYo.js.map} +1 -1
  149. package/dist/chunks/{SlaConfigPage-BPGRloOS.js → SlaConfigPage-DTtP2Q4t.js} +2 -2
  150. package/dist/chunks/{SlaConfigPage-BPGRloOS.js.map → SlaConfigPage-DTtP2Q4t.js.map} +1 -1
  151. package/dist/chunks/{SlaConfigPage-D5TRn7Ir.js → SlaConfigPage-LpVD_ai4.js} +2 -2
  152. package/dist/chunks/{SlaConfigPage-D5TRn7Ir.js.map → SlaConfigPage-LpVD_ai4.js.map} +1 -1
  153. package/dist/chunks/{SupportPermissionsPage-UXmYLrIq.js → SupportPermissionsPage-BV8F_Tl3.js} +2 -2
  154. package/dist/chunks/{SupportPermissionsPage-UXmYLrIq.js.map → SupportPermissionsPage-BV8F_Tl3.js.map} +1 -1
  155. package/dist/chunks/{SupportPermissionsPage-Dc2bWTzG.js → SupportPermissionsPage-Bzfq6pKf.js} +2 -2
  156. package/dist/chunks/{SupportPermissionsPage-Dc2bWTzG.js.map → SupportPermissionsPage-Bzfq6pKf.js.map} +1 -1
  157. package/dist/chunks/{TemplatesPage-nTY85sNA.js → TemplatesPage-CYHH5WlP.js} +2 -2
  158. package/dist/chunks/{TemplatesPage-nTY85sNA.js.map → TemplatesPage-CYHH5WlP.js.map} +1 -1
  159. package/dist/chunks/{TemplatesPage-dmPlqqiD.js → TemplatesPage-czt_RH5f.js} +2 -2
  160. package/dist/chunks/{TemplatesPage-dmPlqqiD.js.map → TemplatesPage-czt_RH5f.js.map} +1 -1
  161. package/dist/chunks/{TenantCard-BhT-31ls.js → TenantCard-Bqh5PGJx.js} +2 -2
  162. package/dist/chunks/{TenantCard-BhT-31ls.js.map → TenantCard-Bqh5PGJx.js.map} +1 -1
  163. package/dist/chunks/{TenantCard-BUXfstRZ.js → TenantCard-C6qKD480.js} +2 -2
  164. package/dist/chunks/{TenantCard-BUXfstRZ.js.map → TenantCard-C6qKD480.js.map} +1 -1
  165. package/dist/chunks/{TenantScopeSelector-B-SRDR2R.js → TenantScopeSelector-DWUP8Le7.js} +2 -2
  166. package/dist/chunks/{TenantScopeSelector-B-SRDR2R.js.map → TenantScopeSelector-DWUP8Le7.js.map} +1 -1
  167. package/dist/chunks/{TenantScopeSelector-3_mzBLNI.js → TenantScopeSelector-DxQ7HNbh.js} +2 -2
  168. package/dist/chunks/{TenantScopeSelector-3_mzBLNI.js.map → TenantScopeSelector-DxQ7HNbh.js.map} +1 -1
  169. package/dist/chunks/{TicketDetailPage-xN3wPnFL.js → TicketDetailPage-BuxXLcJi.js} +2 -2
  170. package/dist/chunks/{TicketDetailPage-xN3wPnFL.js.map → TicketDetailPage-BuxXLcJi.js.map} +1 -1
  171. package/dist/chunks/{TicketDetailPage-B4cR3rOC.js → TicketDetailPage-Dy4pg33-.js} +2 -2
  172. package/dist/chunks/{TicketDetailPage-B4cR3rOC.js.map → TicketDetailPage-Dy4pg33-.js.map} +1 -1
  173. package/dist/chunks/{TicketsPage-CkHgXSxU.js → TicketsPage-Ck-HUgte.js} +2 -2
  174. package/dist/chunks/{TicketsPage-CkHgXSxU.js.map → TicketsPage-Ck-HUgte.js.map} +1 -1
  175. package/dist/chunks/{TicketsPage-Dwi2xpMI.js → TicketsPage-jlN9JDzm.js} +2 -2
  176. package/dist/chunks/{TicketsPage-Dwi2xpMI.js.map → TicketsPage-jlN9JDzm.js.map} +1 -1
  177. package/dist/chunks/{UserCreateTicketPage-D2a3EOey.js → UserCreateTicketPage-BrRZyXMn.js} +2 -2
  178. package/dist/chunks/{UserCreateTicketPage-D2a3EOey.js.map → UserCreateTicketPage-BrRZyXMn.js.map} +1 -1
  179. package/dist/chunks/{UserCreateTicketPage-bcbSLglE.js → UserCreateTicketPage-D58Ro4Nb.js} +2 -2
  180. package/dist/chunks/{UserCreateTicketPage-bcbSLglE.js.map → UserCreateTicketPage-D58Ro4Nb.js.map} +1 -1
  181. package/dist/chunks/{UserDashboardPage-DwnDRNoW.js → UserDashboardPage-C5ulSzaI.js} +2 -2
  182. package/dist/chunks/{UserDashboardPage-DwnDRNoW.js.map → UserDashboardPage-C5ulSzaI.js.map} +1 -1
  183. package/dist/chunks/{UserDashboardPage-ZMsx8LWw.js → UserDashboardPage-CjAx5OHh.js} +2 -2
  184. package/dist/chunks/{UserDashboardPage-ZMsx8LWw.js.map → UserDashboardPage-CjAx5OHh.js.map} +1 -1
  185. package/dist/chunks/{UserDetailPage-BRFowOFL.js → UserDetailPage-Bhpry9xq.js} +2 -2
  186. package/dist/chunks/{UserDetailPage-BRFowOFL.js.map → UserDetailPage-Bhpry9xq.js.map} +1 -1
  187. package/dist/chunks/{UserDetailPage-CZyV-zsg.js → UserDetailPage-DUu2mA_n.js} +5 -5
  188. package/dist/chunks/{UserDetailPage-CZyV-zsg.js.map → UserDetailPage-DUu2mA_n.js.map} +1 -1
  189. package/dist/chunks/{UserTicketDetailPage-DzB_pELt.js → UserTicketDetailPage-DpFFjIso.js} +2 -2
  190. package/dist/chunks/{UserTicketDetailPage-DzB_pELt.js.map → UserTicketDetailPage-DpFFjIso.js.map} +1 -1
  191. package/dist/chunks/{UserTicketDetailPage-BstGk_BP.js → UserTicketDetailPage-YJvBWFEu.js} +2 -2
  192. package/dist/chunks/{UserTicketDetailPage-BstGk_BP.js.map → UserTicketDetailPage-YJvBWFEu.js.map} +1 -1
  193. package/dist/chunks/{UsersGroupsPage-DTmhzttW.js → UsersGroupsPage-b2PTQX_m.js} +2 -2
  194. package/dist/chunks/{UsersGroupsPage-DTmhzttW.js.map → UsersGroupsPage-b2PTQX_m.js.map} +1 -1
  195. package/dist/chunks/{UsersGroupsPage-BygTv_kK.js → UsersGroupsPage-l33K3Nca.js} +3 -3
  196. package/dist/chunks/{UsersGroupsPage-BygTv_kK.js.map → UsersGroupsPage-l33K3Nca.js.map} +1 -1
  197. package/dist/chunks/{UsersPage-TIqSHgHj.js → UsersPage-BjC5ZqTa.js} +2 -2
  198. package/dist/chunks/{UsersPage-TIqSHgHj.js.map → UsersPage-BjC5ZqTa.js.map} +1 -1
  199. package/dist/chunks/{UsersPage-DcwLyMAX.js → UsersPage-NsTukS8m.js} +2 -2
  200. package/dist/chunks/{UsersPage-DcwLyMAX.js.map → UsersPage-NsTukS8m.js.map} +1 -1
  201. package/dist/chunks/{accessRequestsApi-B6dsJzvH.js → accessRequestsApi-C2usKVGJ.js} +2 -2
  202. package/dist/chunks/{accessRequestsApi-B6dsJzvH.js.map → accessRequestsApi-C2usKVGJ.js.map} +1 -1
  203. package/dist/chunks/{accessRequestsApi-3FjMFbpa.js → accessRequestsApi-LuovcP6l.js} +2 -2
  204. package/dist/chunks/{accessRequestsApi-3FjMFbpa.js.map → accessRequestsApi-LuovcP6l.js.map} +1 -1
  205. package/dist/chunks/{aiApi-DXOdsoxr.js → aiApi-B03u3zUH.js} +2 -2
  206. package/dist/chunks/{aiApi-DXOdsoxr.js.map → aiApi-B03u3zUH.js.map} +1 -1
  207. package/dist/chunks/{aiApi-9G4wG_mT.js → aiApi-Cwg0B8PJ.js} +2 -2
  208. package/dist/chunks/{aiApi-9G4wG_mT.js.map → aiApi-Cwg0B8PJ.js.map} +1 -1
  209. package/dist/chunks/{applicationAnalyticsApi-DhOd6idI.js → applicationAnalyticsApi-BobBdehV.js} +2 -2
  210. package/dist/chunks/{applicationAnalyticsApi-DhOd6idI.js.map → applicationAnalyticsApi-BobBdehV.js.map} +1 -1
  211. package/dist/chunks/{applicationAnalyticsApi-D0DEp9Y-.js → applicationAnalyticsApi-jCZhWKOx.js} +2 -2
  212. package/dist/chunks/{applicationAnalyticsApi-D0DEp9Y-.js.map → applicationAnalyticsApi-jCZhWKOx.js.map} +1 -1
  213. package/dist/chunks/{groupsApi-Db8G2lLs.js → groupsApi-CoxnW9vH.js} +2 -2
  214. package/dist/chunks/{groupsApi-Db8G2lLs.js.map → groupsApi-CoxnW9vH.js.map} +1 -1
  215. package/dist/chunks/{groupsApi-lbxNsHFv.js → groupsApi-D2lFFcgu.js} +2 -2
  216. package/dist/chunks/{groupsApi-lbxNsHFv.js.map → groupsApi-D2lFFcgu.js.map} +1 -1
  217. package/dist/chunks/{index-xhRXN1Jq.js → index-B5U_Jp0-.js} +2 -2
  218. package/dist/chunks/{index-xhRXN1Jq.js.map → index-B5U_Jp0-.js.map} +1 -1
  219. package/dist/chunks/{index-Bn8HzILk.js → index-BDB_a-p7.js} +4 -4
  220. package/dist/chunks/{index-Bn8HzILk.js.map → index-BDB_a-p7.js.map} +1 -1
  221. package/dist/chunks/{index-DF93KQFR.js → index-BbHRJz-n.js} +2 -2
  222. package/dist/chunks/{index-DF93KQFR.js.map → index-BbHRJz-n.js.map} +1 -1
  223. package/dist/chunks/{index-DqbVFB1H.js → index-CI2WU5ZZ.js} +2 -2
  224. package/dist/chunks/{index-DqbVFB1H.js.map → index-CI2WU5ZZ.js.map} +1 -1
  225. package/dist/chunks/{index-DjC1u2hI.js → index-CLk9ClC2.js} +3 -3
  226. package/dist/chunks/{index-DjC1u2hI.js.map → index-CLk9ClC2.js.map} +1 -1
  227. package/dist/chunks/{index-CgtbaFf5.js → index-CmTKGOa_.js} +2 -2
  228. package/dist/chunks/{index-CgtbaFf5.js.map → index-CmTKGOa_.js.map} +1 -1
  229. package/dist/chunks/{index-DwqLhQ8S.js → index-D5oIr6PO.js} +2 -2
  230. package/dist/chunks/{index-DwqLhQ8S.js.map → index-D5oIr6PO.js.map} +1 -1
  231. package/dist/chunks/{index-CTGSmYvs.js → index-DC6TBJV_.js} +2 -2
  232. package/dist/chunks/{index-CTGSmYvs.js.map → index-DC6TBJV_.js.map} +1 -1
  233. package/dist/chunks/{index-CN2WRyg1.js → index-DN97bp_f.js} +1145 -1108
  234. package/dist/chunks/index-DN97bp_f.js.map +1 -0
  235. package/dist/chunks/{index-DUS-tunb.js → index-DRW5qV_L.js} +2 -2
  236. package/dist/chunks/{index-DUS-tunb.js.map → index-DRW5qV_L.js.map} +1 -1
  237. package/dist/chunks/{index-DLekpNSE.js → index-DcLZao1q.js} +2 -2
  238. package/dist/chunks/{index-DLekpNSE.js.map → index-DcLZao1q.js.map} +1 -1
  239. package/dist/chunks/{index-HsAOBno4.js → index-DcMOmGtX.js} +2 -2
  240. package/dist/chunks/{index-HsAOBno4.js.map → index-DcMOmGtX.js.map} +1 -1
  241. package/dist/chunks/{index-cAikSVW0.js → index-DnML-nfd.js} +10 -10
  242. package/dist/chunks/index-DnML-nfd.js.map +1 -0
  243. package/dist/chunks/{index-DEtq-xUL.js → index-Drd59qAP.js} +8 -8
  244. package/dist/chunks/{index-DEtq-xUL.js.map → index-Drd59qAP.js.map} +1 -1
  245. package/dist/chunks/{index-TiWOcC0g.js → index-EiIHjIgi.js} +2 -2
  246. package/dist/chunks/{index-TiWOcC0g.js.map → index-EiIHjIgi.js.map} +1 -1
  247. package/dist/chunks/{index-D0HS542b.js → index-axYz6ptj.js} +2 -2
  248. package/dist/chunks/{index-D0HS542b.js.map → index-axYz6ptj.js.map} +1 -1
  249. package/dist/chunks/{index-BI2dc1FS.js → index-lXrXnhFc.js} +2 -2
  250. package/dist/chunks/{index-BI2dc1FS.js.map → index-lXrXnhFc.js.map} +1 -1
  251. package/dist/chunks/{index-CUICSveU.js → index-rI-1r6c2.js} +2 -2
  252. package/dist/chunks/{index-CUICSveU.js.map → index-rI-1r6c2.js.map} +1 -1
  253. package/dist/chunks/{tenantIconMap-__FKj6CN.js → tenantIconMap-B4wAYGWP.js} +2 -2
  254. package/dist/chunks/{tenantIconMap-__FKj6CN.js.map → tenantIconMap-B4wAYGWP.js.map} +1 -1
  255. package/dist/chunks/{tenantIconMap-CHeS7oLt.js → tenantIconMap-Cfm15HwB.js} +2 -2
  256. package/dist/chunks/{tenantIconMap-CHeS7oLt.js.map → tenantIconMap-Cfm15HwB.js.map} +1 -1
  257. package/dist/chunks/{ticketingApi-DF4RwD_6.js → ticketingApi-CLMAPZDw.js} +2 -2
  258. package/dist/chunks/{ticketingApi-DF4RwD_6.js.map → ticketingApi-CLMAPZDw.js.map} +1 -1
  259. package/dist/chunks/{ticketingApi-Cj239hYB.js → ticketingApi-CTap4NdE.js} +2 -2
  260. package/dist/chunks/{ticketingApi-Cj239hYB.js.map → ticketingApi-CTap4NdE.js.map} +1 -1
  261. package/dist/chunks/{useAccessRequests-CViOUwyF.js → useAccessRequests-CBpDkq9o.js} +2 -2
  262. package/dist/chunks/{useAccessRequests-CViOUwyF.js.map → useAccessRequests-CBpDkq9o.js.map} +1 -1
  263. package/dist/chunks/{useAccessRequests-CFam8zFR.js → useAccessRequests-Cj2-OoAW.js} +3 -3
  264. package/dist/chunks/{useAccessRequests-CFam8zFR.js.map → useAccessRequests-Cj2-OoAW.js.map} +1 -1
  265. package/dist/chunks/{useUserAccessRequests-CslSQeBJ.js → useUserAccessRequests-C6l2VMe1.js} +2 -2
  266. package/dist/chunks/{useUserAccessRequests-CslSQeBJ.js.map → useUserAccessRequests-C6l2VMe1.js.map} +1 -1
  267. package/dist/chunks/{useUserAccessRequests-B-Cs6NX1.js → useUserAccessRequests-Ds3K-ENU.js} +2 -2
  268. package/dist/chunks/{useUserAccessRequests-B-Cs6NX1.js.map → useUserAccessRequests-Ds3K-ENU.js.map} +1 -1
  269. package/dist/components/routing/DynamicRouter.d.ts.map +1 -1
  270. package/dist/contexts/AuthContext.d.ts.map +1 -1
  271. package/dist/contexts/NavigationContext.d.ts.map +1 -1
  272. package/dist/extensions/PageRegistry.d.ts +2 -0
  273. package/dist/extensions/PageRegistry.d.ts.map +1 -1
  274. package/dist/services/api/adminApi/settings.d.ts +8 -3
  275. package/dist/services/api/adminApi/settings.d.ts.map +1 -1
  276. package/dist/smartstack.cjs +1 -1
  277. package/dist/smartstack.js +1 -1
  278. package/package.json +1 -1
  279. package/dist/chunks/index-CN2WRyg1.js.map +0 -1
  280. package/dist/chunks/index-cAikSVW0.js.map +0 -1
@@ -2,7 +2,7 @@ import { jsx as a, jsxs as r, Fragment as F } from "react/jsx-runtime";
2
2
  import { useState as A, useEffect as G, useCallback as R } from "react";
3
3
  import { useTranslation as Y } from "react-i18next";
4
4
  import { useSearchParams as W } from "react-router-dom";
5
- import { L as Z, M as _, O as z, Q, i as X } from "./index-CN2WRyg1.js";
5
+ import { L as Z, M as _, O as z, Q, i as X } from "./index-DN97bp_f.js";
6
6
  import { Loader2 as V, AlertTriangle as T, ShieldCheck as q, Key as H, Zap as J, Users as B, Building as ee, Calendar as ae, Server as te, Monitor as re, Layers as se, Shield as ne, CheckCircle as I, Infinity as ie, Clock as le, X as j, Unlock as ce, Lock as oe } from "lucide-react";
7
7
  const de = {
8
8
  blue: "bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]",
@@ -528,4 +528,4 @@ function E({ icon: e, label: t, max: s, current: n, margin: i = 0, t: l }) {
528
528
  export {
529
529
  Ce as LicenseManagementPage
530
530
  };
531
- //# sourceMappingURL=index-CTGSmYvs.js.map
531
+ //# sourceMappingURL=index-DC6TBJV_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-CTGSmYvs.js","sources":["../../src/pages/platform/administration/configuration/license/LicenseManagementPage.tsx"],"sourcesContent":["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 { useSearchParams } from 'react-router-dom';\r\nimport { useLicense } from '@/contexts/LicenseContext';\r\nimport { api } from '@/services/api/apiClient';\r\nimport { hasAllLicenseFeatures } from '@/utils/licenseUtils';\r\nimport { LicenseStatusBadge } from '@/components/license/LicenseStatusBadge';\r\nimport { LicenseActivationDialog } from '@/components/license/LicenseActivationDialog';\r\nimport type { LicenseFeatureGroup } from '@/contexts/LicenseContext';\r\nimport {\r\n Shield, Calendar, Key, Layers, Users, Building, Zap, Server,\r\n CheckCircle, Clock, AlertTriangle, Loader2, X, Infinity,\r\n Lock, Unlock, ShieldCheck, Monitor\r\n} from 'lucide-react';\r\n\r\nconst colorClasses = {\r\n blue: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n green: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n yellow: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n red: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n neutral: 'bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]',\r\n};\r\n\r\nfunction getStatusColor(license: { isReadOnlyMode: boolean; isInTrial: boolean; trialDaysRemaining: number; status: string; daysUntilExpiration: number; isInGracePeriod: boolean }) {\r\n if (license.status === 'NoLicense') return 'red' as const;\r\n if (license.isReadOnlyMode) return 'red' as const;\r\n if (license.isInGracePeriod) return 'yellow' as const;\r\n if (license.isInTrial && license.trialDaysRemaining <= 7) return 'yellow' as const;\r\n if (license.status === 'Active' && license.daysUntilExpiration <= 30) return 'yellow' as const;\r\n if (license.status === 'Active') return 'green' as const;\r\n return 'red' as const;\r\n}\r\n\r\nfunction getLicenseDaysColor(license: { isPerpetual: boolean; isInTrial: boolean; trialDaysRemaining: number; daysUntilExpiration: number }): 'red' | 'yellow' | 'green' {\r\n if (license.isPerpetual) return 'green';\r\n const daysRemaining = license.isInTrial ? license.trialDaysRemaining : license.daysUntilExpiration;\r\n if (daysRemaining <= 15) return 'red';\r\n if (daysRemaining <= 30) return 'yellow';\r\n return 'green';\r\n}\r\n\r\nfunction formatDate(dateStr: string | null): string {\r\n if (!dateStr) return '-';\r\n return new Date(dateStr).toLocaleDateString(undefined, {\r\n year: 'numeric',\r\n month: 'long',\r\n day: 'numeric',\r\n });\r\n}\r\n\r\nfunction buildKpiCards(license: any, t: (key: string, fallback: string, opts?: Record<string, unknown>) => string) {\r\n const statusColor = getStatusColor(license);\r\n const daysRemaining = license.isInTrial ? license.trialDaysRemaining : license.daysUntilExpiration;\r\n const daysColor = getLicenseDaysColor(license);\r\n\r\n return [\r\n {\r\n label: t('license.info.edition', 'Edition'),\r\n value: t(`license.edition.${license.edition.toLowerCase()}`, license.edition),\r\n icon: Shield,\r\n color: 'blue' as const,\r\n },\r\n {\r\n label: t('license.info.status', 'Status'),\r\n value: license.isInGracePeriod\r\n ? t('license.page.gracePeriod', 'Grace Period')\r\n : t(`license.status.${license.status.toLowerCase()}`, license.status),\r\n icon: license.isReadOnlyMode ? AlertTriangle : CheckCircle,\r\n color: statusColor,\r\n },\r\n {\r\n label: t('license.page.daysRemaining', 'Days remaining'),\r\n value: license.isPerpetual ? '\\u221E' : daysRemaining.toString(),\r\n icon: license.isPerpetual ? Infinity : Clock,\r\n color: daysColor,\r\n },\r\n {\r\n label: t('license.page.maxUsers', 'Max Users'),\r\n value: license.limits.users > 0 ? license.limits.users.toString() : t('license.page.unlimited', 'Unlimited'),\r\n icon: Users,\r\n color: 'blue' as const,\r\n },\r\n ];\r\n}\r\n\r\n// Sub-component: Status Banners\r\ninterface StatusBannersProps {\r\n readonly showTrialSuccess: boolean;\r\n readonly isInGracePeriod: boolean;\r\n readonly validationResult: { type: 'success' | 'revoked' | 'error'; message: string } | null;\r\n readonly gracePeriodDays: number;\r\n readonly onTrialSuccessClose: () => void;\r\n readonly onValidationResultClear: () => void;\r\n readonly t: TFunction;\r\n}\r\n\r\nfunction StatusBanners({\r\n showTrialSuccess, isInGracePeriod, validationResult, gracePeriodDays,\r\n onTrialSuccessClose, onValidationResultClear, t\r\n}: StatusBannersProps) {\r\n return (\r\n <>\r\n {showTrialSuccess && (\r\n <div className=\"flex items-center gap-3 p-4 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg animate-in fade-in slide-in-from-top\">\r\n <CheckCircle className=\"w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-green-900 dark:text-green-300\">\r\n {t('license.trial.successBanner', 'Your 30-day trial is activated!')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={onTrialSuccessClose}\r\n className=\"text-green-600 dark:text-green-400 hover:text-green-700 dark:hover:text-green-300\"\r\n >\r\n <X className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n )}\r\n\r\n {isInGracePeriod && (\r\n <div className=\"flex items-center gap-3 p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg\">\r\n <AlertTriangle className=\"w-5 h-5 text-amber-600 dark:text-amber-400 flex-shrink-0\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-amber-900 dark:text-amber-300\">\r\n {t('license.page.gracePeriodBanner', 'Your license has expired. You are in a {{days}}-day grace period. Renew to avoid service interruption.', { days: gracePeriodDays })}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {validationResult && (\r\n <div className={`flex items-center gap-3 p-4 rounded-lg border ${\r\n validationResult.type === 'success'\r\n ? 'bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800'\r\n : validationResult.type === 'revoked'\r\n ? 'bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800'\r\n : 'bg-amber-50 dark:bg-amber-900/20 border-amber-200 dark:border-amber-800'\r\n }`}>\r\n {validationResult.type === 'success'\r\n ? <CheckCircle className=\"w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0\" />\r\n : <AlertTriangle className={`w-5 h-5 flex-shrink-0 ${\r\n validationResult.type === 'revoked'\r\n ? 'text-red-600 dark:text-red-400'\r\n : 'text-amber-600 dark:text-amber-400'\r\n }`} />\r\n }\r\n <p className={`text-sm font-medium flex-1 ${\r\n validationResult.type === 'success'\r\n ? 'text-green-900 dark:text-green-300'\r\n : validationResult.type === 'revoked'\r\n ? 'text-red-900 dark:text-red-300'\r\n : 'text-amber-900 dark:text-amber-300'\r\n }`}>\r\n {validationResult.message}\r\n </p>\r\n <button\r\n onClick={onValidationResultClear}\r\n className={\r\n validationResult.type === 'success'\r\n ? 'text-green-600 dark:text-green-400 hover:text-green-700 dark:hover:text-green-300'\r\n : validationResult.type === 'revoked'\r\n ? 'text-red-600 dark:text-red-400 hover:text-red-700 dark:hover:text-red-300'\r\n : 'text-amber-600 dark:text-amber-400 hover:text-amber-700 dark:hover:text-amber-400'\r\n }\r\n >\r\n <X className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n )}\r\n </>\r\n );\r\n}\r\n\r\n// Sub-component: Features Grid\r\ninterface FeaturesGridProps {\r\n readonly hasAllFeatures: boolean;\r\n readonly enabledFeatures: string[];\r\n readonly availableFeatures?: LicenseFeatureGroup[];\r\n readonly t: TFunction;\r\n}\r\n\r\nfunction FeaturesGrid({ hasAllFeatures, enabledFeatures, availableFeatures, t }: FeaturesGridProps) {\r\n if (!availableFeatures || availableFeatures.length === 0) {\r\n return (\r\n <p className=\"text-[var(--text-secondary)] text-sm italic\">\r\n {t('license.page.noFeatures', 'No features enabled')}\r\n </p>\r\n );\r\n }\r\n\r\n return (\r\n <>\r\n {hasAllFeatures && (\r\n <div className=\"flex items-center gap-2 p-3 mb-4 bg-[var(--success-bg)] text-[var(--success-text)] rounded-lg border border-[var(--success-border)]\">\r\n <CheckCircle className=\"w-5 h-5\" />\r\n <span className=\"font-medium\">{t('license.page.allFeatures', 'All features enabled')}</span>\r\n </div>\r\n )}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\r\n {availableFeatures.map(({ group, features }) => (\r\n <div key={group}>\r\n <h3 className=\"text-sm font-semibold text-[var(--text-secondary)] uppercase tracking-wider mb-3\">\r\n {t(`license.group.${group}`, group)}\r\n </h3>\r\n <div className=\"space-y-2\">\r\n {features.map((code) => {\r\n const enabled = hasAllFeatures || enabledFeatures.some(\r\n f => f.toLowerCase() === code.toLowerCase()\r\n );\r\n return (\r\n <div\r\n key={code}\r\n className={`flex items-center gap-2 px-3 py-2 rounded-lg border ${\r\n enabled\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)] border-[var(--border-color)] opacity-60'\r\n }`}\r\n >\r\n {enabled\r\n ? <Unlock className=\"w-4 h-4 flex-shrink-0\" />\r\n : <Lock className=\"w-4 h-4 flex-shrink-0\" />\r\n }\r\n <span className=\"text-sm font-medium\">{t(`license.module.${code}`, code)}</span>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n {!hasAllFeatures && enabledFeatures.length === 0 && (\r\n <p className=\"text-[var(--text-secondary)] text-sm italic mt-3\">\r\n {t('license.page.noFeatures', 'No features enabled')}\r\n </p>\r\n )}\r\n </>\r\n );\r\n}\r\n\r\nfunction useValidateLicense(refreshLicense: () => Promise<void>, t: (key: string, fallback: string, opts?: Record<string, unknown>) => string) {\r\n const [isValidating, setIsValidating] = useState(false);\r\n const [validationResult, setValidationResult] = useState<{ type: 'success' | 'revoked' | 'error'; message: string } | null>(null);\r\n\r\n const handleValidate = useCallback(async () => {\r\n setIsValidating(true);\r\n setValidationResult(null);\r\n try {\r\n const result = await api.post<{ valid: boolean; revoked: boolean; error?: string }>(\r\n '/api/administration/license/validate-server'\r\n );\r\n if (result.revoked) {\r\n setValidationResult({ type: 'revoked', message: t('license.validationRevoked', 'The license has been revoked by the server.') });\r\n await refreshLicense();\r\n } else if (result.valid) {\r\n setValidationResult({ type: 'success', message: t('license.validationSuccess', 'License is valid') });\r\n await refreshLicense();\r\n } else {\r\n setValidationResult({ type: 'error', message: result.error || t('license.validationError', 'Unable to validate the license with the server.') });\r\n }\r\n } catch {\r\n setValidationResult({ type: 'error', message: t('license.validationError', 'Unable to validate the license with the server.') });\r\n } finally {\r\n setIsValidating(false);\r\n setTimeout(() => setValidationResult(null), 5000);\r\n }\r\n }, [t, refreshLicense]);\r\n\r\n const clearValidationResult = useCallback(() => setValidationResult(null), []);\r\n\r\n return { isValidating, validationResult, handleValidate, clearValidationResult };\r\n}\r\n\r\nexport function LicenseManagementPage(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { license, usage, isLoading, error, refreshLicense } = useLicense();\r\n const [showActivation, setShowActivation] = useState(false);\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n const [showTrialSuccess, setShowTrialSuccess] = useState(false);\r\n const { isValidating, validationResult, handleValidate, clearValidationResult } = useValidateLicense(refreshLicense, t);\r\n\r\n // Refresh license data when the page is displayed (e.g. after creating a tenant)\r\n useEffect(() => {\r\n refreshLicense();\r\n }, [refreshLicense]);\r\n\r\n useEffect(() => {\r\n if (searchParams.get('trial') === 'success') {\r\n setShowTrialSuccess(true);\r\n const timer = setTimeout(() => {\r\n setShowTrialSuccess(false);\r\n searchParams.delete('trial');\r\n setSearchParams(searchParams, { replace: true });\r\n }, 5000);\r\n return () => clearTimeout(timer);\r\n }\r\n }, [searchParams, setSearchParams]);\r\n\r\n if (isLoading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-64\">\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 || !license) {\r\n return (\r\n <div className=\"p-6\">\r\n <div className=\"card p-6 text-center\">\r\n <AlertTriangle className=\"w-12 h-12 mx-auto mb-4 text-[var(--warning-text)]\" />\r\n <h2 className=\"text-lg font-semibold mb-2\">{t('license.page.errorTitle', 'Unable to load license')}</h2>\r\n <p className=\"text-[var(--text-secondary)] mb-4\">{error || t('license.page.errorDesc', 'License information is not available.')}</p>\r\n <button\r\n onClick={() => refreshLicense()}\r\n className=\"btn-primary px-4 py-2\"\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 hasAllFeatures = hasAllLicenseFeatures(license.enabledFeatures);\r\n const kpiCards = buildKpiCards(license, t);\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <StatusBanners\r\n showTrialSuccess={showTrialSuccess}\r\n isInGracePeriod={license.isInGracePeriod}\r\n validationResult={validationResult}\r\n gracePeriodDays={license.gracePeriodDays}\r\n onTrialSuccessClose={() => setShowTrialSuccess(false)}\r\n onValidationResultClear={clearValidationResult}\r\n t={t}\r\n />\r\n\r\n {/* Banners handled by StatusBanners component above */}\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('license.page.title', 'License Management')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)] mt-1\">\r\n {t('license.page.subtitle', 'View and manage your platform license')}\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n <LicenseStatusBadge showDetails />\r\n <button\r\n onClick={handleValidate}\r\n disabled={isValidating}\r\n className=\"btn-secondary px-4 py-2 flex items-center gap-2\"\r\n >\r\n {isValidating\r\n ? <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n : <ShieldCheck className=\"w-4 h-4\" />\r\n }\r\n {isValidating\r\n ? t('license.validating', 'Validating...')\r\n : t('license.validate', 'Validate')}\r\n </button>\r\n <button\r\n onClick={() => setShowActivation(true)}\r\n className=\"btn-primary px-4 py-2 flex items-center gap-2\"\r\n >\r\n <Key className=\"w-4 h-4\" />\r\n {t('license.activate', 'Activate')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* KPI Cards */}\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n {kpiCards.map((card) => (\r\n <div key={card.label} className={`card p-4 border ${colorClasses[card.color]}`}>\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <card.icon className=\"w-5 h-5 opacity-80\" />\r\n <span className=\"text-sm opacity-80\">{card.label}</span>\r\n </div>\r\n <div className=\"text-2xl font-bold\">{card.value}</div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Limits Section */}\r\n <div className=\"card p-6\">\r\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\r\n <Zap className=\"w-5 h-5\" />\r\n {t('license.info.limits', 'Limits')}\r\n </h2>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\r\n <CircularGauge\r\n icon={Users}\r\n label={t('license.page.usersLimit', 'Users')}\r\n max={license.limits.users}\r\n current={usage?.activeUsers ?? 0}\r\n margin={10}\r\n t={t}\r\n />\r\n <CircularGauge\r\n icon={Building}\r\n label={t('license.page.tenantsLimit', 'Tenants (B2B)')}\r\n max={license.limits.tenants}\r\n current={usage?.activeTenants ?? 0}\r\n margin={2}\r\n t={t}\r\n />\r\n </div>\r\n {/* Custom limits from JWT */}\r\n {(() => {\r\n const standardKeys = ['users', 'tenants', 'max_instances', 'max_users'];\r\n const customEntries = Object.entries(license.limits.custom ?? {}).filter(\r\n ([key]) => !standardKeys.includes(key)\r\n );\r\n if (customEntries.length === 0) return null;\r\n return (\r\n <div className=\"mt-4 pt-4 border-t border-[var(--border-color)]\">\r\n <h3 className=\"text-sm font-medium text-[var(--text-secondary)] mb-3\">\r\n {t('license.page.customLimits', 'Custom Limits')}\r\n </h3>\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-3\">\r\n {customEntries.map(([key, value]) => (\r\n <div key={key} className=\"flex justify-between items-center py-1.5 px-3 bg-[var(--bg-secondary)] rounded-lg\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{key}</span>\r\n <span className=\"text-sm font-medium\">{value}</span>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n })()}\r\n </div>\r\n\r\n {/* Details + Subscription + Machine Section */}\r\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\r\n {/* License Details */}\r\n <div className=\"card p-6\">\r\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\r\n <Calendar className=\"w-5 h-5\" />\r\n {t('license.page.details', 'License Details')}\r\n </h2>\r\n <div className=\"space-y-3\">\r\n <DetailRow label={t('license.info.productId', 'Product')} value={license.productId} />\r\n <DetailRow label={t('license.info.company', 'Company')} value={license.companyName || '-'} />\r\n <DetailRow\r\n label={t('license.info.edition', 'Edition')}\r\n value={t(`license.edition.${license.edition.toLowerCase()}`, license.edition)}\r\n />\r\n <DetailRow\r\n label={t('license.info.status', 'Status')}\r\n value={t(`license.status.${license.status.toLowerCase()}`, license.status)}\r\n />\r\n <DetailRow\r\n label={t('license.info.activatedAt', 'Activated At')}\r\n value={formatDate(license.activatedAt)}\r\n />\r\n <DetailRow\r\n label={t('license.info.expiresAt', 'Expires At')}\r\n value={license.isPerpetual\r\n ? t('license.page.never', 'Never (Perpetual)')\r\n : formatDate(license.expiresAt)}\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Subscription Info */}\r\n <div className=\"card p-6\">\r\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\r\n <Server className=\"w-5 h-5\" />\r\n {t('license.page.subscription', 'Subscription')}\r\n </h2>\r\n <div className=\"space-y-3\">\r\n <DetailRow\r\n label={t('license.page.licenseType', 'License Type')}\r\n value={license.isPerpetual\r\n ? t('license.page.perpetual', 'Perpetual')\r\n : license.isInTrial\r\n ? t('license.edition.trial', 'Trial')\r\n : t('license.page.subscription', 'Subscription')}\r\n />\r\n <DetailRow\r\n label={t('license.page.maxUsers', 'Max Users')}\r\n value={license.limits.users > 0 ? license.limits.users.toString() : t('license.page.unlimited', 'Unlimited')}\r\n />\r\n <DetailRow\r\n label={t('license.page.gracePeriodDays', 'Grace Period')}\r\n value={license.gracePeriodDays > 0\r\n ? t('license.page.gracePeriodValue', '{{days}} days', { days: license.gracePeriodDays })\r\n : t('license.page.noGracePeriod', 'None')}\r\n />\r\n <DetailRow\r\n label={t('license.page.renewalDate', 'Renewal Date')}\r\n value={formatDate(license.renewalDate)}\r\n />\r\n <DetailRow\r\n label={t('license.page.mode', 'Mode')}\r\n value={license.isReadOnlyMode\r\n ? t('license.page.readOnly', 'Read-only')\r\n : license.isInTrial\r\n ? t('license.edition.trial', 'Trial')\r\n : t('license.page.licensed', 'Licensed')}\r\n />\r\n {license.isInGracePeriod && (\r\n <DetailRow\r\n label={t('license.page.gracePeriodStatus', 'Grace Period Status')}\r\n value={t('license.page.inGracePeriod', 'Active')}\r\n highlight=\"yellow\"\r\n />\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Machine Info */}\r\n <div className=\"card p-6\">\r\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\r\n <Monitor className=\"w-5 h-5\" />\r\n {t('license.page.machineInfo', 'Machine')}\r\n </h2>\r\n <div className=\"space-y-3\">\r\n <div className=\"py-2 border-b border-[var(--border-color)] last:border-b-0\">\r\n <div className=\"flex justify-between items-center mb-1\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{t('license.page.machineName', 'Machine Name')}</span>\r\n </div>\r\n <span className=\"text-xs font-mono text-[var(--text-primary)] break-all\">\r\n {license.machineName || '-'}\r\n </span>\r\n </div>\r\n <div className=\"py-2 border-b border-[var(--border-color)] last:border-b-0\">\r\n <div className=\"flex justify-between items-center mb-1\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{t('license.page.instanceId', 'Instance ID')}</span>\r\n </div>\r\n <span className=\"text-xs font-mono text-[var(--text-primary)] break-all\">\r\n {license.instanceId || '-'}\r\n </span>\r\n </div>\r\n <div className=\"py-2 border-b border-[var(--border-color)] last:border-b-0\">\r\n <div className=\"flex justify-between items-center mb-1\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{t('license.page.licenseId', 'License ID')}</span>\r\n </div>\r\n <span className=\"text-xs font-mono text-[var(--text-primary)] break-all\">\r\n {license.licenseServerId || '-'}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"card p-6\">\r\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\r\n <Layers className=\"w-5 h-5\" />\r\n {t('license.info.features', 'Features')}\r\n </h2>\r\n <FeaturesGrid\r\n hasAllFeatures={hasAllFeatures}\r\n enabledFeatures={license.enabledFeatures}\r\n availableFeatures={license.availableFeatures}\r\n t={t}\r\n />\r\n </div>\r\n\r\n <LicenseActivationDialog open={showActivation} onOpenChange={setShowActivation} />\r\n </div>\r\n );\r\n}\r\n\r\nfunction DetailRow({ label, value, highlight }: { label: string; value: string; highlight?: 'yellow' | 'red' | 'green' }) {\r\n const highlightClass = highlight === 'yellow'\r\n ? 'text-amber-600 dark:text-amber-400 font-semibold'\r\n : highlight === 'red'\r\n ? 'text-red-600 dark:text-red-400 font-semibold'\r\n : highlight === 'green'\r\n ? 'text-green-600 dark:text-green-400 font-semibold'\r\n : 'text-[var(--text-primary)]';\r\n\r\n return (\r\n <div className=\"flex justify-between items-center py-2 border-b border-[var(--border-color)] last:border-b-0\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{label}</span>\r\n <span className={`text-sm font-medium ${highlightClass}`}>{value}</span>\r\n </div>\r\n );\r\n}\r\n\r\nfunction getGaugeIconColor(exceededEffective: boolean, inToleranceZone: boolean): string {\r\n if (exceededEffective) return 'text-red-500';\r\n if (inToleranceZone) return 'text-amber-500';\r\n return 'text-blue-500';\r\n}\r\n\r\nfunction getGaugeTextColor(exceededEffective: boolean, inToleranceZone: boolean): string {\r\n if (exceededEffective) return 'text-red-500';\r\n if (inToleranceZone) return 'text-amber-500';\r\n return 'text-[var(--text-primary)]';\r\n}\r\n\r\nfunction CircularGauge({ icon: Icon, label, max, current, margin = 0, t }: {\r\n icon: typeof Users;\r\n label: string;\r\n max: number;\r\n current: number;\r\n margin?: number;\r\n t: (key: string, fallback: string, opts?: Record<string, unknown>) => string;\r\n}) {\r\n const unlimited = max <= 0;\r\n const licensedLimit = max - margin;\r\n const total = max;\r\n\r\n // SVG arc parameters\r\n const size = 140;\r\n const strokeWidth = 12;\r\n const radius = (size - strokeWidth) / 2;\r\n const center = size / 2;\r\n // Arc spans 270 degrees (from 135° to 405°)\r\n const startAngle = 135;\r\n const totalArc = 270;\r\n\r\n // Percentages\r\n const usagePercent = total > 0 ? Math.min(1, current / total) : 0;\r\n const licensedPercent = total > 0 ? licensedLimit / total : 1;\r\n\r\n // Zone detection\r\n const inToleranceZone = margin > 0 && current > licensedLimit && current <= total;\r\n const exceededEffective = current > total;\r\n\r\n // Colors\r\n let usageColor = '#3b82f6'; // blue-500\r\n if (exceededEffective) usageColor = '#ef4444'; // red-500\r\n else if (inToleranceZone) usageColor = '#f59e0b'; // amber-500\r\n\r\n const toleranceTrackColor = 'rgba(245, 158, 11, 0.25)'; // amber with opacity\r\n\r\n // Helper to compute SVG arc endpoint\r\n const polarToCartesian = (angleDeg: number) => {\r\n const rad = (angleDeg * Math.PI) / 180;\r\n return {\r\n x: center + radius * Math.cos(rad),\r\n y: center + radius * Math.sin(rad),\r\n };\r\n };\r\n\r\n // Build an arc path from startAngle spanning `sweep` degrees\r\n const describeArc = (sweep: number) => {\r\n if (sweep <= 0) return '';\r\n const endAngle = startAngle + sweep;\r\n const start = polarToCartesian(startAngle);\r\n const end = polarToCartesian(endAngle);\r\n const largeArc = sweep > 180 ? 1 : 0;\r\n return `M ${start.x} ${start.y} A ${radius} ${radius} 0 ${largeArc} 1 ${end.x} ${end.y}`;\r\n };\r\n\r\n // Percentage display\r\n const displayPercent = total > 0 ? Math.round((current / licensedLimit) * 100) : 0;\r\n\r\n if (unlimited) {\r\n return (\r\n <div className=\"flex flex-col items-center gap-3 py-4\">\r\n <div className=\"relative\" style={{ width: size, height: size }}>\r\n <svg width={size} height={size}>\r\n {/* Background track */}\r\n <path\r\n d={describeArc(totalArc)}\r\n fill=\"none\"\r\n stroke=\"var(--bg-tertiary)\"\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n />\r\n {/* Full green arc for unlimited */}\r\n <path\r\n d={describeArc(totalArc)}\r\n fill=\"none\"\r\n stroke=\"#22c55e\"\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n opacity={0.5}\r\n />\r\n </svg>\r\n <div className=\"absolute inset-0 flex flex-col items-center justify-center\">\r\n <Icon className=\"w-6 h-6 text-green-500 mb-1\" />\r\n <span className=\"text-lg font-bold text-green-500\">&infin;</span>\r\n </div>\r\n </div>\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">{label}</span>\r\n <span className=\"text-xs text-[var(--text-secondary)]\">{t('license.page.unlimited', 'Unlimited')}</span>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex flex-col items-center gap-3 py-4\">\r\n <div className=\"relative\" style={{ width: size, height: size }}>\r\n <svg width={size} height={size}>\r\n {/* Background track */}\r\n <path\r\n d={describeArc(totalArc)}\r\n fill=\"none\"\r\n stroke=\"var(--bg-tertiary)\"\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n />\r\n {/* Tolerance zone: arc from licensed limit to effective limit */}\r\n {margin > 0 && (() => {\r\n const toleranceSweep = totalArc * (1 - licensedPercent);\r\n const toleranceStartAngle = startAngle + totalArc * licensedPercent;\r\n const tStart = polarToCartesian(toleranceStartAngle);\r\n const tEnd = polarToCartesian(startAngle + totalArc);\r\n const largeArc = toleranceSweep > 180 ? 1 : 0;\r\n const tolerancePath = `M ${tStart.x} ${tStart.y} A ${radius} ${radius} 0 ${largeArc} 1 ${tEnd.x} ${tEnd.y}`;\r\n return (\r\n <path\r\n d={tolerancePath}\r\n fill=\"none\"\r\n stroke={toleranceTrackColor}\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n />\r\n );\r\n })()}\r\n {/* Usage arc */}\r\n <path\r\n d={describeArc(totalArc * usagePercent)}\r\n fill=\"none\"\r\n stroke={usageColor}\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n style={{ transition: 'stroke 0.3s, d 0.3s' }}\r\n />\r\n {/* Licensed limit tick mark */}\r\n {margin > 0 && (() => {\r\n const tickAngle = startAngle + totalArc * licensedPercent;\r\n const innerR = radius - strokeWidth / 2 - 2;\r\n const outerR = radius + strokeWidth / 2 + 2;\r\n const rad = (tickAngle * Math.PI) / 180;\r\n return (\r\n <line\r\n x1={center + innerR * Math.cos(rad)}\r\n y1={center + innerR * Math.sin(rad)}\r\n x2={center + outerR * Math.cos(rad)}\r\n y2={center + outerR * Math.sin(rad)}\r\n stroke=\"var(--text-secondary)\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n />\r\n );\r\n })()}\r\n </svg>\r\n {/* Center content */}\r\n <div className=\"absolute inset-0 flex flex-col items-center justify-center\">\r\n <Icon className={`w-5 h-5 mb-0.5 ${getGaugeIconColor(exceededEffective, inToleranceZone)}`} />\r\n <span className={`text-2xl font-bold ${getGaugeTextColor(exceededEffective, inToleranceZone)}`}>\r\n {displayPercent}%\r\n </span>\r\n <span className=\"text-xs text-[var(--text-secondary)]\">\r\n {current} / {licensedLimit}\r\n </span>\r\n </div>\r\n </div>\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">{label}</span>\r\n {margin > 0 && (\r\n <span className={`text-xs ${inToleranceZone || exceededEffective ? 'text-amber-600 dark:text-amber-400' : 'text-[var(--text-secondary)]'}`}>\r\n +{margin} {t('license.page.tolerance', 'tolerance')}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["colorClasses","getStatusColor","license","getLicenseDaysColor","daysRemaining","formatDate","dateStr","buildKpiCards","statusColor","daysColor","Shield","AlertTriangle","CheckCircle","Infinity","Clock","Users","StatusBanners","showTrialSuccess","isInGracePeriod","validationResult","gracePeriodDays","onTrialSuccessClose","onValidationResultClear","t","jsxs","Fragment","jsx","X","FeaturesGrid","hasAllFeatures","enabledFeatures","availableFeatures","group","features","code","enabled","f","Unlock","Lock","useValidateLicense","refreshLicense","isValidating","setIsValidating","useState","setValidationResult","handleValidate","useCallback","result","api","clearValidationResult","LicenseManagementPage","useTranslation","usage","isLoading","error","useLicense","showActivation","setShowActivation","searchParams","setSearchParams","useSearchParams","setShowTrialSuccess","useEffect","timer","Loader2","hasAllLicenseFeatures","kpiCards","LicenseStatusBadge","ShieldCheck","Key","card","Zap","CircularGauge","Building","standardKeys","customEntries","key","value","Calendar","DetailRow","Server","Monitor","Layers","LicenseActivationDialog","label","highlight","getGaugeIconColor","exceededEffective","inToleranceZone","getGaugeTextColor","Icon","max","current","margin","unlimited","licensedLimit","total","size","strokeWidth","radius","center","startAngle","totalArc","usagePercent","licensedPercent","usageColor","toleranceTrackColor","polarToCartesian","angleDeg","rad","describeArc","sweep","endAngle","start","end","largeArc","displayPercent","toleranceSweep","toleranceStartAngle","tStart","tEnd","tolerancePath","tickAngle","innerR","outerR"],"mappings":"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"}
1
+ {"version":3,"file":"index-DC6TBJV_.js","sources":["../../src/pages/platform/administration/configuration/license/LicenseManagementPage.tsx"],"sourcesContent":["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 { useSearchParams } from 'react-router-dom';\r\nimport { useLicense } from '@/contexts/LicenseContext';\r\nimport { api } from '@/services/api/apiClient';\r\nimport { hasAllLicenseFeatures } from '@/utils/licenseUtils';\r\nimport { LicenseStatusBadge } from '@/components/license/LicenseStatusBadge';\r\nimport { LicenseActivationDialog } from '@/components/license/LicenseActivationDialog';\r\nimport type { LicenseFeatureGroup } from '@/contexts/LicenseContext';\r\nimport {\r\n Shield, Calendar, Key, Layers, Users, Building, Zap, Server,\r\n CheckCircle, Clock, AlertTriangle, Loader2, X, Infinity,\r\n Lock, Unlock, ShieldCheck, Monitor\r\n} from 'lucide-react';\r\n\r\nconst colorClasses = {\r\n blue: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n green: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n yellow: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n red: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n neutral: 'bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]',\r\n};\r\n\r\nfunction getStatusColor(license: { isReadOnlyMode: boolean; isInTrial: boolean; trialDaysRemaining: number; status: string; daysUntilExpiration: number; isInGracePeriod: boolean }) {\r\n if (license.status === 'NoLicense') return 'red' as const;\r\n if (license.isReadOnlyMode) return 'red' as const;\r\n if (license.isInGracePeriod) return 'yellow' as const;\r\n if (license.isInTrial && license.trialDaysRemaining <= 7) return 'yellow' as const;\r\n if (license.status === 'Active' && license.daysUntilExpiration <= 30) return 'yellow' as const;\r\n if (license.status === 'Active') return 'green' as const;\r\n return 'red' as const;\r\n}\r\n\r\nfunction getLicenseDaysColor(license: { isPerpetual: boolean; isInTrial: boolean; trialDaysRemaining: number; daysUntilExpiration: number }): 'red' | 'yellow' | 'green' {\r\n if (license.isPerpetual) return 'green';\r\n const daysRemaining = license.isInTrial ? license.trialDaysRemaining : license.daysUntilExpiration;\r\n if (daysRemaining <= 15) return 'red';\r\n if (daysRemaining <= 30) return 'yellow';\r\n return 'green';\r\n}\r\n\r\nfunction formatDate(dateStr: string | null): string {\r\n if (!dateStr) return '-';\r\n return new Date(dateStr).toLocaleDateString(undefined, {\r\n year: 'numeric',\r\n month: 'long',\r\n day: 'numeric',\r\n });\r\n}\r\n\r\nfunction buildKpiCards(license: any, t: (key: string, fallback: string, opts?: Record<string, unknown>) => string) {\r\n const statusColor = getStatusColor(license);\r\n const daysRemaining = license.isInTrial ? license.trialDaysRemaining : license.daysUntilExpiration;\r\n const daysColor = getLicenseDaysColor(license);\r\n\r\n return [\r\n {\r\n label: t('license.info.edition', 'Edition'),\r\n value: t(`license.edition.${license.edition.toLowerCase()}`, license.edition),\r\n icon: Shield,\r\n color: 'blue' as const,\r\n },\r\n {\r\n label: t('license.info.status', 'Status'),\r\n value: license.isInGracePeriod\r\n ? t('license.page.gracePeriod', 'Grace Period')\r\n : t(`license.status.${license.status.toLowerCase()}`, license.status),\r\n icon: license.isReadOnlyMode ? AlertTriangle : CheckCircle,\r\n color: statusColor,\r\n },\r\n {\r\n label: t('license.page.daysRemaining', 'Days remaining'),\r\n value: license.isPerpetual ? '\\u221E' : daysRemaining.toString(),\r\n icon: license.isPerpetual ? Infinity : Clock,\r\n color: daysColor,\r\n },\r\n {\r\n label: t('license.page.maxUsers', 'Max Users'),\r\n value: license.limits.users > 0 ? license.limits.users.toString() : t('license.page.unlimited', 'Unlimited'),\r\n icon: Users,\r\n color: 'blue' as const,\r\n },\r\n ];\r\n}\r\n\r\n// Sub-component: Status Banners\r\ninterface StatusBannersProps {\r\n readonly showTrialSuccess: boolean;\r\n readonly isInGracePeriod: boolean;\r\n readonly validationResult: { type: 'success' | 'revoked' | 'error'; message: string } | null;\r\n readonly gracePeriodDays: number;\r\n readonly onTrialSuccessClose: () => void;\r\n readonly onValidationResultClear: () => void;\r\n readonly t: TFunction;\r\n}\r\n\r\nfunction StatusBanners({\r\n showTrialSuccess, isInGracePeriod, validationResult, gracePeriodDays,\r\n onTrialSuccessClose, onValidationResultClear, t\r\n}: StatusBannersProps) {\r\n return (\r\n <>\r\n {showTrialSuccess && (\r\n <div className=\"flex items-center gap-3 p-4 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg animate-in fade-in slide-in-from-top\">\r\n <CheckCircle className=\"w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-green-900 dark:text-green-300\">\r\n {t('license.trial.successBanner', 'Your 30-day trial is activated!')}\r\n </p>\r\n </div>\r\n <button\r\n onClick={onTrialSuccessClose}\r\n className=\"text-green-600 dark:text-green-400 hover:text-green-700 dark:hover:text-green-300\"\r\n >\r\n <X className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n )}\r\n\r\n {isInGracePeriod && (\r\n <div className=\"flex items-center gap-3 p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg\">\r\n <AlertTriangle className=\"w-5 h-5 text-amber-600 dark:text-amber-400 flex-shrink-0\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-amber-900 dark:text-amber-300\">\r\n {t('license.page.gracePeriodBanner', 'Your license has expired. You are in a {{days}}-day grace period. Renew to avoid service interruption.', { days: gracePeriodDays })}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {validationResult && (\r\n <div className={`flex items-center gap-3 p-4 rounded-lg border ${\r\n validationResult.type === 'success'\r\n ? 'bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800'\r\n : validationResult.type === 'revoked'\r\n ? 'bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800'\r\n : 'bg-amber-50 dark:bg-amber-900/20 border-amber-200 dark:border-amber-800'\r\n }`}>\r\n {validationResult.type === 'success'\r\n ? <CheckCircle className=\"w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0\" />\r\n : <AlertTriangle className={`w-5 h-5 flex-shrink-0 ${\r\n validationResult.type === 'revoked'\r\n ? 'text-red-600 dark:text-red-400'\r\n : 'text-amber-600 dark:text-amber-400'\r\n }`} />\r\n }\r\n <p className={`text-sm font-medium flex-1 ${\r\n validationResult.type === 'success'\r\n ? 'text-green-900 dark:text-green-300'\r\n : validationResult.type === 'revoked'\r\n ? 'text-red-900 dark:text-red-300'\r\n : 'text-amber-900 dark:text-amber-300'\r\n }`}>\r\n {validationResult.message}\r\n </p>\r\n <button\r\n onClick={onValidationResultClear}\r\n className={\r\n validationResult.type === 'success'\r\n ? 'text-green-600 dark:text-green-400 hover:text-green-700 dark:hover:text-green-300'\r\n : validationResult.type === 'revoked'\r\n ? 'text-red-600 dark:text-red-400 hover:text-red-700 dark:hover:text-red-300'\r\n : 'text-amber-600 dark:text-amber-400 hover:text-amber-700 dark:hover:text-amber-400'\r\n }\r\n >\r\n <X className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n )}\r\n </>\r\n );\r\n}\r\n\r\n// Sub-component: Features Grid\r\ninterface FeaturesGridProps {\r\n readonly hasAllFeatures: boolean;\r\n readonly enabledFeatures: string[];\r\n readonly availableFeatures?: LicenseFeatureGroup[];\r\n readonly t: TFunction;\r\n}\r\n\r\nfunction FeaturesGrid({ hasAllFeatures, enabledFeatures, availableFeatures, t }: FeaturesGridProps) {\r\n if (!availableFeatures || availableFeatures.length === 0) {\r\n return (\r\n <p className=\"text-[var(--text-secondary)] text-sm italic\">\r\n {t('license.page.noFeatures', 'No features enabled')}\r\n </p>\r\n );\r\n }\r\n\r\n return (\r\n <>\r\n {hasAllFeatures && (\r\n <div className=\"flex items-center gap-2 p-3 mb-4 bg-[var(--success-bg)] text-[var(--success-text)] rounded-lg border border-[var(--success-border)]\">\r\n <CheckCircle className=\"w-5 h-5\" />\r\n <span className=\"font-medium\">{t('license.page.allFeatures', 'All features enabled')}</span>\r\n </div>\r\n )}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\r\n {availableFeatures.map(({ group, features }) => (\r\n <div key={group}>\r\n <h3 className=\"text-sm font-semibold text-[var(--text-secondary)] uppercase tracking-wider mb-3\">\r\n {t(`license.group.${group}`, group)}\r\n </h3>\r\n <div className=\"space-y-2\">\r\n {features.map((code) => {\r\n const enabled = hasAllFeatures || enabledFeatures.some(\r\n f => f.toLowerCase() === code.toLowerCase()\r\n );\r\n return (\r\n <div\r\n key={code}\r\n className={`flex items-center gap-2 px-3 py-2 rounded-lg border ${\r\n enabled\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)] border-[var(--border-color)] opacity-60'\r\n }`}\r\n >\r\n {enabled\r\n ? <Unlock className=\"w-4 h-4 flex-shrink-0\" />\r\n : <Lock className=\"w-4 h-4 flex-shrink-0\" />\r\n }\r\n <span className=\"text-sm font-medium\">{t(`license.module.${code}`, code)}</span>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n {!hasAllFeatures && enabledFeatures.length === 0 && (\r\n <p className=\"text-[var(--text-secondary)] text-sm italic mt-3\">\r\n {t('license.page.noFeatures', 'No features enabled')}\r\n </p>\r\n )}\r\n </>\r\n );\r\n}\r\n\r\nfunction useValidateLicense(refreshLicense: () => Promise<void>, t: (key: string, fallback: string, opts?: Record<string, unknown>) => string) {\r\n const [isValidating, setIsValidating] = useState(false);\r\n const [validationResult, setValidationResult] = useState<{ type: 'success' | 'revoked' | 'error'; message: string } | null>(null);\r\n\r\n const handleValidate = useCallback(async () => {\r\n setIsValidating(true);\r\n setValidationResult(null);\r\n try {\r\n const result = await api.post<{ valid: boolean; revoked: boolean; error?: string }>(\r\n '/api/administration/license/validate-server'\r\n );\r\n if (result.revoked) {\r\n setValidationResult({ type: 'revoked', message: t('license.validationRevoked', 'The license has been revoked by the server.') });\r\n await refreshLicense();\r\n } else if (result.valid) {\r\n setValidationResult({ type: 'success', message: t('license.validationSuccess', 'License is valid') });\r\n await refreshLicense();\r\n } else {\r\n setValidationResult({ type: 'error', message: result.error || t('license.validationError', 'Unable to validate the license with the server.') });\r\n }\r\n } catch {\r\n setValidationResult({ type: 'error', message: t('license.validationError', 'Unable to validate the license with the server.') });\r\n } finally {\r\n setIsValidating(false);\r\n setTimeout(() => setValidationResult(null), 5000);\r\n }\r\n }, [t, refreshLicense]);\r\n\r\n const clearValidationResult = useCallback(() => setValidationResult(null), []);\r\n\r\n return { isValidating, validationResult, handleValidate, clearValidationResult };\r\n}\r\n\r\nexport function LicenseManagementPage(): ReactElement | null {\r\n const { t } = useTranslation('admin');\r\n const { license, usage, isLoading, error, refreshLicense } = useLicense();\r\n const [showActivation, setShowActivation] = useState(false);\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n const [showTrialSuccess, setShowTrialSuccess] = useState(false);\r\n const { isValidating, validationResult, handleValidate, clearValidationResult } = useValidateLicense(refreshLicense, t);\r\n\r\n // Refresh license data when the page is displayed (e.g. after creating a tenant)\r\n useEffect(() => {\r\n refreshLicense();\r\n }, [refreshLicense]);\r\n\r\n useEffect(() => {\r\n if (searchParams.get('trial') === 'success') {\r\n setShowTrialSuccess(true);\r\n const timer = setTimeout(() => {\r\n setShowTrialSuccess(false);\r\n searchParams.delete('trial');\r\n setSearchParams(searchParams, { replace: true });\r\n }, 5000);\r\n return () => clearTimeout(timer);\r\n }\r\n }, [searchParams, setSearchParams]);\r\n\r\n if (isLoading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-64\">\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 || !license) {\r\n return (\r\n <div className=\"p-6\">\r\n <div className=\"card p-6 text-center\">\r\n <AlertTriangle className=\"w-12 h-12 mx-auto mb-4 text-[var(--warning-text)]\" />\r\n <h2 className=\"text-lg font-semibold mb-2\">{t('license.page.errorTitle', 'Unable to load license')}</h2>\r\n <p className=\"text-[var(--text-secondary)] mb-4\">{error || t('license.page.errorDesc', 'License information is not available.')}</p>\r\n <button\r\n onClick={() => refreshLicense()}\r\n className=\"btn-primary px-4 py-2\"\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 hasAllFeatures = hasAllLicenseFeatures(license.enabledFeatures);\r\n const kpiCards = buildKpiCards(license, t);\r\n\r\n return (\r\n <div className=\"p-6 space-y-6\">\r\n <StatusBanners\r\n showTrialSuccess={showTrialSuccess}\r\n isInGracePeriod={license.isInGracePeriod}\r\n validationResult={validationResult}\r\n gracePeriodDays={license.gracePeriodDays}\r\n onTrialSuccessClose={() => setShowTrialSuccess(false)}\r\n onValidationResultClear={clearValidationResult}\r\n t={t}\r\n />\r\n\r\n {/* Banners handled by StatusBanners component above */}\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('license.page.title', 'License Management')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)] mt-1\">\r\n {t('license.page.subtitle', 'View and manage your platform license')}\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n <LicenseStatusBadge showDetails />\r\n <button\r\n onClick={handleValidate}\r\n disabled={isValidating}\r\n className=\"btn-secondary px-4 py-2 flex items-center gap-2\"\r\n >\r\n {isValidating\r\n ? <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n : <ShieldCheck className=\"w-4 h-4\" />\r\n }\r\n {isValidating\r\n ? t('license.validating', 'Validating...')\r\n : t('license.validate', 'Validate')}\r\n </button>\r\n <button\r\n onClick={() => setShowActivation(true)}\r\n className=\"btn-primary px-4 py-2 flex items-center gap-2\"\r\n >\r\n <Key className=\"w-4 h-4\" />\r\n {t('license.activate', 'Activate')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* KPI Cards */}\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n {kpiCards.map((card) => (\r\n <div key={card.label} className={`card p-4 border ${colorClasses[card.color]}`}>\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <card.icon className=\"w-5 h-5 opacity-80\" />\r\n <span className=\"text-sm opacity-80\">{card.label}</span>\r\n </div>\r\n <div className=\"text-2xl font-bold\">{card.value}</div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Limits Section */}\r\n <div className=\"card p-6\">\r\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\r\n <Zap className=\"w-5 h-5\" />\r\n {t('license.info.limits', 'Limits')}\r\n </h2>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\r\n <CircularGauge\r\n icon={Users}\r\n label={t('license.page.usersLimit', 'Users')}\r\n max={license.limits.users}\r\n current={usage?.activeUsers ?? 0}\r\n margin={10}\r\n t={t}\r\n />\r\n <CircularGauge\r\n icon={Building}\r\n label={t('license.page.tenantsLimit', 'Tenants (B2B)')}\r\n max={license.limits.tenants}\r\n current={usage?.activeTenants ?? 0}\r\n margin={2}\r\n t={t}\r\n />\r\n </div>\r\n {/* Custom limits from JWT */}\r\n {(() => {\r\n const standardKeys = ['users', 'tenants', 'max_instances', 'max_users'];\r\n const customEntries = Object.entries(license.limits.custom ?? {}).filter(\r\n ([key]) => !standardKeys.includes(key)\r\n );\r\n if (customEntries.length === 0) return null;\r\n return (\r\n <div className=\"mt-4 pt-4 border-t border-[var(--border-color)]\">\r\n <h3 className=\"text-sm font-medium text-[var(--text-secondary)] mb-3\">\r\n {t('license.page.customLimits', 'Custom Limits')}\r\n </h3>\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-3\">\r\n {customEntries.map(([key, value]) => (\r\n <div key={key} className=\"flex justify-between items-center py-1.5 px-3 bg-[var(--bg-secondary)] rounded-lg\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{key}</span>\r\n <span className=\"text-sm font-medium\">{value}</span>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n })()}\r\n </div>\r\n\r\n {/* Details + Subscription + Machine Section */}\r\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\r\n {/* License Details */}\r\n <div className=\"card p-6\">\r\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\r\n <Calendar className=\"w-5 h-5\" />\r\n {t('license.page.details', 'License Details')}\r\n </h2>\r\n <div className=\"space-y-3\">\r\n <DetailRow label={t('license.info.productId', 'Product')} value={license.productId} />\r\n <DetailRow label={t('license.info.company', 'Company')} value={license.companyName || '-'} />\r\n <DetailRow\r\n label={t('license.info.edition', 'Edition')}\r\n value={t(`license.edition.${license.edition.toLowerCase()}`, license.edition)}\r\n />\r\n <DetailRow\r\n label={t('license.info.status', 'Status')}\r\n value={t(`license.status.${license.status.toLowerCase()}`, license.status)}\r\n />\r\n <DetailRow\r\n label={t('license.info.activatedAt', 'Activated At')}\r\n value={formatDate(license.activatedAt)}\r\n />\r\n <DetailRow\r\n label={t('license.info.expiresAt', 'Expires At')}\r\n value={license.isPerpetual\r\n ? t('license.page.never', 'Never (Perpetual)')\r\n : formatDate(license.expiresAt)}\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Subscription Info */}\r\n <div className=\"card p-6\">\r\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\r\n <Server className=\"w-5 h-5\" />\r\n {t('license.page.subscription', 'Subscription')}\r\n </h2>\r\n <div className=\"space-y-3\">\r\n <DetailRow\r\n label={t('license.page.licenseType', 'License Type')}\r\n value={license.isPerpetual\r\n ? t('license.page.perpetual', 'Perpetual')\r\n : license.isInTrial\r\n ? t('license.edition.trial', 'Trial')\r\n : t('license.page.subscription', 'Subscription')}\r\n />\r\n <DetailRow\r\n label={t('license.page.maxUsers', 'Max Users')}\r\n value={license.limits.users > 0 ? license.limits.users.toString() : t('license.page.unlimited', 'Unlimited')}\r\n />\r\n <DetailRow\r\n label={t('license.page.gracePeriodDays', 'Grace Period')}\r\n value={license.gracePeriodDays > 0\r\n ? t('license.page.gracePeriodValue', '{{days}} days', { days: license.gracePeriodDays })\r\n : t('license.page.noGracePeriod', 'None')}\r\n />\r\n <DetailRow\r\n label={t('license.page.renewalDate', 'Renewal Date')}\r\n value={formatDate(license.renewalDate)}\r\n />\r\n <DetailRow\r\n label={t('license.page.mode', 'Mode')}\r\n value={license.isReadOnlyMode\r\n ? t('license.page.readOnly', 'Read-only')\r\n : license.isInTrial\r\n ? t('license.edition.trial', 'Trial')\r\n : t('license.page.licensed', 'Licensed')}\r\n />\r\n {license.isInGracePeriod && (\r\n <DetailRow\r\n label={t('license.page.gracePeriodStatus', 'Grace Period Status')}\r\n value={t('license.page.inGracePeriod', 'Active')}\r\n highlight=\"yellow\"\r\n />\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Machine Info */}\r\n <div className=\"card p-6\">\r\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\r\n <Monitor className=\"w-5 h-5\" />\r\n {t('license.page.machineInfo', 'Machine')}\r\n </h2>\r\n <div className=\"space-y-3\">\r\n <div className=\"py-2 border-b border-[var(--border-color)] last:border-b-0\">\r\n <div className=\"flex justify-between items-center mb-1\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{t('license.page.machineName', 'Machine Name')}</span>\r\n </div>\r\n <span className=\"text-xs font-mono text-[var(--text-primary)] break-all\">\r\n {license.machineName || '-'}\r\n </span>\r\n </div>\r\n <div className=\"py-2 border-b border-[var(--border-color)] last:border-b-0\">\r\n <div className=\"flex justify-between items-center mb-1\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{t('license.page.instanceId', 'Instance ID')}</span>\r\n </div>\r\n <span className=\"text-xs font-mono text-[var(--text-primary)] break-all\">\r\n {license.instanceId || '-'}\r\n </span>\r\n </div>\r\n <div className=\"py-2 border-b border-[var(--border-color)] last:border-b-0\">\r\n <div className=\"flex justify-between items-center mb-1\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{t('license.page.licenseId', 'License ID')}</span>\r\n </div>\r\n <span className=\"text-xs font-mono text-[var(--text-primary)] break-all\">\r\n {license.licenseServerId || '-'}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"card p-6\">\r\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\r\n <Layers className=\"w-5 h-5\" />\r\n {t('license.info.features', 'Features')}\r\n </h2>\r\n <FeaturesGrid\r\n hasAllFeatures={hasAllFeatures}\r\n enabledFeatures={license.enabledFeatures}\r\n availableFeatures={license.availableFeatures}\r\n t={t}\r\n />\r\n </div>\r\n\r\n <LicenseActivationDialog open={showActivation} onOpenChange={setShowActivation} />\r\n </div>\r\n );\r\n}\r\n\r\nfunction DetailRow({ label, value, highlight }: { label: string; value: string; highlight?: 'yellow' | 'red' | 'green' }) {\r\n const highlightClass = highlight === 'yellow'\r\n ? 'text-amber-600 dark:text-amber-400 font-semibold'\r\n : highlight === 'red'\r\n ? 'text-red-600 dark:text-red-400 font-semibold'\r\n : highlight === 'green'\r\n ? 'text-green-600 dark:text-green-400 font-semibold'\r\n : 'text-[var(--text-primary)]';\r\n\r\n return (\r\n <div className=\"flex justify-between items-center py-2 border-b border-[var(--border-color)] last:border-b-0\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">{label}</span>\r\n <span className={`text-sm font-medium ${highlightClass}`}>{value}</span>\r\n </div>\r\n );\r\n}\r\n\r\nfunction getGaugeIconColor(exceededEffective: boolean, inToleranceZone: boolean): string {\r\n if (exceededEffective) return 'text-red-500';\r\n if (inToleranceZone) return 'text-amber-500';\r\n return 'text-blue-500';\r\n}\r\n\r\nfunction getGaugeTextColor(exceededEffective: boolean, inToleranceZone: boolean): string {\r\n if (exceededEffective) return 'text-red-500';\r\n if (inToleranceZone) return 'text-amber-500';\r\n return 'text-[var(--text-primary)]';\r\n}\r\n\r\nfunction CircularGauge({ icon: Icon, label, max, current, margin = 0, t }: {\r\n icon: typeof Users;\r\n label: string;\r\n max: number;\r\n current: number;\r\n margin?: number;\r\n t: (key: string, fallback: string, opts?: Record<string, unknown>) => string;\r\n}) {\r\n const unlimited = max <= 0;\r\n const licensedLimit = max - margin;\r\n const total = max;\r\n\r\n // SVG arc parameters\r\n const size = 140;\r\n const strokeWidth = 12;\r\n const radius = (size - strokeWidth) / 2;\r\n const center = size / 2;\r\n // Arc spans 270 degrees (from 135° to 405°)\r\n const startAngle = 135;\r\n const totalArc = 270;\r\n\r\n // Percentages\r\n const usagePercent = total > 0 ? Math.min(1, current / total) : 0;\r\n const licensedPercent = total > 0 ? licensedLimit / total : 1;\r\n\r\n // Zone detection\r\n const inToleranceZone = margin > 0 && current > licensedLimit && current <= total;\r\n const exceededEffective = current > total;\r\n\r\n // Colors\r\n let usageColor = '#3b82f6'; // blue-500\r\n if (exceededEffective) usageColor = '#ef4444'; // red-500\r\n else if (inToleranceZone) usageColor = '#f59e0b'; // amber-500\r\n\r\n const toleranceTrackColor = 'rgba(245, 158, 11, 0.25)'; // amber with opacity\r\n\r\n // Helper to compute SVG arc endpoint\r\n const polarToCartesian = (angleDeg: number) => {\r\n const rad = (angleDeg * Math.PI) / 180;\r\n return {\r\n x: center + radius * Math.cos(rad),\r\n y: center + radius * Math.sin(rad),\r\n };\r\n };\r\n\r\n // Build an arc path from startAngle spanning `sweep` degrees\r\n const describeArc = (sweep: number) => {\r\n if (sweep <= 0) return '';\r\n const endAngle = startAngle + sweep;\r\n const start = polarToCartesian(startAngle);\r\n const end = polarToCartesian(endAngle);\r\n const largeArc = sweep > 180 ? 1 : 0;\r\n return `M ${start.x} ${start.y} A ${radius} ${radius} 0 ${largeArc} 1 ${end.x} ${end.y}`;\r\n };\r\n\r\n // Percentage display\r\n const displayPercent = total > 0 ? Math.round((current / licensedLimit) * 100) : 0;\r\n\r\n if (unlimited) {\r\n return (\r\n <div className=\"flex flex-col items-center gap-3 py-4\">\r\n <div className=\"relative\" style={{ width: size, height: size }}>\r\n <svg width={size} height={size}>\r\n {/* Background track */}\r\n <path\r\n d={describeArc(totalArc)}\r\n fill=\"none\"\r\n stroke=\"var(--bg-tertiary)\"\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n />\r\n {/* Full green arc for unlimited */}\r\n <path\r\n d={describeArc(totalArc)}\r\n fill=\"none\"\r\n stroke=\"#22c55e\"\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n opacity={0.5}\r\n />\r\n </svg>\r\n <div className=\"absolute inset-0 flex flex-col items-center justify-center\">\r\n <Icon className=\"w-6 h-6 text-green-500 mb-1\" />\r\n <span className=\"text-lg font-bold text-green-500\">&infin;</span>\r\n </div>\r\n </div>\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">{label}</span>\r\n <span className=\"text-xs text-[var(--text-secondary)]\">{t('license.page.unlimited', 'Unlimited')}</span>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex flex-col items-center gap-3 py-4\">\r\n <div className=\"relative\" style={{ width: size, height: size }}>\r\n <svg width={size} height={size}>\r\n {/* Background track */}\r\n <path\r\n d={describeArc(totalArc)}\r\n fill=\"none\"\r\n stroke=\"var(--bg-tertiary)\"\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n />\r\n {/* Tolerance zone: arc from licensed limit to effective limit */}\r\n {margin > 0 && (() => {\r\n const toleranceSweep = totalArc * (1 - licensedPercent);\r\n const toleranceStartAngle = startAngle + totalArc * licensedPercent;\r\n const tStart = polarToCartesian(toleranceStartAngle);\r\n const tEnd = polarToCartesian(startAngle + totalArc);\r\n const largeArc = toleranceSweep > 180 ? 1 : 0;\r\n const tolerancePath = `M ${tStart.x} ${tStart.y} A ${radius} ${radius} 0 ${largeArc} 1 ${tEnd.x} ${tEnd.y}`;\r\n return (\r\n <path\r\n d={tolerancePath}\r\n fill=\"none\"\r\n stroke={toleranceTrackColor}\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n />\r\n );\r\n })()}\r\n {/* Usage arc */}\r\n <path\r\n d={describeArc(totalArc * usagePercent)}\r\n fill=\"none\"\r\n stroke={usageColor}\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n style={{ transition: 'stroke 0.3s, d 0.3s' }}\r\n />\r\n {/* Licensed limit tick mark */}\r\n {margin > 0 && (() => {\r\n const tickAngle = startAngle + totalArc * licensedPercent;\r\n const innerR = radius - strokeWidth / 2 - 2;\r\n const outerR = radius + strokeWidth / 2 + 2;\r\n const rad = (tickAngle * Math.PI) / 180;\r\n return (\r\n <line\r\n x1={center + innerR * Math.cos(rad)}\r\n y1={center + innerR * Math.sin(rad)}\r\n x2={center + outerR * Math.cos(rad)}\r\n y2={center + outerR * Math.sin(rad)}\r\n stroke=\"var(--text-secondary)\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n />\r\n );\r\n })()}\r\n </svg>\r\n {/* Center content */}\r\n <div className=\"absolute inset-0 flex flex-col items-center justify-center\">\r\n <Icon className={`w-5 h-5 mb-0.5 ${getGaugeIconColor(exceededEffective, inToleranceZone)}`} />\r\n <span className={`text-2xl font-bold ${getGaugeTextColor(exceededEffective, inToleranceZone)}`}>\r\n {displayPercent}%\r\n </span>\r\n <span className=\"text-xs text-[var(--text-secondary)]\">\r\n {current} / {licensedLimit}\r\n </span>\r\n </div>\r\n </div>\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">{label}</span>\r\n {margin > 0 && (\r\n <span className={`text-xs ${inToleranceZone || exceededEffective ? 'text-amber-600 dark:text-amber-400' : 'text-[var(--text-secondary)]'}`}>\r\n +{margin} {t('license.page.tolerance', 'tolerance')}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["colorClasses","getStatusColor","license","getLicenseDaysColor","daysRemaining","formatDate","dateStr","buildKpiCards","statusColor","daysColor","Shield","AlertTriangle","CheckCircle","Infinity","Clock","Users","StatusBanners","showTrialSuccess","isInGracePeriod","validationResult","gracePeriodDays","onTrialSuccessClose","onValidationResultClear","t","jsxs","Fragment","jsx","X","FeaturesGrid","hasAllFeatures","enabledFeatures","availableFeatures","group","features","code","enabled","f","Unlock","Lock","useValidateLicense","refreshLicense","isValidating","setIsValidating","useState","setValidationResult","handleValidate","useCallback","result","api","clearValidationResult","LicenseManagementPage","useTranslation","usage","isLoading","error","useLicense","showActivation","setShowActivation","searchParams","setSearchParams","useSearchParams","setShowTrialSuccess","useEffect","timer","Loader2","hasAllLicenseFeatures","kpiCards","LicenseStatusBadge","ShieldCheck","Key","card","Zap","CircularGauge","Building","standardKeys","customEntries","key","value","Calendar","DetailRow","Server","Monitor","Layers","LicenseActivationDialog","label","highlight","getGaugeIconColor","exceededEffective","inToleranceZone","getGaugeTextColor","Icon","max","current","margin","unlimited","licensedLimit","total","size","strokeWidth","radius","center","startAngle","totalArc","usagePercent","licensedPercent","usageColor","toleranceTrackColor","polarToCartesian","angleDeg","rad","describeArc","sweep","endAngle","start","end","largeArc","displayPercent","toleranceSweep","toleranceStartAngle","tStart","tEnd","tolerancePath","tickAngle","innerR","outerR"],"mappings":"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"}