@burdenoff/microfe-admin 2026.625.1 → 2026.626.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 (70) hide show
  1. package/dist/admin/components/AccessDenied.js +2 -2
  2. package/dist/admin/components/AccessDenied.js.map +1 -1
  3. package/dist/admin/components/ActivityFeed.js +4 -4
  4. package/dist/admin/components/ActivityFeed.js.map +1 -1
  5. package/dist/admin/components/Charts.js.map +1 -1
  6. package/dist/admin/components/ConfirmDialog.js +1 -1
  7. package/dist/admin/components/ConfirmDialog.js.map +1 -1
  8. package/dist/admin/components/FormSheet.js +1 -1
  9. package/dist/admin/components/FormSheet.js.map +1 -1
  10. package/dist/admin/components/TenantSsoPanel.js +1 -1
  11. package/dist/admin/components/TenantSsoPanel.js.map +1 -1
  12. package/dist/admin/components/Toast.js +11 -11
  13. package/dist/admin/components/Toast.js.map +1 -1
  14. package/dist/admin/components/forms/SubscriptionForm.js +2 -2
  15. package/dist/admin/components/forms/SubscriptionForm.js.map +1 -1
  16. package/dist/admin/components/forms/TenantForm.js +1 -1
  17. package/dist/admin/components/forms/UserForm.js +1 -1
  18. package/dist/admin/components/ui.js +3 -3
  19. package/dist/admin/components/ui.js.map +1 -1
  20. package/dist/admin/constants/index.js +33 -24
  21. package/dist/admin/constants/index.js.map +1 -1
  22. package/dist/admin/pages/AuditLogsPage.js +92 -77
  23. package/dist/admin/pages/AuditLogsPage.js.map +1 -1
  24. package/dist/admin/pages/BillingPage.js +95 -51
  25. package/dist/admin/pages/BillingPage.js.map +1 -1
  26. package/dist/admin/pages/CommunicationsPage.js +97 -92
  27. package/dist/admin/pages/CommunicationsPage.js.map +1 -1
  28. package/dist/admin/pages/ContentPagesPage.js +274 -259
  29. package/dist/admin/pages/ContentPagesPage.js.map +1 -1
  30. package/dist/admin/pages/DashboardPage.js +113 -84
  31. package/dist/admin/pages/DashboardPage.js.map +1 -1
  32. package/dist/admin/pages/FeatureFlagsPage.js +93 -75
  33. package/dist/admin/pages/FeatureFlagsPage.js.map +1 -1
  34. package/dist/admin/pages/OrganizationsListPage.js +105 -87
  35. package/dist/admin/pages/OrganizationsListPage.js.map +1 -1
  36. package/dist/admin/pages/ProductsPage.js +138 -130
  37. package/dist/admin/pages/ProductsPage.js.map +1 -1
  38. package/dist/admin/pages/ReferralsPage.js +70 -52
  39. package/dist/admin/pages/ReferralsPage.js.map +1 -1
  40. package/dist/admin/pages/RolesPermissionsPage.js +136 -118
  41. package/dist/admin/pages/RolesPermissionsPage.js.map +1 -1
  42. package/dist/admin/pages/SREPage.js +34 -32
  43. package/dist/admin/pages/SREPage.js.map +1 -1
  44. package/dist/admin/pages/SandboxSettingsPage.js +360 -322
  45. package/dist/admin/pages/SandboxSettingsPage.js.map +1 -1
  46. package/dist/admin/pages/SettingsPage.js +63 -60
  47. package/dist/admin/pages/SettingsPage.js.map +1 -1
  48. package/dist/admin/pages/SyncFailuresPage.js +120 -118
  49. package/dist/admin/pages/SyncFailuresPage.js.map +1 -1
  50. package/dist/admin/pages/TenantDetailPage.js +261 -218
  51. package/dist/admin/pages/TenantDetailPage.js.map +1 -1
  52. package/dist/admin/pages/TenantFormRoutePage.js +65 -61
  53. package/dist/admin/pages/TenantFormRoutePage.js.map +1 -1
  54. package/dist/admin/pages/TenantsListPage.js +86 -71
  55. package/dist/admin/pages/TenantsListPage.js.map +1 -1
  56. package/dist/admin/pages/UsersListPage.js +128 -113
  57. package/dist/admin/pages/UsersListPage.js.map +1 -1
  58. package/dist/admin/pages/WaitlistPage.js +78 -63
  59. package/dist/admin/pages/WaitlistPage.js.map +1 -1
  60. package/dist/admin/pages/WorkflowsPage.js +107 -102
  61. package/dist/admin/pages/WorkflowsPage.js.map +1 -1
  62. package/dist/admin/pages/WorkspacesListPage.js +61 -49
  63. package/dist/admin/pages/WorkspacesListPage.js.map +1 -1
  64. package/dist/node_modules/@hookform/resolvers/dist/resolvers.js +2 -2
  65. package/dist/node_modules/@hookform/resolvers/dist/resolvers.js.map +1 -1
  66. package/dist/node_modules/@hookform/resolvers/zod/dist/zod.js +35 -26
  67. package/dist/node_modules/@hookform/resolvers/zod/dist/zod.js.map +1 -1
  68. package/dist/node_modules/react-hook-form/dist/index.esm.js +609 -516
  69. package/dist/node_modules/react-hook-form/dist/index.esm.js.map +1 -1
  70. package/package.json +2 -2
