convex-cms 0.0.9-alpha.9 → 0.0.10

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 (117) hide show
  1. package/admin/src/components/Header.tsx +1 -1
  2. package/admin/src/components/RouteGuard.tsx +1 -1
  3. package/admin/src/components/UploadDropzone.tsx +1 -1
  4. package/admin/src/components/ui/sidebar.tsx +1 -1
  5. package/admin/src/contexts/AuthContext.tsx +1 -1
  6. package/admin/src/embed/components/EmbedSidebar.tsx +10 -10
  7. package/admin/src/embed/contexts/ApiContext.tsx +1 -1
  8. package/admin/src/hooks/usePermissions.ts +1 -1
  9. package/admin/src/index.css +432 -0
  10. package/admin/src/lib/cmsExports.ts +6 -0
  11. package/admin/src/pages/DashboardPage.tsx +2 -3
  12. package/admin/src/routes/__root.tsx +1 -1
  13. package/admin-dist/nitro.json +1 -1
  14. package/admin-dist/public/assets/{CmsEmptyState-DTlpzjOI.js → CmsEmptyState-BKeL4DBB.js} +1 -1
  15. package/admin-dist/public/assets/CmsFilterBar-CEpMHd_c.js +1 -0
  16. package/admin-dist/public/assets/{CmsPageHeader-0REGRH4X.js → CmsPageHeader-CIEkTbyH.js} +1 -1
  17. package/admin-dist/public/assets/{CmsStatusBadge-D_n8u8xa.js → CmsStatusBadge-BFMOsfMW.js} +1 -1
  18. package/admin-dist/public/assets/{CmsSurface-BHmvNai4.js → CmsSurface-kqqaFKUI.js} +1 -1
  19. package/admin-dist/public/assets/CmsTable-Db53Exq0.js +1 -0
  20. package/admin-dist/public/assets/ContentEntryEditor-Ct7cHayy.js +4 -0
  21. package/admin-dist/public/assets/TaxonomyFilter-Bm1DI1A7.js +1 -0
  22. package/admin-dist/public/assets/_contentTypeId-BekeCblX.js +1 -0
  23. package/admin-dist/public/assets/{_entryId-jPXz4z9T.js → _entryId-CoZDE0l0.js} +1 -1
  24. package/admin-dist/public/assets/{alert-CG97cMfC.js → alert-CpLdsTGU.js} +1 -1
  25. package/admin-dist/public/assets/{badge-C6qt24oj.js → badge-BQAotc5B.js} +1 -1
  26. package/admin-dist/public/assets/{circle-check-big-PltpxuB1.js → circle-check-big-BF3Y5nES.js} +1 -1
  27. package/admin-dist/public/assets/{command-CJ8i86fd.js → command-lEq6f_Ee.js} +1 -1
  28. package/admin-dist/public/assets/content-DH6k0dN6.js +1 -0
  29. package/admin-dist/public/assets/content-types-DHr9tc2V.js +1 -0
  30. package/admin-dist/public/assets/index-Cf0lbl0G.js +1 -0
  31. package/admin-dist/public/assets/index-D-4wFfgU.css +1 -0
  32. package/admin-dist/public/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  33. package/admin-dist/public/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  34. package/admin-dist/public/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  35. package/admin-dist/public/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  36. package/admin-dist/public/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  37. package/admin-dist/public/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  38. package/admin-dist/public/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  39. package/admin-dist/public/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  40. package/admin-dist/public/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  41. package/admin-dist/public/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  42. package/admin-dist/public/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  43. package/admin-dist/public/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  44. package/admin-dist/public/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  45. package/admin-dist/public/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  46. package/admin-dist/public/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  47. package/admin-dist/public/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  48. package/admin-dist/public/assets/main-B-6700eG.js +137 -0
  49. package/admin-dist/public/assets/media-DY5zD52L.js +1 -0
  50. package/admin-dist/public/assets/{new._contentTypeId-qsvo01mH.js → new._contentTypeId-Dq_NqTQV.js} +1 -1
  51. package/admin-dist/public/assets/{pencil-gAL0R34f.js → pencil-CI_KfxSx.js} +1 -1
  52. package/admin-dist/public/assets/refresh-cw-BrXg9a2r.js +1 -0
  53. package/admin-dist/public/assets/rotate-ccw-PwzxdPxd.js +1 -0
  54. package/admin-dist/public/assets/{scroll-area-CJBhf9pf.js → scroll-area-DX_nZYp8.js} +1 -1
  55. package/admin-dist/public/assets/{search-WXp6KxDJ.js → search-DlwBH4C5.js} +1 -1
  56. package/admin-dist/public/assets/settings-2mx3_ORG.js +1 -0
  57. package/admin-dist/public/assets/{switch-Ck9ecqEX.js → switch-CjPi4DKH.js} +1 -1
  58. package/admin-dist/public/assets/{tabs-vQYu8rjC.js → tabs-B5X37GEM.js} +1 -1
  59. package/admin-dist/public/assets/tanstack-adapter-KSm-nO5L.js +1 -0
  60. package/admin-dist/public/assets/{taxonomies-DvILUNvr.js → taxonomies-CHjJKNlR.js} +1 -1
  61. package/admin-dist/public/assets/trash-Cle-tcqq.js +1 -0
  62. package/admin-dist/public/assets/{useBreadcrumbLabel-tlSh7dtO.js → useBreadcrumbLabel-yZQG_N_3.js} +1 -1
  63. package/admin-dist/public/assets/{usePermissions-BTGdTOJS.js → usePermissions-D6vsoaJf.js} +1 -1
  64. package/admin-dist/server/_libs/convex-helpers.mjs +1077 -2
  65. package/admin-dist/server/_libs/convex.mjs +222 -13
  66. package/admin-dist/server/_libs/lucide-react.mjs +57 -51
  67. package/admin-dist/server/_ssr/{CmsEmptyState-CB6e53i5.mjs → CmsEmptyState-DzzuQG0S.mjs} +1 -1
  68. package/admin-dist/server/_ssr/CmsFilterBar-C5XADS12.mjs +81 -0
  69. package/admin-dist/server/_ssr/{CmsPageHeader-COUHuECp.mjs → CmsPageHeader-DZ6h7smh.mjs} +1 -1
  70. package/admin-dist/server/_ssr/{CmsStatusBadge-kMTL6koE.mjs → CmsStatusBadge-D-YFSAa1.mjs} +3 -3
  71. package/admin-dist/server/_ssr/{CmsSurface-D1HDYjRg.mjs → CmsSurface-Cv51NBLZ.mjs} +1 -1
  72. package/admin-dist/server/_ssr/CmsTable-DG88C5nO.mjs +189 -0
  73. package/admin-dist/server/_ssr/{ContentEntryEditor-Bq8FR_uK.mjs → ContentEntryEditor-CRjwXB17.mjs} +10 -10
  74. package/admin-dist/server/_ssr/{TaxonomyFilter-bm_p4ADg.mjs → TaxonomyFilter-xGwcgtjr.mjs} +3 -3
  75. package/admin-dist/server/_ssr/{_contentTypeId-B7obLmi_.mjs → _contentTypeId-DRCfeKkm.mjs} +53 -12
  76. package/admin-dist/server/_ssr/{_entryId-B4zhQqFg.mjs → _entryId-DULm2TDy.mjs} +11 -11
  77. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-iX3K33p1.mjs +4 -0
  78. package/admin-dist/server/_ssr/{badge-NOEC9bkk.mjs → badge-CbjIvhb6.mjs} +1 -1
  79. package/admin-dist/server/_ssr/{command-h4-OYNBo.mjs → command-xB2uiYps.mjs} +2 -2
  80. package/admin-dist/server/_ssr/{content-CShtLuhK.mjs → content-BfLBaJCZ.mjs} +108 -138
  81. package/admin-dist/server/_ssr/{content-types-PeyRyfbc.mjs → content-types-DZbF6O2q.mjs} +130 -119
  82. package/admin-dist/server/_ssr/{index-CplFXpGg.mjs → index-Cfe8sZv5.mjs} +65 -39
  83. package/admin-dist/server/_ssr/index.mjs +2 -2
  84. package/admin-dist/server/_ssr/{media-QAkNdX54.mjs → media-Bds2AnPC.mjs} +36 -56
  85. package/admin-dist/server/_ssr/{new._contentTypeId-DEJyMphJ.mjs → new._contentTypeId-DGvz_tlW.mjs} +10 -10
  86. package/admin-dist/server/_ssr/{router-CQXMuGMF.mjs → router-DxF7GBcO.mjs} +8804 -4995
  87. package/admin-dist/server/_ssr/{scroll-area-B7zoNyWB.mjs → scroll-area-DLDlXI07.mjs} +1 -1
  88. package/admin-dist/server/_ssr/{settings-CNaqVa4D.mjs → settings-BbaiS6z9.mjs} +13 -10
  89. package/admin-dist/server/_ssr/{switch-BKZhvryc.mjs → switch-Bl89Pfxu.mjs} +1 -1
  90. package/admin-dist/server/_ssr/{tabs-DtIIQxiD.mjs → tabs-QkbR0iir.mjs} +3 -3
  91. package/admin-dist/server/_ssr/{tanstack-adapter-CLavdbUY.mjs → tanstack-adapter-CKknPtcU.mjs} +19 -1
  92. package/admin-dist/server/_ssr/{taxonomies-vIZYICzr.mjs → taxonomies-S_Ontd0z.mjs} +9 -9
  93. package/admin-dist/server/_ssr/{trash-7yGR4-dF.mjs → trash-BzAIsbbN.mjs} +109 -132
  94. package/admin-dist/server/_ssr/{useBreadcrumbLabel-DR5FaAMf.mjs → useBreadcrumbLabel-BjiR1fM_.mjs} +1 -1
  95. package/admin-dist/server/_ssr/{usePermissions-DKkpETj_.mjs → usePermissions-CDHN95Nz.mjs} +1 -1
  96. package/admin-dist/server/index.mjs +284 -165
  97. package/package.json +3 -2
  98. package/admin/src/styles/globals.css +0 -82
  99. package/admin/src/styles/tailwind-config.css +0 -111
  100. package/admin/src/styles/theme.css +0 -384
  101. package/admin-dist/public/assets/CmsToolbar-CY6GV2L8.js +0 -1
  102. package/admin-dist/public/assets/ContentEntryEditor-CRgcRkk5.js +0 -4
  103. package/admin-dist/public/assets/TaxonomyFilter-Ohv5Jg9c.js +0 -1
  104. package/admin-dist/public/assets/_contentTypeId-C_vJq22X.js +0 -1
  105. package/admin-dist/public/assets/content-pKaIL2ru.js +0 -1
  106. package/admin-dist/public/assets/content-types-Bl_8I1Re.js +0 -1
  107. package/admin-dist/public/assets/globals-CoCRjt0K.css +0 -1
  108. package/admin-dist/public/assets/index-CtHq_P5q.js +0 -1
  109. package/admin-dist/public/assets/main-CA-4LyFT.js +0 -107
  110. package/admin-dist/public/assets/media-Bl1tBbJQ.js +0 -1
  111. package/admin-dist/public/assets/refresh-cw-sdVUGJNs.js +0 -1
  112. package/admin-dist/public/assets/rotate-ccw-6OcXCcxb.js +0 -1
  113. package/admin-dist/public/assets/settings-D8crrFCn.js +0 -1
  114. package/admin-dist/public/assets/tanstack-adapter-BRt2CUCw.js +0 -1
  115. package/admin-dist/public/assets/trash-YyYaC3L9.js +0 -1
  116. package/admin-dist/server/_ssr/CmsToolbar-NB014hsd.mjs +0 -48
  117. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-DndoqCo7.mjs +0 -4
