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,217 @@
1
+ /**
2
+ * Type definitions for field renderer components.
3
+ *
4
+ * These types define the props interface for all field renderers,
5
+ * ensuring consistent behavior across different field types.
6
+ */
7
+
8
+ /**
9
+ * Built-in field types supported by the CMS.
10
+ */
11
+ export type BuiltInFieldType =
12
+ | 'text'
13
+ | 'richText'
14
+ | 'number'
15
+ | 'boolean'
16
+ | 'date'
17
+ | 'datetime'
18
+ | 'reference'
19
+ | 'media'
20
+ | 'json'
21
+ | 'select'
22
+ | 'multiSelect'
23
+ | 'tags'
24
+ | 'category';
25
+
26
+ /**
27
+ * Field types supported by the CMS.
28
+ * Includes built-in types and allows custom types via string.
29
+ */
30
+ export type FieldType = BuiltInFieldType | (string & {});
31
+
32
+ /**
33
+ * Select option for select/multiSelect fields.
34
+ */
35
+ export interface SelectOption {
36
+ value: string;
37
+ label: string;
38
+ }
39
+
40
+ /**
41
+ * Field-specific options that control validation and behavior.
42
+ * These are passed from the content type field definition.
43
+ */
44
+ export interface FieldOptions {
45
+ // Text fields
46
+ minLength?: number;
47
+ maxLength?: number;
48
+ pattern?: string;
49
+
50
+ // Number fields
51
+ min?: number;
52
+ max?: number;
53
+ step?: number;
54
+ /** Number of decimal places. 0 for integer. */
55
+ precision?: number;
56
+
57
+ // Reference fields
58
+ allowedContentTypes?: string[];
59
+ multiple?: boolean;
60
+ minItems?: number;
61
+
62
+ // Media fields
63
+ allowedMimeTypes?: string[];
64
+ maxFileSize?: number;
65
+
66
+ // Select fields
67
+ options?: SelectOption[];
68
+
69
+ // Rich text fields
70
+ allowedBlocks?: string[];
71
+ allowedMarks?: string[];
72
+
73
+ // Tag fields
74
+ taxonomyId?: string;
75
+ allowCreate?: boolean;
76
+ maxTags?: number;
77
+ minTags?: number;
78
+
79
+ // Category fields
80
+ allowMultiple?: boolean;
81
+ }
82
+
83
+ /**
84
+ * Field definition as stored in content type.
85
+ */
86
+ export interface FieldDefinition {
87
+ /** Unique field identifier within the content type */
88
+ name: string;
89
+ /** Human-readable label */
90
+ label: string;
91
+ /** Field type */
92
+ type: FieldType;
93
+ /** Whether the field is required */
94
+ required: boolean;
95
+ /** Whether the field is searchable */
96
+ searchable?: boolean;
97
+ /** Whether the field supports localization */
98
+ localized?: boolean;
99
+ /** Help text displayed below the field */
100
+ description?: string;
101
+ /** Default value for new entries */
102
+ defaultValue?: unknown;
103
+ /** Type-specific options */
104
+ options?: FieldOptions;
105
+ }
106
+
107
+ /**
108
+ * Validation error for a field.
109
+ */
110
+ export interface FieldError {
111
+ /** Error message to display */
112
+ message: string;
113
+ /** Optional error code for programmatic handling */
114
+ code?: string;
115
+ }
116
+
117
+ /**
118
+ * Base props shared by all field renderer components.
119
+ */
120
+ export interface BaseFieldProps<T = unknown> {
121
+ /** The field definition from the content type */
122
+ field: FieldDefinition;
123
+ /** Current value of the field */
124
+ value: T;
125
+ /** Callback when the value changes */
126
+ onChange: (value: T) => void;
127
+ /** Validation error to display */
128
+ error?: FieldError;
129
+ /** Whether the field is disabled */
130
+ disabled?: boolean;
131
+ /** Whether the field is in read-only mode */
132
+ readOnly?: boolean;
133
+ /** Optional CSS class name */
134
+ className?: string;
135
+ /** Unique ID for the field (for label association) */
136
+ id?: string;
137
+ }
138
+
139
+ /**
140
+ * Props for text input field.
141
+ */
142
+ export interface TextFieldProps extends BaseFieldProps<string> {
143
+ /** Placeholder text */
144
+ placeholder?: string;
145
+ /** Input type (text, email, url, etc.) */
146
+ inputType?: 'text' | 'email' | 'url' | 'tel';
147
+ }
148
+
149
+ /**
150
+ * Props for textarea field.
151
+ */
152
+ export interface TextAreaFieldProps extends BaseFieldProps<string> {
153
+ /** Placeholder text */
154
+ placeholder?: string;
155
+ /** Number of visible rows */
156
+ rows?: number;
157
+ /** Whether to auto-resize based on content */
158
+ autoResize?: boolean;
159
+ }
160
+
161
+ /**
162
+ * Props for number input field.
163
+ */
164
+ export interface NumberFieldProps extends BaseFieldProps<number | null> {
165
+ /** Placeholder text */
166
+ placeholder?: string;
167
+ }
168
+
169
+ /**
170
+ * Props for boolean toggle field.
171
+ */
172
+ export interface BooleanFieldProps extends BaseFieldProps<boolean> {
173
+ /** Label for the true state */
174
+ trueLabel?: string;
175
+ /** Label for the false state */
176
+ falseLabel?: string;
177
+ }
178
+
179
+ /**
180
+ * Props for date picker field.
181
+ */
182
+ export interface DateFieldProps extends BaseFieldProps<string | null> {
183
+ /** Whether to include time picker (datetime) */
184
+ includeTime?: boolean;
185
+ /** Placeholder text */
186
+ placeholder?: string;
187
+ }
188
+
189
+ /**
190
+ * Props for rich text (markdown) field.
191
+ */
192
+ export interface RichTextFieldProps extends BaseFieldProps<string> {
193
+ /** Placeholder text */
194
+ placeholder?: string;
195
+ /** Minimum height for the editor */
196
+ minHeight?: number;
197
+ }
198
+
199
+ /**
200
+ * Props for the unified FieldRenderer component.
201
+ */
202
+ export interface FieldRendererProps {
203
+ /** The field definition from the content type */
204
+ field: FieldDefinition;
205
+ /** Current value of the field */
206
+ value: unknown;
207
+ /** Callback when the value changes */
208
+ onChange: (value: unknown) => void;
209
+ /** Validation error to display */
210
+ error?: FieldError;
211
+ /** Whether the field is disabled */
212
+ disabled?: boolean;
213
+ /** Whether the field is in read-only mode */
214
+ readOnly?: boolean;
215
+ /** Optional CSS class name */
216
+ className?: string;
217
+ }
@@ -0,0 +1,254 @@
1
+ import { useState, useCallback, useMemo } from 'react'
2
+ import { useQuery } from 'convex/react'
3
+ import { api } from '../../../convex/_generated/api'
4
+ import { CmsButton } from '~/components/cmsds/CmsButton'
5
+ import {
6
+ Popover,
7
+ PopoverContent,
8
+ PopoverTrigger,
9
+ } from '~/components/ui/popover'
10
+ import {
11
+ Command,
12
+ CommandEmpty,
13
+ CommandGroup,
14
+ CommandInput,
15
+ CommandItem,
16
+ CommandList,
17
+ CommandSeparator,
18
+ } from '~/components/ui/command'
19
+ import { Badge } from '~/components/ui/badge'
20
+ import { Checkbox } from '~/components/ui/checkbox'
21
+ import { cn } from '~/lib/cn'
22
+ import { Tags, ChevronDown, X, Check } from 'lucide-react'
23
+
24
+ interface TaxonomyTerm {
25
+ _id: string
26
+ name: string
27
+ slug: string
28
+ color?: string
29
+ usageCount: number
30
+ }
31
+
32
+ export interface TaxonomyFilterProps {
33
+ selectedTermIds: string[]
34
+ onChange: (termIds: string[]) => void
35
+ taxonomyId?: string
36
+ placeholder?: string
37
+ disabled?: boolean
38
+ className?: string
39
+ }
40
+
41
+ export function TaxonomyFilter({
42
+ selectedTermIds,
43
+ onChange,
44
+ taxonomyId,
45
+ placeholder = 'Filter by tags...',
46
+ disabled = false,
47
+ className,
48
+ }: TaxonomyFilterProps) {
49
+ const [open, setOpen] = useState(false)
50
+ const [search, setSearch] = useState('')
51
+
52
+ const taxonomiesResult = useQuery(api.taxonomies.list, { isActive: true })
53
+ const taxonomies = taxonomiesResult?.page ?? []
54
+
55
+ const activeTaxonomy = useMemo(() => {
56
+ if (taxonomyId) {
57
+ return taxonomies.find((t) => t._id === taxonomyId)
58
+ }
59
+ return null
60
+ }, [taxonomyId, taxonomies])
61
+
62
+ const targetTaxonomyId = taxonomyId ?? taxonomies[0]?._id
63
+
64
+ const termsResult = useQuery(
65
+ api.taxonomies.listTerms,
66
+ targetTaxonomyId
67
+ ? {
68
+ taxonomyId: targetTaxonomyId,
69
+ paginationOpts: { numItems: 200, cursor: null },
70
+ }
71
+ : 'skip'
72
+ )
73
+ const terms = (termsResult?.page ?? []) as TaxonomyTerm[]
74
+
75
+ const selectedTermsDetails = useMemo(() => {
76
+ return terms.filter((t) => selectedTermIds.includes(t._id))
77
+ }, [terms, selectedTermIds])
78
+
79
+ const filteredTerms = useMemo(() => {
80
+ if (!search.trim()) return terms
81
+ const lowerSearch = search.toLowerCase()
82
+ return terms.filter((term) => term.name.toLowerCase().includes(lowerSearch))
83
+ }, [terms, search])
84
+
85
+ const handleToggleTerm = useCallback(
86
+ (termId: string) => {
87
+ if (selectedTermIds.includes(termId)) {
88
+ onChange(selectedTermIds.filter((id) => id !== termId))
89
+ } else {
90
+ onChange([...selectedTermIds, termId])
91
+ }
92
+ },
93
+ [selectedTermIds, onChange]
94
+ )
95
+
96
+ const handleClear = useCallback(() => {
97
+ onChange([])
98
+ setOpen(false)
99
+ }, [onChange])
100
+
101
+ const handleRemoveTerm = useCallback(
102
+ (termId: string, e: React.MouseEvent) => {
103
+ e.stopPropagation()
104
+ onChange(selectedTermIds.filter((id) => id !== termId))
105
+ },
106
+ [selectedTermIds, onChange]
107
+ )
108
+
109
+ const displayTaxonomyName = activeTaxonomy?.displayName ?? taxonomies[0]?.displayName ?? 'Tags'
110
+ const isLoading = taxonomiesResult === undefined || (!!targetTaxonomyId && termsResult === undefined)
111
+ const hasNoTaxonomies = taxonomies.length === 0 && taxonomiesResult !== undefined
112
+
113
+ if (hasNoTaxonomies) {
114
+ return null
115
+ }
116
+
117
+ return (
118
+ <Popover open={open} onOpenChange={setOpen}>
119
+ <PopoverTrigger asChild>
120
+ <CmsButton
121
+ variant="outline"
122
+ role="combobox"
123
+ aria-expanded={open}
124
+ disabled={disabled || isLoading}
125
+ className={cn(
126
+ 'h-9 min-w-[140px] justify-between gap-2',
127
+ selectedTermIds.length > 0 && 'border-primary/50',
128
+ className
129
+ )}
130
+ >
131
+ <div className="flex items-center gap-2">
132
+ <Tags className="size-4 text-muted-foreground" />
133
+ {selectedTermIds.length === 0 ? (
134
+ <span className="text-muted-foreground">{placeholder}</span>
135
+ ) : selectedTermIds.length === 1 ? (
136
+ <span className="max-w-[100px] truncate">
137
+ {selectedTermsDetails[0]?.name ?? 'Tag'}
138
+ </span>
139
+ ) : (
140
+ <span>{selectedTermIds.length} tags</span>
141
+ )}
142
+ </div>
143
+ <div className="flex items-center gap-1">
144
+ {selectedTermIds.length > 0 && (
145
+ <Badge
146
+ variant="secondary"
147
+ className="size-5 rounded-full p-0 text-xs"
148
+ >
149
+ {selectedTermIds.length}
150
+ </Badge>
151
+ )}
152
+ <ChevronDown className="size-4 text-muted-foreground" />
153
+ </div>
154
+ </CmsButton>
155
+ </PopoverTrigger>
156
+
157
+ <PopoverContent className="w-[280px] p-0" align="start">
158
+ <Command shouldFilter={false}>
159
+ <CommandInput
160
+ placeholder={`Search ${displayTaxonomyName.toLowerCase()}...`}
161
+ value={search}
162
+ onValueChange={setSearch}
163
+ />
164
+ <CommandList>
165
+ {filteredTerms.length === 0 ? (
166
+ <CommandEmpty>
167
+ {terms.length === 0 ? `No ${displayTaxonomyName.toLowerCase()} found` : 'No matches'}
168
+ </CommandEmpty>
169
+ ) : (
170
+ <CommandGroup heading={displayTaxonomyName}>
171
+ {filteredTerms.map((term) => (
172
+ <TermItem
173
+ key={term._id}
174
+ term={term}
175
+ isSelected={selectedTermIds.includes(term._id)}
176
+ onToggle={() => handleToggleTerm(term._id)}
177
+ />
178
+ ))}
179
+ </CommandGroup>
180
+ )}
181
+ </CommandList>
182
+
183
+ {selectedTermIds.length > 0 && (
184
+ <>
185
+ <CommandSeparator />
186
+ <div className="p-2">
187
+ <div className="mb-2 flex flex-wrap gap-1">
188
+ {selectedTermsDetails.map((term) => (
189
+ <Badge
190
+ key={term._id}
191
+ variant="secondary"
192
+ className="gap-1 pr-1"
193
+ style={
194
+ term.color
195
+ ? { backgroundColor: term.color, color: '#fff' }
196
+ : undefined
197
+ }
198
+ >
199
+ {term.name}
200
+ <button
201
+ type="button"
202
+ className="ml-0.5 rounded-full p-0.5 hover:bg-black/10"
203
+ onClick={(e) => handleRemoveTerm(term._id, e)}
204
+ aria-label={`Remove ${term.name}`}
205
+ >
206
+ <X className="size-3" />
207
+ </button>
208
+ </Badge>
209
+ ))}
210
+ </div>
211
+ <CmsButton
212
+ variant="ghost"
213
+ size="sm"
214
+ className="w-full"
215
+ onClick={handleClear}
216
+ >
217
+ Clear all filters
218
+ </CmsButton>
219
+ </div>
220
+ </>
221
+ )}
222
+ </Command>
223
+ </PopoverContent>
224
+ </Popover>
225
+ )
226
+ }
227
+
228
+ interface TermItemProps {
229
+ term: TaxonomyTerm
230
+ isSelected: boolean
231
+ onToggle: () => void
232
+ }
233
+
234
+ function TermItem({ term, isSelected, onToggle }: TermItemProps) {
235
+ return (
236
+ <CommandItem onSelect={onToggle} className="cursor-pointer">
237
+ <Checkbox
238
+ checked={isSelected}
239
+ className="mr-2"
240
+ aria-hidden="true"
241
+ tabIndex={-1}
242
+ />
243
+ {term.color && (
244
+ <span
245
+ className="size-2.5 shrink-0 rounded-full"
246
+ style={{ backgroundColor: term.color }}
247
+ />
248
+ )}
249
+ <span className="flex-1 truncate">{term.name}</span>
250
+ <span className="text-xs text-muted-foreground">{term.usageCount}</span>
251
+ {isSelected && <Check className="ml-1 size-4 text-primary" />}
252
+ </CommandItem>
253
+ )
254
+ }
@@ -0,0 +1 @@
1
+ export { TaxonomyFilter, type TaxonomyFilterProps } from './TaxonomyFilter'
@@ -0,0 +1,8 @@
1
+ export { AdminLayout } from './AdminLayout'
2
+ export { Sidebar } from './Sidebar'
3
+ export { Header } from './Header'
4
+ export { RouteGuard, type RouteGuardProps } from './RouteGuard'
5
+ export { UploadDropzone, type UploadDropzoneProps, type UploadedFile } from './UploadDropzone'
6
+ export { ContentTypeFormModal } from './ContentTypeFormModal'
7
+ export { ErrorBoundary } from './ErrorBoundary'
8
+ export { ErrorState, ErrorAlert } from './ErrorState'
@@ -0,0 +1,115 @@
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 {
10
+ Eye,
11
+ Pencil,
12
+ FolderInput,
13
+ Download,
14
+ Link2,
15
+ Trash2,
16
+ MoreVertical,
17
+ } from "lucide-react";
18
+
19
+ export interface MediaAssetForActions {
20
+ _id: string;
21
+ name: string;
22
+ url: string | null;
23
+ }
24
+
25
+ interface MediaAssetActionsProps {
26
+ asset: MediaAssetForActions;
27
+ onView?: () => void;
28
+ onEdit?: () => void;
29
+ onMove?: () => void;
30
+ onDelete?: () => void;
31
+ }
32
+
33
+ export function MediaAssetActions({
34
+ asset,
35
+ onView,
36
+ onEdit,
37
+ onMove,
38
+ onDelete,
39
+ }: MediaAssetActionsProps) {
40
+ const handleDownload = () => {
41
+ if (!asset.url) return;
42
+ const link = document.createElement("a");
43
+ link.href = asset.url;
44
+ link.download = asset.name;
45
+ link.target = "_blank";
46
+ document.body.appendChild(link);
47
+ link.click();
48
+ document.body.removeChild(link);
49
+ };
50
+
51
+ const handleCopyUrl = async () => {
52
+ if (!asset.url) return;
53
+ await navigator.clipboard.writeText(asset.url);
54
+ };
55
+
56
+ return (
57
+ <DropdownMenu>
58
+ <DropdownMenuTrigger asChild>
59
+ <CmsButton
60
+ variant="ghost"
61
+ size="icon-sm"
62
+ className="opacity-0 group-hover:opacity-100"
63
+ onClick={(e) => e.stopPropagation()}
64
+ >
65
+ <MoreVertical className="size-4" />
66
+ </CmsButton>
67
+ </DropdownMenuTrigger>
68
+ <DropdownMenuContent
69
+ // align="start"
70
+ side="bottom"
71
+ onClick={(e) => e.stopPropagation()}
72
+ >
73
+ {onView && (
74
+ <DropdownMenuItem onClick={onView}>
75
+ <Eye className="mr-2 size-4" />
76
+ View Details
77
+ </DropdownMenuItem>
78
+ )}
79
+ {onEdit && (
80
+ <DropdownMenuItem onClick={onEdit}>
81
+ <Pencil className="mr-2 size-4" />
82
+ Edit
83
+ </DropdownMenuItem>
84
+ )}
85
+ {onMove && (
86
+ <DropdownMenuItem onClick={onMove}>
87
+ <FolderInput className="mr-2 size-4" />
88
+ Move to...
89
+ </DropdownMenuItem>
90
+ )}
91
+ <DropdownMenuSeparator />
92
+ <DropdownMenuItem onClick={handleDownload} disabled={!asset.url}>
93
+ <Download className="mr-2 size-4" />
94
+ Download
95
+ </DropdownMenuItem>
96
+ <DropdownMenuItem onClick={handleCopyUrl} disabled={!asset.url}>
97
+ <Link2 className="mr-2 size-4" />
98
+ Copy URL
99
+ </DropdownMenuItem>
100
+ {onDelete && (
101
+ <>
102
+ <DropdownMenuSeparator />
103
+ <DropdownMenuItem
104
+ onClick={onDelete}
105
+ className="text-destructive focus:text-destructive"
106
+ >
107
+ <Trash2 className="mr-2 size-4" />
108
+ Delete
109
+ </DropdownMenuItem>
110
+ </>
111
+ )}
112
+ </DropdownMenuContent>
113
+ </DropdownMenu>
114
+ );
115
+ }