@@ -2,20 +2,21 @@ import { useToast as e } from "../components/Toast.js";
2
2
  import { useAdminPermissions as t } from "../hooks/useAdminPermissions.js";
3
3
  import { Badge as n, Button as r, EmptyState as i, Input as a } from "../components/ui.js";
4
4
  import { PageLayout as ee } from "../components/PageLayout.js";
5
- import { formatDate as te } from "../utils/formatters.js";
6
- import { DataTable as ne, Pagination as re } from "../components/DataTable.js";
7
- import { FormRow as o, FormSection as s, FormSheet as ie, FormSheetFooter as ae } from "../components/FormSheet.js";
8
- import { DeleteConfirmDialog as oe } from "../components/ConfirmDialog.js";
9
- import { RowActions as se, createRowActions as ce } from "../components/RowActions.js";
10
- import { PermissionGuard as le } from "../components/PermissionGuard.js";
5
+ import { formatDate as o } from "../utils/formatters.js";
6
+ import { DataTable as te, Pagination as ne } from "../components/DataTable.js";
7
+ import { FormRow as s, FormSection as c, FormSheet as re, FormSheetFooter as ie } from "../components/FormSheet.js";
8
+ import { DeleteConfirmDialog as ae } from "../components/ConfirmDialog.js";
9
+ import { RowActions as oe, createRowActions as se } from "../components/RowActions.js";
10
+ import { PermissionGuard as ce } from "../components/PermissionGuard.js";
11
11
  import "../components/index.js";
12
- import { useCallback as c, useEffect as l, useRef as ue, useState as u } from "react";
13
- import { FileText as de, Plus as fe, Search as pe } from "lucide-react";
14
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
15
- import { gql as p } from "@apollo/client";
12
+ import { useCallback as l, useEffect as u, useRef as le, useState as d } from "react";
13
+ import { FileText as f, Plus as ue, Search as de } from "lucide-react";
14
+ import { jsx as p, jsxs as m } from "react/jsx-runtime";
15
+ import { EmphasisPanel as fe, PagePurpose as pe } from "@burdenoff/fe-libs/ui";
16
+ import { gql as h } from "@apollo/client";
16
17
  import { useApolloClient as me } from "@apollo/client/react";
17
18
  //#region src/admin/pages/ContentPagesPage.tsx