@@ -1,14 +1,15 @@
1
1
  import { j as jsxRuntimeExports, r as reactExports } from "../_chunks/_libs/react.mjs";
2
- import { h as api, n as DropdownMenu, o as DropdownMenuTrigger, C as CmsButton, p as DropdownMenuContent, q as DropdownMenuItem, I as Input, S as Select, a as SelectTrigger, b as SelectValue, c as SelectContent, d as SelectItem, e as Checkbox, f as cn, u as useApi, i as CmsDialog } from "./router-CQXMuGMF.mjs";
3
- import { u as usePermissions } from "./usePermissions-DKkpETj_.mjs";
4
- import { B as Badge } from "./badge-NOEC9bkk.mjs";
5
- import { C as CmsPageHeader } from "./CmsPageHeader-COUHuECp.mjs";
6
- import { C as CmsToolbar } from "./CmsToolbar-NB014hsd.mjs";
7
- import { C as CmsEmptyState } from "./CmsEmptyState-CB6e53i5.mjs";
8
- import { C as CmsStatusBadge } from "./CmsStatusBadge-kMTL6koE.mjs";
9
- import { u as useTanStackNavigation } from "./tanstack-adapter-CLavdbUY.mjs";
10
- import { u as useQuery, f as useMutation } from "../_libs/convex.mjs";
11
- import { P as Plus, d as ChevronDown, a1 as Search, Q as FileText, X, al as CircleCheckBig, a0 as TriangleAlert } from "../_libs/lucide-react.mjs";
2
+ import { b as api, C as CmsButton, n as DropdownMenu, o as DropdownMenuTrigger, p as DropdownMenuContent, q as DropdownMenuItem, u as useApi, c as CmsDialog } from "./router-DxF7GBcO.mjs";
3
+ import { u as usePermissions } from "./usePermissions-CDHN95Nz.mjs";
4
+ import { B as Badge } from "./badge-CbjIvhb6.mjs";
5
+ import { C as CmsStatusBadge } from "./CmsStatusBadge-D-YFSAa1.mjs";
6
+ import { C as CmsEmptyState } from "./CmsEmptyState-DzzuQG0S.mjs";
7
+ import { C as CmsPageHeader } from "./CmsPageHeader-DZ6h7smh.mjs";
8
+ import { C as CmsTable } from "./CmsTable-DG88C5nO.mjs";
9
+ import { u as useTanStackNavigation } from "./tanstack-adapter-CKknPtcU.mjs";
10
+ import { C as CmsFilterBar } from "./CmsFilterBar-C5XADS12.mjs";
11
+ import { u as useQuery, k as useMutation } from "../_libs/convex.mjs";
12
+ import { P as Plus, d as ChevronDown, Q as FileText, X, al as CircleCheckBig, a0 as TriangleAlert } from "../_libs/lucide-react.mjs";
12
13
  import "../_chunks/_libs/@tanstack/react-router.mjs";
