@burdenoff/microfe-admin 2026.511.1

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 (370) hide show
  1. package/README.md +74 -0
  2. package/dist/admin/AdminRoot.d.ts +31 -0
  3. package/dist/admin/AdminRoot.d.ts.map +1 -0
  4. package/dist/admin/AdminRoot.js +175 -0
  5. package/dist/admin/AdminRoot.js.map +1 -0
  6. package/dist/admin/AdminRoutes.d.ts +29 -0
  7. package/dist/admin/AdminRoutes.d.ts.map +1 -0
  8. package/dist/admin/AdminRoutes.js +143 -0
  9. package/dist/admin/AdminRoutes.js.map +1 -0
  10. package/dist/admin/components/AccessDenied.d.ts +8 -0
  11. package/dist/admin/components/AccessDenied.d.ts.map +1 -0
  12. package/dist/admin/components/AccessDenied.js +28 -0
  13. package/dist/admin/components/AccessDenied.js.map +1 -0
  14. package/dist/admin/components/ActivityFeed.d.ts +20 -0
  15. package/dist/admin/components/ActivityFeed.d.ts.map +1 -0
  16. package/dist/admin/components/ActivityFeed.js +91 -0
  17. package/dist/admin/components/ActivityFeed.js.map +1 -0
  18. package/dist/admin/components/Charts.d.ts +33 -0
  19. package/dist/admin/components/Charts.d.ts.map +1 -0
  20. package/dist/admin/components/Charts.js +37 -0
  21. package/dist/admin/components/Charts.js.map +1 -0
  22. package/dist/admin/components/ConfirmDialog.d.ts +45 -0
  23. package/dist/admin/components/ConfirmDialog.d.ts.map +1 -0
  24. package/dist/admin/components/ConfirmDialog.js +4 -0
  25. package/dist/admin/components/DataTable.d.ts +64 -0
  26. package/dist/admin/components/DataTable.d.ts.map +1 -0
  27. package/dist/admin/components/DataTable.js +127 -0
  28. package/dist/admin/components/DataTable.js.map +1 -0
  29. package/dist/admin/components/FormSheet.d.ts +79 -0
  30. package/dist/admin/components/FormSheet.d.ts.map +1 -0
  31. package/dist/admin/components/FormSheet.js +111 -0
  32. package/dist/admin/components/FormSheet.js.map +1 -0
  33. package/dist/admin/components/MetricCard.d.ts +40 -0
  34. package/dist/admin/components/MetricCard.d.ts.map +1 -0
  35. package/dist/admin/components/MetricCard.js +57 -0
  36. package/dist/admin/components/MetricCard.js.map +1 -0
  37. package/dist/admin/components/PageLayout.d.ts +34 -0
  38. package/dist/admin/components/PageLayout.d.ts.map +1 -0
  39. package/dist/admin/components/PageLayout.js +31 -0
  40. package/dist/admin/components/PageLayout.js.map +1 -0
  41. package/dist/admin/components/PermissionGuard.d.ts +12 -0
  42. package/dist/admin/components/PermissionGuard.d.ts.map +1 -0
  43. package/dist/admin/components/PermissionGuard.js +18 -0
  44. package/dist/admin/components/PermissionGuard.js.map +1 -0
  45. package/dist/admin/components/RowActions.d.ts +41 -0
  46. package/dist/admin/components/RowActions.d.ts.map +1 -0
  47. package/dist/admin/components/RowActions.js +93 -0
  48. package/dist/admin/components/RowActions.js.map +1 -0
  49. package/dist/admin/components/StatusBadge.d.ts +35 -0
  50. package/dist/admin/components/StatusBadge.d.ts.map +1 -0
  51. package/dist/admin/components/StatusBadge.js +41 -0
  52. package/dist/admin/components/StatusBadge.js.map +1 -0
  53. package/dist/admin/components/Toast.d.ts +26 -0
  54. package/dist/admin/components/Toast.d.ts.map +1 -0
  55. package/dist/admin/components/Toast.js +133 -0
  56. package/dist/admin/components/Toast.js.map +1 -0
  57. package/dist/admin/components/forms/SubscriptionForm.d.ts +57 -0
  58. package/dist/admin/components/forms/SubscriptionForm.d.ts.map +1 -0
  59. package/dist/admin/components/forms/SubscriptionForm.js +299 -0
  60. package/dist/admin/components/forms/SubscriptionForm.js.map +1 -0
  61. package/dist/admin/components/forms/TenantForm.d.ts +68 -0
  62. package/dist/admin/components/forms/TenantForm.d.ts.map +1 -0
  63. package/dist/admin/components/forms/TenantForm.js +346 -0
  64. package/dist/admin/components/forms/TenantForm.js.map +1 -0
  65. package/dist/admin/components/forms/TicketForm.d.ts +67 -0
  66. package/dist/admin/components/forms/TicketForm.d.ts.map +1 -0
  67. package/dist/admin/components/forms/TicketForm.js +55 -0
  68. package/dist/admin/components/forms/TicketForm.js.map +1 -0
  69. package/dist/admin/components/forms/UserForm.d.ts +57 -0
  70. package/dist/admin/components/forms/UserForm.d.ts.map +1 -0
  71. package/dist/admin/components/forms/UserForm.js +253 -0
  72. package/dist/admin/components/forms/UserForm.js.map +1 -0
  73. package/dist/admin/components/forms/index.d.ts +5 -0
  74. package/dist/admin/components/forms/index.d.ts.map +1 -0
  75. package/dist/admin/components/forms/index.js +4 -0
  76. package/dist/admin/components/index.d.ts +15 -0
  77. package/dist/admin/components/index.d.ts.map +1 -0
  78. package/dist/admin/components/index.js +17 -0
  79. package/dist/admin/components/ui.d.ts +52 -0
  80. package/dist/admin/components/ui.d.ts.map +1 -0
  81. package/dist/admin/components/ui.js +140 -0
  82. package/dist/admin/components/ui.js.map +1 -0
  83. package/dist/admin/constants/index.d.ts +75 -0
  84. package/dist/admin/constants/index.d.ts.map +1 -0
  85. package/dist/admin/constants/index.js +90 -0
  86. package/dist/admin/constants/index.js.map +1 -0
  87. package/dist/admin/constants/permissions.d.ts +27 -0
  88. package/dist/admin/constants/permissions.d.ts.map +1 -0
  89. package/dist/admin/constants/permissions.js +23 -0
  90. package/dist/admin/constants/permissions.js.map +1 -0
  91. package/dist/admin/hooks/useAdminPermissions.d.ts +30 -0
  92. package/dist/admin/hooks/useAdminPermissions.d.ts.map +1 -0
  93. package/dist/admin/hooks/useAdminPermissions.js +56 -0
  94. package/dist/admin/hooks/useAdminPermissions.js.map +1 -0
  95. package/dist/admin/index.d.ts +31 -0
  96. package/dist/admin/index.d.ts.map +1 -0
  97. package/dist/admin/index.js +9 -0
  98. package/dist/admin/pages/AuditLogsPage.d.ts +5 -0
  99. package/dist/admin/pages/AuditLogsPage.d.ts.map +1 -0
  100. package/dist/admin/pages/AuditLogsPage.js +209 -0
  101. package/dist/admin/pages/AuditLogsPage.js.map +1 -0
  102. package/dist/admin/pages/BillingPage.d.ts +2 -0
  103. package/dist/admin/pages/BillingPage.d.ts.map +1 -0
  104. package/dist/admin/pages/BillingPage.js +164 -0
  105. package/dist/admin/pages/BillingPage.js.map +1 -0
  106. package/dist/admin/pages/CommunicationsPage.d.ts +2 -0
  107. package/dist/admin/pages/CommunicationsPage.d.ts.map +1 -0
  108. package/dist/admin/pages/CommunicationsPage.js +118 -0
  109. package/dist/admin/pages/CommunicationsPage.js.map +1 -0
  110. package/dist/admin/pages/DashboardPage.d.ts +5 -0
  111. package/dist/admin/pages/DashboardPage.d.ts.map +1 -0
  112. package/dist/admin/pages/DashboardPage.js +121 -0
  113. package/dist/admin/pages/DashboardPage.js.map +1 -0
  114. package/dist/admin/pages/FeatureFlagsPage.d.ts +2 -0
  115. package/dist/admin/pages/FeatureFlagsPage.d.ts.map +1 -0
  116. package/dist/admin/pages/FeatureFlagsPage.js +116 -0
  117. package/dist/admin/pages/FeatureFlagsPage.js.map +1 -0
  118. package/dist/admin/pages/OrganizationsListPage.d.ts +2 -0
  119. package/dist/admin/pages/OrganizationsListPage.d.ts.map +1 -0
  120. package/dist/admin/pages/OrganizationsListPage.js +112 -0
  121. package/dist/admin/pages/OrganizationsListPage.js.map +1 -0
  122. package/dist/admin/pages/ProductsPage.d.ts +5 -0
  123. package/dist/admin/pages/ProductsPage.d.ts.map +1 -0
  124. package/dist/admin/pages/ProductsPage.js +392 -0
  125. package/dist/admin/pages/ProductsPage.js.map +1 -0
  126. package/dist/admin/pages/ReferralsPage.d.ts +2 -0
  127. package/dist/admin/pages/ReferralsPage.d.ts.map +1 -0
  128. package/dist/admin/pages/ReferralsPage.js +272 -0
  129. package/dist/admin/pages/ReferralsPage.js.map +1 -0
  130. package/dist/admin/pages/RolesPermissionsPage.d.ts +2 -0
  131. package/dist/admin/pages/RolesPermissionsPage.d.ts.map +1 -0
  132. package/dist/admin/pages/RolesPermissionsPage.js +145 -0
  133. package/dist/admin/pages/RolesPermissionsPage.js.map +1 -0
  134. package/dist/admin/pages/SREPage.d.ts +5 -0
  135. package/dist/admin/pages/SREPage.d.ts.map +1 -0
  136. package/dist/admin/pages/SREPage.js +405 -0
  137. package/dist/admin/pages/SREPage.js.map +1 -0
  138. package/dist/admin/pages/SandboxSettingsPage.d.ts +7 -0
  139. package/dist/admin/pages/SandboxSettingsPage.d.ts.map +1 -0
  140. package/dist/admin/pages/SandboxSettingsPage.js +497 -0
  141. package/dist/admin/pages/SandboxSettingsPage.js.map +1 -0
  142. package/dist/admin/pages/SettingsPage.d.ts +5 -0
  143. package/dist/admin/pages/SettingsPage.d.ts.map +1 -0
  144. package/dist/admin/pages/SettingsPage.js +279 -0
  145. package/dist/admin/pages/SettingsPage.js.map +1 -0
  146. package/dist/admin/pages/TenantDetailPage.d.ts +5 -0
  147. package/dist/admin/pages/TenantDetailPage.d.ts.map +1 -0
  148. package/dist/admin/pages/TenantDetailPage.js +274 -0
  149. package/dist/admin/pages/TenantDetailPage.js.map +1 -0
  150. package/dist/admin/pages/TenantFormRoutePage.d.ts +6 -0
  151. package/dist/admin/pages/TenantFormRoutePage.d.ts.map +1 -0
  152. package/dist/admin/pages/TenantFormRoutePage.js +136 -0
  153. package/dist/admin/pages/TenantFormRoutePage.js.map +1 -0
  154. package/dist/admin/pages/TenantsListPage.d.ts +5 -0
  155. package/dist/admin/pages/TenantsListPage.d.ts.map +1 -0
  156. package/dist/admin/pages/TenantsListPage.js +339 -0
  157. package/dist/admin/pages/TenantsListPage.js.map +1 -0
  158. package/dist/admin/pages/UsersListPage.d.ts +5 -0
  159. package/dist/admin/pages/UsersListPage.d.ts.map +1 -0
  160. package/dist/admin/pages/UsersListPage.js +250 -0
  161. package/dist/admin/pages/UsersListPage.js.map +1 -0
  162. package/dist/admin/pages/WaitlistPage.d.ts +2 -0
  163. package/dist/admin/pages/WaitlistPage.d.ts.map +1 -0
  164. package/dist/admin/pages/WaitlistPage.js +241 -0
  165. package/dist/admin/pages/WaitlistPage.js.map +1 -0
  166. package/dist/admin/pages/WorkflowsPage.d.ts +2 -0
  167. package/dist/admin/pages/WorkflowsPage.d.ts.map +1 -0
  168. package/dist/admin/pages/WorkflowsPage.js +126 -0
  169. package/dist/admin/pages/WorkflowsPage.js.map +1 -0
  170. package/dist/admin/pages/WorkspacesListPage.d.ts +2 -0
  171. package/dist/admin/pages/WorkspacesListPage.d.ts.map +1 -0
  172. package/dist/admin/pages/WorkspacesListPage.js +100 -0
  173. package/dist/admin/pages/WorkspacesListPage.js.map +1 -0
  174. package/dist/admin/pages/index.d.ts +20 -0
  175. package/dist/admin/pages/index.d.ts.map +1 -0
  176. package/dist/admin/pages/index.js +19 -0
  177. package/dist/admin/providers/AdminProvider.d.ts +13 -0
  178. package/dist/admin/providers/AdminProvider.d.ts.map +1 -0
  179. package/dist/admin/providers/AdminProvider.js +43 -0
  180. package/dist/admin/providers/AdminProvider.js.map +1 -0
  181. package/dist/admin/schemas/index.d.ts +409 -0
  182. package/dist/admin/schemas/index.d.ts.map +1 -0
  183. package/dist/admin/schemas/index.js +111 -0
  184. package/dist/admin/schemas/index.js.map +1 -0
  185. package/dist/admin/store/adminStore.d.ts +28 -0
  186. package/dist/admin/store/adminStore.d.ts.map +1 -0
  187. package/dist/admin/store/adminStore.js +48 -0
  188. package/dist/admin/store/adminStore.js.map +1 -0
  189. package/dist/admin/types/index.d.ts +325 -0
  190. package/dist/admin/types/index.d.ts.map +1 -0
  191. package/dist/admin/utils/cn.d.ts +7 -0
  192. package/dist/admin/utils/cn.d.ts.map +1 -0
  193. package/dist/admin/utils/cn.js +10 -0
  194. package/dist/admin/utils/cn.js.map +1 -0
  195. package/dist/admin/utils/directActivityGraphql.d.ts +11 -0
  196. package/dist/admin/utils/directActivityGraphql.d.ts.map +1 -0
  197. package/dist/admin/utils/directActivityGraphql.js +25 -0
  198. package/dist/admin/utils/directActivityGraphql.js.map +1 -0
  199. package/dist/admin/utils/formatters.d.ts +33 -0
  200. package/dist/admin/utils/formatters.d.ts.map +1 -0
  201. package/dist/admin/utils/formatters.js +54 -0
  202. package/dist/admin/utils/formatters.js.map +1 -0
  203. package/dist/admin/utils/gatewayGraphql.d.ts +9 -0
  204. package/dist/admin/utils/gatewayGraphql.d.ts.map +1 -0
  205. package/dist/admin/utils/i18n.d.ts +6 -0
  206. package/dist/admin/utils/i18n.d.ts.map +1 -0
  207. package/dist/admin/utils/i18n.js +15 -0
  208. package/dist/admin/utils/i18n.js.map +1 -0
  209. package/dist/admin/utils/mappers.d.ts +15 -0
  210. package/dist/admin/utils/mappers.d.ts.map +1 -0
  211. package/dist/admin/utils/mappers.js +73 -0
  212. package/dist/admin/utils/mappers.js.map +1 -0
  213. package/dist/admin/utils/navigation.d.ts +9 -0
  214. package/dist/admin/utils/navigation.d.ts.map +1 -0
  215. package/dist/admin/utils/navigation.js +8 -0
  216. package/dist/admin/utils/navigation.js.map +1 -0
  217. package/dist/admin/utils/tenantEvents.d.ts +11 -0
  218. package/dist/admin/utils/tenantEvents.d.ts.map +1 -0
  219. package/dist/admin/utils/tenantEvents.js +8 -0
  220. package/dist/admin/utils/tenantEvents.js.map +1 -0
  221. package/dist/dev/main.d.ts +2 -0
  222. package/dist/dev/main.d.ts.map +1 -0
  223. package/dist/generated/global-operations.d.ts +2749 -0
  224. package/dist/generated/global-operations.d.ts.map +1 -0
  225. package/dist/generated/global-operations.js +907 -0
  226. package/dist/generated/global-operations.js.map +1 -0
  227. package/dist/generated/global-types.d.ts +20773 -0
  228. package/dist/generated/global-types.d.ts.map +1 -0
  229. package/dist/generated/global-types.js +12 -0
  230. package/dist/generated/global-types.js.map +1 -0
  231. package/dist/generated/wspace-operations.d.ts +132 -0
  232. package/dist/generated/wspace-operations.d.ts.map +1 -0
  233. package/dist/generated/wspace-operations.js +65 -0
  234. package/dist/generated/wspace-operations.js.map +1 -0
  235. package/dist/generated/wspace-types.d.ts +53363 -0
  236. package/dist/generated/wspace-types.d.ts.map +1 -0
  237. package/dist/index.d.ts +6 -0
  238. package/dist/index.d.ts.map +1 -0
  239. package/dist/index.js +10 -0
  240. package/dist/node_modules/@hookform/resolvers/dist/resolvers.js +34 -0
  241. package/dist/node_modules/@hookform/resolvers/dist/resolvers.js.map +1 -0
  242. package/dist/node_modules/@hookform/resolvers/zod/dist/zod.js +118 -0
  243. package/dist/node_modules/@hookform/resolvers/zod/dist/zod.js.map +1 -0
  244. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  245. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  246. package/dist/node_modules/date-fns/_lib/addLeadingZeros.js +8 -0
  247. package/dist/node_modules/date-fns/_lib/addLeadingZeros.js.map +1 -0
  248. package/dist/node_modules/date-fns/_lib/defaultOptions.js +9 -0
  249. package/dist/node_modules/date-fns/_lib/defaultOptions.js.map +1 -0
  250. package/dist/node_modules/date-fns/_lib/format/formatters.js +384 -0
  251. package/dist/node_modules/date-fns/_lib/format/formatters.js.map +1 -0
  252. package/dist/node_modules/date-fns/_lib/format/lightFormatters.js +45 -0
  253. package/dist/node_modules/date-fns/_lib/format/lightFormatters.js.map +1 -0
  254. package/dist/node_modules/date-fns/_lib/format/longFormatters.js +42 -0
  255. package/dist/node_modules/date-fns/_lib/format/longFormatters.js.map +1 -0
  256. package/dist/node_modules/date-fns/_lib/getRoundingMethod.js +11 -0
  257. package/dist/node_modules/date-fns/_lib/getRoundingMethod.js.map +1 -0
  258. package/dist/node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js +10 -0
  259. package/dist/node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js.map +1 -0
  260. package/dist/node_modules/date-fns/_lib/normalizeDates.js +10 -0
  261. package/dist/node_modules/date-fns/_lib/normalizeDates.js.map +1 -0
  262. package/dist/node_modules/date-fns/_lib/protectedTokens.js +25 -0
  263. package/dist/node_modules/date-fns/_lib/protectedTokens.js.map +1 -0
  264. package/dist/node_modules/date-fns/compareAsc.js +10 -0
  265. package/dist/node_modules/date-fns/compareAsc.js.map +1 -0
  266. package/dist/node_modules/date-fns/constants.js +8 -0
  267. package/dist/node_modules/date-fns/constants.js.map +1 -0
  268. package/dist/node_modules/date-fns/constructFrom.js +9 -0
  269. package/dist/node_modules/date-fns/constructFrom.js.map +1 -0
  270. package/dist/node_modules/date-fns/constructNow.js +9 -0
  271. package/dist/node_modules/date-fns/constructNow.js.map +1 -0
  272. package/dist/node_modules/date-fns/differenceInCalendarDays.js +13 -0
  273. package/dist/node_modules/date-fns/differenceInCalendarDays.js.map +1 -0
  274. package/dist/node_modules/date-fns/differenceInCalendarMonths.js +10 -0
  275. package/dist/node_modules/date-fns/differenceInCalendarMonths.js.map +1 -0
  276. package/dist/node_modules/date-fns/differenceInMilliseconds.js +9 -0
  277. package/dist/node_modules/date-fns/differenceInMilliseconds.js.map +1 -0
  278. package/dist/node_modules/date-fns/differenceInMonths.js +18 -0
  279. package/dist/node_modules/date-fns/differenceInMonths.js.map +1 -0
  280. package/dist/node_modules/date-fns/differenceInSeconds.js +11 -0
  281. package/dist/node_modules/date-fns/differenceInSeconds.js.map +1 -0
  282. package/dist/node_modules/date-fns/endOfDay.js +10 -0
  283. package/dist/node_modules/date-fns/endOfDay.js.map +1 -0
  284. package/dist/node_modules/date-fns/endOfMonth.js +10 -0
  285. package/dist/node_modules/date-fns/endOfMonth.js.map +1 -0
  286. package/dist/node_modules/date-fns/format.js +61 -0
  287. package/dist/node_modules/date-fns/format.js.map +1 -0
  288. package/dist/node_modules/date-fns/formatDistance.js +39 -0
  289. package/dist/node_modules/date-fns/formatDistance.js.map +1 -0
  290. package/dist/node_modules/date-fns/formatDistanceToNow.js +10 -0
  291. package/dist/node_modules/date-fns/formatDistanceToNow.js.map +1 -0
  292. package/dist/node_modules/date-fns/getDayOfYear.js +12 -0
  293. package/dist/node_modules/date-fns/getDayOfYear.js.map +1 -0
  294. package/dist/node_modules/date-fns/getISOWeek.js +13 -0
  295. package/dist/node_modules/date-fns/getISOWeek.js.map +1 -0
  296. package/dist/node_modules/date-fns/getISOWeekYear.js +16 -0
  297. package/dist/node_modules/date-fns/getISOWeekYear.js.map +1 -0
  298. package/dist/node_modules/date-fns/getWeek.js +13 -0
  299. package/dist/node_modules/date-fns/getWeek.js.map +1 -0
  300. package/dist/node_modules/date-fns/getWeekYear.js +17 -0
  301. package/dist/node_modules/date-fns/getWeekYear.js.map +1 -0
  302. package/dist/node_modules/date-fns/isDate.js +8 -0
  303. package/dist/node_modules/date-fns/isDate.js.map +1 -0
  304. package/dist/node_modules/date-fns/isLastDayOfMonth.js +12 -0
  305. package/dist/node_modules/date-fns/isLastDayOfMonth.js.map +1 -0
  306. package/dist/node_modules/date-fns/isValid.js +10 -0
  307. package/dist/node_modules/date-fns/isValid.js.map +1 -0
  308. package/dist/node_modules/date-fns/locale/_lib/buildFormatLongFn.js +11 -0
  309. package/dist/node_modules/date-fns/locale/_lib/buildFormatLongFn.js.map +1 -0
  310. package/dist/node_modules/date-fns/locale/_lib/buildLocalizeFn.js +19 -0
  311. package/dist/node_modules/date-fns/locale/_lib/buildLocalizeFn.js.map +1 -0
  312. package/dist/node_modules/date-fns/locale/_lib/buildMatchFn.js +24 -0
  313. package/dist/node_modules/date-fns/locale/_lib/buildMatchFn.js.map +1 -0
  314. package/dist/node_modules/date-fns/locale/_lib/buildMatchPatternFn.js +20 -0
  315. package/dist/node_modules/date-fns/locale/_lib/buildMatchPatternFn.js.map +1 -0
  316. package/dist/node_modules/date-fns/locale/en-US/_lib/formatDistance.js +71 -0
  317. package/dist/node_modules/date-fns/locale/en-US/_lib/formatDistance.js.map +1 -0
  318. package/dist/node_modules/date-fns/locale/en-US/_lib/formatLong.js +34 -0
  319. package/dist/node_modules/date-fns/locale/en-US/_lib/formatLong.js.map +1 -0
  320. package/dist/node_modules/date-fns/locale/en-US/_lib/formatRelative.js +13 -0
  321. package/dist/node_modules/date-fns/locale/en-US/_lib/formatRelative.js.map +1 -0
  322. package/dist/node_modules/date-fns/locale/en-US/_lib/localize.js +204 -0
  323. package/dist/node_modules/date-fns/locale/en-US/_lib/localize.js.map +1 -0
  324. package/dist/node_modules/date-fns/locale/en-US/_lib/match.js +126 -0
  325. package/dist/node_modules/date-fns/locale/en-US/_lib/match.js.map +1 -0
  326. package/dist/node_modules/date-fns/locale/en-US.js +22 -0
  327. package/dist/node_modules/date-fns/locale/en-US.js.map +1 -0
  328. package/dist/node_modules/date-fns/parseISO.js +119 -0
  329. package/dist/node_modules/date-fns/parseISO.js.map +1 -0
  330. package/dist/node_modules/date-fns/startOfDay.js +10 -0
  331. package/dist/node_modules/date-fns/startOfDay.js.map +1 -0
  332. package/dist/node_modules/date-fns/startOfISOWeek.js +12 -0
  333. package/dist/node_modules/date-fns/startOfISOWeek.js.map +1 -0
  334. package/dist/node_modules/date-fns/startOfISOWeekYear.js +12 -0
  335. package/dist/node_modules/date-fns/startOfISOWeekYear.js.map +1 -0
  336. package/dist/node_modules/date-fns/startOfWeek.js +11 -0
  337. package/dist/node_modules/date-fns/startOfWeek.js.map +1 -0
  338. package/dist/node_modules/date-fns/startOfWeekYear.js +13 -0
  339. package/dist/node_modules/date-fns/startOfWeekYear.js.map +1 -0
  340. package/dist/node_modules/date-fns/startOfYear.js +10 -0
  341. package/dist/node_modules/date-fns/startOfYear.js.map +1 -0
  342. package/dist/node_modules/date-fns/toDate.js +9 -0
  343. package/dist/node_modules/date-fns/toDate.js.map +1 -0
  344. package/dist/node_modules/react-hook-form/dist/index.esm.js +1210 -0
  345. package/dist/node_modules/react-hook-form/dist/index.esm.js.map +1 -0
  346. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
  347. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  348. package/dist/node_modules/zod/v3/ZodError.js +82 -0
  349. package/dist/node_modules/zod/v3/ZodError.js.map +1 -0
  350. package/dist/node_modules/zod/v3/errors.js +10 -0
  351. package/dist/node_modules/zod/v3/errors.js.map +1 -0
  352. package/dist/node_modules/zod/v3/helpers/errorUtil.js +9 -0
  353. package/dist/node_modules/zod/v3/helpers/errorUtil.js.map +1 -0
  354. package/dist/node_modules/zod/v3/helpers/parseUtil.js +93 -0
  355. package/dist/node_modules/zod/v3/helpers/parseUtil.js.map +1 -0
  356. package/dist/node_modules/zod/v3/helpers/util.js +76 -0
  357. package/dist/node_modules/zod/v3/helpers/util.js.map +1 -0
  358. package/dist/node_modules/zod/v3/locales/en.js +62 -0
  359. package/dist/node_modules/zod/v3/locales/en.js.map +1 -0
  360. package/dist/node_modules/zod/v3/types.js +2459 -0
  361. package/dist/node_modules/zod/v3/types.js.map +1 -0
  362. package/dist/node_modules/zod/v4/core/core.js +35 -0
  363. package/dist/node_modules/zod/v4/core/core.js.map +1 -0
  364. package/dist/node_modules/zod/v4/core/errors.js +24 -0
  365. package/dist/node_modules/zod/v4/core/errors.js.map +1 -0
  366. package/dist/node_modules/zod/v4/core/parse.js +29 -0
  367. package/dist/node_modules/zod/v4/core/parse.js.map +1 -0
  368. package/dist/node_modules/zod/v4/core/util.js +20 -0
  369. package/dist/node_modules/zod/v4/core/util.js.map +1 -0
  370. package/package.json +111 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantDetailPage.js","names":[],"sources":["../../../src/admin/pages/TenantDetailPage.tsx"],"sourcesContent":["import { useParams, useNavigate } from 'react-router-dom';\nimport {\n ArrowLeft,\n Building2,\n Users,\n Mail,\n Calendar,\n Globe,\n Settings,\n Ban,\n CheckCircle,\n Loader2,\n} from 'lucide-react';\nimport { useAdmin } from '../providers/AdminProvider';\nimport { useAdminPermissions } from '../hooks/useAdminPermissions';\nimport {\n PageLayout,\n Button,\n Card,\n CardHeader,\n CardTitle,\n CardContent,\n Avatar,\n TenantStatusBadge,\n Separator,\n useToast,\n PermissionGuard,\n} from '../components';\nimport { joinPath } from '../utils/navigation';\nimport { formatDate } from '../utils/formatters';\nimport { mapTenantToUi } from '../utils/mappers';\nimport type { Tenant } from '../types';\nimport {\n useGetTenantQuery,\n useSuspendTenantMutation,\n useActivateTenantMutation,\n} from '../../generated/global-operations';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport { tWithFallback } from '../utils/i18n';\nimport { emitTenantLifecycle } from '../utils/tenantEvents';\n\n/**\n * Tenant detail page\n */\nexport function TenantDetailPage() {\n const { canViewTenants, canManageTenants, isLoading: permissionsLoading } = useAdminPermissions();\n\n const { tenantId } = useParams<{ tenantId: string }>();\n const navigate = useNavigate();\n const { basePath = '' } = useAdmin();\n const toast = useToast();\n const { t } = useI18n();\n const tr = (key: string, fallback: string, params?: Record<string, string | number>): string =>\n tWithFallback(t, key, fallback, params);\n\n const { data, loading, error } = useGetTenantQuery({\n variables: { id: tenantId! },\n skip: !tenantId || permissionsLoading || !canViewTenants,\n fetchPolicy: 'cache-and-network',\n });\n\n const [suspendTenant, { loading: suspending }] = useSuspendTenantMutation();\n const [activateTenant, { loading: activating }] = useActivateTenantMutation();\n const events = useEventBus();\n\n const tenant: Tenant | null = data?.tenant ? mapTenantToUi(data.tenant) : null;\n\n const handleSuspend = async () => {\n if (!tenantId) return;\n // Capture before the await: a refetch could null `tenant` mid-mutation,\n // and we want consumers of `tenant.tenant.suspended` to see the slug as\n // it was when the user clicked suspend.\n const slugAtClick = tenant?.slug;\n try {\n await suspendTenant({ variables: { id: tenantId } });\n emitTenantLifecycle(events, 'tenant.tenant.suspended', {\n tenantId,\n tenantSlug: slugAtClick,\n status: 'SUSPENDED',\n });\n toast.success(\n tr('admin.tenantDetail.toast.suspendedTitle', 'Tenant suspended'),\n tr('admin.tenantDetail.toast.suspendedDescription', '{{name}} has been suspended.', {\n name: tenant?.name ?? '',\n })\n );\n } catch (err) {\n toast.error(\n tr('admin.tenantDetail.toast.errorTitle', 'Error'),\n err instanceof Error\n ? err.message\n : tr('admin.tenantDetail.toast.suspendFailed', 'Failed to suspend tenant.')\n );\n }\n };\n\n const handleActivate = async () => {\n if (!tenantId) return;\n const slugAtClick = tenant?.slug;\n try {\n await activateTenant({ variables: { id: tenantId } });\n emitTenantLifecycle(events, 'tenant.tenant.activated', {\n tenantId,\n tenantSlug: slugAtClick,\n status: 'ACTIVE',\n });\n toast.success(\n tr('admin.tenantDetail.toast.activatedTitle', 'Tenant activated'),\n tr('admin.tenantDetail.toast.activatedDescription', '{{name}} has been activated.', {\n name: tenant?.name ?? '',\n })\n );\n } catch (err) {\n toast.error(\n tr('admin.tenantDetail.toast.errorTitle', 'Error'),\n err instanceof Error\n ? err.message\n : tr('admin.tenantDetail.toast.activateFailed', 'Failed to activate tenant.')\n );\n }\n };\n\n const workspaces = data?.tenant?.workspaces ?? [];\n\n return (\n <PermissionGuard\n allowed={canViewTenants}\n isLoading={permissionsLoading}\n pageTitle={tr('admin.tenantDetail.pageTitle', 'Tenant Details')}\n denyMessage={tr(\n 'admin.tenantDetail.denyMessage',\n \"You don't have permission to view tenant details.\"\n )}\n >\n {loading ? (\n <PageLayout title={tr('admin.tenantDetail.loadingTitle', 'Loading...')}>\n <div className=\"flex h-64 items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n </PageLayout>\n ) : error || !tenant ? (\n <PageLayout\n title={tr('admin.tenantDetail.notFoundTitle', 'Tenant Not Found')}\n description={tr(\n 'admin.tenantDetail.notFoundDescription',\n 'The requested tenant could not be found'\n )}\n >\n {error && (\n <div className=\"mb-4 rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive\">\n {error.message}\n </div>\n )}\n <Button variant=\"outline\" onClick={() => navigate(joinPath(basePath, 'tenants'))}>\n <ArrowLeft className=\"mr-2 h-4 w-4\" />\n {tr('admin.tenantDetail.backToTenants', 'Back to Tenants')}\n </Button>\n </PageLayout>\n ) : (\n <PageLayout\n title={tenant.name}\n description={tr('admin.tenantDetail.tenantId', 'Tenant ID: {{id}}', { id: tenant.id })}\n actions={\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" onClick={() => navigate(joinPath(basePath, 'tenants'))}>\n <ArrowLeft className=\"mr-2 h-4 w-4\" />\n {tr('admin.tenantDetail.back', 'Back')}\n </Button>\n {canManageTenants && (\n <Button\n variant=\"outline\"\n onClick={() => navigate(joinPath(basePath, `tenants/${tenant.id}/edit`))}\n >\n <Settings className=\"mr-2 h-4 w-4\" />\n {tr('admin.tenantDetail.edit', 'Edit')}\n </Button>\n )}\n {canManageTenants &&\n (tenant.status === 'active' ? (\n <Button\n variant=\"outline\"\n className=\"text-warning\"\n onClick={handleSuspend}\n disabled={suspending}\n >\n {suspending ? (\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n ) : (\n <Ban className=\"mr-2 h-4 w-4\" />\n )}\n {tr('admin.tenantDetail.suspend', 'Suspend')}\n </Button>\n ) : (\n <Button\n variant=\"outline\"\n className=\"text-success\"\n onClick={handleActivate}\n disabled={activating}\n >\n {activating ? (\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n ) : (\n <CheckCircle className=\"mr-2 h-4 w-4\" />\n )}\n {tr('admin.tenantDetail.activate', 'Activate')}\n </Button>\n ))}\n </div>\n }\n >\n <div className=\"grid gap-6 lg:grid-cols-3\">\n {/* Main Info */}\n <div className=\"space-y-6 lg:col-span-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-lg\">\n {tr('admin.tenantDetail.overview.title', 'Overview')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-start gap-4\">\n <Avatar fallback={tenant.name.slice(0, 2).toUpperCase()} size=\"lg\" />\n <div className=\"flex-1 space-y-4\">\n <div>\n <h2 className=\"text-xl font-semibold text-foreground\">{tenant.name}</h2>\n <p className=\"text-sm text-muted-foreground\">@{tenant.slug}</p>\n </div>\n <div className=\"flex flex-wrap items-center gap-4\">\n <TenantStatusBadge status={tenant.status} />\n {tenant.plan && (\n <span className=\"rounded-md bg-primary/10 px-2 py-1 text-xs font-medium text-primary\">\n {tenant.plan}\n </span>\n )}\n </div>\n </div>\n </div>\n\n <Separator className=\"my-6\" />\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {tenant.ownerEmail && (\n <div className=\"flex items-center gap-3\">\n <Mail className=\"h-4 w-4 text-muted-foreground\" />\n <div>\n <p className=\"text-xs text-muted-foreground\">\n {tr('admin.tenantDetail.overview.ownerEmail', 'Owner Email')}\n </p>\n <p className=\"text-sm font-medium\">{tenant.ownerEmail}</p>\n </div>\n </div>\n )}\n {tenant.domain && (\n <div className=\"flex items-center gap-3\">\n <Globe className=\"h-4 w-4 text-muted-foreground\" />\n <div>\n <p className=\"text-xs text-muted-foreground\">\n {tr('admin.tenantDetail.overview.domain', 'Domain')}\n </p>\n <p className=\"text-sm font-medium\">{tenant.domain}</p>\n </div>\n </div>\n )}\n <div className=\"flex items-center gap-3\">\n <Calendar className=\"h-4 w-4 text-muted-foreground\" />\n <div>\n <p className=\"text-xs text-muted-foreground\">\n {tr('admin.tenantDetail.overview.created', 'Created')}\n </p>\n <p className=\"text-sm font-medium\">{formatDate(tenant.createdAt)}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <Calendar className=\"h-4 w-4 text-muted-foreground\" />\n <div>\n <p className=\"text-xs text-muted-foreground\">\n {tr('admin.tenantDetail.overview.lastUpdated', 'Last Updated')}\n </p>\n <p className=\"text-sm font-medium\">{formatDate(tenant.updatedAt)}</p>\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {/* Workspaces */}\n {workspaces.length > 0 && (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-lg\">\n {tr('admin.tenantDetail.workspaces.title', 'Workspaces ({{count}})', {\n count: workspaces.length,\n })}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n {workspaces.map(\n (ws: { id: string; name: string; status?: string | null }) => (\n <div\n key={ws.id}\n className=\"flex items-center justify-between rounded-lg border border-border p-3\"\n >\n <span className=\"text-sm font-medium\">{ws.name}</span>\n <span className=\"text-xs text-muted-foreground capitalize\">\n {ws.status?.toLowerCase()}\n </span>\n </div>\n )\n )}\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Config */}\n {tenant.settings && (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-lg\">\n {tr('admin.tenantDetail.settings.title', 'Settings')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"flex items-center justify-between rounded-lg border border-border p-3\">\n <span className=\"text-sm\">\n {tr('admin.tenantDetail.settings.allowSignup', 'Allow Signup')}\n </span>\n <span\n className={`text-sm font-medium ${\n tenant.settings?.allowSignup ? 'text-success' : 'text-muted-foreground'\n }`}\n >\n {tenant.settings?.allowSignup\n ? tr('admin.tenantDetail.settings.enabled', 'Enabled')\n : tr('admin.tenantDetail.settings.disabled', 'Disabled')}\n </span>\n </div>\n <div className=\"flex items-center justify-between rounded-lg border border-border p-3\">\n <span className=\"text-sm\">\n {tr('admin.tenantDetail.settings.sso', 'SSO')}\n </span>\n <span\n className={`text-sm font-medium ${\n tenant.settings?.ssoEnabled ? 'text-success' : 'text-muted-foreground'\n }`}\n >\n {tenant.settings?.ssoEnabled\n ? tr('admin.tenantDetail.settings.enabled', 'Enabled')\n : tr('admin.tenantDetail.settings.disabled', 'Disabled')}\n </span>\n </div>\n <div className=\"flex items-center justify-between rounded-lg border border-border p-3\">\n <span className=\"text-sm\">\n {tr('admin.tenantDetail.settings.mfaRequired', 'MFA Required')}\n </span>\n <span\n className={`text-sm font-medium ${\n tenant.settings?.mfaRequired ? 'text-success' : 'text-muted-foreground'\n }`}\n >\n {tenant.settings?.mfaRequired\n ? tr('admin.tenantDetail.settings.yes', 'Yes')\n : tr('admin.tenantDetail.settings.no', 'No')}\n </span>\n </div>\n <div className=\"flex items-center justify-between rounded-lg border border-border p-3\">\n <span className=\"text-sm\">\n {tr('admin.tenantDetail.settings.dataRetention', 'Data Retention')}\n </span>\n <span className=\"text-sm font-medium\">\n {tr('admin.tenantDetail.settings.dataRetentionDays', '{{days}} days', {\n days: tenant.settings?.dataRetentionDays ?? 0,\n })}\n </span>\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Actions */}\n <Card>\n <CardHeader>\n <CardTitle className=\"text-lg\">\n {tr('admin.tenantDetail.actions.title', 'Actions')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <Button\n variant=\"outline\"\n className=\"w-full justify-start\"\n onClick={() => navigate(joinPath(basePath, `users?tenantId=${tenant.id}`))}\n >\n <Users className=\"mr-2 h-4 w-4\" />\n {tr('admin.tenantDetail.actions.viewUsers', 'View Users')}\n </Button>\n <Button\n variant=\"outline\"\n className=\"w-full justify-start\"\n onClick={() =>\n navigate(joinPath(basePath, `billing/subscriptions?tenantId=${tenant.id}`))\n }\n >\n <Building2 className=\"mr-2 h-4 w-4\" />\n {tr('admin.tenantDetail.actions.viewBilling', 'View Billing')}\n </Button>\n </CardContent>\n </Card>\n </div>\n </div>\n </PageLayout>\n )}\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ type TenantFormRoutePageProps = {
2
+ mode: 'create' | 'edit';
3
+ };
4
+ export declare function TenantFormRoutePage({ mode }: TenantFormRoutePageProps): import("react/jsx-runtime").JSX.Element;
5
+ export {};
6
+ //# sourceMappingURL=TenantFormRoutePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantFormRoutePage.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/TenantFormRoutePage.tsx"],"names":[],"mappings":"AAoBA,KAAK,wBAAwB,GAAG;IAC9B,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;CACzB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,EAAE,wBAAwB,2CAmQrE"}
@@ -0,0 +1,136 @@
1
+ import { useToast as e } from "../components/Toast.js";
2
+ import { useAdmin as t } from "../providers/AdminProvider.js";
3
+ import { useAdminPermissions as n } from "../hooks/useAdminPermissions.js";
4
+ import { Button as r } from "../components/ui.js";
5
+ import { PageLayout as i } from "../components/PageLayout.js";
6
+ import { tWithFallback as a } from "../utils/i18n.js";
7
+ import { TenantForm as o } from "../components/forms/TenantForm.js";
8
+ import { PermissionGuard as s } from "../components/PermissionGuard.js";
9
+ import "../components/index.js";
10
+ import { joinPath as c } from "../utils/navigation.js";
11
+ import { mapTenantToUi as l } from "../utils/mappers.js";
12
+ import { useCreateTenantMutation as u, useGetTenantQuery as d, useUpdateTenantMutation as f } from "../../generated/global-operations.js";
13
+ import { emitTenantLifecycle as p } from "../utils/tenantEvents.js";
14
+ import { useCallback as m, useMemo as h } from "react";
15
+ import { ArrowLeft as g, Loader2 as _ } from "lucide-react";
16
+ import { useNavigate as v, useParams as y } from "react-router-dom";
17
+ import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
18
+ import { useFeatureFlag as C } from "@burdenoff/fe-libs/shared/feature-flags";
19
+ import { useI18n as w } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
20
+ import { useEventBus as T } from "@burdenoff/fe-libs/shared/events";
21
+ //#region src/admin/pages/TenantFormRoutePage.tsx
22
+ function E({ mode: E }) {
23
+ let { tenantId: D } = y(), O = v(), { basePath: k = "" } = t(), A = e(), { t: j } = w(), { canManageTenants: M, isLoading: N } = n(), P = E === "edit", F = C(P ? "admin.tenant.edit" : "admin.tenant.create", !0), I = T(), L = m((e, t, n) => a(j, e, t, n), [j]), R = c(k, "tenants"), z = P && D ? c(k, `tenants/${D}`) : R, { data: B, loading: V, error: H } = d({
24
+ variables: { id: D ?? "" },
25
+ skip: !P || !D || N || !M || !F,
26
+ fetchPolicy: "cache-and-network"
27
+ }), [U] = u(), [W] = f(), G = h(() => B?.tenant ? l(B.tenant) : void 0, [B?.tenant]), K = m(() => {
28
+ O(z);
29
+ }, [O, z]), q = m(async (e) => {
30
+ if (P) {
31
+ if (!D) return;
32
+ try {
33
+ p(I, "tenant.tenant.updated", {
34
+ tenantId: D,
35
+ tenantSlug: (await W({ variables: {
36
+ id: D,
37
+ input: {
38
+ name: e.name,
39
+ customDomain: e.domain,
40
+ metadata: {
41
+ ownerEmail: e.ownerEmail,
42
+ billingEmail: e.billingEmail,
43
+ plan: e.plan
44
+ }
45
+ }
46
+ } })).data?.updateTenant?.slug ?? G?.slug
47
+ }), A.success(L("admin.tenants.toast.updatedTitle", "Tenant updated"), L("admin.tenants.toast.updatedDescription", "{{name}} has been updated.", { name: e.name ?? "" })), O(c(k, `tenants/${D}`));
48
+ } catch (e) {
49
+ throw A.error(L("admin.tenants.toast.updateFailedTitle", "Update failed"), e instanceof Error ? e.message : ""), e;
50
+ }
51
+ return;
52
+ }
53
+ try {
54
+ let t = (await U({ variables: { input: {
55
+ name: e.name,
56
+ slug: e.slug,
57
+ customDomain: e.domain,
58
+ metadata: {
59
+ ownerEmail: e.ownerEmail,
60
+ billingEmail: e.billingEmail,
61
+ plan: e.plan
62
+ }
63
+ } } })).data?.createTenant;
64
+ if (!t?.id) throw Error(L("admin.tenants.toast.createNoRecord", "Tenant create returned no record. Please retry."));
65
+ p(I, "tenant.tenant.created", {
66
+ tenantId: t.id,
67
+ tenantSlug: t.slug
68
+ }), A.success(L("admin.tenants.toast.createdTitle", "Tenant created"), L("admin.tenants.toast.createdDescription", "{{name}} has been created.", { name: e.name ?? "" })), O(c(k, `tenants/${t.id}`));
69
+ } catch (e) {
70
+ throw A.error(L("admin.tenants.toast.createFailedTitle", "Create failed"), e instanceof Error ? e.message : ""), e;
71
+ }
72
+ }, [
73
+ k,
74
+ U,
75
+ I,
76
+ P,
77
+ O,
78
+ G?.slug,
79
+ D,
80
+ R,
81
+ A,
82
+ L,
83
+ W
84
+ ]);
85
+ return !N && !M ? /* @__PURE__ */ x(s, {
86
+ allowed: !1,
87
+ isLoading: !1,
88
+ pageTitle: P ? L("admin.tenantForm.editTitle", "Edit Tenant") : L("admin.tenantForm.createTitle", "Create Tenant"),
89
+ denyMessage: L("admin.tenantForm.permissionDenied", "You do not have permission to manage tenants."),
90
+ children: /* @__PURE__ */ x(b, {})
91
+ }) : F ? /* @__PURE__ */ x(s, {
92
+ allowed: M,
93
+ isLoading: N,
94
+ pageTitle: P ? L("admin.tenantForm.editTitle", "Edit Tenant") : L("admin.tenantForm.createTitle", "Create Tenant"),
95
+ denyMessage: L("admin.tenantForm.denyMessage", "You don't have permission to manage tenants."),
96
+ children: P && V ? /* @__PURE__ */ x(i, {
97
+ title: L("admin.tenantForm.loadingTitle", "Loading tenant..."),
98
+ children: /* @__PURE__ */ x("div", {
99
+ className: "flex h-64 items-center justify-center",
100
+ children: /* @__PURE__ */ x(_, { className: "h-8 w-8 animate-spin text-muted-foreground" })
101
+ })
102
+ }) : P && (H || !G) ? /* @__PURE__ */ S(i, {
103
+ title: L("admin.tenantForm.notFoundTitle", "Tenant Not Found"),
104
+ description: L("admin.tenantForm.notFoundDescription", "The tenant you want to edit could not be found."),
105
+ children: [H && /* @__PURE__ */ x("div", {
106
+ className: "mb-4 rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive",
107
+ children: H.message
108
+ }), /* @__PURE__ */ S(r, {
109
+ variant: "outline",
110
+ onClick: () => O(R),
111
+ children: [/* @__PURE__ */ x(g, { className: "mr-2 h-4 w-4" }), L("admin.tenantForm.backToTenants", "Back to Tenants")]
112
+ })]
113
+ }) : /* @__PURE__ */ x(i, {
114
+ title: P ? L("admin.tenantForm.editTitle", "Edit Tenant") : L("admin.tenantForm.createTitle", "Create Tenant"),
115
+ description: P ? L("admin.tenantForm.editDescription", "Update tenant configuration and metadata.") : L("admin.tenantForm.createDescription", "Add a new tenant to the platform."),
116
+ children: /* @__PURE__ */ x(o, {
117
+ open: !0,
118
+ onClose: K,
119
+ tenant: G,
120
+ onSave: q
121
+ })
122
+ })
123
+ }) : /* @__PURE__ */ x(i, {
124
+ title: P ? L("admin.tenantForm.editTitle", "Edit Tenant") : L("admin.tenantForm.createTitle", "Create Tenant"),
125
+ description: L("admin.tenantForm.featureDisabled", "This feature is currently disabled."),
126
+ children: /* @__PURE__ */ S(r, {
127
+ variant: "outline",
128
+ onClick: () => O(R),
129
+ children: [/* @__PURE__ */ x(g, { className: "mr-2 h-4 w-4" }), L("admin.tenantForm.backToTenants", "Back to Tenants")]
130
+ })
131
+ });
132
+ }
133
+ //#endregion
134
+ export { E as TenantFormRoutePage };
135
+
136
+ //# sourceMappingURL=TenantFormRoutePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantFormRoutePage.js","names":[],"sources":["../../../src/admin/pages/TenantFormRoutePage.tsx"],"sourcesContent":["import { useCallback, useMemo } from 'react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { ArrowLeft, Loader2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useFeatureFlag } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport { emitTenantLifecycle } from '../utils/tenantEvents';\nimport {\n useCreateTenantMutation,\n useGetTenantQuery,\n useUpdateTenantMutation,\n} from '../../generated/global-operations';\nimport { Button, PageLayout, PermissionGuard, TenantForm, useToast } from '../components';\nimport { useAdminPermissions } from '../hooks/useAdminPermissions';\nimport type { CreateTenantInput, UpdateTenantInput } from '../schemas';\nimport { useAdmin } from '../providers/AdminProvider';\nimport { joinPath } from '../utils/navigation';\nimport { tWithFallback } from '../utils/i18n';\nimport { mapTenantToUi } from '../utils/mappers';\n\ntype TenantFormRoutePageProps = {\n mode: 'create' | 'edit';\n};\n\nexport function TenantFormRoutePage({ mode }: TenantFormRoutePageProps) {\n const { tenantId } = useParams<{ tenantId: string }>();\n const navigate = useNavigate();\n const { basePath = '' } = useAdmin();\n const toast = useToast();\n const { t } = useI18n();\n const { canManageTenants, isLoading: permissionsLoading } = useAdminPermissions();\n const isEdit = mode === 'edit';\n // Page-level feature flags. Default-allow keeps prior behavior intact when\n // the flag is missing; turning the flag OFF in OpenBao/feature-flag-svc\n // disables the corresponding route without a code deploy.\n const flagKey = isEdit ? 'admin.tenant.edit' : 'admin.tenant.create';\n const flagEnabled = useFeatureFlag(flagKey, true);\n const events = useEventBus();\n const tr = useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>): string =>\n tWithFallback(t, key, fallback, params),\n [t]\n );\n\n const tenantsPath = joinPath(basePath, 'tenants');\n const closePath = isEdit && tenantId ? joinPath(basePath, `tenants/${tenantId}`) : tenantsPath;\n\n const { data, loading, error } = useGetTenantQuery({\n variables: { id: tenantId ?? '' },\n // Also skip when the page is feature-flag-disabled: the early return\n // below renders the \"feature disabled\" panel instead of the form, so a\n // network round-trip would be wasted.\n skip: !isEdit || !tenantId || permissionsLoading || !canManageTenants || !flagEnabled,\n fetchPolicy: 'cache-and-network',\n });\n\n const [createTenant] = useCreateTenantMutation();\n const [updateTenant] = useUpdateTenantMutation();\n\n // Memoize the mapped tenant so its object identity is stable across\n // renders. mapTenantToUi otherwise produces a new object on every render,\n // forcing downstream memoization (TenantForm.defaultValues, reset effects)\n // to fan out unnecessarily.\n const tenant = useMemo(\n () => (data?.tenant ? mapTenantToUi(data.tenant) : undefined),\n [data?.tenant]\n );\n\n const handleClose = useCallback(() => {\n navigate(closePath);\n }, [navigate, closePath]);\n\n const handleSave = useCallback(\n async (input: CreateTenantInput | UpdateTenantInput) => {\n if (isEdit) {\n if (!tenantId) return;\n try {\n const updated = await updateTenant({\n variables: {\n id: tenantId,\n input: {\n name: input.name,\n customDomain: input.domain,\n metadata: {\n ownerEmail: input.ownerEmail,\n billingEmail: input.billingEmail,\n plan: input.plan,\n } as Record<string, unknown>,\n },\n },\n });\n // The update mutation does not accept slug, so emit the slug from\n // the persisted record (mutation response, falling back to the\n // already-loaded tenant) rather than the user's form input — the\n // form's slug field is read-only for edits, but a defensive emit\n // protects listeners against any future change.\n emitTenantLifecycle(events, 'tenant.tenant.updated', {\n tenantId,\n tenantSlug: updated.data?.updateTenant?.slug ?? tenant?.slug,\n });\n toast.success(\n tr('admin.tenants.toast.updatedTitle', 'Tenant updated'),\n tr('admin.tenants.toast.updatedDescription', '{{name}} has been updated.', {\n name: input.name ?? '',\n })\n );\n navigate(joinPath(basePath, `tenants/${tenantId}`));\n } catch (err) {\n toast.error(\n tr('admin.tenants.toast.updateFailedTitle', 'Update failed'),\n err instanceof Error ? err.message : ''\n );\n // Rethrow so TenantForm.onSubmit's try/catch sees the rejection\n // and keeps the form open instead of calling onClose() — losing\n // the user's edits would be a worse outcome than a duplicate\n // surfacing of the same error.\n throw err;\n }\n return;\n }\n\n try {\n const result = await createTenant({\n variables: {\n input: {\n name: input.name!,\n slug: input.slug!,\n customDomain: input.domain,\n metadata: {\n ownerEmail: input.ownerEmail,\n billingEmail: input.billingEmail,\n plan: input.plan,\n } as Record<string, unknown>,\n },\n },\n });\n const created = result.data?.createTenant;\n if (!created?.id) {\n // A resolved mutation without a createdTenant record is a\n // degenerate response (federation hiccup, partial schema, etc.).\n // Treat as failure so the user is not shown a misleading success\n // toast and the form stays open with their input intact.\n throw new Error(\n tr(\n 'admin.tenants.toast.createNoRecord',\n 'Tenant create returned no record. Please retry.'\n )\n );\n }\n // Slug from the server-confirmed record so listeners cannot see a\n // form value that was rejected (e.g. uniqueness collision).\n emitTenantLifecycle(events, 'tenant.tenant.created', {\n tenantId: created.id,\n tenantSlug: created.slug,\n });\n toast.success(\n tr('admin.tenants.toast.createdTitle', 'Tenant created'),\n tr('admin.tenants.toast.createdDescription', '{{name}} has been created.', {\n name: input.name ?? '',\n })\n );\n navigate(joinPath(basePath, `tenants/${created.id}`));\n } catch (err) {\n toast.error(\n tr('admin.tenants.toast.createFailedTitle', 'Create failed'),\n err instanceof Error ? err.message : ''\n );\n // Rethrow so the form stays open on failure (see edit branch).\n throw err;\n }\n },\n [\n basePath,\n createTenant,\n events,\n isEdit,\n navigate,\n tenant?.slug,\n tenantId,\n tenantsPath,\n toast,\n tr,\n updateTenant,\n ]\n );\n\n // Permission denials win over feature-flag denials: a user without\n // canManageTenants should see \"permission denied\" rather than learning\n // whether the feature flag is on/off (minor information disclosure).\n if (!permissionsLoading && !canManageTenants) {\n return (\n <PermissionGuard\n allowed={false}\n isLoading={false}\n pageTitle={\n isEdit\n ? tr('admin.tenantForm.editTitle', 'Edit Tenant')\n : tr('admin.tenantForm.createTitle', 'Create Tenant')\n }\n denyMessage={tr(\n 'admin.tenantForm.permissionDenied',\n 'You do not have permission to manage tenants.'\n )}\n >\n <></>\n </PermissionGuard>\n );\n }\n\n if (!flagEnabled) {\n return (\n <PageLayout\n title={\n isEdit\n ? tr('admin.tenantForm.editTitle', 'Edit Tenant')\n : tr('admin.tenantForm.createTitle', 'Create Tenant')\n }\n description={tr('admin.tenantForm.featureDisabled', 'This feature is currently disabled.')}\n >\n <Button variant=\"outline\" onClick={() => navigate(tenantsPath)}>\n <ArrowLeft className=\"mr-2 h-4 w-4\" />\n {tr('admin.tenantForm.backToTenants', 'Back to Tenants')}\n </Button>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard\n allowed={canManageTenants}\n isLoading={permissionsLoading}\n pageTitle={\n isEdit\n ? tr('admin.tenantForm.editTitle', 'Edit Tenant')\n : tr('admin.tenantForm.createTitle', 'Create Tenant')\n }\n denyMessage={tr(\n 'admin.tenantForm.denyMessage',\n \"You don't have permission to manage tenants.\"\n )}\n >\n {isEdit && loading ? (\n <PageLayout title={tr('admin.tenantForm.loadingTitle', 'Loading tenant...')}>\n <div className=\"flex h-64 items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n </PageLayout>\n ) : isEdit && (error || !tenant) ? (\n <PageLayout\n title={tr('admin.tenantForm.notFoundTitle', 'Tenant Not Found')}\n description={tr(\n 'admin.tenantForm.notFoundDescription',\n 'The tenant you want to edit could not be found.'\n )}\n >\n {error && (\n <div className=\"mb-4 rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive\">\n {error.message}\n </div>\n )}\n <Button variant=\"outline\" onClick={() => navigate(tenantsPath)}>\n <ArrowLeft className=\"mr-2 h-4 w-4\" />\n {tr('admin.tenantForm.backToTenants', 'Back to Tenants')}\n </Button>\n </PageLayout>\n ) : (\n <PageLayout\n title={\n isEdit\n ? tr('admin.tenantForm.editTitle', 'Edit Tenant')\n : tr('admin.tenantForm.createTitle', 'Create Tenant')\n }\n description={\n isEdit\n ? tr('admin.tenantForm.editDescription', 'Update tenant configuration and metadata.')\n : tr('admin.tenantForm.createDescription', 'Add a new tenant to the platform.')\n }\n >\n <TenantForm open={true} onClose={handleClose} tenant={tenant} onSave={handleSave} />\n </PageLayout>\n )}\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tenants list page
3
+ */
4
+ export declare function TenantsListPage(): import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=TenantsListPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantsListPage.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/TenantsListPage.tsx"],"names":[],"mappings":"AA2CA;;GAEG;AACH,wBAAgB,eAAe,4CAud9B"}
@@ -0,0 +1,339 @@
1
+ import { useToast as e } from "../components/Toast.js";
2
+ import { useAdmin as t } from "../providers/AdminProvider.js";
3
+ import { useAdminPermissions as n } from "../hooks/useAdminPermissions.js";
4
+ import { Avatar as r, Button as i, EmptyState as a, Input as ee } from "../components/ui.js";
5
+ import { PageLayout as te } from "../components/PageLayout.js";
6
+ import { TenantStatusBadge as ne } from "../components/StatusBadge.js";
7
+ import { formatBytes as re, formatDate as o, formatNumber as s } from "../utils/formatters.js";
8
+ import { DataTable as c, Pagination as l } from "../components/DataTable.js";
9
+ import { tWithFallback as ie } from "../utils/i18n.js";
10
+ import { TenantForm as ae } from "../components/forms/TenantForm.js";
11
+ import { RowActions as oe, createRowActions as se } from "../components/RowActions.js";
12
+ import { PermissionGuard as ce } from "../components/PermissionGuard.js";
13
+ import "../components/index.js";
14
+ import { joinPath as u } from "../utils/navigation.js";
15
+ import { mapTenantToUi as d } from "../utils/mappers.js";
16
+ import { useActivateTenantMutation as f, useCreateTenantMutation as p, useListTenantsQuery as le, useSuspendTenantMutation as ue, useUpdateTenantMutation as de } from "../../generated/global-operations.js";
17
+ import { useAdminStore as m } from "../store/adminStore.js";
18
+ import { emitTenantLifecycle as h } from "../utils/tenantEvents.js";
19
+ import { useCallback as g, useMemo as _, useState as v } from "react";
20
+ import { Building2 as y, Plus as fe, Search as pe } from "lucide-react";
21
+ import { useNavigate as me } from "react-router-dom";
22
+ import { jsx as b, jsxs as x } from "react/jsx-runtime";
23
+ import { useFeatureFlag as S } from "@burdenoff/fe-libs/shared/feature-flags";
24
+ import { useI18n as he } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
25
+ import { useEventBus as ge } from "@burdenoff/fe-libs/shared/events";
26
+ //#region src/admin/pages/TenantsListPage.tsx
27
+ var C = 20;
28
+ function w() {
29
+ let { canViewTenants: w, canManageTenants: T, isLoading: E } = n(), D = me(), { basePath: O = "" } = t(), { tenantFilter: k, updateTenantFilter: A, resetTenantFilter: j } = m(), M = e(), { t: N } = he(), P = S("admin.tenant.create", !0), F = S("admin.tenant.edit", !0), I = ge(), L = g((e, t, n) => ie(N, e, t, n), [N]), [R, z] = v(1), [B, V] = v(!1), [_e, H] = v(void 0), ve = _(() => {
30
+ let e = {};
31
+ k.search && (e.search = k.search);
32
+ let t = {
33
+ active: "ACTIVE",
34
+ suspended: "SUSPENDED",
35
+ deleted: "DELETED"
36
+ };
37
+ return k.status !== "all" && t[k.status] && (e.status = t[k.status]), e;
38
+ }, [k.search, k.status]), ye = E || !w, { data: U, loading: be, error: W, refetch: G } = le({
39
+ variables: {
40
+ filter: ve,
41
+ limit: C,
42
+ offset: (R - 1) * C
43
+ },
44
+ fetchPolicy: "cache-and-network",
45
+ skip: ye
46
+ }), [K, { loading: xe }] = p({ onCompleted: () => {
47
+ G();
48
+ } }), [q, { loading: Se }] = de({ onCompleted: () => {
49
+ G();
50
+ } }), [J] = ue({ onCompleted: () => {
51
+ G();
52
+ } }), [Y] = f({ onCompleted: () => {
53
+ G();
54
+ } }), Ce = _(() => (U?.tenants?.items ?? []).map(d), [U]), X = U?.tenants?.total ?? 0, we = Math.ceil(X / C), Te = g(() => {
55
+ H(void 0), V(!0);
56
+ }, []), Z = g((e) => {
57
+ H(e), V(!0);
58
+ }, []), Q = g(async (e) => {
59
+ try {
60
+ await J({ variables: { id: e.id } }), h(I, "tenant.tenant.suspended", {
61
+ tenantId: e.id,
62
+ tenantSlug: e.slug,
63
+ status: "SUSPENDED"
64
+ }), M.success(L("admin.tenants.toast.suspendedTitle", "Tenant suspended"), L("admin.tenants.toast.suspendedDescription", "{{name}} has been suspended.", { name: e.name }));
65
+ } catch {
66
+ M.error(L("admin.tenants.toast.errorTitle", "Error"), L("admin.tenants.toast.suspendFailed", "Failed to suspend tenant."));
67
+ }
68
+ }, [
69
+ J,
70
+ M,
71
+ L,
72
+ I
73
+ ]), $ = g(async (e) => {
74
+ try {
75
+ await Y({ variables: { id: e.id } }), h(I, "tenant.tenant.activated", {
76
+ tenantId: e.id,
77
+ tenantSlug: e.slug,
78
+ status: "ACTIVE"
79
+ }), M.success(L("admin.tenants.toast.activatedTitle", "Tenant activated"), L("admin.tenants.toast.activatedDescription", "{{name}} has been activated.", { name: e.name }));
80
+ } catch {
81
+ M.error(L("admin.tenants.toast.errorTitle", "Error"), L("admin.tenants.toast.activateFailed", "Failed to activate tenant."));
82
+ }
83
+ }, [
84
+ Y,
85
+ M,
86
+ L,
87
+ I
88
+ ]), Ee = g(async (e) => {
89
+ let t = "id" in e && e.id;
90
+ try {
91
+ if (t) {
92
+ let t = await q({ variables: {
93
+ id: e.id,
94
+ input: {
95
+ name: e.name,
96
+ customDomain: e.domain,
97
+ metadata: {
98
+ ownerEmail: e.ownerEmail,
99
+ billingEmail: e.billingEmail,
100
+ plan: e.plan
101
+ }
102
+ }
103
+ } }), n = t.data?.updateTenant?.id ?? e.id, r = t.data?.updateTenant?.slug;
104
+ h(I, "tenant.tenant.updated", {
105
+ tenantId: n,
106
+ tenantSlug: r
107
+ }), M.success(L("admin.tenants.toast.updatedTitle", "Tenant updated"), L("admin.tenants.toast.updatedDescription", "{{name}} has been updated.", { name: e.name ?? "" }));
108
+ } else {
109
+ let t = (await K({ variables: { input: {
110
+ name: e.name,
111
+ slug: e.slug,
112
+ customDomain: e.domain,
113
+ metadata: {
114
+ ownerEmail: e.ownerEmail,
115
+ billingEmail: e.billingEmail,
116
+ plan: e.plan
117
+ }
118
+ } } })).data?.createTenant;
119
+ t?.id && h(I, "tenant.tenant.created", {
120
+ tenantId: t.id,
121
+ tenantSlug: t.slug
122
+ }), M.success(L("admin.tenants.toast.createdTitle", "Tenant created"), L("admin.tenants.toast.createdDescription", "{{name}} has been created.", { name: e.name ?? "" }));
123
+ }
124
+ V(!1);
125
+ } catch (e) {
126
+ let n = e instanceof Error ? e.message : "Unknown error";
127
+ throw M.error(t ? L("admin.tenants.toast.updateFailedTitle", "Update failed") : L("admin.tenants.toast.createFailedTitle", "Create failed"), n), e;
128
+ }
129
+ }, [
130
+ K,
131
+ q,
132
+ M,
133
+ L,
134
+ I
135
+ ]), De = (e) => {
136
+ D(u(O, `tenants/${e.id}`));
137
+ }, Oe = g((e) => {
138
+ let t = se({
139
+ onView: () => D(u(O, `tenants/${e.id}`)),
140
+ onEdit: T && F ? () => Z(e) : void 0
141
+ });
142
+ return T && t.push({
143
+ key: e.status === "active" ? "suspend" : "activate",
144
+ label: e.status === "active" ? L("admin.tenants.actions.suspend", "Suspend") : L("admin.tenants.actions.activate", "Activate"),
145
+ separator: !0,
146
+ onClick: e.status === "active" ? () => Q(e) : () => $(e)
147
+ }), t;
148
+ }, [
149
+ D,
150
+ O,
151
+ T,
152
+ F,
153
+ Z,
154
+ Q,
155
+ $,
156
+ L
157
+ ]), ke = [
158
+ {
159
+ key: "name",
160
+ header: L("admin.tenants.table.tenant", "Tenant"),
161
+ sortable: !0,
162
+ render: (e) => /* @__PURE__ */ x("div", {
163
+ className: "flex items-center gap-3",
164
+ children: [/* @__PURE__ */ b(r, {
165
+ fallback: e.name.slice(0, 2).toUpperCase(),
166
+ size: "sm"
167
+ }), /* @__PURE__ */ x("div", {
168
+ className: "min-w-0",
169
+ children: [/* @__PURE__ */ b("div", {
170
+ className: "truncate font-medium text-foreground",
171
+ children: e.name
172
+ }), /* @__PURE__ */ b("div", {
173
+ className: "truncate text-xs text-muted-foreground",
174
+ children: e.slug
175
+ })]
176
+ })]
177
+ })
178
+ },
179
+ {
180
+ key: "status",
181
+ header: L("admin.tenants.table.status", "Status"),
182
+ width: "120px",
183
+ render: (e) => /* @__PURE__ */ b(ne, { status: e.status })
184
+ },
185
+ {
186
+ key: "plan",
187
+ header: L("admin.tenants.table.plan", "Plan"),
188
+ width: "100px"
189
+ },
190
+ {
191
+ key: "userCount",
192
+ header: L("admin.tenants.table.users", "Users"),
193
+ width: "80px",
194
+ align: "right",
195
+ sortable: !0,
196
+ render: (e) => s(e.userCount)
197
+ },
198
+ {
199
+ key: "storageUsed",
200
+ header: L("admin.tenants.table.storage", "Storage"),
201
+ width: "100px",
202
+ align: "right",
203
+ render: (e) => re(e.storageUsed)
204
+ },
205
+ {
206
+ key: "createdAt",
207
+ header: L("admin.tenants.table.created", "Created"),
208
+ width: "120px",
209
+ sortable: !0,
210
+ render: (e) => o(e.createdAt)
211
+ },
212
+ {
213
+ key: "actions",
214
+ header: "",
215
+ width: "50px",
216
+ align: "right",
217
+ render: (e) => /* @__PURE__ */ b(oe, {
218
+ actions: Oe(e),
219
+ ariaLabel: L("admin.tenants.table.actionsFor", "Actions for {{name}}", { name: e.name })
220
+ })
221
+ }
222
+ ];
223
+ return /* @__PURE__ */ b(ce, {
224
+ allowed: w,
225
+ isLoading: E,
226
+ pageTitle: L("admin.tenants.title", "Tenants"),
227
+ denyMessage: L("admin.tenants.denyMessage", "You don't have permission to view tenants."),
228
+ children: /* @__PURE__ */ x(te, {
229
+ title: L("admin.tenants.title", "Tenants"),
230
+ description: X ? L("admin.tenants.descriptionWithTotal", "Manage all tenants on the platform · {{total}} total", { total: X }) : L("admin.tenants.description", "Manage all tenants on the platform"),
231
+ actions: T && P ? /* @__PURE__ */ x(i, {
232
+ onClick: Te,
233
+ disabled: xe || Se,
234
+ children: [/* @__PURE__ */ b(fe, { className: "mr-2 h-4 w-4" }), L("admin.tenants.actions.createTenant", "Create Tenant")]
235
+ }) : void 0,
236
+ children: [/* @__PURE__ */ x("div", {
237
+ className: "space-y-4",
238
+ children: [
239
+ /* @__PURE__ */ x("div", {
240
+ className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
241
+ children: [/* @__PURE__ */ x("div", {
242
+ className: "relative max-w-sm flex-1",
243
+ children: [/* @__PURE__ */ b(pe, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), /* @__PURE__ */ b(ee, {
244
+ placeholder: L("admin.tenants.searchPlaceholder", "Search tenants..."),
245
+ value: k.search,
246
+ onChange: (e) => {
247
+ z(1), A({ search: e.target.value });
248
+ },
249
+ className: "pl-9"
250
+ })]
251
+ }), /* @__PURE__ */ x("div", {
252
+ className: "flex items-center gap-2",
253
+ children: [/* @__PURE__ */ x("select", {
254
+ value: k.status,
255
+ onChange: (e) => {
256
+ z(1), A({ status: e.target.value });
257
+ },
258
+ className: "h-10 rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
259
+ children: [
260
+ /* @__PURE__ */ b("option", {
261
+ value: "all",
262
+ children: L("admin.tenants.filters.status.all", "All Status")
263
+ }),
264
+ /* @__PURE__ */ b("option", {
265
+ value: "active",
266
+ children: L("admin.tenants.filters.status.active", "Active")
267
+ }),
268
+ /* @__PURE__ */ b("option", {
269
+ value: "suspended",
270
+ children: L("admin.tenants.filters.status.suspended", "Suspended")
271
+ }),
272
+ /* @__PURE__ */ b("option", {
273
+ value: "deleted",
274
+ children: L("admin.tenants.filters.status.deleted", "Deleted")
275
+ })
276
+ ]
277
+ }), (k.search || k.status !== "all") && /* @__PURE__ */ b(i, {
278
+ variant: "ghost",
279
+ onClick: () => {
280
+ z(1), j();
281
+ },
282
+ children: L("admin.tenants.filters.clear", "Clear")
283
+ })]
284
+ })]
285
+ }),
286
+ W && /* @__PURE__ */ x("div", {
287
+ className: "rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive",
288
+ children: [
289
+ L("admin.tenants.error.loadFailed", "Failed to load tenants"),
290
+ ": ",
291
+ W.message
292
+ ]
293
+ }),
294
+ /* @__PURE__ */ b(c, {
295
+ columns: ke,
296
+ data: Ce,
297
+ keyExtractor: (e) => e.id,
298
+ onRowClick: De,
299
+ sortBy: k.sortBy,
300
+ sortOrder: k.sortOrder,
301
+ onSort: (e, t) => A({
302
+ sortBy: e,
303
+ sortOrder: t
304
+ }),
305
+ loading: be,
306
+ emptyState: /* @__PURE__ */ b(a, {
307
+ icon: /* @__PURE__ */ b(y, { className: "h-8 w-8" }),
308
+ title: L("admin.tenants.empty.title", "No tenants found"),
309
+ description: L("admin.tenants.empty.description", "Try adjusting your search or filters"),
310
+ action: /* @__PURE__ */ b(i, {
311
+ variant: "outline",
312
+ onClick: () => {
313
+ z(1), j();
314
+ },
315
+ children: L("admin.tenants.empty.clearFilters", "Clear filters")
316
+ })
317
+ })
318
+ }),
319
+ X > C && /* @__PURE__ */ b(l, {
320
+ page: R,
321
+ totalPages: we,
322
+ totalItems: X,
323
+ pageSize: C,
324
+ onPageChange: z
325
+ })
326
+ ]
327
+ }), /* @__PURE__ */ b(ae, {
328
+ open: B,
329
+ onClose: () => V(!1),
330
+ tenant: _e,
331
+ onSave: Ee
332
+ })]
333
+ })
334
+ });
335
+ }
336
+ //#endregion
337
+ export { w as TenantsListPage };
338
+
339
+ //# sourceMappingURL=TenantsListPage.js.map