convex-cms 0.0.5-alpha.4 → 0.0.5-alpha.5

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 (145) hide show
  1. package/README.md +3 -3
  2. package/admin/src/components/Sidebar.tsx +150 -58
  3. package/admin/src/components/ui/collapsible.tsx +7 -0
  4. package/admin/src/embed/components/EmbedSidebar.tsx +163 -68
  5. package/admin-dist/nitro.json +1 -1
  6. package/admin-dist/public/assets/{CmsEmptyState-CkqBIab3.js → CmsEmptyState-Do_erIgn.js} +1 -1
  7. package/admin-dist/public/assets/{CmsPageHeader-CUtl5MMG.js → CmsPageHeader-qDwPGi48.js} +1 -1
  8. package/admin-dist/public/assets/{CmsStatusBadge-CUYFgEe-.js → CmsStatusBadge-Dd9uToHE.js} +1 -1
  9. package/admin-dist/public/assets/{CmsSurface-CsJfAVa3.js → CmsSurface-DBy5Lumx.js} +1 -1
  10. package/admin-dist/public/assets/{CmsToolbar-CnfbcxeP.js → CmsToolbar-D1-Y-7SK.js} +1 -1
  11. package/admin-dist/public/assets/ContentEntryEditor-CWBiIx52.js +4 -0
  12. package/admin-dist/public/assets/{TaxonomyFilter-CWCxC5HZ.js → TaxonomyFilter-CdYQawxb.js} +1 -1
  13. package/admin-dist/public/assets/_contentTypeId-D9VMP6Gs.js +1 -0
  14. package/admin-dist/public/assets/_entryId-2FlCfqE7.js +1 -0
  15. package/admin-dist/public/assets/{alert-CF1BSzGR.js → alert-GxZx0y5c.js} +1 -1
  16. package/admin-dist/public/assets/{badge-CmuOIVKp.js → badge-BAlGIjop.js} +1 -1
  17. package/admin-dist/public/assets/{circle-check-big-BKDVG6DU.js → circle-check-big-CpLxAvEj.js} +1 -1
  18. package/admin-dist/public/assets/{command-XJxnF2Sd.js → command-di7XCqcv.js} +1 -1
  19. package/admin-dist/public/assets/content-D8zELsDG.js +1 -0
  20. package/admin-dist/public/assets/{content-types-CrNEm8Hf.js → content-types-BmzD0krT.js} +2 -2
  21. package/admin-dist/public/assets/globals-BvFfH-v9.css +1 -0
  22. package/admin-dist/public/assets/{index-C7xOwudI.js → index-zqfj4T_v.js} +1 -1
  23. package/admin-dist/public/assets/{label-CHCnXeBk.js → label-B6PPtKR5.js} +1 -1
  24. package/admin-dist/public/assets/{link-2-Bb34judH.js → link-2-W2fVnVOf.js} +1 -1
  25. package/admin-dist/public/assets/{list-9Pzt48ld.js → list-F8O0lZXC.js} +1 -1
  26. package/admin-dist/public/assets/main-dZT72bAG.js +97 -0
  27. package/admin-dist/public/assets/media-CETueFbV.js +1 -0
  28. package/admin-dist/public/assets/new._contentTypeId-BV2-TyyR.js +1 -0
  29. package/admin-dist/public/assets/{plus-Ceef7DHk.js → plus-AABQIF0N.js} +1 -1
  30. package/admin-dist/public/assets/{rotate-ccw-7k7-4VUq.js → rotate-ccw-BZpZtw0N.js} +1 -1
  31. package/admin-dist/public/assets/{scroll-area-CC6wujnp.js → scroll-area-CDfk-zrz.js} +1 -1
  32. package/admin-dist/public/assets/{search-DwoUV2pv.js → search-BvgYr-c9.js} +1 -1
  33. package/admin-dist/public/assets/{select-hOZTp8aC.js → select-BuiHcMzS.js} +1 -1
  34. package/admin-dist/public/assets/settings-DBxbYDvn.js +1 -0
  35. package/admin-dist/public/assets/{switch-jX2pDaNU.js → switch-DiJvolcs.js} +1 -1
  36. package/admin-dist/public/assets/tabs-Cgz6G_Xy.js +1 -0
  37. package/admin-dist/public/assets/{tanstack-adapter-B-Glm4kH.js → tanstack-adapter-BknsSgra.js} +1 -1
  38. package/admin-dist/public/assets/taxonomies-DOErsLl5.js +1 -0
  39. package/admin-dist/public/assets/{textarea-B6SfBmr0.js → textarea-CgggMxUX.js} +1 -1
  40. package/admin-dist/public/assets/{trash-BOCnIznD.js → trash-BU4ANuaW.js} +1 -1
  41. package/admin-dist/public/assets/{triangle-alert-CXFIO_Gu.js → triangle-alert-lvCbwp0s.js} +1 -1
  42. package/admin-dist/public/assets/{useBreadcrumbLabel-_6qBagc3.js → useBreadcrumbLabel-D00rvqjw.js} +1 -1
  43. package/admin-dist/public/assets/{usePermissions-M1ijZ7a6.js → usePermissions-D7tQowaF.js} +1 -1
  44. package/admin-dist/server/_chunks/_libs/@radix-ui/react-collapsible.mjs +144 -0
  45. package/admin-dist/server/_chunks/_libs/@radix-ui/react-slot.mjs +21 -21
  46. package/admin-dist/server/_libs/lucide-react.mjs +131 -124
  47. package/admin-dist/server/_ssr/{CmsButton-DOiTVKQq.mjs → CmsButton-DbzfJru_.mjs} +1 -1
  48. package/admin-dist/server/_ssr/{CmsEmptyState-fbnGt3LD.mjs → CmsEmptyState-CuvcXr3Z.mjs} +3 -3
  49. package/admin-dist/server/_ssr/{CmsPageHeader-DHRrdOZa.mjs → CmsPageHeader-ClNPU7Up.mjs} +1 -1
  50. package/admin-dist/server/_ssr/{CmsStatusBadge-s7obWbKZ.mjs → CmsStatusBadge-CojMbrY7.mjs} +2 -2
  51. package/admin-dist/server/_ssr/{CmsSurface-rFoYjb62.mjs → CmsSurface-Dcv440rp.mjs} +1 -1
  52. package/admin-dist/server/_ssr/{CmsToolbar-zTE45z2q.mjs → CmsToolbar-BKv1nL6u.mjs} +2 -2
  53. package/admin-dist/server/_ssr/{ContentEntryEditor-BLoEjT_m.mjs → ContentEntryEditor-weiXSBdZ.mjs} +35 -51
  54. package/admin-dist/server/_ssr/{TaxonomyFilter-XAtaJC2z.mjs → TaxonomyFilter-BPQ57Mwk.mjs} +7 -7
  55. package/admin-dist/server/_ssr/{_contentTypeId-Csl4822C.mjs → _contentTypeId-DyyauLOs.mjs} +24 -23
  56. package/admin-dist/server/_ssr/{_entryId-D8alLFBx.mjs → _entryId-9Cafwxmw.mjs} +22 -21
  57. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-Dk-FIYPN.mjs +4 -0
  58. package/admin-dist/server/_ssr/{command-C0Di14--.mjs → command-CEf8YBxY.mjs} +1 -1
  59. package/admin-dist/server/_ssr/{content-CT-FPsmV.mjs → content-ZFWVzO25.mjs} +20 -19
  60. package/admin-dist/server/_ssr/{content-types-C8cBFdzE.mjs → content-types-D25lUE-j.mjs} +18 -17
  61. package/admin-dist/server/_ssr/{index-BJtcrEc-.mjs → index-BlSIlH4Z.mjs} +10 -9
  62. package/admin-dist/server/_ssr/index.mjs +2 -2
  63. package/admin-dist/server/_ssr/{label-qn2Afwl4.mjs → label-PblVvdRv.mjs} +1 -1
  64. package/admin-dist/server/_ssr/{media-qv5IAsMZ.mjs → media-CD2_NUMw.mjs} +683 -314
  65. package/admin-dist/server/_ssr/{new._contentTypeId-DdGyrhqs.mjs → new._contentTypeId-dmZy6PBX.mjs} +20 -19
  66. package/admin-dist/server/_ssr/{router-nSVkxb6Y.mjs → router-x6Ab8T4s.mjs} +109 -43
  67. package/admin-dist/server/_ssr/{scroll-area-BCinP455.mjs → scroll-area-BH_1K-WT.mjs} +1 -1
  68. package/admin-dist/server/_ssr/{select-BKQlQScw.mjs → select-CrfEkFJw.mjs} +2 -2
  69. package/admin-dist/server/_ssr/{settings-BCr2KQlk.mjs → settings-DVdsoWoh.mjs} +158 -105
  70. package/admin-dist/server/_ssr/{switch-BaOi42fE.mjs → switch-DX_X8vZl.mjs} +1 -1
  71. package/admin-dist/server/_ssr/{tabs-DYXEi9kq.mjs → tabs-4FWM0sn8.mjs} +3 -3
  72. package/admin-dist/server/_ssr/{tanstack-adapter-Bsz8kha-.mjs → tanstack-adapter-D3ZcKtbY.mjs} +1 -1
  73. package/admin-dist/server/_ssr/{taxonomies-CueMHTbE.mjs → taxonomies-BHFfO9Yr.mjs} +21 -20
  74. package/admin-dist/server/_ssr/{textarea-CI0Jqx2x.mjs → textarea-CZVaroMc.mjs} +1 -1
  75. package/admin-dist/server/_ssr/{trash-DE6W8GoX.mjs → trash-9tUB2KwI.mjs} +14 -13
  76. package/admin-dist/server/_ssr/{useBreadcrumbLabel-B5Yi72lM.mjs → useBreadcrumbLabel-DVme3DSb.mjs} +1 -1
  77. package/admin-dist/server/_ssr/{usePermissions-C3nZ-Izm.mjs → usePermissions-zAQj-ruE.mjs} +1 -1
  78. package/admin-dist/server/index.mjs +188 -188
  79. package/dist/cli/commands/init.d.ts +12 -2
  80. package/dist/cli/commands/init.d.ts.map +1 -1
  81. package/dist/cli/commands/init.js +136 -138
  82. package/dist/cli/commands/init.js.map +1 -1
  83. package/dist/cli/index.js +2 -1
  84. package/dist/cli/index.js.map +1 -1
  85. package/dist/cli/templates/admin.d.ts +10 -0
  86. package/dist/cli/templates/admin.d.ts.map +1 -0
  87. package/dist/cli/templates/admin.js +212 -0
  88. package/dist/cli/templates/admin.js.map +1 -0
  89. package/dist/cli/templates/cmsClient.d.ts +7 -0
  90. package/dist/cli/templates/cmsClient.d.ts.map +1 -0
  91. package/dist/cli/templates/cmsClient.js +36 -0
  92. package/dist/cli/templates/cmsClient.js.map +1 -0
  93. package/dist/cli/templates/cmsConfig.d.ts +7 -0
  94. package/dist/cli/templates/cmsConfig.d.ts.map +1 -0
  95. package/dist/cli/templates/cmsConfig.js +86 -0
  96. package/dist/cli/templates/cmsConfig.js.map +1 -0
  97. package/dist/cli/templates/index.d.ts +10 -0
  98. package/dist/cli/templates/index.d.ts.map +1 -0
  99. package/dist/cli/templates/index.js +10 -0
  100. package/dist/cli/templates/index.js.map +1 -0
  101. package/dist/cli/templates/schemas/blog.d.ts +8 -0
  102. package/dist/cli/templates/schemas/blog.d.ts.map +1 -0
  103. package/dist/cli/templates/schemas/blog.js +103 -0
  104. package/dist/cli/templates/schemas/blog.js.map +1 -0
  105. package/dist/cli/templates/schemas/docs.d.ts +8 -0
  106. package/dist/cli/templates/schemas/docs.d.ts.map +1 -0
  107. package/dist/cli/templates/schemas/docs.js +110 -0
  108. package/dist/cli/templates/schemas/docs.js.map +1 -0
  109. package/dist/cli/templates/schemas/index.d.ts +11 -0
  110. package/dist/cli/templates/schemas/index.d.ts.map +1 -0
  111. package/dist/cli/templates/schemas/index.js +13 -0
  112. package/dist/cli/templates/schemas/index.js.map +1 -0
  113. package/dist/cli/templates/schemas/landing.d.ts +8 -0
  114. package/dist/cli/templates/schemas/landing.d.ts.map +1 -0
  115. package/dist/cli/templates/schemas/landing.js +135 -0
  116. package/dist/cli/templates/schemas/landing.js.map +1 -0
  117. package/dist/cli/utils/fileUtils.d.ts +21 -0
  118. package/dist/cli/utils/fileUtils.d.ts.map +1 -0
  119. package/dist/cli/utils/fileUtils.js +95 -0
  120. package/dist/cli/utils/fileUtils.js.map +1 -0
  121. package/dist/cli/utils/prompts.d.ts +25 -0
  122. package/dist/cli/utils/prompts.d.ts.map +1 -0
  123. package/dist/cli/utils/prompts.js +87 -0
  124. package/dist/cli/utils/prompts.js.map +1 -0
  125. package/dist/client/agentTools.d.ts +1 -1427
  126. package/dist/client/agentTools.d.ts.map +1 -1
  127. package/dist/component/contentTypeMutations.d.ts +1 -1
  128. package/dist/test.d.ts +5 -0
  129. package/dist/test.d.ts.map +1 -1
  130. package/dist/test.js +0 -1
  131. package/dist/test.js.map +1 -1
  132. package/package.json +28 -28
  133. package/admin/README.md +0 -99
  134. package/admin-dist/public/assets/ContentEntryEditor-BU220CCy.js +0 -4
  135. package/admin-dist/public/assets/_contentTypeId-DK8cskRt.js +0 -1
  136. package/admin-dist/public/assets/_entryId-CuVMExbb.js +0 -1
  137. package/admin-dist/public/assets/content-QBUxdxbS.js +0 -1
  138. package/admin-dist/public/assets/globals-B7Wsfh_v.css +0 -1
  139. package/admin-dist/public/assets/main-CjQ2VI9L.js +0 -97
  140. package/admin-dist/public/assets/media-Dc5PWt2Q.js +0 -1
  141. package/admin-dist/public/assets/new._contentTypeId-C_I4YxIa.js +0 -1
  142. package/admin-dist/public/assets/settings-t2PbCZh4.js +0 -1
  143. package/admin-dist/public/assets/tabs-q4EbZk7c.js +0 -1
  144. package/admin-dist/public/assets/taxonomies-kyk5P4ZW.js +0 -1
  145. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-BffZedId.mjs +0 -4