13
14
  import "../_libs/tiny-warning.mjs";
14
15
  import "../_chunks/_libs/@tanstack/router-core.mjs";
@@ -407,27 +408,58 @@ function ContentPage({ api: api2, navigation }) {
407
408
  day: "numeric"
408
409
  });
409
410
  };
410
- const handleSelectItem = reactExports.useCallback((id, selected) => {
411
- setSelectedIds((prev) => {
412
- const next = new Set(prev);
413
- if (selected) {
414
- next.add(id);
415
- } else {
416
- next.delete(id);
417
- }
418
- return next;
419
- });
420
- }, []);
421
- const handleSelectAll = reactExports.useCallback(() => {
422
- if (selectedIds.size === entries.length && entries.length > 0) {
423
- setSelectedIds(/* @__PURE__ */ new Set());
424
- } else {
425
- setSelectedIds(new Set(entries.map((e) => e._id)));
426
- }
427
- }, [selectedIds.size, entries]);
428
411
  const handleClearSelection = reactExports.useCallback(() => {
429
412
  setSelectedIds(/* @__PURE__ */ new Set());
430
413
  }, []);
414
+ const entryColumns = reactExports.useMemo(
415
+ () => [
416
+ {
417
+ key: "title",
418
+ header: "Title",
419
+ cell: (entry) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
420
+ "button",
421
+ {
422
+ type: "button",
423
+ onClick: () => navigation.navigateToEntry(entry._id),
424
+ className: "block text-left",
425
+ children: [
426
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-foreground hover:text-primary", children: getEntryTitle(entry, entry.contentTypeName) }),
427
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-muted-foreground", children: entry.slug })
428
+ ]
429
+ }
430
+ )
431
+ },
432
+ {
433
+ key: "type",
434
+ header: "Type",
435
+ cell: (entry) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-muted-foreground", children: getContentTypeDisplayName(entry.contentTypeName) })
436
+ },
437
+ {
438
+ key: "status",
439
+ header: "Status",
440
+ cell: (entry) => /* @__PURE__ */ jsxRuntimeExports.jsx(CmsStatusBadge, { status: entry.status })
441
+ },
442
+ {
443
+ key: "updated",
444
+ header: "Updated",
445
+ cell: (entry) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-muted-foreground", children: formatDate(entry._creationTime) })
446
+ },
447
+ {
448
+ key: "actions",
449
+ header: "Actions",
450
+ cell: (entry) => /* @__PURE__ */ jsxRuntimeExports.jsx(
451
+ CmsButton,
452
+ {
453
+ variant: "outline",
454
+ size: "sm",
455
+ onClick: () => navigation.navigateToEntry(entry._id),
456
+ children: canUpdate("contentEntries") ? "Edit" : "View"
457
+ }
458
+ )
459
+ }
460
+ ],
461
+ [navigation, contentTypes, canUpdate]
462
+ );
431
463
  if (isLoading) {
432
464
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6 p-6", children: [
433
465
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -452,56 +484,43 @@ function ContentPage({ api: api2, navigation }) {
452
484
  }
453
485
  ),
