@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
@@ -1 +1 @@
1
- {"version":3,"file":"CreateSupportTicketPage-C2X2mfds.js","sources":["../../src/hooks/useCreateSupportTicket.ts","../../src/pages/platform/support/CreateSupportTicketPage.tsx"],"sourcesContent":["import React, { useState, useCallback, useRef } from 'react';\r\nimport { api } from '@/services/api/apiClient';\r\nimport {\r\n errorContextService,\r\n type ErrorContext,\r\n} from '@/services/support/errorContextService';\r\nimport {\r\n browserInfoService,\r\n type BrowserInfo,\r\n} from '@/services/support/browserInfoService';\r\nimport {\r\n ticketDraftService,\r\n type DraftErrorContext,\r\n type DraftAttachment,\r\n} from '@/services/support/ticketDraftService';\r\nimport type {\r\n TicketType,\r\n TicketPriority,\r\n ClientContextDto,\r\n MyTicketDetailDto,\r\n} from '@/services/api/ticketApi';\r\nimport type { UserTenantDto } from '@/services/api/adminApi';\r\n\r\nconst maxFileSize = 10 * 1024 * 1024; // 10 MB\r\nexport const allowedExtensions = [\r\n '.jpg',\r\n '.jpeg',\r\n '.png',\r\n '.gif',\r\n '.pdf',\r\n '.doc',\r\n '.docx',\r\n '.xls',\r\n '.xlsx',\r\n '.txt',\r\n '.log',\r\n '.zip',\r\n];\r\n\r\ninterface UseCreateSupportTicketOptions {\r\n draftId: string | null;\r\n effectiveTenant: UserTenantDto | null;\r\n}\r\n\r\nexport interface UseCreateSupportTicketReturn {\r\n selectedType: TicketType | null;\r\n setSelectedType: React.Dispatch<React.SetStateAction<TicketType | null>>;\r\n title: string;\r\n setTitle: React.Dispatch<React.SetStateAction<string>>;\r\n description: string;\r\n setDescription: React.Dispatch<React.SetStateAction<string>>;\r\n priority: TicketPriority;\r\n setPriority: React.Dispatch<React.SetStateAction<TicketPriority>>;\r\n submitting: boolean;\r\n error: string | null;\r\n setError: React.Dispatch<React.SetStateAction<string | null>>;\r\n errorContext: ErrorContext | null;\r\n setErrorContext: React.Dispatch<React.SetStateAction<ErrorContext | null>>;\r\n includeScreenshot: boolean;\r\n setIncludeScreenshot: React.Dispatch<React.SetStateAction<boolean>>;\r\n includeErrorLogs: boolean;\r\n setIncludeErrorLogs: React.Dispatch<React.SetStateAction<boolean>>;\r\n includeBrowserInfo: boolean;\r\n setIncludeBrowserInfo: React.Dispatch<React.SetStateAction<boolean>>;\r\n annotatedScreenshot: string | null;\r\n setAnnotatedScreenshot: React.Dispatch<React.SetStateAction<string | null>>;\r\n browserInfo: BrowserInfo | null;\r\n setBrowserInfo: React.Dispatch<React.SetStateAction<BrowserInfo | null>>;\r\n pendingFiles: File[];\r\n setPendingFiles: React.Dispatch<React.SetStateAction<File[]>>;\r\n uploadingFiles: boolean;\r\n fileInputRef: React.RefObject<HTMLInputElement | null>;\r\n showDraftSaved: boolean;\r\n setShowDraftSaved: React.Dispatch<React.SetStateAction<boolean>>;\r\n saveFailed: boolean;\r\n setSaveFailed: React.Dispatch<React.SetStateAction<boolean>>;\r\n autoSaveTimerRef: React.MutableRefObject<ReturnType<typeof setTimeout> | null>;\r\n isInitialLoadCompleteRef: React.MutableRefObject<boolean>;\r\n hasUnsavedChangesRef: React.MutableRefObject<boolean>;\r\n draftAttachmentsRef: React.MutableRefObject<DraftAttachment[]>;\r\n errorContextToDraft: (context: ErrorContext) => DraftErrorContext;\r\n draftToErrorContext: (draft: DraftErrorContext) => ErrorContext;\r\n fileToAttachment: (file: File) => Promise<DraftAttachment>;\r\n attachmentToFile: (attachment: DraftAttachment) => File;\r\n filesToAttachments: (files: File[]) => Promise<DraftAttachment[]>;\r\n saveDraftNow: () => boolean;\r\n processFiles: (files: File[]) => void;\r\n removeFile: (index: number) => void;\r\n buildClientContext: () => ClientContextDto;\r\n cleanupAfterSubmit: () => void;\r\n submitTicket: () => Promise<MyTicketDetailDto | null>;\r\n}\r\n\r\nexport function useCreateSupportTicket({\r\n draftId,\r\n effectiveTenant,\r\n}: UseCreateSupportTicketOptions): UseCreateSupportTicketReturn {\r\n const [selectedType, setSelectedType] = useState<TicketType | null>(null);\r\n const [title, setTitle] = useState('');\r\n const [description, setDescription] = useState('');\r\n const [priority, setPriority] = useState<TicketPriority>('Medium');\r\n const [submitting, setSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const [errorContext, setErrorContext] = useState<ErrorContext | null>(null);\r\n const [includeScreenshot, setIncludeScreenshot] = useState(true);\r\n const [includeErrorLogs, setIncludeErrorLogs] = useState(true);\r\n const [includeBrowserInfo, setIncludeBrowserInfo] = useState(true);\r\n const [annotatedScreenshot, setAnnotatedScreenshot] = useState<string | null>(null);\r\n const [browserInfo, setBrowserInfo] = useState<BrowserInfo | null>(null);\r\n\r\n const [pendingFiles, setPendingFiles] = useState<File[]>([]);\r\n const [uploadingFiles, setUploadingFiles] = useState(false);\r\n const fileInputRef = useRef<HTMLInputElement>(null);\r\n\r\n const [showDraftSaved, setShowDraftSaved] = useState(false);\r\n const [saveFailed, setSaveFailed] = useState(false);\r\n const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const isInitialLoadCompleteRef = useRef(false);\r\n const hasUnsavedChangesRef = useRef(false);\r\n const draftAttachmentsRef = useRef<DraftAttachment[]>([]);\r\n\r\n const errorContextToDraft = useCallback((context: ErrorContext): DraftErrorContext => ({\r\n url: context.url,\r\n timestamp: context.timestamp.toISOString(),\r\n recentErrors: context.recentErrors.map((e) => ({\r\n ...e,\r\n timestamp: e.timestamp.toISOString(),\r\n })),\r\n browserInfo: context.browserInfo,\r\n }), []);\r\n\r\n const draftToErrorContext = useCallback((draft: DraftErrorContext): ErrorContext => ({\r\n url: draft.url,\r\n timestamp: new Date(draft.timestamp),\r\n recentErrors: draft.recentErrors.map((e) => ({\r\n ...e,\r\n timestamp: new Date(e.timestamp),\r\n })),\r\n browserInfo: draft.browserInfo,\r\n }), []);\r\n\r\n const fileToAttachment = useCallback((file: File): Promise<DraftAttachment> => {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n resolve({\r\n name: file.name,\r\n type: file.type,\r\n size: file.size,\r\n data: reader.result as string,\r\n });\r\n };\r\n reader.onerror = reject;\r\n reader.readAsDataURL(file);\r\n });\r\n }, []);\r\n\r\n const attachmentToFile = useCallback((attachment: DraftAttachment): File => {\r\n const arr = attachment.data.split(',');\r\n const mime = /:(.*?);/.exec(arr[0])?.[1] || attachment.type;\r\n const bstr = atob(arr[1]);\r\n let n = bstr.length;\r\n const u8arr = new Uint8Array(n);\r\n while (n--) {\r\n u8arr[n] = bstr.charCodeAt(n);\r\n }\r\n return new window.File([u8arr], attachment.name, { type: mime });\r\n }, []);\r\n\r\n const filesToAttachments = useCallback(\r\n async (files: File[]): Promise<DraftAttachment[]> => {\r\n return Promise.all(files.map(fileToAttachment));\r\n },\r\n [fileToAttachment]\r\n );\r\n\r\n const saveDraftNow = useCallback(() => {\r\n if (!draftId) return false;\r\n\r\n const result = ticketDraftService.updateDraft(draftId, {\r\n type: selectedType,\r\n title,\r\n description,\r\n priority,\r\n includeScreenshot,\r\n includeErrorLogs,\r\n screenshot: annotatedScreenshot || undefined,\r\n errorContext: errorContext ? errorContextToDraft(errorContext) : undefined,\r\n attachments:\r\n draftAttachmentsRef.current.length > 0\r\n ? draftAttachmentsRef.current\r\n : undefined,\r\n tenantId: effectiveTenant?.id,\r\n tenantSlug: effectiveTenant?.slug,\r\n tenantName: effectiveTenant?.name,\r\n });\r\n\r\n if (result.success) {\r\n hasUnsavedChangesRef.current = false;\r\n setShowDraftSaved(true);\r\n setSaveFailed(false);\r\n setTimeout(() => setShowDraftSaved(false), 2000);\r\n } else {\r\n setSaveFailed(true);\r\n console.error('[CreateSupportTicketPage] Failed to save draft!');\r\n }\r\n\r\n return result.success;\r\n }, [\r\n draftId,\r\n selectedType,\r\n title,\r\n description,\r\n priority,\r\n includeScreenshot,\r\n includeErrorLogs,\r\n annotatedScreenshot,\r\n errorContext,\r\n errorContextToDraft,\r\n effectiveTenant,\r\n ]);\r\n\r\n const processFiles = useCallback((files: File[]) => {\r\n const validFiles: File[] = [];\r\n const errors: string[] = [];\r\n\r\n files.forEach((file) => {\r\n const extension = '.' + file.name.split('.').pop()?.toLowerCase();\r\n if (!allowedExtensions.includes(extension)) {\r\n errors.push(`${file.name}: file type not allowed`);\r\n return;\r\n }\r\n if (file.size > maxFileSize) {\r\n errors.push(`${file.name}: file too large`);\r\n return;\r\n }\r\n validFiles.push(file);\r\n });\r\n\r\n if (errors.length > 0) {\r\n setError(errors.join('\\n'));\r\n } else {\r\n setError(null);\r\n }\r\n\r\n if (validFiles.length > 0) {\r\n setPendingFiles((prev) => [...prev, ...validFiles]);\r\n }\r\n }, []);\r\n\r\n const removeFile = useCallback((index: number) => {\r\n setPendingFiles((prev) => prev.filter((_, i) => i !== index));\r\n }, []);\r\n\r\n const buildClientContext = useCallback((): ClientContextDto => {\r\n const info = browserInfoService.captureBrowserInfo();\r\n return {\r\n sourceUrl: window.location.href,\r\n browser: {\r\n name: info.browser,\r\n version: info.browserVersion,\r\n language: info.language,\r\n },\r\n os: {\r\n name: info.os,\r\n version: info.osVersion,\r\n },\r\n device: {\r\n type: info.deviceType,\r\n screenResolution: info.screenResolution,\r\n },\r\n recentErrors: includeErrorLogs\r\n ? (errorContext?.recentErrors.slice(0, 5).map((e) => ({\r\n message: e.message,\r\n stack: e.stack,\r\n component: e.component,\r\n timestamp: e.timestamp.toISOString(),\r\n })) ?? [])\r\n : [],\r\n };\r\n }, [errorContext, includeErrorLogs]);\r\n\r\n const cleanupAfterSubmit = useCallback((): void => {\r\n if (draftId) {\r\n ticketDraftService.deleteDraft(draftId);\r\n }\r\n errorContextService.clearContext();\r\n }, [draftId]);\r\n\r\n const submitTicket = useCallback(\r\n async (): Promise<MyTicketDetailDto | null> => {\r\n if (!selectedType || !title.trim() || !description.trim()) {\r\n return null;\r\n }\r\n\r\n try {\r\n setSubmitting(true);\r\n setError(null);\r\n\r\n const clientContext = buildClientContext();\r\n\r\n const tenantHeaders = effectiveTenant\r\n ? { 'X-Tenant-Slug': effectiveTenant.slug }\r\n : {};\r\n\r\n const ticket = await api.post<MyTicketDetailDto>(\r\n '/api/support/my-tickets',\r\n {\r\n title: title.trim(),\r\n description: description.trim(),\r\n type: selectedType,\r\n priority,\r\n clientContext,\r\n },\r\n { headers: tenantHeaders }\r\n );\r\n\r\n setUploadingFiles(true);\r\n\r\n if (includeScreenshot && annotatedScreenshot) {\r\n try {\r\n const response = await fetch(annotatedScreenshot);\r\n const blob = await response.blob();\r\n const file = new (globalThis as typeof window).File([blob], 'screenshot.png', {\r\n type: 'image/png',\r\n });\r\n const formData = new FormData();\r\n formData.append('file', file);\r\n await api.post(\r\n `/api/support/my-tickets/${ticket.id}/attachments`,\r\n formData,\r\n {\r\n headers: { 'Content-Type': 'multipart/form-data', ...tenantHeaders },\r\n }\r\n );\r\n } catch (err) {\r\n console.error('Failed to upload screenshot:', err);\r\n }\r\n }\r\n\r\n for (const file of pendingFiles) {\r\n try {\r\n const formData = new FormData();\r\n formData.append('file', file);\r\n await api.post(\r\n `/api/support/my-tickets/${ticket.id}/attachments`,\r\n formData,\r\n {\r\n headers: { 'Content-Type': 'multipart/form-data', ...tenantHeaders },\r\n }\r\n );\r\n } catch (err) {\r\n console.error('Failed to upload file:', file.name, err);\r\n }\r\n }\r\n\r\n cleanupAfterSubmit();\r\n return ticket;\r\n } catch (err) {\r\n setError('An error occurred');\r\n return null;\r\n } finally {\r\n setSubmitting(false);\r\n setUploadingFiles(false);\r\n }\r\n },\r\n [\r\n selectedType,\r\n title,\r\n description,\r\n priority,\r\n buildClientContext,\r\n effectiveTenant,\r\n includeScreenshot,\r\n annotatedScreenshot,\r\n pendingFiles,\r\n cleanupAfterSubmit,\r\n ]\r\n );\r\n\r\n return {\r\n selectedType,\r\n setSelectedType,\r\n title,\r\n setTitle,\r\n description,\r\n setDescription,\r\n priority,\r\n setPriority,\r\n submitting,\r\n error,\r\n setError,\r\n errorContext,\r\n setErrorContext,\r\n includeScreenshot,\r\n setIncludeScreenshot,\r\n includeErrorLogs,\r\n setIncludeErrorLogs,\r\n includeBrowserInfo,\r\n setIncludeBrowserInfo,\r\n annotatedScreenshot,\r\n setAnnotatedScreenshot,\r\n browserInfo,\r\n setBrowserInfo,\r\n pendingFiles,\r\n setPendingFiles,\r\n uploadingFiles,\r\n fileInputRef,\r\n showDraftSaved,\r\n setShowDraftSaved,\r\n saveFailed,\r\n setSaveFailed,\r\n autoSaveTimerRef,\r\n isInitialLoadCompleteRef,\r\n hasUnsavedChangesRef,\r\n draftAttachmentsRef,\r\n errorContextToDraft,\r\n draftToErrorContext,\r\n fileToAttachment,\r\n attachmentToFile,\r\n filesToAttachments,\r\n saveDraftNow,\r\n processFiles,\r\n removeFile,\r\n buildClientContext,\r\n cleanupAfterSubmit,\r\n submitTicket,\r\n };\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate, useSearchParams } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n ArrowLeft, Headset, Bug, Lightbulb, AppWindow, HelpCircle, MessageSquare,\r\n Loader2, AlertTriangle, Send, Camera, Monitor,\r\n Paperclip, X, FileText, Image as ImageIcon, File, Sparkles, Check, Trash2, Info, ExternalLink,\r\n Building2\r\n} from 'lucide-react';\r\nimport { type TicketType, type TicketPriority } from '@/services/api/ticketApi';\r\nimport { errorContextService } from '@/services/support/errorContextService';\r\nimport { browserInfoService } from '@/services/support/browserInfoService';\r\nimport { ScreenshotAnnotator } from '@/components/platform/support/ScreenshotAnnotator';\r\nimport { ticketDraftService } from '@/services/support/ticketDraftService';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { useTicketingProvider } from '@/hooks/useTicketingProvider';\r\nimport { useCreateSupportTicket, allowedExtensions } from '@/hooks/useCreateSupportTicket';\r\nimport type { UserTenantDto } from '@/services/api/adminApi';\r\n\r\nconst ticketTypes: { value: TicketType; labelKey: string; descriptionKey: string; icon: React.ElementType }[] = [\r\n { value: 'Bug', labelKey: 'types.Bug', descriptionKey: 'typeDescriptions.Bug', icon: Bug },\r\n { value: 'FeatureRequest', labelKey: 'types.FeatureRequest', descriptionKey: 'typeDescriptions.FeatureRequest', icon: Lightbulb },\r\n { value: 'Suggestion', labelKey: 'types.Suggestion', descriptionKey: 'typeDescriptions.Suggestion', icon: Sparkles },\r\n { value: 'ApplicationRequest', labelKey: 'types.ApplicationRequest', descriptionKey: 'typeDescriptions.ApplicationRequest', icon: AppWindow },\r\n { value: 'Support', labelKey: 'types.Support', descriptionKey: 'typeDescriptions.Support', icon: MessageSquare },\r\n { value: 'Question', labelKey: 'types.Question', descriptionKey: 'typeDescriptions.Question', icon: HelpCircle },\r\n];\r\n\r\nconst priorityOptions: { value: TicketPriority; labelKey: string; descriptionKey: string }[] = [\r\n { value: 'Low', labelKey: 'priorities.Low', descriptionKey: 'priorityDescriptions.Low' },\r\n { value: 'Medium', labelKey: 'priorities.Medium', descriptionKey: 'priorityDescriptions.Medium' },\r\n { value: 'High', labelKey: 'priorities.High', descriptionKey: 'priorityDescriptions.High' },\r\n { value: 'Critical', labelKey: 'priorities.Critical', descriptionKey: 'priorityDescriptions.Critical' },\r\n];\r\n\r\nexport function CreateSupportTicketPage(): ReactElement | null {\r\n const { t } = useTranslation(['support', 'common']);\r\n const navigate = useNavigate();\r\n const [searchParams] = useSearchParams();\r\n const { currentTenant, userTenants, isGlobalView } = useTenant();\r\n const { isGlpi, glpiBaseUrl } = useTicketingProvider();\r\n\r\n // When in global view (no tenant selected), allow user to pick a tenant for the ticket\r\n const [selectedTenantForTicket, setSelectedTenantForTicket] = useState<UserTenantDto | null>(null);\r\n const [showTenantPicker, setShowTenantPicker] = useState(false);\r\n const [showDiscardConfirm, setShowDiscardConfirm] = useState(false);\r\n\r\n // The effective tenant: either the global current tenant or the locally selected one\r\n const effectiveTenant = currentTenant ?? selectedTenantForTicket;\r\n\r\n // Show tenant picker on mount when no tenant is selected\r\n useEffect(() => {\r\n if (!currentTenant && isGlobalView && userTenants.length > 0) {\r\n setShowTenantPicker(true);\r\n }\r\n }, [currentTenant, isGlobalView, userTenants.length]);\r\n\r\n const [step, setStep] = useState(1);\r\n const [isDragging, setIsDragging] = useState(false);\r\n\r\n const draftId = searchParams.get('draft');\r\n\r\n // Use hook for form logic\r\n const {\r\n selectedType,\r\n setSelectedType,\r\n title,\r\n setTitle,\r\n description,\r\n setDescription,\r\n priority,\r\n setPriority,\r\n submitting,\r\n error,\r\n setError: _setError,\r\n errorContext,\r\n setErrorContext,\r\n includeScreenshot,\r\n setIncludeScreenshot,\r\n includeErrorLogs,\r\n setIncludeErrorLogs,\r\n includeBrowserInfo,\r\n setIncludeBrowserInfo,\r\n annotatedScreenshot,\r\n setAnnotatedScreenshot,\r\n browserInfo,\r\n setBrowserInfo,\r\n pendingFiles,\r\n setPendingFiles,\r\n uploadingFiles,\r\n fileInputRef,\r\n showDraftSaved,\r\n setShowDraftSaved: _setShowDraftSaved,\r\n saveFailed,\r\n setSaveFailed: _setSaveFailed,\r\n autoSaveTimerRef,\r\n isInitialLoadCompleteRef,\r\n hasUnsavedChangesRef,\r\n draftAttachmentsRef,\r\n errorContextToDraft: _errorContextToDraft,\r\n draftToErrorContext,\r\n fileToAttachment: _fileToAttachment,\r\n attachmentToFile,\r\n filesToAttachments,\r\n saveDraftNow,\r\n processFiles,\r\n removeFile,\r\n buildClientContext: _buildClientContext,\r\n cleanupAfterSubmit: _cleanupAfterSubmit,\r\n submitTicket,\r\n } = useCreateSupportTicket({\r\n draftId,\r\n effectiveTenant,\r\n });\r\n\r\n // Load and apply draft data\r\n const applyDraftData = (draft: ReturnType<typeof ticketDraftService.getDraft>) => {\r\n if (!draft) return { hasType: false, hasScreenshot: false, hasErrorContext: false };\r\n\r\n setTitle(draft.title);\r\n setDescription(draft.description);\r\n setPriority(draft.priority);\r\n setIncludeScreenshot(draft.includeScreenshot);\r\n setIncludeErrorLogs(draft.includeErrorLogs);\r\n\r\n if (draft.type) {\r\n setSelectedType(draft.type);\r\n setStep(2);\r\n }\r\n\r\n if (draft.screenshot) {\r\n setAnnotatedScreenshot(draft.screenshot);\r\n }\r\n\r\n if (draft.errorContext) {\r\n setErrorContext(draftToErrorContext(draft.errorContext));\r\n }\r\n\r\n if (draft.attachments?.length) {\r\n const restoredFiles = draft.attachments.map(attachmentToFile);\r\n setPendingFiles(restoredFiles);\r\n draftAttachmentsRef.current = draft.attachments;\r\n }\r\n\r\n // Restore tenant selection from draft\r\n if (draft.tenantId && draft.tenantSlug) {\r\n const matchingTenant = userTenants.find(t => t.id === draft.tenantId);\r\n if (matchingTenant) {\r\n setSelectedTenantForTicket(matchingTenant);\r\n }\r\n }\r\n\r\n return {\r\n hasType: !!draft.type,\r\n hasScreenshot: !!draft.screenshot,\r\n hasErrorContext: !!draft.errorContext,\r\n };\r\n };\r\n\r\n // Load session context (error logs and screenshot from page navigation)\r\n const applySessionContext = (draftState: ReturnType<typeof applyDraftData>) => {\r\n const sessionContext = errorContextService.loadContext();\r\n if (!sessionContext) return;\r\n\r\n if (!draftState.hasErrorContext) {\r\n setErrorContext(sessionContext);\r\n }\r\n\r\n if (!draftState.hasScreenshot && sessionContext.screenshot) {\r\n setAnnotatedScreenshot(sessionContext.screenshot);\r\n }\r\n\r\n if (sessionContext.recentErrors.length > 0 && !draftState.hasType) {\r\n setSelectedType('Bug');\r\n setPriority('High');\r\n }\r\n };\r\n\r\n // Load draft and error context on mount\r\n useEffect(() => {\r\n const draftState = draftId ? applyDraftData(ticketDraftService.getDraft(draftId)) : { hasType: false, hasScreenshot: false, hasErrorContext: false };\r\n applySessionContext(draftState);\r\n\r\n const info = browserInfoService.captureBrowserInfo();\r\n setBrowserInfo(info);\r\n\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(() => {\r\n isInitialLoadCompleteRef.current = true;\r\n });\r\n });\r\n\r\n return () => {\r\n errorContextService.clearContext();\r\n };\r\n }, [draftId, draftToErrorContext, attachmentToFile]);\r\n\r\n // Update draftAttachmentsRef whenever pendingFiles changes\r\n useEffect(() => {\r\n if (pendingFiles.length === 0) {\r\n draftAttachmentsRef.current = [];\r\n return;\r\n }\r\n\r\n // Convert files to attachments asynchronously\r\n filesToAttachments(pendingFiles)\r\n .then((attachments) => {\r\n draftAttachmentsRef.current = attachments;\r\n })\r\n .catch((err) => {\r\n console.error(\r\n '[CreateSupportTicketPage] Failed to convert files to attachments:',\r\n err\r\n );\r\n });\r\n }, [pendingFiles, filesToAttachments]);\r\n\r\n // Debounced auto-save when data changes\r\n useEffect(() => {\r\n if (!isInitialLoadCompleteRef.current || !draftId) return;\r\n\r\n hasUnsavedChangesRef.current = true;\r\n\r\n if (autoSaveTimerRef.current) {\r\n clearTimeout(autoSaveTimerRef.current);\r\n }\r\n\r\n autoSaveTimerRef.current = setTimeout(() => {\r\n saveDraftNow();\r\n }, 1000);\r\n\r\n return () => {\r\n if (autoSaveTimerRef.current) {\r\n clearTimeout(autoSaveTimerRef.current);\r\n }\r\n };\r\n }, [\r\n selectedType,\r\n title,\r\n description,\r\n priority,\r\n includeScreenshot,\r\n includeErrorLogs,\r\n includeBrowserInfo,\r\n annotatedScreenshot,\r\n errorContext,\r\n pendingFiles,\r\n draftId,\r\n saveDraftNow,\r\n ]);\r\n\r\n // Save on unmount (when navigating away)\r\n useEffect(() => {\r\n const handleBeforeUnload = () => {\r\n if (hasUnsavedChangesRef.current && draftId) {\r\n saveDraftNow();\r\n // Don't show browser prompt, we're auto-saving\r\n }\r\n };\r\n\r\n window.addEventListener('beforeunload', handleBeforeUnload);\r\n\r\n return () => {\r\n window.removeEventListener('beforeunload', handleBeforeUnload);\r\n // Save on cleanup (component unmount / navigation)\r\n if (hasUnsavedChangesRef.current && draftId && isInitialLoadCompleteRef.current) {\r\n // Direct call since we can't use async in cleanup\r\n ticketDraftService.updateDraft(draftId, {\r\n type: selectedType,\r\n title,\r\n description,\r\n priority,\r\n includeScreenshot,\r\n includeErrorLogs,\r\n screenshot: annotatedScreenshot || undefined,\r\n errorContext: errorContext\r\n ? {\r\n url: errorContext.url,\r\n timestamp: errorContext.timestamp.toISOString(),\r\n recentErrors: errorContext.recentErrors.map((e) => ({\r\n ...e,\r\n timestamp: e.timestamp.toISOString(),\r\n })),\r\n browserInfo: errorContext.browserInfo,\r\n }\r\n : undefined,\r\n attachments:\r\n draftAttachmentsRef.current.length > 0\r\n ? draftAttachmentsRef.current\r\n : undefined,\r\n });\r\n }\r\n };\r\n }, [\r\n draftId,\r\n selectedType,\r\n title,\r\n description,\r\n priority,\r\n includeScreenshot,\r\n includeErrorLogs,\r\n annotatedScreenshot,\r\n errorContext,\r\n saveDraftNow,\r\n ]);\r\n\r\n const handleAnnotatedScreenshot = (dataUrl: string) => {\r\n setAnnotatedScreenshot(dataUrl);\r\n };\r\n\r\n // Recapture screenshot (for reset functionality)\r\n const handleRecaptureScreenshot = async () => {\r\n try {\r\n const newContext = await errorContextService.captureContext();\r\n if (newContext.screenshot) {\r\n setAnnotatedScreenshot(newContext.screenshot);\r\n // Also update error context with fresh data\r\n setErrorContext(newContext);\r\n }\r\n } catch (err) {\r\n console.error('[CreateSupportTicketPage] Error recapturing screenshot:', err);\r\n }\r\n };\r\n\r\n // Discard draft and navigate away\r\n const handleDiscardDraft = () => {\r\n if (draftId) {\r\n // Clear any pending auto-save\r\n if (autoSaveTimerRef.current) {\r\n clearTimeout(autoSaveTimerRef.current);\r\n autoSaveTimerRef.current = null;\r\n }\r\n // Delete the draft\r\n ticketDraftService.deleteDraft(draftId);\r\n }\r\n // Navigate to tickets page\r\n navigate('/support/my-tickets?tab=submitted');\r\n };\r\n\r\n const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const files = Array.from(e.target.files || []);\r\n processFiles(files);\r\n if (fileInputRef.current) {\r\n fileInputRef.current.value = '';\r\n }\r\n };\r\n\r\n // Drag and drop handlers\r\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n };\r\n\r\n const handleDragEnter = (e: React.DragEvent<HTMLDivElement>) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n setIsDragging(true);\r\n };\r\n\r\n const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n // Only set isDragging to false if we're leaving the drop zone entirely\r\n const rect = e.currentTarget.getBoundingClientRect();\r\n const x = e.clientX;\r\n const y = e.clientY;\r\n if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) {\r\n setIsDragging(false);\r\n }\r\n };\r\n\r\n const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n setIsDragging(false);\r\n\r\n const files = Array.from(e.dataTransfer.files);\r\n if (files.length > 0) {\r\n processFiles(files);\r\n }\r\n };\r\n\r\n const formatFileSize = (bytes: number): string => {\r\n if (bytes < 1024) return `${bytes} B`;\r\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\r\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\r\n };\r\n\r\n const getFileIcon = (fileName: string) => {\r\n const ext = fileName.split('.').pop()?.toLowerCase();\r\n if (['jpg', 'jpeg', 'png', 'gif'].includes(ext || '')) return ImageIcon;\r\n if (['pdf', 'doc', 'docx', 'txt'].includes(ext || '')) return FileText;\r\n return File;\r\n };\r\n\r\n const handleSubmit = async () => {\r\n if (!selectedType || !title.trim() || !description.trim()) return;\r\n\r\n if (!effectiveTenant) {\r\n // No tenant selected at all - show picker modal\r\n setShowTenantPicker(true);\r\n return;\r\n }\r\n\r\n const ticket = await submitTicket();\r\n if (ticket) {\r\n navigate(`/support/my-tickets/${ticket.id}?tab=submitted`);\r\n }\r\n };\r\n\r\n const renderTypeSelection = () => (\r\n <div className=\"space-y-4\">\r\n <h2 className=\"text-lg font-semibold mb-4\">{t('tickets.createFlow.selectType')}</h2>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {ticketTypes.map((type) => (\r\n <button\r\n key={type.value}\r\n onClick={() => {\r\n setSelectedType(type.value);\r\n setStep(2);\r\n }}\r\n className={`card p-4 text-left hover:shadow-md transition-shadow ${\r\n selectedType === type.value ? 'ring-2 ring-[var(--color-primary-600)]' : ''\r\n }`}\r\n >\r\n <div className=\"flex items-start gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <type.icon className=\"w-6 h-6\" />\r\n </div>\r\n <div>\r\n <h3 className=\"font-medium\">{t(`tickets.${type.labelKey}`)}</h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{t(`tickets.${type.descriptionKey}`, type.value)}</p>\r\n </div>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n\r\n const renderSystemInfo = () => {\r\n if (!browserInfo) return null;\r\n return (\r\n <div className=\"card p-4 bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"font-medium flex items-center gap-2\">\r\n <Monitor className=\"w-5 h-5 text-[var(--color-primary-600)]\" />\r\n {t('tickets.create.systemInfo', 'System Information')}\r\n </h3>\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={includeBrowserInfo}\r\n onChange={(e) => setIncludeBrowserInfo(e.target.checked)}\r\n className=\"rounded border-[var(--border-color)]\"\r\n />\r\n <span className=\"text-xs text-[var(--text-secondary)]\">\r\n {t('tickets.create.includeSystemInfo', 'Include in ticket')}\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <div className={`grid grid-cols-2 md:grid-cols-3 gap-3 text-sm ${!includeBrowserInfo ? 'opacity-50' : ''}`}>\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">{t('tickets.create.browser', 'Browser')}</span>\r\n <span className=\"font-medium\">{browserInfo.browser} {browserInfo.browserVersion}</span>\r\n </div>\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">{t('tickets.create.os', 'OS')}</span>\r\n <span className=\"font-medium\">{browserInfo.os} {browserInfo.osVersion}</span>\r\n </div>\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">{t('tickets.create.device', 'Device')}</span>\r\n <span className=\"font-medium\">{browserInfo.deviceType}</span>\r\n </div>\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">{t('tickets.create.screen', 'Screen')}</span>\r\n <span className=\"font-medium\">{browserInfo.screenResolution}</span>\r\n </div>\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">{t('tickets.create.language', 'Language')}</span>\r\n <span className=\"font-medium\">{browserInfo.language}</span>\r\n </div>\r\n {errorContext && (\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">URL</span>\r\n <span className=\"font-medium font-mono text-xs truncate block\">{errorContext.url}</span>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderScreenshot = () => {\r\n if (!annotatedScreenshot) return null;\r\n return (\r\n <div className=\"card p-4\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"font-medium flex items-center gap-2\">\r\n <Camera className=\"w-5 h-5 text-[var(--color-primary-600)]\" />\r\n {t('tickets.createFlow.screenshot')}\r\n </h3>\r\n <label className=\"flex items-center gap-2 text-sm\">\r\n <input\r\n type=\"checkbox\"\r\n checked={includeScreenshot}\r\n onChange={(e) => setIncludeScreenshot(e.target.checked)}\r\n className=\"rounded border-[var(--border-color)]\"\r\n />\r\n {t('tickets.createFlow.includeScreenshot')}\r\n </label>\r\n </div>\r\n\r\n {includeScreenshot ? (\r\n <ScreenshotAnnotator\r\n screenshot={annotatedScreenshot}\r\n onAnnotatedScreenshot={handleAnnotatedScreenshot}\r\n onReset={handleRecaptureScreenshot}\r\n />\r\n ) : (\r\n <div className=\"p-8 text-center text-[var(--text-secondary)] bg-[var(--bg-secondary)] rounded-lg\">\r\n <Camera className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n <p className=\"text-sm\">{t('tickets.createFlow.screenshotExcluded', 'Screenshot will not be included')}</p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n };\r\n\r\n const renderErrorLogs = () => {\r\n if (!errorContext || errorContext.recentErrors.length === 0) return null;\r\n return (\r\n <div className=\"card p-4\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"font-medium flex items-center gap-2\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n {t('tickets.createFlow.recentErrors')} ({errorContext.recentErrors.length})\r\n </h3>\r\n <label className=\"flex items-center gap-2 text-sm\">\r\n <input\r\n type=\"checkbox\"\r\n checked={includeErrorLogs}\r\n onChange={(e) => setIncludeErrorLogs(e.target.checked)}\r\n className=\"rounded border-[var(--border-color)]\"\r\n />\r\n {t('tickets.createFlow.includeErrorLogs')}\r\n </label>\r\n </div>\r\n\r\n {includeErrorLogs ? (\r\n <div className=\"bg-[var(--bg-secondary)] rounded-lg p-4 text-sm font-mono max-h-48 overflow-y-auto space-y-2\">\r\n {errorContext.recentErrors.slice(0, 10).map((err, index) => (\r\n <div key={`error-${index}`} className=\"p-2 bg-[var(--error-bg)]/50 rounded text-[var(--error-text)]\">\r\n <div className=\"flex items-center gap-2 text-xs opacity-70 mb-1\">\r\n <span>{err.timestamp.toLocaleTimeString()}</span>\r\n {err.component && <span className=\"px-1.5 py-0.5 bg-[var(--bg-primary)] rounded\">{err.component}</span>}\r\n </div>\r\n <div className=\"break-words\">{err.message}</div>\r\n </div>\r\n ))}\r\n </div>\r\n ) : (\r\n <div className=\"p-4 text-center text-[var(--text-secondary)] bg-[var(--bg-secondary)] rounded-lg\">\r\n <p className=\"text-sm\">{t('tickets.createFlow.logsExcluded', 'Error logs will not be included')}</p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n };\r\n\r\n const renderCapturedContext = () => {\r\n if (!errorContext && !browserInfo) return null;\r\n\r\n return (\r\n <div className=\"space-y-6 mb-6\">\r\n {renderSystemInfo()}\r\n {renderScreenshot()}\r\n {renderErrorLogs()}\r\n </div>\r\n );\r\n };\r\n\r\n const renderAttachmentSection = () => {\r\n return (\r\n <div>\r\n <label className=\"block text-sm font-medium mb-2\">\r\n {t('tickets.createFlow.attachments')}\r\n </label>\r\n <div\r\n className={`border-2 border-dashed rounded-lg p-6 text-center transition-colors cursor-pointer ${\r\n isDragging\r\n ? 'border-[var(--color-primary-600)] bg-[var(--color-primary-600)]/10'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-primary-600)]'\r\n }`}\r\n onClick={() => fileInputRef.current?.click()}\r\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); fileInputRef.current?.click(); } }}\r\n role=\"button\"\r\n tabIndex={0}\r\n onDragOver={handleDragOver}\r\n onDragEnter={handleDragEnter}\r\n onDragLeave={handleDragLeave}\r\n onDrop={handleDrop}\r\n >\r\n <input\r\n ref={fileInputRef}\r\n type=\"file\"\r\n multiple\r\n onChange={handleFileSelect}\r\n accept={allowedExtensions.join(',')}\r\n className=\"hidden\"\r\n />\r\n <Paperclip className={`w-8 h-8 mx-auto mb-2 ${isDragging ? 'text-[var(--color-primary-600)]' : 'text-[var(--text-secondary)]'}`} />\r\n <p className={`text-sm ${isDragging ? 'text-[var(--color-primary-600)] font-medium' : 'text-[var(--text-secondary)]'}`}>\r\n {isDragging\r\n ? t('tickets.createFlow.dropFilesNow', 'Drop files here')\r\n : t('tickets.createFlow.dropFilesHere')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {t('tickets.createFlow.maxFileSize', { size: '10 MB' })}\r\n </p>\r\n </div>\r\n\r\n {pendingFiles.length > 0 && (\r\n <div className=\"mt-3 space-y-2\">\r\n {pendingFiles.map((file, index) => {\r\n const FileIcon = getFileIcon(file.name);\r\n return (\r\n <div\r\n key={`file-${file.name}-${index}`}\r\n className=\"flex items-center gap-3 p-3 bg-[var(--bg-secondary)] rounded-lg\"\r\n >\r\n <FileIcon className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium truncate\">{file.name}</p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">{formatFileSize(file.size)}</p>\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n removeFile(index);\r\n }}\r\n className=\"p-1 hover:bg-[var(--bg-hover)] rounded\"\r\n >\r\n <X className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n </button>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n };\r\n\r\n const renderForm = () => {\r\n const currentTypeConfig = ticketTypes.find(tt => tt.value === selectedType);\r\n const CurrentTypeIcon = currentTypeConfig?.icon || Bug;\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"flex items-center gap-4 mb-6\">\r\n <button onClick={() => setStep(1)} className=\"btn btn-ghost p-2\">\r\n <ArrowLeft className=\"w-5 h-5\" />\r\n </button>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--bg-secondary)]\">\r\n <CurrentTypeIcon className=\"w-5 h-5\" />\r\n </div>\r\n <select\r\n value={selectedType || ''}\r\n onChange={(e) => setSelectedType(e.target.value as TicketType)}\r\n className=\"input text-lg font-semibold bg-transparent border-none p-0 pr-8 cursor-pointer hover:text-[var(--color-primary-600)] focus:ring-0\"\r\n >\r\n {ticketTypes.map((type) => (\r\n <option key={type.value} value={type.value}>\r\n {t(`tickets.${type.labelKey}`)}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tickets.createFlow.fillDetails')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {renderCapturedContext()}\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium mb-2\">\r\n {t('tickets.form.title')} <span className=\"text-[var(--error-text)]\">*</span>\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={title}\r\n onChange={(e) => setTitle(e.target.value)}\r\n placeholder={t('tickets.form.titlePlaceholder')}\r\n className=\"input w-full\"\r\n maxLength={200}\r\n />\r\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {title.length}/200\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium mb-2\">\r\n {t('tickets.form.description')} <span className=\"text-[var(--error-text)]\">*</span>\r\n </label>\r\n <textarea\r\n value={description}\r\n onChange={(e) => setDescription(e.target.value)}\r\n placeholder={t('tickets.form.descriptionPlaceholder')}\r\n className=\"input w-full h-40\"\r\n maxLength={5000}\r\n />\r\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {description.length}/5000\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium mb-2\">{t('tickets.form.priority')}</label>\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-2\">\r\n {priorityOptions.map((option) => (\r\n <button\r\n key={option.value}\r\n type=\"button\"\r\n onClick={() => setPriority(option.value)}\r\n className={`p-3 rounded-lg border text-center transition-colors ${\r\n priority === option.value\r\n ? 'border-[var(--color-primary-600)] bg-[var(--color-primary-600)]/10'\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div className=\"font-medium\">{t(`tickets.${option.labelKey}`)}</div>\r\n <div className=\"text-xs text-[var(--text-secondary)]\">{t(`tickets.${option.descriptionKey}`, option.value)}</div>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {renderAttachmentSection()}\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-lg bg-[var(--error-bg)] text-[var(--error-text)] flex items-center gap-2\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n {error}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex items-center justify-between pt-4 border-t border-[var(--border-color)]\">\r\n <button onClick={() => setStep(1)} className=\"btn btn-secondary\">\r\n {t('common:actions.back')}\r\n </button>\r\n <button\r\n onClick={handleSubmit}\r\n disabled={!title.trim() || !description.trim() || submitting || uploadingFiles}\r\n className=\"btn btn-primary\"\r\n >\r\n {(submitting || uploadingFiles) ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin mr-2\" />\r\n ) : (\r\n <Send className=\"w-4 h-4 mr-2\" />\r\n )}\r\n {(() => {\r\n if (uploadingFiles) return t('tickets.createFlow.uploadingFiles');\r\n if (submitting) return t('common:actions.submitting');\r\n return t('common:actions.submit');\r\n })()}\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"max-w-3xl mx-auto\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('title', 'Support'), href: '/support' },\r\n { label: t('list.title', 'Tickets'), href: '/support/tickets' },\r\n { label: t('create.title', 'Create Ticket') }\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-center gap-4 mb-6 mt-6\">\r\n <button onClick={() => navigate(-1)} className=\"btn btn-ghost p-2\">\r\n <ArrowLeft className=\"w-5 h-5\" />\r\n </button>\r\n <div className=\"flex-1\">\r\n <h1 className=\"text-2xl font-bold flex items-center gap-2\">\r\n <Headset className=\"w-6 h-6\" />\r\n {t('tickets.createFlow.title')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {t('tickets.createFlow.subtitle')}\r\n </p>\r\n </div>\r\n {draftId && (\r\n <button\r\n onClick={() => setShowDiscardConfirm(true)}\r\n className=\"btn btn-ghost text-[var(--error-text)] hover:bg-[var(--error-bg)]\"\r\n title={t('common:drafts.discard')}\r\n >\r\n <Trash2 className=\"w-4 h-4 mr-2\" />\r\n {t('common:drafts.discard')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {isGlpi ? (\r\n <div className=\"mb-6 p-4 rounded-lg bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <div className=\"flex items-center gap-3 mb-3\">\r\n <Info className=\"w-5 h-5 text-[var(--info-text)] flex-shrink-0\" />\r\n <p className=\"font-medium text-[var(--info-text)]\">\r\n {t('glpi.cannotCreateTicket', 'Tickets are managed by GLPI. Please create tickets directly in GLPI.')}\r\n </p>\r\n </div>\r\n {glpiBaseUrl && (\r\n <a\r\n href={glpiBaseUrl}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"btn btn-primary inline-flex items-center gap-2\"\r\n >\r\n <ExternalLink className=\"w-4 h-4\" />\r\n {t('glpi.openGlpi')}\r\n </a>\r\n )}\r\n </div>\r\n ) : (\r\n <>\r\n <div className=\"flex items-center gap-4 mb-8\">\r\n <div className={`flex items-center gap-2 ${step >= 1 ? 'text-[var(--color-primary-600)]' : 'text-[var(--text-secondary)]'}`}>\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center ${\r\n step >= 1 ? 'bg-[var(--color-primary-600)] text-white' : 'bg-[var(--bg-secondary)]'\r\n }`}>\r\n 1\r\n </div>\r\n <span className=\"font-medium\">{t('tickets.createFlow.step1')}</span>\r\n </div>\r\n <div className={`flex-1 h-0.5 ${step >= 2 ? 'bg-[var(--color-primary-600)]' : 'bg-[var(--border-color)]'}`} />\r\n <div className={`flex items-center gap-2 ${step >= 2 ? 'text-[var(--color-primary-600)]' : 'text-[var(--text-secondary)]'}`}>\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center ${\r\n step >= 2 ? 'bg-[var(--color-primary-600)] text-white' : 'bg-[var(--bg-secondary)]'\r\n }`}>\r\n 2\r\n </div>\r\n <span className=\"font-medium\">{t('tickets.createFlow.step2')}</span>\r\n </div>\r\n\r\n {/* Draft auto-save indicator */}\r\n {saveFailed ? (\r\n <div className=\"ml-auto flex items-center gap-1.5 text-xs text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-3.5 h-3.5\" />\r\n <span>{t('common:errors.generic')}</span>\r\n </div>\r\n ) : (\r\n <div className={`ml-auto flex items-center gap-1.5 text-xs text-[var(--success-text)] transition-opacity duration-300 ${\r\n showDraftSaved ? 'opacity-100' : 'opacity-0'\r\n }`}>\r\n <Check className=\"w-3.5 h-3.5\" />\r\n <span>{t('common:drafts.autoSaved')}</span>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Tenant context indicator (shown when using locally selected tenant in global view) */}\r\n {selectedTenantForTicket && !currentTenant && (\r\n <div className=\"mb-4 p-3 rounded-lg bg-[var(--info-bg)] border border-[var(--info-border)] flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2 text-sm text-[var(--info-text)]\">\r\n <Building2 className=\"w-4 h-4\" />\r\n <span>{t('support:tickets.tenantPicker.creatingFor')}</span>\r\n <span className=\"font-semibold\">{selectedTenantForTicket.name}</span>\r\n </div>\r\n <button\r\n onClick={() => setShowTenantPicker(true)}\r\n className=\"text-xs text-[var(--info-text)] underline hover:no-underline\"\r\n >\r\n {t('common:actions.change')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n <div className=\"card p-6\">\r\n {step === 1 && renderTypeSelection()}\r\n {step === 2 && renderForm()}\r\n </div>\r\n\r\n {/* Tenant picker modal (shown in global view when no tenant selected) */}\r\n {showTenantPicker && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4\">\r\n <div className=\"card w-full max-w-md p-6\">\r\n <div className=\"flex items-center gap-3 mb-4\">\r\n <div className=\"w-10 h-10 rounded-full bg-[var(--info-bg)] flex items-center justify-center\">\r\n <Building2 className=\"w-5 h-5 text-[var(--info-text)]\" />\r\n </div>\r\n <div>\r\n <h2 className=\"text-xl font-bold\">{t('support:tickets.tenantPicker.title')}</h2>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{t('support:tickets.tenantPicker.description')}</p>\r\n </div>\r\n </div>\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto\">\r\n {userTenants\r\n .filter(tenant => tenant.status === 'Active')\r\n .map(tenant => (\r\n <button\r\n key={tenant.id}\r\n onClick={() => {\r\n setSelectedTenantForTicket(tenant);\r\n setShowTenantPicker(false);\r\n // Immediately persist tenant to draft\r\n if (draftId) {\r\n ticketDraftService.updateDraft(draftId, {\r\n tenantId: tenant.id,\r\n tenantSlug: tenant.slug,\r\n tenantName: tenant.name,\r\n });\r\n }\r\n }}\r\n className={`w-full p-3 rounded-lg border text-left transition-colors hover:bg-[var(--bg-hover)] ${\r\n selectedTenantForTicket?.id === tenant.id\r\n ? 'border-[var(--color-primary-600)] bg-[var(--color-primary-600)]/10'\r\n : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3\">\r\n <Building2 className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"font-medium truncate\">{tenant.name}</div>\r\n {tenant.organisationName && (\r\n <div className=\"text-xs text-[var(--text-secondary)] truncate\">{tenant.organisationName}</div>\r\n )}\r\n </div>\r\n <span className={`text-xs px-2 py-0.5 rounded-full ${\r\n tenant.type === 'Personal'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n }`}>\r\n {tenant.type === 'Personal' ? t('common:tenant.personal') : t('common:tenant.business')}\r\n </span>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n <div className=\"flex justify-end gap-3 mt-4 pt-4 border-t border-[var(--border-color)]\">\r\n <button\r\n onClick={() => {\r\n setShowTenantPicker(false);\r\n if (!effectiveTenant) navigate(-1);\r\n }}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:actions.cancel')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Discard confirmation modal */}\r\n {showDiscardConfirm && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4\">\r\n <div className=\"card w-full max-w-md p-6\">\r\n <div className=\"flex items-center gap-3 mb-4\">\r\n <div className=\"w-10 h-10 rounded-full bg-[var(--error-bg)] flex items-center justify-center\">\r\n <Trash2 className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n </div>\r\n <h2 className=\"text-xl font-bold\">{t('common:drafts.discardConfirmTitle')}</h2>\r\n </div>\r\n <p className=\"text-[var(--text-secondary)] mb-6\">\r\n {t('common:drafts.discardConfirmMessage')}\r\n </p>\r\n <div className=\"flex justify-end gap-3\">\r\n <button\r\n onClick={() => setShowDiscardConfirm(false)}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:actions.cancel')}\r\n </button>\r\n <button\r\n onClick={() => {\r\n setShowDiscardConfirm(false);\r\n handleDiscardDraft();\r\n }}\r\n className=\"btn bg-[var(--error-bg)] text-[var(--error-text)] hover:opacity-90\"\r\n >\r\n <Trash2 className=\"w-4 h-4 mr-2\" />\r\n {t('common:drafts.discardConfirm')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["maxFileSize","allowedExtensions","useCreateSupportTicket","draftId","effectiveTenant","selectedType","setSelectedType","useState","title","setTitle","description","setDescription","priority","setPriority","submitting","setSubmitting","error","setError","errorContext","setErrorContext","includeScreenshot","setIncludeScreenshot","includeErrorLogs","setIncludeErrorLogs","includeBrowserInfo","setIncludeBrowserInfo","annotatedScreenshot","setAnnotatedScreenshot","browserInfo","setBrowserInfo","pendingFiles","setPendingFiles","uploadingFiles","setUploadingFiles","fileInputRef","useRef","showDraftSaved","setShowDraftSaved","saveFailed","setSaveFailed","autoSaveTimerRef","isInitialLoadCompleteRef","hasUnsavedChangesRef","draftAttachmentsRef","errorContextToDraft","useCallback","context","e","draftToErrorContext","draft","fileToAttachment","file","resolve","reject","reader","attachmentToFile","attachment","arr","mime","bstr","n","u8arr","filesToAttachments","files","saveDraftNow","result","ticketDraftService","processFiles","validFiles","errors","extension","prev","removeFile","index","_","buildClientContext","info","browserInfoService","cleanupAfterSubmit","errorContextService","submitTicket","clientContext","tenantHeaders","ticket","api","blob","formData","err","ticketTypes","Bug","Lightbulb","Sparkles","AppWindow","MessageSquare","HelpCircle","priorityOptions","CreateSupportTicketPage","t","useTranslation","navigate","useNavigate","searchParams","useSearchParams","currentTenant","userTenants","isGlobalView","useTenant","isGlpi","glpiBaseUrl","useTicketingProvider","selectedTenantForTicket","setSelectedTenantForTicket","showTenantPicker","setShowTenantPicker","showDiscardConfirm","setShowDiscardConfirm","useEffect","step","setStep","isDragging","setIsDragging","applyDraftData","restoredFiles","matchingTenant","applySessionContext","draftState","sessionContext","attachments","handleBeforeUnload","handleAnnotatedScreenshot","dataUrl","handleRecaptureScreenshot","newContext","handleDiscardDraft","handleFileSelect","handleDragOver","handleDragEnter","handleDragLeave","rect","x","y","handleDrop","formatFileSize","bytes","getFileIcon","fileName","ext","ImageIcon","FileText","File","handleSubmit","renderTypeSelection","jsxs","jsx","type","renderSystemInfo","Monitor","renderScreenshot","Camera","ScreenshotAnnotator","renderErrorLogs","AlertTriangle","renderCapturedContext","renderAttachmentSection","Paperclip","FileIcon","X","renderForm","CurrentTypeIcon","tt","ArrowLeft","option","Loader2","Send","Breadcrumb","Headset","Trash2","Info","ExternalLink","Fragment","Check","Building2","tenant"],"mappings":"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"}
1
+ {"version":3,"file":"CreateSupportTicketPage-DDiv79-p.js","sources":["../../src/hooks/useCreateSupportTicket.ts","../../src/pages/platform/support/CreateSupportTicketPage.tsx"],"sourcesContent":["import React, { useState, useCallback, useRef } from 'react';\r\nimport { api } from '@/services/api/apiClient';\r\nimport {\r\n errorContextService,\r\n type ErrorContext,\r\n} from '@/services/support/errorContextService';\r\nimport {\r\n browserInfoService,\r\n type BrowserInfo,\r\n} from '@/services/support/browserInfoService';\r\nimport {\r\n ticketDraftService,\r\n type DraftErrorContext,\r\n type DraftAttachment,\r\n} from '@/services/support/ticketDraftService';\r\nimport type {\r\n TicketType,\r\n TicketPriority,\r\n ClientContextDto,\r\n MyTicketDetailDto,\r\n} from '@/services/api/ticketApi';\r\nimport type { UserTenantDto } from '@/services/api/adminApi';\r\n\r\nconst maxFileSize = 10 * 1024 * 1024; // 10 MB\r\nexport const allowedExtensions = [\r\n '.jpg',\r\n '.jpeg',\r\n '.png',\r\n '.gif',\r\n '.pdf',\r\n '.doc',\r\n '.docx',\r\n '.xls',\r\n '.xlsx',\r\n '.txt',\r\n '.log',\r\n '.zip',\r\n];\r\n\r\ninterface UseCreateSupportTicketOptions {\r\n draftId: string | null;\r\n effectiveTenant: UserTenantDto | null;\r\n}\r\n\r\nexport interface UseCreateSupportTicketReturn {\r\n selectedType: TicketType | null;\r\n setSelectedType: React.Dispatch<React.SetStateAction<TicketType | null>>;\r\n title: string;\r\n setTitle: React.Dispatch<React.SetStateAction<string>>;\r\n description: string;\r\n setDescription: React.Dispatch<React.SetStateAction<string>>;\r\n priority: TicketPriority;\r\n setPriority: React.Dispatch<React.SetStateAction<TicketPriority>>;\r\n submitting: boolean;\r\n error: string | null;\r\n setError: React.Dispatch<React.SetStateAction<string | null>>;\r\n errorContext: ErrorContext | null;\r\n setErrorContext: React.Dispatch<React.SetStateAction<ErrorContext | null>>;\r\n includeScreenshot: boolean;\r\n setIncludeScreenshot: React.Dispatch<React.SetStateAction<boolean>>;\r\n includeErrorLogs: boolean;\r\n setIncludeErrorLogs: React.Dispatch<React.SetStateAction<boolean>>;\r\n includeBrowserInfo: boolean;\r\n setIncludeBrowserInfo: React.Dispatch<React.SetStateAction<boolean>>;\r\n annotatedScreenshot: string | null;\r\n setAnnotatedScreenshot: React.Dispatch<React.SetStateAction<string | null>>;\r\n browserInfo: BrowserInfo | null;\r\n setBrowserInfo: React.Dispatch<React.SetStateAction<BrowserInfo | null>>;\r\n pendingFiles: File[];\r\n setPendingFiles: React.Dispatch<React.SetStateAction<File[]>>;\r\n uploadingFiles: boolean;\r\n fileInputRef: React.RefObject<HTMLInputElement | null>;\r\n showDraftSaved: boolean;\r\n setShowDraftSaved: React.Dispatch<React.SetStateAction<boolean>>;\r\n saveFailed: boolean;\r\n setSaveFailed: React.Dispatch<React.SetStateAction<boolean>>;\r\n autoSaveTimerRef: React.MutableRefObject<ReturnType<typeof setTimeout> | null>;\r\n isInitialLoadCompleteRef: React.MutableRefObject<boolean>;\r\n hasUnsavedChangesRef: React.MutableRefObject<boolean>;\r\n draftAttachmentsRef: React.MutableRefObject<DraftAttachment[]>;\r\n errorContextToDraft: (context: ErrorContext) => DraftErrorContext;\r\n draftToErrorContext: (draft: DraftErrorContext) => ErrorContext;\r\n fileToAttachment: (file: File) => Promise<DraftAttachment>;\r\n attachmentToFile: (attachment: DraftAttachment) => File;\r\n filesToAttachments: (files: File[]) => Promise<DraftAttachment[]>;\r\n saveDraftNow: () => boolean;\r\n processFiles: (files: File[]) => void;\r\n removeFile: (index: number) => void;\r\n buildClientContext: () => ClientContextDto;\r\n cleanupAfterSubmit: () => void;\r\n submitTicket: () => Promise<MyTicketDetailDto | null>;\r\n}\r\n\r\nexport function useCreateSupportTicket({\r\n draftId,\r\n effectiveTenant,\r\n}: UseCreateSupportTicketOptions): UseCreateSupportTicketReturn {\r\n const [selectedType, setSelectedType] = useState<TicketType | null>(null);\r\n const [title, setTitle] = useState('');\r\n const [description, setDescription] = useState('');\r\n const [priority, setPriority] = useState<TicketPriority>('Medium');\r\n const [submitting, setSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const [errorContext, setErrorContext] = useState<ErrorContext | null>(null);\r\n const [includeScreenshot, setIncludeScreenshot] = useState(true);\r\n const [includeErrorLogs, setIncludeErrorLogs] = useState(true);\r\n const [includeBrowserInfo, setIncludeBrowserInfo] = useState(true);\r\n const [annotatedScreenshot, setAnnotatedScreenshot] = useState<string | null>(null);\r\n const [browserInfo, setBrowserInfo] = useState<BrowserInfo | null>(null);\r\n\r\n const [pendingFiles, setPendingFiles] = useState<File[]>([]);\r\n const [uploadingFiles, setUploadingFiles] = useState(false);\r\n const fileInputRef = useRef<HTMLInputElement>(null);\r\n\r\n const [showDraftSaved, setShowDraftSaved] = useState(false);\r\n const [saveFailed, setSaveFailed] = useState(false);\r\n const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const isInitialLoadCompleteRef = useRef(false);\r\n const hasUnsavedChangesRef = useRef(false);\r\n const draftAttachmentsRef = useRef<DraftAttachment[]>([]);\r\n\r\n const errorContextToDraft = useCallback((context: ErrorContext): DraftErrorContext => ({\r\n url: context.url,\r\n timestamp: context.timestamp.toISOString(),\r\n recentErrors: context.recentErrors.map((e) => ({\r\n ...e,\r\n timestamp: e.timestamp.toISOString(),\r\n })),\r\n browserInfo: context.browserInfo,\r\n }), []);\r\n\r\n const draftToErrorContext = useCallback((draft: DraftErrorContext): ErrorContext => ({\r\n url: draft.url,\r\n timestamp: new Date(draft.timestamp),\r\n recentErrors: draft.recentErrors.map((e) => ({\r\n ...e,\r\n timestamp: new Date(e.timestamp),\r\n })),\r\n browserInfo: draft.browserInfo,\r\n }), []);\r\n\r\n const fileToAttachment = useCallback((file: File): Promise<DraftAttachment> => {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n resolve({\r\n name: file.name,\r\n type: file.type,\r\n size: file.size,\r\n data: reader.result as string,\r\n });\r\n };\r\n reader.onerror = reject;\r\n reader.readAsDataURL(file);\r\n });\r\n }, []);\r\n\r\n const attachmentToFile = useCallback((attachment: DraftAttachment): File => {\r\n const arr = attachment.data.split(',');\r\n const mime = /:(.*?);/.exec(arr[0])?.[1] || attachment.type;\r\n const bstr = atob(arr[1]);\r\n let n = bstr.length;\r\n const u8arr = new Uint8Array(n);\r\n while (n--) {\r\n u8arr[n] = bstr.charCodeAt(n);\r\n }\r\n return new window.File([u8arr], attachment.name, { type: mime });\r\n }, []);\r\n\r\n const filesToAttachments = useCallback(\r\n async (files: File[]): Promise<DraftAttachment[]> => {\r\n return Promise.all(files.map(fileToAttachment));\r\n },\r\n [fileToAttachment]\r\n );\r\n\r\n const saveDraftNow = useCallback(() => {\r\n if (!draftId) return false;\r\n\r\n const result = ticketDraftService.updateDraft(draftId, {\r\n type: selectedType,\r\n title,\r\n description,\r\n priority,\r\n includeScreenshot,\r\n includeErrorLogs,\r\n screenshot: annotatedScreenshot || undefined,\r\n errorContext: errorContext ? errorContextToDraft(errorContext) : undefined,\r\n attachments:\r\n draftAttachmentsRef.current.length > 0\r\n ? draftAttachmentsRef.current\r\n : undefined,\r\n tenantId: effectiveTenant?.id,\r\n tenantSlug: effectiveTenant?.slug,\r\n tenantName: effectiveTenant?.name,\r\n });\r\n\r\n if (result.success) {\r\n hasUnsavedChangesRef.current = false;\r\n setShowDraftSaved(true);\r\n setSaveFailed(false);\r\n setTimeout(() => setShowDraftSaved(false), 2000);\r\n } else {\r\n setSaveFailed(true);\r\n console.error('[CreateSupportTicketPage] Failed to save draft!');\r\n }\r\n\r\n return result.success;\r\n }, [\r\n draftId,\r\n selectedType,\r\n title,\r\n description,\r\n priority,\r\n includeScreenshot,\r\n includeErrorLogs,\r\n annotatedScreenshot,\r\n errorContext,\r\n errorContextToDraft,\r\n effectiveTenant,\r\n ]);\r\n\r\n const processFiles = useCallback((files: File[]) => {\r\n const validFiles: File[] = [];\r\n const errors: string[] = [];\r\n\r\n files.forEach((file) => {\r\n const extension = '.' + file.name.split('.').pop()?.toLowerCase();\r\n if (!allowedExtensions.includes(extension)) {\r\n errors.push(`${file.name}: file type not allowed`);\r\n return;\r\n }\r\n if (file.size > maxFileSize) {\r\n errors.push(`${file.name}: file too large`);\r\n return;\r\n }\r\n validFiles.push(file);\r\n });\r\n\r\n if (errors.length > 0) {\r\n setError(errors.join('\\n'));\r\n } else {\r\n setError(null);\r\n }\r\n\r\n if (validFiles.length > 0) {\r\n setPendingFiles((prev) => [...prev, ...validFiles]);\r\n }\r\n }, []);\r\n\r\n const removeFile = useCallback((index: number) => {\r\n setPendingFiles((prev) => prev.filter((_, i) => i !== index));\r\n }, []);\r\n\r\n const buildClientContext = useCallback((): ClientContextDto => {\r\n const info = browserInfoService.captureBrowserInfo();\r\n return {\r\n sourceUrl: window.location.href,\r\n browser: {\r\n name: info.browser,\r\n version: info.browserVersion,\r\n language: info.language,\r\n },\r\n os: {\r\n name: info.os,\r\n version: info.osVersion,\r\n },\r\n device: {\r\n type: info.deviceType,\r\n screenResolution: info.screenResolution,\r\n },\r\n recentErrors: includeErrorLogs\r\n ? (errorContext?.recentErrors.slice(0, 5).map((e) => ({\r\n message: e.message,\r\n stack: e.stack,\r\n component: e.component,\r\n timestamp: e.timestamp.toISOString(),\r\n })) ?? [])\r\n : [],\r\n };\r\n }, [errorContext, includeErrorLogs]);\r\n\r\n const cleanupAfterSubmit = useCallback((): void => {\r\n if (draftId) {\r\n ticketDraftService.deleteDraft(draftId);\r\n }\r\n errorContextService.clearContext();\r\n }, [draftId]);\r\n\r\n const submitTicket = useCallback(\r\n async (): Promise<MyTicketDetailDto | null> => {\r\n if (!selectedType || !title.trim() || !description.trim()) {\r\n return null;\r\n }\r\n\r\n try {\r\n setSubmitting(true);\r\n setError(null);\r\n\r\n const clientContext = buildClientContext();\r\n\r\n const tenantHeaders = effectiveTenant\r\n ? { 'X-Tenant-Slug': effectiveTenant.slug }\r\n : {};\r\n\r\n const ticket = await api.post<MyTicketDetailDto>(\r\n '/api/support/my-tickets',\r\n {\r\n title: title.trim(),\r\n description: description.trim(),\r\n type: selectedType,\r\n priority,\r\n clientContext,\r\n },\r\n { headers: tenantHeaders }\r\n );\r\n\r\n setUploadingFiles(true);\r\n\r\n if (includeScreenshot && annotatedScreenshot) {\r\n try {\r\n const response = await fetch(annotatedScreenshot);\r\n const blob = await response.blob();\r\n const file = new (globalThis as typeof window).File([blob], 'screenshot.png', {\r\n type: 'image/png',\r\n });\r\n const formData = new FormData();\r\n formData.append('file', file);\r\n await api.post(\r\n `/api/support/my-tickets/${ticket.id}/attachments`,\r\n formData,\r\n {\r\n headers: { 'Content-Type': 'multipart/form-data', ...tenantHeaders },\r\n }\r\n );\r\n } catch (err) {\r\n console.error('Failed to upload screenshot:', err);\r\n }\r\n }\r\n\r\n for (const file of pendingFiles) {\r\n try {\r\n const formData = new FormData();\r\n formData.append('file', file);\r\n await api.post(\r\n `/api/support/my-tickets/${ticket.id}/attachments`,\r\n formData,\r\n {\r\n headers: { 'Content-Type': 'multipart/form-data', ...tenantHeaders },\r\n }\r\n );\r\n } catch (err) {\r\n console.error('Failed to upload file:', file.name, err);\r\n }\r\n }\r\n\r\n cleanupAfterSubmit();\r\n return ticket;\r\n } catch (err) {\r\n setError('An error occurred');\r\n return null;\r\n } finally {\r\n setSubmitting(false);\r\n setUploadingFiles(false);\r\n }\r\n },\r\n [\r\n selectedType,\r\n title,\r\n description,\r\n priority,\r\n buildClientContext,\r\n effectiveTenant,\r\n includeScreenshot,\r\n annotatedScreenshot,\r\n pendingFiles,\r\n cleanupAfterSubmit,\r\n ]\r\n );\r\n\r\n return {\r\n selectedType,\r\n setSelectedType,\r\n title,\r\n setTitle,\r\n description,\r\n setDescription,\r\n priority,\r\n setPriority,\r\n submitting,\r\n error,\r\n setError,\r\n errorContext,\r\n setErrorContext,\r\n includeScreenshot,\r\n setIncludeScreenshot,\r\n includeErrorLogs,\r\n setIncludeErrorLogs,\r\n includeBrowserInfo,\r\n setIncludeBrowserInfo,\r\n annotatedScreenshot,\r\n setAnnotatedScreenshot,\r\n browserInfo,\r\n setBrowserInfo,\r\n pendingFiles,\r\n setPendingFiles,\r\n uploadingFiles,\r\n fileInputRef,\r\n showDraftSaved,\r\n setShowDraftSaved,\r\n saveFailed,\r\n setSaveFailed,\r\n autoSaveTimerRef,\r\n isInitialLoadCompleteRef,\r\n hasUnsavedChangesRef,\r\n draftAttachmentsRef,\r\n errorContextToDraft,\r\n draftToErrorContext,\r\n fileToAttachment,\r\n attachmentToFile,\r\n filesToAttachments,\r\n saveDraftNow,\r\n processFiles,\r\n removeFile,\r\n buildClientContext,\r\n cleanupAfterSubmit,\r\n submitTicket,\r\n };\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate, useSearchParams } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n ArrowLeft, Headset, Bug, Lightbulb, AppWindow, HelpCircle, MessageSquare,\r\n Loader2, AlertTriangle, Send, Camera, Monitor,\r\n Paperclip, X, FileText, Image as ImageIcon, File, Sparkles, Check, Trash2, Info, ExternalLink,\r\n Building2\r\n} from 'lucide-react';\r\nimport { type TicketType, type TicketPriority } from '@/services/api/ticketApi';\r\nimport { errorContextService } from '@/services/support/errorContextService';\r\nimport { browserInfoService } from '@/services/support/browserInfoService';\r\nimport { ScreenshotAnnotator } from '@/components/platform/support/ScreenshotAnnotator';\r\nimport { ticketDraftService } from '@/services/support/ticketDraftService';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { useTicketingProvider } from '@/hooks/useTicketingProvider';\r\nimport { useCreateSupportTicket, allowedExtensions } from '@/hooks/useCreateSupportTicket';\r\nimport type { UserTenantDto } from '@/services/api/adminApi';\r\n\r\nconst ticketTypes: { value: TicketType; labelKey: string; descriptionKey: string; icon: React.ElementType }[] = [\r\n { value: 'Bug', labelKey: 'types.Bug', descriptionKey: 'typeDescriptions.Bug', icon: Bug },\r\n { value: 'FeatureRequest', labelKey: 'types.FeatureRequest', descriptionKey: 'typeDescriptions.FeatureRequest', icon: Lightbulb },\r\n { value: 'Suggestion', labelKey: 'types.Suggestion', descriptionKey: 'typeDescriptions.Suggestion', icon: Sparkles },\r\n { value: 'ApplicationRequest', labelKey: 'types.ApplicationRequest', descriptionKey: 'typeDescriptions.ApplicationRequest', icon: AppWindow },\r\n { value: 'Support', labelKey: 'types.Support', descriptionKey: 'typeDescriptions.Support', icon: MessageSquare },\r\n { value: 'Question', labelKey: 'types.Question', descriptionKey: 'typeDescriptions.Question', icon: HelpCircle },\r\n];\r\n\r\nconst priorityOptions: { value: TicketPriority; labelKey: string; descriptionKey: string }[] = [\r\n { value: 'Low', labelKey: 'priorities.Low', descriptionKey: 'priorityDescriptions.Low' },\r\n { value: 'Medium', labelKey: 'priorities.Medium', descriptionKey: 'priorityDescriptions.Medium' },\r\n { value: 'High', labelKey: 'priorities.High', descriptionKey: 'priorityDescriptions.High' },\r\n { value: 'Critical', labelKey: 'priorities.Critical', descriptionKey: 'priorityDescriptions.Critical' },\r\n];\r\n\r\nexport function CreateSupportTicketPage(): ReactElement | null {\r\n const { t } = useTranslation(['support', 'common']);\r\n const navigate = useNavigate();\r\n const [searchParams] = useSearchParams();\r\n const { currentTenant, userTenants, isGlobalView } = useTenant();\r\n const { isGlpi, glpiBaseUrl } = useTicketingProvider();\r\n\r\n // When in global view (no tenant selected), allow user to pick a tenant for the ticket\r\n const [selectedTenantForTicket, setSelectedTenantForTicket] = useState<UserTenantDto | null>(null);\r\n const [showTenantPicker, setShowTenantPicker] = useState(false);\r\n const [showDiscardConfirm, setShowDiscardConfirm] = useState(false);\r\n\r\n // The effective tenant: either the global current tenant or the locally selected one\r\n const effectiveTenant = currentTenant ?? selectedTenantForTicket;\r\n\r\n // Show tenant picker on mount when no tenant is selected\r\n useEffect(() => {\r\n if (!currentTenant && isGlobalView && userTenants.length > 0) {\r\n setShowTenantPicker(true);\r\n }\r\n }, [currentTenant, isGlobalView, userTenants.length]);\r\n\r\n const [step, setStep] = useState(1);\r\n const [isDragging, setIsDragging] = useState(false);\r\n\r\n const draftId = searchParams.get('draft');\r\n\r\n // Use hook for form logic\r\n const {\r\n selectedType,\r\n setSelectedType,\r\n title,\r\n setTitle,\r\n description,\r\n setDescription,\r\n priority,\r\n setPriority,\r\n submitting,\r\n error,\r\n setError: _setError,\r\n errorContext,\r\n setErrorContext,\r\n includeScreenshot,\r\n setIncludeScreenshot,\r\n includeErrorLogs,\r\n setIncludeErrorLogs,\r\n includeBrowserInfo,\r\n setIncludeBrowserInfo,\r\n annotatedScreenshot,\r\n setAnnotatedScreenshot,\r\n browserInfo,\r\n setBrowserInfo,\r\n pendingFiles,\r\n setPendingFiles,\r\n uploadingFiles,\r\n fileInputRef,\r\n showDraftSaved,\r\n setShowDraftSaved: _setShowDraftSaved,\r\n saveFailed,\r\n setSaveFailed: _setSaveFailed,\r\n autoSaveTimerRef,\r\n isInitialLoadCompleteRef,\r\n hasUnsavedChangesRef,\r\n draftAttachmentsRef,\r\n errorContextToDraft: _errorContextToDraft,\r\n draftToErrorContext,\r\n fileToAttachment: _fileToAttachment,\r\n attachmentToFile,\r\n filesToAttachments,\r\n saveDraftNow,\r\n processFiles,\r\n removeFile,\r\n buildClientContext: _buildClientContext,\r\n cleanupAfterSubmit: _cleanupAfterSubmit,\r\n submitTicket,\r\n } = useCreateSupportTicket({\r\n draftId,\r\n effectiveTenant,\r\n });\r\n\r\n // Load and apply draft data\r\n const applyDraftData = (draft: ReturnType<typeof ticketDraftService.getDraft>) => {\r\n if (!draft) return { hasType: false, hasScreenshot: false, hasErrorContext: false };\r\n\r\n setTitle(draft.title);\r\n setDescription(draft.description);\r\n setPriority(draft.priority);\r\n setIncludeScreenshot(draft.includeScreenshot);\r\n setIncludeErrorLogs(draft.includeErrorLogs);\r\n\r\n if (draft.type) {\r\n setSelectedType(draft.type);\r\n setStep(2);\r\n }\r\n\r\n if (draft.screenshot) {\r\n setAnnotatedScreenshot(draft.screenshot);\r\n }\r\n\r\n if (draft.errorContext) {\r\n setErrorContext(draftToErrorContext(draft.errorContext));\r\n }\r\n\r\n if (draft.attachments?.length) {\r\n const restoredFiles = draft.attachments.map(attachmentToFile);\r\n setPendingFiles(restoredFiles);\r\n draftAttachmentsRef.current = draft.attachments;\r\n }\r\n\r\n // Restore tenant selection from draft\r\n if (draft.tenantId && draft.tenantSlug) {\r\n const matchingTenant = userTenants.find(t => t.id === draft.tenantId);\r\n if (matchingTenant) {\r\n setSelectedTenantForTicket(matchingTenant);\r\n }\r\n }\r\n\r\n return {\r\n hasType: !!draft.type,\r\n hasScreenshot: !!draft.screenshot,\r\n hasErrorContext: !!draft.errorContext,\r\n };\r\n };\r\n\r\n // Load session context (error logs and screenshot from page navigation)\r\n const applySessionContext = (draftState: ReturnType<typeof applyDraftData>) => {\r\n const sessionContext = errorContextService.loadContext();\r\n if (!sessionContext) return;\r\n\r\n if (!draftState.hasErrorContext) {\r\n setErrorContext(sessionContext);\r\n }\r\n\r\n if (!draftState.hasScreenshot && sessionContext.screenshot) {\r\n setAnnotatedScreenshot(sessionContext.screenshot);\r\n }\r\n\r\n if (sessionContext.recentErrors.length > 0 && !draftState.hasType) {\r\n setSelectedType('Bug');\r\n setPriority('High');\r\n }\r\n };\r\n\r\n // Load draft and error context on mount\r\n useEffect(() => {\r\n const draftState = draftId ? applyDraftData(ticketDraftService.getDraft(draftId)) : { hasType: false, hasScreenshot: false, hasErrorContext: false };\r\n applySessionContext(draftState);\r\n\r\n const info = browserInfoService.captureBrowserInfo();\r\n setBrowserInfo(info);\r\n\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(() => {\r\n isInitialLoadCompleteRef.current = true;\r\n });\r\n });\r\n\r\n return () => {\r\n errorContextService.clearContext();\r\n };\r\n }, [draftId, draftToErrorContext, attachmentToFile]);\r\n\r\n // Update draftAttachmentsRef whenever pendingFiles changes\r\n useEffect(() => {\r\n if (pendingFiles.length === 0) {\r\n draftAttachmentsRef.current = [];\r\n return;\r\n }\r\n\r\n // Convert files to attachments asynchronously\r\n filesToAttachments(pendingFiles)\r\n .then((attachments) => {\r\n draftAttachmentsRef.current = attachments;\r\n })\r\n .catch((err) => {\r\n console.error(\r\n '[CreateSupportTicketPage] Failed to convert files to attachments:',\r\n err\r\n );\r\n });\r\n }, [pendingFiles, filesToAttachments]);\r\n\r\n // Debounced auto-save when data changes\r\n useEffect(() => {\r\n if (!isInitialLoadCompleteRef.current || !draftId) return;\r\n\r\n hasUnsavedChangesRef.current = true;\r\n\r\n if (autoSaveTimerRef.current) {\r\n clearTimeout(autoSaveTimerRef.current);\r\n }\r\n\r\n autoSaveTimerRef.current = setTimeout(() => {\r\n saveDraftNow();\r\n }, 1000);\r\n\r\n return () => {\r\n if (autoSaveTimerRef.current) {\r\n clearTimeout(autoSaveTimerRef.current);\r\n }\r\n };\r\n }, [\r\n selectedType,\r\n title,\r\n description,\r\n priority,\r\n includeScreenshot,\r\n includeErrorLogs,\r\n includeBrowserInfo,\r\n annotatedScreenshot,\r\n errorContext,\r\n pendingFiles,\r\n draftId,\r\n saveDraftNow,\r\n ]);\r\n\r\n // Save on unmount (when navigating away)\r\n useEffect(() => {\r\n const handleBeforeUnload = () => {\r\n if (hasUnsavedChangesRef.current && draftId) {\r\n saveDraftNow();\r\n // Don't show browser prompt, we're auto-saving\r\n }\r\n };\r\n\r\n window.addEventListener('beforeunload', handleBeforeUnload);\r\n\r\n return () => {\r\n window.removeEventListener('beforeunload', handleBeforeUnload);\r\n // Save on cleanup (component unmount / navigation)\r\n if (hasUnsavedChangesRef.current && draftId && isInitialLoadCompleteRef.current) {\r\n // Direct call since we can't use async in cleanup\r\n ticketDraftService.updateDraft(draftId, {\r\n type: selectedType,\r\n title,\r\n description,\r\n priority,\r\n includeScreenshot,\r\n includeErrorLogs,\r\n screenshot: annotatedScreenshot || undefined,\r\n errorContext: errorContext\r\n ? {\r\n url: errorContext.url,\r\n timestamp: errorContext.timestamp.toISOString(),\r\n recentErrors: errorContext.recentErrors.map((e) => ({\r\n ...e,\r\n timestamp: e.timestamp.toISOString(),\r\n })),\r\n browserInfo: errorContext.browserInfo,\r\n }\r\n : undefined,\r\n attachments:\r\n draftAttachmentsRef.current.length > 0\r\n ? draftAttachmentsRef.current\r\n : undefined,\r\n });\r\n }\r\n };\r\n }, [\r\n draftId,\r\n selectedType,\r\n title,\r\n description,\r\n priority,\r\n includeScreenshot,\r\n includeErrorLogs,\r\n annotatedScreenshot,\r\n errorContext,\r\n saveDraftNow,\r\n ]);\r\n\r\n const handleAnnotatedScreenshot = (dataUrl: string) => {\r\n setAnnotatedScreenshot(dataUrl);\r\n };\r\n\r\n // Recapture screenshot (for reset functionality)\r\n const handleRecaptureScreenshot = async () => {\r\n try {\r\n const newContext = await errorContextService.captureContext();\r\n if (newContext.screenshot) {\r\n setAnnotatedScreenshot(newContext.screenshot);\r\n // Also update error context with fresh data\r\n setErrorContext(newContext);\r\n }\r\n } catch (err) {\r\n console.error('[CreateSupportTicketPage] Error recapturing screenshot:', err);\r\n }\r\n };\r\n\r\n // Discard draft and navigate away\r\n const handleDiscardDraft = () => {\r\n if (draftId) {\r\n // Clear any pending auto-save\r\n if (autoSaveTimerRef.current) {\r\n clearTimeout(autoSaveTimerRef.current);\r\n autoSaveTimerRef.current = null;\r\n }\r\n // Delete the draft\r\n ticketDraftService.deleteDraft(draftId);\r\n }\r\n // Navigate to tickets page\r\n navigate('/support/my-tickets?tab=submitted');\r\n };\r\n\r\n const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const files = Array.from(e.target.files || []);\r\n processFiles(files);\r\n if (fileInputRef.current) {\r\n fileInputRef.current.value = '';\r\n }\r\n };\r\n\r\n // Drag and drop handlers\r\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n };\r\n\r\n const handleDragEnter = (e: React.DragEvent<HTMLDivElement>) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n setIsDragging(true);\r\n };\r\n\r\n const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n // Only set isDragging to false if we're leaving the drop zone entirely\r\n const rect = e.currentTarget.getBoundingClientRect();\r\n const x = e.clientX;\r\n const y = e.clientY;\r\n if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) {\r\n setIsDragging(false);\r\n }\r\n };\r\n\r\n const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n setIsDragging(false);\r\n\r\n const files = Array.from(e.dataTransfer.files);\r\n if (files.length > 0) {\r\n processFiles(files);\r\n }\r\n };\r\n\r\n const formatFileSize = (bytes: number): string => {\r\n if (bytes < 1024) return `${bytes} B`;\r\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\r\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\r\n };\r\n\r\n const getFileIcon = (fileName: string) => {\r\n const ext = fileName.split('.').pop()?.toLowerCase();\r\n if (['jpg', 'jpeg', 'png', 'gif'].includes(ext || '')) return ImageIcon;\r\n if (['pdf', 'doc', 'docx', 'txt'].includes(ext || '')) return FileText;\r\n return File;\r\n };\r\n\r\n const handleSubmit = async () => {\r\n if (!selectedType || !title.trim() || !description.trim()) return;\r\n\r\n if (!effectiveTenant) {\r\n // No tenant selected at all - show picker modal\r\n setShowTenantPicker(true);\r\n return;\r\n }\r\n\r\n const ticket = await submitTicket();\r\n if (ticket) {\r\n navigate(`/support/my-tickets/${ticket.id}?tab=submitted`);\r\n }\r\n };\r\n\r\n const renderTypeSelection = () => (\r\n <div className=\"space-y-4\">\r\n <h2 className=\"text-lg font-semibold mb-4\">{t('tickets.createFlow.selectType')}</h2>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {ticketTypes.map((type) => (\r\n <button\r\n key={type.value}\r\n onClick={() => {\r\n setSelectedType(type.value);\r\n setStep(2);\r\n }}\r\n className={`card p-4 text-left hover:shadow-md transition-shadow ${\r\n selectedType === type.value ? 'ring-2 ring-[var(--color-primary-600)]' : ''\r\n }`}\r\n >\r\n <div className=\"flex items-start gap-4\">\r\n <div className=\"p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <type.icon className=\"w-6 h-6\" />\r\n </div>\r\n <div>\r\n <h3 className=\"font-medium\">{t(`tickets.${type.labelKey}`)}</h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{t(`tickets.${type.descriptionKey}`, type.value)}</p>\r\n </div>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n\r\n const renderSystemInfo = () => {\r\n if (!browserInfo) return null;\r\n return (\r\n <div className=\"card p-4 bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"font-medium flex items-center gap-2\">\r\n <Monitor className=\"w-5 h-5 text-[var(--color-primary-600)]\" />\r\n {t('tickets.create.systemInfo', 'System Information')}\r\n </h3>\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={includeBrowserInfo}\r\n onChange={(e) => setIncludeBrowserInfo(e.target.checked)}\r\n className=\"rounded border-[var(--border-color)]\"\r\n />\r\n <span className=\"text-xs text-[var(--text-secondary)]\">\r\n {t('tickets.create.includeSystemInfo', 'Include in ticket')}\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <div className={`grid grid-cols-2 md:grid-cols-3 gap-3 text-sm ${!includeBrowserInfo ? 'opacity-50' : ''}`}>\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">{t('tickets.create.browser', 'Browser')}</span>\r\n <span className=\"font-medium\">{browserInfo.browser} {browserInfo.browserVersion}</span>\r\n </div>\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">{t('tickets.create.os', 'OS')}</span>\r\n <span className=\"font-medium\">{browserInfo.os} {browserInfo.osVersion}</span>\r\n </div>\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">{t('tickets.create.device', 'Device')}</span>\r\n <span className=\"font-medium\">{browserInfo.deviceType}</span>\r\n </div>\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">{t('tickets.create.screen', 'Screen')}</span>\r\n <span className=\"font-medium\">{browserInfo.screenResolution}</span>\r\n </div>\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">{t('tickets.create.language', 'Language')}</span>\r\n <span className=\"font-medium\">{browserInfo.language}</span>\r\n </div>\r\n {errorContext && (\r\n <div className=\"p-3 bg-[var(--bg-primary)] rounded-lg\">\r\n <span className=\"text-xs text-[var(--text-secondary)] block\">URL</span>\r\n <span className=\"font-medium font-mono text-xs truncate block\">{errorContext.url}</span>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const renderScreenshot = () => {\r\n if (!annotatedScreenshot) return null;\r\n return (\r\n <div className=\"card p-4\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"font-medium flex items-center gap-2\">\r\n <Camera className=\"w-5 h-5 text-[var(--color-primary-600)]\" />\r\n {t('tickets.createFlow.screenshot')}\r\n </h3>\r\n <label className=\"flex items-center gap-2 text-sm\">\r\n <input\r\n type=\"checkbox\"\r\n checked={includeScreenshot}\r\n onChange={(e) => setIncludeScreenshot(e.target.checked)}\r\n className=\"rounded border-[var(--border-color)]\"\r\n />\r\n {t('tickets.createFlow.includeScreenshot')}\r\n </label>\r\n </div>\r\n\r\n {includeScreenshot ? (\r\n <ScreenshotAnnotator\r\n screenshot={annotatedScreenshot}\r\n onAnnotatedScreenshot={handleAnnotatedScreenshot}\r\n onReset={handleRecaptureScreenshot}\r\n />\r\n ) : (\r\n <div className=\"p-8 text-center text-[var(--text-secondary)] bg-[var(--bg-secondary)] rounded-lg\">\r\n <Camera className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n <p className=\"text-sm\">{t('tickets.createFlow.screenshotExcluded', 'Screenshot will not be included')}</p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n };\r\n\r\n const renderErrorLogs = () => {\r\n if (!errorContext || errorContext.recentErrors.length === 0) return null;\r\n return (\r\n <div className=\"card p-4\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"font-medium flex items-center gap-2\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n {t('tickets.createFlow.recentErrors')} ({errorContext.recentErrors.length})\r\n </h3>\r\n <label className=\"flex items-center gap-2 text-sm\">\r\n <input\r\n type=\"checkbox\"\r\n checked={includeErrorLogs}\r\n onChange={(e) => setIncludeErrorLogs(e.target.checked)}\r\n className=\"rounded border-[var(--border-color)]\"\r\n />\r\n {t('tickets.createFlow.includeErrorLogs')}\r\n </label>\r\n </div>\r\n\r\n {includeErrorLogs ? (\r\n <div className=\"bg-[var(--bg-secondary)] rounded-lg p-4 text-sm font-mono max-h-48 overflow-y-auto space-y-2\">\r\n {errorContext.recentErrors.slice(0, 10).map((err, index) => (\r\n <div key={`error-${index}`} className=\"p-2 bg-[var(--error-bg)]/50 rounded text-[var(--error-text)]\">\r\n <div className=\"flex items-center gap-2 text-xs opacity-70 mb-1\">\r\n <span>{err.timestamp.toLocaleTimeString()}</span>\r\n {err.component && <span className=\"px-1.5 py-0.5 bg-[var(--bg-primary)] rounded\">{err.component}</span>}\r\n </div>\r\n <div className=\"break-words\">{err.message}</div>\r\n </div>\r\n ))}\r\n </div>\r\n ) : (\r\n <div className=\"p-4 text-center text-[var(--text-secondary)] bg-[var(--bg-secondary)] rounded-lg\">\r\n <p className=\"text-sm\">{t('tickets.createFlow.logsExcluded', 'Error logs will not be included')}</p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n };\r\n\r\n const renderCapturedContext = () => {\r\n if (!errorContext && !browserInfo) return null;\r\n\r\n return (\r\n <div className=\"space-y-6 mb-6\">\r\n {renderSystemInfo()}\r\n {renderScreenshot()}\r\n {renderErrorLogs()}\r\n </div>\r\n );\r\n };\r\n\r\n const renderAttachmentSection = () => {\r\n return (\r\n <div>\r\n <label className=\"block text-sm font-medium mb-2\">\r\n {t('tickets.createFlow.attachments')}\r\n </label>\r\n <div\r\n className={`border-2 border-dashed rounded-lg p-6 text-center transition-colors cursor-pointer ${\r\n isDragging\r\n ? 'border-[var(--color-primary-600)] bg-[var(--color-primary-600)]/10'\r\n : 'border-[var(--border-color)] hover:border-[var(--color-primary-600)]'\r\n }`}\r\n onClick={() => fileInputRef.current?.click()}\r\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); fileInputRef.current?.click(); } }}\r\n role=\"button\"\r\n tabIndex={0}\r\n onDragOver={handleDragOver}\r\n onDragEnter={handleDragEnter}\r\n onDragLeave={handleDragLeave}\r\n onDrop={handleDrop}\r\n >\r\n <input\r\n ref={fileInputRef}\r\n type=\"file\"\r\n multiple\r\n onChange={handleFileSelect}\r\n accept={allowedExtensions.join(',')}\r\n className=\"hidden\"\r\n />\r\n <Paperclip className={`w-8 h-8 mx-auto mb-2 ${isDragging ? 'text-[var(--color-primary-600)]' : 'text-[var(--text-secondary)]'}`} />\r\n <p className={`text-sm ${isDragging ? 'text-[var(--color-primary-600)] font-medium' : 'text-[var(--text-secondary)]'}`}>\r\n {isDragging\r\n ? t('tickets.createFlow.dropFilesNow', 'Drop files here')\r\n : t('tickets.createFlow.dropFilesHere')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {t('tickets.createFlow.maxFileSize', { size: '10 MB' })}\r\n </p>\r\n </div>\r\n\r\n {pendingFiles.length > 0 && (\r\n <div className=\"mt-3 space-y-2\">\r\n {pendingFiles.map((file, index) => {\r\n const FileIcon = getFileIcon(file.name);\r\n return (\r\n <div\r\n key={`file-${file.name}-${index}`}\r\n className=\"flex items-center gap-3 p-3 bg-[var(--bg-secondary)] rounded-lg\"\r\n >\r\n <FileIcon className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium truncate\">{file.name}</p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">{formatFileSize(file.size)}</p>\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n removeFile(index);\r\n }}\r\n className=\"p-1 hover:bg-[var(--bg-hover)] rounded\"\r\n >\r\n <X className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n </button>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n };\r\n\r\n const renderForm = () => {\r\n const currentTypeConfig = ticketTypes.find(tt => tt.value === selectedType);\r\n const CurrentTypeIcon = currentTypeConfig?.icon || Bug;\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"flex items-center gap-4 mb-6\">\r\n <button onClick={() => setStep(1)} className=\"btn btn-ghost p-2\">\r\n <ArrowLeft className=\"w-5 h-5\" />\r\n </button>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--bg-secondary)]\">\r\n <CurrentTypeIcon className=\"w-5 h-5\" />\r\n </div>\r\n <select\r\n value={selectedType || ''}\r\n onChange={(e) => setSelectedType(e.target.value as TicketType)}\r\n className=\"input text-lg font-semibold bg-transparent border-none p-0 pr-8 cursor-pointer hover:text-[var(--color-primary-600)] focus:ring-0\"\r\n >\r\n {ticketTypes.map((type) => (\r\n <option key={type.value} value={type.value}>\r\n {t(`tickets.${type.labelKey}`)}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1\">\r\n {t('tickets.createFlow.fillDetails')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {renderCapturedContext()}\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium mb-2\">\r\n {t('tickets.form.title')} <span className=\"text-[var(--error-text)]\">*</span>\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={title}\r\n onChange={(e) => setTitle(e.target.value)}\r\n placeholder={t('tickets.form.titlePlaceholder')}\r\n className=\"input w-full\"\r\n maxLength={200}\r\n />\r\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {title.length}/200\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium mb-2\">\r\n {t('tickets.form.description')} <span className=\"text-[var(--error-text)]\">*</span>\r\n </label>\r\n <textarea\r\n value={description}\r\n onChange={(e) => setDescription(e.target.value)}\r\n placeholder={t('tickets.form.descriptionPlaceholder')}\r\n className=\"input w-full h-40\"\r\n maxLength={5000}\r\n />\r\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {description.length}/5000\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium mb-2\">{t('tickets.form.priority')}</label>\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-2\">\r\n {priorityOptions.map((option) => (\r\n <button\r\n key={option.value}\r\n type=\"button\"\r\n onClick={() => setPriority(option.value)}\r\n className={`p-3 rounded-lg border text-center transition-colors ${\r\n priority === option.value\r\n ? 'border-[var(--color-primary-600)] bg-[var(--color-primary-600)]/10'\r\n : 'border-[var(--border-color)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <div className=\"font-medium\">{t(`tickets.${option.labelKey}`)}</div>\r\n <div className=\"text-xs text-[var(--text-secondary)]\">{t(`tickets.${option.descriptionKey}`, option.value)}</div>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {renderAttachmentSection()}\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-lg bg-[var(--error-bg)] text-[var(--error-text)] flex items-center gap-2\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n {error}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex items-center justify-between pt-4 border-t border-[var(--border-color)]\">\r\n <button onClick={() => setStep(1)} className=\"btn btn-secondary\">\r\n {t('common:actions.back')}\r\n </button>\r\n <button\r\n onClick={handleSubmit}\r\n disabled={!title.trim() || !description.trim() || submitting || uploadingFiles}\r\n className=\"btn btn-primary\"\r\n >\r\n {(submitting || uploadingFiles) ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin mr-2\" />\r\n ) : (\r\n <Send className=\"w-4 h-4 mr-2\" />\r\n )}\r\n {(() => {\r\n if (uploadingFiles) return t('tickets.createFlow.uploadingFiles');\r\n if (submitting) return t('common:actions.submitting');\r\n return t('common:actions.submit');\r\n })()}\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"max-w-3xl mx-auto\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('title', 'Support'), href: '/support' },\r\n { label: t('list.title', 'Tickets'), href: '/support/tickets' },\r\n { label: t('create.title', 'Create Ticket') }\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-center gap-4 mb-6 mt-6\">\r\n <button onClick={() => navigate(-1)} className=\"btn btn-ghost p-2\">\r\n <ArrowLeft className=\"w-5 h-5\" />\r\n </button>\r\n <div className=\"flex-1\">\r\n <h1 className=\"text-2xl font-bold flex items-center gap-2\">\r\n <Headset className=\"w-6 h-6\" />\r\n {t('tickets.createFlow.title')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {t('tickets.createFlow.subtitle')}\r\n </p>\r\n </div>\r\n {draftId && (\r\n <button\r\n onClick={() => setShowDiscardConfirm(true)}\r\n className=\"btn btn-ghost text-[var(--error-text)] hover:bg-[var(--error-bg)]\"\r\n title={t('common:drafts.discard')}\r\n >\r\n <Trash2 className=\"w-4 h-4 mr-2\" />\r\n {t('common:drafts.discard')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {isGlpi ? (\r\n <div className=\"mb-6 p-4 rounded-lg bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <div className=\"flex items-center gap-3 mb-3\">\r\n <Info className=\"w-5 h-5 text-[var(--info-text)] flex-shrink-0\" />\r\n <p className=\"font-medium text-[var(--info-text)]\">\r\n {t('glpi.cannotCreateTicket', 'Tickets are managed by GLPI. Please create tickets directly in GLPI.')}\r\n </p>\r\n </div>\r\n {glpiBaseUrl && (\r\n <a\r\n href={glpiBaseUrl}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"btn btn-primary inline-flex items-center gap-2\"\r\n >\r\n <ExternalLink className=\"w-4 h-4\" />\r\n {t('glpi.openGlpi')}\r\n </a>\r\n )}\r\n </div>\r\n ) : (\r\n <>\r\n <div className=\"flex items-center gap-4 mb-8\">\r\n <div className={`flex items-center gap-2 ${step >= 1 ? 'text-[var(--color-primary-600)]' : 'text-[var(--text-secondary)]'}`}>\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center ${\r\n step >= 1 ? 'bg-[var(--color-primary-600)] text-white' : 'bg-[var(--bg-secondary)]'\r\n }`}>\r\n 1\r\n </div>\r\n <span className=\"font-medium\">{t('tickets.createFlow.step1')}</span>\r\n </div>\r\n <div className={`flex-1 h-0.5 ${step >= 2 ? 'bg-[var(--color-primary-600)]' : 'bg-[var(--border-color)]'}`} />\r\n <div className={`flex items-center gap-2 ${step >= 2 ? 'text-[var(--color-primary-600)]' : 'text-[var(--text-secondary)]'}`}>\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center ${\r\n step >= 2 ? 'bg-[var(--color-primary-600)] text-white' : 'bg-[var(--bg-secondary)]'\r\n }`}>\r\n 2\r\n </div>\r\n <span className=\"font-medium\">{t('tickets.createFlow.step2')}</span>\r\n </div>\r\n\r\n {/* Draft auto-save indicator */}\r\n {saveFailed ? (\r\n <div className=\"ml-auto flex items-center gap-1.5 text-xs text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-3.5 h-3.5\" />\r\n <span>{t('common:errors.generic')}</span>\r\n </div>\r\n ) : (\r\n <div className={`ml-auto flex items-center gap-1.5 text-xs text-[var(--success-text)] transition-opacity duration-300 ${\r\n showDraftSaved ? 'opacity-100' : 'opacity-0'\r\n }`}>\r\n <Check className=\"w-3.5 h-3.5\" />\r\n <span>{t('common:drafts.autoSaved')}</span>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Tenant context indicator (shown when using locally selected tenant in global view) */}\r\n {selectedTenantForTicket && !currentTenant && (\r\n <div className=\"mb-4 p-3 rounded-lg bg-[var(--info-bg)] border border-[var(--info-border)] flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2 text-sm text-[var(--info-text)]\">\r\n <Building2 className=\"w-4 h-4\" />\r\n <span>{t('support:tickets.tenantPicker.creatingFor')}</span>\r\n <span className=\"font-semibold\">{selectedTenantForTicket.name}</span>\r\n </div>\r\n <button\r\n onClick={() => setShowTenantPicker(true)}\r\n className=\"text-xs text-[var(--info-text)] underline hover:no-underline\"\r\n >\r\n {t('common:actions.change')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n <div className=\"card p-6\">\r\n {step === 1 && renderTypeSelection()}\r\n {step === 2 && renderForm()}\r\n </div>\r\n\r\n {/* Tenant picker modal (shown in global view when no tenant selected) */}\r\n {showTenantPicker && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4\">\r\n <div className=\"card w-full max-w-md p-6\">\r\n <div className=\"flex items-center gap-3 mb-4\">\r\n <div className=\"w-10 h-10 rounded-full bg-[var(--info-bg)] flex items-center justify-center\">\r\n <Building2 className=\"w-5 h-5 text-[var(--info-text)]\" />\r\n </div>\r\n <div>\r\n <h2 className=\"text-xl font-bold\">{t('support:tickets.tenantPicker.title')}</h2>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{t('support:tickets.tenantPicker.description')}</p>\r\n </div>\r\n </div>\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto\">\r\n {userTenants\r\n .filter(tenant => tenant.status === 'Active')\r\n .map(tenant => (\r\n <button\r\n key={tenant.id}\r\n onClick={() => {\r\n setSelectedTenantForTicket(tenant);\r\n setShowTenantPicker(false);\r\n // Immediately persist tenant to draft\r\n if (draftId) {\r\n ticketDraftService.updateDraft(draftId, {\r\n tenantId: tenant.id,\r\n tenantSlug: tenant.slug,\r\n tenantName: tenant.name,\r\n });\r\n }\r\n }}\r\n className={`w-full p-3 rounded-lg border text-left transition-colors hover:bg-[var(--bg-hover)] ${\r\n selectedTenantForTicket?.id === tenant.id\r\n ? 'border-[var(--color-primary-600)] bg-[var(--color-primary-600)]/10'\r\n : 'border-[var(--border-color)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-3\">\r\n <Building2 className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"font-medium truncate\">{tenant.name}</div>\r\n {tenant.organisationName && (\r\n <div className=\"text-xs text-[var(--text-secondary)] truncate\">{tenant.organisationName}</div>\r\n )}\r\n </div>\r\n <span className={`text-xs px-2 py-0.5 rounded-full ${\r\n tenant.type === 'Personal'\r\n ? 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n : 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n }`}>\r\n {tenant.type === 'Personal' ? t('common:tenant.personal') : t('common:tenant.business')}\r\n </span>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n <div className=\"flex justify-end gap-3 mt-4 pt-4 border-t border-[var(--border-color)]\">\r\n <button\r\n onClick={() => {\r\n setShowTenantPicker(false);\r\n if (!effectiveTenant) navigate(-1);\r\n }}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:actions.cancel')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Discard confirmation modal */}\r\n {showDiscardConfirm && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4\">\r\n <div className=\"card w-full max-w-md p-6\">\r\n <div className=\"flex items-center gap-3 mb-4\">\r\n <div className=\"w-10 h-10 rounded-full bg-[var(--error-bg)] flex items-center justify-center\">\r\n <Trash2 className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n </div>\r\n <h2 className=\"text-xl font-bold\">{t('common:drafts.discardConfirmTitle')}</h2>\r\n </div>\r\n <p className=\"text-[var(--text-secondary)] mb-6\">\r\n {t('common:drafts.discardConfirmMessage')}\r\n </p>\r\n <div className=\"flex justify-end gap-3\">\r\n <button\r\n onClick={() => setShowDiscardConfirm(false)}\r\n className=\"btn btn-secondary\"\r\n >\r\n {t('common:actions.cancel')}\r\n </button>\r\n <button\r\n onClick={() => {\r\n setShowDiscardConfirm(false);\r\n handleDiscardDraft();\r\n }}\r\n className=\"btn bg-[var(--error-bg)] text-[var(--error-text)] hover:opacity-90\"\r\n >\r\n <Trash2 className=\"w-4 h-4 mr-2\" />\r\n {t('common:drafts.discardConfirm')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["maxFileSize","allowedExtensions","useCreateSupportTicket","draftId","effectiveTenant","selectedType","setSelectedType","useState","title","setTitle","description","setDescription","priority","setPriority","submitting","setSubmitting","error","setError","errorContext","setErrorContext","includeScreenshot","setIncludeScreenshot","includeErrorLogs","setIncludeErrorLogs","includeBrowserInfo","setIncludeBrowserInfo","annotatedScreenshot","setAnnotatedScreenshot","browserInfo","setBrowserInfo","pendingFiles","setPendingFiles","uploadingFiles","setUploadingFiles","fileInputRef","useRef","showDraftSaved","setShowDraftSaved","saveFailed","setSaveFailed","autoSaveTimerRef","isInitialLoadCompleteRef","hasUnsavedChangesRef","draftAttachmentsRef","errorContextToDraft","useCallback","context","e","draftToErrorContext","draft","fileToAttachment","file","resolve","reject","reader","attachmentToFile","attachment","arr","mime","bstr","n","u8arr","filesToAttachments","files","saveDraftNow","result","ticketDraftService","processFiles","validFiles","errors","extension","prev","removeFile","index","_","buildClientContext","info","browserInfoService","cleanupAfterSubmit","errorContextService","submitTicket","clientContext","tenantHeaders","ticket","api","blob","formData","err","ticketTypes","Bug","Lightbulb","Sparkles","AppWindow","MessageSquare","HelpCircle","priorityOptions","CreateSupportTicketPage","t","useTranslation","navigate","useNavigate","searchParams","useSearchParams","currentTenant","userTenants","isGlobalView","useTenant","isGlpi","glpiBaseUrl","useTicketingProvider","selectedTenantForTicket","setSelectedTenantForTicket","showTenantPicker","setShowTenantPicker","showDiscardConfirm","setShowDiscardConfirm","useEffect","step","setStep","isDragging","setIsDragging","applyDraftData","restoredFiles","matchingTenant","applySessionContext","draftState","sessionContext","attachments","handleBeforeUnload","handleAnnotatedScreenshot","dataUrl","handleRecaptureScreenshot","newContext","handleDiscardDraft","handleFileSelect","handleDragOver","handleDragEnter","handleDragLeave","rect","x","y","handleDrop","formatFileSize","bytes","getFileIcon","fileName","ext","ImageIcon","FileText","File","handleSubmit","renderTypeSelection","jsxs","jsx","type","renderSystemInfo","Monitor","renderScreenshot","Camera","ScreenshotAnnotator","renderErrorLogs","AlertTriangle","renderCapturedContext","renderAttachmentSection","Paperclip","FileIcon","X","renderForm","CurrentTypeIcon","tt","ArrowLeft","option","Loader2","Send","Breadcrumb","Headset","Trash2","Info","ExternalLink","Fragment","Check","Building2","tenant"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),c=require("react"),_=require("react-router-dom"),ee=require("react-i18next"),a=require("lucide-react"),h=require("./index-cAikSVW0.js"),D=require("./applicationAnalyticsApi-DhOd6idI.js"),$={Desktop:e.jsx(a.Monitor,{className:"w-4 h-4"}),Mobile:e.jsx(a.Smartphone,{className:"w-4 h-4"}),Tablet:e.jsx(a.Tablet,{className:"w-4 h-4"}),Unknown:e.jsx(a.Monitor,{className:"w-4 h-4 opacity-50"})},M=["#3b82f6","#22c55e","#f59e0b","#6b7280"],P=["#3b82f6","#8b5cf6","#22c55e","#f59e0b","#ef4444"],se=({data:t})=>!t||!t.byDeviceType?.length&&!t.byBrowser?.length?e.jsx("div",{className:"text-center py-8 text-[var(--text-secondary)]",children:"No device data available"}):e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-3",children:"By Device Type"}),e.jsx("div",{className:"space-y-3",children:t.byDeviceType.map((l,n)=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2 w-28",children:[$[l.deviceType]||$.Unknown,e.jsx("span",{className:"text-sm",children:l.deviceType})]}),e.jsx("div",{className:"flex-1 h-6 bg-[var(--bg-secondary)] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${l.percentage}%`,backgroundColor:M[n%M.length]}})}),e.jsxs("div",{className:"w-20 text-right",children:[e.jsx("span",{className:"font-medium",children:l.count}),e.jsxs("span",{className:"text-xs text-[var(--text-secondary)] ml-1",children:["(",l.percentage.toFixed(1),"%)"]})]})]},l.deviceType))})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-3",children:"By Browser"}),e.jsx("div",{className:"space-y-3",children:t.byBrowser.map((l,n)=>{const r=Math.max(...t.byBrowser.map(u=>u.count),1),d=l.count/r*100;return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-24 text-sm",children:l.browser}),e.jsx("div",{className:"flex-1 h-6 bg-[var(--bg-secondary)] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${d}%`,backgroundColor:P[n%P.length]}})}),e.jsx("div",{className:"w-12 text-right font-medium",children:l.count})]},l.browser)})})]})]}),B=["#ef4444","#f59e0b","#22c55e","#3b82f6"],te=({data:t})=>{if(!t)return e.jsx("div",{className:"text-center py-8 text-[var(--text-secondary)]",children:"No engagement data available"});const l=Math.max(...t.sessionDistribution.map(r=>r.count),1),n=Math.max(...t.peakUsageHours.map(r=>r.accessCount),1);return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-3",children:"Session Duration Distribution"}),e.jsx("div",{className:"space-y-3",children:t.sessionDistribution.map((r,d)=>{const u=r.count/l*100;return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-20 text-sm",children:r.label}),e.jsx("div",{className:"flex-1 h-6 bg-[var(--bg-secondary)] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${u}%`,backgroundColor:B[d%B.length]}})}),e.jsxs("div",{className:"w-16 text-right",children:[e.jsx("span",{className:"font-medium",children:r.count}),e.jsx("span",{className:"text-xs text-[var(--text-secondary)] ml-1",children:"sessions"})]})]},r.bucket)})})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-3",children:"Peak Usage Hours"}),e.jsx("div",{className:"flex items-end gap-1 h-32 overflow-x-auto pb-2",children:t.peakUsageHours.map(r=>{const d=r.accessCount/n*100;return e.jsxs("div",{className:"flex-1 min-w-[20px] flex flex-col items-center gap-1",children:[e.jsx("div",{className:"w-full bg-gradient-to-t from-blue-500 to-cyan-500 rounded-t transition-all duration-300 hover:opacity-80",style:{height:`${d}%`,minHeight:r.accessCount>0?"4px":"0"},title:`${r.hour}h: ${r.accessCount} accesses`}),r.hour%3===0&&e.jsxs("span",{className:"text-xs text-[var(--text-secondary)]",children:[r.hour,"h"]})]},r.hour)})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4 pt-4 border-t border-[var(--border-color)]",children:[e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{className:"text-2xl font-bold text-blue-600",children:t.dailyActiveUsers}),e.jsx("div",{className:"text-xs text-[var(--text-secondary)] mt-1",children:"Daily Active Users"})]}),e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsxs("div",{className:"text-2xl font-bold text-green-600",children:[(t.retentionRate*100).toFixed(1),"%"]}),e.jsx("div",{className:"text-xs text-[var(--text-secondary)] mt-1",children:"Retention Rate"})]})]})]})},ae={Active:"#22c55e",Inactive:"#ef4444"};function re(){const{t}=ee.useTranslation(["admin","navigation"]),l=_.useNavigate(),{currentTenant:n,isGlobalView:r}=h.useTenant(),[d,u]=c.useState(!0),[C,S]=c.useState(!1),[o,I]=c.useState(30),[x,E]=c.useState(null),[k,L]=c.useState([]),[f,q]=c.useState([]),[H,F]=c.useState([]),[R,V]=c.useState([]),[y,z]=c.useState([]),[v,O]=c.useState(null),[G,K]=c.useState(null),[X,J]=c.useState(null),[U,p]=c.useState(null),N=c.useRef(null),w=c.useCallback(async s=>{try{p(null);const[i,m,b,g,A,Q,W,Y,Z]=await Promise.all([h.adminApi.dashboard.getOverview(o,{signal:s}),h.adminApi.dashboard.getByStatus({signal:s}),h.adminApi.dashboard.getByRole({signal:s}),h.adminApi.dashboard.getTrends(o,{signal:s}),h.adminApi.dashboard.getLatestActiveSessions(5,{signal:s}),h.adminApi.dashboard.getSecurityAlerts(3,24,{signal:s}),h.adminApi.dashboard.getActiveSessions({signal:s}),D.applicationAnalyticsApi.getDeviceStats(o,{signal:s}),D.applicationAnalyticsApi.getEngagementMetrics(o,{signal:s})]);s?.aborted||(E(i??null),L(m??[]),q(b??[]),F(g??[]),V(A??[]),z(Q??[]),O(W??null),K(Y??null),J(Z??null))}catch(i){if(i instanceof Error&&i.name==="CanceledError")return;console.error("Failed to load dashboard data:",i);const m=i;m.response?.status===401?p("Session expirée. Veuillez vous reconnecter."):m.response?.status===403?p("Vous n'avez pas les permissions nécessaires pour accéder au dashboard."):p("Erreur lors du chargement des données. Vérifiez que l'API est accessible.")}finally{s?.aborted||(u(!1),S(!1))}},[o,n?.id,r]);c.useEffect(()=>{N.current?.abort();const s=new AbortController;return N.current=s,w(s.signal),()=>{s.abort()}},[w]);const T=()=>{N.current?.abort();const s=new AbortController;N.current=s,S(!0),w(s.signal)};return d?e.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:e.jsx(a.Loader2,{className:"w-8 h-8 animate-spin text-[var(--color-primary-600)]"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsx(h.Breadcrumb,{items:[{label:t("header.title")},{label:t("dashboard.title")}]}),U&&e.jsxs("div",{className:"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 flex items-center gap-3",children:[e.jsx(a.AlertTriangle,{className:"w-5 h-5 text-red-600 dark:text-red-400 flex-shrink-0"}),e.jsx("div",{className:"flex-1",children:e.jsx("p",{className:"text-red-800 dark:text-red-200 font-medium",children:U})}),e.jsx("button",{onClick:T,className:"text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-200",children:e.jsx(a.RefreshCw,{className:"w-5 h-5"})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold text-[var(--text-primary)] flex items-center gap-2",children:[e.jsx(a.Users,{className:"w-6 h-6"}),t("admin:header.title")]}),e.jsx("p",{className:"text-[var(--text-secondary)] mt-1",children:"Vue d'ensemble de la gestion des utilisateurs"})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("select",{value:o,onChange:s=>I(Number(s.target.value)),className:"input",children:[e.jsx("option",{value:7,children:"7 derniers jours"}),e.jsx("option",{value:30,children:"30 derniers jours"}),e.jsx("option",{value:90,children:"90 derniers jours"})]}),e.jsxs("button",{onClick:T,disabled:C,className:"btn btn-secondary flex items-center gap-2",children:[e.jsx(a.RefreshCw,{className:`w-4 h-4 ${C?"animate-spin":""}`}),"Actualiser"]})]})]}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4",children:[e.jsx(j,{title:"Total Utilisateurs",value:x?.totalUsers??0,icon:e.jsx(a.Users,{className:"w-5 h-5"}),color:"blue"}),e.jsx(j,{title:"Actifs",value:x?.activeUsers??0,icon:e.jsx(a.UserCheck,{className:"w-5 h-5"}),color:"green"}),e.jsx(j,{title:"Inactifs",value:x?.inactiveUsers??0,icon:e.jsx(a.UserX,{className:"w-5 h-5"}),color:"red"}),e.jsx(j,{title:"Nouveaux",value:x?.newUsers??0,icon:e.jsx(a.UserPlus,{className:"w-5 h-5"}),color:"blue",subtitle:`${o} derniers jours`}),e.jsx(j,{title:"Sessions",value:x?.totalSessions??0,icon:e.jsx(a.Activity,{className:"w-5 h-5"}),color:"green",subtitle:`${o} derniers jours`}),e.jsx(j,{title:"Connexions Echouées",value:x?.failedLogins??0,icon:e.jsx(a.AlertTriangle,{className:"w-5 h-5"}),color:(x?.failedLogins??0)>10?"red":"yellow",subtitle:`${o} derniers jours`})]}),(y?.length??0)>0&&e.jsxs("div",{className:"card p-4 border-l-4 border-red-500",children:[e.jsxs("h3",{className:"font-semibold text-red-600 flex items-center gap-2 mb-3",children:[e.jsx(a.AlertTriangle,{className:"w-5 h-5"}),"Alertes Sécurité (",y?.length??0,")"]}),e.jsx("div",{className:"space-y-2 max-h-40 overflow-y-auto",children:(y??[]).slice(0,5).map(s=>e.jsxs("button",{type:"button",className:"w-full flex items-center justify-between p-2 bg-red-50 dark:bg-red-900/20 rounded cursor-pointer hover:bg-red-100 dark:hover:bg-red-900/30 text-left",onClick:()=>l(`/administration/users/${s.userId}`),children:[e.jsxs("div",{children:[e.jsx("span",{className:"font-medium",children:s.fullName}),e.jsx("span",{className:"ml-2 text-sm text-[var(--text-secondary)]",children:s.email})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-xs text-red-600 font-medium",children:[s.failedAttempts," échecs"]}),e.jsxs("span",{className:"text-xs text-[var(--text-secondary)]",children:[s.ipAddresses?.length??0," IP(s)"]})]})]},s.userId))})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.UserCheck,{className:"w-5 h-5"}),"Utilisateurs par Statut"]}),e.jsx("div",{className:"space-y-3",children:(k??[]).map(s=>{const i=(k??[]).reduce((b,g)=>b+g.count,0),m=i>0?s.count/i*100:0;return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-24 text-sm",children:s.status==="Active"?"Actifs":"Inactifs"}),e.jsx("div",{className:"flex-1 h-6 bg-[var(--bg-secondary)] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${m}%`,backgroundColor:ae[s.status]||"#6b7280"}})}),e.jsxs("div",{className:"w-20 text-right",children:[e.jsx("span",{className:"font-medium",children:s.count}),e.jsxs("span",{className:"text-xs text-[var(--text-secondary)] ml-1",children:["(",m.toFixed(0),"%)"]})]})]},s.status)})})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Key,{className:"w-5 h-5"}),"Utilisateurs par Rôle"]}),e.jsx("div",{className:"space-y-3",children:(f?.length??0)>0?(f??[]).map((s,i)=>{const m=Math.max(...(f??[]).map(A=>A.count),1),b=s.count/m*100,g=["#3b82f6","#8b5cf6","#22c55e","#f59e0b","#ef4444"];return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-32 text-sm truncate",title:s.roleName,children:s.roleName}),e.jsx("div",{className:"flex-1 h-6 bg-[var(--bg-secondary)] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${b}%`,backgroundColor:g[i%g.length]}})}),e.jsx("div",{className:"w-12 text-right font-medium",children:s.count})]},s.roleName)}):e.jsx("div",{className:"text-center py-4 text-[var(--text-secondary)]",children:"Aucun rôle configuré"})})]})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Shield,{className:"w-5 h-5"}),"Configuration Système"]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"text-center p-4 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{className:"text-3xl font-bold text-purple-600",children:x?.totalRoles??0}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Rôles"})]}),e.jsxs("div",{className:"text-center p-4 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{className:"text-3xl font-bold text-green-600",children:x?.totalPermissions??0}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Permissions"})]}),e.jsxs("div",{className:"text-center p-4 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{className:"text-3xl font-bold text-blue-600",children:x?.usersLoggedInRecently??0}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Connectés récemment"})]}),e.jsxs("div",{className:"text-center p-4 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{className:"text-3xl font-bold text-orange-600",children:v?.totalActiveSessions??0}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Sessions actives"})]})]})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Monitor,{className:"w-5 h-5"}),"Sessions Actives"]}),v&&((v.byBrowser?.length??0)>0||(v.byCountry?.length??0)>0)?e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-2",children:"Par Navigateur"}),e.jsx("div",{className:"space-y-2",children:(v.byBrowser??[]).map(s=>e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{children:s.browser}),e.jsx("span",{className:"font-medium",children:s.count})]},s.browser))})]}),e.jsxs("div",{children:[e.jsxs("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-2 flex items-center gap-1",children:[e.jsx(a.Globe,{className:"w-4 h-4"})," Par Pays"]}),e.jsx("div",{className:"space-y-2",children:(v.byCountry?.length??0)>0?(v.byCountry??[]).map(s=>e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{children:s.country}),e.jsx("span",{className:"font-medium",children:s.count})]},s.country)):e.jsx("span",{className:"text-[var(--text-secondary)] text-sm",children:"Non disponible"})})]})]}):e.jsx("div",{className:"text-center py-8 text-[var(--text-secondary)]",children:"Aucune session active"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Monitor,{className:"w-5 h-5"}),"Appareils & Navigateurs"]}),e.jsx(se,{data:G})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Activity,{className:"w-5 h-5"}),"Engagement Utilisateurs"]}),e.jsx(te,{data:X})]})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.TrendingUp,{className:"w-5 h-5"}),"Tendances (",o," derniers jours)"]}),e.jsx("div",{className:"h-64",children:e.jsx(le,{data:H??[]})})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Clock,{className:"w-5 h-5"}),"Dernières Sessions Actives"]}),(R?.length??0)>0?e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[var(--border-color)]",children:[e.jsx("th",{className:"text-left p-3 font-medium",children:"Utilisateur"}),e.jsx("th",{className:"text-right p-3 font-medium",children:"Durée"})]})}),e.jsx("tbody",{children:(R??[]).map(s=>e.jsxs("tr",{className:"border-b border-[var(--border-color)] hover:bg-[var(--bg-secondary)] cursor-pointer",onClick:()=>l(`/administration/users/${s.userId}`),children:[e.jsx("td",{className:"p-3 font-medium",children:s.fullName}),e.jsx("td",{className:"p-3 text-right",children:e.jsx("span",{className:"px-2 py-1 rounded text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400",children:s.duration})})]},s.userId+s.loginAt))})]})}):e.jsx("div",{className:"text-center py-8 text-[var(--text-secondary)]",children:"Aucune session active"})]})]})}function j({title:t,value:l,icon:n,color:r,subtitle:d}){const u={blue:"bg-blue-50 text-blue-600 border-blue-200 dark:bg-blue-900/20 dark:border-blue-800",green:"bg-green-50 text-green-600 border-green-200 dark:bg-green-900/20 dark:border-green-800",yellow:"bg-yellow-50 text-yellow-600 border-yellow-200 dark:bg-yellow-900/20 dark:border-yellow-800",red:"bg-red-50 text-red-600 border-red-200 dark:bg-red-900/20 dark:border-red-800"};return e.jsxs("div",{className:`card p-4 border ${u[r]}`,children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-sm font-medium opacity-80",children:t}),n]}),e.jsx("div",{className:"text-2xl font-bold",children:l}),d&&e.jsx("div",{className:"text-xs opacity-70 mt-1",children:d})]})}function le({data:t}){if(t.length===0)return e.jsx("div",{className:"flex items-center justify-center h-full text-[var(--text-secondary)]",children:"Aucune donnée de tendance disponible"});const l=Math.max(...t.flatMap(n=>[n.newUsers,n.logins]),1);return e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"flex items-center gap-4 mb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-3 h-3 rounded bg-blue-500"}),e.jsx("span",{className:"text-sm",children:"Nouveaux utilisateurs"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-3 h-3 rounded bg-green-500"}),e.jsx("span",{className:"text-sm",children:"Connexions"})]})]}),e.jsx("div",{className:"flex-1 flex items-end gap-1 overflow-x-auto pb-4",children:t.map(n=>e.jsxs("div",{className:"flex-1 min-w-[20px] flex gap-0.5",children:[e.jsx("div",{className:"flex-1 bg-blue-500 rounded-t transition-all duration-300 hover:opacity-80",style:{height:`${n.newUsers/l*100}%`,minHeight:n.newUsers>0?"4px":"0"},title:`Nouveaux: ${n.newUsers}`}),e.jsx("div",{className:"flex-1 bg-green-500 rounded-t transition-all duration-300 hover:opacity-80",style:{height:`${n.logins/l*100}%`,minHeight:n.logins>0?"4px":"0"},title:`Connexions: ${n.logins}`})]},`${n.date}`))}),e.jsxs("div",{className:"flex justify-between text-xs text-[var(--text-secondary)] mt-2",children:[e.jsx("span",{children:t[0]&&new Date(t[0].date).toLocaleDateString("fr-FR")}),e.jsx("span",{children:t.at(-1)&&new Date(t.at(-1).date).toLocaleDateString("fr-FR")})]})]})}exports.AdminDashboardPage=re;
2
- //# sourceMappingURL=DashboardPage-4oy2YqvT.js.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),c=require("react"),_=require("react-router-dom"),ee=require("react-i18next"),a=require("lucide-react"),h=require("./index-DnML-nfd.js"),D=require("./applicationAnalyticsApi-BobBdehV.js"),$={Desktop:e.jsx(a.Monitor,{className:"w-4 h-4"}),Mobile:e.jsx(a.Smartphone,{className:"w-4 h-4"}),Tablet:e.jsx(a.Tablet,{className:"w-4 h-4"}),Unknown:e.jsx(a.Monitor,{className:"w-4 h-4 opacity-50"})},M=["#3b82f6","#22c55e","#f59e0b","#6b7280"],P=["#3b82f6","#8b5cf6","#22c55e","#f59e0b","#ef4444"],se=({data:t})=>!t||!t.byDeviceType?.length&&!t.byBrowser?.length?e.jsx("div",{className:"text-center py-8 text-[var(--text-secondary)]",children:"No device data available"}):e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-3",children:"By Device Type"}),e.jsx("div",{className:"space-y-3",children:t.byDeviceType.map((l,n)=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2 w-28",children:[$[l.deviceType]||$.Unknown,e.jsx("span",{className:"text-sm",children:l.deviceType})]}),e.jsx("div",{className:"flex-1 h-6 bg-[var(--bg-secondary)] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${l.percentage}%`,backgroundColor:M[n%M.length]}})}),e.jsxs("div",{className:"w-20 text-right",children:[e.jsx("span",{className:"font-medium",children:l.count}),e.jsxs("span",{className:"text-xs text-[var(--text-secondary)] ml-1",children:["(",l.percentage.toFixed(1),"%)"]})]})]},l.deviceType))})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-3",children:"By Browser"}),e.jsx("div",{className:"space-y-3",children:t.byBrowser.map((l,n)=>{const r=Math.max(...t.byBrowser.map(u=>u.count),1),d=l.count/r*100;return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-24 text-sm",children:l.browser}),e.jsx("div",{className:"flex-1 h-6 bg-[var(--bg-secondary)] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${d}%`,backgroundColor:P[n%P.length]}})}),e.jsx("div",{className:"w-12 text-right font-medium",children:l.count})]},l.browser)})})]})]}),B=["#ef4444","#f59e0b","#22c55e","#3b82f6"],te=({data:t})=>{if(!t)return e.jsx("div",{className:"text-center py-8 text-[var(--text-secondary)]",children:"No engagement data available"});const l=Math.max(...t.sessionDistribution.map(r=>r.count),1),n=Math.max(...t.peakUsageHours.map(r=>r.accessCount),1);return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-3",children:"Session Duration Distribution"}),e.jsx("div",{className:"space-y-3",children:t.sessionDistribution.map((r,d)=>{const u=r.count/l*100;return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-20 text-sm",children:r.label}),e.jsx("div",{className:"flex-1 h-6 bg-[var(--bg-secondary)] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${u}%`,backgroundColor:B[d%B.length]}})}),e.jsxs("div",{className:"w-16 text-right",children:[e.jsx("span",{className:"font-medium",children:r.count}),e.jsx("span",{className:"text-xs text-[var(--text-secondary)] ml-1",children:"sessions"})]})]},r.bucket)})})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-3",children:"Peak Usage Hours"}),e.jsx("div",{className:"flex items-end gap-1 h-32 overflow-x-auto pb-2",children:t.peakUsageHours.map(r=>{const d=r.accessCount/n*100;return e.jsxs("div",{className:"flex-1 min-w-[20px] flex flex-col items-center gap-1",children:[e.jsx("div",{className:"w-full bg-gradient-to-t from-blue-500 to-cyan-500 rounded-t transition-all duration-300 hover:opacity-80",style:{height:`${d}%`,minHeight:r.accessCount>0?"4px":"0"},title:`${r.hour}h: ${r.accessCount} accesses`}),r.hour%3===0&&e.jsxs("span",{className:"text-xs text-[var(--text-secondary)]",children:[r.hour,"h"]})]},r.hour)})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4 pt-4 border-t border-[var(--border-color)]",children:[e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{className:"text-2xl font-bold text-blue-600",children:t.dailyActiveUsers}),e.jsx("div",{className:"text-xs text-[var(--text-secondary)] mt-1",children:"Daily Active Users"})]}),e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsxs("div",{className:"text-2xl font-bold text-green-600",children:[(t.retentionRate*100).toFixed(1),"%"]}),e.jsx("div",{className:"text-xs text-[var(--text-secondary)] mt-1",children:"Retention Rate"})]})]})]})},ae={Active:"#22c55e",Inactive:"#ef4444"};function re(){const{t}=ee.useTranslation(["admin","navigation"]),l=_.useNavigate(),{currentTenant:n,isGlobalView:r}=h.useTenant(),[d,u]=c.useState(!0),[C,S]=c.useState(!1),[o,I]=c.useState(30),[x,E]=c.useState(null),[k,L]=c.useState([]),[f,q]=c.useState([]),[H,F]=c.useState([]),[R,V]=c.useState([]),[y,z]=c.useState([]),[v,O]=c.useState(null),[G,K]=c.useState(null),[X,J]=c.useState(null),[U,p]=c.useState(null),N=c.useRef(null),w=c.useCallback(async s=>{try{p(null);const[i,m,b,g,A,Q,W,Y,Z]=await Promise.all([h.adminApi.dashboard.getOverview(o,{signal:s}),h.adminApi.dashboard.getByStatus({signal:s}),h.adminApi.dashboard.getByRole({signal:s}),h.adminApi.dashboard.getTrends(o,{signal:s}),h.adminApi.dashboard.getLatestActiveSessions(5,{signal:s}),h.adminApi.dashboard.getSecurityAlerts(3,24,{signal:s}),h.adminApi.dashboard.getActiveSessions({signal:s}),D.applicationAnalyticsApi.getDeviceStats(o,{signal:s}),D.applicationAnalyticsApi.getEngagementMetrics(o,{signal:s})]);s?.aborted||(E(i??null),L(m??[]),q(b??[]),F(g??[]),V(A??[]),z(Q??[]),O(W??null),K(Y??null),J(Z??null))}catch(i){if(i instanceof Error&&i.name==="CanceledError")return;console.error("Failed to load dashboard data:",i);const m=i;m.response?.status===401?p("Session expirée. Veuillez vous reconnecter."):m.response?.status===403?p("Vous n'avez pas les permissions nécessaires pour accéder au dashboard."):p("Erreur lors du chargement des données. Vérifiez que l'API est accessible.")}finally{s?.aborted||(u(!1),S(!1))}},[o,n?.id,r]);c.useEffect(()=>{N.current?.abort();const s=new AbortController;return N.current=s,w(s.signal),()=>{s.abort()}},[w]);const T=()=>{N.current?.abort();const s=new AbortController;N.current=s,S(!0),w(s.signal)};return d?e.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:e.jsx(a.Loader2,{className:"w-8 h-8 animate-spin text-[var(--color-primary-600)]"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsx(h.Breadcrumb,{items:[{label:t("header.title")},{label:t("dashboard.title")}]}),U&&e.jsxs("div",{className:"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 flex items-center gap-3",children:[e.jsx(a.AlertTriangle,{className:"w-5 h-5 text-red-600 dark:text-red-400 flex-shrink-0"}),e.jsx("div",{className:"flex-1",children:e.jsx("p",{className:"text-red-800 dark:text-red-200 font-medium",children:U})}),e.jsx("button",{onClick:T,className:"text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-200",children:e.jsx(a.RefreshCw,{className:"w-5 h-5"})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold text-[var(--text-primary)] flex items-center gap-2",children:[e.jsx(a.Users,{className:"w-6 h-6"}),t("admin:header.title")]}),e.jsx("p",{className:"text-[var(--text-secondary)] mt-1",children:"Vue d'ensemble de la gestion des utilisateurs"})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("select",{value:o,onChange:s=>I(Number(s.target.value)),className:"input",children:[e.jsx("option",{value:7,children:"7 derniers jours"}),e.jsx("option",{value:30,children:"30 derniers jours"}),e.jsx("option",{value:90,children:"90 derniers jours"})]}),e.jsxs("button",{onClick:T,disabled:C,className:"btn btn-secondary flex items-center gap-2",children:[e.jsx(a.RefreshCw,{className:`w-4 h-4 ${C?"animate-spin":""}`}),"Actualiser"]})]})]}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4",children:[e.jsx(j,{title:"Total Utilisateurs",value:x?.totalUsers??0,icon:e.jsx(a.Users,{className:"w-5 h-5"}),color:"blue"}),e.jsx(j,{title:"Actifs",value:x?.activeUsers??0,icon:e.jsx(a.UserCheck,{className:"w-5 h-5"}),color:"green"}),e.jsx(j,{title:"Inactifs",value:x?.inactiveUsers??0,icon:e.jsx(a.UserX,{className:"w-5 h-5"}),color:"red"}),e.jsx(j,{title:"Nouveaux",value:x?.newUsers??0,icon:e.jsx(a.UserPlus,{className:"w-5 h-5"}),color:"blue",subtitle:`${o} derniers jours`}),e.jsx(j,{title:"Sessions",value:x?.totalSessions??0,icon:e.jsx(a.Activity,{className:"w-5 h-5"}),color:"green",subtitle:`${o} derniers jours`}),e.jsx(j,{title:"Connexions Echouées",value:x?.failedLogins??0,icon:e.jsx(a.AlertTriangle,{className:"w-5 h-5"}),color:(x?.failedLogins??0)>10?"red":"yellow",subtitle:`${o} derniers jours`})]}),(y?.length??0)>0&&e.jsxs("div",{className:"card p-4 border-l-4 border-red-500",children:[e.jsxs("h3",{className:"font-semibold text-red-600 flex items-center gap-2 mb-3",children:[e.jsx(a.AlertTriangle,{className:"w-5 h-5"}),"Alertes Sécurité (",y?.length??0,")"]}),e.jsx("div",{className:"space-y-2 max-h-40 overflow-y-auto",children:(y??[]).slice(0,5).map(s=>e.jsxs("button",{type:"button",className:"w-full flex items-center justify-between p-2 bg-red-50 dark:bg-red-900/20 rounded cursor-pointer hover:bg-red-100 dark:hover:bg-red-900/30 text-left",onClick:()=>l(`/administration/users/${s.userId}`),children:[e.jsxs("div",{children:[e.jsx("span",{className:"font-medium",children:s.fullName}),e.jsx("span",{className:"ml-2 text-sm text-[var(--text-secondary)]",children:s.email})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-xs text-red-600 font-medium",children:[s.failedAttempts," échecs"]}),e.jsxs("span",{className:"text-xs text-[var(--text-secondary)]",children:[s.ipAddresses?.length??0," IP(s)"]})]})]},s.userId))})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.UserCheck,{className:"w-5 h-5"}),"Utilisateurs par Statut"]}),e.jsx("div",{className:"space-y-3",children:(k??[]).map(s=>{const i=(k??[]).reduce((b,g)=>b+g.count,0),m=i>0?s.count/i*100:0;return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-24 text-sm",children:s.status==="Active"?"Actifs":"Inactifs"}),e.jsx("div",{className:"flex-1 h-6 bg-[var(--bg-secondary)] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${m}%`,backgroundColor:ae[s.status]||"#6b7280"}})}),e.jsxs("div",{className:"w-20 text-right",children:[e.jsx("span",{className:"font-medium",children:s.count}),e.jsxs("span",{className:"text-xs text-[var(--text-secondary)] ml-1",children:["(",m.toFixed(0),"%)"]})]})]},s.status)})})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Key,{className:"w-5 h-5"}),"Utilisateurs par Rôle"]}),e.jsx("div",{className:"space-y-3",children:(f?.length??0)>0?(f??[]).map((s,i)=>{const m=Math.max(...(f??[]).map(A=>A.count),1),b=s.count/m*100,g=["#3b82f6","#8b5cf6","#22c55e","#f59e0b","#ef4444"];return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-32 text-sm truncate",title:s.roleName,children:s.roleName}),e.jsx("div",{className:"flex-1 h-6 bg-[var(--bg-secondary)] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${b}%`,backgroundColor:g[i%g.length]}})}),e.jsx("div",{className:"w-12 text-right font-medium",children:s.count})]},s.roleName)}):e.jsx("div",{className:"text-center py-4 text-[var(--text-secondary)]",children:"Aucun rôle configuré"})})]})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Shield,{className:"w-5 h-5"}),"Configuration Système"]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"text-center p-4 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{className:"text-3xl font-bold text-purple-600",children:x?.totalRoles??0}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Rôles"})]}),e.jsxs("div",{className:"text-center p-4 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{className:"text-3xl font-bold text-green-600",children:x?.totalPermissions??0}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Permissions"})]}),e.jsxs("div",{className:"text-center p-4 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{className:"text-3xl font-bold text-blue-600",children:x?.usersLoggedInRecently??0}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Connectés récemment"})]}),e.jsxs("div",{className:"text-center p-4 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{className:"text-3xl font-bold text-orange-600",children:v?.totalActiveSessions??0}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Sessions actives"})]})]})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Monitor,{className:"w-5 h-5"}),"Sessions Actives"]}),v&&((v.byBrowser?.length??0)>0||(v.byCountry?.length??0)>0)?e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-2",children:"Par Navigateur"}),e.jsx("div",{className:"space-y-2",children:(v.byBrowser??[]).map(s=>e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{children:s.browser}),e.jsx("span",{className:"font-medium",children:s.count})]},s.browser))})]}),e.jsxs("div",{children:[e.jsxs("h4",{className:"text-sm font-medium text-[var(--text-secondary)] mb-2 flex items-center gap-1",children:[e.jsx(a.Globe,{className:"w-4 h-4"})," Par Pays"]}),e.jsx("div",{className:"space-y-2",children:(v.byCountry?.length??0)>0?(v.byCountry??[]).map(s=>e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{children:s.country}),e.jsx("span",{className:"font-medium",children:s.count})]},s.country)):e.jsx("span",{className:"text-[var(--text-secondary)] text-sm",children:"Non disponible"})})]})]}):e.jsx("div",{className:"text-center py-8 text-[var(--text-secondary)]",children:"Aucune session active"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Monitor,{className:"w-5 h-5"}),"Appareils & Navigateurs"]}),e.jsx(se,{data:G})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Activity,{className:"w-5 h-5"}),"Engagement Utilisateurs"]}),e.jsx(te,{data:X})]})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.TrendingUp,{className:"w-5 h-5"}),"Tendances (",o," derniers jours)"]}),e.jsx("div",{className:"h-64",children:e.jsx(le,{data:H??[]})})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("h3",{className:"font-semibold mb-4 flex items-center gap-2",children:[e.jsx(a.Clock,{className:"w-5 h-5"}),"Dernières Sessions Actives"]}),(R?.length??0)>0?e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[var(--border-color)]",children:[e.jsx("th",{className:"text-left p-3 font-medium",children:"Utilisateur"}),e.jsx("th",{className:"text-right p-3 font-medium",children:"Durée"})]})}),e.jsx("tbody",{children:(R??[]).map(s=>e.jsxs("tr",{className:"border-b border-[var(--border-color)] hover:bg-[var(--bg-secondary)] cursor-pointer",onClick:()=>l(`/administration/users/${s.userId}`),children:[e.jsx("td",{className:"p-3 font-medium",children:s.fullName}),e.jsx("td",{className:"p-3 text-right",children:e.jsx("span",{className:"px-2 py-1 rounded text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400",children:s.duration})})]},s.userId+s.loginAt))})]})}):e.jsx("div",{className:"text-center py-8 text-[var(--text-secondary)]",children:"Aucune session active"})]})]})}function j({title:t,value:l,icon:n,color:r,subtitle:d}){const u={blue:"bg-blue-50 text-blue-600 border-blue-200 dark:bg-blue-900/20 dark:border-blue-800",green:"bg-green-50 text-green-600 border-green-200 dark:bg-green-900/20 dark:border-green-800",yellow:"bg-yellow-50 text-yellow-600 border-yellow-200 dark:bg-yellow-900/20 dark:border-yellow-800",red:"bg-red-50 text-red-600 border-red-200 dark:bg-red-900/20 dark:border-red-800"};return e.jsxs("div",{className:`card p-4 border ${u[r]}`,children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-sm font-medium opacity-80",children:t}),n]}),e.jsx("div",{className:"text-2xl font-bold",children:l}),d&&e.jsx("div",{className:"text-xs opacity-70 mt-1",children:d})]})}function le({data:t}){if(t.length===0)return e.jsx("div",{className:"flex items-center justify-center h-full text-[var(--text-secondary)]",children:"Aucune donnée de tendance disponible"});const l=Math.max(...t.flatMap(n=>[n.newUsers,n.logins]),1);return e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"flex items-center gap-4 mb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-3 h-3 rounded bg-blue-500"}),e.jsx("span",{className:"text-sm",children:"Nouveaux utilisateurs"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-3 h-3 rounded bg-green-500"}),e.jsx("span",{className:"text-sm",children:"Connexions"})]})]}),e.jsx("div",{className:"flex-1 flex items-end gap-1 overflow-x-auto pb-4",children:t.map(n=>e.jsxs("div",{className:"flex-1 min-w-[20px] flex gap-0.5",children:[e.jsx("div",{className:"flex-1 bg-blue-500 rounded-t transition-all duration-300 hover:opacity-80",style:{height:`${n.newUsers/l*100}%`,minHeight:n.newUsers>0?"4px":"0"},title:`Nouveaux: ${n.newUsers}`}),e.jsx("div",{className:"flex-1 bg-green-500 rounded-t transition-all duration-300 hover:opacity-80",style:{height:`${n.logins/l*100}%`,minHeight:n.logins>0?"4px":"0"},title:`Connexions: ${n.logins}`})]},`${n.date}`))}),e.jsxs("div",{className:"flex justify-between text-xs text-[var(--text-secondary)] mt-2",children:[e.jsx("span",{children:t[0]&&new Date(t[0].date).toLocaleDateString("fr-FR")}),e.jsx("span",{children:t.at(-1)&&new Date(t.at(-1).date).toLocaleDateString("fr-FR")})]})]})}exports.AdminDashboardPage=re;
2
+ //# sourceMappingURL=DashboardPage-B_uyyRRE.js.map