@@ -1,18 +1,19 @@
1
- import { r as reactExports, j as jsxRuntimeExports } from "../_chunks/_libs/react.mjs";
2
- import { d as useNavigate } from "../_chunks/_libs/@tanstack/react-router.mjs";
3
- import { u as useSettingsConfig, a as api, c as cn, D as DropdownMenu, d as DropdownMenuTrigger, e as DropdownMenuContent, f as DropdownMenuItem, g as DropdownMenuSeparator, B as Button } from "./router-nSVkxb6Y.mjs";
4
- import { T as Tabs, a as TabsList, b as TabsTrigger, U as UploadDropzone } from "./tabs-DYXEi9kq.mjs";
5
- import { C as CmsPageHeader } from "./CmsPageHeader-DHRrdOZa.mjs";
6
- import { C as CmsToolbar } from "./CmsToolbar-zTE45z2q.mjs";
7
- import { I as Input, a as Checkbox, C as CmsEmptyState, D as Dialog, d as DialogContent, e as DialogHeader, f as DialogTitle, g as DialogFooter, b as CmsConfirmDialog, c as CmsDialog } from "./CmsEmptyState-fbnGt3LD.mjs";
8
- import { B as Badge, C as CmsButton } from "./CmsButton-DOiTVKQq.mjs";
9
- import { T as TaxonomyFilter } from "./TaxonomyFilter-XAtaJC2z.mjs";
10
- import { L as Label } from "./label-qn2Afwl4.mjs";
11
- import { S as Select, a as SelectTrigger, b as SelectValue, c as SelectContent, d as SelectItem } from "./select-BKQlQScw.mjs";
1
+ import { j as jsxRuntimeExports, r as reactExports } from "../_chunks/_libs/react.mjs";
2
+ import { h as useSettingsConfig, a as api, c as cn, D as DropdownMenu, d as DropdownMenuTrigger, e as DropdownMenuContent, f as DropdownMenuItem, g as DropdownMenuSeparator, B as Button } from "./router-x6Ab8T4s.mjs";
3
+ import { B as Badge, C as CmsButton } from "./CmsButton-DbzfJru_.mjs";
4
+ import { T as Tabs, a as TabsList, b as TabsTrigger, U as UploadDropzone } from "./tabs-4FWM0sn8.mjs";
5
+ import { C as CmsPageHeader } from "./CmsPageHeader-ClNPU7Up.mjs";
6
+ import { C as CmsToolbar } from "./CmsToolbar-BKv1nL6u.mjs";
7
+ import { I as Input, a as Checkbox, C as CmsEmptyState, D as Dialog, d as DialogContent, e as DialogHeader, f as DialogTitle, g as DialogFooter, b as CmsConfirmDialog, c as CmsDialog } from "./CmsEmptyState-CuvcXr3Z.mjs";
8
+ import { T as TaxonomyFilter } from "./TaxonomyFilter-BPQ57Mwk.mjs";
9
+ import { L as Label } from "./label-PblVvdRv.mjs";
10
+ import { S as Select, a as SelectTrigger, b as SelectValue, c as SelectContent, d as SelectItem } from "./select-CrfEkFJw.mjs";
12
11
  import { a as VisuallyHidden } from "../_chunks/_libs/@radix-ui/react-visually-hidden.mjs";
13
- import { T as Textarea } from "./textarea-CI0Jqx2x.mjs";
12
+ import { T as Textarea } from "./textarea-CZVaroMc.mjs";
13
+ import { u as useTanStackNavigation } from "./tanstack-adapter-D3ZcKtbY.mjs";
14
14
  import { u as useQuery, d as useMutation } from "../_libs/convex.mjs";
15
- import { I as Image, w as Trash2, H as House, a1 as ChevronLeft, a2 as FolderPlus, a3 as Upload, N as Search, X, o as Folder, R as RotateCcw, a4 as Ellipsis, W as Pencil, a5 as FolderInput, a6 as EllipsisVertical, h as Eye, a7 as Download, a8 as Link2, a9 as File, J as FileText, aa as Music, ab as Video, ac as Copy, f as ChevronRight, V as Tag, L as LoaderCircle, Q as Plus } from "../_libs/lucide-react.mjs";
15
+ import { I as Image, w as Trash2, H as House, a2 as ChevronLeft, a3 as FolderPlus, a4 as Upload, N as Search, X, o as Folder, R as RotateCcw, a5 as Ellipsis, W as Pencil, a6 as FolderInput, a7 as EllipsisVertical, h as Eye, a8 as Download, a9 as Link2, aa as File, J as FileText, ab as Music, ac as Video, ad as Copy, f as ChevronRight, V as Tag, L as LoaderCircle, Q as Plus } from "../_libs/lucide-react.mjs";
16
+ import "../_chunks/_libs/@tanstack/react-router.mjs";
16
17
  import "../_libs/tiny-warning.mjs";
17
18
  import "../_chunks/_libs/@tanstack/router-core.mjs";
18
19
  import "../_libs/cookie-es.mjs";
@@ -33,14 +34,17 @@ import "../_chunks/_libs/@tanstack/react-store.mjs";
33
34
  import "../_libs/use-sync-external-store.mjs";