454
486
  /* @__PURE__ */ jsxRuntimeExports.jsx(
455
- CmsToolbar,
487
+ CmsFilterBar,
456
488
  {
457
- left: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
458
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
459
- /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
460
- /* @__PURE__ */ jsxRuntimeExports.jsx(
461
- Input,
462
- {
463
- type: "text",
464
- placeholder: "Search content...",
465
- value: searchQuery,
466
- onChange: (e) => setSearchQuery(e.target.value),
467
- className: "w-64 pl-9",
468
- "data-testid": "content-search-input"
469
- }
470
- )
471
- ] }),
472
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
473
- Select,
474
- {
475
- value: selectedTypeId || "all",
476
- onValueChange: (v) => setSelectedTypeId(v === "all" ? "" : v),
477
- children: [
478
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-48", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All Content Types" }) }),
479
- /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
480
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "all", children: "All Content Types" }),
481
- contentTypes.map((type) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: type._id, children: type.displayName }, type._id))
482
- ] })
483
- ]
484
- }
485
- ),
486
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
487
- Select,
488
- {
489
- value: selectedStatus || "all",
490
- onValueChange: (v) => setSelectedStatus(v === "all" ? "" : v),
491
- children: [
492
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-36", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All Statuses" }) }),
493
- /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
494
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "all", children: "All Statuses" }),
495
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "draft", children: "Draft" }),
496
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "published", children: "Published" }),
497
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "scheduled", children: "Scheduled" }),
498
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "archived", children: "Archived" })
499
- ] })
500
- ]
501
- }
502
- )
503
- ] }),
504
- right: canCreate("contentEntries") && /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
489
+ search: {
490
+ value: searchQuery,
491
+ onChange: setSearchQuery,
492
+ placeholder: "Search content...",
493
+ className: "w-64"
494
+ },
495
+ filters: [
496
+ {
497
+ key: "contentType",
498
+ value: selectedTypeId || "all",
499
+ onChange: (v) => setSelectedTypeId(v === "all" ? "" : v),
500
+ options: [
501
+ { value: "all", label: "All Content Types" },
502
+ ...contentTypes.map((type) => ({
503
+ value: type._id,
504
+ label: type.displayName
505
+ }))
506
+ ],
507
+ className: "w-48"
508
+ },
509
+ {
510
+ key: "status",
511
+ value: selectedStatus || "all",
512
+ onChange: (v) => setSelectedStatus(v === "all" ? "" : v),
513
+ options: [
514
+ { value: "all", label: "All Statuses" },
515
+ { value: "draft", label: "Draft" },
516
+ { value: "published", label: "Published" },
517
+ { value: "scheduled", label: "Scheduled" },
518
+ { value: "archived", label: "Archived" }
519
+ ],
520
+ className: "w-36"
521
+ }
522
+ ],
523
+ actions: canCreate("contentEntries") && /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
505
524
  /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { disabled: contentTypes.length === 0, children: [
506
525
  /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" }),
507
526
  "Create Entry",
@@ -533,67 +552,18 @@ function ContentPage({ api: api2, navigation }) {
533
552
  title: "No content entries yet",
534
553
  description: contentTypes.length === 0 ? "Create a content type first, then start adding content entries." : 'Click "Create Entry" to add your first content entry.'
535
554
  }
536
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full", children: [
537
- /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b", children: [
538
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "w-10 p-3 text-left", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
539
- Checkbox,
540
- {
541
- checked: selectedIds.size === entries.length && entries.length > 0,
542
- onCheckedChange: handleSelectAll,
543
- "aria-label": "Select all entries"
544
- }
545
- ) }),
546
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Title" }),
547
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Type" }),
548
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Status" }),
549
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Updated" }),
550
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Actions" })
551
- ] }) }),
552
- /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: entries.map((entry) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
553
- "tr",
554
- {
555
- className: cn(
556
- "border-b last:border-0 transition-colors hover:bg-muted/50",
557
- selectedIds.has(entry._id) && "bg-primary/5"
558
- ),
559
- children: [
560
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
561
- Checkbox,
562
- {
563
- checked: selectedIds.has(entry._id),
564
- onCheckedChange: (checked) => handleSelectItem(entry._id, checked),
565
- "aria-label": `Select ${getEntryTitle(entry, entry.contentTypeName)}`
566
- }
567
- ) }),
568
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
569
- "button",
570
- {
571
- type: "button",
572
- onClick: () => navigation.navigateToEntry(entry._id),
573
- className: "block text-left",
574
- children: [
575
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-foreground hover:text-primary", children: getEntryTitle(entry, entry.contentTypeName) }),
576
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-muted-foreground", children: entry.slug })
577
- ]
578
- }
579
- ) }),
580
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3 text-sm text-muted-foreground", children: getContentTypeDisplayName(entry.contentTypeName) }),
581
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CmsStatusBadge, { status: entry.status }) }),
582
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3 text-sm text-muted-foreground", children: formatDate(entry._creationTime) }),
583
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
584
- CmsButton,
585
- {
586
- variant: "outline",
587
- size: "sm",
588
- onClick: () => navigation.navigateToEntry(entry._id),
589
- children: canUpdate("contentEntries") ? "Edit" : "View"
590
- }
591
- ) })
592
- ]
593
- },
594
- entry._id
595
- )) })
596
- ] }) })
555
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
556
+ CmsTable,
557
+ {
558
+ columns: entryColumns,
559
+ data: entries,
560
+ getRowId: (e) => e._id,
561
+ selectable: true,
562
+ selectedIds,
563
+ onSelectionChange: setSelectedIds,
564
+ emptyMessage: "No content entries found"
565
+ }
566
+ )
597
567
  ] });
