convex-cms 0.0.2 → 0.0.3

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 (265) hide show
  1. package/admin-dist/nitro.json +15 -0
  2. package/admin-dist/public/assets/CmsEmptyState-CRswfTzk.js +5 -0
  3. package/admin-dist/public/assets/CmsPageHeader-CirpXndm.js +1 -0
  4. package/admin-dist/public/assets/CmsStatusBadge-CbEUpQu-.js +1 -0
  5. package/admin-dist/public/assets/CmsToolbar-BI2nZOXp.js +1 -0
  6. package/admin-dist/public/assets/ContentEntryEditor-CBeCyK_m.js +4 -0
  7. package/admin-dist/public/assets/ErrorState-BIVaWmom.js +1 -0
  8. package/admin-dist/public/assets/TaxonomyFilter-ChaY6Y_x.js +1 -0
  9. package/admin-dist/public/assets/_contentTypeId-DQ8k_Rvw.js +1 -0
  10. package/admin-dist/public/assets/_entryId-CKU_glsK.js +1 -0
  11. package/admin-dist/public/assets/alert-BXjTqrwQ.js +1 -0
  12. package/admin-dist/public/assets/badge-hvUOzpVZ.js +1 -0
  13. package/admin-dist/public/assets/circle-check-big-CF_pR17r.js +1 -0
  14. package/admin-dist/public/assets/command-DU82cJlt.js +1 -0
  15. package/admin-dist/public/assets/content-_LXl3pp7.js +1 -0
  16. package/admin-dist/public/assets/content-types-KjxaXGxY.js +2 -0
  17. package/admin-dist/public/assets/globals-CS6BZ0zp.css +1 -0
  18. package/admin-dist/public/assets/index-DNGIZHL-.js +1 -0
  19. package/admin-dist/public/assets/label-KNtpL71g.js +1 -0
  20. package/admin-dist/public/assets/link-2-Bw2aI4V4.js +1 -0
  21. package/admin-dist/public/assets/list-sYepHjt_.js +1 -0
  22. package/admin-dist/public/assets/main-CKj5yfEi.js +97 -0
  23. package/admin-dist/public/assets/media-Bkrkffm7.js +1 -0
  24. package/admin-dist/public/assets/new._contentTypeId-C3LstjNs.js +1 -0
  25. package/admin-dist/public/assets/plus-DUn8v_Xf.js +1 -0
  26. package/admin-dist/public/assets/rotate-ccw-DJEoHcRI.js +1 -0
  27. package/admin-dist/public/assets/scroll-area-DfIlT0in.js +1 -0
  28. package/admin-dist/public/assets/search-MuAUDJKR.js +1 -0
  29. package/admin-dist/public/assets/select-BD29IXCI.js +1 -0
  30. package/admin-dist/public/assets/settings-DmMyn_6A.js +1 -0
  31. package/admin-dist/public/assets/switch-h3Rrnl5i.js +1 -0
  32. package/admin-dist/public/assets/tabs-imc8h-Dp.js +1 -0
  33. package/admin-dist/public/assets/taxonomies-dAsrT65H.js +1 -0
  34. package/admin-dist/public/assets/textarea-BTy7nwzR.js +1 -0
  35. package/admin-dist/public/assets/trash-SAWKZZHv.js +1 -0
  36. package/admin-dist/public/assets/triangle-alert-E52Vfeuh.js +1 -0
  37. package/admin-dist/public/assets/useBreadcrumbLabel-BECBMCzM.js +1 -0
  38. package/admin-dist/public/assets/usePermissions-Basjs9BT.js +1 -0
  39. package/admin-dist/public/favicon.ico +0 -0
  40. package/admin-dist/server/_chunks/_libs/@date-fns/tz.mjs +217 -0
  41. package/admin-dist/server/_chunks/_libs/@floating-ui/core.mjs +719 -0
  42. package/admin-dist/server/_chunks/_libs/@floating-ui/dom.mjs +622 -0
  43. package/admin-dist/server/_chunks/_libs/@floating-ui/react-dom.mjs +292 -0
  44. package/admin-dist/server/_chunks/_libs/@floating-ui/utils.mjs +320 -0
  45. package/admin-dist/server/_chunks/_libs/@radix-ui/number.mjs +6 -0
  46. package/admin-dist/server/_chunks/_libs/@radix-ui/primitive.mjs +11 -0
  47. package/admin-dist/server/_chunks/_libs/@radix-ui/react-arrow.mjs +23 -0
  48. package/admin-dist/server/_chunks/_libs/@radix-ui/react-avatar.mjs +119 -0
  49. package/admin-dist/server/_chunks/_libs/@radix-ui/react-checkbox.mjs +270 -0
  50. package/admin-dist/server/_chunks/_libs/@radix-ui/react-collection.mjs +69 -0
  51. package/admin-dist/server/_chunks/_libs/@radix-ui/react-compose-refs.mjs +39 -0
  52. package/admin-dist/server/_chunks/_libs/@radix-ui/react-context.mjs +137 -0
  53. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dialog.mjs +325 -0
  54. package/admin-dist/server/_chunks/_libs/@radix-ui/react-direction.mjs +9 -0
  55. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dismissable-layer.mjs +210 -0
  56. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dropdown-menu.mjs +253 -0
  57. package/admin-dist/server/_chunks/_libs/@radix-ui/react-focus-guards.mjs +29 -0
  58. package/admin-dist/server/_chunks/_libs/@radix-ui/react-focus-scope.mjs +206 -0
  59. package/admin-dist/server/_chunks/_libs/@radix-ui/react-id.mjs +14 -0
  60. package/admin-dist/server/_chunks/_libs/@radix-ui/react-label.mjs +23 -0
  61. package/admin-dist/server/_chunks/_libs/@radix-ui/react-menu.mjs +812 -0
  62. package/admin-dist/server/_chunks/_libs/@radix-ui/react-popover.mjs +300 -0
  63. package/admin-dist/server/_chunks/_libs/@radix-ui/react-popper.mjs +286 -0
  64. package/admin-dist/server/_chunks/_libs/@radix-ui/react-portal.mjs +16 -0
  65. package/admin-dist/server/_chunks/_libs/@radix-ui/react-presence.mjs +128 -0
  66. package/admin-dist/server/_chunks/_libs/@radix-ui/react-primitive.mjs +141 -0
  67. package/admin-dist/server/_chunks/_libs/@radix-ui/react-roving-focus.mjs +224 -0
  68. package/admin-dist/server/_chunks/_libs/@radix-ui/react-scroll-area.mjs +721 -0
  69. package/admin-dist/server/_chunks/_libs/@radix-ui/react-select.mjs +1163 -0
  70. package/admin-dist/server/_chunks/_libs/@radix-ui/react-separator.mjs +28 -0
  71. package/admin-dist/server/_chunks/_libs/@radix-ui/react-slot.mjs +601 -0
  72. package/admin-dist/server/_chunks/_libs/@radix-ui/react-switch.mjs +152 -0
  73. package/admin-dist/server/_chunks/_libs/@radix-ui/react-tabs.mjs +189 -0
  74. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-callback-ref.mjs +11 -0
  75. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-controllable-state.mjs +69 -0
  76. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-effect-event.mjs +1 -0
  77. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-escape-keydown.mjs +17 -0
  78. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-is-hydrated.mjs +15 -0
  79. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-layout-effect.mjs +6 -0
  80. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-previous.mjs +14 -0
  81. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-size.mjs +39 -0
  82. package/admin-dist/server/_chunks/_libs/@radix-ui/react-visually-hidden.mjs +33 -0
  83. package/admin-dist/server/_chunks/_libs/@tanstack/history.mjs +409 -0
  84. package/admin-dist/server/_chunks/_libs/@tanstack/react-router.mjs +1711 -0
  85. package/admin-dist/server/_chunks/_libs/@tanstack/react-store.mjs +56 -0
  86. package/admin-dist/server/_chunks/_libs/@tanstack/router-core.mjs +4829 -0
  87. package/admin-dist/server/_chunks/_libs/@tanstack/store.mjs +134 -0
  88. package/admin-dist/server/_chunks/_libs/react-dom.mjs +10781 -0
  89. package/admin-dist/server/_chunks/_libs/react.mjs +513 -0
  90. package/admin-dist/server/_libs/aria-hidden.mjs +122 -0
  91. package/admin-dist/server/_libs/class-variance-authority.mjs +44 -0
  92. package/admin-dist/server/_libs/clsx.mjs +16 -0
  93. package/admin-dist/server/_libs/cmdk.mjs +315 -0
  94. package/admin-dist/server/_libs/convex.mjs +4841 -0
  95. package/admin-dist/server/_libs/cookie-es.mjs +58 -0
  96. package/admin-dist/server/_libs/croner.mjs +1 -0
  97. package/admin-dist/server/_libs/crossws.mjs +1 -0
  98. package/admin-dist/server/_libs/date-fns.mjs +1716 -0
  99. package/admin-dist/server/_libs/detect-node-es.mjs +1 -0
  100. package/admin-dist/server/_libs/get-nonce.mjs +9 -0
  101. package/admin-dist/server/_libs/h3-v2.mjs +277 -0
  102. package/admin-dist/server/_libs/h3.mjs +401 -0
  103. package/admin-dist/server/_libs/hookable.mjs +1 -0
  104. package/admin-dist/server/_libs/isbot.mjs +20 -0
  105. package/admin-dist/server/_libs/lucide-react.mjs +850 -0
  106. package/admin-dist/server/_libs/ohash.mjs +1 -0
  107. package/admin-dist/server/_libs/react-day-picker.mjs +2201 -0
  108. package/admin-dist/server/_libs/react-remove-scroll-bar.mjs +82 -0
  109. package/admin-dist/server/_libs/react-remove-scroll.mjs +328 -0
  110. package/admin-dist/server/_libs/react-style-singleton.mjs +69 -0
  111. package/admin-dist/server/_libs/rou3.mjs +8 -0
  112. package/admin-dist/server/_libs/seroval-plugins.mjs +58 -0
  113. package/admin-dist/server/_libs/seroval.mjs +1765 -0
  114. package/admin-dist/server/_libs/srvx.mjs +719 -0
  115. package/admin-dist/server/_libs/tailwind-merge.mjs +3010 -0
  116. package/admin-dist/server/_libs/tiny-invariant.mjs +12 -0
  117. package/admin-dist/server/_libs/tiny-warning.mjs +5 -0
  118. package/admin-dist/server/_libs/tslib.mjs +39 -0
  119. package/admin-dist/server/_libs/ufo.mjs +54 -0
  120. package/admin-dist/server/_libs/unctx.mjs +1 -0
  121. package/admin-dist/server/_libs/unstorage.mjs +1 -0
  122. package/admin-dist/server/_libs/use-callback-ref.mjs +66 -0
  123. package/admin-dist/server/_libs/use-sidecar.mjs +106 -0
  124. package/admin-dist/server/_libs/use-sync-external-store.mjs +139 -0
  125. package/admin-dist/server/_libs/zod.mjs +4223 -0
  126. package/admin-dist/server/_ssr/CmsEmptyState-DU7-7-mV.mjs +290 -0
  127. package/admin-dist/server/_ssr/CmsPageHeader-CseW0AHm.mjs +24 -0
  128. package/admin-dist/server/_ssr/CmsStatusBadge-B_pi4KCp.mjs +127 -0
  129. package/admin-dist/server/_ssr/CmsToolbar-X75ex6ek.mjs +49 -0
  130. package/admin-dist/server/_ssr/ContentEntryEditor-CepusRsA.mjs +3720 -0
  131. package/admin-dist/server/_ssr/ErrorState-cI-bKLez.mjs +89 -0
  132. package/admin-dist/server/_ssr/TaxonomyFilter-Bwrq0-cz.mjs +188 -0
  133. package/admin-dist/server/_ssr/_contentTypeId-BqYKEcLr.mjs +379 -0
  134. package/admin-dist/server/_ssr/_entryId-CRfnqeDf.mjs +161 -0
  135. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-BwDlABVk.mjs +4 -0
  136. package/admin-dist/server/_ssr/alert-CVt45UUP.mjs +92 -0
  137. package/admin-dist/server/_ssr/badge-6BsP37vG.mjs +125 -0
  138. package/admin-dist/server/_ssr/command-fy8epIKf.mjs +128 -0
  139. package/admin-dist/server/_ssr/config.server-D7JHDcDv.mjs +117 -0
  140. package/admin-dist/server/_ssr/content-B5RhL7uW.mjs +532 -0
  141. package/admin-dist/server/_ssr/content-types-BIOqCQYN.mjs +1166 -0
  142. package/admin-dist/server/_ssr/index-DHSHDPt1.mjs +193 -0
  143. package/admin-dist/server/_ssr/index.mjs +1275 -0
  144. package/admin-dist/server/_ssr/label-C8Dko1j7.mjs +22 -0
  145. package/admin-dist/server/_ssr/media-CSx3XttC.mjs +1832 -0
  146. package/admin-dist/server/_ssr/new._contentTypeId-DzanEZQM.mjs +144 -0
  147. package/admin-dist/server/_ssr/router-DDWcF-kt.mjs +1556 -0
  148. package/admin-dist/server/_ssr/scroll-area-bjPYwhXN.mjs +59 -0
  149. package/admin-dist/server/_ssr/select-BUhDDf4T.mjs +142 -0
  150. package/admin-dist/server/_ssr/settings-DAsxnw2q.mjs +348 -0
  151. package/admin-dist/server/_ssr/start-HYkvq4Ni.mjs +4 -0
  152. package/admin-dist/server/_ssr/switch-BgyRtQ1Z.mjs +31 -0
  153. package/admin-dist/server/_ssr/tabs-DzMdRB1A.mjs +628 -0
  154. package/admin-dist/server/_ssr/taxonomies-C8j8g5Q5.mjs +915 -0
  155. package/admin-dist/server/_ssr/textarea-9jNeYJSc.mjs +18 -0
  156. package/admin-dist/server/_ssr/trash-DYMxwhZB.mjs +291 -0
  157. package/admin-dist/server/_ssr/useBreadcrumbLabel-FNSAr2Ha.mjs +16 -0
  158. package/admin-dist/server/_ssr/usePermissions-BJGGahrJ.mjs +68 -0
  159. package/admin-dist/server/favicon.ico +0 -0
  160. package/admin-dist/server/index.mjs +627 -0
  161. package/dist/cli/index.js +0 -0
  162. package/dist/client/admin-config.d.ts +0 -1
  163. package/dist/client/admin-config.d.ts.map +1 -1
  164. package/dist/client/admin-config.js +0 -1
  165. package/dist/client/admin-config.js.map +1 -1
  166. package/dist/client/adminApi.d.ts.map +1 -1
  167. package/dist/client/agentTools.d.ts +1237 -135
  168. package/dist/client/agentTools.d.ts.map +1 -1
  169. package/dist/client/agentTools.js +33 -9
  170. package/dist/client/agentTools.js.map +1 -1
  171. package/dist/client/index.d.ts +1 -1
  172. package/dist/client/index.d.ts.map +1 -1
  173. package/dist/client/index.js.map +1 -1
  174. package/dist/component/_generated/component.d.ts +9 -0
  175. package/dist/component/_generated/component.d.ts.map +1 -1
  176. package/dist/component/mediaAssets.d.ts +35 -0
  177. package/dist/component/mediaAssets.d.ts.map +1 -1
  178. package/dist/component/mediaAssets.js +81 -0
  179. package/dist/component/mediaAssets.js.map +1 -1
  180. package/dist/test.d.ts.map +1 -1
  181. package/dist/test.js +2 -1
  182. package/dist/test.js.map +1 -1
  183. package/package.json +9 -5
  184. package/dist/component/auditLog.d.ts +0 -410
  185. package/dist/component/auditLog.d.ts.map +0 -1
  186. package/dist/component/auditLog.js +0 -607
  187. package/dist/component/auditLog.js.map +0 -1
  188. package/dist/component/types.d.ts +0 -4
  189. package/dist/component/types.d.ts.map +0 -1
  190. package/dist/component/types.js +0 -2
  191. package/dist/component/types.js.map +0 -1
  192. package/src/cli/commands/admin.ts +0 -104
  193. package/src/cli/index.ts +0 -21
  194. package/src/cli/utils/detectConvexUrl.ts +0 -54
  195. package/src/cli/utils/openBrowser.ts +0 -16
  196. package/src/client/admin-config.ts +0 -138
  197. package/src/client/adminApi.ts +0 -942
  198. package/src/client/agentTools.ts +0 -1311
  199. package/src/client/argTypes.ts +0 -316
  200. package/src/client/field-types.ts +0 -187
  201. package/src/client/index.ts +0 -1301
  202. package/src/client/queryBuilder.ts +0 -1100
  203. package/src/client/schema/codegen.ts +0 -500
  204. package/src/client/schema/defineContentType.ts +0 -501
  205. package/src/client/schema/index.ts +0 -169
  206. package/src/client/schema/schemaDrift.ts +0 -574
  207. package/src/client/schema/typedClient.ts +0 -688
  208. package/src/client/schema/types.ts +0 -666
  209. package/src/client/types.ts +0 -723
  210. package/src/client/workflows.ts +0 -141
  211. package/src/client/wrapper.ts +0 -4304
  212. package/src/component/_generated/api.ts +0 -140
  213. package/src/component/_generated/component.ts +0 -5029
  214. package/src/component/_generated/dataModel.ts +0 -60
  215. package/src/component/_generated/server.ts +0 -156
  216. package/src/component/authorization.ts +0 -647
  217. package/src/component/authorizationHooks.ts +0 -668
  218. package/src/component/bulkOperations.ts +0 -687
  219. package/src/component/contentEntries.ts +0 -1976
  220. package/src/component/contentEntryMutations.ts +0 -1223
  221. package/src/component/contentEntryValidation.ts +0 -707
  222. package/src/component/contentLock.ts +0 -550
  223. package/src/component/contentTypeMigration.ts +0 -1064
  224. package/src/component/contentTypeMutations.ts +0 -969
  225. package/src/component/contentTypes.ts +0 -346
  226. package/src/component/convex.config.ts +0 -44
  227. package/src/component/documentTypes.ts +0 -240
  228. package/src/component/eventEmitter.ts +0 -485
  229. package/src/component/exportImport.ts +0 -1169
  230. package/src/component/index.ts +0 -491
  231. package/src/component/lib/deepReferenceResolver.ts +0 -999
  232. package/src/component/lib/errors.ts +0 -816
  233. package/src/component/lib/index.ts +0 -145
  234. package/src/component/lib/mediaReferenceResolver.ts +0 -495
  235. package/src/component/lib/metadataExtractor.ts +0 -792
  236. package/src/component/lib/mutationAuth.ts +0 -199
  237. package/src/component/lib/queries.ts +0 -79
  238. package/src/component/lib/ragContentChunker.ts +0 -1371
  239. package/src/component/lib/referenceResolver.ts +0 -430
  240. package/src/component/lib/slugGenerator.ts +0 -262
  241. package/src/component/lib/slugUniqueness.ts +0 -333
  242. package/src/component/lib/softDelete.ts +0 -44
  243. package/src/component/localeFallbackChain.ts +0 -673
  244. package/src/component/localeFields.ts +0 -896
  245. package/src/component/mediaAssetMutations.ts +0 -725
  246. package/src/component/mediaAssets.ts +0 -932
  247. package/src/component/mediaFolderMutations.ts +0 -1046
  248. package/src/component/mediaUploadMutations.ts +0 -224
  249. package/src/component/mediaVariantMutations.ts +0 -900
  250. package/src/component/mediaVariants.ts +0 -793
  251. package/src/component/ragContentIndexer.ts +0 -1067
  252. package/src/component/rateLimitHooks.ts +0 -572
  253. package/src/component/roles.ts +0 -1360
  254. package/src/component/scheduledPublish.ts +0 -358
  255. package/src/component/schema.ts +0 -617
  256. package/src/component/taxonomies.ts +0 -949
  257. package/src/component/taxonomyMutations.ts +0 -1210
  258. package/src/component/trash.ts +0 -724
  259. package/src/component/userContext.ts +0 -898
  260. package/src/component/validation.ts +0 -1388
  261. package/src/component/validators.ts +0 -949
  262. package/src/component/versionMutations.ts +0 -392
  263. package/src/component/webhookTrigger.ts +0 -1922
  264. package/src/react/index.ts +0 -898
  265. package/src/test.ts +0 -1580