34
35
  import "../_libs/clsx.mjs";
35
36
  import "../_libs/tailwind-merge.mjs";
36
- import "../_chunks/_libs/@radix-ui/react-slot.mjs";
37
- import "../_chunks/_libs/@radix-ui/react-compose-refs.mjs";
38
- import "../_chunks/_libs/@radix-ui/react-dropdown-menu.mjs";
37
+ import "../_chunks/_libs/@radix-ui/react-collapsible.mjs";
39
38
  import "../_chunks/_libs/@radix-ui/primitive.mjs";
40
39
  import "../_chunks/_libs/@radix-ui/react-context.mjs";
41
40
  import "../_chunks/_libs/@radix-ui/react-use-controllable-state.mjs";
42
41
  import "../_chunks/_libs/@radix-ui/react-use-layout-effect.mjs";
42
+ import "../_chunks/_libs/@radix-ui/react-compose-refs.mjs";
43
43
  import "../_chunks/_libs/@radix-ui/react-primitive.mjs";
44
+ import "../_chunks/_libs/@radix-ui/react-slot.mjs";
45
+ import "../_chunks/_libs/@radix-ui/react-presence.mjs";
46
+ import "../_chunks/_libs/@radix-ui/react-id.mjs";
47
+ import "../_chunks/_libs/@radix-ui/react-dropdown-menu.mjs";
44
48
  import "../_chunks/_libs/@radix-ui/react-menu.mjs";
45
49
  import "../_chunks/_libs/@radix-ui/react-collection.mjs";
46
50
  import "../_chunks/_libs/@radix-ui/react-direction.mjs";
@@ -57,9 +61,7 @@ import "../_chunks/_libs/@floating-ui/utils.mjs";
57
61
  import "../_chunks/_libs/@radix-ui/react-arrow.mjs";
58
62
  import "../_chunks/_libs/@radix-ui/react-use-size.mjs";
59
63
  import "../_chunks/_libs/@radix-ui/react-portal.mjs";
60
- import "../_chunks/_libs/@radix-ui/react-presence.mjs";
61
64
  import "../_chunks/_libs/@radix-ui/react-roving-focus.mjs";
62
- import "../_chunks/_libs/@radix-ui/react-id.mjs";
63
65
  import "../_libs/aria-hidden.mjs";
64
66
  import "../_libs/react-remove-scroll.mjs";
65
67
  import "../_libs/tslib.mjs";
@@ -85,7 +87,7 @@ import "../_chunks/_libs/@radix-ui/react-tabs.mjs";
85
87
  import "../_chunks/_libs/@radix-ui/react-dialog.mjs";
86
88
  import "../_chunks/_libs/@radix-ui/react-checkbox.mjs";
87
89
  import "../_chunks/_libs/@radix-ui/react-use-previous.mjs";
88
- import "./command-C0Di14--.mjs";
90
+ import "./command-CEf8YBxY.mjs";
89
91
  import "../_libs/cmdk.mjs";
90
92
  import "../_chunks/_libs/@radix-ui/react-label.mjs";
91
93
  import "../_chunks/_libs/@radix-ui/react-select.mjs";