598
568
  }
599
569
  function ContentRoute() {
@@ -1,12 +1,13 @@
1
1
  import { j as jsxRuntimeExports, r as reactExports } from "../_chunks/_libs/react.mjs";
2
- import { h as api, f as cn, C as CmsButton, I as Input, e as Checkbox, w as ContentTypeFormModal } from "./router-CQXMuGMF.mjs";
3
- import { B as Badge } from "./badge-NOEC9bkk.mjs";
4
- import { C as CmsPageHeader } from "./CmsPageHeader-COUHuECp.mjs";
5
- import { C as CmsToolbar } from "./CmsToolbar-NB014hsd.mjs";
6
- import { C as CmsEmptyState } from "./CmsEmptyState-CB6e53i5.mjs";
7
- import { u as useTanStackNavigation } from "./tanstack-adapter-CLavdbUY.mjs";
2
+ import { b as api, e as cn, C as CmsButton, d as Checkbox, w as ContentTypeFormModal } from "./router-DxF7GBcO.mjs";
3
+ import { B as Badge } from "./badge-CbjIvhb6.mjs";
4
+ import { u as useTanStackNavigation } from "./tanstack-adapter-CKknPtcU.mjs";
5
+ import { C as CmsEmptyState } from "./CmsEmptyState-DzzuQG0S.mjs";
6
+ import { C as CmsPageHeader } from "./CmsPageHeader-DZ6h7smh.mjs";
7
+ import { C as CmsTable } from "./CmsTable-DG88C5nO.mjs";
8
+ import { C as CmsFilterBar } from "./CmsFilterBar-C5XADS12.mjs";
8
9
  import { u as useQuery } from "../_libs/convex.mjs";
9
- import { ak as Grid3x3, Y as List, P as Plus, a1 as Search, _ as FileType, f as CodeXml, k as Eye, a3 as Pencil, $ as TextAlignStart, V as FolderOpen, W as Tag, d as ChevronDown, t as Braces, O as Image, Z as Link2, y as Calendar, T as ToggleLeft, v as Hash } from "../_libs/lucide-react.mjs";
10
+ import { f as CodeXml, k as Eye, a2 as Pencil, ak as Grid3x3, Y as List, P as Plus, _ as FileType, $ as TextAlignStart, V as FolderOpen, W as Tag, d as ChevronDown, t as Braces, O as Image, Z as Link2, y as Calendar, T as ToggleLeft, v as Hash } from "../_libs/lucide-react.mjs";
10
11
  import "../_chunks/_libs/@tanstack/react-router.mjs";
11
12
  import "../_libs/tiny-warning.mjs";
12
13
  import "../_chunks/_libs/@tanstack/router-core.mjs";
@@ -145,6 +146,110 @@ function ContentTypesPage({ api: api2, navigation }) {
145
146
  return "Just now";
146
147
  }
147
148
  };
