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.
- package/README.md +3 -3
- package/admin/src/components/Sidebar.tsx +150 -58
- package/admin/src/components/ui/collapsible.tsx +7 -0
- package/admin/src/embed/components/EmbedSidebar.tsx +163 -68
- package/admin-dist/nitro.json +1 -1
- package/admin-dist/public/assets/{CmsEmptyState-CkqBIab3.js → CmsEmptyState-Do_erIgn.js} +1 -1
- package/admin-dist/public/assets/{CmsPageHeader-CUtl5MMG.js → CmsPageHeader-qDwPGi48.js} +1 -1
- package/admin-dist/public/assets/{CmsStatusBadge-CUYFgEe-.js → CmsStatusBadge-Dd9uToHE.js} +1 -1
- package/admin-dist/public/assets/{CmsSurface-CsJfAVa3.js → CmsSurface-DBy5Lumx.js} +1 -1
- package/admin-dist/public/assets/{CmsToolbar-CnfbcxeP.js → CmsToolbar-D1-Y-7SK.js} +1 -1
- package/admin-dist/public/assets/ContentEntryEditor-CWBiIx52.js +4 -0
- package/admin-dist/public/assets/{TaxonomyFilter-CWCxC5HZ.js → TaxonomyFilter-CdYQawxb.js} +1 -1
- package/admin-dist/public/assets/_contentTypeId-D9VMP6Gs.js +1 -0
- package/admin-dist/public/assets/_entryId-2FlCfqE7.js +1 -0
- package/admin-dist/public/assets/{alert-CF1BSzGR.js → alert-GxZx0y5c.js} +1 -1
- package/admin-dist/public/assets/{badge-CmuOIVKp.js → badge-BAlGIjop.js} +1 -1
- package/admin-dist/public/assets/{circle-check-big-BKDVG6DU.js → circle-check-big-CpLxAvEj.js} +1 -1
- package/admin-dist/public/assets/{command-XJxnF2Sd.js → command-di7XCqcv.js} +1 -1
- package/admin-dist/public/assets/content-D8zELsDG.js +1 -0
- package/admin-dist/public/assets/{content-types-CrNEm8Hf.js → content-types-BmzD0krT.js} +2 -2
- package/admin-dist/public/assets/globals-BvFfH-v9.css +1 -0
- package/admin-dist/public/assets/{index-C7xOwudI.js → index-zqfj4T_v.js} +1 -1
- package/admin-dist/public/assets/{label-CHCnXeBk.js → label-B6PPtKR5.js} +1 -1
- package/admin-dist/public/assets/{link-2-Bb34judH.js → link-2-W2fVnVOf.js} +1 -1
- package/admin-dist/public/assets/{list-9Pzt48ld.js → list-F8O0lZXC.js} +1 -1
- package/admin-dist/public/assets/main-dZT72bAG.js +97 -0
- package/admin-dist/public/assets/media-CETueFbV.js +1 -0
- package/admin-dist/public/assets/new._contentTypeId-BV2-TyyR.js +1 -0
- package/admin-dist/public/assets/{plus-Ceef7DHk.js → plus-AABQIF0N.js} +1 -1
- package/admin-dist/public/assets/{rotate-ccw-7k7-4VUq.js → rotate-ccw-BZpZtw0N.js} +1 -1
- package/admin-dist/public/assets/{scroll-area-CC6wujnp.js → scroll-area-CDfk-zrz.js} +1 -1
- package/admin-dist/public/assets/{search-DwoUV2pv.js → search-BvgYr-c9.js} +1 -1
- package/admin-dist/public/assets/{select-hOZTp8aC.js → select-BuiHcMzS.js} +1 -1
- package/admin-dist/public/assets/settings-DBxbYDvn.js +1 -0
- package/admin-dist/public/assets/{switch-jX2pDaNU.js → switch-DiJvolcs.js} +1 -1
- package/admin-dist/public/assets/tabs-Cgz6G_Xy.js +1 -0
- package/admin-dist/public/assets/{tanstack-adapter-B-Glm4kH.js → tanstack-adapter-BknsSgra.js} +1 -1
- package/admin-dist/public/assets/taxonomies-DOErsLl5.js +1 -0
- package/admin-dist/public/assets/{textarea-B6SfBmr0.js → textarea-CgggMxUX.js} +1 -1
- package/admin-dist/public/assets/{trash-BOCnIznD.js → trash-BU4ANuaW.js} +1 -1
- package/admin-dist/public/assets/{triangle-alert-CXFIO_Gu.js → triangle-alert-lvCbwp0s.js} +1 -1
- package/admin-dist/public/assets/{useBreadcrumbLabel-_6qBagc3.js → useBreadcrumbLabel-D00rvqjw.js} +1 -1
- package/admin-dist/public/assets/{usePermissions-M1ijZ7a6.js → usePermissions-D7tQowaF.js} +1 -1
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-collapsible.mjs +144 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-slot.mjs +21 -21
- package/admin-dist/server/_libs/lucide-react.mjs +131 -124
- package/admin-dist/server/_ssr/{CmsButton-DOiTVKQq.mjs → CmsButton-DbzfJru_.mjs} +1 -1
- package/admin-dist/server/_ssr/{CmsEmptyState-fbnGt3LD.mjs → CmsEmptyState-CuvcXr3Z.mjs} +3 -3
- package/admin-dist/server/_ssr/{CmsPageHeader-DHRrdOZa.mjs → CmsPageHeader-ClNPU7Up.mjs} +1 -1
- package/admin-dist/server/_ssr/{CmsStatusBadge-s7obWbKZ.mjs → CmsStatusBadge-CojMbrY7.mjs} +2 -2
- package/admin-dist/server/_ssr/{CmsSurface-rFoYjb62.mjs → CmsSurface-Dcv440rp.mjs} +1 -1
- package/admin-dist/server/_ssr/{CmsToolbar-zTE45z2q.mjs → CmsToolbar-BKv1nL6u.mjs} +2 -2
- package/admin-dist/server/_ssr/{ContentEntryEditor-BLoEjT_m.mjs → ContentEntryEditor-weiXSBdZ.mjs} +35 -51
- package/admin-dist/server/_ssr/{TaxonomyFilter-XAtaJC2z.mjs → TaxonomyFilter-BPQ57Mwk.mjs} +7 -7
- package/admin-dist/server/_ssr/{_contentTypeId-Csl4822C.mjs → _contentTypeId-DyyauLOs.mjs} +24 -23
- package/admin-dist/server/_ssr/{_entryId-D8alLFBx.mjs → _entryId-9Cafwxmw.mjs} +22 -21
- package/admin-dist/server/_ssr/_tanstack-start-manifest_v-Dk-FIYPN.mjs +4 -0
- package/admin-dist/server/_ssr/{command-C0Di14--.mjs → command-CEf8YBxY.mjs} +1 -1
- package/admin-dist/server/_ssr/{content-CT-FPsmV.mjs → content-ZFWVzO25.mjs} +20 -19
- package/admin-dist/server/_ssr/{content-types-C8cBFdzE.mjs → content-types-D25lUE-j.mjs} +18 -17
- package/admin-dist/server/_ssr/{index-BJtcrEc-.mjs → index-BlSIlH4Z.mjs} +10 -9
- package/admin-dist/server/_ssr/index.mjs +2 -2
- package/admin-dist/server/_ssr/{label-qn2Afwl4.mjs → label-PblVvdRv.mjs} +1 -1
- package/admin-dist/server/_ssr/{media-qv5IAsMZ.mjs → media-CD2_NUMw.mjs} +683 -314
- package/admin-dist/server/_ssr/{new._contentTypeId-DdGyrhqs.mjs → new._contentTypeId-dmZy6PBX.mjs} +20 -19
- package/admin-dist/server/_ssr/{router-nSVkxb6Y.mjs → router-x6Ab8T4s.mjs} +109 -43
- package/admin-dist/server/_ssr/{scroll-area-BCinP455.mjs → scroll-area-BH_1K-WT.mjs} +1 -1
- package/admin-dist/server/_ssr/{select-BKQlQScw.mjs → select-CrfEkFJw.mjs} +2 -2
- package/admin-dist/server/_ssr/{settings-BCr2KQlk.mjs → settings-DVdsoWoh.mjs} +158 -105
- package/admin-dist/server/_ssr/{switch-BaOi42fE.mjs → switch-DX_X8vZl.mjs} +1 -1
- package/admin-dist/server/_ssr/{tabs-DYXEi9kq.mjs → tabs-4FWM0sn8.mjs} +3 -3
- package/admin-dist/server/_ssr/{tanstack-adapter-Bsz8kha-.mjs → tanstack-adapter-D3ZcKtbY.mjs} +1 -1
- package/admin-dist/server/_ssr/{taxonomies-CueMHTbE.mjs → taxonomies-BHFfO9Yr.mjs} +21 -20
- package/admin-dist/server/_ssr/{textarea-CI0Jqx2x.mjs → textarea-CZVaroMc.mjs} +1 -1
- package/admin-dist/server/_ssr/{trash-DE6W8GoX.mjs → trash-9tUB2KwI.mjs} +14 -13
- package/admin-dist/server/_ssr/{useBreadcrumbLabel-B5Yi72lM.mjs → useBreadcrumbLabel-DVme3DSb.mjs} +1 -1
- package/admin-dist/server/_ssr/{usePermissions-C3nZ-Izm.mjs → usePermissions-zAQj-ruE.mjs} +1 -1
- package/admin-dist/server/index.mjs +188 -188
- package/dist/cli/commands/init.d.ts +12 -2
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +136 -138
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/templates/admin.d.ts +10 -0
- package/dist/cli/templates/admin.d.ts.map +1 -0
- package/dist/cli/templates/admin.js +212 -0
- package/dist/cli/templates/admin.js.map +1 -0
- package/dist/cli/templates/cmsClient.d.ts +7 -0
- package/dist/cli/templates/cmsClient.d.ts.map +1 -0
- package/dist/cli/templates/cmsClient.js +36 -0
- package/dist/cli/templates/cmsClient.js.map +1 -0
- package/dist/cli/templates/cmsConfig.d.ts +7 -0
- package/dist/cli/templates/cmsConfig.d.ts.map +1 -0
- package/dist/cli/templates/cmsConfig.js +86 -0
- package/dist/cli/templates/cmsConfig.js.map +1 -0
- package/dist/cli/templates/index.d.ts +10 -0
- package/dist/cli/templates/index.d.ts.map +1 -0
- package/dist/cli/templates/index.js +10 -0
- package/dist/cli/templates/index.js.map +1 -0
- package/dist/cli/templates/schemas/blog.d.ts +8 -0
- package/dist/cli/templates/schemas/blog.d.ts.map +1 -0
- package/dist/cli/templates/schemas/blog.js +103 -0
- package/dist/cli/templates/schemas/blog.js.map +1 -0
- package/dist/cli/templates/schemas/docs.d.ts +8 -0
- package/dist/cli/templates/schemas/docs.d.ts.map +1 -0
- package/dist/cli/templates/schemas/docs.js +110 -0
- package/dist/cli/templates/schemas/docs.js.map +1 -0
- package/dist/cli/templates/schemas/index.d.ts +11 -0
- package/dist/cli/templates/schemas/index.d.ts.map +1 -0
- package/dist/cli/templates/schemas/index.js +13 -0
- package/dist/cli/templates/schemas/index.js.map +1 -0
- package/dist/cli/templates/schemas/landing.d.ts +8 -0
- package/dist/cli/templates/schemas/landing.d.ts.map +1 -0
- package/dist/cli/templates/schemas/landing.js +135 -0
- package/dist/cli/templates/schemas/landing.js.map +1 -0
- package/dist/cli/utils/fileUtils.d.ts +21 -0
- package/dist/cli/utils/fileUtils.d.ts.map +1 -0
- package/dist/cli/utils/fileUtils.js +95 -0
- package/dist/cli/utils/fileUtils.js.map +1 -0
- package/dist/cli/utils/prompts.d.ts +25 -0
- package/dist/cli/utils/prompts.d.ts.map +1 -0
- package/dist/cli/utils/prompts.js +87 -0
- package/dist/cli/utils/prompts.js.map +1 -0
- package/dist/client/agentTools.d.ts +1 -1427
- package/dist/client/agentTools.d.ts.map +1 -1
- package/dist/component/contentTypeMutations.d.ts +1 -1
- package/dist/test.d.ts +5 -0
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +0 -1
- package/dist/test.js.map +1 -1
- package/package.json +28 -28
- package/admin/README.md +0 -99
- package/admin-dist/public/assets/ContentEntryEditor-BU220CCy.js +0 -4
- package/admin-dist/public/assets/_contentTypeId-DK8cskRt.js +0 -1
- package/admin-dist/public/assets/_entryId-CuVMExbb.js +0 -1
- package/admin-dist/public/assets/content-QBUxdxbS.js +0 -1
- package/admin-dist/public/assets/globals-B7Wsfh_v.css +0 -1
- package/admin-dist/public/assets/main-CjQ2VI9L.js +0 -97
- package/admin-dist/public/assets/media-Dc5PWt2Q.js +0 -1
- package/admin-dist/public/assets/new._contentTypeId-C_I4YxIa.js +0 -1
- package/admin-dist/public/assets/settings-t2PbCZh4.js +0 -1
- package/admin-dist/public/assets/tabs-q4EbZk7c.js +0 -1
- package/admin-dist/public/assets/taxonomies-kyk5P4ZW.js +0 -1
- package/admin-dist/server/_ssr/_tanstack-start-manifest_v-BffZedId.mjs +0 -4
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { d as
|
|
3
|
-
import {
|
|
4
|
-
import { T as Tabs, a as TabsList, b as TabsTrigger, U as UploadDropzone } from "./tabs-
|
|
5
|
-
import { C as CmsPageHeader } from "./CmsPageHeader-
|
|
6
|
-
import { C as CmsToolbar } from "./CmsToolbar-
|
|
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-
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
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-
|
|
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,
|
|
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-
|
|
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-
|
|
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.
|
|
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.
|
|
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.
|
|
413
|
-
const createTermMutation = useMutation(api.
|
|
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.
|
|
665
|
-
const taxonomiesResult = useQuery(api.
|
|
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.
|
|
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.
|
|
1154
|
-
const moveAssets = useMutation(api.
|
|
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,
|
|
1317
|
-
const [currentFolderId, setCurrentFolderId] = reactExports.useState(
|
|
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(
|
|
1330
|
-
|
|
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(
|
|
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(
|
|
1353
|
-
const mediaByTermResult0 = useQuery(
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
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 = [
|
|
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
|
-
}, [
|
|
1376
|
-
|
|
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(
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
const
|
|
1385
|
-
const
|
|
1386
|
-
const
|
|
1387
|
-
const
|
|
1388
|
-
const
|
|
1389
|
-
const
|
|
1390
|
-
const
|
|
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(
|
|
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(
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
id: assetId
|
|
1499
|
-
})
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
}
|
|
1505
|
-
|
|
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(
|
|
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(
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
id: folderId
|
|
1527
|
-
})
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
}
|
|
1533
|
-
|
|
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
|
-
}, [
|
|
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(
|
|
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(
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
"
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
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(
|
|
1603
|
-
|
|
1604
|
-
|
|
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(
|
|
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(
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
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(
|
|
1657
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
1658
|
-
|
|
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(
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
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(
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
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(
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
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(
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
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(
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
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(
|
|
1786
|
-
|
|
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(
|
|
1792
|
-
|
|
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(
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
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
|
-
|
|
2200
|
+
MediaRoute as component
|
|
1832
2201
|
};
|