@@ -397,20 +399,20 @@ function MediaTaxonomyPicker({
397
399
  const inputRef = reactExports.useRef(null);
398
400
  const suggestionsRef = reactExports.useRef(null);
399
401
  const containerRef = reactExports.useRef(null);
400
- const currentTerms = useQuery(api.taxonomies.getTermsByMedia, {
402
+ const currentTerms = useQuery(api.admin.getTermsByMedia, {
401
403
  mediaId,
402
404
  taxonomyId
403
405
  });
404
406
  const selectedTermIds = currentTerms?.map((t) => t._id) ?? [];
405
- const suggestionsResult = useQuery(api.taxonomies.suggestTerms, {
407
+ const suggestionsResult = useQuery(api.admin.suggestTerms, {
406
408
  taxonomyId,
407
409
  query: inputValue,
408
410
  limit: 10,
409
411
  excludeIds: selectedTermIds
410
412
  });
411
413
  const suggestions = suggestionsResult ?? [];
412
- const setMediaTermsMutation = useMutation(api.taxonomies.setMediaTerms);
413
- const createTermMutation = useMutation(api.taxonomies.createTermAndAddToMedia);
414
+ const setMediaTermsMutation = useMutation(api.admin.setMediaTerms);
415
+ const createTermMutation = useMutation(api.admin.createTermAndAddToMedia);
414
416
  reactExports.useEffect(() => {
415
417
  function handleClickOutside(event) {
416
418
  if (containerRef.current && !containerRef.current.contains(event.target)) {
@@ -661,8 +663,8 @@ function MediaAssetEditDialog({
661
663
  const [tagsInput, setTagsInput] = reactExports.useState("");
662
664
  const [isSaving, setIsSaving] = reactExports.useState(false);
663
665
  const [error, setError] = reactExports.useState("");
664
- const updateAsset = useMutation(api.media.updateAsset);
665
- const taxonomiesResult = useQuery(api.taxonomies.list, {
666
+ const updateAsset = useMutation(api.admin.updateMediaAsset);
667
+ const taxonomiesResult = useQuery(api.admin.listTaxonomies, {
666
668
  isActive: true,
667
669
  paginationOpts: { numItems: 50, cursor: null }
668
670
  });
@@ -841,7 +843,7 @@ function MediaFolderEditDialog({
841
843
  const [description, setDescription] = reactExports.useState("");
842
844
  const [isSaving, setIsSaving] = reactExports.useState(false);
843
845
  const [error, setError] = reactExports.useState("");
844
- const updateFolder = useMutation(api.media.updateFolder);
846
+ const updateFolder = useMutation(api.admin.updateMediaFolder);
845
847
  reactExports.useEffect(() => {
846
848
  if (folder) {
847
849
  setName(folder.name);
@@ -1150,8 +1152,8 @@ function MediaMoveModal({
1150
1152
  );
1151
1153
  const [isMoving, setIsMoving] = reactExports.useState(false);
1152
1154
  const [error, setError] = reactExports.useState("");
1153
- const folderTree = useQuery(api.media.getFolderTree, {});
1154
- const moveAssets = useMutation(api.media.moveAssets);
1155
+ const folderTree = useQuery(api.admin.getMediaFolderTree, {});
1156
+ const moveAssets = useMutation(api.admin.moveMediaAssets);
1155
1157
  const sortedFolders = reactExports.useMemo(() => {
1156
1158
  if (!folderTree) return [];
1157
1159
  const buildTree = (parentId, depth) => {
@@ -1276,9 +1278,7 @@ function formatDate(timestamp) {
1276
1278
  });
1277
1279
  }
1278
1280
  function getMediaTypeIcon(type, className = "size-6") {
1279
- const iconProps = {
1280
- className
1281
- };
1281
+ const iconProps = { className };
1282
1282
  switch (type) {
1283
1283
  case "image":
1284
1284
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { ...iconProps });
@@ -1302,19 +1302,15 @@ function getMediaTypeFromMimeType(mimeType) {
1302
1302
  }
1303
1303
  return "other";
1304
1304
  }
1305
- function MediaPage() {
1306
- const {
1307
- settings
1308
- } = useSettingsConfig();
1309
- const navigate = useNavigate();
1305
+ function MediaPage({ api: api2, navigation, settings }) {
1310
1306
  reactExports.useEffect(() => {
1311
1307
  if (settings && !settings.features.mediaManagement) {
1312
- navigate({
1313
- to: "/"
1314
- });
1308
+ navigation.navigate("/");
1315
1309
  }
1316
- }, [settings, navigate]);
1317
- const [currentFolderId, setCurrentFolderId] = reactExports.useState(void 0);
1310
+ }, [settings, navigation]);
1311
+ const [currentFolderId, setCurrentFolderId] = reactExports.useState(
1312
+ void 0
1313
+ );
1318
1314
  const [searchQuery, setSearchQuery] = reactExports.useState("");
1319
1315
  const [typeFilter, setTypeFilter] = reactExports.useState("");
1320
1316
  const [selectedTermIds, setSelectedTermIds] = reactExports.useState([]);
@@ -1326,8 +1322,12 @@ function MediaPage() {
1326
1322
  const [isCreatingFolder, setIsCreatingFolder] = reactExports.useState(false);
1327
1323
  const [folderError, setFolderError] = reactExports.useState("");
1328
1324
  const [previewIndex, setPreviewIndex] = reactExports.useState(null);
1329
- const [editingAsset, setEditingAsset] = reactExports.useState(null);
1330
- const [editingFolder, setEditingFolder] = reactExports.useState(null);
1325
+ const [editingAsset, setEditingAsset] = reactExports.useState(
1326
+ null
1327
+ );
1328
+ const [editingFolder, setEditingFolder] = reactExports.useState(
1329
+ null
1330
+ );
1331
1331
  const [deleteTarget, setDeleteTarget] = reactExports.useState(null);
1332
1332
  const [isDeleting, setIsDeleting] = reactExports.useState(false);
1333
1333
  const [showMoveModal, setShowMoveModal] = reactExports.useState(false);
@@ -1339,30 +1339,34 @@ function MediaPage() {
1339
1339
  const [showPermanentDeleteConfirm, setShowPermanentDeleteConfirm] = reactExports.useState(false);
1340
1340
  const [permanentDeleteTarget, setPermanentDeleteTarget] = reactExports.useState(null);
1341
1341
  const isTrashView = activeView === "trash";
1342
- const assetsResult = useQuery(api.media.listAssets, {
1342
+ const assetsResult = useQuery(api2.listMediaAssets, {
1343
1343
  folderId: isTrashView ? void 0 : currentFolderId,
1344
1344
  type: typeFilter || void 0,
1345
1345
  search: searchQuery || void 0,
1346
1346
  deletedOnly: isTrashView ? true : void 0,
1347
- paginationOpts: {
1348
- numItems: 100,
1349
- cursor: null
1350
- }
1347
+ paginationOpts: { numItems: 100, cursor: null }
1351
1348
  });
1352
- const trashCount = useQuery(api.media.getTrashCount, {});
1353
- const mediaByTermResult0 = useQuery(api.taxonomies.getMediaByTerm, selectedTermIds[0] ? {
1354
- termId: selectedTermIds[0]
1355
- } : "skip");
1356
- const mediaByTermResult1 = useQuery(api.taxonomies.getMediaByTerm, selectedTermIds[1] ? {
1357
- termId: selectedTermIds[1]
1358
- } : "skip");
1359
- const mediaByTermResult2 = useQuery(api.taxonomies.getMediaByTerm, selectedTermIds[2] ? {
1360
- termId: selectedTermIds[2]
1361
- } : "skip");
1349
+ const trashCount = useQuery(api2.getMediaTrashCount, {});
1350
+ const mediaByTermResult0 = useQuery(
1351
+ api2.getMediaByTerm,
1352
+ selectedTermIds[0] ? { termId: selectedTermIds[0] } : "skip"
1353
+ );
1354
+ const mediaByTermResult1 = useQuery(
1355
+ api2.getMediaByTerm,
1356
+ selectedTermIds[1] ? { termId: selectedTermIds[1] } : "skip"
1357
+ );
1358
+ const mediaByTermResult2 = useQuery(
1359
+ api2.getMediaByTerm,
1360
+ selectedTermIds[2] ? { termId: selectedTermIds[2] } : "skip"
1361
+ );
1362
1362
  const termFilteredMediaIds = reactExports.useMemo(() => {
1363
1363
  if (selectedTermIds.length === 0) return null;
1364
1364
  const ids = /* @__PURE__ */ new Set();
1365
- const results = [mediaByTermResult0, mediaByTermResult1, mediaByTermResult2];
1365
+ const results = [
1366
+ mediaByTermResult0,
1367
+ mediaByTermResult1,
1368
+ mediaByTermResult2
1369
+ ];
1366
1370
  for (let i = 0; i < selectedTermIds.length && i < 3; i++) {
1367
1371
  const result = results[i];
1368
1372
  if (result?.page) {
@@ -1372,26 +1376,36 @@ function MediaPage() {
1372
1376
  }
1373
1377
  }
1374
1378
  return ids;
1375
- }, [selectedTermIds, mediaByTermResult0, mediaByTermResult1, mediaByTermResult2]);
1376
- const folders = useQuery(api.media.listFolders, {
1379
+ }, [
1380
+ selectedTermIds,
1381
+ mediaByTermResult0,
1382
+ mediaByTermResult1,
1383
+ mediaByTermResult2
1384
+ ]);
1385
+ const folders = useQuery(api2.listMediaFolders, {
1377
1386
  parentId: isTrashView ? void 0 : currentFolderId,
1378
1387
  deletedOnly: isTrashView || void 0
1379
1388
  });
1380
- const currentFolder = useQuery(api.media.getFolder, currentFolderId ? {
1381
- id: currentFolderId
1382
- } : "skip");
1383
- const folderTree = useQuery(api.media.getFolderTree, {});
1384
- const createFolder = useMutation(api.media.createFolder);
1385
- const deleteAsset = useMutation(api.media.deleteAsset);
1386
- const deleteFolder = useMutation(api.media.deleteFolder);
1387
- const restoreAsset = useMutation(api.media.restoreAsset);
1388
- const restoreFolder = useMutation(api.media.restoreFolder);
1389
- const permanentDeleteAsset = useMutation(api.media.permanentDeleteAsset);
1390
- const bulkPermanentDeleteAssets = useMutation(api.media.bulkPermanentDeleteAssets);
1389
+ const currentFolder = useQuery(
1390
+ api2.getMediaFolder,
1391
+ currentFolderId ? { id: currentFolderId } : "skip"
1392
+ );
1393
+ const folderTree = useQuery(api2.getMediaFolderTree, {});
1394
+ const createFolder = useMutation(api2.createMediaFolder);
1395
+ const deleteAsset = useMutation(api2.deleteMediaAsset);
1396
+ const deleteFolder = useMutation(api2.deleteMediaFolder);
1397
+ const restoreAsset = useMutation(api2.restoreMediaAsset);
1398
+ const restoreFolder = useMutation(api2.restoreMediaFolder);
1399
+ const permanentDeleteAsset = useMutation(api2.permanentDeleteMediaAsset);
1400
+ const bulkPermanentDeleteAssets = useMutation(
1401
+ api2.bulkPermanentDeleteMediaAssets
1402
+ );
1391
1403
  const breadcrumbPath = reactExports.useMemo(() => {
1392
1404
  if (!currentFolderId || !folderTree) return [];
1393
1405
  const path = [];
1394
- let folder = folderTree.find((f) => f._id === currentFolderId);
1406
+ let folder = folderTree.find(
1407
+ (f) => f._id === currentFolderId
1408
+ );
1395
1409
  while (folder) {
1396
1410
  path.unshift(folder);
1397
1411
  const parentId = folder.parentId;
@@ -1437,16 +1451,19 @@ function MediaPage() {
1437
1451
  setSelectedAssets(/* @__PURE__ */ new Set());
1438
1452
  setIsSelectionMode(false);
1439
1453
  }, []);
1440
- const handleAssetClick = reactExports.useCallback((assetId) => {
1441
- if (isSelectionMode) {
1442
- handleAssetSelect(assetId);
1443
- } else {
1444
- const index = assetsResult?.page?.findIndex((a) => a._id === assetId) ?? -1;
1445
- if (index !== -1) {
1446
- setPreviewIndex(index);
1454
+ const handleAssetClick = reactExports.useCallback(
1455
+ (assetId) => {
1456
+ if (isSelectionMode) {
1457
+ handleAssetSelect(assetId);
1458
+ } else {
1459
+ const index = assetsResult?.page?.findIndex((a) => a._id === assetId) ?? -1;
1460
+ if (index !== -1) {
1461
+ setPreviewIndex(index);
1462
+ }
1447
1463
  }
1448
- }
1449
- }, [isSelectionMode, handleAssetSelect, assetsResult?.page]);
1464
+ },
1465
+ [isSelectionMode, handleAssetSelect, assetsResult?.page]
1466
+ );
1450
1467
  const handlePreviewNavigate = reactExports.useCallback((index) => {
1451
1468
  setPreviewIndex(index);
1452
1469
  }, []);
@@ -1455,13 +1472,9 @@ function MediaPage() {
1455
1472
  setIsDeleting(true);
1456
1473
  try {
1457
1474
  if (deleteTarget.type === "asset") {
1458
- await deleteAsset({
1459
- id: deleteTarget.id
1460
- });
1475
+ await deleteAsset({ id: deleteTarget.id });
1461
1476
  } else {
1462
- await deleteFolder({
1463
- id: deleteTarget.id
1464
- });
1477
+ await deleteFolder({ id: deleteTarget.id });
1465
1478
  }
1466
1479
  setDeleteTarget(null);
1467
1480
  } catch (err) {
@@ -1474,9 +1487,9 @@ function MediaPage() {
1474
1487
  if (selectedAssets.size === 0) return;
1475
1488
  setIsBulkDeleting(true);
1476
1489
  try {
1477
- const deletePromises = Array.from(selectedAssets).map((id) => deleteAsset({
1478
- id
1479
- }));
1490
+ const deletePromises = Array.from(selectedAssets).map(
1491
+ (id) => deleteAsset({ id })
1492
+ );
1480
1493
  await Promise.all(deletePromises);
1481
1494
  setSelectedAssets(/* @__PURE__ */ new Set());
1482
1495
  setIsSelectionMode(false);
@@ -1491,25 +1504,26 @@ function MediaPage() {
1491
1504
  setSelectedAssets(/* @__PURE__ */ new Set());
1492
1505
  setIsSelectionMode(false);
1493
1506
  }, []);
1494
- const handleRestore = reactExports.useCallback(async (assetId) => {
1495
- setIsRestoring(true);
1496
- try {
1497
- await restoreAsset({
1498
- id: assetId
1499
- });
1500
- } catch (err) {
1501
- console.error("Restore failed:", err);
1502
- } finally {
1503
- setIsRestoring(false);
1504
- }
1505
- }, [restoreAsset]);
1507
+ const handleRestore = reactExports.useCallback(
1508
+ async (assetId) => {
1509
+ setIsRestoring(true);
1510
+ try {
1511
+ await restoreAsset({ id: assetId });
1512
+ } catch (err) {
1513
+ console.error("Restore failed:", err);
1514
+ } finally {
1515
+ setIsRestoring(false);
1516
+ }
1517
+ },
1518
+ [restoreAsset]
1519
+ );
1506
1520
  const handleBulkRestore = reactExports.useCallback(async () => {
1507
1521
  if (selectedAssets.size === 0) return;
1508
1522
  setIsRestoring(true);
1509
1523
  try {
1510
- const restorePromises = Array.from(selectedAssets).map((id) => restoreAsset({
1511
- id
1512
- }));
1524
+ const restorePromises = Array.from(selectedAssets).map(
1525
+ (id) => restoreAsset({ id })
1526
+ );
1513
1527
  await Promise.all(restorePromises);
1514
1528
  setSelectedAssets(/* @__PURE__ */ new Set());
1515
1529
  setIsSelectionMode(false);
@@ -1519,32 +1533,29 @@ function MediaPage() {
1519
1533
  setIsRestoring(false);
1520
1534
  }
1521
1535
  }, [selectedAssets, restoreAsset]);
1522
- const handleRestoreFolder = reactExports.useCallback(async (folderId) => {
1523
- setIsRestoring(true);
1524
- try {
1525
- await restoreFolder({
1526
- id: folderId
1527
- });
1528
- } catch (err) {
1529
- console.error("Restore folder failed:", err);
1530
- } finally {
1531
- setIsRestoring(false);
1532
- }
1533
- }, [restoreFolder]);
1536
+ const handleRestoreFolder = reactExports.useCallback(
1537
+ async (folderId) => {
1538
+ setIsRestoring(true);
1539
+ try {
1540
+ await restoreFolder({ id: folderId });
1541
+ } catch (err) {
1542
+ console.error("Restore folder failed:", err);
1543
+ } finally {
1544
+ setIsRestoring(false);
1545
+ }
1546
+ },
1547
+ [restoreFolder]
1548
+ );
1534
1549
  const handlePermanentDelete = reactExports.useCallback(async () => {
1535
1550
  if (!permanentDeleteTarget) return;
1536
1551
  setIsPermanentlyDeleting(true);
1537
1552
  try {
1538
1553
  if (permanentDeleteTarget === "bulk") {
1539
- await bulkPermanentDeleteAssets({
1540
- ids: Array.from(selectedAssets)
1541
- });
1554
+ await bulkPermanentDeleteAssets({ ids: Array.from(selectedAssets) });
1542
1555
  setSelectedAssets(/* @__PURE__ */ new Set());
1543
1556
  setIsSelectionMode(false);
1544
1557
  } else {
1545
- await permanentDeleteAsset({
1546
- id: permanentDeleteTarget
1547
- });
1558
+ await permanentDeleteAsset({ id: permanentDeleteTarget });
1548
1559
  }
1549
1560
  setShowPermanentDeleteConfirm(false);
1550
1561
  setPermanentDeleteTarget(null);
@@ -1553,7 +1564,12 @@ function MediaPage() {
1553
1564
  } finally {
1554
1565
  setIsPermanentlyDeleting(false);
1555
1566
  }
1556
- }, [permanentDeleteTarget, permanentDeleteAsset, bulkPermanentDeleteAssets, selectedAssets]);
1567
+ }, [
1568
+ permanentDeleteTarget,
1569
+ permanentDeleteAsset,
1570
+ bulkPermanentDeleteAssets,
1571
+ selectedAssets
1572
+ ]);
1557
1573
  const handleCreateFolder = reactExports.useCallback(async () => {
1558
1574
  if (!newFolderName.trim()) {
1559
1575
  setFolderError("Folder name is required");
@@ -1569,7 +1585,9 @@ function MediaPage() {
1569
1585
  setShowNewFolderModal(false);
1570
1586
  setNewFolderName("");
1571
1587
  } catch (error) {
1572
- setFolderError(error instanceof Error ? error.message : "Failed to create folder");
1588
+ setFolderError(
1589
+ error instanceof Error ? error.message : "Failed to create folder"
1590
+ );
1573
1591
  } finally {
1574
1592
  setIsCreatingFolder(false);
1575
1593
  }
@@ -1586,101 +1604,212 @@ function MediaPage() {
1586
1604
  return assets.filter((asset) => termFilteredMediaIds.has(asset._id));
1587
1605
  }, [assetsResult?.page, termFilteredMediaIds]);
1588
1606
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6 p-6", children: [
1589
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsPageHeader, { title: "Media Library", description: "Upload, organize, and manage media assets for your content." }),
1590
- /* @__PURE__ */ jsxRuntimeExports.jsx(Tabs, { value: activeView, onValueChange: (v) => handleViewChange(v), children: /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsList, { children: [
1591
- /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsTrigger, { value: "library", children: [
1592
- /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { className: "mr-1.5 size-4" }),
1593
- "Library"
1594
- ] }),
1595
- /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsTrigger, { value: "trash", children: [
1596
- /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "mr-1.5 size-4" }),
1597
- "Trash",
1598
- trashCount && trashCount.total > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "secondary", className: "ml-1.5", children: trashCount.total })
1599
- ] })
1600
- ] }) }),
1607
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1608
+ CmsPageHeader,
1609
+ {
1610
+ title: "Media Library",
1611
+ description: "Upload, organize, and manage media assets for your content."
1612
+ }
1613
+ ),
1614
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1615
+ Tabs,
1616
+ {
1617
+ value: activeView,
1618
+ onValueChange: (v) => handleViewChange(v),
1619
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsList, { children: [
1620
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsTrigger, { value: "library", children: [
1621
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { className: "mr-1.5 size-4" }),
1622
+ "Library"
1623
+ ] }),
1624
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsTrigger, { value: "trash", children: [
1625
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "mr-1.5 size-4" }),
1626
+ "Trash",
1627
+ trashCount && trashCount.total > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "secondary", className: "ml-1.5", children: trashCount.total })
1628
+ ] })
1629
+ ] })
1630
+ }
1631
+ ),
1601
1632
  !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsxs("nav", { className: "flex items-center gap-1", "aria-label": "Folder navigation", children: [
1602
- /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: cn("flex items-center gap-1.5 rounded-md px-2 py-1 text-sm transition-colors", !currentFolderId ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-muted hover:text-foreground"), onClick: handleNavigateToRoot, children: [
1603
- /* @__PURE__ */ jsxRuntimeExports.jsx(House, { className: "size-4" }),
1604
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "All Files" })
1605
- ] }),
1633
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1634
+ "button",
1635
+ {
1636
+ className: cn(
1637
+ "flex items-center gap-1.5 rounded-md px-2 py-1 text-sm transition-colors",
1638
+ !currentFolderId ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-muted hover:text-foreground"
1639
+ ),
1640
+ onClick: handleNavigateToRoot,
1641
+ children: [
1642
+ /* @__PURE__ */ jsxRuntimeExports.jsx(House, { className: "size-4" }),
1643
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "All Files" })
1644
+ ]
1645
+ }
1646
+ ),
1606
1647
  breadcrumbPath.map((folder, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center", children: [
1607
1648
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mx-1 text-muted-foreground", children: "/" }),
1608
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: cn("rounded-md px-2 py-1 text-sm transition-colors", index === breadcrumbPath.length - 1 ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-muted hover:text-foreground"), onClick: () => handleFolderClick(folder._id), children: folder.name })
1649
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1650
+ "button",
1651
+ {
1652
+ className: cn(
1653
+ "rounded-md px-2 py-1 text-sm transition-colors",
1654
+ index === breadcrumbPath.length - 1 ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-muted hover:text-foreground"
1655
+ ),
1656
+ onClick: () => handleFolderClick(folder._id),
1657
+ children: folder.name
1658
+ }
1659
+ )
1609
1660
  ] }, folder._id))
1610
1661
  ] }),
1611
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsToolbar, { left: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
1612
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
1613
- /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
1614
- /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "search", placeholder: "Search files...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "w-64 pl-9" }),
1615
- searchQuery && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 hover:bg-muted", onClick: () => setSearchQuery(""), "aria-label": "Clear search", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-4 text-muted-foreground" }) })
1616
- ] }),
1617
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: typeFilter || "all", onValueChange: (v) => setTypeFilter(v === "all" ? "" : v), children: [
1618
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-36", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All Types" }) }),
1619
- /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
1620
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "all", children: "All Types" }),
1621
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "image", children: "Images" }),
1622
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "video", children: "Videos" }),
1623
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "audio", children: "Audio" }),
1624
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "document", children: "Documents" }),
1625
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "other", children: "Other" })
1626
- ] })
1627
- ] }),
1628
- /* @__PURE__ */ jsxRuntimeExports.jsx(TaxonomyFilter, { selectedTermIds, onChange: setSelectedTermIds, placeholder: "Tags" }),
1629
- assetsResult?.page && assetsResult.page.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex cursor-pointer items-center gap-2 text-sm", children: [
1630
- /* @__PURE__ */ jsxRuntimeExports.jsx(Checkbox, { checked: isSelectionMode, onCheckedChange: (checked) => {
1631
- setIsSelectionMode(checked);
1632
- if (!checked) {
1633
- setSelectedAssets(/* @__PURE__ */ new Set());
1634
- }
1635
- } }),
1636
- "Selection Mode"
1637
- ] })
1638
- ] }), right: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1639
- isSelectionMode && selectedAssets.size > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-muted-foreground", children: [
1640
- selectedAssets.size,
1641
- " selected"
1642
- ] }),
1643
- isSelectionMode && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1644
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { variant: "secondary", size: "sm", onClick: handleSelectAll, children: "Select All" }),
1645
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { variant: "secondary", size: "sm", onClick: handleDeselectAll, children: "Clear" })
1646
- ] }),
1647
- currentFolderId && !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { variant: "secondary", onClick: handleNavigateUp, children: [
1648
- /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { className: "size-4" }),
1649
- "Up"
1650
- ] }),
1651
- !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1652
- /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { variant: "secondary", onClick: () => setShowNewFolderModal(true), children: [
1653
- /* @__PURE__ */ jsxRuntimeExports.jsx(FolderPlus, { className: "size-4" }),
1654
- "New Folder"
1662
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1663
+ CmsToolbar,
1664
+ {
1665
+ left: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
1666
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
1667
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
1668
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1669
+ Input,
1670
+ {
1671
+ type: "search",
1672
+ placeholder: "Search files...",
1673
+ value: searchQuery,
1674
+ onChange: (e) => setSearchQuery(e.target.value),
1675
+ className: "w-64 pl-9"
1676
+ }
1677
+ ),
1678
+ searchQuery && /* @__PURE__ */ jsxRuntimeExports.jsx(
1679
+ "button",
1680
+ {
1681
+ className: "absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 hover:bg-muted",
1682
+ onClick: () => setSearchQuery(""),
1683
+ "aria-label": "Clear search",
1684
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-4 text-muted-foreground" })
1685
+ }
1686
+ )
1687
+ ] }),
1688
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1689
+ Select,
1690
+ {
1691
+ value: typeFilter || "all",
1692
+ onValueChange: (v) => setTypeFilter(v === "all" ? "" : v),
1693
+ children: [
1694
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-36", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All Types" }) }),
1695
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
1696
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "all", children: "All Types" }),
1697
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "image", children: "Images" }),
1698
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "video", children: "Videos" }),
1699
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "audio", children: "Audio" }),
1700
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "document", children: "Documents" }),
1701
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "other", children: "Other" })
1702
+ ] })
1703
+ ]
1704
+ }
1705
+ ),
1706
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1707
+ TaxonomyFilter,
1708
+ {
1709
+ selectedTermIds,
1710
+ onChange: setSelectedTermIds,
1711
+ placeholder: "Tags"
1712
+ }
1713
+ ),
1714
+ assetsResult?.page && assetsResult.page.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex cursor-pointer items-center gap-2 text-sm", children: [
1715
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1716
+ Checkbox,
1717
+ {
1718
+ checked: isSelectionMode,
1719
+ onCheckedChange: (checked) => {
1720
+ setIsSelectionMode(checked);
1721
+ if (!checked) {
1722
+ setSelectedAssets(/* @__PURE__ */ new Set());
1723
+ }
1724
+ }
1725
+ }
1726
+ ),
1727
+ "Selection Mode"
1728
+ ] })
1655
1729
  ] }),