149
+ const contentTypeColumns = reactExports.useMemo(
150
+ () => [
151
+ {
152
+ key: "name",
153
+ header: "Name",
154
+ cell: (contentType) => /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
155
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium text-foreground", children: contentType.displayName }),
156
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: contentType.name })
157
+ ] })
158
+ },
159
+ {
160
+ key: "fields",
161
+ header: "Fields",
162
+ cell: (contentType) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-muted-foreground", children: contentType.fields.length })
163
+ },
164
+ {
165
+ key: "entries",
166
+ header: "Entries",
167
+ cell: (contentType) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-muted-foreground", children: contentType.entryCount ?? 0 })
168
+ },
169
+ {
170
+ key: "status",
171
+ header: "Status",
172
+ cell: (contentType) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [
173
+ contentType.source === "code" && /* @__PURE__ */ jsxRuntimeExports.jsxs(
174
+ Badge,
175
+ {
176
+ variant: "secondary",
177
+ className: "border-violet-200 bg-violet-50 text-xs font-normal text-violet-700",
178
+ title: "Managed by code",
179
+ children: [
180
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CodeXml, { className: "mr-1 size-3" }),
181
+ "Code"
182
+ ]
183
+ }
184
+ ),
185
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
186
+ Badge,
187
+ {
188
+ variant: contentType.isActive ? "default" : "secondary",
189
+ className: cn(
190
+ "text-xs font-normal",
191
+ contentType.isActive && "border-diff-added-border bg-diff-added-bg text-diff-added-foreground"
192
+ ),
193
+ children: contentType.isActive ? "Active" : "Inactive"
194
+ }
195
+ ),
196
+ contentType.singleton && /* @__PURE__ */ jsxRuntimeExports.jsx(
197
+ Badge,
198
+ {
199
+ variant: "secondary",
200
+ className: "border-diff-modified-border bg-diff-modified-bg text-xs font-normal text-diff-modified-foreground",
201
+ children: "Singleton"
202
+ }
203
+ )
204
+ ] })
205
+ },
206
+ {
207
+ key: "updated",
208
+ header: "Last Updated",
209
+ cell: (contentType) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-muted-foreground", children: formatDate(contentType._creationTime) })
210
+ },
211
+ {
212
+ key: "actions",
213
+ header: "Actions",
214
+ cell: (contentType) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
215
+ contentType.source === "code" ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
216
+ CmsButton,
217
+ {
218
+ variant: "outline",
219
+ size: "sm",
220
+ onClick: () => setEditingContentType(contentType),
221
+ title: "View content type (managed by code)",
222
+ children: [
223
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "size-3.5" }),
224
+ "View"
225
+ ]
226
+ }
227
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
228
+ CmsButton,
229
+ {
230
+ variant: "outline",
231
+ size: "sm",
232
+ onClick: () => setEditingContentType(contentType),
233
+ children: [
234
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-3.5" }),
235
+ "Edit"
236
+ ]
237
+ }
238
+ ),
239
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
240
+ CmsButton,
241
+ {
242
+ variant: "outline",
243
+ size: "sm",
244
+ onClick: () => navigation.navigateToContentType(contentType._id),
245
+ children: "View Entries"
246
+ }
247
+ )
248
+ ] })
249
+ }
250
+ ],
251
+ [navigation, formatDate, setEditingContentType]
252
+ );
148
253
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6 p-6", children: [
149
254
  /* @__PURE__ */ jsxRuntimeExports.jsx(
150
255
  CmsPageHeader,
@@ -154,22 +259,15 @@ function ContentTypesPage({ api: api2, navigation }) {
154
259
  }
155
260
  ),
