convex-cms 0.0.5-alpha.0 → 0.0.5-alpha.2

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 (323) hide show
  1. package/README.md +95 -144
  2. package/admin/README.md +99 -0
  3. package/admin/src/components/AdminLayout.tsx +22 -0
  4. package/admin/src/components/BreakingChangesWarningDialog.tsx +81 -0
  5. package/admin/src/components/BulkActionBar.tsx +190 -0
  6. package/admin/src/components/BulkOperationModal.tsx +177 -0
  7. package/admin/src/components/ContentEntryEditor.tsx +1104 -0
  8. package/admin/src/components/ContentTypeFormModal.tsx +1012 -0
  9. package/admin/src/components/ErrorBoundary.tsx +83 -0
  10. package/admin/src/components/ErrorState.tsx +147 -0
  11. package/admin/src/components/Header.tsx +294 -0
  12. package/admin/src/components/RouteGuard.tsx +264 -0
  13. package/admin/src/components/Sidebar.tsx +90 -0
  14. package/admin/src/components/TaxonomyEditor.tsx +348 -0
  15. package/admin/src/components/TermTree.tsx +533 -0
  16. package/admin/src/components/UploadDropzone.tsx +383 -0
  17. package/admin/src/components/VersionCompare.tsx +250 -0
  18. package/admin/src/components/VersionHistory.tsx +279 -0
  19. package/admin/src/components/VersionRollbackModal.tsx +79 -0
  20. package/admin/src/components/cmsds/CmsButton.tsx +101 -0
  21. package/admin/src/components/cmsds/CmsDialog.tsx +139 -0
  22. package/admin/src/components/cmsds/CmsDropdown.tsx +62 -0
  23. package/admin/src/components/cmsds/CmsEmptyState.tsx +54 -0
  24. package/admin/src/components/cmsds/CmsField.tsx +47 -0
  25. package/admin/src/components/cmsds/CmsPageHeader.tsx +35 -0
  26. package/admin/src/components/cmsds/CmsStatusBadge.tsx +153 -0
  27. package/admin/src/components/cmsds/CmsSurface.tsx +52 -0
  28. package/admin/src/components/cmsds/CmsTable.tsx +164 -0
  29. package/admin/src/components/cmsds/CmsToolbar.tsx +58 -0
  30. package/admin/src/components/cmsds/index.ts +10 -0
  31. package/admin/src/components/fields/BooleanField.tsx +74 -0
  32. package/admin/src/components/fields/CategoryField.tsx +394 -0
  33. package/admin/src/components/fields/DateField.tsx +173 -0
  34. package/admin/src/components/fields/DefaultFieldRenderer.tsx +74 -0
  35. package/admin/src/components/fields/FieldRenderer.tsx +180 -0
  36. package/admin/src/components/fields/FieldWrapper.tsx +57 -0
  37. package/admin/src/components/fields/JsonField.tsx +172 -0
  38. package/admin/src/components/fields/MediaField.tsx +367 -0
  39. package/admin/src/components/fields/MultiSelectField.tsx +118 -0
  40. package/admin/src/components/fields/NumberField.tsx +77 -0
  41. package/admin/src/components/fields/ReferenceField.tsx +386 -0
  42. package/admin/src/components/fields/RichTextField.tsx +171 -0
  43. package/admin/src/components/fields/SelectField.tsx +62 -0
  44. package/admin/src/components/fields/TagField.tsx +325 -0
  45. package/admin/src/components/fields/TextAreaField.tsx +68 -0
  46. package/admin/src/components/fields/TextField.tsx +56 -0
  47. package/admin/src/components/fields/index.ts +54 -0
  48. package/admin/src/components/fields/registry.ts +64 -0
  49. package/admin/src/components/fields/types.ts +217 -0
  50. package/admin/src/components/filters/TaxonomyFilter.tsx +254 -0
  51. package/admin/src/components/filters/index.ts +1 -0
  52. package/admin/src/components/index.ts +8 -0
  53. package/admin/src/components/media/MediaAssetActions.tsx +115 -0
  54. package/admin/src/components/media/MediaAssetEditDialog.tsx +217 -0
  55. package/admin/src/components/media/MediaBulkActionBar.tsx +51 -0
  56. package/admin/src/components/media/MediaFolderActions.tsx +69 -0
  57. package/admin/src/components/media/MediaFolderEditDialog.tsx +126 -0
  58. package/admin/src/components/media/MediaMoveModal.tsx +179 -0
  59. package/admin/src/components/media/MediaPreviewModal.tsx +370 -0
  60. package/admin/src/components/media/MediaTaxonomyPicker.tsx +304 -0
  61. package/admin/src/components/media/MediaTrashBulkActionBar.tsx +59 -0
  62. package/admin/src/components/ui/accordion.tsx +64 -0
  63. package/admin/src/components/ui/alert-dialog.tsx +155 -0
  64. package/admin/src/components/ui/alert.tsx +66 -0
  65. package/admin/src/components/ui/avatar.tsx +53 -0
  66. package/admin/src/components/ui/badge.tsx +46 -0
  67. package/admin/src/components/ui/breadcrumb.tsx +109 -0
  68. package/admin/src/components/ui/button.tsx +62 -0
  69. package/admin/src/components/ui/calendar.tsx +220 -0
  70. package/admin/src/components/ui/card.tsx +92 -0
  71. package/admin/src/components/ui/checkbox.tsx +30 -0
  72. package/admin/src/components/ui/command.tsx +182 -0
  73. package/admin/src/components/ui/dialog.tsx +143 -0
  74. package/admin/src/components/ui/dropdown-menu.tsx +257 -0
  75. package/admin/src/components/ui/form.tsx +167 -0
  76. package/admin/src/components/ui/input.tsx +21 -0
  77. package/admin/src/components/ui/label.tsx +24 -0
  78. package/admin/src/components/ui/popover.tsx +46 -0
  79. package/admin/src/components/ui/scroll-area.tsx +56 -0
  80. package/admin/src/components/ui/select.tsx +190 -0
  81. package/admin/src/components/ui/separator.tsx +26 -0
  82. package/admin/src/components/ui/sheet.tsx +137 -0
  83. package/admin/src/components/ui/sidebar.tsx +724 -0
  84. package/admin/src/components/ui/skeleton.tsx +13 -0
  85. package/admin/src/components/ui/sonner.tsx +38 -0
  86. package/admin/src/components/ui/switch.tsx +31 -0
  87. package/admin/src/components/ui/table.tsx +114 -0
  88. package/admin/src/components/ui/tabs.tsx +66 -0
  89. package/admin/src/components/ui/textarea.tsx +18 -0
  90. package/admin/src/components/ui/tooltip.tsx +61 -0
  91. package/admin/src/contexts/AdminConfigContext.tsx +30 -0
  92. package/admin/src/contexts/AuthContext.tsx +330 -0
  93. package/admin/src/contexts/BreadcrumbContext.tsx +49 -0
  94. package/admin/src/contexts/SettingsConfigContext.tsx +57 -0
  95. package/admin/src/contexts/ThemeContext.tsx +91 -0
  96. package/admin/src/contexts/index.ts +20 -0
  97. package/admin/src/embed/components/EmbedHeader.tsx +103 -0
  98. package/admin/src/embed/components/EmbedLayout.tsx +29 -0
  99. package/admin/src/embed/components/EmbedSidebar.tsx +119 -0
  100. package/admin/src/embed/components/index.ts +3 -0
  101. package/admin/src/embed/contexts/ApiContext.tsx +32 -0
  102. package/admin/src/embed/index.tsx +184 -0
  103. package/admin/src/embed/navigation.tsx +202 -0
  104. package/admin/src/embed/pages/Content.tsx +19 -0
  105. package/admin/src/embed/pages/ContentTypes.tsx +19 -0
  106. package/admin/src/embed/pages/Dashboard.tsx +19 -0
  107. package/admin/src/embed/pages/Media.tsx +19 -0
  108. package/admin/src/embed/pages/Settings.tsx +22 -0
  109. package/admin/src/embed/pages/Taxonomies.tsx +22 -0
  110. package/admin/src/embed/pages/Trash.tsx +22 -0
  111. package/admin/src/embed/pages/index.ts +7 -0
  112. package/admin/src/embed/types.ts +24 -0
  113. package/admin/src/hooks/index.ts +2 -0
  114. package/admin/src/hooks/use-mobile.ts +19 -0
  115. package/admin/src/hooks/useBreadcrumbLabel.ts +15 -0
  116. package/admin/src/hooks/usePermissions.ts +211 -0
  117. package/admin/src/lib/admin-config.ts +111 -0
  118. package/admin/src/lib/cn.ts +6 -0
  119. package/admin/src/lib/config.server.ts +56 -0
  120. package/admin/src/lib/convex.ts +26 -0
  121. package/admin/src/lib/embed-adapter.ts +80 -0
  122. package/admin/src/lib/icons.tsx +96 -0
  123. package/admin/src/lib/loadAdminConfig.ts +92 -0
  124. package/admin/src/lib/motion.ts +29 -0
  125. package/admin/src/lib/navigation.ts +43 -0
  126. package/admin/src/lib/tanstack-adapter.ts +82 -0
  127. package/admin/src/pages/ContentPage.tsx +337 -0
  128. package/admin/src/pages/ContentTypesPage.tsx +457 -0
  129. package/admin/src/pages/DashboardPage.tsx +163 -0
  130. package/admin/src/pages/MediaPage.tsx +34 -0
  131. package/admin/src/pages/SettingsPage.tsx +486 -0
  132. package/admin/src/pages/TaxonomiesPage.tsx +289 -0
  133. package/admin/src/pages/TrashPage.tsx +421 -0
  134. package/admin/src/pages/index.ts +14 -0
  135. package/admin/src/routeTree.gen.ts +262 -0
  136. package/admin/src/router.tsx +22 -0
  137. package/admin/src/routes/__root.tsx +250 -0
  138. package/admin/src/routes/content-types.tsx +20 -0
  139. package/admin/src/routes/content.tsx +20 -0
  140. package/admin/src/routes/entries/$entryId.tsx +107 -0
  141. package/admin/src/routes/entries/new.$contentTypeId.tsx +69 -0
  142. package/admin/src/routes/entries/type/$contentTypeId.tsx +503 -0
  143. package/admin/src/routes/index.tsx +20 -0
  144. package/admin/src/routes/media.tsx +1095 -0
  145. package/admin/src/routes/settings.tsx +20 -0
  146. package/admin/src/routes/taxonomies.tsx +20 -0
  147. package/admin/src/routes/trash.tsx +20 -0
  148. package/admin/src/styles/globals.css +69 -0
  149. package/admin/src/styles/tailwind-config.css +74 -0
  150. package/admin/src/styles/theme.css +73 -0
  151. package/admin/src/types/index.ts +221 -0
  152. package/admin/src/utils/errorParsing.ts +163 -0
  153. package/admin/src/utils/index.ts +5 -0
  154. package/admin/src/vite-env.d.ts +14 -0
  155. package/admin/tailwind.preset.cjs +102 -0
  156. package/admin-dist/nitro.json +1 -1
  157. package/admin-dist/public/assets/{CmsEmptyState-CiMQwSQV.js → CmsEmptyState-CkqBIab3.js} +1 -1
  158. package/admin-dist/public/assets/{CmsPageHeader-ohOq0luT.js → CmsPageHeader-CUtl5MMG.js} +1 -1
  159. package/admin-dist/public/assets/{CmsStatusBadge-BdNf0V9v.js → CmsStatusBadge-CUYFgEe-.js} +1 -1
  160. package/admin-dist/public/assets/{CmsSurface-CWup6Jh7.js → CmsSurface-CsJfAVa3.js} +1 -1
  161. package/admin-dist/public/assets/{CmsToolbar-cEBlCHa3.js → CmsToolbar-CnfbcxeP.js} +1 -1
  162. package/admin-dist/public/assets/{ContentEntryEditor-BY5ypfUs.js → ContentEntryEditor-BU220CCy.js} +1 -1
  163. package/admin-dist/public/assets/TaxonomyFilter-CWCxC5HZ.js +1 -0
  164. package/admin-dist/public/assets/_contentTypeId-DK8cskRt.js +1 -0
  165. package/admin-dist/public/assets/{_entryId-BpSmrfAm.js → _entryId-CuVMExbb.js} +1 -1
  166. package/admin-dist/public/assets/{alert-Bf2l8kxw.js → alert-CF1BSzGR.js} +1 -1
  167. package/admin-dist/public/assets/{badge-qPrc4AUM.js → badge-CmuOIVKp.js} +1 -1
  168. package/admin-dist/public/assets/{circle-check-big-Dgozy3vV.js → circle-check-big-BKDVG6DU.js} +1 -1
  169. package/admin-dist/public/assets/{command-QOmNhlb0.js → command-XJxnF2Sd.js} +1 -1
  170. package/admin-dist/public/assets/content-QBUxdxbS.js +1 -0
  171. package/admin-dist/public/assets/content-types-CrNEm8Hf.js +2 -0
  172. package/admin-dist/public/assets/globals-B7Wsfh_v.css +1 -0
  173. package/admin-dist/public/assets/index-C7xOwudI.js +1 -0
  174. package/admin-dist/public/assets/{label-DCsUdvFh.js → label-CHCnXeBk.js} +1 -1
  175. package/admin-dist/public/assets/{link-2-Czw1N61H.js → link-2-Bb34judH.js} +1 -1
  176. package/admin-dist/public/assets/{list-DtCsXj8-.js → list-9Pzt48ld.js} +1 -1
  177. package/admin-dist/public/assets/{main-CXgkZMhe.js → main-CjQ2VI9L.js} +3 -3
  178. package/admin-dist/public/assets/media-Dc5PWt2Q.js +1 -0
  179. package/admin-dist/public/assets/{new._contentTypeId-CoTDxKzf.js → new._contentTypeId-C_I4YxIa.js} +1 -1
  180. package/admin-dist/public/assets/{plus-xCFJK0RC.js → plus-Ceef7DHk.js} +1 -1
  181. package/admin-dist/public/assets/{rotate-ccw-DIqK63wY.js → rotate-ccw-7k7-4VUq.js} +1 -1
  182. package/admin-dist/public/assets/{scroll-area-B-yrE66a.js → scroll-area-CC6wujnp.js} +1 -1
  183. package/admin-dist/public/assets/{search-CbCbboeU.js → search-DwoUV2pv.js} +1 -1
  184. package/admin-dist/public/assets/{select-Co3TZFJb.js → select-hOZTp8aC.js} +1 -1
  185. package/admin-dist/public/assets/{settings-BspTTv_o.js → settings-t2PbCZh4.js} +1 -1
  186. package/admin-dist/public/assets/{switch-CfavASmR.js → switch-jX2pDaNU.js} +1 -1
  187. package/admin-dist/public/assets/{tabs-CN5s5u2W.js → tabs-q4EbZk7c.js} +1 -1
  188. package/admin-dist/public/assets/{tanstack-adapter-npeE3RdY.js → tanstack-adapter-B-Glm4kH.js} +1 -1
  189. package/admin-dist/public/assets/taxonomies-kyk5P4ZW.js +1 -0
  190. package/admin-dist/public/assets/{textarea-BJ0XFZpT.js → textarea-B6SfBmr0.js} +1 -1
  191. package/admin-dist/public/assets/trash-BOCnIznD.js +1 -0
  192. package/admin-dist/public/assets/{triangle-alert-BZRcqsUg.js → triangle-alert-CXFIO_Gu.js} +1 -1
  193. package/admin-dist/public/assets/{useBreadcrumbLabel-DwZlwvFF.js → useBreadcrumbLabel-_6qBagc3.js} +1 -1
  194. package/admin-dist/public/assets/{usePermissions-C1JQhfqb.js → usePermissions-M1ijZ7a6.js} +1 -1
  195. package/admin-dist/server/_ssr/{CmsButton-B45JAKR1.mjs → CmsButton-DOiTVKQq.mjs} +1 -1
  196. package/admin-dist/server/_ssr/{CmsEmptyState-D_BQFAVR.mjs → CmsEmptyState-fbnGt3LD.mjs} +2 -2
  197. package/admin-dist/server/_ssr/{CmsPageHeader-CrUZA59A.mjs → CmsPageHeader-DHRrdOZa.mjs} +1 -1
  198. package/admin-dist/server/_ssr/{CmsStatusBadge-B-sj6yaj.mjs → CmsStatusBadge-s7obWbKZ.mjs} +2 -2
  199. package/admin-dist/server/_ssr/{CmsSurface-DKJZhpjk.mjs → CmsSurface-rFoYjb62.mjs} +1 -1
  200. package/admin-dist/server/_ssr/{CmsToolbar-ByaW5iXf.mjs → CmsToolbar-zTE45z2q.mjs} +2 -2
  201. package/admin-dist/server/_ssr/{ContentEntryEditor-D3_Jb1dq.mjs → ContentEntryEditor-BLoEjT_m.mjs} +12 -12
  202. package/admin-dist/server/_ssr/{TaxonomyFilter-BRJkuCtA.mjs → TaxonomyFilter-XAtaJC2z.mjs} +5 -5
  203. package/admin-dist/server/_ssr/{_contentTypeId-B9kA6CaM.mjs → _contentTypeId-Csl4822C.mjs} +13 -13
  204. package/admin-dist/server/_ssr/{_entryId-BddcMkZN.mjs → _entryId-D8alLFBx.mjs} +15 -15
  205. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-BffZedId.mjs +4 -0
  206. package/admin-dist/server/_ssr/{command-CGtVr8Gb.mjs → command-C0Di14--.mjs} +1 -1
  207. package/admin-dist/server/_ssr/{content-D1tbeOd0.mjs → content-CT-FPsmV.mjs} +12 -55
  208. package/admin-dist/server/_ssr/{content-types-BZqY_BER.mjs → content-types-C8cBFdzE.mjs} +15 -46
  209. package/admin-dist/server/_ssr/{index-BIdq4xaC.mjs → index-BJtcrEc-.mjs} +5 -5
  210. package/admin-dist/server/_ssr/index.mjs +2 -2
  211. package/admin-dist/server/_ssr/{label-T-QNKAr6.mjs → label-qn2Afwl4.mjs} +1 -1
  212. package/admin-dist/server/_ssr/{media-C-xqjBrl.mjs → media-qv5IAsMZ.mjs} +14 -14
  213. package/admin-dist/server/_ssr/{new._contentTypeId-DWic9cRq.mjs → new._contentTypeId-DdGyrhqs.mjs} +13 -13
  214. package/admin-dist/server/_ssr/{router-D1BMAMJT.mjs → router-nSVkxb6Y.mjs} +11 -11
  215. package/admin-dist/server/_ssr/{scroll-area-C0pic_WA.mjs → scroll-area-BCinP455.mjs} +1 -1
  216. package/admin-dist/server/_ssr/{select-CqmuN2F6.mjs → select-BKQlQScw.mjs} +1 -1
  217. package/admin-dist/server/_ssr/{settings-CAkncGGV.mjs → settings-BCr2KQlk.mjs} +55 -40
  218. package/admin-dist/server/_ssr/{switch-CgmuJkT9.mjs → switch-BaOi42fE.mjs} +1 -1
  219. package/admin-dist/server/_ssr/{tabs-CnMj0aRy.mjs → tabs-DYXEi9kq.mjs} +2 -2
  220. package/admin-dist/server/_ssr/{tanstack-adapter-BXZrMauE.mjs → tanstack-adapter-Bsz8kha-.mjs} +1 -1
  221. package/admin-dist/server/_ssr/{taxonomies-thl3BfVm.mjs → taxonomies-CueMHTbE.mjs} +30 -19
  222. package/admin-dist/server/_ssr/{textarea-4K5OJgeh.mjs → textarea-CI0Jqx2x.mjs} +1 -1
  223. package/admin-dist/server/_ssr/{trash-B40Gx5zP.mjs → trash-DE6W8GoX.mjs} +20 -17
  224. package/admin-dist/server/_ssr/{useBreadcrumbLabel-rn-fL4zV.mjs → useBreadcrumbLabel-B5Yi72lM.mjs} +1 -1
  225. package/admin-dist/server/_ssr/{usePermissions-CKeM6_Vw.mjs → usePermissions-C3nZ-Izm.mjs} +1 -1
  226. package/admin-dist/server/index.mjs +183 -190
  227. package/dist/client/admin/bulk.d.ts +79 -0
  228. package/dist/client/admin/bulk.d.ts.map +1 -0
  229. package/dist/client/admin/bulk.js +72 -0
  230. package/dist/client/admin/bulk.js.map +1 -0
  231. package/dist/client/admin/contentLock.d.ts +118 -0
  232. package/dist/client/admin/contentLock.d.ts.map +1 -0
  233. package/dist/client/admin/contentLock.js +81 -0
  234. package/dist/client/admin/contentLock.js.map +1 -0
  235. package/dist/client/{adminApi.d.ts → admin/contentTypes.d.ts} +39 -1134
  236. package/dist/client/admin/contentTypes.d.ts.map +1 -0
  237. package/dist/client/admin/contentTypes.js +122 -0
  238. package/dist/client/admin/contentTypes.js.map +1 -0
  239. package/dist/client/admin/dashboard.d.ts +16 -0
  240. package/dist/client/admin/dashboard.d.ts.map +1 -0
  241. package/dist/client/admin/dashboard.js +33 -0
  242. package/dist/client/admin/dashboard.js.map +1 -0
  243. package/dist/client/admin/entries.d.ts +358 -0
  244. package/dist/client/admin/entries.d.ts.map +1 -0
  245. package/dist/client/admin/entries.js +220 -0
  246. package/dist/client/admin/entries.js.map +1 -0
  247. package/dist/client/admin/index.d.ts +6568 -0
  248. package/dist/client/admin/index.d.ts.map +1 -0
  249. package/dist/client/admin/index.js +305 -0
  250. package/dist/client/admin/index.js.map +1 -0
  251. package/dist/client/admin/media.d.ts +1038 -0
  252. package/dist/client/admin/media.d.ts.map +1 -0
  253. package/dist/client/admin/media.js +489 -0
  254. package/dist/client/admin/media.js.map +1 -0
  255. package/dist/client/admin/taxonomies.d.ts +339 -0
  256. package/dist/client/admin/taxonomies.d.ts.map +1 -0
  257. package/dist/client/admin/taxonomies.js +364 -0
  258. package/dist/client/admin/taxonomies.js.map +1 -0
  259. package/dist/client/admin/trash.d.ts +91 -0
  260. package/dist/client/admin/trash.d.ts.map +1 -0
  261. package/dist/client/admin/trash.js +71 -0
  262. package/dist/client/admin/trash.js.map +1 -0
  263. package/dist/client/admin/types.d.ts +320 -0
  264. package/dist/client/admin/types.d.ts.map +1 -0
  265. package/dist/client/admin/types.js +7 -0
  266. package/dist/client/admin/types.js.map +1 -0
  267. package/dist/client/admin/validators.d.ts +3886 -0
  268. package/dist/client/admin/validators.d.ts.map +1 -0
  269. package/dist/client/admin/validators.js +322 -0
  270. package/dist/client/admin/validators.js.map +1 -0
  271. package/dist/client/admin/versions.d.ts +106 -0
  272. package/dist/client/admin/versions.d.ts.map +1 -0
  273. package/dist/client/admin/versions.js +57 -0
  274. package/dist/client/admin/versions.js.map +1 -0
  275. package/dist/client/adminApiTypes.d.ts +27 -0
  276. package/dist/client/adminApiTypes.d.ts.map +1 -0
  277. package/dist/client/adminApiTypes.js +12 -0
  278. package/dist/client/adminApiTypes.js.map +1 -0
  279. package/dist/client/{admin-config.d.ts → adminConfig.d.ts} +2 -2
  280. package/dist/client/adminConfig.d.ts.map +1 -0
  281. package/dist/client/{admin-config.js → adminConfig.js} +1 -1
  282. package/dist/client/adminConfig.js.map +1 -0
  283. package/dist/client/agentTools.d.ts +4 -4
  284. package/dist/client/index.d.ts +2 -2
  285. package/dist/client/index.d.ts.map +1 -1
  286. package/dist/client/index.js +15 -2
  287. package/dist/client/index.js.map +1 -1
  288. package/dist/component/contentEntries.d.ts +4 -4
  289. package/dist/component/contentEntryMutations.d.ts +46 -0
  290. package/dist/component/contentEntryMutations.d.ts.map +1 -1
  291. package/dist/component/contentEntryMutations.js +1 -1
  292. package/dist/component/contentEntryMutations.js.map +1 -1
  293. package/dist/component/contentTypeMigration.d.ts +1 -1
  294. package/dist/component/contentTypeMutations.d.ts +22 -0
  295. package/dist/component/contentTypeMutations.d.ts.map +1 -1
  296. package/dist/component/contentTypeMutations.js +1 -1
  297. package/dist/component/contentTypeMutations.js.map +1 -1
  298. package/dist/component/mediaAssetMutations.d.ts +47 -0
  299. package/dist/component/mediaAssetMutations.d.ts.map +1 -1
  300. package/dist/component/mediaAssetMutations.js +1 -1
  301. package/dist/component/mediaAssetMutations.js.map +1 -1
  302. package/dist/component/schema.d.ts +9 -0
  303. package/dist/component/schema.d.ts.map +1 -1
  304. package/dist/component/schema.js +1 -1
  305. package/dist/component/schema.js.map +1 -1
  306. package/package.json +85 -3
  307. package/admin-dist/public/assets/ErrorState-C4nJ-ml4.js +0 -1
  308. package/admin-dist/public/assets/TaxonomyFilter-BgE_SR_O.js +0 -1
  309. package/admin-dist/public/assets/_contentTypeId-DtZectcC.js +0 -1
  310. package/admin-dist/public/assets/content-OEBGlxg1.js +0 -1
  311. package/admin-dist/public/assets/content-types-CjQliqVV.js +0 -2
  312. package/admin-dist/public/assets/globals-hAmgC66w.css +0 -1
  313. package/admin-dist/public/assets/index-BH_ECMhv.js +0 -1
  314. package/admin-dist/public/assets/media-DTJ3-ViE.js +0 -1
  315. package/admin-dist/public/assets/taxonomies-CgG46fIF.js +0 -1
  316. package/admin-dist/public/assets/trash-B3daldm5.js +0 -1
  317. package/admin-dist/server/_ssr/ErrorState-cI-bKLez.mjs +0 -89
  318. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-Dd7AmelK.mjs +0 -4
  319. package/dist/client/admin-config.d.ts.map +0 -1
  320. package/dist/client/admin-config.js.map +0 -1
  321. package/dist/client/adminApi.d.ts.map +0 -1
  322. package/dist/client/adminApi.js +0 -736
  323. package/dist/client/adminApi.js.map +0 -1