1656
- /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { onClick: () => setShowUploadModal(true), children: [
1657
- /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "size-4" }),
1658
- "Upload Files"
1730
+ right: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1731
+ isSelectionMode && selectedAssets.size > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-muted-foreground", children: [
1732
+ selectedAssets.size,
1733
+ " selected"
1734
+ ] }),
1735
+ isSelectionMode && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1736
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1737
+ CmsButton,
1738
+ {
1739
+ variant: "secondary",
1740
+ size: "sm",
1741
+ onClick: handleSelectAll,
1742
+ children: "Select All"
1743
+ }
1744
+ ),
1745
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1746
+ CmsButton,
1747
+ {
1748
+ variant: "secondary",
1749
+ size: "sm",
1750
+ onClick: handleDeselectAll,
1751
+ children: "Clear"
1752
+ }
1753
+ )
1754
+ ] }),
1755
+ currentFolderId && !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { variant: "secondary", onClick: handleNavigateUp, children: [
1756
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { className: "size-4" }),
1757
+ "Up"
1758
+ ] }),
1759
+ !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1760
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1761
+ CmsButton,
1762
+ {
1763
+ variant: "secondary",
1764
+ onClick: () => setShowNewFolderModal(true),
1765
+ children: [
1766
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FolderPlus, { className: "size-4" }),
1767
+ "New Folder"
1768
+ ]
1769
+ }
1770
+ ),
1771
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { onClick: () => setShowUploadModal(true), children: [
1772
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "size-4" }),
1773
+ "Upload Files"
1774
+ ] })
1775
+ ] })
1659
1776
  ] })