156
261
  /* @__PURE__ */ jsxRuntimeExports.jsx(
157
- CmsToolbar,
262
+ CmsFilterBar,
158
263
  {
159
- left: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
160
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
161
- /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
162
- /* @__PURE__ */ jsxRuntimeExports.jsx(
163
- Input,
164
- {
165
- type: "search",
166
- placeholder: "Search content types...",
167
- value: searchQuery,
168
- onChange: (e) => setSearchQuery(e.target.value),
169
- className: "w-64 pl-9"
170
- }
171
- )
172
- ] }),
264
+ search: {
265
+ value: searchQuery,
266
+ onChange: setSearchQuery,
267
+ placeholder: "Search content types...",
268
+ className: "w-64"
269
+ },
270
+ actions: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
173
271
  /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex cursor-pointer items-center gap-2 text-sm", children: [
174
272
  /* @__PURE__ */ jsxRuntimeExports.jsx(
175
273
  Checkbox,
@@ -179,9 +277,7 @@ function ContentTypesPage({ api: api2, navigation }) {
179
277
  }
180
278
  ),
181
279
  "Active only"
182
- ] })
183
- ] }),
184
- right: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
280
+ ] }),
185
281
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex rounded-md border bg-muted/30", children: [
186
282
  /* @__PURE__ */ jsxRuntimeExports.jsx(
187
283
  "button",
@@ -332,100 +428,15 @@ function ContentTypesPage({ api: api2, navigation }) {
332
428
  ]
333
429
  },