18
- var m = 20, h = [
19
+ var g = 20, _ = [
19
20
  {
20
21
  value: "blog",
21
22
  label: "Blog",
@@ -35,7 +36,7 @@ var m = 20, h = [
35
36
  blog: "default",
36
37
  "case-study": "secondary",
37
38
  changelog: "outline"
38
- }, g = p`
39
+ }, ge = h`
39
40
  query AdminContentListProducts($limit: Int, $offset: Int) {
40
41
  platformProducts(limit: $limit, offset: $offset) {
41
42
  items {
@@ -45,7 +46,7 @@ var m = 20, h = [
45
46
  }
46
47
  }
47
48
  }
48
- `, ge = p`
49
+ `, _e = h`
49
50
  query AdminContentPages(
50
51
  $productId: String
51
52
  $filter: ContentPageFilterInput
@@ -75,25 +76,25 @@ var m = 20, h = [
75
76
  total
76
77
  }
77
78
  }
78
- `, _e = p`
79
+ `, ve = h`
79
80
  mutation AdminCreateContentPage($input: CreateContentPageInput!) {
80
81
  createContentPage(input: $input) {
81
82
  id
82
83
  slug
83
84
  }
84
85
  }
85
- `, ve = p`
86
+ `, v = h`
86
87
  mutation AdminUpdateContentPage($id: ID!, $input: UpdateContentPageInput!) {
87
88
  updateContentPage(id: $id, input: $input) {
88
89
  id
89
90
  slug
90
91
  }
91
92
  }
92
- `, ye = p`
93
+ `, ye = h`
93
94
  mutation AdminDeleteContentPage($id: ID!) {
94
95
  deleteContentPage(id: $id)
95
96
  }
96
- `, _ = {
97
+ `, y = {
97
98
  productId: "",
98
99
  type: "blog",
99
100
  slug: "",
@@ -107,24 +108,24 @@ var m = 20, h = [
107
108
  featured: !1,
108
109
  isPublished: !0
109
110
  };
110
- function v(e) {
111
+ function be(e) {
111
112
  return e.includes("changelog") ? "changelog" : e.includes("case-study") ? "case-study" : "blog";
112
113
  }
113
- var y = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50";
114
- function b() {
115
- let { canViewProducts: p, canManageProducts: b, isLoading: x } = t(), S = me(), C = e(), [w, be] = u([]), [T, E] = u(""), [D, xe] = u(""), [O, Se] = u(""), [k, A] = u(""), [j, M] = u(1), N = ue(0);
116
- l(() => {
114
+ var b = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50";
115
+ function x() {
116
+ let { canViewProducts: h, canManageProducts: x, isLoading: S } = t(), C = me(), w = e(), [T, xe] = d([]), [E, D] = d(""), [O, Se] = d(""), [k, A] = d(""), [j, Ce] = d(""), [M, N] = d(1), P = le(0);
117
+ u(() => {
117
118
  let e = setTimeout(() => {
118
- A(O), M(1);
119
+ Ce(k), N(1);
119
120
  }, 300);
120
121
  return () => clearTimeout(e);
121
- }, [O]);
122
- let [P, Ce] = u([]), [F, we] = u(0), [Te, I] = u(!1), [L, R] = u(null), [Ee, z] = u(!1), [B, V] = u(null), [H, U] = u(_), [De, W] = u(!1), [G, K] = u(null), [q, J] = u(!1), Y = x || !p;
123
- l(() => {
124
- if (Y) return;
122
+ }, [k]);
123
+ let [F, we] = d([]), [I, Te] = d(0), [Ee, L] = d(!1), [R, z] = d(null), [De, B] = d(!1), [V, H] = d(null), [U, W] = d(y), [Oe, G] = d(!1), [K, q] = d(null), [J, Y] = d(!1), X = S || !h;
124
+ u(() => {
125
+ if (X) return;
125
126
  let e = !0;
126
- return S.query({
127
- query: g,
127
+ return C.query({
128
+ query: ge,
128
129
  variables: {
129
130
  limit: 100,
130
131
  offset: 0
@@ -133,60 +134,60 @@ function b() {
133
134
  }).then((t) => {
134
135
  if (!e) return;
135
136
  let n = t.data?.platformProducts?.items ?? [];
136
- be(n), E((e) => e || n[0]?.id || "");
137
+ xe(n), D((e) => e || n[0]?.id || "");
137
138
  }).catch((t) => {
138
- e && R(t instanceof Error ? t.message : "Failed to load products");
139
+ e && z(t instanceof Error ? t.message : "Failed to load products");
139
140
  }), () => {
140
141
  e = !1;
141
142
  };
142
- }, [S, Y]);
143
- let X = c(async () => {
144
- if (Y || !T) return;
145
- let e = ++N.current;
146
- I(!0);
143
+ }, [C, X]);
144
+ let Z = l(async () => {
145
+ if (X || !E) return;
146
+ let e = ++P.current;
147
+ L(!0);
147
148
  try {
148
- let t = await S.query({
149
- query: ge,
149
+ let t = await C.query({
150
+ query: _e,
150
151
  variables: {
151
- productId: T,
152
+ productId: E,
152
153
  filter: {
153
- ...k ? { search: k } : {},
154
- ...D ? { tag: D } : {}
154
+ ...j ? { search: j } : {},
155
+ ...O ? { tag: O } : {}
155
156
  },
156
- limit: m,
157
- offset: (j - 1) * m
157
+ limit: g,
158
+ offset: (M - 1) * g
158
159
  },
159
160
  fetchPolicy: "network-only"
160
161
  });
161
- if (e !== N.current) return;
162
- Ce(t.data?.contentPages?.items ?? []), we(t.data?.contentPages?.total ?? 0), R(null);
162
+ if (e !== P.current) return;
163
+ we(t.data?.contentPages?.items ?? []), Te(t.data?.contentPages?.total ?? 0), z(null);
163
164
  } catch (t) {
164
- if (e !== N.current) return;
165
- R(t instanceof Error ? t.message : "Failed to load content pages");
165
+ if (e !== P.current) return;
166
+ z(t instanceof Error ? t.message : "Failed to load content pages");
166
167
  } finally {
167
- e === N.current && I(!1);
168
+ e === P.current && L(!1);
168
169
  }
169
170
  }, [
170
- S,
171
- Y,
172
- T,
173
- k,
174
- D,
175
- j
171
+ C,
172
+ X,
173
+ E,
174
+ j,
175
+ O,
176
+ M
176
177
  ]);
177
- l(() => {
178
- X();
179
- }, [X]);
180
- let Z = Math.ceil(F / m), Oe = c(() => {
181
- V(null), U({
182
- ..._,
183
- productId: T,
184
- type: D || "blog"
185
- }), z(!0);
186
- }, [T, D]), ke = c((e) => {
187
- V(e), U({
178
+ u(() => {
179
+ Z();
180
+ }, [Z]);
181
+ let ke = Math.ceil(I / g), Ae = l(() => {
182
+ H(null), W({
183
+ ...y,
184
+ productId: E,
185
+ type: O || "blog"
186
+ }), B(!0);
187
+ }, [E, O]), je = l((e) => {
188
+ H(e), W({
188
189
  productId: e.productId ?? "",
189
- type: v(e.tags),
190
+ type: be(e.tags),
190
191
  slug: e.slug,
191
192
  title: e.title,
192
193
  excerpt: e.excerpt ?? "",
@@ -197,96 +198,96 @@ function b() {
197
198
  readingTime: e.readingTime == null ? "" : String(e.readingTime),
198
199
  featured: e.featured,
199
200
  isPublished: e.isPublished
200
- }), z(!0);
201
- }, []), Ae = c(async () => {
201
+ }), B(!0);
202
+ }, []), Me = l(async () => {
202
203
  let e = [
203
- !H.title.trim() && "Title",
204
- !H.slug.trim() && "Slug",
205
- !H.content.trim() && "Content"
204
+ !U.title.trim() && "Title",
205
+ !U.slug.trim() && "Slug",
206
+ !U.content.trim() && "Content"
206
207
  ].filter(Boolean);
207
208
  if (e.length) {
208
- C.error(`${e.join(", ")} ${e.length > 1 ? "are" : "is"} required`);
209
+ w.error(`${e.join(", ")} ${e.length > 1 ? "are" : "is"} required`);
209
210
  return;
210
211
  }
211
- let t = H.thumbnail.trim();
212
+ let t = U.thumbnail.trim();
212
213
  if (t && !/^(https?:\/\/|\/\/|\/)/i.test(t)) {
213
- C.error("Thumbnail must be an http(s) URL or an absolute path");
214
+ w.error("Thumbnail must be an http(s) URL or an absolute path");
214
215
  return;
215
216
  }
216
- W(!0);
217
- let n = h.find((e) => e.value === H.type), r = B ? null : void 0, i = {
218
- title: H.title.trim(),
219
- content: H.content,
217
+ G(!0);
218
+ let n = _.find((e) => e.value === U.type), r = V ? null : void 0, i = {
219
+ title: U.title.trim(),
220
+ content: U.content,
220
221
  contentFormat: "markdown",
221
- excerpt: H.excerpt.trim() || r,
222
- author: H.author.trim() || r,
223
- publishedAt: H.publishedAt ? new Date(H.publishedAt).toISOString() : r,
224
- thumbnail: H.thumbnail.trim() || r,
225
- readingTime: H.readingTime === "" ? r : Number(H.readingTime),
226
- featured: H.featured,
227
- isPublished: H.isPublished
222
+ excerpt: U.excerpt.trim() || r,
223
+ author: U.author.trim() || r,
224
+ publishedAt: U.publishedAt ? new Date(U.publishedAt).toISOString() : r,
225
+ thumbnail: U.thumbnail.trim() || r,
226
+ readingTime: U.readingTime === "" ? r : Number(U.readingTime),
227
+ featured: U.featured,
228
+ isPublished: U.isPublished
228
229
  };
229
230
  try {
230
- B ? (await S.mutate({
231
- mutation: ve,
231
+ V ? (await C.mutate({
232
+ mutation: v,
232
233
  variables: {
233
- id: B.id,
234
+ id: V.id,
234
235
  input: i
235
236
  }
236
- }), C.success("Content page updated")) : (await S.mutate({
237
- mutation: _e,
237
+ }), w.success("Content page updated")) : (await C.mutate({
238
+ mutation: ve,
238
239
  variables: { input: {
239
240
  ...i,
240
241
  visibility: "PUBLIC",
241
- tags: [H.type],
242
+ tags: [U.type],
242
243
  category: n.category,
243
- productId: H.productId || void 0,
244
- slug: H.slug.trim().replace(/-+/g, "-").replace(/^-+|-+$/g, "")
244
+ productId: U.productId || void 0,
245
+ slug: U.slug.trim().replace(/-+/g, "-").replace(/^-+|-+$/g, "")
245
246
  } }
246
- }), C.success("Content page created")), z(!1), await X();
247
+ }), w.success("Content page created")), B(!1), await Z();
247
248
  } catch (e) {
248
- C.error(e instanceof Error ? e.message : "Failed to save content page");
249
+ w.error(e instanceof Error ? e.message : "Failed to save content page");
249
250
  } finally {
250
- W(!1);
251
+ G(!1);
251
252
  }
252
253
  }, [
253
- H,
254
- B,
255
- S,
254
+ U,
255
+ V,
256
256
  C,
257
- X
258
- ]), je = c(async () => {
259
- if (!(!G || q)) {
260
- J(!0);
257
+ w,
258
+ Z
259
+ ]), Ne = l(async () => {
260
+ if (!(!K || J)) {
261
+ Y(!0);
261
262
  try {
262
- await S.mutate({
263
+ await C.mutate({
263
264
  mutation: ye,
264
- variables: { id: G.id }
265
- }), C.success("Content page deleted"), K(null), P.length === 1 && j > 1 ? M((e) => e - 1) : await X();
265
+ variables: { id: K.id }
266
+ }), w.success("Content page deleted"), q(null), F.length === 1 && M > 1 ? N((e) => e - 1) : await Z();
266
267
  } catch (e) {
267
- C.error(e instanceof Error ? e.message : "Failed to delete content page");
268
+ w.error(e instanceof Error ? e.message : "Failed to delete content page");
268
269
  } finally {
269
- J(!1);
270
+ Y(!1);
270
271
  }
271
272
  }
272
273
  }, [
273
- G,
274
- q,
275
- S,
274
+ K,
275
+ J,
276
276
  C,
277
- X,
278
- P.length,
279
- j
280
- ]), Me = [
277
+ w,
278
+ Z,
279
+ F.length,
280
+ M
281
+ ]), Pe = [
281
282
  {
282
283
  key: "title",
283
284
  header: "Title",
284
- render: (e) => /* @__PURE__ */ f("div", {
285
+ render: (e) => /* @__PURE__ */ m("div", {
285
286
  className: "min-w-0",
286
- children: [/* @__PURE__ */ d("div", {
287
+ children: [/* @__PURE__ */ p("div", {
287
288
  className: "font-medium text-foreground",
288
289
  children: e.title
289
- }), /* @__PURE__ */ d("div", {
290
+ }), /* @__PURE__ */ p("div", {
290
291
  className: "truncate text-xs text-muted-foreground",
291
292
  children: e.slug
292
293
  })]
@@ -297,8 +298,8 @@ function b() {
297
298
  header: "Type",
298
299
  width: "120px",
299
300
  render: (e) => {
300
- let t = h.find((t) => e.tags.includes(t.value));
301
- return /* @__PURE__ */ d(n, {
301
+ let t = _.find((t) => e.tags.includes(t.value));
302
+ return /* @__PURE__ */ p(n, {
302
303
  variant: t ? he[t.value] : "outline",
303
304
  className: "text-xs capitalize",
304
305
  children: t?.label ?? "Other"
@@ -309,13 +310,13 @@ function b() {
309
310
  key: "status",
310
311
  header: "Status",
311
312
  width: "110px",
312
- render: (e) => /* @__PURE__ */ f("div", {
313
+ render: (e) => /* @__PURE__ */ m("div", {
313
314
  className: "flex items-center gap-1",
314
- children: [/* @__PURE__ */ d(n, {
315
+ children: [/* @__PURE__ */ p(n, {
315
316
  variant: e.isPublished ? "default" : "outline",
316
317
  className: "text-xs",
317
318
  children: e.isPublished ? "Published" : "Draft"
318
- }), e.featured && /* @__PURE__ */ d(n, {
319
+ }), e.featured && /* @__PURE__ */ p(n, {
319
320
  variant: "secondary",
320
321
  className: "text-xs",
321
322
  children: "Featured"
@@ -326,194 +327,208 @@ function b() {
326
327
  key: "updatedAt",
327
328
  header: "Updated",
328
329
  width: "110px",
329
- render: (e) => te(e.updatedAt)
330
+ render: (e) => o(e.updatedAt)
330
331
  },
331
332
  {
332
333
  key: "actions",
333
334
  header: "",
334
335
  width: "60px",
335
336
  align: "right",
336
- render: (e) => /* @__PURE__ */ d(se, { actions: ce({
337
- onEdit: b ? () => ke(e) : void 0,
338
- onDelete: b ? () => K(e) : void 0
337
+ render: (e) => /* @__PURE__ */ p(oe, { actions: se({
338
+ onEdit: x ? () => je(e) : void 0,
339
+ onDelete: x ? () => q(e) : void 0
339
340
  }) })
340
341
  }
341
- ], Q = "content-page-form", $ = !!B && !h.some((e) => B.tags.includes(e.value));
342
- return /* @__PURE__ */ f(le, {
343
- allowed: p,
344
- isLoading: x,
342
+ ], Q = "content-page-form", $ = !!V && !_.some((e) => V.tags.includes(e.value));
343
+ return /* @__PURE__ */ m(ce, {
344
+ allowed: h,
345
+ isLoading: S,
345
346
  pageTitle: "Content",
346
347
  denyMessage: "You don't have permission to manage content pages.",
347
348
  children: [
348
- /* @__PURE__ */ d(ee, {
349
+ /* @__PURE__ */ p(ee, {
349
350
  title: "Content",
350
351
  gradientWord: "Content",
351
- description: `Blog posts, case studies, and changelog entries${F ? ` · ${F} total` : ""}`,
352
- actions: /* @__PURE__ */ f(r, {
353
- onClick: Oe,
354
- disabled: !b || !T,
355
- children: [/* @__PURE__ */ d(fe, { className: "mr-2 h-4 w-4" }), "New Content"]
352
+ description: `Blog posts, case studies, and changelog entries${I ? ` · ${I} total` : ""}`,
353
+ actions: /* @__PURE__ */ m(r, {
354
+ onClick: Ae,
355
+ disabled: !x || !E,
356
+ children: [/* @__PURE__ */ p(ue, { className: "mr-2 h-4 w-4" }), "New Content"]
356
357
  }),
357
- children: /* @__PURE__ */ f("div", {
358
+ children: /* @__PURE__ */ m("div", {
358
359
  className: "space-y-4",
359
360
  children: [
360
- /* @__PURE__ */ f("div", {
361
+ /* @__PURE__ */ p(pe, { children: "Manage the marketing and product content that powers each product's public site — blog posts, case studies and changelog entries. Pick a product, then draft, edit and publish the stories that show up on its website." }),
362
+ /* @__PURE__ */ m(fe, {
363
+ className: "flex items-center gap-4 p-5",
364
+ children: [/* @__PURE__ */ p("div", {
365
+ className: "flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-action-primary-bg/15 text-action-primary-bg",
366
+ children: /* @__PURE__ */ p(f, { className: "h-6 w-6" })
367
+ }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("div", {
368
+ className: "text-3xl font-bold tabular-nums text-text-primary",
369
+ children: I
370
+ }), /* @__PURE__ */ p("p", {
371
+ className: "text-sm text-text-secondary",
372
+ children: "content entries for this product"
373
+ })] })]
374
+ }),
375
+ /* @__PURE__ */ m("div", {
361
376
  className: "flex flex-wrap items-center gap-3",
362
377
  children: [
363
- /* @__PURE__ */ f("select", {
378
+ /* @__PURE__ */ m("select", {
364
379
  "aria-label": "Filter by product",
365
- className: `${y} max-w-xs`,
366
- value: T,
380
+ className: `${b} max-w-xs`,
381
+ value: E,
367
382
  onChange: (e) => {
368
- M(1), E(e.target.value);
383
+ N(1), D(e.target.value);
369
384
  },
370
- children: [w.length === 0 && /* @__PURE__ */ d("option", {
385
+ children: [T.length === 0 && /* @__PURE__ */ p("option", {
371
386
  value: "",
372
387
  children: "Loading products…"
373
- }), w.map((e) => /* @__PURE__ */ d("option", {
388
+ }), T.map((e) => /* @__PURE__ */ p("option", {
374
389
  value: e.id,
375
390
  children: e.name
376
391
  }, e.id))]
377
392
  }),
378
- /* @__PURE__ */ f("select", {
393
+ /* @__PURE__ */ m("select", {
379
394
  "aria-label": "Filter by content type",
380
- className: `${y} max-w-[180px]`,
381
- value: D,
395
+ className: `${b} max-w-[180px]`,
396
+ value: O,
382
397
  onChange: (e) => {
383
- M(1), xe(e.target.value);
398
+ N(1), Se(e.target.value);
384
399
  },
385
- children: [/* @__PURE__ */ d("option", {
400
+ children: [/* @__PURE__ */ p("option", {
386
401
  value: "",
387
402
  children: "All types"
388
- }), h.map((e) => /* @__PURE__ */ d("option", {
403
+ }), _.map((e) => /* @__PURE__ */ p("option", {
389
404
  value: e.value,
390
405
  children: e.label
391
406
  }, e.value))]
392
407
  }),
393
- /* @__PURE__ */ f("div", {
408
+ /* @__PURE__ */ m("div", {
394
409
  className: "relative max-w-sm flex-1",
395
- children: [/* @__PURE__ */ d(pe, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), /* @__PURE__ */ d(a, {
410
+ children: [/* @__PURE__ */ p(de, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), /* @__PURE__ */ p(a, {
396
411
  placeholder: "Search content...",
397
- value: O,
398
- onChange: (e) => Se(e.target.value),
412
+ value: k,
413
+ onChange: (e) => A(e.target.value),
399
414
  className: "pl-9"
400
415
  })]
401
416
  })
402
417
  ]
403
418
  }),
404
- L && /* @__PURE__ */ d("div", {
419
+ R && /* @__PURE__ */ p("div", {
405
420
  className: "rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive",
406
- children: L
421
+ children: R
407
422
  }),
408
- /* @__PURE__ */ d(ne, {
409
- columns: Me,
410
- data: P,
423
+ /* @__PURE__ */ p(te, {
424
+ columns: Pe,
425
+ data: F,
411
426
  keyExtractor: (e) => e.id,
412
- loading: Te,
413
- emptyState: /* @__PURE__ */ d(i, {
427
+ loading: Ee,
428
+ emptyState: /* @__PURE__ */ p(i, {
414
429
  illustration: "empty-files",
415
- icon: /* @__PURE__ */ d(de, { className: "h-8 w-8" }),
430
+ icon: /* @__PURE__ */ p(f, { className: "h-8 w-8" }),
416
431
  title: "No content yet",
417
432
  description: "Create a blog post, case study, or changelog entry to get started."
418
433
  })
419
434
  }),
420
- F > m && /* @__PURE__ */ d(re, {
421
- page: j,
422
- totalPages: Z,
423
- totalItems: F,
424
- pageSize: m,
425
- onPageChange: M
435
+ I > g && /* @__PURE__ */ p(ne, {
436
+ page: M,
437
+ totalPages: ke,
438
+ totalItems: I,
439
+ pageSize: g,
440
+ onPageChange: N
426
441
  })
427
442
  ]
428
443
  })
429
444
  }),
430
- /* @__PURE__ */ d(ie, {
431
- open: Ee,
432
- onClose: () => z(!1),
433
- title: B ? "Edit content" : "New content",
434
- footer: /* @__PURE__ */ d(ae, {
445
+ /* @__PURE__ */ p(re, {
446
+ open: De,
447
+ onClose: () => B(!1),
448
+ title: V ? "Edit content" : "New content",
449
+ footer: /* @__PURE__ */ p(ie, {
435
450
  formId: Q,
436
- isSubmitting: De,
437
- submitLabel: B ? "Save changes" : "Create",
438
- onCancel: () => z(!1)
451
+ isSubmitting: Oe,
452
+ submitLabel: V ? "Save changes" : "Create",
453
+ onCancel: () => B(!1)
439
454
  }),
440
- children: /* @__PURE__ */ f("form", {
455
+ children: /* @__PURE__ */ m("form", {
441
456
  id: Q,
442
457
  onSubmit: (e) => {
443
- e.preventDefault(), Ae();
458
+ e.preventDefault(), Me();
444
459
  },
445
460
  className: "space-y-6",
446
461
  children: [
447
- /* @__PURE__ */ f(s, {
462
+ /* @__PURE__ */ m(c, {
448
463
  title: "Basics",
449
464
  children: [
450
- /* @__PURE__ */ f(o, {
465
+ /* @__PURE__ */ m(s, {
451
466
  cols: 2,
452
- children: [/* @__PURE__ */ f("label", {
467
+ children: [/* @__PURE__ */ m("label", {
453
468
  className: "space-y-1.5",
454
- children: [/* @__PURE__ */ d("span", {
469
+ children: [/* @__PURE__ */ p("span", {
455
470
  className: "text-sm font-medium",
456
471
  children: "Type"
457
- }), /* @__PURE__ */ f("select", {
458
- className: y,
459
- value: $ ? "__other" : H.type,
460
- disabled: !!B,
461
- onChange: (e) => U((t) => ({
472
+ }), /* @__PURE__ */ m("select", {
473
+ className: b,
474
+ value: $ ? "__other" : U.type,
475
+ disabled: !!V,
476
+ onChange: (e) => W((t) => ({
462
477
  ...t,
463
478
  type: e.target.value
464
479
  })),
465
- children: [$ && /* @__PURE__ */ d("option", {
480
+ children: [$ && /* @__PURE__ */ p("option", {
466
481
  value: "__other",
467
482
  children: "Other"
468
- }), h.map((e) => /* @__PURE__ */ d("option", {
483
+ }), _.map((e) => /* @__PURE__ */ p("option", {
469
484
  value: e.value,
470
485
  children: e.label
471
486
  }, e.value))]
472
487
  })]
473
- }), /* @__PURE__ */ f("label", {
488
+ }), /* @__PURE__ */ m("label", {
474
489
  className: "space-y-1.5",
475
- children: [/* @__PURE__ */ d("span", {
490
+ children: [/* @__PURE__ */ p("span", {
476
491
  className: "text-sm font-medium",
477
492
  children: "Product"
478
- }), /* @__PURE__ */ d("select", {
479
- className: y,
480
- value: H.productId,
481
- disabled: !!B,
482
- onChange: (e) => U((t) => ({
493
+ }), /* @__PURE__ */ p("select", {
494
+ className: b,
495
+ value: U.productId,
496
+ disabled: !!V,
497
+ onChange: (e) => W((t) => ({
483
498
  ...t,
484
499
  productId: e.target.value
485
500
  })),
486
- children: w.map((e) => /* @__PURE__ */ d("option", {
501
+ children: T.map((e) => /* @__PURE__ */ p("option", {
487
502
  value: e.id,
488
503
  children: e.name
489
504
  }, e.id))
490
505
  })]
491
506
  })]
492
507
  }),
493
- /* @__PURE__ */ f(o, {
508
+ /* @__PURE__ */ m(s, {
494
509
  cols: 2,
495
- children: [/* @__PURE__ */ f("label", {
510
+ children: [/* @__PURE__ */ m("label", {
496
511
  className: "space-y-1.5",
497
- children: [/* @__PURE__ */ d("span", {
512
+ children: [/* @__PURE__ */ p("span", {
498
513
  className: "text-sm font-medium",
499
514
  children: "Title"
500
- }), /* @__PURE__ */ d(a, {
501
- value: H.title,
502
- onChange: (e) => U((t) => ({
515
+ }), /* @__PURE__ */ p(a, {
516
+ value: U.title,
517
+ onChange: (e) => W((t) => ({
503
518
  ...t,
504
519
  title: e.target.value
505
520
  })),
506
521
  placeholder: "A clear, descriptive title"
507
522
  })]
508
- }), /* @__PURE__ */ f("label", {
523
+ }), /* @__PURE__ */ m("label", {
509
524
  className: "space-y-1.5",
510
- children: [/* @__PURE__ */ d("span", {
525
+ children: [/* @__PURE__ */ p("span", {
511
526
  className: "text-sm font-medium",
512
527
  children: "Slug"
513
- }), /* @__PURE__ */ d(a, {
514
- value: H.slug,
515
- disabled: !!B,
516
- onChange: (e) => U((t) => ({
528
+ }), /* @__PURE__ */ p(a, {
529
+ value: U.slug,
530
+ disabled: !!V,
531
+ onChange: (e) => W((t) => ({
517
532
  ...t,
518
533
  slug: e.target.value.toLowerCase().replace(/[^a-z0-9-]+/g, "-")
519
534
  })),
@@ -521,15 +536,15 @@ function b() {
521
536
  })]
522
537
  })]
523
538
  }),
524
- /* @__PURE__ */ f("label", {
539
+ /* @__PURE__ */ m("label", {
525
540
  className: "block space-y-1.5",
526
- children: [/* @__PURE__ */ d("span", {
541
+ children: [/* @__PURE__ */ p("span", {
527
542
  className: "text-sm font-medium",
528
543
  children: "Excerpt"
529
- }), /* @__PURE__ */ d("textarea", {
530
- className: `${y} h-16 py-2`,
531
- value: H.excerpt,
532
- onChange: (e) => U((t) => ({
544
+ }), /* @__PURE__ */ p("textarea", {
545
+ className: `${b} h-16 py-2`,
546
+ value: U.excerpt,
547
+ onChange: (e) => W((t) => ({
533
548
  ...t,
534
549
  excerpt: e.target.value
535
550
  })),
@@ -538,64 +553,64 @@ function b() {
538
553
  })
539
554
  ]
540
555
  }),
541
- /* @__PURE__ */ d(s, {
556
+ /* @__PURE__ */ p(c, {
542
557
  title: "Content",
543
558
  description: "Markdown supported (headings, lists, links, bold).",
544
- children: /* @__PURE__ */ d("textarea", {
559
+ children: /* @__PURE__ */ p("textarea", {
545
560
  "aria-label": "Content",
546
- className: `${y} h-64 py-2 font-mono text-xs`,
547
- value: H.content,
548
- onChange: (e) => U((t) => ({
561
+ className: `${b} h-64 py-2 font-mono text-xs`,
562
+ value: U.content,
563
+ onChange: (e) => W((t) => ({
549
564
  ...t,
550
565
  content: e.target.value
551
566
  })),
552
567
  placeholder: "## Heading\n\nWrite your content in markdown..."
553
568
  })
554
569
  }),
555
- /* @__PURE__ */ f(s, {
570
+ /* @__PURE__ */ m(c, {
556
571
  title: "Meta",
557
572
  children: [
558
- /* @__PURE__ */ f(o, {
573
+ /* @__PURE__ */ m(s, {
559
574
  cols: 3,
560
575
  children: [
561
- /* @__PURE__ */ f("label", {
576
+ /* @__PURE__ */ m("label", {
562
577
  className: "space-y-1.5",
563
- children: [/* @__PURE__ */ d("span", {
578
+ children: [/* @__PURE__ */ p("span", {
564
579
  className: "text-sm font-medium",
565
580
  children: "Author"
566
- }), /* @__PURE__ */ d(a, {
567
- value: H.author,
568
- onChange: (e) => U((t) => ({
581
+ }), /* @__PURE__ */ p(a, {
582
+ value: U.author,
583
+ onChange: (e) => W((t) => ({
569
584
  ...t,
570
585
  author: e.target.value
571
586
  })),
572
587
  placeholder: "The Team"
573
588
  })]
574
589
  }),
575
- /* @__PURE__ */ f("label", {
590
+ /* @__PURE__ */ m("label", {
576
591
  className: "space-y-1.5",
577
- children: [/* @__PURE__ */ d("span", {
592
+ children: [/* @__PURE__ */ p("span", {
578
593
  className: "text-sm font-medium",
579
594
  children: "Published date"
580
- }), /* @__PURE__ */ d(a, {
595
+ }), /* @__PURE__ */ p(a, {
581
596
  type: "date",
582
- value: H.publishedAt,
583
- onChange: (e) => U((t) => ({
597
+ value: U.publishedAt,
598
+ onChange: (e) => W((t) => ({
584
599
  ...t,
585
600
  publishedAt: e.target.value
586
601
  }))
587
602
  })]
588
603
  }),
589
- /* @__PURE__ */ f("label", {
604
+ /* @__PURE__ */ m("label", {
590
605
  className: "space-y-1.5",
591
- children: [/* @__PURE__ */ d("span", {
606
+ children: [/* @__PURE__ */ p("span", {
592
607
  className: "text-sm font-medium",
593
608
  children: "Reading time (min)"
594
- }), /* @__PURE__ */ d(a, {
609
+ }), /* @__PURE__ */ p(a, {
595
610
  type: "number",
596
611
  min: 0,
597
- value: H.readingTime,
598
- onChange: (e) => U((t) => ({
612
+ value: U.readingTime,
613
+ onChange: (e) => W((t) => ({
599
614
  ...t,
600
615
  readingTime: e.target.value
601
616
  }))
@@ -603,38 +618,38 @@ function b() {
603
618
  })
604
619
  ]
605
620
  }),
606
- /* @__PURE__ */ f("label", {
621
+ /* @__PURE__ */ m("label", {
607
622
  className: "block space-y-1.5",
608
- children: [/* @__PURE__ */ d("span", {
623
+ children: [/* @__PURE__ */ p("span", {
609
624
  className: "text-sm font-medium",
610
625
  children: "Thumbnail URL"
611
- }), /* @__PURE__ */ d(a, {
612
- value: H.thumbnail,
613
- onChange: (e) => U((t) => ({
626
+ }), /* @__PURE__ */ p(a, {
627
+ value: U.thumbnail,
628
+ onChange: (e) => W((t) => ({
614
629
  ...t,
615
630
  thumbnail: e.target.value
616
631
  })),
617
632
  placeholder: "https://…/image.png"
618
633
  })]
619
634
  }),
620
- /* @__PURE__ */ f("div", {
635
+ /* @__PURE__ */ m("div", {
621
636
  className: "flex items-center gap-6 pt-1",
622
- children: [/* @__PURE__ */ f("label", {
637
+ children: [/* @__PURE__ */ m("label", {
623
638
  className: "flex items-center gap-2 text-sm",
624
- children: [/* @__PURE__ */ d("input", {
639
+ children: [/* @__PURE__ */ p("input", {
625
640
  type: "checkbox",
626
- checked: H.featured,
627
- onChange: (e) => U((t) => ({
641
+ checked: U.featured,
642
+ onChange: (e) => W((t) => ({
628
643
  ...t,
629
644
  featured: e.target.checked
630
645
  }))
631
646
  }), "Featured"]
632
- }), /* @__PURE__ */ f("label", {
647
+ }), /* @__PURE__ */ m("label", {
633
648
  className: "flex items-center gap-2 text-sm",
634
- children: [/* @__PURE__ */ d("input", {
649
+ children: [/* @__PURE__ */ p("input", {
635
650
  type: "checkbox",
636
- checked: H.isPublished,
637
- onChange: (e) => U((t) => ({
651
+ checked: U.isPublished,
652
+ onChange: (e) => W((t) => ({
638
653
  ...t,
639
654
  isPublished: e.target.checked
640
655
  }))
@@ -646,18 +661,18 @@ function b() {
646
661
  ]
647
662
  })
648
663
  }),
649
- /* @__PURE__ */ d(oe, {
650
- open: !!G,
651
- onClose: () => K(null),
652
- onConfirm: je,
653
- itemName: G?.title ?? "this content page",
664
+ /* @__PURE__ */ p(ae, {
665
+ open: !!K,
666
+ onClose: () => q(null),
667
+ onConfirm: Ne,
668
+ itemName: K?.title ?? "this content page",
654
669
  itemType: "content page",
655
- loading: q
670
+ loading: J
656
671
  })
657
672
  ]
658
673
  });
659
674
  }
660
675
  //#endregion
661
- export { b as ContentPagesPage };
676
+ export { x as ContentPagesPage };
662
677
 
663
678
  //# sourceMappingURL=ContentPagesPage.js.map