@@ -0,0 +1,1832 @@
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-DDWcF-kt.mjs";
4
+ import { T as Tabs, a as TabsList, b as TabsTrigger, U as UploadDropzone } from "./tabs-DzMdRB1A.mjs";
5
+ import { C as CmsPageHeader } from "./CmsPageHeader-CseW0AHm.mjs";
6
+ import { C as CmsToolbar } from "./CmsToolbar-X75ex6ek.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-DU7-7-mV.mjs";
8
+ import { B as Badge, C as CmsButton } from "./badge-6BsP37vG.mjs";
9
+ import { T as TaxonomyFilter } from "./TaxonomyFilter-Bwrq0-cz.mjs";
10
+ import { L as Label } from "./label-C8Dko1j7.mjs";
11
+ import { S as Select, a as SelectTrigger, b as SelectValue, c as SelectContent, d as SelectItem } from "./select-BUhDDf4T.mjs";
12
+ import { a as VisuallyHidden } from "../_chunks/_libs/@radix-ui/react-visually-hidden.mjs";
13
+ import { T as Textarea } from "./textarea-9jNeYJSc.mjs";
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";
16
+ import "../_libs/tiny-warning.mjs";
17
+ import "../_chunks/_libs/@tanstack/router-core.mjs";
18
+ import "../_libs/cookie-es.mjs";
19
+ import "../_chunks/_libs/@tanstack/store.mjs";
20
+ import "../_chunks/_libs/@tanstack/history.mjs";
21
+ import "../_libs/tiny-invariant.mjs";
22
+ import "../_libs/seroval.mjs";
23
+ import "../_libs/seroval-plugins.mjs";
24
+ import "node:stream/web";
25
+ import "node:stream";
26
+ import "../_chunks/_libs/react-dom.mjs";
27
+ import "util";
28
+ import "crypto";
29
+ import "async_hooks";
30
+ import "stream";
31
+ import "../_libs/isbot.mjs";
32
+ import "../_chunks/_libs/@tanstack/react-store.mjs";
33
+ import "../_libs/use-sync-external-store.mjs";
34
+ import "../_libs/clsx.mjs";
35
+ 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";
39
+ import "../_chunks/_libs/@radix-ui/primitive.mjs";
40
+ import "../_chunks/_libs/@radix-ui/react-context.mjs";
41
+ import "../_chunks/_libs/@radix-ui/react-use-controllable-state.mjs";
42
+ import "../_chunks/_libs/@radix-ui/react-use-layout-effect.mjs";
43
+ import "../_chunks/_libs/@radix-ui/react-primitive.mjs";
44
+ import "../_chunks/_libs/@radix-ui/react-menu.mjs";
45
+ import "../_chunks/_libs/@radix-ui/react-collection.mjs";
46
+ import "../_chunks/_libs/@radix-ui/react-direction.mjs";
47
+ import "../_chunks/_libs/@radix-ui/react-dismissable-layer.mjs";
48
+ import "../_chunks/_libs/@radix-ui/react-use-callback-ref.mjs";
49
+ import "../_chunks/_libs/@radix-ui/react-use-escape-keydown.mjs";
50
+ import "../_chunks/_libs/@radix-ui/react-focus-guards.mjs";
51
+ import "../_chunks/_libs/@radix-ui/react-focus-scope.mjs";
52
+ import "../_chunks/_libs/@radix-ui/react-popper.mjs";
53
+ import "../_chunks/_libs/@floating-ui/react-dom.mjs";
54
+ import "../_chunks/_libs/@floating-ui/dom.mjs";
55
+ import "../_chunks/_libs/@floating-ui/core.mjs";
56
+ import "../_chunks/_libs/@floating-ui/utils.mjs";
57
+ import "../_chunks/_libs/@radix-ui/react-arrow.mjs";
58
+ import "../_chunks/_libs/@radix-ui/react-use-size.mjs";
59
+ import "../_chunks/_libs/@radix-ui/react-portal.mjs";
60
+ import "../_chunks/_libs/@radix-ui/react-presence.mjs";
61
+ import "../_chunks/_libs/@radix-ui/react-roving-focus.mjs";
62
+ import "../_chunks/_libs/@radix-ui/react-id.mjs";
63
+ import "../_libs/aria-hidden.mjs";
64
+ import "../_libs/react-remove-scroll.mjs";
65
+ import "../_libs/tslib.mjs";
66
+ import "../_libs/react-remove-scroll-bar.mjs";
67
+ import "../_libs/react-style-singleton.mjs";
68
+ import "../_libs/get-nonce.mjs";
69
+ import "../_libs/use-sidecar.mjs";
70
+ import "../_libs/use-callback-ref.mjs";
71
+ import "../_chunks/_libs/@radix-ui/react-avatar.mjs";
72
+ import "../_chunks/_libs/@radix-ui/react-use-is-hydrated.mjs";
73
+ import "../_libs/class-variance-authority.mjs";
74
+ import "../_chunks/_libs/@radix-ui/react-popover.mjs";
75
+ import "./index.mjs";
76
+ import "node:async_hooks";
77
+ import "../_libs/h3-v2.mjs";
78
+ import "../_libs/rou3.mjs";
79
+ import "../_libs/srvx.mjs";
80
+ import "node:http";
81
+ import "node:https";
82
+ import "node:http2";
83
+ import "../_libs/zod.mjs";
84
+ import "../_chunks/_libs/@radix-ui/react-tabs.mjs";
85
+ import "../_chunks/_libs/@radix-ui/react-dialog.mjs";
86
+ import "../_chunks/_libs/@radix-ui/react-checkbox.mjs";
87
+ import "../_chunks/_libs/@radix-ui/react-use-previous.mjs";
88
+ import "./command-fy8epIKf.mjs";
89
+ import "../_libs/cmdk.mjs";
90
+ import "../_chunks/_libs/@radix-ui/react-label.mjs";
91
+ import "../_chunks/_libs/@radix-ui/react-select.mjs";
92
+ import "../_chunks/_libs/@radix-ui/number.mjs";
93
+ function getMediaTypeFromMimeType$1(mimeType) {
94
+ if (!mimeType) return "other";
95
+ if (mimeType.startsWith("image/")) return "image";
96
+ if (mimeType.startsWith("video/")) return "video";
97
+ if (mimeType.startsWith("audio/")) return "audio";
98
+ if (mimeType === "application/pdf" || mimeType.includes("document") || mimeType.includes("sheet") || mimeType.includes("presentation") || mimeType.startsWith("text/")) {
99
+ return "document";
100
+ }
101
+ return "other";
102
+ }
103
+ function formatFileSize$1(bytes) {
104
+ if (!bytes || bytes === 0) return "0 B";
105
+ const k = 1024;
106
+ const sizes = ["B", "KB", "MB", "GB"];
107
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
108
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
109
+ }
110
+ function formatDate$1(timestamp) {
111
+ return new Date(timestamp).toLocaleDateString("en-US", {
112
+ month: "short",
113
+ day: "numeric",
114
+ year: "numeric",
115
+ hour: "numeric",
116
+ minute: "2-digit"
117
+ });
118
+ }
119
+ function getMediaTypeIcon$1(type, className = "size-16") {
120
+ const iconProps = { className };
121
+ switch (type) {
122
+ case "image":
123
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { ...iconProps });
124
+ case "video":
125
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Video, { ...iconProps });
126
+ case "audio":
127
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Music, { ...iconProps });
128
+ case "document":
129
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { ...iconProps });
130
+ default:
131
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(File, { ...iconProps });
132
+ }
133
+ }
134
+ function MediaPreviewModal({
135
+ asset,
136
+ assets,
137
+ currentIndex,
138
+ open,
139
+ onOpenChange,
140
+ onNavigate,
141
+ onEdit,
142
+ onDelete
143
+ }) {
144
+ const canNavigatePrev = currentIndex > 0;
145
+ const canNavigateNext = currentIndex < assets.length - 1;
146
+ const handlePrev = reactExports.useCallback(() => {
147
+ if (canNavigatePrev) {
148
+ onNavigate(currentIndex - 1);
149
+ }
150
+ }, [canNavigatePrev, currentIndex, onNavigate]);
151
+ const handleNext = reactExports.useCallback(() => {
152
+ if (canNavigateNext) {
153
+ onNavigate(currentIndex + 1);
154
+ }
155
+ }, [canNavigateNext, currentIndex, onNavigate]);
156
+ const handleKeyDown = reactExports.useCallback(
157
+ (e) => {
158
+ if (!open) return;
159
+ switch (e.key) {
160
+ case "ArrowLeft":
161
+ e.preventDefault();
162
+ handlePrev();
163
+ break;
164
+ case "ArrowRight":
165
+ e.preventDefault();
166
+ handleNext();
167
+ break;
168
+ case "Escape":
169
+ e.preventDefault();
170
+ onOpenChange(false);
171
+ break;
172
+ }
173
+ },
174
+ [open, handlePrev, handleNext, onOpenChange]
175
+ );
176
+ reactExports.useEffect(() => {
177
+ window.addEventListener("keydown", handleKeyDown);
178
+ return () => window.removeEventListener("keydown", handleKeyDown);
179
+ }, [handleKeyDown]);
180
+ const handleDownload = reactExports.useCallback(() => {
181
+ if (!asset?.url) return;
182
+ const link = document.createElement("a");
183
+ link.href = asset.url;
184
+ link.download = asset.name;
185
+ link.target = "_blank";
186
+ document.body.appendChild(link);
187
+ link.click();
188
+ document.body.removeChild(link);
189
+ }, [asset]);
190
+ const handleCopyUrl = reactExports.useCallback(async () => {
191
+ if (!asset?.url) return;
192
+ await navigator.clipboard.writeText(asset.url);
193
+ }, [asset]);
194
+ if (!asset) return null;
195
+ const mediaType = getMediaTypeFromMimeType$1(asset.mimeType);
196
+ const isImage = mediaType === "image";
197
+ const hasUrl = Boolean(asset.url);
198
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
199
+ DialogContent,
200
+ {
201
+ className: "flex h-[90vh] w-[95vw] max-w-[1400px] flex-col gap-0 overflow-hidden p-0 sm:max-w-[1400px]",
202
+ showCloseButton: false,
203
+ children: [
204
+ /* @__PURE__ */ jsxRuntimeExports.jsx(VisuallyHidden, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { children: [
205
+ "Preview: ",
206
+ asset.name
207
+ ] }) }),
208
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between border-b px-4 py-3", children: [
209
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
210
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "truncate text-lg font-semibold", title: asset.name, children: asset.name }),
211
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-muted-foreground", children: [
212
+ currentIndex + 1,
213
+ " of ",
214
+ assets.length
215
+ ] })
216
+ ] }),
217
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
218
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
219
+ CmsButton,
220
+ {
221
+ variant: "ghost",
222
+ size: "icon",
223
+ onClick: handleCopyUrl,
224
+ disabled: !asset.url,
225
+ title: "Copy URL",
226
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-4" })
227
+ }
228
+ ),
229
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
230
+ CmsButton,
231
+ {
232
+ variant: "ghost",
233
+ size: "icon",
234
+ onClick: handleDownload,
235
+ disabled: !asset.url,
236
+ title: "Download",
237
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "size-4" })
238
+ }
239
+ ),
240
+ onEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
241
+ CmsButton,
242
+ {
243
+ variant: "ghost",
244
+ size: "icon",
245
+ onClick: () => onEdit(asset),
246
+ title: "Edit",
247
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-4" })
248
+ }
249
+ ),
250
+ onDelete && /* @__PURE__ */ jsxRuntimeExports.jsx(
251
+ CmsButton,
252
+ {
253
+ variant: "ghost",
254
+ size: "icon",
255
+ onClick: () => onDelete(asset),
256
+ title: "Delete",
257
+ className: "text-destructive hover:text-destructive",
258
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4" })
259
+ }
260
+ ),
261
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
262
+ CmsButton,
263
+ {
264
+ variant: "ghost",
265
+ size: "icon",
266
+ onClick: () => onOpenChange(false),
267
+ title: "Close (Esc)",
268
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-4" })
269
+ }
270
+ )
271
+ ] })
272
+ ] }),
273
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-h-0 flex-1", children: [
274
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex flex-1 items-center justify-center bg-zinc-950", children: [
275
+ canNavigatePrev && /* @__PURE__ */ jsxRuntimeExports.jsx(
276
+ "button",
277
+ {
278
+ onClick: handlePrev,
279
+ className: "absolute left-4 z-10 flex size-10 items-center justify-center rounded-full bg-black/50 text-white transition-colors hover:bg-black/70",
280
+ title: "Previous (←)",
281
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { className: "size-6" })
282
+ }
283
+ ),
284
+ canNavigateNext && /* @__PURE__ */ jsxRuntimeExports.jsx(
285
+ "button",
286
+ {
287
+ onClick: handleNext,
288
+ className: "absolute right-4 z-10 flex size-10 items-center justify-center rounded-full bg-black/50 text-white transition-colors hover:bg-black/70",
289
+ title: "Next (→)",
290
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-6" })
291
+ }
292
+ ),
293
+ isImage && hasUrl ? /* @__PURE__ */ jsxRuntimeExports.jsx(
294
+ "img",
295
+ {
296
+ src: asset.url,
297
+ alt: asset.altText || asset.title || asset.name,
298
+ className: "max-h-full max-w-full object-contain"
299
+ }
300
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-4 text-zinc-400", children: [
301
+ getMediaTypeIcon$1(mediaType),
302
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: isImage && !hasUrl ? "Image URL not available" : "Preview not available for this file type" }),
303
+ hasUrl && /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { variant: "secondary", onClick: handleDownload, children: [
304
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "mr-2 size-4" }),
305
+ "Download to view"
306
+ ] })
307
+ ] })
308
+ ] }),
309
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-72 shrink-0 overflow-y-auto border-l bg-background", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 p-4", children: [
310
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold", children: "File Information" }),
311
+ /* @__PURE__ */ jsxRuntimeExports.jsx(InfoRow, { label: "Filename", value: asset.name }),
312
+ asset.title && /* @__PURE__ */ jsxRuntimeExports.jsx(InfoRow, { label: "Title", value: asset.title }),
313
+ asset.description && /* @__PURE__ */ jsxRuntimeExports.jsx(InfoRow, { label: "Description", value: asset.description }),
314
+ asset.altText && /* @__PURE__ */ jsxRuntimeExports.jsx(InfoRow, { label: "Alt Text", value: asset.altText }),
315
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t pt-4", children: [
316
+ /* @__PURE__ */ jsxRuntimeExports.jsx(InfoRow, { label: "Type", value: mediaType, capitalize: true }),
317
+ asset.mimeType && /* @__PURE__ */ jsxRuntimeExports.jsx(InfoRow, { label: "MIME Type", value: asset.mimeType }),
318
+ /* @__PURE__ */ jsxRuntimeExports.jsx(InfoRow, { label: "Size", value: formatFileSize$1(asset.size) }),
319
+ asset.width && asset.height && /* @__PURE__ */ jsxRuntimeExports.jsx(
320
+ InfoRow,
321
+ {
322
+ label: "Dimensions",
323
+ value: `${asset.width} × ${asset.height} px`
324
+ }
325
+ )
326
+ ] }),
327
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t pt-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(InfoRow, { label: "Uploaded", value: formatDate$1(asset._creationTime) }) }),
328
+ asset.tags && asset.tags.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t pt-4", children: [
329
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mb-2 text-xs font-medium text-muted-foreground", children: "Tags" }),
330
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1", children: asset.tags.map((tag) => /* @__PURE__ */ jsxRuntimeExports.jsx(
331
+ "span",
332
+ {
333
+ className: "rounded-full bg-muted px-2 py-0.5 text-xs",
334
+ children: tag
335
+ },
336
+ tag
337
+ )) })
338
+ ] })
339
+ ] }) })
340
+ ] })
341
+ ]
342
+ }
343
+ ) });
344
+ }
345
+ function InfoRow({
346
+ label,
347
+ value,
348
+ capitalize
349
+ }) {
350
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-0.5", children: [
351
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-medium text-muted-foreground", children: label }),
352
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: cn("break-words text-sm", capitalize && "capitalize"), children: value })
353
+ ] });
354
+ }
355
+ function CmsField({
356
+ label,
357
+ description,
358
+ error,
359
+ required,
360
+ htmlFor,
361
+ className,
362
+ children
363
+ }) {
364
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("space-y-2", className), children: [
365
+ label && /* @__PURE__ */ jsxRuntimeExports.jsxs(
366
+ Label,
367
+ {
368
+ htmlFor,
369
+ className: cn(
370
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
371
+ error && "text-destructive"
372
+ ),
373
+ children: [
374
+ label,
375
+ required && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-1 text-destructive", children: "*" })
376
+ ]
377
+ }
378
+ ),
379
+ children,
380
+ description && !error && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[13px] text-muted-foreground", children: description }),
381
+ error && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[13px] font-medium text-destructive", children: error })
382
+ ] });
383
+ }
384
+ function MediaTaxonomyPicker({
385
+ mediaId,
386
+ taxonomyId,
387
+ taxonomyName = "Tags",
388
+ allowCreate = true,
389
+ disabled = false,
390
+ className = ""
391
+ }) {
392
+ const [inputValue, setInputValue] = reactExports.useState("");
393
+ const [showSuggestions, setShowSuggestions] = reactExports.useState(false);
394
+ const [activeSuggestionIndex, setActiveSuggestionIndex] = reactExports.useState(0);
395
+ const [isCreating, setIsCreating] = reactExports.useState(false);
396
+ const [isSaving, setIsSaving] = reactExports.useState(false);
397
+ const inputRef = reactExports.useRef(null);
398
+ const suggestionsRef = reactExports.useRef(null);
399
+ const containerRef = reactExports.useRef(null);
400
+ const currentTerms = useQuery(api.taxonomies.getTermsByMedia, {
401
+ mediaId,
402
+ taxonomyId
403
+ });
404
+ const selectedTermIds = currentTerms?.map((t) => t._id) ?? [];
405
+ const suggestionsResult = useQuery(api.taxonomies.suggestTerms, {
406
+ taxonomyId,
407
+ query: inputValue,
408
+ limit: 10,
409
+ excludeIds: selectedTermIds
410
+ });
411
+ const suggestions = suggestionsResult ?? [];
412
+ const setMediaTermsMutation = useMutation(api.taxonomies.setMediaTerms);
413
+ const createTermMutation = useMutation(api.taxonomies.createTermAndAddToMedia);
414
+ reactExports.useEffect(() => {
415
+ function handleClickOutside(event) {
416
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
417
+ setShowSuggestions(false);
418
+ }
419
+ }
420
+ document.addEventListener("mousedown", handleClickOutside);
421
+ return () => document.removeEventListener("mousedown", handleClickOutside);
422
+ }, []);
423
+ const addTag = reactExports.useCallback(
424
+ async (termId) => {
425
+ if (selectedTermIds.includes(termId)) return;
426
+ setIsSaving(true);
427
+ try {
428
+ await setMediaTermsMutation({
429
+ mediaId,
430
+ taxonomyId,
431
+ termIds: [...selectedTermIds, termId]
432
+ });
433
+ } catch (err) {
434
+ console.error("Failed to add tag:", err);
435
+ } finally {
436
+ setIsSaving(false);
437
+ setInputValue("");
438
+ setShowSuggestions(false);
439
+ setActiveSuggestionIndex(0);
440
+ inputRef.current?.focus();
441
+ }
442
+ },
443
+ [mediaId, taxonomyId, selectedTermIds, setMediaTermsMutation]
444
+ );
445
+ const removeTag = reactExports.useCallback(
446
+ async (termId) => {
447
+ setIsSaving(true);
448
+ try {
449
+ await setMediaTermsMutation({
450
+ mediaId,
451
+ taxonomyId,
452
+ termIds: selectedTermIds.filter((id) => id !== termId)
453
+ });
454
+ } catch (err) {
455
+ console.error("Failed to remove tag:", err);
456
+ } finally {
457
+ setIsSaving(false);
458
+ }
459
+ },
460
+ [mediaId, taxonomyId, selectedTermIds, setMediaTermsMutation]
461
+ );
462
+ const createTag = reactExports.useCallback(async () => {
463
+ if (!inputValue.trim() || !allowCreate) return;
464
+ setIsCreating(true);
465
+ try {
466
+ await createTermMutation({
467
+ taxonomyId,
468
+ name: inputValue.trim(),
469
+ mediaId
470
+ });
471
+ setInputValue("");
472
+ setShowSuggestions(false);
473
+ setActiveSuggestionIndex(0);
474
+ } catch (err) {
475
+ console.error("Failed to create tag:", err);
476
+ } finally {
477
+ setIsCreating(false);
478
+ }
479
+ }, [inputValue, allowCreate, taxonomyId, mediaId, createTermMutation]);
480
+ const handleKeyDown = (e) => {
481
+ if (disabled) return;
482
+ switch (e.key) {
483
+ case "ArrowDown":
484
+ e.preventDefault();
485
+ setActiveSuggestionIndex(
486
+ (prev) => prev < suggestions.length - 1 ? prev + 1 : prev
487
+ );
488
+ break;
489
+ case "ArrowUp":
490
+ e.preventDefault();
491
+ setActiveSuggestionIndex((prev) => prev > 0 ? prev - 1 : 0);
492
+ break;
493
+ case "Enter":
494
+ e.preventDefault();
495
+ if (suggestions.length > 0 && activeSuggestionIndex < suggestions.length) {
496
+ addTag(suggestions[activeSuggestionIndex]._id);
497
+ } else if (inputValue.trim() && allowCreate) {
498
+ createTag();
499
+ }
500
+ break;
501
+ case "Escape":
502
+ setShowSuggestions(false);
503
+ break;
504
+ case "Backspace":
505
+ if (inputValue === "" && selectedTermIds.length > 0) {
506
+ removeTag(selectedTermIds[selectedTermIds.length - 1]);
507
+ }
508
+ break;
509
+ }
510
+ };
511
+ reactExports.useEffect(() => {
512
+ if (suggestionsRef.current && showSuggestions) {
513
+ const activeElement = suggestionsRef.current.querySelector(
514
+ `[data-index="${activeSuggestionIndex}"]`
515
+ );
516
+ if (activeElement) {
517
+ activeElement.scrollIntoView({ block: "nearest" });
518
+ }
519
+ }
520
+ }, [activeSuggestionIndex, showSuggestions]);
521
+ const filteredSuggestions = suggestions.filter(
522
+ (term) => !selectedTermIds.includes(term._id)
523
+ );
524
+ const showCreateOption = allowCreate && inputValue.trim() && !filteredSuggestions.some(
525
+ (s) => s.name.toLowerCase() === inputValue.trim().toLowerCase()
526
+ );
527
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("space-y-2", className), children: [
528
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-sm font-medium text-muted-foreground", children: [
529
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Tag, { className: "size-4" }),
530
+ taxonomyName
531
+ ] }),
532
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
533
+ "div",
534
+ {
535
+ ref: containerRef,
536
+ className: cn(
537
+ "relative rounded-md border border-input bg-background",
538
+ disabled && "opacity-50"
539
+ ),
540
+ children: [
541
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-1.5 p-2", children: [
542
+ (currentTerms ?? []).map((term) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
543
+ Badge,
544
+ {
545
+ variant: "secondary",
546
+ className: "gap-1 pr-1",
547
+ style: term.color ? { backgroundColor: term.color, color: "#fff" } : void 0,
548
+ children: [
549
+ term.name,
550
+ !disabled && /* @__PURE__ */ jsxRuntimeExports.jsx(
551
+ Button,
552
+ {
553
+ type: "button",
554
+ variant: "ghost",
555
+ size: "icon",
556
+ className: "size-4 hover:bg-transparent",
557
+ onClick: () => removeTag(term._id),
558
+ disabled: isSaving,
559
+ "aria-label": `Remove ${term.name}`,
560
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-3" })
561
+ }
562
+ )
563
+ ]
564
+ },
565
+ term._id
566
+ )),
567
+ !disabled && /* @__PURE__ */ jsxRuntimeExports.jsx(
568
+ Input,
569
+ {
570
+ ref: inputRef,
571
+ type: "text",
572
+ className: "h-7 min-w-[120px] flex-1 border-0 bg-transparent px-1 shadow-none focus-visible:ring-0",
573
+ value: inputValue,
574
+ onChange: (e) => {
575
+ setInputValue(e.target.value);
576
+ setShowSuggestions(true);
577
+ setActiveSuggestionIndex(0);
578
+ },
579
+ onFocus: () => setShowSuggestions(true),
580
+ onKeyDown: handleKeyDown,
581
+ placeholder: selectedTermIds.length === 0 ? "Add tags..." : "",
582
+ disabled: disabled || isCreating || isSaving
583
+ }
584
+ )
585
+ ] }),
586
+ showSuggestions && (filteredSuggestions.length > 0 || showCreateOption) && /* @__PURE__ */ jsxRuntimeExports.jsxs(
587
+ "div",
588
+ {
589
+ ref: suggestionsRef,
590
+ className: "absolute left-0 right-0 top-full z-50 mt-1 max-h-48 overflow-auto rounded-md border bg-popover shadow-lg",
591
+ role: "listbox",
592
+ children: [
593
+ filteredSuggestions.map((term, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
594
+ "div",
595
+ {
596
+ "data-index": index,
597
+ className: cn(
598
+ "flex cursor-pointer items-center gap-2 px-3 py-2 text-sm",
599
+ index === activeSuggestionIndex && "bg-accent"
600
+ ),
601
+ onClick: () => addTag(term._id),
602
+ role: "option",
603
+ "aria-selected": index === activeSuggestionIndex,
604
+ children: [
605
+ term.color && /* @__PURE__ */ jsxRuntimeExports.jsx(
606
+ "span",
607
+ {
608
+ className: "size-2.5 rounded-full",
609
+ style: { backgroundColor: term.color }
610
+ }
611
+ ),
612
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1", children: term.name }),
613
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-muted-foreground", children: [
614
+ term.usageCount,
615
+ " uses"
616
+ ] })
617
+ ]
618
+ },
619
+ term._id
620
+ )),
621
+ showCreateOption && /* @__PURE__ */ jsxRuntimeExports.jsxs(
622
+ "div",
623
+ {
624
+ "data-index": filteredSuggestions.length,
625
+ className: cn(
626
+ "flex cursor-pointer items-center gap-2 px-3 py-2 text-sm",
627
+ filteredSuggestions.length === activeSuggestionIndex && "bg-accent"
628
+ ),
629
+ onClick: createTag,
630
+ role: "option",
631
+ "aria-selected": filteredSuggestions.length === activeSuggestionIndex,
632
+ children: [
633
+ isCreating ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" }),
634
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
635
+ 'Create "',
636
+ inputValue.trim(),
637
+ '"'
638
+ ] })
639
+ ]
640
+ }
641
+ )
642
+ ]
643
+ }
644
+ ),
645
+ (isSaving || isCreating) && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-background/50", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin" }) })
646
+ ]
647
+ }
648
+ )
649
+ ] });
650
+ }
651
+ function MediaAssetEditDialog({
652
+ asset,
653
+ open,
654
+ onOpenChange,
655
+ onSaved
656
+ }) {
657
+ const [name, setName] = reactExports.useState("");
658
+ const [title, setTitle] = reactExports.useState("");
659
+ const [description, setDescription] = reactExports.useState("");
660
+ const [altText, setAltText] = reactExports.useState("");
661
+ const [tagsInput, setTagsInput] = reactExports.useState("");
662
+ const [isSaving, setIsSaving] = reactExports.useState(false);
663
+ const [error, setError] = reactExports.useState("");
664
+ const updateAsset = useMutation(api.media.updateAsset);
665
+ const taxonomiesResult = useQuery(api.taxonomies.list, {
666
+ isActive: true,
667
+ paginationOpts: { numItems: 50, cursor: null }
668
+ });
669
+ const taxonomies = taxonomiesResult?.page ?? [];
670
+ reactExports.useEffect(() => {
671
+ if (asset) {
672
+ setName(asset.name);
673
+ setTitle(asset.title || "");
674
+ setDescription(asset.description || "");
675
+ setAltText(asset.altText || "");
676
+ setTagsInput(asset.tags?.join(", ") || "");
677
+ setError("");
678
+ }
679
+ }, [asset]);
680
+ const handleSave = reactExports.useCallback(async () => {
681
+ if (!asset) return;
682
+ if (!name.trim()) {
683
+ setError("Filename is required");
684
+ return;
685
+ }
686
+ setIsSaving(true);
687
+ setError("");
688
+ try {
689
+ const tags = tagsInput.split(",").map((t) => t.trim()).filter(Boolean);
690
+ await updateAsset({
691
+ id: asset._id,
692
+ name: name.trim(),
693
+ title: title.trim() || void 0,
694
+ description: description.trim() || void 0,
695
+ altText: altText.trim() || void 0,
696
+ tags: tags.length > 0 ? tags : void 0
697
+ });
698
+ onSaved?.();
699
+ onOpenChange(false);
700
+ } catch (err) {
701
+ setError(err instanceof Error ? err.message : "Failed to update asset");
702
+ } finally {
703
+ setIsSaving(false);
704
+ }
705
+ }, [
706
+ asset,
707
+ name,
708
+ title,
709
+ description,
710
+ altText,
711
+ tagsInput,
712
+ updateAsset,
713
+ onSaved,
714
+ onOpenChange
715
+ ]);
716
+ if (!asset) return null;
717
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
718
+ CmsDialog,
719
+ {
720
+ open,
721
+ onOpenChange,
722
+ title: "Edit File",
723
+ size: "md",
724
+ footer: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
725
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
726
+ CmsButton,
727
+ {
728
+ variant: "outline",
729
+ onClick: () => onOpenChange(false),
730
+ disabled: isSaving,
731
+ children: "Cancel"
732
+ }
733
+ ),
734
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { onClick: handleSave, loading: isSaving, children: "Save Changes" })
735
+ ] }),
736
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
737
+ error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md bg-destructive/10 p-3 text-sm text-destructive", children: error }),
738
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CmsField, { label: "Filename", required: true, htmlFor: "asset-name", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
739
+ Input,
740
+ {
741
+ id: "asset-name",
742
+ value: name,
743
+ onChange: (e) => setName(e.target.value),
744
+ placeholder: "Enter filename"
745
+ }
746
+ ) }),
747
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
748
+ CmsField,
749
+ {
750
+ label: "Title",
751
+ description: "A human-readable title for the file",
752
+ htmlFor: "asset-title",
753
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
754
+ Input,
755
+ {
756
+ id: "asset-title",
757
+ value: title,
758
+ onChange: (e) => setTitle(e.target.value),
759
+ placeholder: "Enter title (optional)"
760
+ }
761
+ )
762
+ }
763
+ ),
764
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
765
+ CmsField,
766
+ {
767
+ label: "Description",
768
+ description: "A brief description of the file",
769
+ htmlFor: "asset-description",
770
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
771
+ Textarea,
772
+ {
773
+ id: "asset-description",
774
+ value: description,
775
+ onChange: (e) => setDescription(e.target.value),
776
+ placeholder: "Enter description (optional)",
777
+ rows: 3
778
+ }
779
+ )
780
+ }
781
+ ),
782
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
783
+ CmsField,
784
+ {
785
+ label: "Alt Text",
786
+ description: "Alternative text for accessibility (important for images)",
787
+ htmlFor: "asset-alt",
788
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
789
+ Input,
790
+ {
791
+ id: "asset-alt",
792
+ value: altText,
793
+ onChange: (e) => setAltText(e.target.value),
794
+ placeholder: "Describe the image content"
795
+ }
796
+ )
797
+ }
798
+ ),
799
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
800
+ CmsField,
801
+ {
802
+ label: "Quick Tags",
803
+ description: "Comma-separated tags for simple organization",
804
+ htmlFor: "asset-tags",
805
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
806
+ Input,
807
+ {
808
+ id: "asset-tags",
809
+ value: tagsInput,
810
+ onChange: (e) => setTagsInput(e.target.value),
811
+ placeholder: "e.g., hero, blog, product"
812
+ }
813
+ )
814
+ }
815
+ ),
816
+ taxonomies.length > 0 && asset && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 pt-2 border-t", children: [
817
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground", children: "Organize with taxonomy terms" }),
818
+ taxonomies.map((taxonomy) => /* @__PURE__ */ jsxRuntimeExports.jsx(
819
+ MediaTaxonomyPicker,
820
+ {
821
+ mediaId: asset._id,
822
+ taxonomyId: taxonomy._id,
823
+ taxonomyName: taxonomy.displayName,
824
+ allowCreate: taxonomy.allowInlineCreation,
825
+ disabled: isSaving
826
+ },
827
+ taxonomy._id
828
+ ))
829
+ ] })
830
+ ] })
831
+ }
832
+ );
833
+ }
834
+ function MediaFolderEditDialog({
835
+ folder,
836
+ open,
837
+ onOpenChange,
838
+ onSaved
839
+ }) {
840
+ const [name, setName] = reactExports.useState("");
841
+ const [description, setDescription] = reactExports.useState("");
842
+ const [isSaving, setIsSaving] = reactExports.useState(false);
843
+ const [error, setError] = reactExports.useState("");
844
+ const updateFolder = useMutation(api.media.updateFolder);
845
+ reactExports.useEffect(() => {
846
+ if (folder) {
847
+ setName(folder.name);
848
+ setDescription(folder.description || "");
849
+ setError("");
850
+ }
851
+ }, [folder]);
852
+ const handleSave = reactExports.useCallback(async () => {
853
+ if (!folder) return;
854
+ if (!name.trim()) {
855
+ setError("Folder name is required");
856
+ return;
857
+ }
858
+ setIsSaving(true);
859
+ setError("");
860
+ try {
861
+ await updateFolder({
862
+ id: folder._id,
863
+ name: name.trim(),
864
+ description: description.trim() || void 0
865
+ });
866
+ onSaved?.();
867
+ onOpenChange(false);
868
+ } catch (err) {
869
+ setError(err instanceof Error ? err.message : "Failed to update folder");
870
+ } finally {
871
+ setIsSaving(false);
872
+ }
873
+ }, [folder, name, description, updateFolder, onSaved, onOpenChange]);
874
+ if (!folder) return null;
875
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
876
+ CmsDialog,
877
+ {
878
+ open,
879
+ onOpenChange,
880
+ title: "Edit Folder",
881
+ size: "sm",
882
+ footer: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
883
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
884
+ CmsButton,
885
+ {
886
+ variant: "outline",
887
+ onClick: () => onOpenChange(false),
888
+ disabled: isSaving,
889
+ children: "Cancel"
890
+ }
891
+ ),
892
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { onClick: handleSave, loading: isSaving, children: "Save Changes" })
893
+ ] }),
894
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
895
+ error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md bg-destructive/10 p-3 text-sm text-destructive", children: error }),
896
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CmsField, { label: "Folder Name", required: true, htmlFor: "folder-name", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
897
+ Input,
898
+ {
899
+ id: "folder-name",
900
+ value: name,
901
+ onChange: (e) => setName(e.target.value),
902
+ placeholder: "Enter folder name"
903
+ }
904
+ ) }),
905
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
906
+ CmsField,
907
+ {
908
+ label: "Description",
909
+ description: "A brief description of the folder contents",
910
+ htmlFor: "folder-description",
911
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
912
+ Textarea,
913
+ {
914
+ id: "folder-description",
915
+ value: description,
916
+ onChange: (e) => setDescription(e.target.value),
917
+ placeholder: "Enter description (optional)",
918
+ rows: 3
919
+ }
920
+ )
921
+ }
922
+ )
923
+ ] })
924
+ }
925
+ );
926
+ }
927
+ function MediaAssetActions({
928
+ asset,
929
+ onView,
930
+ onEdit,
931
+ onMove,
932
+ onDelete
933
+ }) {
934
+ const handleDownload = () => {
935
+ if (!asset.url) return;
936
+ const link = document.createElement("a");
937
+ link.href = asset.url;
938
+ link.download = asset.name;
939
+ link.target = "_blank";
940
+ document.body.appendChild(link);
941
+ link.click();
942
+ document.body.removeChild(link);
943
+ };
944
+ const handleCopyUrl = async () => {
945
+ if (!asset.url) return;
946
+ await navigator.clipboard.writeText(asset.url);
947
+ };
948
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
949
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
950
+ CmsButton,
951
+ {
952
+ variant: "ghost",
953
+ size: "icon-sm",
954
+ className: "opacity-0 group-hover:opacity-100",
955
+ onClick: (e) => e.stopPropagation(),
956
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(EllipsisVertical, { className: "size-4" })
957
+ }
958
+ ) }),
959
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
960
+ DropdownMenuContent,
961
+ {
962
+ side: "bottom",
963
+ onClick: (e) => e.stopPropagation(),
964
+ children: [
965
+ onView && /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: onView, children: [
966
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "mr-2 size-4" }),
967
+ "View Details"
968
+ ] }),
969
+ onEdit && /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: onEdit, children: [
970
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "mr-2 size-4" }),
971
+ "Edit"
972
+ ] }),
973
+ onMove && /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: onMove, children: [
974
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FolderInput, { className: "mr-2 size-4" }),
975
+ "Move to..."
976
+ ] }),
977
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuSeparator, {}),
978
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: handleDownload, disabled: !asset.url, children: [
979
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "mr-2 size-4" }),
980
+ "Download"
981
+ ] }),
982
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: handleCopyUrl, disabled: !asset.url, children: [
983
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link2, { className: "mr-2 size-4" }),
984
+ "Copy URL"
985
+ ] }),
986
+ onDelete && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
987
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuSeparator, {}),
988
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
989
+ DropdownMenuItem,
990
+ {
991
+ onClick: onDelete,
992
+ className: "text-destructive focus:text-destructive",
993
+ children: [
994
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "mr-2 size-4" }),
995
+ "Delete"
996
+ ]
997
+ }
998
+ )
999
+ ] })
1000
+ ]
1001
+ }
1002
+ )
1003
+ ] });
1004
+ }
1005
+ function MediaFolderActions({
1006
+ folder: _folder,
1007
+ onEdit,
1008
+ onMove,
1009
+ onDelete
1010
+ }) {
1011
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
1012
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1013
+ CmsButton,
1014
+ {
1015
+ variant: "ghost",
1016
+ size: "icon-sm",
1017
+ className: "opacity-0 group-hover:opacity-100",
1018
+ onClick: (e) => e.stopPropagation(),
1019
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Ellipsis, { className: "size-4" })
1020
+ }
1021
+ ) }),
1022
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuContent, { align: "end", onClick: (e) => e.stopPropagation(), children: [
1023
+ onEdit && /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: onEdit, children: [
1024
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "mr-2 size-4" }),
1025
+ "Rename"
1026
+ ] }),
1027
+ onMove && /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: onMove, children: [
1028
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FolderInput, { className: "mr-2 size-4" }),
1029
+ "Move to..."
1030
+ ] }),
1031
+ onDelete && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1032
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuSeparator, {}),
1033
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1034
+ DropdownMenuItem,
1035
+ {
1036
+ onClick: onDelete,
1037
+ className: "text-destructive focus:text-destructive",
1038
+ children: [
1039
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "mr-2 size-4" }),
1040
+ "Delete"
1041
+ ]
1042
+ }
1043
+ )
1044
+ ] })
1045
+ ] })
1046
+ ] });
1047
+ }
1048
+ function MediaBulkActionBar({
1049
+ selectedCount,
1050
+ onClear,
1051
+ onMove,
1052
+ onDelete,
1053
+ isDeleting
1054
+ }) {
1055
+ if (selectedCount === 0) return null;
1056
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-x-0 bottom-0 z-50 border-t bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto flex max-w-7xl items-center justify-between px-6 py-3", children: [
1057
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
1058
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm font-medium", children: [
1059
+ selectedCount,
1060
+ " ",
1061
+ selectedCount === 1 ? "file" : "files",
1062
+ " selected"
1063
+ ] }),
1064
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { variant: "ghost", size: "sm", onClick: onClear, children: [
1065
+ /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "mr-1 size-4" }),
1066
+ "Clear"
1067
+ ] })
1068
+ ] }),
1069
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1070
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { variant: "secondary", onClick: onMove, disabled: isDeleting, children: [
1071
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FolderInput, { className: "mr-2 size-4" }),
1072
+ "Move to..."
1073
+ ] }),
1074
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1075
+ CmsButton,
1076
+ {
1077
+ variant: "destructive",
1078
+ onClick: onDelete,
1079
+ loading: isDeleting,
1080
+ children: [
1081
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "mr-2 size-4" }),
1082
+ "Delete"
1083
+ ]
1084
+ }
1085
+ )
1086
+ ] })
1087
+ ] }) });
1088
+ }
1089
+ function MediaTrashBulkActionBar({
1090
+ selectedCount,
1091
+ onClear,
1092
+ onRestore,
1093
+ onPermanentDelete,
1094
+ isRestoring,
1095
+ isDeleting
1096
+ }) {
1097
+ if (selectedCount === 0) return null;
1098
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-x-0 bottom-0 z-50 border-t bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto flex max-w-7xl items-center justify-between px-6 py-3", children: [
1099
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
1100
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm font-medium", children: [
1101
+ selectedCount,
1102
+ " ",
1103
+ selectedCount === 1 ? "file" : "files",
1104
+ " selected"
1105
+ ] }),
1106
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { variant: "ghost", size: "sm", onClick: onClear, children: [
1107
+ /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "mr-1 size-4" }),
1108
+ "Clear"
1109
+ ] })
1110
+ ] }),
1111
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1112
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1113
+ CmsButton,
1114
+ {
1115
+ variant: "secondary",
1116
+ onClick: onRestore,
1117
+ loading: isRestoring,
1118
+ disabled: isDeleting,
1119
+ children: [
1120
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "mr-2 size-4" }),
1121
+ "Restore"
1122
+ ]
1123
+ }
1124
+ ),
1125
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1126
+ CmsButton,
1127
+ {
1128
+ variant: "danger",
1129
+ onClick: onPermanentDelete,
1130
+ loading: isDeleting,
1131
+ disabled: isRestoring,
1132
+ children: [
1133
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "mr-2 size-4" }),
1134
+ "Delete Forever"
1135
+ ]
1136
+ }
1137
+ )
1138
+ ] })
1139
+ ] }) });
1140
+ }
1141
+ function MediaMoveModal({
1142
+ open,
1143
+ onOpenChange,
1144
+ assetIds,
1145
+ currentFolderId,
1146
+ onMoved
1147
+ }) {
1148
+ const [selectedFolderId, setSelectedFolderId] = reactExports.useState(
1149
+ void 0
1150
+ );
1151
+ const [isMoving, setIsMoving] = reactExports.useState(false);
1152
+ const [error, setError] = reactExports.useState("");
1153
+ const folderTree = useQuery(api.media.getFolderTree, {});
1154
+ const moveAssets = useMutation(api.media.moveAssets);
1155
+ const sortedFolders = reactExports.useMemo(() => {
1156
+ if (!folderTree) return [];
1157
+ const buildTree = (parentId, depth) => {
1158
+ const children = folderTree.filter((f) => f.parentId === parentId);
1159
+ return children.flatMap((folder) => [
1160
+ { ...folder, depth },
1161
+ ...buildTree(folder._id, depth + 1)
1162
+ ]);
1163
+ };
1164
+ return buildTree(void 0, 0);
1165
+ }, [folderTree]);
1166
+ const handleMove = async () => {
1167
+ if (assetIds.length === 0) return;
1168
+ setIsMoving(true);
1169
+ setError("");
1170
+ try {
1171
+ await moveAssets({
1172
+ assetIds,
1173
+ targetFolderId: selectedFolderId
1174
+ });
1175
+ onMoved?.();
1176
+ onOpenChange(false);
1177
+ } catch (err) {
1178
+ setError(err instanceof Error ? err.message : "Failed to move files");
1179
+ } finally {
1180
+ setIsMoving(false);
1181
+ }
1182
+ };
1183
+ const isCurrentFolder = selectedFolderId === currentFolderId;
1184
+ const isRootSelected = selectedFolderId === void 0;
1185
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
1186
+ CmsDialog,
1187
+ {
1188
+ open,
1189
+ onOpenChange,
1190
+ title: "Move Files",
1191
+ description: `Select a destination folder for ${assetIds.length} ${assetIds.length === 1 ? "file" : "files"}`,
1192
+ size: "sm",
1193
+ footer: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1194
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1195
+ CmsButton,
1196
+ {
1197
+ variant: "outline",
1198
+ onClick: () => onOpenChange(false),
1199
+ disabled: isMoving,
1200
+ children: "Cancel"
1201
+ }
1202
+ ),
1203
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1204
+ CmsButton,
1205
+ {
1206
+ onClick: handleMove,
1207
+ loading: isMoving,
1208
+ disabled: isCurrentFolder,
1209
+ children: "Move Here"
1210
+ }
1211
+ )
1212
+ ] }),
1213
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1214
+ error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md bg-destructive/10 p-3 text-sm text-destructive", children: error }),
1215
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-h-[300px] overflow-y-auto rounded-md border", children: [
1216
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1217
+ "button",
1218
+ {
1219
+ type: "button",
1220
+ className: cn(
1221
+ "flex w-full items-center gap-2 px-3 py-2 text-left text-sm transition-colors hover:bg-muted",
1222
+ isRootSelected && "bg-primary/10 text-primary",
1223
+ currentFolderId === void 0 && "opacity-50"
1224
+ ),
1225
+ onClick: () => setSelectedFolderId(void 0),
1226
+ children: [
1227
+ /* @__PURE__ */ jsxRuntimeExports.jsx(House, { className: "size-4" }),
1228
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Root (All Files)" }),
1229
+ currentFolderId === void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-auto text-xs text-muted-foreground", children: "Current" })
1230
+ ]
1231
+ }
1232
+ ),
1233
+ sortedFolders.map((folder) => {
1234
+ const isCurrent = folder._id === currentFolderId;
1235
+ const isSelected = folder._id === selectedFolderId;
1236
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1237
+ "button",
1238
+ {
1239
+ type: "button",
1240
+ className: cn(
1241
+ "flex w-full items-center gap-2 px-3 py-2 text-left text-sm transition-colors hover:bg-muted",
1242
+ isSelected && "bg-primary/10 text-primary",
1243
+ isCurrent && "opacity-50"
1244
+ ),
1245
+ style: { paddingLeft: `${12 + folder.depth * 20}px` },
1246
+ onClick: () => setSelectedFolderId(folder._id),
1247
+ children: [
1248
+ folder.depth > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" }),
1249
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-4 text-amber-500" }),
1250
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: folder.name }),
1251
+ isCurrent && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-auto text-xs text-muted-foreground", children: "Current" })
1252
+ ]
1253
+ },
1254
+ folder._id
1255
+ );
1256
+ }),
1257
+ sortedFolders.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: "No folders yet. Create folders to organize your files." })
1258
+ ] }),
1259
+ isCurrentFolder && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Files are already in this folder" })
1260
+ ] })
1261
+ }
1262
+ );
1263
+ }
1264
+ function formatFileSize(bytes) {
1265
+ if (bytes === 0) return "0 B";
1266
+ const k = 1024;
1267
+ const sizes = ["B", "KB", "MB", "GB"];
1268
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1269
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
1270
+ }
1271
+ function formatDate(timestamp) {
1272
+ return new Date(timestamp).toLocaleDateString("en-US", {
1273
+ month: "short",
1274
+ day: "numeric",
1275
+ year: "numeric"
1276
+ });
1277
+ }
1278
+ function getMediaTypeIcon(type, className = "size-6") {
1279
+ const iconProps = {
1280
+ className
1281
+ };
1282
+ switch (type) {
1283
+ case "image":
1284
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { ...iconProps });
1285
+ case "video":
1286
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Video, { ...iconProps });
1287
+ case "audio":
1288
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Music, { ...iconProps });
1289
+ case "document":
1290
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { ...iconProps });
1291
+ default:
1292
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(File, { ...iconProps });
1293
+ }
1294
+ }
1295
+ function getMediaTypeFromMimeType(mimeType) {
1296
+ if (!mimeType) return "other";
1297
+ if (mimeType.startsWith("image/")) return "image";
1298
+ if (mimeType.startsWith("video/")) return "video";
1299
+ if (mimeType.startsWith("audio/")) return "audio";
1300
+ if (mimeType === "application/pdf" || mimeType.includes("document") || mimeType.includes("sheet") || mimeType.includes("presentation") || mimeType.startsWith("text/")) {
1301
+ return "document";
1302
+ }
1303
+ return "other";
1304
+ }
1305
+ function MediaPage() {
1306
+ const {
1307
+ settings
1308
+ } = useSettingsConfig();
1309
+ const navigate = useNavigate();
1310
+ reactExports.useEffect(() => {
1311
+ if (settings && !settings.features.mediaManagement) {
1312
+ navigate({
1313
+ to: "/"
1314
+ });
1315
+ }
1316
+ }, [settings, navigate]);
1317
+ const [currentFolderId, setCurrentFolderId] = reactExports.useState(void 0);
1318
+ const [searchQuery, setSearchQuery] = reactExports.useState("");
1319
+ const [typeFilter, setTypeFilter] = reactExports.useState("");
1320
+ const [selectedTermIds, setSelectedTermIds] = reactExports.useState([]);
1321
+ const [selectedAssets, setSelectedAssets] = reactExports.useState(/* @__PURE__ */ new Set());
1322
+ const [isSelectionMode, setIsSelectionMode] = reactExports.useState(false);
1323
+ const [showNewFolderModal, setShowNewFolderModal] = reactExports.useState(false);
1324
+ const [showUploadModal, setShowUploadModal] = reactExports.useState(false);
1325
+ const [newFolderName, setNewFolderName] = reactExports.useState("");
1326
+ const [isCreatingFolder, setIsCreatingFolder] = reactExports.useState(false);
1327
+ const [folderError, setFolderError] = reactExports.useState("");
1328
+ const [previewIndex, setPreviewIndex] = reactExports.useState(null);
1329
+ const [editingAsset, setEditingAsset] = reactExports.useState(null);
1330
+ const [editingFolder, setEditingFolder] = reactExports.useState(null);
1331
+ const [deleteTarget, setDeleteTarget] = reactExports.useState(null);
1332
+ const [isDeleting, setIsDeleting] = reactExports.useState(false);
1333
+ const [showMoveModal, setShowMoveModal] = reactExports.useState(false);
1334
+ const [showBulkDeleteConfirm, setShowBulkDeleteConfirm] = reactExports.useState(false);
1335
+ const [isBulkDeleting, setIsBulkDeleting] = reactExports.useState(false);
1336
+ const [activeView, setActiveView] = reactExports.useState("library");
1337
+ const [isRestoring, setIsRestoring] = reactExports.useState(false);
1338
+ const [isPermanentlyDeleting, setIsPermanentlyDeleting] = reactExports.useState(false);
1339
+ const [showPermanentDeleteConfirm, setShowPermanentDeleteConfirm] = reactExports.useState(false);
1340
+ const [permanentDeleteTarget, setPermanentDeleteTarget] = reactExports.useState(null);
1341
+ const isTrashView = activeView === "trash";
1342
+ const assetsResult = useQuery(api.media.listAssets, {
1343
+ folderId: isTrashView ? void 0 : currentFolderId,
1344
+ type: typeFilter || void 0,
1345
+ search: searchQuery || void 0,
1346
+ deletedOnly: isTrashView ? true : void 0,
1347
+ paginationOpts: {
1348
+ numItems: 100,
1349
+ cursor: null
1350
+ }
1351
+ });
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");
1362
+ const termFilteredMediaIds = reactExports.useMemo(() => {
1363
+ if (selectedTermIds.length === 0) return null;
1364
+ const ids = /* @__PURE__ */ new Set();
1365
+ const results = [mediaByTermResult0, mediaByTermResult1, mediaByTermResult2];
1366
+ for (let i = 0; i < selectedTermIds.length && i < 3; i++) {
1367
+ const result = results[i];
1368
+ if (result?.page) {
1369
+ for (const media of result.page) {
1370
+ ids.add(media._id);
1371
+ }
1372
+ }
1373
+ }
1374
+ return ids;
1375
+ }, [selectedTermIds, mediaByTermResult0, mediaByTermResult1, mediaByTermResult2]);
1376
+ const folders = useQuery(api.media.listFolders, {
1377
+ parentId: isTrashView ? void 0 : currentFolderId,
1378
+ deletedOnly: isTrashView || void 0
1379
+ });
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);
1391
+ const breadcrumbPath = reactExports.useMemo(() => {
1392
+ if (!currentFolderId || !folderTree) return [];
1393
+ const path = [];
1394
+ let folder = folderTree.find((f) => f._id === currentFolderId);
1395
+ while (folder) {
1396
+ path.unshift(folder);
1397
+ const parentId = folder.parentId;
1398
+ folder = parentId ? folderTree.find((f) => f._id === parentId) : void 0;
1399
+ }
1400
+ return path;
1401
+ }, [currentFolderId, folderTree]);
1402
+ const handleFolderClick = reactExports.useCallback((folderId) => {
1403
+ setCurrentFolderId(folderId);
1404
+ setSearchQuery("");
1405
+ }, []);
1406
+ const handleNavigateUp = reactExports.useCallback(() => {
1407
+ if (currentFolder?.parentId) {
1408
+ setCurrentFolderId(currentFolder.parentId);
1409
+ } else {
1410
+ setCurrentFolderId(void 0);
1411
+ }
1412
+ }, [currentFolder]);
1413
+ const handleNavigateToRoot = reactExports.useCallback(() => {
1414
+ setCurrentFolderId(void 0);
1415
+ setSearchQuery("");
1416
+ }, []);
1417
+ const handleAssetSelect = reactExports.useCallback((assetId) => {
1418
+ setSelectedAssets((prev) => {
1419
+ const next = new Set(prev);
1420
+ if (next.has(assetId)) {
1421
+ next.delete(assetId);
1422
+ } else {
1423
+ next.add(assetId);
1424
+ }
1425
+ return next;
1426
+ });
1427
+ }, []);
1428
+ const handleSelectAll = reactExports.useCallback(() => {
1429
+ if (!assetsResult?.page) return;
1430
+ setSelectedAssets(new Set(assetsResult.page.map((a) => a._id)));
1431
+ }, [assetsResult?.page]);
1432
+ const handleDeselectAll = reactExports.useCallback(() => {
1433
+ setSelectedAssets(/* @__PURE__ */ new Set());
1434
+ }, []);
1435
+ const handleViewChange = reactExports.useCallback((view) => {
1436
+ setActiveView(view);
1437
+ setSelectedAssets(/* @__PURE__ */ new Set());
1438
+ setIsSelectionMode(false);
1439
+ }, []);
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);
1447
+ }
1448
+ }
1449
+ }, [isSelectionMode, handleAssetSelect, assetsResult?.page]);
1450
+ const handlePreviewNavigate = reactExports.useCallback((index) => {
1451
+ setPreviewIndex(index);
1452
+ }, []);
1453
+ const handleDelete = reactExports.useCallback(async () => {
1454
+ if (!deleteTarget) return;
1455
+ setIsDeleting(true);
1456
+ try {
1457
+ if (deleteTarget.type === "asset") {
1458
+ await deleteAsset({
1459
+ id: deleteTarget.id
1460
+ });
1461
+ } else {
1462
+ await deleteFolder({
1463
+ id: deleteTarget.id
1464
+ });
1465
+ }
1466
+ setDeleteTarget(null);
1467
+ } catch (err) {
1468
+ console.error("Delete failed:", err);
1469
+ } finally {
1470
+ setIsDeleting(false);
1471
+ }
1472
+ }, [deleteTarget, deleteAsset, deleteFolder]);
1473
+ const handleBulkDelete = reactExports.useCallback(async () => {
1474
+ if (selectedAssets.size === 0) return;
1475
+ setIsBulkDeleting(true);
1476
+ try {
1477
+ const deletePromises = Array.from(selectedAssets).map((id) => deleteAsset({
1478
+ id
1479
+ }));
1480
+ await Promise.all(deletePromises);
1481
+ setSelectedAssets(/* @__PURE__ */ new Set());
1482
+ setIsSelectionMode(false);
1483
+ setShowBulkDeleteConfirm(false);
1484
+ } catch (err) {
1485
+ console.error("Bulk delete failed:", err);
1486
+ } finally {
1487
+ setIsBulkDeleting(false);
1488
+ }
1489
+ }, [selectedAssets, deleteAsset]);
1490
+ const handleBulkMoveComplete = reactExports.useCallback(() => {
1491
+ setSelectedAssets(/* @__PURE__ */ new Set());
1492
+ setIsSelectionMode(false);
1493
+ }, []);
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]);
1506
+ const handleBulkRestore = reactExports.useCallback(async () => {
1507
+ if (selectedAssets.size === 0) return;
1508
+ setIsRestoring(true);
1509
+ try {
1510
+ const restorePromises = Array.from(selectedAssets).map((id) => restoreAsset({
1511
+ id
1512
+ }));
1513
+ await Promise.all(restorePromises);
1514
+ setSelectedAssets(/* @__PURE__ */ new Set());
1515
+ setIsSelectionMode(false);
1516
+ } catch (err) {
1517
+ console.error("Bulk restore failed:", err);
1518
+ } finally {
1519
+ setIsRestoring(false);
1520
+ }
1521
+ }, [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]);
1534
+ const handlePermanentDelete = reactExports.useCallback(async () => {
1535
+ if (!permanentDeleteTarget) return;
1536
+ setIsPermanentlyDeleting(true);
1537
+ try {
1538
+ if (permanentDeleteTarget === "bulk") {
1539
+ await bulkPermanentDeleteAssets({
1540
+ ids: Array.from(selectedAssets)
1541
+ });
1542
+ setSelectedAssets(/* @__PURE__ */ new Set());
1543
+ setIsSelectionMode(false);
1544
+ } else {
1545
+ await permanentDeleteAsset({
1546
+ id: permanentDeleteTarget
1547
+ });
1548
+ }
1549
+ setShowPermanentDeleteConfirm(false);
1550
+ setPermanentDeleteTarget(null);
1551
+ } catch (err) {
1552
+ console.error("Permanent delete failed:", err);
1553
+ } finally {
1554
+ setIsPermanentlyDeleting(false);
1555
+ }
1556
+ }, [permanentDeleteTarget, permanentDeleteAsset, bulkPermanentDeleteAssets, selectedAssets]);
1557
+ const handleCreateFolder = reactExports.useCallback(async () => {
1558
+ if (!newFolderName.trim()) {
1559
+ setFolderError("Folder name is required");
1560
+ return;
1561
+ }
1562
+ setIsCreatingFolder(true);
1563
+ setFolderError("");
1564
+ try {
1565
+ await createFolder({
1566
+ name: newFolderName.trim(),
1567
+ parentId: currentFolderId
1568
+ });
1569
+ setShowNewFolderModal(false);
1570
+ setNewFolderName("");
1571
+ } catch (error) {
1572
+ setFolderError(error instanceof Error ? error.message : "Failed to create folder");
1573
+ } finally {
1574
+ setIsCreatingFolder(false);
1575
+ }
1576
+ }, [newFolderName, currentFolderId, createFolder]);
1577
+ const handleUploadComplete = reactExports.useCallback((_results) => {
1578
+ setShowUploadModal(false);
1579
+ }, []);
1580
+ const isLoading = assetsResult === void 0 || folders === void 0;
1581
+ const displayedAssets = reactExports.useMemo(() => {
1582
+ const assets = assetsResult?.page ?? [];
1583
+ if (termFilteredMediaIds === null) {
1584
+ return assets;
1585
+ }
1586
+ return assets.filter((asset) => termFilteredMediaIds.has(asset._id));
1587
+ }, [assetsResult?.page, termFilteredMediaIds]);
1588
+ 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
+ ] }) }),
1601
+ !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
+ ] }),
1606
+ breadcrumbPath.map((folder, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center", children: [
1607
+ /* @__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 })
1609
+ ] }, folder._id))
1610
+ ] }),
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"
1655
+ ] }),
1656
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CmsButton, { onClick: () => setShowUploadModal(true), children: [
1657
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "size-4" }),
1658
+ "Upload Files"
1659
+ ] })
1660
+ ] })
1661
+ ] }) }),
1662
+ isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-12", children: [
1663
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "size-8 animate-spin rounded-full border-2 border-muted border-t-primary" }),
1664
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-4 text-sm text-muted-foreground", children: "Loading media library..." })
1665
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1666
+ !isTrashView && folders && folders.length > 0 && !searchQuery && /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { children: [
1667
+ /* @__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)) })
1684
+ ] }),
1685
+ isTrashView && folders && folders.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { children: [
1686
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "mb-3 text-sm font-medium text-muted-foreground", children: [
1687
+ "Deleted Folders (",
1688
+ folders.length,
1689
+ ")"
1690
+ ] }),
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)) })
1699
+ ] }),
1700
+ displayedAssets.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { children: [
1701
+ !isTrashView && folders && folders.length > 0 && !searchQuery && /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "mb-3 text-sm font-medium text-muted-foreground", children: "Files" }),
1702
+ isTrashView && /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "mb-3 text-sm font-medium text-muted-foreground", children: [
1703
+ "Deleted Files (",
1704
+ displayedAssets.length,
1705
+ ")"
1706
+ ] }),
1707
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-4 md:grid-cols-6", children: displayedAssets.map((asset) => {
1708
+ const assetId = asset._id;
1709
+ const isSelected = selectedAssets.has(assetId);
1710
+ 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);
1754
+ }) }),
1755
+ !assetsResult.isDone && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-4 text-center text-sm text-muted-foreground", children: [
1756
+ "Showing ",
1757
+ assetsResult.page.length,
1758
+ " files. More files available."
1759
+ ] })
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
+ } })
1769
+ ] }),
1770
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: showNewFolderModal, onOpenChange: setShowNewFolderModal, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { children: [
1771
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Create New Folder" }) }),
1772
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4 py-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1773
+ /* @__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();
1780
+ }
1781
+ } }),
1782
+ folderError && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-destructive", children: folderError })
1783
+ ] }) }),
1784
+ /* @__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" })
1787
+ ] })
1788
+ ] }) }),
1789
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: showUploadModal, onOpenChange: setShowUploadModal, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-lg", children: [
1790
+ /* @__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" }) })
1793
+ ] }) }),
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 })
1828
+ ] });
1829
+ }
1830
+ export {
1831
+ MediaPage as component
1832
+ };