334
430
  contentType._id
335
- )) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full", children: [
336
- /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b", children: [
337
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Name" }),
338
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Fields" }),
339
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Entries" }),
340
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Status" }),
341
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Last Updated" }),
342
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 text-left text-sm font-medium text-muted-foreground", children: "Actions" })
343
- ] }) }),
344
- /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: filteredContentTypes.map((contentType) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
345
- "tr",
346
- {
347
- className: "border-b last:border-0 transition-colors hover:bg-muted/50",
348
- children: [
349
- /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "p-3", children: [
350
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium text-foreground", children: contentType.displayName }),
351
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: contentType.name })
352
- ] }),
353
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3 text-sm text-muted-foreground", children: contentType.fields.length }),
354
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3 text-sm text-muted-foreground", children: contentType.entryCount ?? 0 }),
355
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [
356
- contentType.source === "code" && /* @__PURE__ */ jsxRuntimeExports.jsxs(
357
- Badge,
358
- {
359
- variant: "secondary",
360
- className: "border-violet-200 bg-violet-50 text-xs font-normal text-violet-700",
361
- title: "Managed by code",
362
- children: [
363
- /* @__PURE__ */ jsxRuntimeExports.jsx(CodeXml, { className: "mr-1 size-3" }),
364
- "Code"
365
- ]
366
- }
367
- ),
368
- /* @__PURE__ */ jsxRuntimeExports.jsx(
369
- Badge,
370
- {
371
- variant: contentType.isActive ? "default" : "secondary",
372
- className: cn(
373
- "text-xs font-normal",
374
- contentType.isActive && "border-diff-added-border bg-diff-added-bg text-diff-added-foreground"
375
- ),
376
- children: contentType.isActive ? "Active" : "Inactive"
377
- }
378
- ),
379
- contentType.singleton && /* @__PURE__ */ jsxRuntimeExports.jsx(
380
- Badge,
381
- {
382
- variant: "secondary",
383
- className: "border-diff-modified-border bg-diff-modified-bg text-xs font-normal text-diff-modified-foreground",
384
- children: "Singleton"
385
- }
386
- )
387
- ] }) }),
388
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3 text-sm text-muted-foreground", children: formatDate(contentType._creationTime) }),
389
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
390
- contentType.source === "code" ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
391
- CmsButton,
392
- {
393
- variant: "outline",
394
- size: "sm",
395
- onClick: () => setEditingContentType(contentType),
396
- title: "View content type (managed by code)",
397
- children: [
398
- /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "size-3.5" }),
399
- "View"
400
- ]
401
- }
402
- ) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
403
- CmsButton,
404
- {
405
- variant: "outline",
406
- size: "sm",
407
- onClick: () => setEditingContentType(contentType),
408
- children: [
409
- /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-3.5" }),
410
- "Edit"
411
- ]
412
- }
413
- ),
414
- /* @__PURE__ */ jsxRuntimeExports.jsx(
415
- CmsButton,
416
- {
417
- variant: "outline",
418
- size: "sm",
419
- onClick: () => navigation.navigateToContentType(contentType._id),
420
- children: "View Entries"
421
- }
422
- )
423
- ] }) })
424
- ]
425
- },
426
- contentType._id
427
- )) })
428
- ] }) }),
431
+ )) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
432
+ CmsTable,
433
+ {
434
+ columns: contentTypeColumns,
435
+ data: filteredContentTypes,
436
+ getRowId: (ct) => ct._id,
437
+ emptyMessage: "No content types found"
438
+ }
439
+ ),
429
440
  !isLoading && filteredContentTypes.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-center text-sm text-muted-foreground", children: [
430
441
  "Showing ",
431
442
  filteredContentTypes.length,