1660
- ] })
1661
- ] }) }),
1777
+ }
1778
+ ),
1662
1779
  isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-12", children: [
1663
1780
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "size-8 animate-spin rounded-full border-2 border-muted border-t-primary" }),
1664
1781
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-4 text-sm text-muted-foreground", children: "Loading media library..." })
1665
1782
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1666
1783
  !isTrashView && folders && folders.length > 0 && !searchQuery && /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { children: [
1667
1784
  /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "mb-3 text-sm font-medium text-muted-foreground", children: "Folders" }),
1668
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-4 md:grid-cols-6", children: folders.map((folder) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "group relative flex flex-col items-center gap-2 rounded-lg border bg-card p-4 text-center transition-colors hover:border-primary/50 hover:bg-muted/50 cursor-pointer", onClick: () => handleFolderClick(folder._id), children: [
1669
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute right-2 top-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(MediaFolderActions, { folder: {
1670
- _id: folder._id,
1671
- name: folder.name
1672
- }, onEdit: () => setEditingFolder({
1673
- _id: folder._id,
1674
- name: folder.name,
1675
- description: folder.description
1676
- }), onDelete: () => setDeleteTarget({
1677
- type: "folder",
1678
- id: folder._id,
1679
- name: folder.name
1680
- }) }) }),
1681
- /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-10 text-amber-500" }),
1682
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate text-sm font-medium", children: folder.name })
1683
- ] }, folder._id)) })
1785
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-4 md:grid-cols-6", children: folders.map((folder) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
1786
+ "div",
1787
+ {
1788
+ className: "group relative flex cursor-pointer flex-col items-center gap-2 rounded-lg border bg-card p-4 text-center transition-colors hover:border-primary/50 hover:bg-muted/50",
1789
+ onClick: () => handleFolderClick(folder._id),
1790
+ children: [
1791
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute right-2 top-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1792
+ MediaFolderActions,
1793
+ {
1794
+ folder: { _id: folder._id, name: folder.name },
1795
+ onEdit: () => setEditingFolder({
1796
+ _id: folder._id,
1797
+ name: folder.name,
1798
+ description: folder.description
1799
+ }),
1800
+ onDelete: () => setDeleteTarget({
1801
+ type: "folder",
1802
+ id: folder._id,
1803
+ name: folder.name
1804
+ })
1805
+ }
1806
+ ) }),
1807
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-10 text-amber-500" }),
1808
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate text-sm font-medium", children: folder.name })
1809
+ ]
1810
+ },
1811
+ folder._id
1812
+ )) })
1684
1813
  ] }),
1685
1814
  isTrashView && folders && folders.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { children: [
1686
1815
  /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "mb-3 text-sm font-medium text-muted-foreground", children: [
@@ -1688,14 +1817,30 @@ function MediaPage() {
1688
1817
  folders.length,
1689
1818
  ")"
1690
1819
  ] }),
1691
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-4 md:grid-cols-6", children: folders.map((folder) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "group relative flex flex-col items-center gap-2 rounded-lg border border-destructive/20 bg-card p-4 text-center opacity-60", children: [
1692
- /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-10 text-amber-500/50" }),
1693
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate text-sm font-medium", children: folder.name }),
1694
- /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { variant: "secondary", size: "sm", onClick: () => handleRestoreFolder(folder._id), disabled: isRestoring, children: [
1695
- /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "mr-1 size-3" }),
1696
- "Restore"
1697
- ] })
1698
- ] }, folder._id)) })
1820
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-4 md:grid-cols-6", children: folders.map((folder) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
1821
+ "div",
1822
+ {
1823
+ className: "group relative flex flex-col items-center gap-2 rounded-lg border border-destructive/20 bg-card p-4 text-center opacity-60",
1824
+ children: [
1825
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-10 text-amber-500/50" }),
1826
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate text-sm font-medium", children: folder.name }),
1827
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1828
+ CmsButton,
1829
+ {
1830
+ variant: "secondary",
1831
+ size: "sm",
1832
+ onClick: () => handleRestoreFolder(folder._id),
1833
+ disabled: isRestoring,
1834
+ children: [
1835
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "mr-1 size-3" }),
1836
+ "Restore"
1837
+ ]
1838
+ }
1839
+ )
1840
+ ]
1841
+ },
1842
+ folder._id
1843
+ )) })
1699
1844
  ] }),
1700
1845
  displayedAssets.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { children: [
1701
1846
  !isTrashView && folders && folders.length > 0 && !searchQuery && /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "mb-3 text-sm font-medium text-muted-foreground", children: "Files" }),
