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,83 @@
1
+ import { Component, type ReactNode, type ErrorInfo } from 'react';
2
+
3
+ interface ErrorBoundaryProps {
4
+ /** Child components to render */
5
+ children: ReactNode;
6
+ /** Optional fallback UI to render on error */
7
+ fallback?: ReactNode;
8
+ /** Optional callback when an error is caught */
9
+ onError?: (error: Error, errorInfo: ErrorInfo) => void;
10
+ /** Optional title for the error state */
11
+ title?: string;
12
+ }
13
+
14
+ interface ErrorBoundaryState {
15
+ hasError: boolean;
16
+ error: Error | null;
17
+ }
18
+
19
+ /**
20
+ * ErrorBoundary catches JavaScript errors in child component trees
21
+ * and displays a fallback UI instead of crashing the whole app.
22
+ *
23
+ * Usage:
24
+ * ```tsx
25
+ * <ErrorBoundary fallback={<div>Something went wrong</div>}>
26
+ * <MyComponent />
27
+ * </ErrorBoundary>
28
+ * ```
29
+ */
30
+ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
31
+ constructor(props: ErrorBoundaryProps) {
32
+ super(props);
33
+ this.state = { hasError: false, error: null };
34
+ }
35
+
36
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState {
37
+ return { hasError: true, error };
38
+ }
39
+
40
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
41
+ console.error('ErrorBoundary caught an error:', error, errorInfo);
42
+ this.props.onError?.(error, errorInfo);
43
+ }
44
+
45
+ handleRetry = (): void => {
46
+ this.setState({ hasError: false, error: null });
47
+ };
48
+
49
+ render(): ReactNode {
50
+ if (this.state.hasError) {
51
+ if (this.props.fallback) {
52
+ return this.props.fallback;
53
+ }
54
+
55
+ return (
56
+ <div className="error-boundary" role="alert">
57
+ <div className="error-boundary-icon">
58
+ <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
59
+ <circle cx="12" cy="12" r="10" />
60
+ <line x1="12" y1="8" x2="12" y2="12" />
61
+ <line x1="12" y1="16" x2="12.01" y2="16" />
62
+ </svg>
63
+ </div>
64
+ <h3 className="error-boundary-title">
65
+ {this.props.title || 'Something went wrong'}
66
+ </h3>
67
+ <p className="error-boundary-message">
68
+ {this.state.error?.message || 'An unexpected error occurred'}
69
+ </p>
70
+ <button
71
+ className="btn btn-primary"
72
+ onClick={this.handleRetry}
73
+ type="button"
74
+ >
75
+ Try Again
76
+ </button>
77
+ </div>
78
+ );
79
+ }
80
+
81
+ return this.props.children;
82
+ }
83
+ }
@@ -0,0 +1,147 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ interface ErrorStateProps {
4
+ /** The error to display */
5
+ error: Error | string | null | undefined;
6
+ /** Optional title for the error (defaults to "Something went wrong") */
7
+ title?: string;
8
+ /** Optional retry handler - shows a retry button when provided */
9
+ onRetry?: () => void;
10
+ /** Whether a retry is currently in progress */
11
+ isRetrying?: boolean;
12
+ /** Optional custom icon */
13
+ icon?: ReactNode;
14
+ /** Optional additional CSS class */
15
+ className?: string;
16
+ }
17
+
18
+ /**
19
+ * ErrorState displays a full-page or section error state with
20
+ * an icon, message, and optional retry button.
21
+ *
22
+ * Usage:
23
+ * ```tsx
24
+ * if (error) {
25
+ * return <ErrorState error={error} onRetry={() => refetch()} />
26
+ * }
27
+ * ```
28
+ */
29
+ export function ErrorState({
30
+ error,
31
+ title = 'Something went wrong',
32
+ onRetry,
33
+ isRetrying = false,
34
+ icon,
35
+ className = '',
36
+ }: ErrorStateProps) {
37
+ const errorMessage = error instanceof Error ? error.message : error ?? 'An unexpected error occurred';
38
+
39
+ return (
40
+ <div className={`error-state ${className}`} role="alert" data-testid="error-state">
41
+ <div className="error-state-icon">
42
+ {icon ?? (
43
+ <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
44
+ <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" />
45
+ <line x1="12" y1="9" x2="12" y2="13" />
46
+ <line x1="12" y1="17" x2="12.01" y2="17" />
47
+ </svg>
48
+ )}
49
+ </div>
50
+ <h3 className="error-state-title">{title}</h3>
51
+ <p className="error-state-message">{errorMessage}</p>
52
+ {onRetry && (
53
+ <button
54
+ type="button"
55
+ className="btn btn-primary"
56
+ onClick={onRetry}
57
+ disabled={isRetrying}
58
+ data-testid="error-retry-button"
59
+ >
60
+ {isRetrying ? 'Retrying...' : 'Try Again'}
61
+ </button>
62
+ )}
63
+ </div>
64
+ );
65
+ }
66
+
67
+ interface ErrorAlertProps {
68
+ /** The error to display */
69
+ error: Error | string | null | undefined;
70
+ /** Optional dismiss handler - shows a dismiss button when provided */
71
+ onDismiss?: () => void;
72
+ /** Optional retry handler - shows a retry button when provided */
73
+ onRetry?: () => void;
74
+ /** Whether a retry is currently in progress */
75
+ isRetrying?: boolean;
76
+ /** Variant of the alert (default: 'error') */
77
+ variant?: 'error' | 'warning';
78
+ /** Optional additional CSS class */
79
+ className?: string;
80
+ }
81
+
82
+ /**
83
+ * ErrorAlert displays an inline error alert with optional dismiss/retry actions.
84
+ *
85
+ * Usage:
86
+ * ```tsx
87
+ * {error && <ErrorAlert error={error} onDismiss={() => setError(null)} />}
88
+ * ```
89
+ */
90
+ export function ErrorAlert({
91
+ error,
92
+ onDismiss,
93
+ onRetry,
94
+ isRetrying = false,
95
+ variant = 'error',
96
+ className = '',
97
+ }: ErrorAlertProps) {
98
+ if (!error) return null;
99
+
100
+ const errorMessage = error instanceof Error ? error.message : error;
101
+
102
+ return (
103
+ <div
104
+ className={`error-alert error-alert--${variant} ${className}`}
105
+ role="alert"
106
+ data-testid="error-alert"
107
+ >
108
+ <div className="error-alert-icon">
109
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
110
+ <circle cx="12" cy="12" r="10" />
111
+ <line x1="12" y1="8" x2="12" y2="12" />
112
+ <line x1="12" y1="16" x2="12.01" y2="16" />
113
+ </svg>
114
+ </div>
115
+ <div className="error-alert-content">
116
+ <p className="error-alert-message">{errorMessage}</p>
117
+ </div>
118
+ <div className="error-alert-actions">
119
+ {onRetry && (
120
+ <button
121
+ type="button"
122
+ className="error-alert-btn error-alert-btn--retry"
123
+ onClick={onRetry}
124
+ disabled={isRetrying}
125
+ data-testid="error-alert-retry"
126
+ >
127
+ {isRetrying ? 'Retrying...' : 'Retry'}
128
+ </button>
129
+ )}
130
+ {onDismiss && (
131
+ <button
132
+ type="button"
133
+ className="error-alert-btn error-alert-btn--dismiss"
134
+ onClick={onDismiss}
135
+ aria-label="Dismiss error"
136
+ data-testid="error-alert-dismiss"
137
+ >
138
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
139
+ <line x1="18" y1="6" x2="6" y2="18" />
140
+ <line x1="6" y1="6" x2="18" y2="18" />
141
+ </svg>
142
+ </button>
143
+ )}
144
+ </div>
145
+ </div>
146
+ );
147
+ }
@@ -0,0 +1,294 @@
1
+ import { useRouterState, useNavigate, Link } from '@tanstack/react-router'
2
+ import { useAuth, useAdminConfig, useBreadcrumbContext } from '~/contexts'
3
+ import { getRole } from '../../../src/component/roles'
4
+ import {
5
+ Breadcrumb,
6
+ BreadcrumbItem,
7
+ BreadcrumbLink,
8
+ BreadcrumbList,
9
+ BreadcrumbPage,
10
+ BreadcrumbSeparator,
11
+ } from '~/components/ui/breadcrumb'
12
+ import {
13
+ DropdownMenu,
14
+ DropdownMenuContent,
15
+ DropdownMenuItem,
16
+ DropdownMenuLabel,
17
+ DropdownMenuSeparator,
18
+ DropdownMenuTrigger,
19
+ } from '~/components/ui/dropdown-menu'
20
+ import { Avatar, AvatarFallback, AvatarImage } from '~/components/ui/avatar'
21
+ import { Button } from '~/components/ui/button'
22
+ import {
23
+ Popover,
24
+ PopoverContent,
25
+ PopoverTrigger,
26
+ } from '~/components/ui/popover'
27
+ import {
28
+ Bell,
29
+ HelpCircle,
30
+ Home,
31
+ LogOut,
32
+ Settings as _Settings,
33
+ User,
34
+ ChevronDown,
35
+ ExternalLink,
36
+ Book,
37
+ Code,
38
+ MessageSquare,
39
+ } from 'lucide-react'
40
+ import { cn as _cn } from '~/lib/cn'
41
+ import { Fragment } from 'react'
42
+
43
+ interface BreadcrumbData {
44
+ label: string
45
+ to?: string
46
+ }
47
+
48
+ const KEYBOARD_SHORTCUTS = [
49
+ { keys: ['⌘', 'S'], description: 'Save entry' },
50
+ { keys: ['⌘', '⇧', 'P'], description: 'Publish entry' },
51
+ { keys: ['⌘', 'K'], description: 'Quick search' },
52
+ { keys: ['Esc'], description: 'Close modal/panel' },
53
+ ]
54
+
55
+ const HELP_RESOURCES = [
56
+ { label: 'Documentation', url: 'https://docs.convex.dev', icon: Book },
57
+ { label: 'API Reference', url: 'https://docs.convex.dev/api', icon: Code },
58
+ { label: 'Community Discord', url: 'https://discord.gg/convex', icon: MessageSquare },
59
+ ]
60
+
61
+ const routeLabels: Record<string, string> = {
62
+ '/': 'Dashboard',
63
+ '/content': 'Content',
64
+ '/media': 'Media Library',
65
+ '/content-types': 'Content Types',
66
+ '/settings': 'Settings',
67
+ '/taxonomies': 'Taxonomies',
68
+ '/trash': 'Trash',
69
+ '/entries': 'Entries',
70
+ '/entries/type': 'Content Types',
71
+ '/entries/new': 'New Entry',
72
+ }
73
+
74
+ function getBreadcrumbs(
75
+ pathname: string,
76
+ appName: string,
77
+ overrides: Map<string, string>
78
+ ): BreadcrumbData[] {
79
+ const breadcrumbs: BreadcrumbData[] = [{ label: appName, to: '/' }]
80
+
81
+ if (pathname === '/') {
82
+ return breadcrumbs
83
+ }
84
+
85
+ const segments = pathname.split('/').filter(Boolean)
86
+ let currentPath = ''
87
+
88
+ segments.forEach((segment, index) => {
89
+ currentPath += `/${segment}`
90
+ const isLast = index === segments.length - 1
91
+
92
+ // Check for dynamic overrides first, then static labels, then fallback
93
+ let label = overrides.get(currentPath) ?? routeLabels[currentPath]
94
+ if (!label) {
95
+ label = segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' ')
96
+ }
97
+
98
+ if (isLast) {
99
+ breadcrumbs.push({ label })
100
+ } else {
101
+ breadcrumbs.push({ label, to: currentPath })
102
+ }
103
+ })
104
+
105
+ return breadcrumbs
106
+ }
107
+
108
+ export function Header() {
109
+ const routerState = useRouterState()
110
+ const navigate = useNavigate()
111
+ const { branding } = useAdminConfig()
112
+
113
+ let overrides = new Map<string, string>()
114
+ try {
115
+ const breadcrumbContext = useBreadcrumbContext()
116
+ overrides = breadcrumbContext.overrides
117
+ } catch {
118
+ // BreadcrumbProvider not available, use empty overrides
119
+ }
120
+
121
+ const breadcrumbs = getBreadcrumbs(routerState.location.pathname, branding.appName, overrides)
122
+
123
+ let user = null
124
+ let role = null
125
+ let logout = async () => {}
126
+ let isAuthenticated = false
127
+
128
+ try {
129
+ const auth = useAuth()
130
+ user = auth.user
131
+ role = auth.role
132
+ logout = auth.logout
133
+ isAuthenticated = auth.isAuthenticated
134
+ } catch {
135
+ // AuthProvider not available
136
+ }
137
+
138
+ const roleDefinition = role ? getRole(role) : null
139
+ const roleDisplayName = roleDefinition?.displayName ?? role ?? 'No Role'
140
+ const userDisplayName = user?.name ?? user?.email ?? 'User'
141
+
142
+ const getInitials = (name: string) => {
143
+ const parts = name.split(' ')
144
+ if (parts.length >= 2) {
145
+ return `${parts[0][0]}${parts[1][0]}`.toUpperCase()
146
+ }
147
+ return name.slice(0, 2).toUpperCase()
148
+ }
149
+
150
+ const userInitials = user?.name ? getInitials(user.name) : 'U'
151
+
152
+ const handleLogout = async () => {
153
+ await logout()
154
+ }
155
+
156
+ return (
157
+ <header className="sticky top-0 z-40 flex h-14 items-center justify-between border-b border-border bg-background/95 px-6 backdrop-blur supports-[backdrop-filter]:bg-background/60">
158
+ <Breadcrumb>
159
+ <BreadcrumbList>
160
+ {breadcrumbs.map((crumb, index) => (
161
+ <Fragment key={index}>
162
+ {index > 0 && <BreadcrumbSeparator />}
163
+ <BreadcrumbItem>
164
+ {crumb.to ? (
165
+ <BreadcrumbLink asChild>
166
+ <Link to={crumb.to} className="flex items-center gap-1.5">
167
+ {index === 0 && <Home className="size-3.5" />}
168
+ <span>{crumb.label}</span>
169
+ </Link>
170
+ </BreadcrumbLink>
171
+ ) : (
172
+ <BreadcrumbPage>{crumb.label}</BreadcrumbPage>
173
+ )}
174
+ </BreadcrumbItem>
175
+ </Fragment>
176
+ ))}
177
+ </BreadcrumbList>
178
+ </Breadcrumb>
179
+
180
+ <div className="flex items-center gap-1">
181
+ <Popover>
182
+ <PopoverTrigger asChild>
183
+ <Button variant="ghost" size="icon" className="size-9">
184
+ <Bell className="size-4" />
185
+ <span className="sr-only">Notifications</span>
186
+ </Button>
187
+ </PopoverTrigger>
188
+ <PopoverContent align="end" className="w-80">
189
+ <div className="flex items-center justify-between pb-2">
190
+ <h4 className="font-medium">Notifications</h4>
191
+ </div>
192
+ <div className="flex flex-col items-center justify-center py-8 text-center">
193
+ <Bell className="size-8 text-muted-foreground/50" />
194
+ <p className="mt-2 text-sm font-medium">No notifications yet</p>
195
+ <p className="text-xs text-muted-foreground">You're all caught up!</p>
196
+ </div>
197
+ </PopoverContent>
198
+ </Popover>
199
+
200
+ <Popover>
201
+ <PopoverTrigger asChild>
202
+ <Button variant="ghost" size="icon" className="size-9">
203
+ <HelpCircle className="size-4" />
204
+ <span className="sr-only">Help</span>
205
+ </Button>
206
+ </PopoverTrigger>
207
+ <PopoverContent align="end" className="w-72">
208
+ <div className="pb-2">
209
+ <h4 className="font-medium">Help & Resources</h4>
210
+ </div>
211
+ <div className="space-y-4">
212
+ <div>
213
+ <h5 className="mb-2 text-xs font-medium text-muted-foreground">Keyboard Shortcuts</h5>
214
+ <div className="space-y-1">
215
+ {KEYBOARD_SHORTCUTS.map((shortcut, index) => (
216
+ <div key={index} className="flex items-center justify-between text-sm">
217
+ <span className="text-muted-foreground">{shortcut.description}</span>
218
+ <div className="flex gap-0.5">
219
+ {shortcut.keys.map((key, keyIndex) => (
220
+ <kbd
221
+ key={keyIndex}
222
+ className="rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-xs"
223
+ >
224
+ {key}
225
+ </kbd>
226
+ ))}
227
+ </div>
228
+ </div>
229
+ ))}
230
+ </div>
231
+ </div>
232
+ <div>
233
+ <h5 className="mb-2 text-xs font-medium text-muted-foreground">Resources</h5>
234
+ <div className="space-y-1">
235
+ {HELP_RESOURCES.map((resource) => (
236
+ <a
237
+ key={resource.label}
238
+ href={resource.url}
239
+ target="_blank"
240
+ rel="noopener noreferrer"
241
+ className="flex items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-accent"
242
+ >
243
+ <resource.icon className="size-4 text-muted-foreground" />
244
+ <span className="flex-1">{resource.label}</span>
245
+ <ExternalLink className="size-3 text-muted-foreground" />
246
+ </a>
247
+ ))}
248
+ </div>
249
+ </div>
250
+ </div>
251
+ </PopoverContent>
252
+ </Popover>
253
+
254
+ <DropdownMenu>
255
+ <DropdownMenuTrigger asChild>
256
+ <Button variant="ghost" className="h-9 gap-2 pl-2 pr-3">
257
+ <Avatar className="size-6">
258
+ <AvatarImage src={user?.avatarUrl} alt={userDisplayName} />
259
+ <AvatarFallback className="text-xs">{userInitials}</AvatarFallback>
260
+ </Avatar>
261
+ <span className="text-sm font-medium">{userDisplayName}</span>
262
+ <ChevronDown className="size-3.5 text-muted-foreground" />
263
+ </Button>
264
+ </DropdownMenuTrigger>
265
+ <DropdownMenuContent align="end" className="w-56">
266
+ <DropdownMenuLabel className="font-normal">
267
+ <div className="flex flex-col space-y-1">
268
+ <p className="text-sm font-medium">{userDisplayName}</p>
269
+ {user?.email && (
270
+ <p className="text-xs text-muted-foreground">{user.email}</p>
271
+ )}
272
+ <p className="text-xs text-muted-foreground">{roleDisplayName}</p>
273
+ </div>
274
+ </DropdownMenuLabel>
275
+ <DropdownMenuSeparator />
276
+ <DropdownMenuItem onClick={() => navigate({ to: '/settings' })}>
277
+ <User className="mr-2 size-4" />
278
+ <span>Profile & Settings</span>
279
+ </DropdownMenuItem>
280
+ {isAuthenticated && (
281
+ <>
282
+ <DropdownMenuSeparator />
283
+ <DropdownMenuItem onClick={handleLogout} className="text-destructive focus:text-destructive">
284
+ <LogOut className="mr-2 size-4" />
285
+ <span>Logout</span>
286
+ </DropdownMenuItem>
287
+ </>
288
+ )}
289
+ </DropdownMenuContent>
290
+ </DropdownMenu>
291
+ </div>
292
+ </header>
293
+ )
294
+ }