convex-cms 0.0.3 → 0.0.5-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -60
- package/admin/README.md +99 -0
- package/admin/src/components/AdminLayout.tsx +22 -0
- package/admin/src/components/BreakingChangesWarningDialog.tsx +81 -0
- package/admin/src/components/BulkActionBar.tsx +190 -0
- package/admin/src/components/BulkOperationModal.tsx +177 -0
- package/admin/src/components/ContentEntryEditor.tsx +1104 -0
- package/admin/src/components/ContentTypeFormModal.tsx +1012 -0
- package/admin/src/components/ErrorBoundary.tsx +83 -0
- package/admin/src/components/ErrorState.tsx +147 -0
- package/admin/src/components/Header.tsx +294 -0
- package/admin/src/components/RouteGuard.tsx +264 -0
- package/admin/src/components/Sidebar.tsx +90 -0
- package/admin/src/components/TaxonomyEditor.tsx +348 -0
- package/admin/src/components/TermTree.tsx +533 -0
- package/admin/src/components/UploadDropzone.tsx +383 -0
- package/admin/src/components/VersionCompare.tsx +250 -0
- package/admin/src/components/VersionHistory.tsx +279 -0
- package/admin/src/components/VersionRollbackModal.tsx +79 -0
- package/admin/src/components/cmsds/CmsButton.tsx +101 -0
- package/admin/src/components/cmsds/CmsDialog.tsx +139 -0
- package/admin/src/components/cmsds/CmsDropdown.tsx +62 -0
- package/admin/src/components/cmsds/CmsEmptyState.tsx +54 -0
- package/admin/src/components/cmsds/CmsField.tsx +47 -0
- package/admin/src/components/cmsds/CmsPageHeader.tsx +35 -0
- package/admin/src/components/cmsds/CmsStatusBadge.tsx +153 -0
- package/admin/src/components/cmsds/CmsSurface.tsx +52 -0
- package/admin/src/components/cmsds/CmsTable.tsx +164 -0
- package/admin/src/components/cmsds/CmsToolbar.tsx +58 -0
- package/admin/src/components/cmsds/index.ts +10 -0
- package/admin/src/components/fields/BooleanField.tsx +74 -0
- package/admin/src/components/fields/CategoryField.tsx +394 -0
- package/admin/src/components/fields/DateField.tsx +173 -0
- package/admin/src/components/fields/DefaultFieldRenderer.tsx +74 -0
- package/admin/src/components/fields/FieldRenderer.tsx +180 -0
- package/admin/src/components/fields/FieldWrapper.tsx +57 -0
- package/admin/src/components/fields/JsonField.tsx +172 -0
- package/admin/src/components/fields/MediaField.tsx +367 -0
- package/admin/src/components/fields/MultiSelectField.tsx +118 -0
- package/admin/src/components/fields/NumberField.tsx +77 -0
- package/admin/src/components/fields/ReferenceField.tsx +386 -0
- package/admin/src/components/fields/RichTextField.tsx +171 -0
- package/admin/src/components/fields/SelectField.tsx +62 -0
- package/admin/src/components/fields/TagField.tsx +325 -0
- package/admin/src/components/fields/TextAreaField.tsx +68 -0
- package/admin/src/components/fields/TextField.tsx +56 -0
- package/admin/src/components/fields/index.ts +54 -0
- package/admin/src/components/fields/registry.ts +64 -0
- package/admin/src/components/fields/types.ts +217 -0
- package/admin/src/components/filters/TaxonomyFilter.tsx +254 -0
- package/admin/src/components/filters/index.ts +1 -0
- package/admin/src/components/index.ts +8 -0
- package/admin/src/components/media/MediaAssetActions.tsx +115 -0
- package/admin/src/components/media/MediaAssetEditDialog.tsx +217 -0
- package/admin/src/components/media/MediaBulkActionBar.tsx +51 -0
- package/admin/src/components/media/MediaFolderActions.tsx +69 -0
- package/admin/src/components/media/MediaFolderEditDialog.tsx +126 -0
- package/admin/src/components/media/MediaMoveModal.tsx +179 -0
- package/admin/src/components/media/MediaPreviewModal.tsx +370 -0
- package/admin/src/components/media/MediaTaxonomyPicker.tsx +304 -0
- package/admin/src/components/media/MediaTrashBulkActionBar.tsx +59 -0
- package/admin/src/components/ui/accordion.tsx +64 -0
- package/admin/src/components/ui/alert-dialog.tsx +155 -0
- package/admin/src/components/ui/alert.tsx +66 -0
- package/admin/src/components/ui/avatar.tsx +53 -0
- package/admin/src/components/ui/badge.tsx +46 -0
- package/admin/src/components/ui/breadcrumb.tsx +109 -0
- package/admin/src/components/ui/button.tsx +62 -0
- package/admin/src/components/ui/calendar.tsx +220 -0
- package/admin/src/components/ui/card.tsx +92 -0
- package/admin/src/components/ui/checkbox.tsx +30 -0
- package/admin/src/components/ui/command.tsx +182 -0
- package/admin/src/components/ui/dialog.tsx +143 -0
- package/admin/src/components/ui/dropdown-menu.tsx +257 -0
- package/admin/src/components/ui/form.tsx +167 -0
- package/admin/src/components/ui/input.tsx +21 -0
- package/admin/src/components/ui/label.tsx +24 -0
- package/admin/src/components/ui/popover.tsx +46 -0
- package/admin/src/components/ui/scroll-area.tsx +56 -0
- package/admin/src/components/ui/select.tsx +190 -0
- package/admin/src/components/ui/separator.tsx +26 -0
- package/admin/src/components/ui/sheet.tsx +137 -0
- package/admin/src/components/ui/sidebar.tsx +724 -0
- package/admin/src/components/ui/skeleton.tsx +13 -0
- package/admin/src/components/ui/sonner.tsx +38 -0
- package/admin/src/components/ui/switch.tsx +31 -0
- package/admin/src/components/ui/table.tsx +114 -0
- package/admin/src/components/ui/tabs.tsx +66 -0
- package/admin/src/components/ui/textarea.tsx +18 -0
- package/admin/src/components/ui/tooltip.tsx +61 -0
- package/admin/src/contexts/AdminConfigContext.tsx +30 -0
- package/admin/src/contexts/AuthContext.tsx +330 -0
- package/admin/src/contexts/BreadcrumbContext.tsx +49 -0
- package/admin/src/contexts/SettingsConfigContext.tsx +57 -0
- package/admin/src/contexts/ThemeContext.tsx +91 -0
- package/admin/src/contexts/index.ts +20 -0
- package/admin/src/embed/components/EmbedHeader.tsx +103 -0
- package/admin/src/embed/components/EmbedLayout.tsx +29 -0
- package/admin/src/embed/components/EmbedSidebar.tsx +119 -0
- package/admin/src/embed/components/index.ts +3 -0
- package/admin/src/embed/contexts/ApiContext.tsx +32 -0
- package/admin/src/embed/index.tsx +184 -0
- package/admin/src/embed/navigation.tsx +202 -0
- package/admin/src/embed/pages/Content.tsx +19 -0
- package/admin/src/embed/pages/ContentTypes.tsx +19 -0
- package/admin/src/embed/pages/Dashboard.tsx +19 -0
- package/admin/src/embed/pages/Media.tsx +19 -0
- package/admin/src/embed/pages/Settings.tsx +22 -0
- package/admin/src/embed/pages/Taxonomies.tsx +22 -0
- package/admin/src/embed/pages/Trash.tsx +22 -0
- package/admin/src/embed/pages/index.ts +7 -0
- package/admin/src/embed/types.ts +24 -0
- package/admin/src/hooks/index.ts +2 -0
- package/admin/src/hooks/use-mobile.ts +19 -0
- package/admin/src/hooks/useBreadcrumbLabel.ts +15 -0
- package/admin/src/hooks/usePermissions.ts +211 -0
- package/admin/src/lib/admin-config.ts +111 -0
- package/admin/src/lib/cn.ts +6 -0
- package/admin/src/lib/config.server.ts +56 -0
- package/admin/src/lib/convex.ts +26 -0
- package/admin/src/lib/embed-adapter.ts +80 -0
- package/admin/src/lib/icons.tsx +96 -0
- package/admin/src/lib/loadAdminConfig.ts +92 -0
- package/admin/src/lib/motion.ts +29 -0
- package/admin/src/lib/navigation.ts +43 -0
- package/admin/src/lib/tanstack-adapter.ts +82 -0
- package/admin/src/pages/ContentPage.tsx +337 -0
- package/admin/src/pages/ContentTypesPage.tsx +457 -0
- package/admin/src/pages/DashboardPage.tsx +163 -0
- package/admin/src/pages/MediaPage.tsx +34 -0
- package/admin/src/pages/SettingsPage.tsx +486 -0
- package/admin/src/pages/TaxonomiesPage.tsx +289 -0
- package/admin/src/pages/TrashPage.tsx +421 -0
- package/admin/src/pages/index.ts +14 -0
- package/admin/src/routeTree.gen.ts +262 -0
- package/admin/src/router.tsx +22 -0
- package/admin/src/routes/__root.tsx +250 -0
- package/admin/src/routes/content-types.tsx +20 -0
- package/admin/src/routes/content.tsx +20 -0
- package/admin/src/routes/entries/$entryId.tsx +107 -0
- package/admin/src/routes/entries/new.$contentTypeId.tsx +69 -0
- package/admin/src/routes/entries/type/$contentTypeId.tsx +503 -0
- package/admin/src/routes/index.tsx +20 -0
- package/admin/src/routes/media.tsx +1095 -0
- package/admin/src/routes/settings.tsx +20 -0
- package/admin/src/routes/taxonomies.tsx +20 -0
- package/admin/src/routes/trash.tsx +20 -0
- package/admin/src/styles/globals.css +69 -0
- package/admin/src/styles/tailwind-config.css +74 -0
- package/admin/src/styles/theme.css +73 -0
- package/admin/src/types/index.ts +221 -0
- package/admin/src/utils/errorParsing.ts +163 -0
- package/admin/src/utils/index.ts +5 -0
- package/admin/src/vite-env.d.ts +14 -0
- package/admin/tailwind.preset.cjs +102 -0
- package/admin-dist/nitro.json +1 -1
- package/admin-dist/public/assets/{CmsEmptyState-CRswfTzk.js → CmsEmptyState-CkqBIab3.js} +2 -2
- package/admin-dist/public/assets/{CmsPageHeader-CirpXndm.js → CmsPageHeader-CUtl5MMG.js} +1 -1
- package/admin-dist/public/assets/{CmsStatusBadge-CbEUpQu-.js → CmsStatusBadge-CUYFgEe-.js} +1 -1
- package/admin-dist/public/assets/CmsSurface-CsJfAVa3.js +1 -0
- package/admin-dist/public/assets/{CmsToolbar-BI2nZOXp.js → CmsToolbar-CnfbcxeP.js} +1 -1
- package/admin-dist/public/assets/{ContentEntryEditor-CBeCyK_m.js → ContentEntryEditor-BU220CCy.js} +1 -1
- package/admin-dist/public/assets/TaxonomyFilter-CWCxC5HZ.js +1 -0
- package/admin-dist/public/assets/_contentTypeId-DK8cskRt.js +1 -0
- package/admin-dist/public/assets/{_entryId-CKU_glsK.js → _entryId-CuVMExbb.js} +1 -1
- package/admin-dist/public/assets/alert-CF1BSzGR.js +1 -0
- package/admin-dist/public/assets/{badge-hvUOzpVZ.js → badge-CmuOIVKp.js} +1 -1
- package/admin-dist/public/assets/{circle-check-big-CF_pR17r.js → circle-check-big-BKDVG6DU.js} +1 -1
- package/admin-dist/public/assets/{command-DU82cJlt.js → command-XJxnF2Sd.js} +1 -1
- package/admin-dist/public/assets/content-QBUxdxbS.js +1 -0
- package/admin-dist/public/assets/content-types-CrNEm8Hf.js +2 -0
- package/admin-dist/public/assets/globals-B7Wsfh_v.css +1 -0
- package/admin-dist/public/assets/index-C7xOwudI.js +1 -0
- package/admin-dist/public/assets/{label-KNtpL71g.js → label-CHCnXeBk.js} +1 -1
- package/admin-dist/public/assets/{link-2-Bw2aI4V4.js → link-2-Bb34judH.js} +1 -1
- package/admin-dist/public/assets/{list-sYepHjt_.js → list-9Pzt48ld.js} +1 -1
- package/admin-dist/public/assets/{main-CKj5yfEi.js → main-CjQ2VI9L.js} +3 -3
- package/admin-dist/public/assets/media-Dc5PWt2Q.js +1 -0
- package/admin-dist/public/assets/{new._contentTypeId-C3LstjNs.js → new._contentTypeId-C_I4YxIa.js} +1 -1
- package/admin-dist/public/assets/{plus-DUn8v_Xf.js → plus-Ceef7DHk.js} +1 -1
- package/admin-dist/public/assets/{rotate-ccw-DJEoHcRI.js → rotate-ccw-7k7-4VUq.js} +1 -1
- package/admin-dist/public/assets/scroll-area-CC6wujnp.js +1 -0
- package/admin-dist/public/assets/{search-MuAUDJKR.js → search-DwoUV2pv.js} +1 -1
- package/admin-dist/public/assets/select-hOZTp8aC.js +1 -0
- package/admin-dist/public/assets/settings-t2PbCZh4.js +1 -0
- package/admin-dist/public/assets/switch-jX2pDaNU.js +1 -0
- package/admin-dist/public/assets/tabs-q4EbZk7c.js +1 -0
- package/admin-dist/public/assets/tanstack-adapter-B-Glm4kH.js +1 -0
- package/admin-dist/public/assets/taxonomies-kyk5P4ZW.js +1 -0
- package/admin-dist/public/assets/{textarea-BTy7nwzR.js → textarea-B6SfBmr0.js} +1 -1
- package/admin-dist/public/assets/trash-BOCnIznD.js +1 -0
- package/admin-dist/public/assets/{triangle-alert-E52Vfeuh.js → triangle-alert-CXFIO_Gu.js} +1 -1
- package/admin-dist/public/assets/useBreadcrumbLabel-_6qBagc3.js +1 -0
- package/admin-dist/public/assets/{usePermissions-Basjs9BT.js → usePermissions-M1ijZ7a6.js} +1 -1
- package/admin-dist/server/_chunks/_libs/@tanstack/react-router.mjs +7 -0
- package/admin-dist/server/_ssr/{badge-6BsP37vG.mjs → CmsButton-DOiTVKQq.mjs} +33 -33
- package/admin-dist/server/_ssr/{CmsEmptyState-DU7-7-mV.mjs → CmsEmptyState-fbnGt3LD.mjs} +2 -2
- package/admin-dist/server/_ssr/{CmsPageHeader-CseW0AHm.mjs → CmsPageHeader-DHRrdOZa.mjs} +1 -1
- package/admin-dist/server/_ssr/{CmsStatusBadge-B_pi4KCp.mjs → CmsStatusBadge-s7obWbKZ.mjs} +2 -2
- package/admin-dist/server/_ssr/CmsSurface-rFoYjb62.mjs +44 -0
- package/admin-dist/server/_ssr/{CmsToolbar-X75ex6ek.mjs → CmsToolbar-zTE45z2q.mjs} +2 -2
- package/admin-dist/server/_ssr/{ContentEntryEditor-CepusRsA.mjs → ContentEntryEditor-BLoEjT_m.mjs} +12 -12
- package/admin-dist/server/_ssr/{TaxonomyFilter-Bwrq0-cz.mjs → TaxonomyFilter-XAtaJC2z.mjs} +5 -5
- package/admin-dist/server/_ssr/{_contentTypeId-BqYKEcLr.mjs → _contentTypeId-Csl4822C.mjs} +13 -13
- package/admin-dist/server/_ssr/{_entryId-CRfnqeDf.mjs → _entryId-D8alLFBx.mjs} +15 -15
- package/admin-dist/server/_ssr/_tanstack-start-manifest_v-BffZedId.mjs +4 -0
- package/admin-dist/server/_ssr/{command-fy8epIKf.mjs → command-C0Di14--.mjs} +1 -1
- package/admin-dist/server/_ssr/{content-B5RhL7uW.mjs → content-CT-FPsmV.mjs} +170 -98
- package/admin-dist/server/_ssr/{content-types-BIOqCQYN.mjs → content-types-C8cBFdzE.mjs} +260 -115
- package/admin-dist/server/_ssr/{index-DHSHDPt1.mjs → index-BJtcrEc-.mjs} +88 -17
- package/admin-dist/server/_ssr/index.mjs +2 -2
- package/admin-dist/server/_ssr/{label-C8Dko1j7.mjs → label-qn2Afwl4.mjs} +1 -1
- package/admin-dist/server/_ssr/{media-CSx3XttC.mjs → media-qv5IAsMZ.mjs} +43 -43
- package/admin-dist/server/_ssr/{new._contentTypeId-DzanEZQM.mjs → new._contentTypeId-DdGyrhqs.mjs} +13 -13
- package/admin-dist/server/_ssr/{router-DDWcF-kt.mjs → router-nSVkxb6Y.mjs} +11 -11
- package/admin-dist/server/_ssr/{scroll-area-bjPYwhXN.mjs → scroll-area-BCinP455.mjs} +1 -1
- package/admin-dist/server/_ssr/{select-BUhDDf4T.mjs → select-BKQlQScw.mjs} +1 -1
- package/admin-dist/server/_ssr/{settings-DAsxnw2q.mjs → settings-BCr2KQlk.mjs} +236 -139
- package/admin-dist/server/_ssr/{switch-BgyRtQ1Z.mjs → switch-BaOi42fE.mjs} +1 -1
- package/admin-dist/server/_ssr/{tabs-DzMdRB1A.mjs → tabs-DYXEi9kq.mjs} +5 -3
- package/admin-dist/server/_ssr/tanstack-adapter-Bsz8kha-.mjs +119 -0
- package/admin-dist/server/_ssr/{taxonomies-C8j8g5Q5.mjs → taxonomies-CueMHTbE.mjs} +184 -73
- package/admin-dist/server/_ssr/{textarea-9jNeYJSc.mjs → textarea-CI0Jqx2x.mjs} +1 -1
- package/admin-dist/server/_ssr/{trash-DYMxwhZB.mjs → trash-DE6W8GoX.mjs} +211 -88
- package/admin-dist/server/_ssr/{useBreadcrumbLabel-FNSAr2Ha.mjs → useBreadcrumbLabel-B5Yi72lM.mjs} +1 -1
- package/admin-dist/server/_ssr/{usePermissions-BJGGahrJ.mjs → usePermissions-C3nZ-Izm.mjs} +1 -1
- package/admin-dist/server/index.mjs +189 -182
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +156 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/index.js +6 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/client/admin/bulk.d.ts +79 -0
- package/dist/client/admin/bulk.d.ts.map +1 -0
- package/dist/client/admin/bulk.js +72 -0
- package/dist/client/admin/bulk.js.map +1 -0
- package/dist/client/admin/contentLock.d.ts +118 -0
- package/dist/client/admin/contentLock.d.ts.map +1 -0
- package/dist/client/admin/contentLock.js +81 -0
- package/dist/client/admin/contentLock.js.map +1 -0
- package/dist/client/admin/contentTypes.d.ts +1204 -0
- package/dist/client/admin/contentTypes.d.ts.map +1 -0
- package/dist/client/admin/contentTypes.js +122 -0
- package/dist/client/admin/contentTypes.js.map +1 -0
- package/dist/client/admin/dashboard.d.ts +16 -0
- package/dist/client/admin/dashboard.d.ts.map +1 -0
- package/dist/client/admin/dashboard.js +33 -0
- package/dist/client/admin/dashboard.js.map +1 -0
- package/dist/client/admin/entries.d.ts +358 -0
- package/dist/client/admin/entries.d.ts.map +1 -0
- package/dist/client/admin/entries.js +220 -0
- package/dist/client/admin/entries.js.map +1 -0
- package/dist/client/admin/index.d.ts +6568 -0
- package/dist/client/admin/index.d.ts.map +1 -0
- package/dist/client/admin/index.js +305 -0
- package/dist/client/admin/index.js.map +1 -0
- package/dist/client/admin/media.d.ts +1038 -0
- package/dist/client/admin/media.d.ts.map +1 -0
- package/dist/client/admin/media.js +489 -0
- package/dist/client/admin/media.js.map +1 -0
- package/dist/client/admin/taxonomies.d.ts +339 -0
- package/dist/client/admin/taxonomies.d.ts.map +1 -0
- package/dist/client/admin/taxonomies.js +364 -0
- package/dist/client/admin/taxonomies.js.map +1 -0
- package/dist/client/admin/trash.d.ts +91 -0
- package/dist/client/admin/trash.d.ts.map +1 -0
- package/dist/client/admin/trash.js +71 -0
- package/dist/client/admin/trash.js.map +1 -0
- package/dist/client/admin/types.d.ts +320 -0
- package/dist/client/admin/types.d.ts.map +1 -0
- package/dist/client/admin/types.js +7 -0
- package/dist/client/admin/types.js.map +1 -0
- package/dist/client/admin/validators.d.ts +3886 -0
- package/dist/client/admin/validators.d.ts.map +1 -0
- package/dist/client/admin/validators.js +322 -0
- package/dist/client/admin/validators.js.map +1 -0
- package/dist/client/admin/versions.d.ts +106 -0
- package/dist/client/admin/versions.d.ts.map +1 -0
- package/dist/client/admin/versions.js +57 -0
- package/dist/client/admin/versions.js.map +1 -0
- package/dist/client/adminApiTypes.d.ts +27 -0
- package/dist/client/adminApiTypes.d.ts.map +1 -0
- package/dist/client/adminApiTypes.js +12 -0
- package/dist/client/adminApiTypes.js.map +1 -0
- package/dist/client/{admin-config.d.ts → adminConfig.d.ts} +4 -4
- package/dist/client/adminConfig.d.ts.map +1 -0
- package/dist/client/{admin-config.js → adminConfig.js} +3 -3
- package/dist/client/adminConfig.js.map +1 -0
- package/dist/client/agentTools.d.ts +11 -21
- package/dist/client/agentTools.d.ts.map +1 -1
- package/dist/client/agentTools.js +4 -4
- package/dist/client/index.d.ts +6 -6
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +19 -6
- package/dist/client/index.js.map +1 -1
- package/dist/client/schema/codegen.d.ts +2 -2
- package/dist/client/schema/codegen.d.ts.map +1 -1
- package/dist/client/schema/codegen.js +3 -3
- package/dist/client/schema/codegen.js.map +1 -1
- package/dist/client/schema/defineContentType.d.ts +3 -3
- package/dist/client/schema/defineContentType.js +3 -3
- package/dist/client/schema/index.d.ts +7 -7
- package/dist/client/schema/index.d.ts.map +1 -1
- package/dist/client/schema/index.js +5 -5
- package/dist/client/schema/index.js.map +1 -1
- package/dist/client/schema/schemaDrift.d.ts +1 -1
- package/dist/client/schema/schemaDrift.js +1 -1
- package/dist/client/schema/typedClient.d.ts +2 -2
- package/dist/client/schema/typedClient.js +2 -2
- package/dist/client/schema/types.d.ts +1 -1
- package/dist/client/schema/types.js +1 -1
- package/dist/client/wrapper.d.ts +108 -65
- package/dist/client/wrapper.d.ts.map +1 -1
- package/dist/client/wrapper.js +22 -22
- package/dist/client/wrapper.js.map +1 -1
- package/dist/component/contentEntries.d.ts +4 -4
- package/dist/component/contentEntryMutations.d.ts +46 -0
- package/dist/component/contentEntryMutations.d.ts.map +1 -1
- package/dist/component/contentEntryMutations.js +1 -1
- package/dist/component/contentEntryMutations.js.map +1 -1
- package/dist/component/contentTypeMigration.d.ts +1 -1
- package/dist/component/contentTypeMutations.d.ts +22 -0
- package/dist/component/contentTypeMutations.d.ts.map +1 -1
- package/dist/component/contentTypeMutations.js +1 -1
- package/dist/component/contentTypeMutations.js.map +1 -1
- package/dist/component/convex.config.d.ts +2 -2
- package/dist/component/convex.config.js +2 -2
- package/dist/component/index.d.ts +1 -1
- package/dist/component/index.js +1 -1
- package/dist/component/lib/ragContentChunker.d.ts +1 -1
- package/dist/component/lib/ragContentChunker.js +1 -1
- package/dist/component/mediaAssetMutations.d.ts +47 -0
- package/dist/component/mediaAssetMutations.d.ts.map +1 -1
- package/dist/component/mediaAssetMutations.js +1 -1
- package/dist/component/mediaAssetMutations.js.map +1 -1
- package/dist/component/roles.d.ts +1 -1
- package/dist/component/roles.js +1 -1
- package/dist/component/schema.d.ts +9 -0
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +1 -1
- package/dist/component/schema.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +13 -7
- package/dist/react/index.js.map +1 -1
- package/dist/test.d.ts +2 -2
- package/dist/test.js +2 -2
- package/package.json +115 -13
- package/admin-dist/public/assets/ErrorState-BIVaWmom.js +0 -1
- package/admin-dist/public/assets/TaxonomyFilter-ChaY6Y_x.js +0 -1
- package/admin-dist/public/assets/_contentTypeId-DQ8k_Rvw.js +0 -1
- package/admin-dist/public/assets/alert-BXjTqrwQ.js +0 -1
- package/admin-dist/public/assets/content-_LXl3pp7.js +0 -1
- package/admin-dist/public/assets/content-types-KjxaXGxY.js +0 -2
- package/admin-dist/public/assets/globals-CS6BZ0zp.css +0 -1
- package/admin-dist/public/assets/index-DNGIZHL-.js +0 -1
- package/admin-dist/public/assets/media-Bkrkffm7.js +0 -1
- package/admin-dist/public/assets/scroll-area-DfIlT0in.js +0 -1
- package/admin-dist/public/assets/select-BD29IXCI.js +0 -1
- package/admin-dist/public/assets/settings-DmMyn_6A.js +0 -1
- package/admin-dist/public/assets/switch-h3Rrnl5i.js +0 -1
- package/admin-dist/public/assets/tabs-imc8h-Dp.js +0 -1
- package/admin-dist/public/assets/taxonomies-dAsrT65H.js +0 -1
- package/admin-dist/public/assets/trash-SAWKZZHv.js +0 -1
- package/admin-dist/public/assets/useBreadcrumbLabel-BECBMCzM.js +0 -1
- package/admin-dist/server/_ssr/ErrorState-cI-bKLez.mjs +0 -89
- package/admin-dist/server/_ssr/_tanstack-start-manifest_v-BwDlABVk.mjs +0 -4
- package/admin-dist/server/_ssr/alert-CVt45UUP.mjs +0 -92
- package/dist/client/admin-config.d.ts.map +0 -1
- package/dist/client/admin-config.js.map +0 -1
- package/dist/client/adminApi.d.ts +0 -2273
- package/dist/client/adminApi.d.ts.map +0 -1
- package/dist/client/adminApi.js +0 -716
- package/dist/client/adminApi.js.map +0 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Page Components
|
|
3
|
+
*
|
|
4
|
+
* These pages contain all the business logic and UI for the admin interface.
|
|
5
|
+
* They are used by both CLI routes (TanStack Router) and embed pages.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export { ContentPage, type ContentPageProps } from "./ContentPage";
|
|
9
|
+
export { ContentTypesPage, type ContentTypesPageProps } from "./ContentTypesPage";
|
|
10
|
+
export { DashboardPage } from "./DashboardPage";
|
|
11
|
+
export { MediaPage, type MediaPageProps } from "./MediaPage";
|
|
12
|
+
export { SettingsPage, type SettingsPageProps } from "./SettingsPage";
|
|
13
|
+
export { TaxonomiesPage, type TaxonomiesPageProps } from "./TaxonomiesPage";
|
|
14
|
+
export { TrashPage, type TrashPageProps } from "./TrashPage";
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
|
|
5
|
+
// noinspection JSUnusedGlobalSymbols
|
|
6
|
+
|
|
7
|
+
// This file was automatically generated by TanStack Router.
|
|
8
|
+
// You should NOT make any changes in this file as it will be overwritten.
|
|
9
|
+
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
|
10
|
+
|
|
11
|
+
import { Route as rootRouteImport } from './routes/__root'
|
|
12
|
+
import { Route as TrashRouteImport } from './routes/trash'
|
|
13
|
+
import { Route as TaxonomiesRouteImport } from './routes/taxonomies'
|
|
14
|
+
import { Route as SettingsRouteImport } from './routes/settings'
|
|
15
|
+
import { Route as MediaRouteImport } from './routes/media'
|
|
16
|
+
import { Route as ContentTypesRouteImport } from './routes/content-types'
|
|
17
|
+
import { Route as ContentRouteImport } from './routes/content'
|
|
18
|
+
import { Route as IndexRouteImport } from './routes/index'
|
|
19
|
+
import { Route as EntriesEntryIdRouteImport } from './routes/entries/$entryId'
|
|
20
|
+
import { Route as EntriesTypeContentTypeIdRouteImport } from './routes/entries/type/$contentTypeId'
|
|
21
|
+
import { Route as EntriesNewContentTypeIdRouteImport } from './routes/entries/new.$contentTypeId'
|
|
22
|
+
|
|
23
|
+
const TrashRoute = TrashRouteImport.update({
|
|
24
|
+
id: '/trash',
|
|
25
|
+
path: '/trash',
|
|
26
|
+
getParentRoute: () => rootRouteImport,
|
|
27
|
+
} as any)
|
|
28
|
+
const TaxonomiesRoute = TaxonomiesRouteImport.update({
|
|
29
|
+
id: '/taxonomies',
|
|
30
|
+
path: '/taxonomies',
|
|
31
|
+
getParentRoute: () => rootRouteImport,
|
|
32
|
+
} as any)
|
|
33
|
+
const SettingsRoute = SettingsRouteImport.update({
|
|
34
|
+
id: '/settings',
|
|
35
|
+
path: '/settings',
|
|
36
|
+
getParentRoute: () => rootRouteImport,
|
|
37
|
+
} as any)
|
|
38
|
+
const MediaRoute = MediaRouteImport.update({
|
|
39
|
+
id: '/media',
|
|
40
|
+
path: '/media',
|
|
41
|
+
getParentRoute: () => rootRouteImport,
|
|
42
|
+
} as any)
|
|
43
|
+
const ContentTypesRoute = ContentTypesRouteImport.update({
|
|
44
|
+
id: '/content-types',
|
|
45
|
+
path: '/content-types',
|
|
46
|
+
getParentRoute: () => rootRouteImport,
|
|
47
|
+
} as any)
|
|
48
|
+
const ContentRoute = ContentRouteImport.update({
|
|
49
|
+
id: '/content',
|
|
50
|
+
path: '/content',
|
|
51
|
+
getParentRoute: () => rootRouteImport,
|
|
52
|
+
} as any)
|
|
53
|
+
const IndexRoute = IndexRouteImport.update({
|
|
54
|
+
id: '/',
|
|
55
|
+
path: '/',
|
|
56
|
+
getParentRoute: () => rootRouteImport,
|
|
57
|
+
} as any)
|
|
58
|
+
const EntriesEntryIdRoute = EntriesEntryIdRouteImport.update({
|
|
59
|
+
id: '/entries/$entryId',
|
|
60
|
+
path: '/entries/$entryId',
|
|
61
|
+
getParentRoute: () => rootRouteImport,
|
|
62
|
+
} as any)
|
|
63
|
+
const EntriesTypeContentTypeIdRoute =
|
|
64
|
+
EntriesTypeContentTypeIdRouteImport.update({
|
|
65
|
+
id: '/entries/type/$contentTypeId',
|
|
66
|
+
path: '/entries/type/$contentTypeId',
|
|
67
|
+
getParentRoute: () => rootRouteImport,
|
|
68
|
+
} as any)
|
|
69
|
+
const EntriesNewContentTypeIdRoute = EntriesNewContentTypeIdRouteImport.update({
|
|
70
|
+
id: '/entries/new/$contentTypeId',
|
|
71
|
+
path: '/entries/new/$contentTypeId',
|
|
72
|
+
getParentRoute: () => rootRouteImport,
|
|
73
|
+
} as any)
|
|
74
|
+
|
|
75
|
+
export interface FileRoutesByFullPath {
|
|
76
|
+
'/': typeof IndexRoute
|
|
77
|
+
'/content': typeof ContentRoute
|
|
78
|
+
'/content-types': typeof ContentTypesRoute
|
|
79
|
+
'/media': typeof MediaRoute
|
|
80
|
+
'/settings': typeof SettingsRoute
|
|
81
|
+
'/taxonomies': typeof TaxonomiesRoute
|
|
82
|
+
'/trash': typeof TrashRoute
|
|
83
|
+
'/entries/$entryId': typeof EntriesEntryIdRoute
|
|
84
|
+
'/entries/new/$contentTypeId': typeof EntriesNewContentTypeIdRoute
|
|
85
|
+
'/entries/type/$contentTypeId': typeof EntriesTypeContentTypeIdRoute
|
|
86
|
+
}
|
|
87
|
+
export interface FileRoutesByTo {
|
|
88
|
+
'/': typeof IndexRoute
|
|
89
|
+
'/content': typeof ContentRoute
|
|
90
|
+
'/content-types': typeof ContentTypesRoute
|
|
91
|
+
'/media': typeof MediaRoute
|
|
92
|
+
'/settings': typeof SettingsRoute
|
|
93
|
+
'/taxonomies': typeof TaxonomiesRoute
|
|
94
|
+
'/trash': typeof TrashRoute
|
|
95
|
+
'/entries/$entryId': typeof EntriesEntryIdRoute
|
|
96
|
+
'/entries/new/$contentTypeId': typeof EntriesNewContentTypeIdRoute
|
|
97
|
+
'/entries/type/$contentTypeId': typeof EntriesTypeContentTypeIdRoute
|
|
98
|
+
}
|
|
99
|
+
export interface FileRoutesById {
|
|
100
|
+
__root__: typeof rootRouteImport
|
|
101
|
+
'/': typeof IndexRoute
|
|
102
|
+
'/content': typeof ContentRoute
|
|
103
|
+
'/content-types': typeof ContentTypesRoute
|
|
104
|
+
'/media': typeof MediaRoute
|
|
105
|
+
'/settings': typeof SettingsRoute
|
|
106
|
+
'/taxonomies': typeof TaxonomiesRoute
|
|
107
|
+
'/trash': typeof TrashRoute
|
|
108
|
+
'/entries/$entryId': typeof EntriesEntryIdRoute
|
|
109
|
+
'/entries/new/$contentTypeId': typeof EntriesNewContentTypeIdRoute
|
|
110
|
+
'/entries/type/$contentTypeId': typeof EntriesTypeContentTypeIdRoute
|
|
111
|
+
}
|
|
112
|
+
export interface FileRouteTypes {
|
|
113
|
+
fileRoutesByFullPath: FileRoutesByFullPath
|
|
114
|
+
fullPaths:
|
|
115
|
+
| '/'
|
|
116
|
+
| '/content'
|
|
117
|
+
| '/content-types'
|
|
118
|
+
| '/media'
|
|
119
|
+
| '/settings'
|
|
120
|
+
| '/taxonomies'
|
|
121
|
+
| '/trash'
|
|
122
|
+
| '/entries/$entryId'
|
|
123
|
+
| '/entries/new/$contentTypeId'
|
|
124
|
+
| '/entries/type/$contentTypeId'
|
|
125
|
+
fileRoutesByTo: FileRoutesByTo
|
|
126
|
+
to:
|
|
127
|
+
| '/'
|
|
128
|
+
| '/content'
|
|
129
|
+
| '/content-types'
|
|
130
|
+
| '/media'
|
|
131
|
+
| '/settings'
|
|
132
|
+
| '/taxonomies'
|
|
133
|
+
| '/trash'
|
|
134
|
+
| '/entries/$entryId'
|
|
135
|
+
| '/entries/new/$contentTypeId'
|
|
136
|
+
| '/entries/type/$contentTypeId'
|
|
137
|
+
id:
|
|
138
|
+
| '__root__'
|
|
139
|
+
| '/'
|
|
140
|
+
| '/content'
|
|
141
|
+
| '/content-types'
|
|
142
|
+
| '/media'
|
|
143
|
+
| '/settings'
|
|
144
|
+
| '/taxonomies'
|
|
145
|
+
| '/trash'
|
|
146
|
+
| '/entries/$entryId'
|
|
147
|
+
| '/entries/new/$contentTypeId'
|
|
148
|
+
| '/entries/type/$contentTypeId'
|
|
149
|
+
fileRoutesById: FileRoutesById
|
|
150
|
+
}
|
|
151
|
+
export interface RootRouteChildren {
|
|
152
|
+
IndexRoute: typeof IndexRoute
|
|
153
|
+
ContentRoute: typeof ContentRoute
|
|
154
|
+
ContentTypesRoute: typeof ContentTypesRoute
|
|
155
|
+
MediaRoute: typeof MediaRoute
|
|
156
|
+
SettingsRoute: typeof SettingsRoute
|
|
157
|
+
TaxonomiesRoute: typeof TaxonomiesRoute
|
|
158
|
+
TrashRoute: typeof TrashRoute
|
|
159
|
+
EntriesEntryIdRoute: typeof EntriesEntryIdRoute
|
|
160
|
+
EntriesNewContentTypeIdRoute: typeof EntriesNewContentTypeIdRoute
|
|
161
|
+
EntriesTypeContentTypeIdRoute: typeof EntriesTypeContentTypeIdRoute
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
declare module '@tanstack/react-router' {
|
|
165
|
+
interface FileRoutesByPath {
|
|
166
|
+
'/trash': {
|
|
167
|
+
id: '/trash'
|
|
168
|
+
path: '/trash'
|
|
169
|
+
fullPath: '/trash'
|
|
170
|
+
preLoaderRoute: typeof TrashRouteImport
|
|
171
|
+
parentRoute: typeof rootRouteImport
|
|
172
|
+
}
|
|
173
|
+
'/taxonomies': {
|
|
174
|
+
id: '/taxonomies'
|
|
175
|
+
path: '/taxonomies'
|
|
176
|
+
fullPath: '/taxonomies'
|
|
177
|
+
preLoaderRoute: typeof TaxonomiesRouteImport
|
|
178
|
+
parentRoute: typeof rootRouteImport
|
|
179
|
+
}
|
|
180
|
+
'/settings': {
|
|
181
|
+
id: '/settings'
|
|
182
|
+
path: '/settings'
|
|
183
|
+
fullPath: '/settings'
|
|
184
|
+
preLoaderRoute: typeof SettingsRouteImport
|
|
185
|
+
parentRoute: typeof rootRouteImport
|
|
186
|
+
}
|
|
187
|
+
'/media': {
|
|
188
|
+
id: '/media'
|
|
189
|
+
path: '/media'
|
|
190
|
+
fullPath: '/media'
|
|
191
|
+
preLoaderRoute: typeof MediaRouteImport
|
|
192
|
+
parentRoute: typeof rootRouteImport
|
|
193
|
+
}
|
|
194
|
+
'/content-types': {
|
|
195
|
+
id: '/content-types'
|
|
196
|
+
path: '/content-types'
|
|
197
|
+
fullPath: '/content-types'
|
|
198
|
+
preLoaderRoute: typeof ContentTypesRouteImport
|
|
199
|
+
parentRoute: typeof rootRouteImport
|
|
200
|
+
}
|
|
201
|
+
'/content': {
|
|
202
|
+
id: '/content'
|
|
203
|
+
path: '/content'
|
|
204
|
+
fullPath: '/content'
|
|
205
|
+
preLoaderRoute: typeof ContentRouteImport
|
|
206
|
+
parentRoute: typeof rootRouteImport
|
|
207
|
+
}
|
|
208
|
+
'/': {
|
|
209
|
+
id: '/'
|
|
210
|
+
path: '/'
|
|
211
|
+
fullPath: '/'
|
|
212
|
+
preLoaderRoute: typeof IndexRouteImport
|
|
213
|
+
parentRoute: typeof rootRouteImport
|
|
214
|
+
}
|
|
215
|
+
'/entries/$entryId': {
|
|
216
|
+
id: '/entries/$entryId'
|
|
217
|
+
path: '/entries/$entryId'
|
|
218
|
+
fullPath: '/entries/$entryId'
|
|
219
|
+
preLoaderRoute: typeof EntriesEntryIdRouteImport
|
|
220
|
+
parentRoute: typeof rootRouteImport
|
|
221
|
+
}
|
|
222
|
+
'/entries/type/$contentTypeId': {
|
|
223
|
+
id: '/entries/type/$contentTypeId'
|
|
224
|
+
path: '/entries/type/$contentTypeId'
|
|
225
|
+
fullPath: '/entries/type/$contentTypeId'
|
|
226
|
+
preLoaderRoute: typeof EntriesTypeContentTypeIdRouteImport
|
|
227
|
+
parentRoute: typeof rootRouteImport
|
|
228
|
+
}
|
|
229
|
+
'/entries/new/$contentTypeId': {
|
|
230
|
+
id: '/entries/new/$contentTypeId'
|
|
231
|
+
path: '/entries/new/$contentTypeId'
|
|
232
|
+
fullPath: '/entries/new/$contentTypeId'
|
|
233
|
+
preLoaderRoute: typeof EntriesNewContentTypeIdRouteImport
|
|
234
|
+
parentRoute: typeof rootRouteImport
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const rootRouteChildren: RootRouteChildren = {
|
|
240
|
+
IndexRoute: IndexRoute,
|
|
241
|
+
ContentRoute: ContentRoute,
|
|
242
|
+
ContentTypesRoute: ContentTypesRoute,
|
|
243
|
+
MediaRoute: MediaRoute,
|
|
244
|
+
SettingsRoute: SettingsRoute,
|
|
245
|
+
TaxonomiesRoute: TaxonomiesRoute,
|
|
246
|
+
TrashRoute: TrashRoute,
|
|
247
|
+
EntriesEntryIdRoute: EntriesEntryIdRoute,
|
|
248
|
+
EntriesNewContentTypeIdRoute: EntriesNewContentTypeIdRoute,
|
|
249
|
+
EntriesTypeContentTypeIdRoute: EntriesTypeContentTypeIdRoute,
|
|
250
|
+
}
|
|
251
|
+
export const routeTree = rootRouteImport
|
|
252
|
+
._addFileChildren(rootRouteChildren)
|
|
253
|
+
._addFileTypes<FileRouteTypes>()
|
|
254
|
+
|
|
255
|
+
import type { getRouter } from './router.tsx'
|
|
256
|
+
import type { createStart } from '@tanstack/react-start'
|
|
257
|
+
declare module '@tanstack/react-start' {
|
|
258
|
+
interface Register {
|
|
259
|
+
ssr: true
|
|
260
|
+
router: Awaited<ReturnType<typeof getRouter>>
|
|
261
|
+
}
|
|
262
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createRouter } from '@tanstack/react-router'
|
|
2
|
+
import { routeTree } from './routeTree.gen'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates and configures the TanStack Router instance for the admin application.
|
|
6
|
+
* This function is called by TanStack Start to initialize routing.
|
|
7
|
+
*/
|
|
8
|
+
export function getRouter() {
|
|
9
|
+
const router = createRouter({
|
|
10
|
+
routeTree,
|
|
11
|
+
scrollRestoration: true,
|
|
12
|
+
defaultPreload: 'intent',
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
return router
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare module '@tanstack/react-router' {
|
|
19
|
+
interface Register {
|
|
20
|
+
router: ReturnType<typeof getRouter>
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Outlet,
|
|
3
|
+
createRootRoute,
|
|
4
|
+
HeadContent,
|
|
5
|
+
Scripts,
|
|
6
|
+
} from "@tanstack/react-router";
|
|
7
|
+
import { ConvexProvider, ConvexReactClient } from "convex/react";
|
|
8
|
+
import { useMemo, type ReactNode } from "react";
|
|
9
|
+
import globalsCss from "~/styles/globals.css?url";
|
|
10
|
+
import { AdminLayout, RouteGuard } from "~/components";
|
|
11
|
+
import {
|
|
12
|
+
AuthProvider,
|
|
13
|
+
BreadcrumbProvider,
|
|
14
|
+
SettingsConfigProvider,
|
|
15
|
+
ThemeProvider,
|
|
16
|
+
type GetUserHook,
|
|
17
|
+
type GetUserRoleHook,
|
|
18
|
+
type LogoutHook,
|
|
19
|
+
} from "~/contexts";
|
|
20
|
+
import type { AdminConfig } from "~/lib/admin-config";
|
|
21
|
+
import { resolveAdminConfig } from "~/lib/admin-config";
|
|
22
|
+
import { getServerConfig, type ServerConfig } from "~/lib/config.server";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Auth Configuration
|
|
26
|
+
*
|
|
27
|
+
* These hooks integrate with the parent app's authentication system.
|
|
28
|
+
* In a real deployment, these would be provided by your auth provider
|
|
29
|
+
* (Clerk, Auth0, Convex Auth, etc.).
|
|
30
|
+
*
|
|
31
|
+
* For development/demo purposes, we provide a mock implementation.
|
|
32
|
+
* Replace these with actual auth integration in production.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Mock user for development.
|
|
37
|
+
* Set AUTH_MODE=demo to use this, or customize for your auth provider.
|
|
38
|
+
*/
|
|
39
|
+
const mockGetUser: GetUserHook = () => {
|
|
40
|
+
// In development/demo mode, return a mock admin user
|
|
41
|
+
return {
|
|
42
|
+
id: "mock_user_123",
|
|
43
|
+
name: "Demo Admin",
|
|
44
|
+
email: "admin@example.com",
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Mock role resolver for development.
|
|
50
|
+
* Returns 'admin' for the mock user.
|
|
51
|
+
*/
|
|
52
|
+
const mockGetUserRole: GetUserRoleHook = () => {
|
|
53
|
+
// In development/demo mode, return admin role
|
|
54
|
+
return "admin";
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Mock logout handler.
|
|
59
|
+
*/
|
|
60
|
+
const mockLogout: LogoutHook = () => {
|
|
61
|
+
console.log("Logout called (mock mode)");
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* No-auth mode - for when auth is not configured.
|
|
66
|
+
* Returns null to indicate unauthenticated state.
|
|
67
|
+
*/
|
|
68
|
+
const noAuthGetUser: GetUserHook = () => null;
|
|
69
|
+
const noAuthGetUserRole: GetUserRoleHook = () => null;
|
|
70
|
+
const noAuthLogout: LogoutHook = () => {};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get auth hooks based on configuration.
|
|
74
|
+
* Extend this to support different auth providers.
|
|
75
|
+
*/
|
|
76
|
+
function getAuthConfig(authMode: string): {
|
|
77
|
+
getUser: GetUserHook;
|
|
78
|
+
getUserRole: GetUserRoleHook;
|
|
79
|
+
onLogout: LogoutHook;
|
|
80
|
+
} {
|
|
81
|
+
switch (authMode) {
|
|
82
|
+
case "mock":
|
|
83
|
+
case "demo":
|
|
84
|
+
return {
|
|
85
|
+
getUser: mockGetUser,
|
|
86
|
+
getUserRole: mockGetUserRole,
|
|
87
|
+
onLogout: mockLogout,
|
|
88
|
+
};
|
|
89
|
+
case "none":
|
|
90
|
+
case "disabled":
|
|
91
|
+
return {
|
|
92
|
+
getUser: noAuthGetUser,
|
|
93
|
+
getUserRole: noAuthGetUserRole,
|
|
94
|
+
onLogout: noAuthLogout,
|
|
95
|
+
};
|
|
96
|
+
default:
|
|
97
|
+
// Default to mock mode for development convenience
|
|
98
|
+
// In production, you should configure your actual auth provider
|
|
99
|
+
return {
|
|
100
|
+
getUser: mockGetUser,
|
|
101
|
+
getUserRole: mockGetUserRole,
|
|
102
|
+
onLogout: mockLogout,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export const Route = createRootRoute({
|
|
108
|
+
head: () => ({
|
|
109
|
+
meta: [
|
|
110
|
+
{
|
|
111
|
+
charSet: "utf-8",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "viewport",
|
|
115
|
+
content: "width=device-width, initial-scale=1",
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
title: "Convex CMS Admin",
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "description",
|
|
122
|
+
content:
|
|
123
|
+
"Admin interface for Convex CMS - manage content, media, and publishing workflows",
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
links: [
|
|
127
|
+
{ rel: "stylesheet", href: globalsCss },
|
|
128
|
+
{ rel: "icon", href: "/favicon.ico" },
|
|
129
|
+
],
|
|
130
|
+
}),
|
|
131
|
+
// Load server config at route initialization
|
|
132
|
+
loader: async () => {
|
|
133
|
+
const config = await getServerConfig();
|
|
134
|
+
return { config };
|
|
135
|
+
},
|
|
136
|
+
component: RootComponent,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
function RootComponent() {
|
|
140
|
+
const { config } = Route.useLoaderData();
|
|
141
|
+
|
|
142
|
+
const authConfig = useMemo(() => getAuthConfig(config.authMode), [config.authMode]);
|
|
143
|
+
const adminConfig = useMemo(
|
|
144
|
+
() => resolveAdminConfig(config.adminConfig),
|
|
145
|
+
[config.adminConfig]
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<RootDocument>
|
|
150
|
+
<ThemeProvider>
|
|
151
|
+
<BreadcrumbProvider>
|
|
152
|
+
<ConvexProviderWrapper config={config} adminConfig={adminConfig}>
|
|
153
|
+
<AuthProvider
|
|
154
|
+
getUser={authConfig.getUser}
|
|
155
|
+
getUserRole={authConfig.getUserRole}
|
|
156
|
+
onLogout={authConfig.onLogout}
|
|
157
|
+
>
|
|
158
|
+
<RouteGuard>
|
|
159
|
+
<AdminLayout>
|
|
160
|
+
<Outlet />
|
|
161
|
+
</AdminLayout>
|
|
162
|
+
</RouteGuard>
|
|
163
|
+
</AuthProvider>
|
|
164
|
+
</ConvexProviderWrapper>
|
|
165
|
+
</BreadcrumbProvider>
|
|
166
|
+
</ThemeProvider>
|
|
167
|
+
</RootDocument>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function ConvexProviderWrapper({
|
|
172
|
+
children,
|
|
173
|
+
config,
|
|
174
|
+
adminConfig,
|
|
175
|
+
}: {
|
|
176
|
+
children: ReactNode;
|
|
177
|
+
config: ServerConfig;
|
|
178
|
+
adminConfig: AdminConfig;
|
|
179
|
+
}) {
|
|
180
|
+
const convex = useMemo(() => {
|
|
181
|
+
if (!config.convexUrl) return null;
|
|
182
|
+
return new ConvexReactClient(config.convexUrl);
|
|
183
|
+
}, [config.convexUrl]);
|
|
184
|
+
|
|
185
|
+
if (!convex) {
|
|
186
|
+
return (
|
|
187
|
+
<div className="flex min-h-screen items-center justify-center bg-background p-6">
|
|
188
|
+
<div className="max-w-lg space-y-4 rounded-lg border border-amber-200 bg-amber-50 p-6 text-center">
|
|
189
|
+
<h2 className="text-xl font-semibold text-amber-900">
|
|
190
|
+
Convex Configuration Required
|
|
191
|
+
</h2>
|
|
192
|
+
<p className="text-sm text-amber-800">
|
|
193
|
+
Please provide a Convex deployment URL to connect to your backend.
|
|
194
|
+
</p>
|
|
195
|
+
<div className="space-y-2 text-left text-sm text-amber-700">
|
|
196
|
+
<p className="font-medium">Options:</p>
|
|
197
|
+
<ul className="list-inside list-disc space-y-1">
|
|
198
|
+
<li>
|
|
199
|
+
Run with URL:{" "}
|
|
200
|
+
<code className="rounded bg-amber-100 px-1">
|
|
201
|
+
npx convex-cms admin --url YOUR_URL
|
|
202
|
+
</code>
|
|
203
|
+
</li>
|
|
204
|
+
<li>
|
|
205
|
+
Set environment variable:{" "}
|
|
206
|
+
<code className="rounded bg-amber-100 px-1">
|
|
207
|
+
CONVEX_URL=YOUR_URL
|
|
208
|
+
</code>
|
|
209
|
+
</li>
|
|
210
|
+
<li>
|
|
211
|
+
Add to{" "}
|
|
212
|
+
<code className="rounded bg-amber-100 px-1">.env.local</code>:{" "}
|
|
213
|
+
<code className="rounded bg-amber-100 px-1">
|
|
214
|
+
CONVEX_URL=YOUR_URL
|
|
215
|
+
</code>
|
|
216
|
+
</li>
|
|
217
|
+
</ul>
|
|
218
|
+
</div>
|
|
219
|
+
<p className="text-sm text-amber-700">
|
|
220
|
+
Run{" "}
|
|
221
|
+
<code className="rounded bg-amber-100 px-1">npx convex dev</code> to
|
|
222
|
+
start Convex and get your URL.
|
|
223
|
+
</p>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<ConvexProvider client={convex}>
|
|
231
|
+
<SettingsConfigProvider baseConfig={adminConfig}>
|
|
232
|
+
{children}
|
|
233
|
+
</SettingsConfigProvider>
|
|
234
|
+
</ConvexProvider>
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
|
|
239
|
+
return (
|
|
240
|
+
<html lang="en">
|
|
241
|
+
<head>
|
|
242
|
+
<HeadContent />
|
|
243
|
+
</head>
|
|
244
|
+
<body>
|
|
245
|
+
{children}
|
|
246
|
+
<Scripts />
|
|
247
|
+
</body>
|
|
248
|
+
</html>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content Types Route (CLI)
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around the shared ContentTypesPage component.
|
|
5
|
+
* Provides TanStack Router integration and API access.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
9
|
+
import { api } from "../../convex/_generated/api";
|
|
10
|
+
import { ContentTypesPage } from "~/pages";
|
|
11
|
+
import { useTanStackNavigation } from "~/lib/tanstack-adapter";
|
|
12
|
+
|
|
13
|
+
export const Route = createFileRoute("/content-types")({
|
|
14
|
+
component: ContentTypesRoute,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
function ContentTypesRoute() {
|
|
18
|
+
const navigation = useTanStackNavigation();
|
|
19
|
+
return <ContentTypesPage api={api.admin} navigation={navigation} />;
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content Route (CLI)
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around the shared ContentPage component.
|
|
5
|
+
* Provides TanStack Router integration and API access.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
9
|
+
import { api } from "../../convex/_generated/api";
|
|
10
|
+
import { ContentPage } from "~/pages";
|
|
11
|
+
import { useTanStackNavigation } from "~/lib/tanstack-adapter";
|
|
12
|
+
|
|
13
|
+
export const Route = createFileRoute("/content")({
|
|
14
|
+
component: ContentRoute,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
function ContentRoute() {
|
|
18
|
+
const navigation = useTanStackNavigation();
|
|
19
|
+
return <ContentPage api={api.admin} navigation={navigation} />;
|
|
20
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { createFileRoute, useNavigate } from '@tanstack/react-router';
|
|
2
|
+
import { useQuery } from 'convex/react';
|
|
3
|
+
import { api } from '../../../convex/_generated/api';
|
|
4
|
+
import { ContentEntryEditor } from '~/components/ContentEntryEditor';
|
|
5
|
+
import type { ContentType, ContentEntry } from '~/components/ContentEntryEditor';
|
|
6
|
+
import { usePermissions, useBreadcrumbLabel } from '~/hooks';
|
|
7
|
+
import { CmsEmptyState } from '~/components/cmsds/CmsEmptyState';
|
|
8
|
+
import { CmsButton as _CmsButton } from '~/components/cmsds/CmsButton';
|
|
9
|
+
import { FileText } from 'lucide-react';
|
|
10
|
+
|
|
11
|
+
export const Route = createFileRoute('/entries/$entryId')({
|
|
12
|
+
component: EditEntryPage,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
function EditEntryPage() {
|
|
16
|
+
const { entryId } = Route.useParams();
|
|
17
|
+
const navigate = useNavigate();
|
|
18
|
+
const { canDelete } = usePermissions();
|
|
19
|
+
|
|
20
|
+
const entry = useQuery(api.entries.get, { id: entryId });
|
|
21
|
+
|
|
22
|
+
const contentType = useQuery(
|
|
23
|
+
api.contentTypes.get,
|
|
24
|
+
entry ? { id: entry.contentTypeId } : 'skip'
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const getEntryTitle = () => {
|
|
28
|
+
if (!entry || !contentType) return undefined;
|
|
29
|
+
const titleField = contentType.titleField ?? 'title';
|
|
30
|
+
const title = entry.data[titleField];
|
|
31
|
+
return typeof title === 'string' && title ? title : 'Untitled';
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
useBreadcrumbLabel(`/entries/${entryId}`, getEntryTitle());
|
|
35
|
+
|
|
36
|
+
if (entry === undefined || (entry && contentType === undefined)) {
|
|
37
|
+
return (
|
|
38
|
+
<div className="space-y-6 p-6">
|
|
39
|
+
<div className="flex flex-col items-center justify-center py-12">
|
|
40
|
+
<div className="size-8 animate-spin rounded-full border-2 border-muted border-t-primary" />
|
|
41
|
+
<p className="mt-4 text-sm text-muted-foreground">Loading entry...</p>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (entry === null) {
|
|
48
|
+
return (
|
|
49
|
+
<div className="space-y-6 p-6">
|
|
50
|
+
<CmsEmptyState
|
|
51
|
+
icon={<FileText className="size-6" />}
|
|
52
|
+
title="Entry Not Found"
|
|
53
|
+
description="The content entry you're looking for doesn't exist or has been deleted."
|
|
54
|
+
action={{
|
|
55
|
+
label: 'Back to Content',
|
|
56
|
+
onClick: () => navigate({ to: '/content-types' }),
|
|
57
|
+
}}
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (contentType === null) {
|
|
64
|
+
return (
|
|
65
|
+
<div className="space-y-6 p-6">
|
|
66
|
+
<CmsEmptyState
|
|
67
|
+
icon={<FileText className="size-6" />}
|
|
68
|
+
title="Content Type Not Found"
|
|
69
|
+
description="The content type for this entry doesn't exist or has been deleted."
|
|
70
|
+
action={{
|
|
71
|
+
label: 'Back to Content',
|
|
72
|
+
onClick: () => navigate({ to: '/content-types' }),
|
|
73
|
+
}}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Handle successful save
|
|
80
|
+
const handleSave = (_savedEntry: ContentEntry) => {
|
|
81
|
+
// Stay on the page but show a success state
|
|
82
|
+
// The component will handle the success feedback
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Handle cancel
|
|
86
|
+
const handleCancel = () => {
|
|
87
|
+
navigate({ to: '/content' });
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// Handle delete - navigate back to content list
|
|
91
|
+
const handleDelete = () => {
|
|
92
|
+
navigate({ to: '/content' });
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<div className="space-y-6 p-6">
|
|
97
|
+
<ContentEntryEditor
|
|
98
|
+
contentType={contentType as ContentType}
|
|
99
|
+
entry={entry as ContentEntry}
|
|
100
|
+
onSave={handleSave}
|
|
101
|
+
onCancel={handleCancel}
|
|
102
|
+
onDelete={handleDelete}
|
|
103
|
+
canDelete={canDelete('contentEntries')}
|
|
104
|
+
/>
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
}
|