@@ -0,0 +1,217 @@
1
+ import { useState, useCallback, useEffect } from 'react'
2
+ import { useMutation, useQuery } from 'convex/react'
3
+ import { api } from '../../../convex/_generated/api'
4
+ import { CmsDialog } from '~/components/cmsds/CmsDialog'
5
+ import { CmsButton } from '~/components/cmsds/CmsButton'
6
+ import { CmsField } from '~/components/cmsds/CmsField'
7
+ import { Input } from '~/components/ui/input'
8
+ import { Textarea } from '~/components/ui/textarea'
9
+ import { MediaTaxonomyPicker } from './MediaTaxonomyPicker'
10
+
11
+ export interface MediaAssetForEdit {
12
+ _id: string
13
+ name: string
14
+ title?: string
15
+ description?: string
16
+ altText?: string
17
+ tags?: string[]
18
+ }
19
+
20
+ interface MediaAssetEditDialogProps {
21
+ asset: MediaAssetForEdit | null
22
+ open: boolean
23
+ onOpenChange: (open: boolean) => void
24
+ onSaved?: () => void
25
+ }
26
+
27
+ export function MediaAssetEditDialog({
28
+ asset,
29
+ open,
30
+ onOpenChange,
31
+ onSaved,
32
+ }: MediaAssetEditDialogProps) {
33
+ const [name, setName] = useState('')
34
+ const [title, setTitle] = useState('')
35
+ const [description, setDescription] = useState('')
36
+ const [altText, setAltText] = useState('')
37
+ const [tagsInput, setTagsInput] = useState('')
38
+ const [isSaving, setIsSaving] = useState(false)
39
+ const [error, setError] = useState('')
40
+
41
+ const updateAsset = useMutation(api.media.updateAsset)
42
+
43
+ const taxonomiesResult = useQuery(api.taxonomies.list, {
44
+ isActive: true,
45
+ paginationOpts: { numItems: 50, cursor: null },
46
+ })
47
+ const taxonomies = taxonomiesResult?.page ?? []
48
+
49
+ useEffect(() => {
50
+ if (asset) {
51
+ setName(asset.name)
52
+ setTitle(asset.title || '')
53
+ setDescription(asset.description || '')
54
+ setAltText(asset.altText || '')
55
+ setTagsInput(asset.tags?.join(', ') || '')
56
+ setError('')
57
+ }
58
+ }, [asset])
59
+
60
+ const handleSave = useCallback(async () => {
61
+ if (!asset) return
62
+
63
+ if (!name.trim()) {
64
+ setError('Filename is required')
65
+ return
66
+ }
67
+
68
+ setIsSaving(true)
69
+ setError('')
70
+
71
+ try {
72
+ const tags = tagsInput
73
+ .split(',')
74
+ .map((t) => t.trim())
75
+ .filter(Boolean)
76
+
77
+ await updateAsset({
78
+ id: asset._id,
79
+ name: name.trim(),
80
+ title: title.trim() || undefined,
81
+ description: description.trim() || undefined,
82
+ altText: altText.trim() || undefined,
83
+ tags: tags.length > 0 ? tags : undefined,
84
+ })
85
+
86
+ onSaved?.()
87
+ onOpenChange(false)
88
+ } catch (err) {
89
+ setError(err instanceof Error ? err.message : 'Failed to update asset')
90
+ } finally {
91
+ setIsSaving(false)
92
+ }
93
+ }, [
94
+ asset,
95
+ name,
96
+ title,
97
+ description,
98
+ altText,
99
+ tagsInput,
100
+ updateAsset,
101
+ onSaved,
102
+ onOpenChange,
103
+ ])
104
+
105
+ if (!asset) return null
106
+
107
+ return (
108
+ <CmsDialog
109
+ open={open}
110
+ onOpenChange={onOpenChange}
111
+ title="Edit File"
112
+ size="md"
113
+ footer={
114
+ <>
115
+ <CmsButton
116
+ variant="outline"
117
+ onClick={() => onOpenChange(false)}
118
+ disabled={isSaving}
119
+ >
120
+ Cancel
121
+ </CmsButton>
122
+ <CmsButton onClick={handleSave} loading={isSaving}>
123
+ Save Changes
124
+ </CmsButton>
125
+ </>
126
+ }
127
+ >
128
+ <div className="space-y-4">
129
+ {error && (
130
+ <div className="rounded-md bg-destructive/10 p-3 text-sm text-destructive">
131
+ {error}
132
+ </div>
133
+ )}
134
+
135
+ <CmsField label="Filename" required htmlFor="asset-name">
136
+ <Input
137
+ id="asset-name"
138
+ value={name}
139
+ onChange={(e) => setName(e.target.value)}
140
+ placeholder="Enter filename"
141
+ />
142
+ </CmsField>
143
+
144
+ <CmsField
145
+ label="Title"
146
+ description="A human-readable title for the file"
147
+ htmlFor="asset-title"
148
+ >
149
+ <Input
150
+ id="asset-title"
151
+ value={title}
152
+ onChange={(e) => setTitle(e.target.value)}
153
+ placeholder="Enter title (optional)"
154
+ />
155
+ </CmsField>
156
+
157
+ <CmsField
158
+ label="Description"
159
+ description="A brief description of the file"
160
+ htmlFor="asset-description"
161
+ >
162
+ <Textarea
163
+ id="asset-description"
164
+ value={description}
165
+ onChange={(e) => setDescription(e.target.value)}
166
+ placeholder="Enter description (optional)"
167
+ rows={3}
168
+ />
169
+ </CmsField>
170
+
171
+ <CmsField
172
+ label="Alt Text"
173
+ description="Alternative text for accessibility (important for images)"
174
+ htmlFor="asset-alt"
175
+ >
176
+ <Input
177
+ id="asset-alt"
178
+ value={altText}
179
+ onChange={(e) => setAltText(e.target.value)}
180
+ placeholder="Describe the image content"
181
+ />
182
+ </CmsField>
183
+
184
+ <CmsField
185
+ label="Quick Tags"
186
+ description="Comma-separated tags for simple organization"
187
+ htmlFor="asset-tags"
188
+ >
189
+ <Input
190
+ id="asset-tags"
191
+ value={tagsInput}
192
+ onChange={(e) => setTagsInput(e.target.value)}
193
+ placeholder="e.g., hero, blog, product"
194
+ />
195
+ </CmsField>
196
+
197
+ {taxonomies.length > 0 && asset && (
198
+ <div className="space-y-4 pt-2 border-t">
199
+ <p className="text-sm text-muted-foreground">
200
+ Organize with taxonomy terms
201
+ </p>
202
+ {taxonomies.map((taxonomy) => (
203
+ <MediaTaxonomyPicker
204
+ key={taxonomy._id}
205
+ mediaId={asset._id}
206
+ taxonomyId={taxonomy._id}
207
+ taxonomyName={taxonomy.displayName}
208
+ allowCreate={taxonomy.allowInlineCreation}
209
+ disabled={isSaving}
210
+ />
211
+ ))}
212
+ </div>
213
+ )}
214
+ </div>
215
+ </CmsDialog>
216
+ )
217
+ }
@@ -0,0 +1,51 @@
1
+ import { CmsButton } from '~/components/cmsds/CmsButton'
2
+ import { FolderInput, Trash2, X } from 'lucide-react'
3
+
4
+ interface MediaBulkActionBarProps {
5
+ selectedCount: number
6
+ onClear: () => void
7
+ onMove: () => void
8
+ onDelete: () => void
9
+ isDeleting?: boolean
10
+ }
11
+
12
+ export function MediaBulkActionBar({
13
+ selectedCount,
14
+ onClear,
15
+ onMove,
16
+ onDelete,
17
+ isDeleting,
18
+ }: MediaBulkActionBarProps) {
19
+ if (selectedCount === 0) return null
20
+
21
+ return (
22
+ <div className="fixed inset-x-0 bottom-0 z-50 border-t bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80">
23
+ <div className="mx-auto flex max-w-7xl items-center justify-between px-6 py-3">
24
+ <div className="flex items-center gap-3">
25
+ <span className="text-sm font-medium">
26
+ {selectedCount} {selectedCount === 1 ? 'file' : 'files'} selected
27
+ </span>
28
+ <CmsButton variant="ghost" size="sm" onClick={onClear}>
29
+ <X className="mr-1 size-4" />
30
+ Clear
31
+ </CmsButton>
32
+ </div>
33
+
34
+ <div className="flex items-center gap-2">
35
+ <CmsButton variant="secondary" onClick={onMove} disabled={isDeleting}>
36
+ <FolderInput className="mr-2 size-4" />
37
+ Move to...
38
+ </CmsButton>
39
+ <CmsButton
40
+ variant="danger"
41
+ onClick={onDelete}
42
+ loading={isDeleting}
43
+ >
44
+ <Trash2 className="mr-2 size-4" />
45
+ Delete
46
+ </CmsButton>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ )
51
+ }
@@ -0,0 +1,69 @@
1
+ import {
2
+ DropdownMenu,
3
+ DropdownMenuContent,
4
+ DropdownMenuItem,
5
+ DropdownMenuSeparator,
6
+ DropdownMenuTrigger,
7
+ } from '~/components/ui/dropdown-menu'
8
+ import { CmsButton } from '~/components/cmsds/CmsButton'
9
+ import { MoreHorizontal, Pencil, FolderInput, Trash2 } from 'lucide-react'
10
+
11
+ export interface MediaFolderForActions {
12
+ _id: string
13
+ name: string
14
+ }
15
+
16
+ interface MediaFolderActionsProps {
17
+ folder: MediaFolderForActions
18
+ onEdit?: () => void
19
+ onMove?: () => void
20
+ onDelete?: () => void
21
+ }
22
+
23
+ export function MediaFolderActions({
24
+ folder: _folder,
25
+ onEdit,
26
+ onMove,
27
+ onDelete,
28
+ }: MediaFolderActionsProps) {
29
+ return (
30
+ <DropdownMenu>
31
+ <DropdownMenuTrigger asChild>
32
+ <CmsButton
33
+ variant="ghost"
34
+ size="icon-sm"
35
+ className="opacity-0 group-hover:opacity-100"
36
+ onClick={(e) => e.stopPropagation()}
37
+ >
38
+ <MoreHorizontal className="size-4" />
39
+ </CmsButton>
40
+ </DropdownMenuTrigger>
41
+ <DropdownMenuContent align="end" onClick={(e) => e.stopPropagation()}>
42
+ {onEdit && (
43
+ <DropdownMenuItem onClick={onEdit}>
44
+ <Pencil className="mr-2 size-4" />
45
+ Rename
46
+ </DropdownMenuItem>
47
+ )}
48
+ {onMove && (
49
+ <DropdownMenuItem onClick={onMove}>
50
+ <FolderInput className="mr-2 size-4" />
51
+ Move to...
52
+ </DropdownMenuItem>
53
+ )}
54
+ {onDelete && (
55
+ <>
56
+ <DropdownMenuSeparator />
57
+ <DropdownMenuItem
58
+ onClick={onDelete}
59
+ className="text-destructive focus:text-destructive"
60
+ >
61
+ <Trash2 className="mr-2 size-4" />
62
+ Delete
63
+ </DropdownMenuItem>
64
+ </>
65
+ )}
66
+ </DropdownMenuContent>
67
+ </DropdownMenu>
68
+ )
69
+ }
@@ -0,0 +1,126 @@
1
+ import { useState, useCallback, useEffect } from 'react'
2
+ import { useMutation } from 'convex/react'
3
+ import { api } from '../../../convex/_generated/api'
4
+ import { CmsDialog } from '~/components/cmsds/CmsDialog'
5
+ import { CmsButton } from '~/components/cmsds/CmsButton'
6
+ import { CmsField } from '~/components/cmsds/CmsField'
7
+ import { Input } from '~/components/ui/input'
8
+ import { Textarea } from '~/components/ui/textarea'
9
+
10
+ export interface MediaFolderForEdit {
11
+ _id: string
12
+ name: string
13
+ description?: string
14
+ }
15
+
16
+ interface MediaFolderEditDialogProps {
17
+ folder: MediaFolderForEdit | null
18
+ open: boolean
19
+ onOpenChange: (open: boolean) => void
20
+ onSaved?: () => void
21
+ }
22
+
23
+ export function MediaFolderEditDialog({
24
+ folder,
25
+ open,
26
+ onOpenChange,
27
+ onSaved,
28
+ }: MediaFolderEditDialogProps) {
29
+ const [name, setName] = useState('')
30
+ const [description, setDescription] = useState('')
31
+ const [isSaving, setIsSaving] = useState(false)
32
+ const [error, setError] = useState('')
33
+
34
+ const updateFolder = useMutation(api.media.updateFolder)
35
+
36
+ useEffect(() => {
37
+ if (folder) {
38
+ setName(folder.name)
39
+ setDescription(folder.description || '')
40
+ setError('')
41
+ }
42
+ }, [folder])
43
+
44
+ const handleSave = useCallback(async () => {
45
+ if (!folder) return
46
+
47
+ if (!name.trim()) {
48
+ setError('Folder name is required')
49
+ return
50
+ }
51
+
52
+ setIsSaving(true)
53
+ setError('')
54
+
55
+ try {
56
+ await updateFolder({
57
+ id: folder._id,
58
+ name: name.trim(),
59
+ description: description.trim() || undefined,
60
+ })
61
+
62
+ onSaved?.()
63
+ onOpenChange(false)
64
+ } catch (err) {
65
+ setError(err instanceof Error ? err.message : 'Failed to update folder')
66
+ } finally {
67
+ setIsSaving(false)
68
+ }
69
+ }, [folder, name, description, updateFolder, onSaved, onOpenChange])
70
+
71
+ if (!folder) return null
72
+
73
+ return (
74
+ <CmsDialog
75
+ open={open}
76
+ onOpenChange={onOpenChange}
77
+ title="Edit Folder"
78
+ size="sm"
79
+ footer={
80
+ <>
81
+ <CmsButton
82
+ variant="outline"
83
+ onClick={() => onOpenChange(false)}
84
+ disabled={isSaving}
85
+ >
86
+ Cancel
87
+ </CmsButton>
88
+ <CmsButton onClick={handleSave} loading={isSaving}>
89
+ Save Changes
90
+ </CmsButton>
91
+ </>
92
+ }
93
+ >
94
+ <div className="space-y-4">
95
+ {error && (
96
+ <div className="rounded-md bg-destructive/10 p-3 text-sm text-destructive">
97
+ {error}
98
+ </div>
99
+ )}
100
+
101
+ <CmsField label="Folder Name" required htmlFor="folder-name">
102
+ <Input
103
+ id="folder-name"
104
+ value={name}
105
+ onChange={(e) => setName(e.target.value)}
106
+ placeholder="Enter folder name"
107
+ />
108
+ </CmsField>
109
+
110
+ <CmsField
111
+ label="Description"
112
+ description="A brief description of the folder contents"
113
+ htmlFor="folder-description"
114
+ >
115
+ <Textarea
116
+ id="folder-description"
117
+ value={description}
118
+ onChange={(e) => setDescription(e.target.value)}
119
+ placeholder="Enter description (optional)"
120
+ rows={3}
121
+ />
122
+ </CmsField>
123
+ </div>
124
+ </CmsDialog>
125
+ )
126
+ }
@@ -0,0 +1,179 @@
1
+ import { useState, useMemo } from 'react'
2
+ import { useQuery, useMutation } from 'convex/react'
3
+ import { api } from '../../../convex/_generated/api'
4
+ import { CmsDialog } from '~/components/cmsds/CmsDialog'
5
+ import { CmsButton } from '~/components/cmsds/CmsButton'
6
+ import { cn } from '~/lib/cn'
7
+ import { Folder, Home, ChevronRight } from 'lucide-react'
8
+
9
+ interface MediaMoveModalProps {
10
+ open: boolean
11
+ onOpenChange: (open: boolean) => void
12
+ assetIds: string[]
13
+ currentFolderId?: string
14
+ onMoved?: () => void
15
+ }
16
+
17
+ interface FolderTreeItem {
18
+ _id: string
19
+ name: string
20
+ parentId?: string
21
+ depth: number
22
+ }
23
+
24
+ export function MediaMoveModal({
25
+ open,
26
+ onOpenChange,
27
+ assetIds,
28
+ currentFolderId,
29
+ onMoved,
30
+ }: MediaMoveModalProps) {
31
+ const [selectedFolderId, setSelectedFolderId] = useState<string | undefined>(
32
+ undefined
33
+ )
34
+ const [isMoving, setIsMoving] = useState(false)
35
+ const [error, setError] = useState('')
36
+
37
+ const folderTree = useQuery(api.media.getFolderTree, {})
38
+ const moveAssets = useMutation(api.media.moveAssets)
39
+
40
+ const sortedFolders = useMemo(() => {
41
+ if (!folderTree) return []
42
+
43
+ const buildTree = (
44
+ parentId: string | undefined,
45
+ depth: number
46
+ ): FolderTreeItem[] => {
47
+ const children = folderTree.filter((f) => f.parentId === parentId)
48
+ return children.flatMap((folder) => [
49
+ { ...folder, depth },
50
+ ...buildTree(folder._id, depth + 1),
51
+ ])
52
+ }
53
+
54
+ return buildTree(undefined, 0)
55
+ }, [folderTree])
56
+
57
+ const handleMove = async () => {
58
+ if (assetIds.length === 0) return
59
+
60
+ setIsMoving(true)
61
+ setError('')
62
+
63
+ try {
64
+ await moveAssets({
65
+ assetIds,
66
+ targetFolderId: selectedFolderId,
67
+ })
68
+ onMoved?.()
69
+ onOpenChange(false)
70
+ } catch (err) {
71
+ setError(err instanceof Error ? err.message : 'Failed to move files')
72
+ } finally {
73
+ setIsMoving(false)
74
+ }
75
+ }
76
+
77
+ const isCurrentFolder = selectedFolderId === currentFolderId
78
+ const isRootSelected = selectedFolderId === undefined
79
+
80
+ return (
81
+ <CmsDialog
82
+ open={open}
83
+ onOpenChange={onOpenChange}
84
+ title="Move Files"
85
+ description={`Select a destination folder for ${assetIds.length} ${assetIds.length === 1 ? 'file' : 'files'}`}
86
+ size="sm"
87
+ footer={
88
+ <>
89
+ <CmsButton
90
+ variant="outline"
91
+ onClick={() => onOpenChange(false)}
92
+ disabled={isMoving}
93
+ >
94
+ Cancel
95
+ </CmsButton>
96
+ <CmsButton
97
+ onClick={handleMove}
98
+ loading={isMoving}
99
+ disabled={isCurrentFolder}
100
+ >
101
+ Move Here
102
+ </CmsButton>
103
+ </>
104
+ }
105
+ >
106
+ <div className="space-y-2">
107
+ {error && (
108
+ <div className="rounded-md bg-destructive/10 p-3 text-sm text-destructive">
109
+ {error}
110
+ </div>
111
+ )}
112
+
113
+ <div className="max-h-[300px] overflow-y-auto rounded-md border">
114
+ {/* Root folder option */}
115
+ <button
116
+ type="button"
117
+ className={cn(
118
+ 'flex w-full items-center gap-2 px-3 py-2 text-left text-sm transition-colors hover:bg-muted',
119
+ isRootSelected && 'bg-primary/10 text-primary',
120
+ currentFolderId === undefined && 'opacity-50'
121
+ )}
122
+ onClick={() => setSelectedFolderId(undefined)}
123
+ >
124
+ <Home className="size-4" />
125
+ <span className="font-medium">Root (All Files)</span>
126
+ {currentFolderId === undefined && (
127
+ <span className="ml-auto text-xs text-muted-foreground">
128
+ Current
129
+ </span>
130
+ )}
131
+ </button>
132
+
133
+ {/* Folder tree */}
134
+ {sortedFolders.map((folder) => {
135
+ const isCurrent = folder._id === currentFolderId
136
+ const isSelected = folder._id === selectedFolderId
137
+
138
+ return (
139
+ <button
140
+ key={folder._id}
141
+ type="button"
142
+ className={cn(
143
+ 'flex w-full items-center gap-2 px-3 py-2 text-left text-sm transition-colors hover:bg-muted',
144
+ isSelected && 'bg-primary/10 text-primary',
145
+ isCurrent && 'opacity-50'
146
+ )}
147
+ style={{ paddingLeft: `${12 + folder.depth * 20}px` }}
148
+ onClick={() => setSelectedFolderId(folder._id)}
149
+ >
150
+ {folder.depth > 0 && (
151
+ <ChevronRight className="size-3 text-muted-foreground" />
152
+ )}
153
+ <Folder className="size-4 text-amber-500" />
154
+ <span className="truncate">{folder.name}</span>
155
+ {isCurrent && (
156
+ <span className="ml-auto text-xs text-muted-foreground">
157
+ Current
158
+ </span>
159
+ )}
160
+ </button>
161
+ )
162
+ })}
163
+
164
+ {sortedFolders.length === 0 && (
165
+ <div className="px-3 py-6 text-center text-sm text-muted-foreground">
166
+ No folders yet. Create folders to organize your files.
167
+ </div>
168
+ )}
169
+ </div>
170
+
171
+ {isCurrentFolder && (
172
+ <p className="text-xs text-muted-foreground">
173
+ Files are already in this folder
174
+ </p>
175
+ )}
176
+ </div>
177
+ </CmsDialog>
178
+ )
179
+ }