@burdenoff/microfe-admin 2026.625.1 → 2026.712.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 (77) hide show
  1. package/dist/admin/AdminRoot.js +2 -2
  2. package/dist/admin/AdminRoot.js.map +1 -1
  3. package/dist/admin/AdminRoutes.js +130 -78
  4. package/dist/admin/AdminRoutes.js.map +1 -1
  5. package/dist/admin/components/AccessDenied.js +2 -2
  6. package/dist/admin/components/AccessDenied.js.map +1 -1
  7. package/dist/admin/components/ActivityFeed.js +4 -4
  8. package/dist/admin/components/ActivityFeed.js.map +1 -1
  9. package/dist/admin/components/Charts.js.map +1 -1
  10. package/dist/admin/components/ConfirmDialog.js +1 -1
  11. package/dist/admin/components/ConfirmDialog.js.map +1 -1
  12. package/dist/admin/components/DataTable.js.map +1 -1
  13. package/dist/admin/components/FormSheet.js +1 -1
  14. package/dist/admin/components/FormSheet.js.map +1 -1
  15. package/dist/admin/components/TenantSsoPanel.js +1 -1
  16. package/dist/admin/components/TenantSsoPanel.js.map +1 -1
  17. package/dist/admin/components/Toast.js +11 -11
  18. package/dist/admin/components/Toast.js.map +1 -1
  19. package/dist/admin/components/forms/SubscriptionForm.js +2 -2
  20. package/dist/admin/components/forms/SubscriptionForm.js.map +1 -1
  21. package/dist/admin/components/forms/TenantForm.js +1 -1
  22. package/dist/admin/components/forms/UserForm.js +1 -1
  23. package/dist/admin/components/ui.js +3 -3
  24. package/dist/admin/components/ui.js.map +1 -1
  25. package/dist/admin/constants/featureFlags.js +12 -0
  26. package/dist/admin/constants/featureFlags.js.map +1 -0
  27. package/dist/admin/constants/index.js +33 -24
  28. package/dist/admin/constants/index.js.map +1 -1
  29. package/dist/admin/pages/AuditLogsPage.js +92 -77
  30. package/dist/admin/pages/AuditLogsPage.js.map +1 -1
  31. package/dist/admin/pages/BillingPage.js +95 -51
  32. package/dist/admin/pages/BillingPage.js.map +1 -1
  33. package/dist/admin/pages/CommunicationsPage.js +97 -92
  34. package/dist/admin/pages/CommunicationsPage.js.map +1 -1
  35. package/dist/admin/pages/ContentPagesPage.js +274 -259
  36. package/dist/admin/pages/ContentPagesPage.js.map +1 -1
  37. package/dist/admin/pages/DashboardPage.js +113 -84
  38. package/dist/admin/pages/DashboardPage.js.map +1 -1
  39. package/dist/admin/pages/FeatureFlagsPage.js +93 -75
  40. package/dist/admin/pages/FeatureFlagsPage.js.map +1 -1
  41. package/dist/admin/pages/OrganizationsListPage.js +105 -87
  42. package/dist/admin/pages/OrganizationsListPage.js.map +1 -1
  43. package/dist/admin/pages/ProductsPage.js +138 -130
  44. package/dist/admin/pages/ProductsPage.js.map +1 -1
  45. package/dist/admin/pages/ReferralsPage.js +70 -52
  46. package/dist/admin/pages/ReferralsPage.js.map +1 -1
  47. package/dist/admin/pages/RolesPermissionsPage.js +136 -118
  48. package/dist/admin/pages/RolesPermissionsPage.js.map +1 -1
  49. package/dist/admin/pages/SREPage.js +34 -32
  50. package/dist/admin/pages/SREPage.js.map +1 -1
  51. package/dist/admin/pages/SandboxSettingsPage.js +360 -322
  52. package/dist/admin/pages/SandboxSettingsPage.js.map +1 -1
  53. package/dist/admin/pages/SettingsPage.js +64 -61
  54. package/dist/admin/pages/SettingsPage.js.map +1 -1
  55. package/dist/admin/pages/SyncFailuresPage.js +120 -118
  56. package/dist/admin/pages/SyncFailuresPage.js.map +1 -1
  57. package/dist/admin/pages/TenantDetailPage.js +286 -231
  58. package/dist/admin/pages/TenantDetailPage.js.map +1 -1
  59. package/dist/admin/pages/TenantFormRoutePage.js +78 -73
  60. package/dist/admin/pages/TenantFormRoutePage.js.map +1 -1
  61. package/dist/admin/pages/TenantsListPage.js +182 -155
  62. package/dist/admin/pages/TenantsListPage.js.map +1 -1
  63. package/dist/admin/pages/UsersListPage.js +128 -113
  64. package/dist/admin/pages/UsersListPage.js.map +1 -1
  65. package/dist/admin/pages/WaitlistPage.js +78 -63
  66. package/dist/admin/pages/WaitlistPage.js.map +1 -1
  67. package/dist/admin/pages/WorkflowsPage.js +107 -102
  68. package/dist/admin/pages/WorkflowsPage.js.map +1 -1
  69. package/dist/admin/pages/WorkspacesListPage.js +61 -49
  70. package/dist/admin/pages/WorkspacesListPage.js.map +1 -1
  71. package/dist/node_modules/@hookform/resolvers/dist/resolvers.js +2 -2
  72. package/dist/node_modules/@hookform/resolvers/dist/resolvers.js.map +1 -1
  73. package/dist/node_modules/@hookform/resolvers/zod/dist/zod.js +35 -26
  74. package/dist/node_modules/@hookform/resolvers/zod/dist/zod.js.map +1 -1
  75. package/dist/node_modules/react-hook-form/dist/index.esm.js +609 -516
  76. package/dist/node_modules/react-hook-form/dist/index.esm.js.map +1 -1
  77. package/package.json +2 -2