@@ -1708,125 +1853,349 @@ function MediaPage() {
1708
1853
  const assetId = asset._id;
1709
1854
  const isSelected = selectedAssets.has(assetId);
1710
1855
  const mediaType = getMediaTypeFromMimeType(asset.mimeType);
1711
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("group relative flex flex-col overflow-hidden rounded-lg border bg-card transition-all cursor-pointer hover:border-primary/50", isSelected && "border-primary ring-2 ring-primary/20"), onClick: () => handleAssetClick(assetId), children: [
1712
- isSelectionMode && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-2 top-2 z-10", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Checkbox, { checked: isSelected, onCheckedChange: () => handleAssetSelect(assetId), onClick: (e) => e.stopPropagation(), className: "bg-white/80" }) }),
1713
- !isSelectionMode && !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute right-2 top-2 z-10", children: /* @__PURE__ */ jsxRuntimeExports.jsx(MediaAssetActions, { asset: {
1714
- _id: asset._id,
1715
- name: asset.name,
1716
- url: asset.url
1717
- }, onView: () => {
1718
- const index = displayedAssets.findIndex((a) => a._id === asset._id);
1719
- if (index !== -1) setPreviewIndex(index);
1720
- }, onEdit: () => setEditingAsset({
1721
- _id: asset._id,
1722
- name: asset.name,
1723
- title: asset.title,
1724
- description: asset.description,
1725
- altText: asset.altText,
1726
- tags: asset.tags
1727
- }), onDelete: () => setDeleteTarget({
1728
- type: "asset",
1729
- id: asset._id,
1730
- name: asset.name
1731
- }) }) }),
1732
- !isSelectionMode && isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute right-2 top-2 z-10 flex gap-1 opacity-0 group-hover:opacity-100", children: [
1733
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { variant: "secondary", size: "icon-sm", onClick: (e) => {
1734
- e.stopPropagation();
1735
- handleRestore(asset._id);
1736
- }, title: "Restore", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "size-4" }) }),
1737
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { variant: "danger", size: "icon-sm", onClick: (e) => {
1738
- e.stopPropagation();
1739
- setPermanentDeleteTarget(asset._id);
1740
- setShowPermanentDeleteConfirm(true);
1741
- }, title: "Delete Forever", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4" }) })
1742
- ] }),
1743
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "aspect-square overflow-hidden bg-muted", children: mediaType === "image" && asset.url ? /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: asset.url, alt: asset.title || asset.name, className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-full items-center justify-center text-muted-foreground", children: getMediaTypeIcon(mediaType, "size-10") }) }),
1744
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-2", children: [
1745
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "truncate text-sm font-medium", title: asset.name, children: asset.name }),
1746
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-0.5 flex items-center gap-1 text-xs text-muted-foreground", children: [
1747
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "capitalize", children: mediaType }),
1748
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "•" }),
1749
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: formatFileSize(asset.size ?? 0) })
1750
- ] }),
1751
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: formatDate(asset._creationTime) })
1752
- ] })
1753
- ] }, asset._id);
1856
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1857
+ "div",
1858
+ {
1859
+ className: cn(
1860
+ "group relative flex cursor-pointer flex-col overflow-hidden rounded-lg border bg-card transition-all hover:border-primary/50",
1861
+ isSelected && "border-primary ring-2 ring-primary/20"
1862
+ ),
1863
+ onClick: () => handleAssetClick(assetId),
1864
+ children: [
1865
+ isSelectionMode && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-2 top-2 z-10", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1866
+ Checkbox,
1867
+ {
1868
+ checked: isSelected,
1869
+ onCheckedChange: () => handleAssetSelect(assetId),
1870
+ onClick: (e) => e.stopPropagation(),
1871
+ className: "bg-white/80"
1872
+ }
1873
+ ) }),
1874
+ !isSelectionMode && !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute right-2 top-2 z-10", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1875
+ MediaAssetActions,
1876
+ {
1877
+ asset: {
1878
+ _id: asset._id,
1879
+ name: asset.name,
1880
+ url: asset.url
1881
+ },
1882
+ onView: () => {
1883
+ const index = displayedAssets.findIndex(
1884
+ (a) => a._id === asset._id
1885
+ );
1886
+ if (index !== -1) setPreviewIndex(index);
1887
+ },
1888
+ onEdit: () => setEditingAsset({
1889
+ _id: asset._id,
1890
+ name: asset.name,
1891
+ title: asset.title,
1892
+ description: asset.description,
1893
+ altText: asset.altText,
1894
+ tags: asset.tags
1895
+ }),
1896
+ onDelete: () => setDeleteTarget({
1897
+ type: "asset",
1898
+ id: asset._id,
1899
+ name: asset.name
1900
+ })
1901
+ }
1902
+ ) }),
1903
+ !isSelectionMode && isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute right-2 top-2 z-10 flex gap-1 opacity-0 group-hover:opacity-100", children: [
1904
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1905
+ CmsButton,
1906
+ {
1907
+ variant: "secondary",
1908
+ size: "icon-sm",
1909
+ onClick: (e) => {
1910
+ e.stopPropagation();
1911
+ handleRestore(asset._id);
1912
+ },
1913
+ title: "Restore",
1914
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "size-4" })
1915
+ }
1916
+ ),
1917
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1918
+ CmsButton,
1919
+ {
1920
+ variant: "danger",
1921
+ size: "icon-sm",
1922
+ onClick: (e) => {
1923
+ e.stopPropagation();
1924
+ setPermanentDeleteTarget(asset._id);
1925
+ setShowPermanentDeleteConfirm(true);
1926
+ },
1927
+ title: "Delete Forever",
1928
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4" })
1929
+ }
1930
+ )
1931
+ ] }),
1932
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "aspect-square overflow-hidden bg-muted", children: mediaType === "image" && asset.url ? /* @__PURE__ */ jsxRuntimeExports.jsx(
1933
+ "img",
1934
+ {
1935
+ src: asset.url,
1936
+ alt: asset.title || asset.name,
1937
+ className: "h-full w-full object-cover"
1938
+ }
1939
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-full items-center justify-center text-muted-foreground", children: getMediaTypeIcon(mediaType, "size-10") }) }),
1940
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-2", children: [
1941
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1942
+ "p",
1943
+ {
1944
+ className: "truncate text-sm font-medium",
1945
+ title: asset.name,
1946
+ children: asset.name
1947
+ }
1948
+ ),
1949
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-0.5 flex items-center gap-1 text-xs text-muted-foreground", children: [
1950
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "capitalize", children: mediaType }),
1951
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "•" }),
1952
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: formatFileSize(asset.size ?? 0) })
1953
+ ] }),
1954
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: formatDate(asset._creationTime) })
1955
+ ] })
1956
+ ]
1957
+ },
1958
+ asset._id
1959
+ );
1754
1960
  }) }),
1755
1961
  !assetsResult.isDone && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-4 text-center text-sm text-muted-foreground", children: [
1756
1962
  "Showing ",
1757
1963
  assetsResult.page.length,
1758
1964
  " files. More files available."
1759
1965
  ] })
1760
- ] }) : isTrashView ? /* @__PURE__ */ jsxRuntimeExports.jsx(CmsEmptyState, { icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-8" }), title: "Trash is empty", description: "Deleted files will appear here. You can restore them or permanently delete them." }) : !folders?.length && /* @__PURE__ */ jsxRuntimeExports.jsx(CmsEmptyState, { icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { className: "size-8" }), title: "No media assets yet", description: "Upload images, videos, documents, and other files to use in your content.", action: {
1761
- label: "Upload Files",
1762
- onClick: () => setShowUploadModal(true)
1763
- } }),
1764
- searchQuery && displayedAssets.length === 0 && !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsx(CmsEmptyState, { icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "size-8" }), title: "No results found", description: `No files match "${searchQuery}". Try a different search term.`, action: {
1765
- label: "Clear Search",
1766
- onClick: () => setSearchQuery(""),
1767
- variant: "secondary"
1768
- } })
1966
+ ] }) : isTrashView ? /* @__PURE__ */ jsxRuntimeExports.jsx(
1967
+ CmsEmptyState,
1968
+ {
1969
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-8" }),
1970
+ title: "Trash is empty",
1971
+ description: "Deleted files will appear here. You can restore them or permanently delete them."
1972
+ }
1973
+ ) : !folders?.length && /* @__PURE__ */ jsxRuntimeExports.jsx(
1974
+ CmsEmptyState,
1975
+ {
1976
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { className: "size-8" }),
1977
+ title: "No media assets yet",
1978
+ description: "Upload images, videos, documents, and other files to use in your content.",
1979
+ action: {
1980
+ label: "Upload Files",
1981
+ onClick: () => setShowUploadModal(true)
1982
+ }
1983
+ }
1984
+ ),
1985
+ searchQuery && displayedAssets.length === 0 && !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsx(
1986
+ CmsEmptyState,
1987
+ {
1988
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "size-8" }),
1989
+ title: "No results found",
1990
+ description: `No files match "${searchQuery}". Try a different search term.`,
1991
+ action: {
1992
+ label: "Clear Search",
1993
+ onClick: () => setSearchQuery(""),
1994
+ variant: "secondary"
1995
+ }
1996
+ }
1997
+ )
1769
1998
  ] }),
1770
1999
  /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: showNewFolderModal, onOpenChange: setShowNewFolderModal, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { children: [
1771
2000
  /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Create New Folder" }) }),
1772
2001
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4 py-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1773
2002
  /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "folder-name", children: "Folder Name" }),
1774
- /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { id: "folder-name", value: newFolderName, onChange: (e) => {
1775
- setNewFolderName(e.target.value);
1776
- setFolderError("");
1777
- }, placeholder: "Enter folder name", autoFocus: true, onKeyDown: (e) => {
1778
- if (e.key === "Enter" && !isCreatingFolder) {
1779
- handleCreateFolder();
2003
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2004
+ Input,
2005
+ {
2006
+ id: "folder-name",
2007
+ value: newFolderName,
2008
+ onChange: (e) => {
2009
+ setNewFolderName(e.target.value);
2010
+ setFolderError("");
2011
+ },
2012
+ placeholder: "Enter folder name",
2013
+ autoFocus: true,
2014
+ onKeyDown: (e) => {
2015
+ if (e.key === "Enter" && !isCreatingFolder) {
2016
+ handleCreateFolder();
2017
+ }
2018
+ }
1780
2019
  }
1781
- } }),
2020
+ ),
1782
2021
  folderError && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-destructive", children: folderError })
1783
2022
  ] }) }),
1784
2023
  /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [
1785
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { variant: "secondary", onClick: () => setShowNewFolderModal(false), disabled: isCreatingFolder, children: "Cancel" }),
1786
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { onClick: handleCreateFolder, disabled: isCreatingFolder || !newFolderName.trim(), loading: isCreatingFolder, children: "Create Folder" })
2024
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2025
+ CmsButton,
2026
+ {
2027
+ variant: "secondary",
2028
+ onClick: () => setShowNewFolderModal(false),
2029
+ disabled: isCreatingFolder,
2030
+ children: "Cancel"
2031
+ }
2032
+ ),
2033
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2034
+ CmsButton,
2035
+ {
2036
+ onClick: handleCreateFolder,
2037
+ disabled: isCreatingFolder || !newFolderName.trim(),
2038
+ loading: isCreatingFolder,
2039
+ children: "Create Folder"
2040
+ }
2041
+ )
1787
2042
  ] })
1788
2043
  ] }) }),
1789
2044
  /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: showUploadModal, onOpenChange: setShowUploadModal, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-lg", children: [
1790
2045
  /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Upload Files" }) }),
1791
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(UploadDropzone, { currentFolderId, generateUploadUrl: api.media.generateUploadUrl, createAsset: api.media.createAsset, onUploadComplete: handleUploadComplete, maxFileSize: 50 * 1024 * 1024, maxConcurrentUploads: 3 }) }),
1792
- /* @__PURE__ */ jsxRuntimeExports.jsx(DialogFooter, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { variant: "secondary", onClick: () => setShowUploadModal(false), children: "Close" }) })
2046
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
2047
+ UploadDropzone,
2048
+ {
2049
+ currentFolderId,
2050
+ generateUploadUrl: api2.generateUploadUrl,
2051
+ createAsset: api2.createMediaAsset,
2052
+ onUploadComplete: handleUploadComplete,
2053
+ maxFileSize: 50 * 1024 * 1024,
2054
+ maxConcurrentUploads: 3
2055
+ }
2056
+ ) }),
2057
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DialogFooter, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
2058
+ CmsButton,
2059
+ {
2060
+ variant: "secondary",
2061
+ onClick: () => setShowUploadModal(false),
2062
+ children: "Close"
2063
+ }
2064
+ ) })
1793
2065
  ] }) }),
