convex-cms 0.0.5-alpha.0 → 0.0.5-alpha.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 (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 +187 -194
  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,279 @@
1
+ import { useState, useCallback } from 'react'
2
+ import { useQuery, useMutation } from 'convex/react'
3
+ import { api } from '../../convex/_generated/api'
4
+ import { VersionCompare } from './VersionCompare'
5
+ import { VersionRollbackModal } from './VersionRollbackModal'
6
+ import { CmsButton } from '~/components/cmsds/CmsButton'
7
+ import { CmsStatusBadge } from '~/components/cmsds/CmsStatusBadge'
8
+ import { Badge } from '~/components/ui/badge'
9
+ import { ScrollArea } from '~/components/ui/scroll-area'
10
+ import { X, CheckCircle, History } from 'lucide-react'
11
+ import { cn } from '~/lib/cn'
12
+
13
+ interface VersionHistoryProps {
14
+ entryId: string
15
+ currentVersion: number
16
+ onRollbackComplete?: () => void
17
+ onClose: () => void
18
+ }
19
+
20
+ interface VersionItem {
21
+ _id: string
22
+ versionNumber: number
23
+ changeDescription?: string
24
+ createdBy?: string
25
+ _creationTime: number
26
+ status: string
27
+ data: Record<string, unknown>
28
+ wasPublished?: boolean
29
+ }
30
+
31
+ export function VersionHistory({
32
+ entryId,
33
+ currentVersion,
34
+ onRollbackComplete,
35
+ onClose,
36
+ }: VersionHistoryProps) {
37
+ const [selectedVersions, setSelectedVersions] = useState<
38
+ [number, number] | null
39
+ >(null)
40
+ const [rollbackTarget, setRollbackTarget] = useState<number | null>(null)
41
+ const [isRollingBack, setIsRollingBack] = useState(false)
42
+ const [rollbackError, setRollbackError] = useState<string | null>(null)
43
+ const [rollbackSuccess, setRollbackSuccess] = useState(false)
44
+
45
+ const versionsQuery = useQuery(api.versions.getHistory, {
46
+ entryId,
47
+ paginationOpts: { numItems: 50, cursor: null },
48
+ })
49
+
50
+ const rollbackMutation = useMutation(api.versions.rollback)
51
+
52
+ const versions = (versionsQuery?.page ?? []) as VersionItem[]
53
+ const isLoading = versionsQuery === undefined
54
+
55
+ const handleCompare = useCallback(
56
+ (fromVersion: number, toVersion: number) => {
57
+ setSelectedVersions([fromVersion, toVersion])
58
+ },
59
+ []
60
+ )
61
+
62
+ const handleRollback = useCallback((versionNumber: number) => {
63
+ setRollbackTarget(versionNumber)
64
+ setRollbackError(null)
65
+ }, [])
66
+
67
+ const handleConfirmRollback = useCallback(async () => {
68
+ if (rollbackTarget === null) return
69
+
70
+ setIsRollingBack(true)
71
+ setRollbackError(null)
72
+
73
+ try {
74
+ await rollbackMutation({
75
+ entryId,
76
+ versionNumber: rollbackTarget,
77
+ })
78
+ setRollbackTarget(null)
79
+ setRollbackSuccess(true)
80
+ setTimeout(() => {
81
+ setRollbackSuccess(false)
82
+ onRollbackComplete?.()
83
+ }, 1500)
84
+ } catch (error) {
85
+ const message =
86
+ error instanceof Error ? error.message : 'Failed to rollback'
87
+ setRollbackError(message)
88
+ } finally {
89
+ setIsRollingBack(false)
90
+ }
91
+ }, [entryId, rollbackTarget, rollbackMutation, onRollbackComplete])
92
+
93
+ const formatDate = (timestamp: number) => {
94
+ return new Date(timestamp).toLocaleString(undefined, {
95
+ year: 'numeric',
96
+ month: 'short',
97
+ day: 'numeric',
98
+ hour: '2-digit',
99
+ minute: '2-digit',
100
+ })
101
+ }
102
+
103
+ // Render compare view or history list - keep outer container stable to avoid DOM issues
104
+ if (selectedVersions) {
105
+ return (
106
+ <div className="flex h-full flex-col border-l bg-background">
107
+ <VersionCompare
108
+ entryId={entryId}
109
+ fromVersion={selectedVersions[0]}
110
+ toVersion={selectedVersions[1]}
111
+ onClose={() => setSelectedVersions(null)}
112
+ onRollback={(version) => {
113
+ setSelectedVersions(null)
114
+ handleRollback(version)
115
+ }}
116
+ />
117
+ {rollbackTarget !== null && (
118
+ <VersionRollbackModal
119
+ targetVersion={rollbackTarget}
120
+ currentVersion={currentVersion}
121
+ isLoading={isRollingBack}
122
+ error={rollbackError}
123
+ onConfirm={handleConfirmRollback}
124
+ onCancel={() => {
125
+ setRollbackTarget(null)
126
+ setRollbackError(null)
127
+ }}
128
+ />
129
+ )}
130
+ </div>
131
+ )
132
+ }
133
+
134
+ return (
135
+ <div className="flex h-full flex-col border-l bg-background">
136
+ <div className="flex items-center justify-between border-b px-4 py-3">
137
+ <div className="flex items-center gap-2">
138
+ <History className="size-4 text-muted-foreground" />
139
+ <h3 className="font-semibold">Version History</h3>
140
+ </div>
141
+ <button
142
+ type="button"
143
+ onClick={onClose}
144
+ className="rounded p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
145
+ aria-label="Close version history"
146
+ >
147
+ <X className="size-4" />
148
+ </button>
149
+ </div>
150
+
151
+ {rollbackSuccess && (
152
+ <div className="flex items-center gap-2 border-b bg-emerald-50 px-4 py-2 text-sm text-emerald-800">
153
+ <CheckCircle className="size-4" />
154
+ Successfully rolled back to previous version
155
+ </div>
156
+ )}
157
+
158
+ <ScrollArea className="min-h-0 flex-1">
159
+ <div className="p-4">
160
+ {isLoading ? (
161
+ <div className="flex flex-col items-center justify-center py-8">
162
+ <div className="size-6 animate-spin rounded-full border-2 border-muted border-t-primary" />
163
+ <p className="mt-2 text-sm text-muted-foreground">
164
+ Loading versions...
165
+ </p>
166
+ </div>
167
+ ) : versions.length === 0 ? (
168
+ <div className="py-8 text-center text-sm text-muted-foreground">
169
+ Save changes to start building version history
170
+ </div>
171
+ ) : (
172
+ <div className="space-y-3">
173
+ {versions.map((version, index) => {
174
+ const isCurrent = version.versionNumber === currentVersion
175
+ const prevVersion = versions[index + 1]
176
+
177
+ return (
178
+ <div
179
+ key={version._id}
180
+ className={cn(
181
+ 'rounded-lg border p-3 transition-colors',
182
+ isCurrent ? 'border-primary/50 bg-primary/5' : 'bg-card'
183
+ )}
184
+ >
185
+ <div className="flex items-center justify-between">
186
+ <div className="flex items-center gap-2">
187
+ <Badge variant="secondary" className="font-mono">
188
+ v{version.versionNumber}
189
+ </Badge>
190
+ {isCurrent && (
191
+ <Badge
192
+ variant="outline"
193
+ className="border-primary/50 text-primary"
194
+ >
195
+ Current
196
+ </Badge>
197
+ )}
198
+ {version.wasPublished && (
199
+ <Badge
200
+ variant="outline"
201
+ className="border-emerald-500/50 text-emerald-600"
202
+ >
203
+ Published
204
+ </Badge>
205
+ )}
206
+ </div>
207
+ <CmsStatusBadge
208
+ status={
209
+ version.status as
210
+ | 'draft'
211
+ | 'published'
212
+ | 'scheduled'
213
+ | 'archived'
214
+ }
215
+ />
216
+ </div>
217
+
218
+ <div className="mt-2 text-xs text-muted-foreground">
219
+ <span>{formatDate(version._creationTime)}</span>
220
+ {version.createdBy && (
221
+ <span className="ml-2">by {version.createdBy}</span>
222
+ )}
223
+ </div>
224
+
225
+ {version.changeDescription && (
226
+ <p className="mt-2 text-sm text-muted-foreground">
227
+ {version.changeDescription}
228
+ </p>
229
+ )}
230
+
231
+ <div className="mt-3 flex gap-2">
232
+ {prevVersion && (
233
+ <CmsButton
234
+ variant="outline"
235
+ size="sm"
236
+ onClick={() =>
237
+ handleCompare(
238
+ prevVersion.versionNumber,
239
+ version.versionNumber
240
+ )
241
+ }
242
+ >
243
+ Compare with v{prevVersion.versionNumber}
244
+ </CmsButton>
245
+ )}
246
+ {!isCurrent && (
247
+ <CmsButton
248
+ variant="ghost"
249
+ size="sm"
250
+ onClick={() => handleRollback(version.versionNumber)}
251
+ >
252
+ Rollback
253
+ </CmsButton>
254
+ )}
255
+ </div>
256
+ </div>
257
+ )
258
+ })}
259
+ </div>
260
+ )}
261
+ </div>
262
+ </ScrollArea>
263
+
264
+ {rollbackTarget !== null && (
265
+ <VersionRollbackModal
266
+ targetVersion={rollbackTarget}
267
+ currentVersion={currentVersion}
268
+ isLoading={isRollingBack}
269
+ error={rollbackError}
270
+ onConfirm={handleConfirmRollback}
271
+ onCancel={() => {
272
+ setRollbackTarget(null)
273
+ setRollbackError(null)
274
+ }}
275
+ />
276
+ )}
277
+ </div>
278
+ )
279
+ }
@@ -0,0 +1,79 @@
1
+ import { CmsDialog } from '~/components/cmsds/CmsDialog'
2
+ import { CmsButton } from '~/components/cmsds/CmsButton'
3
+ import { AlertTriangle } from 'lucide-react'
4
+
5
+ interface VersionRollbackModalProps {
6
+ targetVersion: number
7
+ currentVersion: number
8
+ isLoading: boolean
9
+ error: string | null
10
+ onConfirm: () => void
11
+ onCancel: () => void
12
+ }
13
+
14
+ export function VersionRollbackModal({
15
+ targetVersion,
16
+ currentVersion,
17
+ isLoading,
18
+ error,
19
+ onConfirm,
20
+ onCancel,
21
+ }: VersionRollbackModalProps) {
22
+ return (
23
+ <CmsDialog
24
+ open={true}
25
+ onOpenChange={(open) => !open && !isLoading && onCancel()}
26
+ title="Confirm Rollback"
27
+ size="sm"
28
+ footer={
29
+ <>
30
+ <CmsButton variant="outline" onClick={onCancel} disabled={isLoading}>
31
+ Cancel
32
+ </CmsButton>
33
+ <CmsButton variant="warning" onClick={onConfirm} loading={isLoading}>
34
+ Rollback to v{targetVersion}
35
+ </CmsButton>
36
+ </>
37
+ }
38
+ >
39
+ <div className="space-y-4">
40
+ <p className="text-sm text-muted-foreground">
41
+ You are about to rollback from{' '}
42
+ <span className="font-semibold text-foreground">
43
+ version {currentVersion}
44
+ </span>{' '}
45
+ to{' '}
46
+ <span className="font-semibold text-foreground">
47
+ version {targetVersion}
48
+ </span>
49
+ .
50
+ </p>
51
+
52
+ <div className="rounded-lg border border-amber-200 bg-amber-50 p-3">
53
+ <div className="flex gap-2">
54
+ <AlertTriangle className="mt-0.5 size-4 shrink-0 text-amber-600" />
55
+ <div className="space-y-2">
56
+ <p className="text-sm font-medium text-amber-800">
57
+ This action will:
58
+ </p>
59
+ <ul className="space-y-1 text-sm text-amber-700">
60
+ <li>
61
+ • Create a new version with the content from version{' '}
62
+ {targetVersion}
63
+ </li>
64
+ <li>• The current version will be preserved in history</li>
65
+ <li>• Any unsaved changes will be lost</li>
66
+ </ul>
67
+ </div>
68
+ </div>
69
+ </div>
70
+
71
+ {error && (
72
+ <div className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-800">
73
+ <span className="font-medium">Error:</span> {error}
74
+ </div>
75
+ )}
76
+ </div>
77
+ </CmsDialog>
78
+ )
79
+ }
@@ -0,0 +1,101 @@
1
+ import * as React from 'react'
2
+ import { Button } from '~/components/ui/button'
3
+ import { cn } from '~/lib/cn'
4
+ import { motion } from '~/lib/motion'
5
+
6
+ type ButtonProps = React.ComponentProps<typeof Button>
7
+
8
+ export interface CmsButtonProps extends Omit<ButtonProps, 'variant'> {
9
+ variant?:
10
+ | 'primary'
11
+ | 'secondary'
12
+ | 'danger'
13
+ | 'ghost'
14
+ | 'outline'
15
+ | 'link'
16
+ | 'success'
17
+ | 'warning'
18
+ loading?: boolean
19
+ }
20
+
21
+ const variantMap = {
22
+ primary: 'default',
23
+ secondary: 'secondary',
24
+ danger: 'destructive',
25
+ ghost: 'ghost',
26
+ outline: 'outline',
27
+ link: 'link',
28
+ success: 'default',
29
+ warning: 'default',
30
+ } as const
31
+
32
+ const customVariantClasses = {
33
+ success:
34
+ 'bg-emerald-600 text-white hover:bg-emerald-700 focus-visible:ring-emerald-500',
35
+ warning:
36
+ 'bg-amber-500 text-white hover:bg-amber-600 focus-visible:ring-amber-500',
37
+ } as Record<string, string>
38
+
39
+ const LoadingSpinner = () => (
40
+ <svg
41
+ className="size-4 animate-spin"
42
+ xmlns="http://www.w3.org/2000/svg"
43
+ fill="none"
44
+ viewBox="0 0 24 24"
45
+ >
46
+ <circle
47
+ className="opacity-25"
48
+ cx="12"
49
+ cy="12"
50
+ r="10"
51
+ stroke="currentColor"
52
+ strokeWidth="4"
53
+ />
54
+ <path
55
+ className="opacity-75"
56
+ fill="currentColor"
57
+ d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
58
+ />
59
+ </svg>
60
+ )
61
+
62
+ export function CmsButton({
63
+ variant = 'primary',
64
+ loading,
65
+ disabled,
66
+ children,
67
+ className,
68
+ asChild,
69
+ ...props
70
+ }: CmsButtonProps) {
71
+ const mappedVariant = variantMap[variant]
72
+ const customClass = customVariantClasses[variant]
73
+
74
+ // When asChild is true, Slot expects exactly one child
75
+ // Don't render loading spinner as sibling - just pass children through
76
+ if (asChild) {
77
+ return (
78
+ <Button
79
+ variant={mappedVariant}
80
+ disabled={disabled || loading}
81
+ className={cn(motion.fast, customClass, className)}
82
+ asChild
83
+ {...props}
84
+ >
85
+ {children}
86
+ </Button>
87
+ )
88
+ }
89
+
90
+ return (
91
+ <Button
92
+ variant={mappedVariant}
93
+ disabled={disabled || loading}
94
+ className={cn(motion.fast, customClass, className)}
95
+ {...props}
96
+ >
97
+ {loading && <LoadingSpinner />}
98
+ {children}
99
+ </Button>
100
+ )
101
+ }
@@ -0,0 +1,139 @@
1
+ import * as React from 'react'
2
+ import {
3
+ Dialog,
4
+ DialogContent,
5
+ DialogDescription,
6
+ DialogFooter,
7
+ DialogHeader,
8
+ DialogTitle,
9
+ } from '~/components/ui/dialog'
10
+ import { CmsButton } from './CmsButton'
11
+ import { cn } from '~/lib/cn'
12
+
13
+ export interface CmsDialogProps {
14
+ open: boolean
15
+ onOpenChange: (open: boolean) => void
16
+ title: string
17
+ description?: string
18
+ children: React.ReactNode
19
+ footer?: React.ReactNode
20
+ size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'
21
+ className?: string
22
+ }
23
+
24
+ const sizeClasses = {
25
+ sm: 'max-w-sm',
26
+ md: 'max-w-md',
27
+ lg: 'max-w-lg',
28
+ xl: 'max-w-xl',
29
+ '2xl': 'max-w-2xl',
30
+ } as const
31
+
32
+ export function CmsDialog({
33
+ open,
34
+ onOpenChange,
35
+ title,
36
+ description,
37
+ children,
38
+ footer,
39
+ size = 'md',
40
+ className,
41
+ }: CmsDialogProps) {
42
+ return (
43
+ <Dialog open={open} onOpenChange={onOpenChange}>
44
+ <DialogContent
45
+ className={cn(
46
+ 'flex max-h-[85vh] flex-col overflow-hidden',
47
+ sizeClasses[size],
48
+ className
49
+ )}
50
+ >
51
+ <DialogHeader className="shrink-0">
52
+ <DialogTitle>{title}</DialogTitle>
53
+ {description && <DialogDescription>{description}</DialogDescription>}
54
+ </DialogHeader>
55
+ <div className="min-h-0 flex-1 py-4 scrollbar-none">
56
+ {children}
57
+ </div>
58
+ {footer && <DialogFooter className="shrink-0 border-t pt-4">{footer}</DialogFooter>}
59
+ </DialogContent>
60
+ </Dialog>
61
+ )
62
+ }
63
+
64
+ export interface CmsConfirmDialogProps {
65
+ open: boolean
66
+ onOpenChange: (open: boolean) => void
67
+ title: string
68
+ description: string
69
+ confirmLabel?: string
70
+ cancelLabel?: string
71
+ onConfirm: () => void
72
+ onCancel?: () => void
73
+ variant?: 'default' | 'danger' | 'primary' | 'warning'
74
+ isLoading?: boolean
75
+ loading?: boolean
76
+ error?: string | null
77
+ }
78
+
79
+ export function CmsConfirmDialog({
80
+ open,
81
+ onOpenChange,
82
+ title,
83
+ description,
84
+ confirmLabel = 'Confirm',
85
+ cancelLabel = 'Cancel',
86
+ onConfirm,
87
+ onCancel,
88
+ variant = 'default',
89
+ loading,
90
+ isLoading,
91
+ error,
92
+ }: CmsConfirmDialogProps) {
93
+ const isLoadingState = loading ?? isLoading ?? false
94
+
95
+ const handleCancel = () => {
96
+ onCancel?.()
97
+ onOpenChange(false)
98
+ }
99
+
100
+ const handleConfirm = () => {
101
+ onConfirm()
102
+ }
103
+
104
+ const getButtonVariant = () => {
105
+ if (variant === 'danger') return 'danger'
106
+ if (variant === 'warning') return 'warning'
107
+ return 'primary'
108
+ }
109
+
110
+ return (
111
+ <CmsDialog
112
+ open={open}
113
+ onOpenChange={onOpenChange}
114
+ title={title}
115
+ size="sm"
116
+ footer={
117
+ <>
118
+ <CmsButton variant="outline" onClick={handleCancel} disabled={isLoadingState}>
119
+ {cancelLabel}
120
+ </CmsButton>
121
+ <CmsButton
122
+ variant={getButtonVariant()}
123
+ onClick={handleConfirm}
124
+ loading={isLoadingState}
125
+ >
126
+ {confirmLabel}
127
+ </CmsButton>
128
+ </>
129
+ }
130
+ >
131
+ <div className="space-y-3">
132
+ <p className="text-sm text-muted-foreground">{description}</p>
133
+ {error && (
134
+ <p className="text-sm text-destructive">{error}</p>
135
+ )}
136
+ </div>
137
+ </CmsDialog>
138
+ )
139
+ }
@@ -0,0 +1,62 @@
1
+ import * as React from 'react'
2
+ import {
3
+ DropdownMenu,
4
+ DropdownMenuContent,
5
+ DropdownMenuItem,
6
+ DropdownMenuSeparator,
7
+ DropdownMenuTrigger,
8
+ } from '~/components/ui/dropdown-menu'
9
+ import { CmsButton } from './CmsButton'
10
+ import { MoreHorizontal } from 'lucide-react'
11
+
12
+ export interface CmsDropdownAction {
13
+ label: string
14
+ icon?: React.ReactNode
15
+ onClick: () => void
16
+ variant?: 'default' | 'danger'
17
+ disabled?: boolean
18
+ }
19
+
20
+ export interface CmsDropdownProps {
21
+ actions: (CmsDropdownAction | 'separator')[]
22
+ trigger?: React.ReactNode
23
+ align?: 'start' | 'center' | 'end'
24
+ }
25
+
26
+ export function CmsDropdown({ actions, trigger, align = 'end' }: CmsDropdownProps) {
27
+ return (
28
+ <DropdownMenu>
29
+ <DropdownMenuTrigger asChild>
30
+ {trigger ?? (
31
+ <CmsButton variant="ghost" size="icon" className="size-8">
32
+ <MoreHorizontal className="size-4" />
33
+ <span className="sr-only">Open menu</span>
34
+ </CmsButton>
35
+ )}
36
+ </DropdownMenuTrigger>
37
+ <DropdownMenuContent align={align} className="w-48">
38
+ {actions.map((action, index) => {
39
+ if (action === 'separator') {
40
+ return <DropdownMenuSeparator key={`sep-${index}`} />
41
+ }
42
+
43
+ return (
44
+ <DropdownMenuItem
45
+ key={action.label}
46
+ onClick={action.onClick}
47
+ disabled={action.disabled}
48
+ className={
49
+ action.variant === 'danger'
50
+ ? 'text-destructive focus:text-destructive'
51
+ : undefined
52
+ }
53
+ >
54
+ {action.icon && <span className="mr-2">{action.icon}</span>}
55
+ {action.label}
56
+ </DropdownMenuItem>
57
+ )
58
+ })}
59
+ </DropdownMenuContent>
60
+ </DropdownMenu>
61
+ )
62
+ }