@@ -8,31 +8,32 @@ import { FeatureFlagStatus as l } from "../../generated/global-types.js";
8
8
  import { useState as u } from "react";
9
9
  import { Plus as d, Search as f, ToggleLeft as p, Trash2 as m } from "lucide-react";
10
10
  import { jsx as h, jsxs as g } from "react/jsx-runtime";
11
+ import { EmphasisPanel as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
11
12
  //#region src/admin/pages/FeatureFlagsPage.tsx
12
- function _() {
13
- let [_, v] = u(""), { data: y, loading: b, error: x, refetch: S } = s({ variables: { filter: _ ? { name: { contains: _ } } : void 0 } }), [C] = c(), [w] = o(), T = y?.featureFlags?.items || [], E = async (e, t) => {
13
+ function y() {
14
+ let [y, b] = u(""), { data: x, loading: S, error: C, refetch: w } = s({ variables: { filter: y ? { name: { contains: y } } : void 0 } }), [T] = c(), [E] = o(), D = x?.featureFlags?.items || [], O = D.filter((e) => e.status === l.Active).length, k = async (e, t) => {
14
15
  let n = t === l.Active ? l.Archived : l.Active;
15
16
  try {
16
- await C({ variables: {
17
+ await T({ variables: {
17
18
  id: e,
18
19
  input: { status: n }
19
- } }), S();
20
+ } }), w();
20
21
  } catch (e) {
21
22
  console.error("Failed to update status:", e);
22
23
  }
23
- }, D = async (e) => {
24
+ }, A = async (e) => {
24
25
  if (confirm("Are you sure you want to delete this feature flag?")) try {
25
- await w({ variables: { id: e } }), S();
26
+ await E({ variables: { id: e } }), w();
26
27
  } catch (e) {
27
28
  console.error("Failed to delete flag:", e);
28
29
  }
29
30
  };
30
- return x ? /* @__PURE__ */ h(r, {
31
+ return C ? /* @__PURE__ */ h(r, {
31
32
  title: "Feature Flags",
32
33
  description: "Error loading feature flags",
33
34
  children: /* @__PURE__ */ g("div", {
34
35
  className: "p-4 text-status-error-text",
35
- children: ["Error: ", x.message]
36
+ children: ["Error: ", C.message]
36
37
  })
37
38
  }) : /* @__PURE__ */ h(r, {
38
39
  title: "Feature Flags",
@@ -41,78 +42,95 @@ function _() {
41
42
  actions: /* @__PURE__ */ g(e, { children: [/* @__PURE__ */ h(d, { className: "mr-2 h-4 w-4" }), "Create Feature Flag"] }),
42
43
  children: /* @__PURE__ */ g("div", {
43
44
  className: "space-y-4",
44
- children: [/* @__PURE__ */ h("div", {
45
- className: "flex items-center justify-between",
46
- children: /* @__PURE__ */ g("div", {
47
- className: "relative max-w-sm flex-1",
48
- children: [/* @__PURE__ */ h(f, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ h(n, {
49
- placeholder: "Search feature flags...",
50
- className: "pl-9",
51
- value: _,
52
- onChange: (e) => v(e.target.value)
53
- })]
54
- })
55
- }), /* @__PURE__ */ h(i, {
56
- columns: [
57
- {
58
- key: "name",
59
- header: "Name",
60
- render: (e) => /* @__PURE__ */ g("div", {
61
- className: "flex flex-col text-left",
62
- children: [/* @__PURE__ */ h("span", {
63
- className: "font-medium",
64
- children: e.name
65
- }), /* @__PURE__ */ h("span", {
66
- className: "text-xs text-text-secondary",
67
- children: e.key
68
- })]
69
- })
70
- },
71
- {
72
- key: "flagType",
73
- header: "Type"
74
- },
75
- {
76
- key: "status",
77
- header: "Status",
78
- render: (t) => {
79
- let n = t.status === l.Active;
80
- return /* @__PURE__ */ h(e, {
81
- variant: "outline",
82
- size: "sm",
83
- onClick: () => E(t.id, t.status),
84
- className: n ? "border-primary text-primary" : "text-text-secondary",
85
- children: n ? "Active" : "Archived"
86
- });
45
+ children: [
46
+ /* @__PURE__ */ h(v, { children: "Feature flags let you turn parts of the platform on or off without shipping new code. Use this page to roll a feature out gradually, kill-switch something that's misbehaving, or archive flags you no longer need." }),
47
+ /* @__PURE__ */ g(_, {
48
+ className: "flex items-center gap-4 p-5",
49
+ children: [/* @__PURE__ */ h("div", {
50
+ className: "flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-action-primary-bg/15 text-action-primary-bg",
51
+ children: /* @__PURE__ */ h(p, { className: "h-6 w-6" })
52
+ }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("div", {
53
+ className: "text-3xl font-bold tabular-nums text-text-primary",
54
+ children: O
55
+ }), /* @__PURE__ */ h("p", {
56
+ className: "text-sm text-text-secondary",
57
+ children: "active feature flags"
58
+ })] })]
59
+ }),
60
+ /* @__PURE__ */ h("div", {
61
+ className: "flex items-center justify-between",
62
+ children: /* @__PURE__ */ g("div", {
63
+ className: "relative max-w-sm flex-1",
64
+ children: [/* @__PURE__ */ h(f, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ h(n, {
65
+ placeholder: "Search feature flags...",
66
+ className: "pl-9",
67
+ value: y,
68
+ onChange: (e) => b(e.target.value)
69
+ })]
70
+ })
71
+ }),
72
+ /* @__PURE__ */ h(i, {
73
+ columns: [
74
+ {
75
+ key: "name",
76
+ header: "Name",
77
+ render: (e) => /* @__PURE__ */ g("div", {
78
+ className: "flex flex-col text-left",
79
+ children: [/* @__PURE__ */ h("span", {
80
+ className: "font-medium",
81
+ children: e.name
82
+ }), /* @__PURE__ */ h("span", {
83
+ className: "text-xs text-text-secondary",
84
+ children: e.key
85
+ })]
86
+ })
87
+ },
88
+ {
89
+ key: "flagType",
90
+ header: "Type"
91
+ },
92
+ {
93
+ key: "status",
94
+ header: "Status",
95
+ render: (t) => {
96
+ let n = t.status === l.Active;
97
+ return /* @__PURE__ */ h(e, {
98
+ variant: "outline",
99
+ size: "sm",
100
+ onClick: () => k(t.id, t.status),
101
+ className: n ? "border-primary text-primary" : "text-text-secondary",
102
+ children: n ? "Active" : "Archived"
103
+ });
104
+ }
105
+ },
106
+ {
107
+ key: "actions",
108
+ header: "",
109
+ align: "right",
110
+ render: (e) => /* @__PURE__ */ h(a, { actions: [{
111
+ key: "delete",
112
+ label: "Delete",
113
+ icon: /* @__PURE__ */ h(m, { className: "h-4 w-4" }),
114
+ onClick: () => A(e.id),
115
+ destructive: !0
116
+ }] })
87
117
  }
88
- },
89
- {
90
- key: "actions",
91
- header: "",
92
- align: "right",
93
- render: (e) => /* @__PURE__ */ h(a, { actions: [{
94
- key: "delete",
95
- label: "Delete",
96
- icon: /* @__PURE__ */ h(m, { className: "h-4 w-4" }),
97
- onClick: () => D(e.id),
98
- destructive: !0
99
- }] })
100
- }
101
- ],
102
- data: T,
103
- keyExtractor: (e) => e.id,
104
- loading: b,
105
- emptyState: /* @__PURE__ */ h(t, {
106
- illustration: "empty-data",
107
- icon: /* @__PURE__ */ h(p, { className: "h-8 w-8" }),
108
- title: "No feature flags found",
109
- description: "Feature flags will appear here when they are created"
118
+ ],
119
+ data: D,
120
+ keyExtractor: (e) => e.id,
121
+ loading: S,
122
+ emptyState: /* @__PURE__ */ h(t, {
123
+ illustration: "empty-data",
124
+ icon: /* @__PURE__ */ h(p, { className: "h-8 w-8" }),
125
+ title: "No feature flags found",
126
+ description: "Feature flags will appear here when they are created"
127
+ })
110
128
  })
111
- })]
129
+ ]
112
130
  })
113
131
  });
114
132
  }
115
133
  //#endregion
116
- export { _ as FeatureFlagsPage };
134
+ export { y as FeatureFlagsPage };
117
135
 
118
136
  //# sourceMappingURL=FeatureFlagsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FeatureFlagsPage.js","names":[],"sources":["../../../src/admin/pages/FeatureFlagsPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { ToggleLeft, Search, Plus, Trash2 } from 'lucide-react';\nimport { PageLayout, Input, Button, EmptyState, DataTable, RowActions } from '../components';\nimport {\n useListFeatureFlagsQuery,\n useUpdateFeatureFlagMutation,\n useDeleteFeatureFlagMutation,\n} from '../../generated/global-operations';\nimport { FeatureFlagStatus } from '../../generated/global-types';\n\nexport function FeatureFlagsPage() {\n const [search, setSearch] = useState('');\n const { data, loading, error, refetch } = useListFeatureFlagsQuery({\n variables: {\n filter: search ? { name: { contains: search } } : undefined,\n },\n });\n\n const [updateFeatureFlag] = useUpdateFeatureFlagMutation();\n const [deleteFeatureFlag] = useDeleteFeatureFlagMutation();\n\n const flags = data?.featureFlags?.items || [];\n\n const handleToggleStatus = async (id: string, currentStatus: FeatureFlagStatus) => {\n const newStatus =\n currentStatus === FeatureFlagStatus.Active\n ? FeatureFlagStatus.Archived\n : FeatureFlagStatus.Active;\n\n try {\n await updateFeatureFlag({\n variables: {\n id,\n input: { status: newStatus },\n },\n });\n refetch();\n } catch (err) {\n console.error('Failed to update status:', err);\n }\n };\n\n const handleDelete = async (id: string) => {\n if (confirm('Are you sure you want to delete this feature flag?')) {\n try {\n await deleteFeatureFlag({ variables: { id } });\n refetch();\n } catch (err) {\n console.error('Failed to delete flag:', err);\n }\n }\n };\n\n const columns = [\n {\n key: 'name',\n header: 'Name',\n render: (flag: any) => (\n <div className=\"flex flex-col text-left\">\n <span className=\"font-medium\">{flag.name}</span>\n <span className=\"text-xs text-text-secondary\">{flag.key}</span>\n </div>\n ),\n },\n {\n key: 'flagType',\n header: 'Type',\n },\n {\n key: 'status',\n header: 'Status',\n render: (flag: any) => {\n const isActive = flag.status === FeatureFlagStatus.Active;\n return (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => handleToggleStatus(flag.id, flag.status)}\n className={isActive ? 'border-primary text-primary' : 'text-text-secondary'}\n >\n {isActive ? 'Active' : 'Archived'}\n </Button>\n );\n },\n },\n {\n key: 'actions',\n header: '',\n align: 'right' as const,\n render: (flag: any) => (\n <RowActions\n actions={[\n {\n key: 'delete',\n label: 'Delete',\n icon: <Trash2 className=\"h-4 w-4\" />,\n onClick: () => handleDelete(flag.id),\n destructive: true,\n },\n ]}\n />\n ),\n },\n ];\n\n if (error) {\n return (\n <PageLayout title=\"Feature Flags\" description=\"Error loading feature flags\">\n <div className=\"p-4 text-status-error-text\">Error: {error.message}</div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Feature Flags\"\n gradientWord=\"Flags\"\n description=\"Manage and monitor platform feature flags\"\n actions={\n <Button>\n <Plus className=\"mr-2 h-4 w-4\" />\n Create Feature Flag\n </Button>\n }\n >\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"relative max-w-sm flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search feature flags...\"\n className=\"pl-9\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n data={flags}\n keyExtractor={(flag) => flag.id}\n loading={loading}\n emptyState={\n <EmptyState\n illustration=\"empty-data\"\n icon={<ToggleLeft className=\"h-8 w-8\" />}\n title=\"No feature flags found\"\n description=\"Feature flags will appear here when they are created\"\n />\n }\n />\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;AAUA,SAAgB,IAAmB;CACjC,IAAM,CAAC,GAAQ,KAAa,EAAS,GAAG,EAClC,EAAE,SAAM,YAAS,UAAO,eAAY,EAAyB,EACjE,WAAW,EACT,QAAQ,IAAS,EAAE,MAAM,EAAE,UAAU,GAAQ,EAAE,GAAG,KAAA,GACnD,EACF,CAAC,EAEI,CAAC,KAAqB,GAA8B,EACpD,CAAC,KAAqB,GAA8B,EAEpD,IAAQ,GAAM,cAAc,SAAS,EAAE,EAEvC,IAAqB,OAAO,GAAY,MAAqC;EACjF,IAAM,IACJ,MAAkB,EAAkB,SAChC,EAAkB,WAClB,EAAkB;AAExB,MAAI;AAOF,GANA,MAAM,EAAkB,EACtB,WAAW;IACT;IACA,OAAO,EAAE,QAAQ,GAAW;IAC7B,EACF,CAAC,EACF,GAAS;WACF,GAAK;AACZ,WAAQ,MAAM,4BAA4B,EAAI;;IAI5C,IAAe,OAAO,MAAe;AACzC,MAAI,QAAQ,qDAAqD,CAC/D,KAAI;AAEF,GADA,MAAM,EAAkB,EAAE,WAAW,EAAE,OAAI,EAAE,CAAC,EAC9C,GAAS;WACF,GAAK;AACZ,WAAQ,MAAM,0BAA0B,EAAI;;;AAiElD,QARI,IAEA,kBAAC,GAAD;EAAY,OAAM;EAAgB,aAAY;YAC5C,kBAAC,OAAD;GAAK,WAAU;aAAf,CAA4C,WAAQ,EAAM,QAAc;;EAC7D,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,cAAa;EACb,aAAY;EACZ,SACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,sBAE1B,EAAA,CAAA;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,wEAAyE,CAAA,EAC3F,kBAAC,GAAD;MACE,aAAY;MACZ,WAAU;MACV,OAAO;MACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;MAC1C,CAAA,CACE;;IACF,CAAA,EAEN,kBAAC,GAAD;IACW,SAtFD;KACd;MACE,KAAK;MACL,QAAQ;MACR,SAAS,MACP,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAe,EAAK;QAAY,CAAA,EAChD,kBAAC,QAAD;QAAM,WAAU;kBAA+B,EAAK;QAAW,CAAA,CAC3D;;MAET;KACD;MACE,KAAK;MACL,QAAQ;MACT;KACD;MACE,KAAK;MACL,QAAQ;MACR,SAAS,MAAc;OACrB,IAAM,IAAW,EAAK,WAAW,EAAkB;AACnD,cACE,kBAAC,GAAD;QACE,SAAQ;QACR,MAAK;QACL,eAAe,EAAmB,EAAK,IAAI,EAAK,OAAO;QACvD,WAAW,IAAW,gCAAgC;kBAErD,IAAW,WAAW;QAChB,CAAA;;MAGd;KACD;MACE,KAAK;MACL,QAAQ;MACR,OAAO;MACP,SAAS,MACP,kBAAC,GAAD,EACE,SAAS,CACP;OACE,KAAK;OACL,OAAO;OACP,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;OACpC,eAAe,EAAa,EAAK,GAAG;OACpC,aAAa;OACd,CACF,EACD,CAAA;MAEL;KACF;IAqCO,MAAM;IACN,eAAe,MAAS,EAAK;IACpB;IACT,YACE,kBAAC,GAAD;KACE,cAAa;KACb,MAAM,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA;KACxC,OAAM;KACN,aAAY;KACZ,CAAA;IAEJ,CAAA,CACE;;EACK,CAAA"}
1
+ {"version":3,"file":"FeatureFlagsPage.js","names":[],"sources":["../../../src/admin/pages/FeatureFlagsPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { ToggleLeft, Search, Plus, Trash2 } from 'lucide-react';\nimport { PageLayout, Input, Button, EmptyState, DataTable, RowActions } from '../components';\nimport { PagePurpose, EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport {\n useListFeatureFlagsQuery,\n useUpdateFeatureFlagMutation,\n useDeleteFeatureFlagMutation,\n} from '../../generated/global-operations';\nimport { FeatureFlagStatus } from '../../generated/global-types';\n\nexport function FeatureFlagsPage() {\n const [search, setSearch] = useState('');\n const { data, loading, error, refetch } = useListFeatureFlagsQuery({\n variables: {\n filter: search ? { name: { contains: search } } : undefined,\n },\n });\n\n const [updateFeatureFlag] = useUpdateFeatureFlagMutation();\n const [deleteFeatureFlag] = useDeleteFeatureFlagMutation();\n\n const flags = data?.featureFlags?.items || [];\n const activeFlagCount = flags.filter(\n (flag: { status: FeatureFlagStatus }) => flag.status === FeatureFlagStatus.Active\n ).length;\n\n const handleToggleStatus = async (id: string, currentStatus: FeatureFlagStatus) => {\n const newStatus =\n currentStatus === FeatureFlagStatus.Active\n ? FeatureFlagStatus.Archived\n : FeatureFlagStatus.Active;\n\n try {\n await updateFeatureFlag({\n variables: {\n id,\n input: { status: newStatus },\n },\n });\n refetch();\n } catch (err) {\n console.error('Failed to update status:', err);\n }\n };\n\n const handleDelete = async (id: string) => {\n if (confirm('Are you sure you want to delete this feature flag?')) {\n try {\n await deleteFeatureFlag({ variables: { id } });\n refetch();\n } catch (err) {\n console.error('Failed to delete flag:', err);\n }\n }\n };\n\n const columns = [\n {\n key: 'name',\n header: 'Name',\n render: (flag: any) => (\n <div className=\"flex flex-col text-left\">\n <span className=\"font-medium\">{flag.name}</span>\n <span className=\"text-xs text-text-secondary\">{flag.key}</span>\n </div>\n ),\n },\n {\n key: 'flagType',\n header: 'Type',\n },\n {\n key: 'status',\n header: 'Status',\n render: (flag: any) => {\n const isActive = flag.status === FeatureFlagStatus.Active;\n return (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => handleToggleStatus(flag.id, flag.status)}\n className={isActive ? 'border-primary text-primary' : 'text-text-secondary'}\n >\n {isActive ? 'Active' : 'Archived'}\n </Button>\n );\n },\n },\n {\n key: 'actions',\n header: '',\n align: 'right' as const,\n render: (flag: any) => (\n <RowActions\n actions={[\n {\n key: 'delete',\n label: 'Delete',\n icon: <Trash2 className=\"h-4 w-4\" />,\n onClick: () => handleDelete(flag.id),\n destructive: true,\n },\n ]}\n />\n ),\n },\n ];\n\n if (error) {\n return (\n <PageLayout title=\"Feature Flags\" description=\"Error loading feature flags\">\n <div className=\"p-4 text-status-error-text\">Error: {error.message}</div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Feature Flags\"\n gradientWord=\"Flags\"\n description=\"Manage and monitor platform feature flags\"\n actions={\n <Button>\n <Plus className=\"mr-2 h-4 w-4\" />\n Create Feature Flag\n </Button>\n }\n >\n <div className=\"space-y-4\">\n <PagePurpose>\n Feature flags let you turn parts of the platform on or off without shipping new code. Use\n this page to roll a feature out gradually, kill-switch something that&apos;s misbehaving,\n or archive flags you no longer need.\n </PagePurpose>\n\n {/* Emphasis: how many flags are currently active. */}\n <EmphasisPanel className=\"flex items-center gap-4 p-5\">\n <div className=\"flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-action-primary-bg/15 text-action-primary-bg\">\n <ToggleLeft className=\"h-6 w-6\" />\n </div>\n <div>\n <div className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {activeFlagCount}\n </div>\n <p className=\"text-sm text-text-secondary\">active feature flags</p>\n </div>\n </EmphasisPanel>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"relative max-w-sm flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search feature flags...\"\n className=\"pl-9\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n data={flags}\n keyExtractor={(flag) => flag.id}\n loading={loading}\n emptyState={\n <EmptyState\n illustration=\"empty-data\"\n icon={<ToggleLeft className=\"h-8 w-8\" />}\n title=\"No feature flags found\"\n description=\"Feature flags will appear here when they are created\"\n />\n }\n />\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -5,17 +5,18 @@ import { useListOrganizationsQuery as i, useUpdateOrganizationMutation as a } fr
5
5
  import { useState as o } from "react";
6
6
  import { Building as s, Loader2 as c, Plus as l, Search as u } from "lucide-react";
7
7
  import { jsx as d, jsxs as f } from "react/jsx-runtime";
8
+ import { EmphasisPanel as p, PagePurpose as m } from "@burdenoff/fe-libs/ui";
8
9
  //#region src/admin/pages/OrganizationsListPage.tsx
9
- function p() {
10
- let [p, m] = o(""), { data: h, loading: g, refetch: _ } = i({ variables: {
11
- filter: p ? { search: p } : void 0,
10
+ function h() {
11
+ let [h, g] = o(""), { data: _, loading: v, refetch: y } = i({ variables: {
12
+ filter: h ? { search: h } : void 0,
12
13
  limit: 50
13
- } }), [v] = a(), y = async (e, t) => {
14
- await v({ variables: {
14
+ } }), [b] = a(), x = async (e, t) => {
15
+ await b({ variables: {
15
16
  id: e,
16
17
  input: { status: t === "ACTIVE" ? "INACTIVE" : "ACTIVE" }
17
- } }), _();
18
- }, b = h?.allOrganizations?.items || [];
18
+ } }), y();
19
+ }, S = _?.allOrganizations?.items || [];
19
20
  return /* @__PURE__ */ d(r, {
20
21
  title: "Organizations",
21
22
  gradientWord: "Organizations",
@@ -23,92 +24,109 @@ function p() {
23
24
  actions: /* @__PURE__ */ f(e, { children: [/* @__PURE__ */ d(l, { className: "mr-2 h-4 w-4" }), "Create Organization"] }),
24
25
  children: /* @__PURE__ */ f("div", {
25
26
  className: "space-y-4",
26
- children: [/* @__PURE__ */ d("div", {
27
- className: "flex items-center justify-between",
28
- children: /* @__PURE__ */ f("div", {
29
- className: "relative max-w-sm flex-1",
30
- children: [/* @__PURE__ */ d(u, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ d(n, {
31
- placeholder: "Search organizations...",
32
- className: "pl-9",
33
- value: p,
34
- onChange: (e) => m(e.target.value)
35
- })]
36
- })
37
- }), g ? /* @__PURE__ */ d("div", {
38
- className: "flex h-64 items-center justify-center",
39
- children: /* @__PURE__ */ d(c, { className: "h-8 w-8 animate-spin text-text-secondary" })
40
- }) : b.length > 0 ? /* @__PURE__ */ d("div", {
41
- className: "rounded-md border",
42
- children: /* @__PURE__ */ f("table", {
43
- className: "w-full text-sm",
44
- children: [/* @__PURE__ */ d("thead", { children: /* @__PURE__ */ f("tr", {
45
- className: "border-b bg-bg-sunken/50 text-left",
46
- children: [
47
- /* @__PURE__ */ d("th", {
48
- className: "p-4 font-medium",
49
- children: "Name"
50
- }),
51
- /* @__PURE__ */ d("th", {
52
- className: "p-4 font-medium",
53
- children: "Slug"
54
- }),
55
- /* @__PURE__ */ d("th", {
56
- className: "p-4 font-medium",
57
- children: "Status"
58
- }),
59
- /* @__PURE__ */ d("th", {
60
- className: "p-4 font-medium",
61
- children: "Created At"
62
- }),
63
- /* @__PURE__ */ d("th", {
64
- className: "p-4 font-medium text-right",
65
- children: "Actions"
66
- })
67
- ]
68
- }) }), /* @__PURE__ */ d("tbody", { children: b.map((t) => /* @__PURE__ */ f("tr", {
69
- className: "border-b transition-colors hover:bg-bg-sunken/50",
70
- children: [
71
- /* @__PURE__ */ d("td", {
72
- className: "p-4 font-medium",
73
- children: t.name
74
- }),
75
- /* @__PURE__ */ d("td", {
76
- className: "p-4 text-text-secondary",
77
- children: t.slug
78
- }),
79
- /* @__PURE__ */ d("td", {
80
- className: "p-4",
81
- children: /* @__PURE__ */ d("span", {
82
- className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold ${t.status === "ACTIVE" ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"}`,
83
- children: t.status
27
+ children: [
28
+ /* @__PURE__ */ d(m, { children: "Organizations group people and workspaces within a tenant — think of a company's departments or a customer's teams. Use this page to find an organization, review whether it is active, and toggle access on or off without touching the tenant itself." }),
29
+ /* @__PURE__ */ f(p, {
30
+ className: "flex items-center gap-4 p-5",
31
+ children: [/* @__PURE__ */ d("div", {
32
+ className: "flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-action-primary-bg/15 text-action-primary-bg",
33
+ children: /* @__PURE__ */ d(s, { className: "h-6 w-6" })
34
+ }), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("div", {
35
+ className: "text-3xl font-bold tabular-nums text-text-primary",
36
+ children: _?.allOrganizations?.total ?? S.length
37
+ }), /* @__PURE__ */ d("p", {
38
+ className: "text-sm text-text-secondary",
39
+ children: "organizations on the platform"
40
+ })] })]
41
+ }),
42
+ /* @__PURE__ */ d("div", {
43
+ className: "flex items-center justify-between",
44
+ children: /* @__PURE__ */ f("div", {
45
+ className: "relative max-w-sm flex-1",
46
+ children: [/* @__PURE__ */ d(u, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ d(n, {
47
+ placeholder: "Search organizations...",
48
+ className: "pl-9",
49
+ value: h,
50
+ onChange: (e) => g(e.target.value)
51
+ })]
52
+ })
53
+ }),
54
+ v ? /* @__PURE__ */ d("div", {
55
+ className: "flex h-64 items-center justify-center",
56
+ children: /* @__PURE__ */ d(c, { className: "h-8 w-8 animate-spin text-text-secondary" })
57
+ }) : S.length > 0 ? /* @__PURE__ */ d("div", {
58
+ className: "rounded-md border",
59
+ children: /* @__PURE__ */ f("table", {
60
+ className: "w-full text-sm",
61
+ children: [/* @__PURE__ */ d("thead", { children: /* @__PURE__ */ f("tr", {
62
+ className: "border-b bg-bg-sunken/50 text-left",
63
+ children: [
64
+ /* @__PURE__ */ d("th", {
65
+ className: "p-4 font-medium",
66
+ children: "Name"
67
+ }),
68
+ /* @__PURE__ */ d("th", {
69
+ className: "p-4 font-medium",
70
+ children: "Slug"
71
+ }),
72
+ /* @__PURE__ */ d("th", {
73
+ className: "p-4 font-medium",
74
+ children: "Status"
75
+ }),
76
+ /* @__PURE__ */ d("th", {
77
+ className: "p-4 font-medium",
78
+ children: "Created At"
79
+ }),
80
+ /* @__PURE__ */ d("th", {
81
+ className: "p-4 font-medium text-right",
82
+ children: "Actions"
84
83
  })
85
- }),
86
- /* @__PURE__ */ d("td", {
87
- className: "p-4 text-text-secondary",
88
- children: new Date(t.createdAt).toLocaleDateString()
89
- }),
90
- /* @__PURE__ */ d("td", {
91
- className: "p-4 text-right",
92
- children: /* @__PURE__ */ d(e, {
93
- variant: "outline",
94
- size: "sm",
95
- onClick: () => y(t.id, t.status),
96
- children: "Toggle Status"
84
+ ]
85
+ }) }), /* @__PURE__ */ d("tbody", { children: S.map((t) => /* @__PURE__ */ f("tr", {
86
+ className: "border-b transition-colors hover:bg-bg-sunken/50",
87
+ children: [
88
+ /* @__PURE__ */ d("td", {
89
+ className: "p-4 font-medium",
90
+ children: t.name
91
+ }),
92
+ /* @__PURE__ */ d("td", {
93
+ className: "p-4 text-text-secondary",
94
+ children: t.slug
95
+ }),
96
+ /* @__PURE__ */ d("td", {
97
+ className: "p-4",
98
+ children: /* @__PURE__ */ d("span", {
99
+ className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold ${t.status === "ACTIVE" ? "bg-status-success-bg text-status-success-text border border-status-success-border" : "bg-status-error-bg text-status-error-text border border-status-error-border"}`,
100
+ children: t.status
101
+ })
102
+ }),
103
+ /* @__PURE__ */ d("td", {
104
+ className: "p-4 text-text-secondary",
105
+ children: new Date(t.createdAt).toLocaleDateString()
106
+ }),
107
+ /* @__PURE__ */ d("td", {
108
+ className: "p-4 text-right",
109
+ children: /* @__PURE__ */ d(e, {
110
+ variant: "outline",
111
+ size: "sm",
112
+ onClick: () => x(t.id, t.status),
113
+ children: "Toggle Status"
114
+ })
97
115
  })
98
- })
99
- ]
100
- }, t.id)) })]
116
+ ]
117
+ }, t.id)) })]
118
+ })
119
+ }) : /* @__PURE__ */ d(t, {
120
+ illustration: "empty-data",
121
+ icon: /* @__PURE__ */ d(s, { className: "h-8 w-8" }),
122
+ title: "No organizations found",
123
+ description: "Organizations will appear here when they are created"
101
124
  })
102
- }) : /* @__PURE__ */ d(t, {
103
- illustration: "empty-data",
104
- icon: /* @__PURE__ */ d(s, { className: "h-8 w-8" }),
105
- title: "No organizations found",
106
- description: "Organizations will appear here when they are created"
107
- })]
125
+ ]
108
126
  })
109
127
  });
110
128
  }
111
129
  //#endregion
112
- export { p as OrganizationsListPage };
130
+ export { h as OrganizationsListPage };
113
131
 
114
132
  //# sourceMappingURL=OrganizationsListPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationsListPage.js","names":[],"sources":["../../../src/admin/pages/OrganizationsListPage.tsx"],"sourcesContent":["import { Building, Search, Plus, Loader2 } from 'lucide-react';\nimport { PageLayout, Input, Button, EmptyState } from '../components';\nimport {\n useListOrganizationsQuery,\n useUpdateOrganizationMutation,\n} from '../../generated/global-operations';\nimport { useState } from 'react';\n\nexport function OrganizationsListPage() {\n const [searchTerm, setSearchTerm] = useState('');\n const { data, loading, refetch } = useListOrganizationsQuery({\n variables: {\n filter: searchTerm ? { search: searchTerm } : undefined,\n limit: 50,\n },\n });\n\n const [updateOrganization] = useUpdateOrganizationMutation();\n\n const handleToggleStatus = async (id: string, currentStatus: string) => {\n const newStatus = currentStatus === 'ACTIVE' ? 'INACTIVE' : 'ACTIVE';\n await updateOrganization({\n variables: {\n id,\n input: { status: newStatus },\n },\n });\n refetch();\n };\n\n const organizations = data?.allOrganizations?.items || [];\n\n return (\n <PageLayout\n title=\"Organizations\"\n gradientWord=\"Organizations\"\n description=\"Manage and monitor platform organizations\"\n actions={\n <Button>\n <Plus className=\"mr-2 h-4 w-4\" />\n Create Organization\n </Button>\n }\n >\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"relative max-w-sm flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search organizations...\"\n className=\"pl-9\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n />\n </div>\n </div>\n\n {loading ? (\n <div className=\"flex h-64 items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n ) : organizations.length > 0 ? (\n <div className=\"rounded-md border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-bg-sunken/50 text-left\">\n <th className=\"p-4 font-medium\">Name</th>\n <th className=\"p-4 font-medium\">Slug</th>\n <th className=\"p-4 font-medium\">Status</th>\n <th className=\"p-4 font-medium\">Created At</th>\n <th className=\"p-4 font-medium text-right\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {organizations.map((org: any) => (\n <tr key={org.id} className=\"border-b transition-colors hover:bg-bg-sunken/50\">\n <td className=\"p-4 font-medium\">{org.name}</td>\n <td className=\"p-4 text-text-secondary\">{org.slug}</td>\n <td className=\"p-4\">\n <span\n className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold ${\n org.status === 'ACTIVE'\n ? 'bg-green-100 text-green-800'\n : 'bg-red-100 text-red-800'\n }`}\n >\n {org.status}\n </span>\n </td>\n <td className=\"p-4 text-text-secondary\">\n {new Date(org.createdAt).toLocaleDateString()}\n </td>\n <td className=\"p-4 text-right\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => handleToggleStatus(org.id, org.status)}\n >\n Toggle Status\n </Button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Building className=\"h-8 w-8\" />}\n title=\"No organizations found\"\n description=\"Organizations will appear here when they are created\"\n />\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,IAAwB;CACtC,IAAM,CAAC,GAAY,KAAiB,EAAS,GAAG,EAC1C,EAAE,SAAM,YAAS,eAAY,EAA0B,EAC3D,WAAW;EACT,QAAQ,IAAa,EAAE,QAAQ,GAAY,GAAG,KAAA;EAC9C,OAAO;EACR,EACF,CAAC,EAEI,CAAC,KAAsB,GAA+B,EAEtD,IAAqB,OAAO,GAAY,MAA0B;AAQtE,EANA,MAAM,EAAmB,EACvB,WAAW;GACT;GACA,OAAO,EAAE,QAJK,MAAkB,WAAW,aAAa,UAI5B;GAC7B,EACF,CAAC,EACF,GAAS;IAGL,IAAgB,GAAM,kBAAkB,SAAS,EAAE;AAEzD,QACE,kBAAC,GAAD;EACE,OAAM;EACN,cAAa;EACb,aAAY;EACZ,SACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,sBAE1B,EAAA,CAAA;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,wEAAyE,CAAA,EAC3F,kBAAC,GAAD;MACE,aAAY;MACZ,WAAU;MACV,OAAO;MACP,WAAW,MAAM,EAAc,EAAE,OAAO,MAAM;MAC9C,CAAA,CACE;;IACF,CAAA,EAEL,IACC,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA;IAC5D,CAAA,GACJ,EAAc,SAAS,IACzB,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACE,kBAAC,MAAD;QAAI,WAAU;kBAAkB;QAAS,CAAA;OACzC,kBAAC,MAAD;QAAI,WAAU;kBAAkB;QAAS,CAAA;OACzC,kBAAC,MAAD;QAAI,WAAU;kBAAkB;QAAW,CAAA;OAC3C,kBAAC,MAAD;QAAI,WAAU;kBAAkB;QAAe,CAAA;OAC/C,kBAAC,MAAD;QAAI,WAAU;kBAA6B;QAAY,CAAA;OACpD;SACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAc,KAAK,MAClB,kBAAC,MAAD;MAAiB,WAAU;gBAA3B;OACE,kBAAC,MAAD;QAAI,WAAU;kBAAmB,EAAI;QAAU,CAAA;OAC/C,kBAAC,MAAD;QAAI,WAAU;kBAA2B,EAAI;QAAU,CAAA;OACvD,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,QAAD;SACE,WAAW,6EACT,EAAI,WAAW,WACX,gCACA;mBAGL,EAAI;SACA,CAAA;QACJ,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBACX,IAAI,KAAK,EAAI,UAAU,CAAC,oBAAoB;QAC1C,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,GAAD;SACE,SAAQ;SACR,MAAK;SACL,eAAe,EAAmB,EAAI,IAAI,EAAI,OAAO;mBACtD;SAEQ,CAAA;QACN,CAAA;OACF;QA1BI,EAAI,GA0BR,CACL,EACI,CAAA,CACF;;IACJ,CAAA,GAEN,kBAAC,GAAD;IACE,cAAa;IACb,MAAM,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;IACtC,OAAM;IACN,aAAY;IACZ,CAAA,CAEA;;EACK,CAAA"}
1
+ {"version":3,"file":"OrganizationsListPage.js","names":[],"sources":["../../../src/admin/pages/OrganizationsListPage.tsx"],"sourcesContent":["import { Building, Search, Plus, Loader2 } from 'lucide-react';\nimport { PageLayout, Input, Button, EmptyState } from '../components';\nimport { PagePurpose, EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport {\n useListOrganizationsQuery,\n useUpdateOrganizationMutation,\n} from '../../generated/global-operations';\nimport { useState } from 'react';\n\nexport function OrganizationsListPage() {\n const [searchTerm, setSearchTerm] = useState('');\n const { data, loading, refetch } = useListOrganizationsQuery({\n variables: {\n filter: searchTerm ? { search: searchTerm } : undefined,\n limit: 50,\n },\n });\n\n const [updateOrganization] = useUpdateOrganizationMutation();\n\n const handleToggleStatus = async (id: string, currentStatus: string) => {\n const newStatus = currentStatus === 'ACTIVE' ? 'INACTIVE' : 'ACTIVE';\n await updateOrganization({\n variables: {\n id,\n input: { status: newStatus },\n },\n });\n refetch();\n };\n\n const organizations = data?.allOrganizations?.items || [];\n\n return (\n <PageLayout\n title=\"Organizations\"\n gradientWord=\"Organizations\"\n description=\"Manage and monitor platform organizations\"\n actions={\n <Button>\n <Plus className=\"mr-2 h-4 w-4\" />\n Create Organization\n </Button>\n }\n >\n <div className=\"space-y-4\">\n <PagePurpose>\n Organizations group people and workspaces within a tenant — think of a company&apos;s\n departments or a customer&apos;s teams. Use this page to find an organization, review\n whether it is active, and toggle access on or off without touching the tenant itself.\n </PagePurpose>\n\n {/* Emphasis: how many organizations exist — the headline stat. */}\n <EmphasisPanel className=\"flex items-center gap-4 p-5\">\n <div className=\"flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-action-primary-bg/15 text-action-primary-bg\">\n <Building className=\"h-6 w-6\" />\n </div>\n <div>\n <div className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {data?.allOrganizations?.total ?? organizations.length}\n </div>\n <p className=\"text-sm text-text-secondary\">organizations on the platform</p>\n </div>\n </EmphasisPanel>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"relative max-w-sm flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search organizations...\"\n className=\"pl-9\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n />\n </div>\n </div>\n\n {loading ? (\n <div className=\"flex h-64 items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n ) : organizations.length > 0 ? (\n <div className=\"rounded-md border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-bg-sunken/50 text-left\">\n <th className=\"p-4 font-medium\">Name</th>\n <th className=\"p-4 font-medium\">Slug</th>\n <th className=\"p-4 font-medium\">Status</th>\n <th className=\"p-4 font-medium\">Created At</th>\n <th className=\"p-4 font-medium text-right\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {organizations.map((org: any) => (\n <tr key={org.id} className=\"border-b transition-colors hover:bg-bg-sunken/50\">\n <td className=\"p-4 font-medium\">{org.name}</td>\n <td className=\"p-4 text-text-secondary\">{org.slug}</td>\n <td className=\"p-4\">\n <span\n className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold ${\n org.status === 'ACTIVE'\n ? 'bg-status-success-bg text-status-success-text border border-status-success-border'\n : 'bg-status-error-bg text-status-error-text border border-status-error-border'\n }`}\n >\n {org.status}\n </span>\n </td>\n <td className=\"p-4 text-text-secondary\">\n {new Date(org.createdAt).toLocaleDateString()}\n </td>\n <td className=\"p-4 text-right\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => handleToggleStatus(org.id, org.status)}\n >\n Toggle Status\n </Button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Building className=\"h-8 w-8\" />}\n title=\"No organizations found\"\n description=\"Organizations will appear here when they are created\"\n />\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}