1794
- /* @__PURE__ */ jsxRuntimeExports.jsx(MediaPreviewModal, { asset: previewIndex !== null && displayedAssets[previewIndex] ? displayedAssets[previewIndex] : null, assets: displayedAssets, currentIndex: previewIndex ?? 0, open: previewIndex !== null, onOpenChange: (open) => {
1795
- if (!open) setPreviewIndex(null);
1796
- }, onNavigate: handlePreviewNavigate, onEdit: isTrashView ? void 0 : (asset) => setEditingAsset({
1797
- _id: asset._id,
1798
- name: asset.name,
1799
- title: asset.title,
1800
- description: asset.description,
1801
- altText: asset.altText,
1802
- tags: asset.tags
1803
- }), onDelete: isTrashView ? void 0 : (asset) => setDeleteTarget({
1804
- type: "asset",
1805
- id: asset._id,
1806
- name: asset.name
1807
- }) }),
1808
- /* @__PURE__ */ jsxRuntimeExports.jsx(MediaAssetEditDialog, { asset: editingAsset, open: editingAsset !== null, onOpenChange: (open) => {
1809
- if (!open) setEditingAsset(null);
1810
- } }),
1811
- /* @__PURE__ */ jsxRuntimeExports.jsx(MediaFolderEditDialog, { folder: editingFolder, open: editingFolder !== null, onOpenChange: (open) => {
1812
- if (!open) setEditingFolder(null);
1813
- } }),
1814
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsConfirmDialog, { open: deleteTarget !== null, onOpenChange: (open) => {
1815
- if (!open) setDeleteTarget(null);
1816
- }, title: `Delete ${deleteTarget?.type === "folder" ? "Folder" : "File"}?`, description: `Are you sure you want to delete "${deleteTarget?.name}"? ${deleteTarget?.type === "folder" ? "This will also delete all files inside the folder." : "This action can be undone from the trash."}`, confirmLabel: "Delete", onConfirm: handleDelete, variant: "danger", loading: isDeleting }),
1817
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsConfirmDialog, { open: showBulkDeleteConfirm, onOpenChange: setShowBulkDeleteConfirm, title: "Delete Selected Files?", description: `Are you sure you want to delete ${selectedAssets.size} ${selectedAssets.size === 1 ? "file" : "files"}? This action can be undone from the trash.`, confirmLabel: "Delete All", onConfirm: handleBulkDelete, variant: "danger", loading: isBulkDeleting }),
1818
- /* @__PURE__ */ jsxRuntimeExports.jsx(CmsConfirmDialog, { open: showPermanentDeleteConfirm, onOpenChange: (open) => {
1819
- setShowPermanentDeleteConfirm(open);
1820
- if (!open) setPermanentDeleteTarget(null);
1821
- }, title: permanentDeleteTarget === "bulk" ? `Delete ${selectedAssets.size} ${selectedAssets.size === 1 ? "File" : "Files"} Forever?` : "Delete Forever?", description: permanentDeleteTarget === "bulk" ? `This will permanently delete ${selectedAssets.size} ${selectedAssets.size === 1 ? "file" : "files"}. This action cannot be undone.` : "This will permanently delete this file. This action cannot be undone.", confirmLabel: "Delete Forever", onConfirm: handlePermanentDelete, variant: "danger", loading: isPermanentlyDeleting }),
1822
- /* @__PURE__ */ jsxRuntimeExports.jsx(MediaMoveModal, { open: showMoveModal, onOpenChange: setShowMoveModal, assetIds: Array.from(selectedAssets), currentFolderId, onMoved: handleBulkMoveComplete }),
1823
- isSelectionMode && !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsx(MediaBulkActionBar, { selectedCount: selectedAssets.size, onClear: handleDeselectAll, onMove: () => setShowMoveModal(true), onDelete: () => setShowBulkDeleteConfirm(true), isDeleting: isBulkDeleting }),
1824
- isSelectionMode && isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsx(MediaTrashBulkActionBar, { selectedCount: selectedAssets.size, onClear: handleDeselectAll, onRestore: handleBulkRestore, onPermanentDelete: () => {
1825
- setPermanentDeleteTarget("bulk");
1826
- setShowPermanentDeleteConfirm(true);
1827
- }, isRestoring, isDeleting: isPermanentlyDeleting })
2066
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2067
+ MediaPreviewModal,
2068
+ {
2069
+ asset: previewIndex !== null && displayedAssets[previewIndex] ? displayedAssets[previewIndex] : null,
2070
+ assets: displayedAssets,
2071
+ currentIndex: previewIndex ?? 0,
2072
+ open: previewIndex !== null,
2073
+ onOpenChange: (open) => {
2074
+ if (!open) setPreviewIndex(null);
2075
+ },
2076
+ onNavigate: handlePreviewNavigate,
2077
+ onEdit: isTrashView ? void 0 : (asset) => setEditingAsset({
2078
+ _id: asset._id,
2079
+ name: asset.name,
2080
+ title: asset.title,
2081
+ description: asset.description,
2082
+ altText: asset.altText,
2083
+ tags: asset.tags
2084
+ }),
2085
+ onDelete: isTrashView ? void 0 : (asset) => setDeleteTarget({
2086
+ type: "asset",
2087
+ id: asset._id,
2088
+ name: asset.name
2089
+ })
2090
+ }
2091
+ ),
2092
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2093
+ MediaAssetEditDialog,
2094
+ {
2095
+ asset: editingAsset,
2096
+ open: editingAsset !== null,
2097
+ onOpenChange: (open) => {
2098
+ if (!open) setEditingAsset(null);
2099
+ }
2100
+ }
2101
+ ),
2102
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2103
+ MediaFolderEditDialog,
2104
+ {
2105
+ folder: editingFolder,
2106
+ open: editingFolder !== null,
2107
+ onOpenChange: (open) => {
2108
+ if (!open) setEditingFolder(null);
2109
+ }
2110
+ }
2111
+ ),
2112
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2113
+ CmsConfirmDialog,
2114
+ {
2115
+ open: deleteTarget !== null,
2116
+ onOpenChange: (open) => {
2117
+ if (!open) setDeleteTarget(null);
2118
+ },
2119
+ title: `Delete ${deleteTarget?.type === "folder" ? "Folder" : "File"}?`,
2120
+ description: `Are you sure you want to delete "${deleteTarget?.name}"? ${deleteTarget?.type === "folder" ? "This will also delete all files inside the folder." : "This action can be undone from the trash."}`,
2121
+ confirmLabel: "Delete",
2122
+ onConfirm: handleDelete,
2123
+ variant: "danger",
2124
+ loading: isDeleting
2125
+ }
2126
+ ),
2127
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2128
+ CmsConfirmDialog,
2129
+ {
2130
+ open: showBulkDeleteConfirm,
2131
+ onOpenChange: setShowBulkDeleteConfirm,
2132
+ title: "Delete Selected Files?",
2133
+ description: `Are you sure you want to delete ${selectedAssets.size} ${selectedAssets.size === 1 ? "file" : "files"}? This action can be undone from the trash.`,
2134
+ confirmLabel: "Delete All",
2135
+ onConfirm: handleBulkDelete,
2136
+ variant: "danger",
2137
+ loading: isBulkDeleting
2138
+ }
2139
+ ),
2140
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2141
+ CmsConfirmDialog,
2142
+ {
2143
+ open: showPermanentDeleteConfirm,
2144
+ onOpenChange: (open) => {
2145
+ setShowPermanentDeleteConfirm(open);
2146
+ if (!open) setPermanentDeleteTarget(null);
2147
+ },
2148
+ title: permanentDeleteTarget === "bulk" ? `Delete ${selectedAssets.size} ${selectedAssets.size === 1 ? "File" : "Files"} Forever?` : "Delete Forever?",
2149
+ description: permanentDeleteTarget === "bulk" ? `This will permanently delete ${selectedAssets.size} ${selectedAssets.size === 1 ? "file" : "files"}. This action cannot be undone.` : "This will permanently delete this file. This action cannot be undone.",
2150
+ confirmLabel: "Delete Forever",
2151
+ onConfirm: handlePermanentDelete,
2152
+ variant: "danger",
2153
+ loading: isPermanentlyDeleting
2154
+ }
2155
+ ),
2156
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2157
+ MediaMoveModal,
2158
+ {
2159
+ open: showMoveModal,
2160
+ onOpenChange: setShowMoveModal,
2161
+ assetIds: Array.from(selectedAssets),
2162
+ currentFolderId,
2163
+ onMoved: handleBulkMoveComplete
2164
+ }
2165
+ ),
2166
+ isSelectionMode && !isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsx(
2167
+ MediaBulkActionBar,
2168
+ {
2169
+ selectedCount: selectedAssets.size,
2170
+ onClear: handleDeselectAll,
2171
+ onMove: () => setShowMoveModal(true),
2172
+ onDelete: () => setShowBulkDeleteConfirm(true),
2173
+ isDeleting: isBulkDeleting
2174
+ }
2175
+ ),
2176
+ isSelectionMode && isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsx(
2177
+ MediaTrashBulkActionBar,
2178
+ {
2179
+ selectedCount: selectedAssets.size,
2180
+ onClear: handleDeselectAll,
2181
+ onRestore: handleBulkRestore,
2182
+ onPermanentDelete: () => {
2183
+ setPermanentDeleteTarget("bulk");
2184
+ setShowPermanentDeleteConfirm(true);
2185
+ },
2186
+ isRestoring,
2187
+ isDeleting: isPermanentlyDeleting
2188
+ }
2189
+ )
1828
2190
  ] });
1829
2191
  }
2192
+ function MediaRoute() {
2193
+ const navigation = useTanStackNavigation();
2194
+ const {
2195
+ settings
2196
+ } = useSettingsConfig();
2197
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(MediaPage, { api: api.admin, navigation, settings });
2198
+ }
1830
2199
  export {
1831
- MediaPage as component
2200
+ MediaRoute as component
1832
2201
  };