convex-cms 0.0.6 → 0.0.7

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 (329) hide show
  1. package/README.md +68 -101
  2. package/admin/src/components/BreakingChangesWarningDialog.tsx +5 -5
  3. package/admin/src/components/BulkOperationModal.tsx +14 -14
  4. package/admin/src/components/ContentEntryEditor.tsx +8 -8
  5. package/admin/src/components/ContentTypeFormModal.tsx +122 -82
  6. package/admin/src/components/Header.tsx +5 -2
  7. package/admin/src/components/SchemaDriftWarning.tsx +126 -0
  8. package/admin/src/components/TaxonomyEditor.tsx +2 -2
  9. package/admin/src/components/TermTree.tsx +3 -3
  10. package/admin/src/components/UploadDropzone.tsx +7 -7
  11. package/admin/src/components/VersionCompare.tsx +13 -13
  12. package/admin/src/components/VersionHistory.tsx +2 -2
  13. package/admin/src/components/VersionRollbackModal.tsx +5 -5
  14. package/admin/src/components/cmsds/CmsButton.tsx +2 -2
  15. package/admin/src/components/cmsds/CmsDialog.tsx +4 -1
  16. package/admin/src/components/cmsds/CmsStatusBadge.tsx +5 -5
  17. package/admin/src/components/fields/JsonField.tsx +1 -1
  18. package/admin/src/components/fields/ReferenceField.tsx +9 -9
  19. package/admin/src/components/fields/TagField.tsx +1 -1
  20. package/admin/src/contexts/SettingsConfigContext.tsx +10 -3
  21. package/admin/src/embed/index.tsx +29 -9
  22. package/admin/src/embed/pages/ContentTypeEntries.tsx +25 -0
  23. package/admin/src/embed/pages/Entry.tsx +114 -0
  24. package/admin/src/embed/pages/Media.tsx +3 -1
  25. package/admin/src/embed/pages/NewEntry.tsx +83 -0
  26. package/admin/src/embed/pages/index.ts +3 -0
  27. package/admin/src/pages/ContentPage.tsx +27 -20
  28. package/admin/src/pages/ContentTypeEntriesPage.tsx +466 -0
  29. package/admin/src/pages/ContentTypesPage.tsx +65 -19
  30. package/admin/src/pages/DashboardPage.tsx +3 -0
  31. package/admin/src/pages/SettingsPage.tsx +4 -4
  32. package/admin/src/pages/index.ts +1 -0
  33. package/admin/src/routes/__root.tsx +10 -10
  34. package/admin/src/routes/entries/$entryId.tsx +1 -1
  35. package/admin/src/routes/entries/type/$contentTypeId.tsx +1 -1
  36. package/admin/src/styles/globals.css +31 -5
  37. package/admin/src/styles/tailwind-config.css +25 -0
  38. package/admin/src/styles/theme.css +50 -0
  39. package/admin-dist/nitro.json +1 -1
  40. package/admin-dist/public/assets/CmsEmptyState-6-PLaXtD.js +1 -0
  41. package/admin-dist/public/assets/CmsPageHeader-SoF4Epu9.js +1 -0
  42. package/admin-dist/public/assets/CmsStatusBadge-D7kYaohx.js +1 -0
  43. package/admin-dist/public/assets/{CmsSurface-DBy5Lumx.js → CmsSurface-BvksBm6W.js} +1 -1
  44. package/admin-dist/public/assets/CmsToolbar-DlZPMe2B.js +1 -0
  45. package/admin-dist/public/assets/ContentEntryEditor-C6n9xLS9.js +4 -0
  46. package/admin-dist/public/assets/TaxonomyFilter-CFX1_g8s.js +1 -0
  47. package/admin-dist/public/assets/_contentTypeId-DTv8UoTp.js +1 -0
  48. package/admin-dist/public/assets/_entryId-D3lr5Dvy.js +1 -0
  49. package/admin-dist/public/assets/alert-BAHTL6ao.js +1 -0
  50. package/admin-dist/public/assets/badge-oJv4Eai8.js +1 -0
  51. package/admin-dist/public/assets/{circle-check-big-CpLxAvEj.js → circle-check-big-3OHxNDhO.js} +1 -1
  52. package/admin-dist/public/assets/command-DwgQs69u.js +1 -0
  53. package/admin-dist/public/assets/content-CKQ4QwW2.js +1 -0
  54. package/admin-dist/public/assets/content-types-BrttaLpc.js +1 -0
  55. package/admin-dist/public/assets/globals-CoCRjt0K.css +1 -0
  56. package/admin-dist/public/assets/index-DOkgTSx0.js +1 -0
  57. package/admin-dist/public/assets/main-DV6oxWnU.js +102 -0
  58. package/admin-dist/public/assets/media-B2i-mCbx.js +1 -0
  59. package/admin-dist/public/assets/new._contentTypeId-VF63rpic.js +1 -0
  60. package/admin-dist/public/assets/pencil-CX1CiTDD.js +1 -0
  61. package/admin-dist/public/assets/refresh-cw-Cm-YOeFI.js +1 -0
  62. package/admin-dist/public/assets/{rotate-ccw-BZpZtw0N.js → rotate-ccw-B45JsL5f.js} +1 -1
  63. package/admin-dist/public/assets/scroll-area-b3A1HHR7.js +1 -0
  64. package/admin-dist/public/assets/{search-BvgYr-c9.js → search-DKKh_DdH.js} +1 -1
  65. package/admin-dist/public/assets/settings-CGVDEV1r.js +1 -0
  66. package/admin-dist/public/assets/switch-BTMY8Qnk.js +1 -0
  67. package/admin-dist/public/assets/tabs-DUQwUoIb.js +1 -0
  68. package/admin-dist/public/assets/tanstack-adapter-f7AHmQ5L.js +1 -0
  69. package/admin-dist/public/assets/taxonomies-DvMppdiD.js +1 -0
  70. package/admin-dist/public/assets/trash-D7e0uKd9.js +1 -0
  71. package/admin-dist/public/assets/{useBreadcrumbLabel-D00rvqjw.js → useBreadcrumbLabel-CF2KYwsw.js} +1 -1
  72. package/admin-dist/public/assets/usePermissions-DWBImEOW.js +1 -0
  73. package/admin-dist/server/_chunks/_libs/@date-fns/tz.mjs +2 -2
  74. package/admin-dist/server/_chunks/_libs/@radix-ui/react-avatar.mjs +1 -1
  75. package/admin-dist/server/_chunks/_libs/@radix-ui/react-collection.mjs +1 -1
  76. package/admin-dist/server/_chunks/_libs/@radix-ui/react-context.mjs +2 -2
  77. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dialog.mjs +2 -2
  78. package/admin-dist/server/_chunks/_libs/@radix-ui/react-label.mjs +1 -1
  79. package/admin-dist/server/_chunks/_libs/@radix-ui/react-menu.mjs +1 -1
  80. package/admin-dist/server/_chunks/_libs/@radix-ui/react-popover.mjs +1 -1
  81. package/admin-dist/server/_chunks/_libs/@radix-ui/react-primitive.mjs +6 -72
  82. package/admin-dist/server/_chunks/_libs/@radix-ui/react-select.mjs +1 -1
  83. package/admin-dist/server/_chunks/_libs/@radix-ui/react-separator.mjs +1 -1
  84. package/admin-dist/server/_chunks/_libs/@radix-ui/react-slot.mjs +20 -435
  85. package/admin-dist/server/_chunks/_libs/@radix-ui/react-visually-hidden.mjs +30 -3
  86. package/admin-dist/server/_chunks/_libs/@tanstack/history.mjs +0 -376
  87. package/admin-dist/server/_chunks/_libs/@tanstack/react-router.mjs +168 -383
  88. package/admin-dist/server/_chunks/_libs/@tanstack/router-core.mjs +451 -1195
  89. package/admin-dist/server/_chunks/_libs/react-dom.mjs +5 -5
  90. package/admin-dist/server/_chunks/_libs/react.mjs +2 -2
  91. package/admin-dist/server/_libs/cmdk.mjs +1 -1
  92. package/admin-dist/server/_libs/convex.mjs +3 -3
  93. package/admin-dist/server/_libs/cookie-es.mjs +1 -58
  94. package/admin-dist/server/_libs/date-fns.mjs +1 -1
  95. package/admin-dist/server/_libs/lucide-react.mjs +117 -103
  96. package/admin-dist/server/_libs/seroval-plugins.mjs +1 -58
  97. package/admin-dist/server/_libs/seroval.mjs +1 -1765
  98. package/admin-dist/server/_libs/zod.mjs +1 -1
  99. package/admin-dist/server/_ssr/CmsEmptyState-BM8DghTl.mjs +38 -0
  100. package/admin-dist/server/_ssr/{CmsPageHeader-ClNPU7Up.mjs → CmsPageHeader-BHUmrIWD.mjs} +1 -1
  101. package/admin-dist/server/_ssr/{CmsStatusBadge-CojMbrY7.mjs → CmsStatusBadge-D0Zb0oRl.mjs} +7 -7
  102. package/admin-dist/server/_ssr/{CmsSurface-Dcv440rp.mjs → CmsSurface-B2eBr-47.mjs} +1 -1
  103. package/admin-dist/server/_ssr/{CmsToolbar-BKv1nL6u.mjs → CmsToolbar-BCrwg7OL.mjs} +2 -3
  104. package/admin-dist/server/_ssr/{ContentEntryEditor-weiXSBdZ.mjs → ContentEntryEditor-Cjfm0uhr.mjs} +46 -49
  105. package/admin-dist/server/_ssr/{TaxonomyFilter-BPQ57Mwk.mjs → TaxonomyFilter-C4pD0kfM.mjs} +4 -5
  106. package/admin-dist/server/_ssr/{_contentTypeId-DyyauLOs.mjs → _contentTypeId-CiDiX-p7.mjs} +34 -43
  107. package/admin-dist/server/_ssr/{_entryId-9Cafwxmw.mjs → _entryId-9GxatOkL.mjs} +35 -47
  108. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-CC7UrHKE.mjs +4 -0
  109. package/admin-dist/server/_ssr/badge-EI998zba.mjs +39 -0
  110. package/admin-dist/server/_ssr/{command-CEf8YBxY.mjs → command-BLAWQhUw.mjs} +2 -2
  111. package/admin-dist/server/_ssr/{config.server-D7JHDcDv.mjs → config.server-BOr7Jxr4.mjs} +5 -14
  112. package/admin-dist/server/_ssr/{content-ZFWVzO25.mjs → content-BHX39L4D.mjs} +63 -63
  113. package/admin-dist/server/_ssr/content-types-DCzrBhTH.mjs +459 -0
  114. package/admin-dist/server/_ssr/{index-BlSIlH4Z.mjs → index-DwM_5VNP.mjs} +114 -30
  115. package/admin-dist/server/_ssr/index.mjs +3459 -62
  116. package/admin-dist/server/_ssr/{media-CD2_NUMw.mjs → media-CbzgTRRQ.mjs} +31 -43
  117. package/admin-dist/server/_ssr/{new._contentTypeId-dmZy6PBX.mjs → new._contentTypeId-6Ph-Gtlw.mjs} +33 -45
  118. package/admin-dist/server/_ssr/router-vd1nySeP.mjs +3041 -0
  119. package/admin-dist/server/_ssr/{scroll-area-BH_1K-WT.mjs → scroll-area--B9snFTJ.mjs} +1 -1
  120. package/admin-dist/server/_ssr/{settings-DVdsoWoh.mjs → settings-DlTO2JSj.mjs} +34 -43
  121. package/admin-dist/server/_ssr/{switch-DX_X8vZl.mjs → switch-C05NgNW0.mjs} +1 -1
  122. package/admin-dist/server/_ssr/{tabs-4FWM0sn8.mjs → tabs-DAk2J5xy.mjs} +9 -10
  123. package/admin-dist/server/_ssr/{tanstack-adapter-D3ZcKtbY.mjs → tanstack-adapter-DWbaPByn.mjs} +15 -1
  124. package/admin-dist/server/_ssr/{taxonomies-BHFfO9Yr.mjs → taxonomies-B8nqce6u.mjs} +35 -44
  125. package/admin-dist/server/_ssr/{trash-9tUB2KwI.mjs → trash-zdlZgpTo.mjs} +30 -39
  126. package/admin-dist/server/_ssr/{useBreadcrumbLabel-DVme3DSb.mjs → useBreadcrumbLabel-DpEKyG1h.mjs} +1 -1
  127. package/admin-dist/server/_ssr/{usePermissions-zAQj-ruE.mjs → usePermissions-olYRd9S9.mjs} +1 -1
  128. package/admin-dist/server/index.mjs +168 -203
  129. package/dist/cli/templates/cmsClient.d.ts +1 -1
  130. package/dist/cli/templates/cmsClient.d.ts.map +1 -1
  131. package/dist/cli/templates/cmsClient.js +30 -11
  132. package/dist/cli/templates/cmsClient.js.map +1 -1
  133. package/dist/cli/templates/cmsConfig.d.ts +1 -1
  134. package/dist/cli/templates/cmsConfig.d.ts.map +1 -1
  135. package/dist/cli/templates/cmsConfig.js +3 -3
  136. package/dist/client/admin/contentLock.d.ts +4 -4
  137. package/dist/client/admin/contentLock.d.ts.map +1 -1
  138. package/dist/client/admin/contentLock.js +1 -1
  139. package/dist/client/admin/contentLock.js.map +1 -1
  140. package/dist/client/admin/contentTypes.d.ts +328 -290
  141. package/dist/client/admin/contentTypes.d.ts.map +1 -1
  142. package/dist/client/admin/contentTypes.js +307 -9
  143. package/dist/client/admin/contentTypes.js.map +1 -1
  144. package/dist/client/admin/entries.d.ts +18 -19
  145. package/dist/client/admin/entries.d.ts.map +1 -1
  146. package/dist/client/admin/entries.js +33 -8
  147. package/dist/client/admin/entries.js.map +1 -1
  148. package/dist/client/admin/index.d.ts +694 -642
  149. package/dist/client/admin/index.d.ts.map +1 -1
  150. package/dist/client/admin/index.js +45 -5
  151. package/dist/client/admin/index.js.map +1 -1
  152. package/dist/client/admin/media.d.ts.map +1 -1
  153. package/dist/client/admin/taxonomies.d.ts.map +1 -1
  154. package/dist/client/admin/trash.d.ts +3 -4
  155. package/dist/client/admin/trash.d.ts.map +1 -1
  156. package/dist/client/admin/types.d.ts +185 -4
  157. package/dist/client/admin/types.d.ts.map +1 -1
  158. package/dist/client/admin/validators.d.ts +2009 -25
  159. package/dist/client/admin/validators.d.ts.map +1 -1
  160. package/dist/client/admin/validators.js +15 -4
  161. package/dist/client/admin/validators.js.map +1 -1
  162. package/dist/client/admin/versions.d.ts +1 -1
  163. package/dist/client/admin/versions.d.ts.map +1 -1
  164. package/dist/client/agentTools.d.ts +1 -4
  165. package/dist/client/agentTools.d.ts.map +1 -1
  166. package/dist/client/agentTools.js +9 -21
  167. package/dist/client/agentTools.js.map +1 -1
  168. package/dist/client/config.d.ts +10 -0
  169. package/dist/client/config.d.ts.map +1 -1
  170. package/dist/client/config.js +1 -0
  171. package/dist/client/config.js.map +1 -1
  172. package/dist/client/defineContent.d.ts +338 -0
  173. package/dist/client/defineContent.d.ts.map +1 -0
  174. package/dist/client/defineContent.js +368 -0
  175. package/dist/client/defineContent.js.map +1 -0
  176. package/dist/client/index.d.ts +2 -0
  177. package/dist/client/index.d.ts.map +1 -1
  178. package/dist/client/index.js +2 -0
  179. package/dist/client/index.js.map +1 -1
  180. package/dist/client/queryBuilder.d.ts +0 -15
  181. package/dist/client/queryBuilder.d.ts.map +1 -1
  182. package/dist/client/queryBuilder.js +0 -23
  183. package/dist/client/queryBuilder.js.map +1 -1
  184. package/dist/client/registry.d.ts +77 -0
  185. package/dist/client/registry.d.ts.map +1 -0
  186. package/dist/client/registry.js +95 -0
  187. package/dist/client/registry.js.map +1 -0
  188. package/dist/client/schema/defineContentType.d.ts +36 -24
  189. package/dist/client/schema/defineContentType.d.ts.map +1 -1
  190. package/dist/client/schema/defineContentType.js +176 -128
  191. package/dist/client/schema/defineContentType.js.map +1 -1
  192. package/dist/client/schema/typedClient.d.ts.map +1 -1
  193. package/dist/client/schema/typedClient.js +2 -10
  194. package/dist/client/schema/typedClient.js.map +1 -1
  195. package/dist/client/schema/types.d.ts +16 -9
  196. package/dist/client/schema/types.d.ts.map +1 -1
  197. package/dist/client/schema/types.js.map +1 -1
  198. package/dist/client/utils/toSlug.d.ts +60 -0
  199. package/dist/client/utils/toSlug.d.ts.map +1 -0
  200. package/dist/client/utils/toSlug.js +31 -0
  201. package/dist/client/utils/toSlug.js.map +1 -0
  202. package/dist/client/wrapper.d.ts +2 -2
  203. package/dist/client/wrapper.d.ts.map +1 -1
  204. package/dist/client/wrapper.js +22 -30
  205. package/dist/client/wrapper.js.map +1 -1
  206. package/dist/component/_generated/component.d.ts +24 -28
  207. package/dist/component/_generated/component.d.ts.map +1 -1
  208. package/dist/component/authorizationHooks.d.ts +1 -1
  209. package/dist/component/authorizationHooks.d.ts.map +1 -1
  210. package/dist/component/authorizationHooks.js +2 -2
  211. package/dist/component/authorizationHooks.js.map +1 -1
  212. package/dist/component/bulkOperations.d.ts.map +1 -1
  213. package/dist/component/bulkOperations.js +7 -4
  214. package/dist/component/bulkOperations.js.map +1 -1
  215. package/dist/component/contentEntries.d.ts +18 -56
  216. package/dist/component/contentEntries.d.ts.map +1 -1
  217. package/dist/component/contentEntries.js +45 -137
  218. package/dist/component/contentEntries.js.map +1 -1
  219. package/dist/component/contentEntryMutations.d.ts +14 -14
  220. package/dist/component/contentEntryMutations.d.ts.map +1 -1
  221. package/dist/component/contentEntryMutations.js +40 -43
  222. package/dist/component/contentEntryMutations.js.map +1 -1
  223. package/dist/component/contentEntryValidation.d.ts +3 -3
  224. package/dist/component/contentEntryValidation.js +6 -9
  225. package/dist/component/contentEntryValidation.js.map +1 -1
  226. package/dist/component/contentLock.d.ts +7 -7
  227. package/dist/component/contentLock.js +3 -3
  228. package/dist/component/contentLock.js.map +1 -1
  229. package/dist/component/contentTypeMigration.d.ts +1 -1
  230. package/dist/component/contentTypeMigration.js +2 -2
  231. package/dist/component/contentTypeMigration.js.map +1 -1
  232. package/dist/component/contentTypeMutations.d.ts.map +1 -1
  233. package/dist/component/contentTypeMutations.js +7 -6
  234. package/dist/component/contentTypeMutations.js.map +1 -1
  235. package/dist/component/convex.config.d.ts.map +1 -1
  236. package/dist/component/convex.config.js +1 -1
  237. package/dist/component/convex.config.js.map +1 -1
  238. package/dist/component/eventEmitter.d.ts +0 -1
  239. package/dist/component/eventEmitter.d.ts.map +1 -1
  240. package/dist/component/eventEmitter.js.map +1 -1
  241. package/dist/component/exportImport.d.ts +37 -37
  242. package/dist/component/exportImport.d.ts.map +1 -1
  243. package/dist/component/exportImport.js +34 -34
  244. package/dist/component/exportImport.js.map +1 -1
  245. package/dist/component/lib/deepReferenceResolver.d.ts +2 -2
  246. package/dist/component/lib/deepReferenceResolver.d.ts.map +1 -1
  247. package/dist/component/lib/deepReferenceResolver.js +13 -8
  248. package/dist/component/lib/deepReferenceResolver.js.map +1 -1
  249. package/dist/component/lib/ragContentChunker.d.ts +3 -3
  250. package/dist/component/lib/ragContentChunker.d.ts.map +1 -1
  251. package/dist/component/lib/ragContentChunker.js +4 -4
  252. package/dist/component/lib/ragContentChunker.js.map +1 -1
  253. package/dist/component/lib/referenceResolver.d.ts.map +1 -1
  254. package/dist/component/lib/referenceResolver.js +10 -17
  255. package/dist/component/lib/referenceResolver.js.map +1 -1
  256. package/dist/component/mediaAssetMutations.js +4 -4
  257. package/dist/component/mediaAssetMutations.js.map +1 -1
  258. package/dist/component/ragContentIndexer.d.ts +2 -2
  259. package/dist/component/ragContentIndexer.d.ts.map +1 -1
  260. package/dist/component/ragContentIndexer.js +44 -48
  261. package/dist/component/ragContentIndexer.js.map +1 -1
  262. package/dist/component/roles.d.ts +3 -3
  263. package/dist/component/scheduledPublish.d.ts +4 -4
  264. package/dist/component/scheduledPublish.js +3 -3
  265. package/dist/component/scheduledPublish.js.map +1 -1
  266. package/dist/component/schema.d.ts +18 -18
  267. package/dist/component/schema.js +5 -5
  268. package/dist/component/schema.js.map +1 -1
  269. package/dist/component/trash.d.ts +6 -9
  270. package/dist/component/trash.d.ts.map +1 -1
  271. package/dist/component/trash.js +12 -36
  272. package/dist/component/trash.js.map +1 -1
  273. package/dist/component/userContext.d.ts +1 -2
  274. package/dist/component/userContext.d.ts.map +1 -1
  275. package/dist/component/userContext.js +1 -2
  276. package/dist/component/userContext.js.map +1 -1
  277. package/dist/component/validators.d.ts +27 -33
  278. package/dist/component/validators.d.ts.map +1 -1
  279. package/dist/component/validators.js +3 -5
  280. package/dist/component/validators.js.map +1 -1
  281. package/dist/component/versionMutations.d.ts +1 -1
  282. package/dist/component/webhookTrigger.d.ts +14 -14
  283. package/dist/test.d.ts +30 -30
  284. package/dist/test.d.ts.map +1 -1
  285. package/dist/test.js +24 -24
  286. package/dist/test.js.map +1 -1
  287. package/package.json +1 -1
  288. package/admin-dist/public/assets/CmsEmptyState-Do_erIgn.js +0 -5
  289. package/admin-dist/public/assets/CmsPageHeader-qDwPGi48.js +0 -1
  290. package/admin-dist/public/assets/CmsStatusBadge-Dd9uToHE.js +0 -1
  291. package/admin-dist/public/assets/CmsToolbar-D1-Y-7SK.js +0 -1
  292. package/admin-dist/public/assets/ContentEntryEditor-CWBiIx52.js +0 -4
  293. package/admin-dist/public/assets/TaxonomyFilter-CdYQawxb.js +0 -1
  294. package/admin-dist/public/assets/_contentTypeId-D9VMP6Gs.js +0 -1
  295. package/admin-dist/public/assets/_entryId-2FlCfqE7.js +0 -1
  296. package/admin-dist/public/assets/alert-GxZx0y5c.js +0 -1
  297. package/admin-dist/public/assets/badge-BAlGIjop.js +0 -1
  298. package/admin-dist/public/assets/command-di7XCqcv.js +0 -1
  299. package/admin-dist/public/assets/content-D8zELsDG.js +0 -1
  300. package/admin-dist/public/assets/content-types-BmzD0krT.js +0 -2
  301. package/admin-dist/public/assets/globals-BvFfH-v9.css +0 -1
  302. package/admin-dist/public/assets/index-zqfj4T_v.js +0 -1
  303. package/admin-dist/public/assets/label-B6PPtKR5.js +0 -1
  304. package/admin-dist/public/assets/link-2-W2fVnVOf.js +0 -1
  305. package/admin-dist/public/assets/list-F8O0lZXC.js +0 -1
  306. package/admin-dist/public/assets/main-dZT72bAG.js +0 -97
  307. package/admin-dist/public/assets/media-CETueFbV.js +0 -1
  308. package/admin-dist/public/assets/new._contentTypeId-BV2-TyyR.js +0 -1
  309. package/admin-dist/public/assets/plus-AABQIF0N.js +0 -1
  310. package/admin-dist/public/assets/scroll-area-CDfk-zrz.js +0 -1
  311. package/admin-dist/public/assets/select-BuiHcMzS.js +0 -1
  312. package/admin-dist/public/assets/settings-DBxbYDvn.js +0 -1
  313. package/admin-dist/public/assets/switch-DiJvolcs.js +0 -1
  314. package/admin-dist/public/assets/tabs-Cgz6G_Xy.js +0 -1
  315. package/admin-dist/public/assets/tanstack-adapter-BknsSgra.js +0 -1
  316. package/admin-dist/public/assets/taxonomies-DOErsLl5.js +0 -1
  317. package/admin-dist/public/assets/textarea-CgggMxUX.js +0 -1
  318. package/admin-dist/public/assets/trash-BU4ANuaW.js +0 -1
  319. package/admin-dist/public/assets/triangle-alert-lvCbwp0s.js +0 -1
  320. package/admin-dist/public/assets/usePermissions-D7tQowaF.js +0 -1
  321. package/admin-dist/server/_libs/h3-v2.mjs +0 -277
  322. package/admin-dist/server/_ssr/CmsButton-DbzfJru_.mjs +0 -125
  323. package/admin-dist/server/_ssr/CmsEmptyState-CuvcXr3Z.mjs +0 -290
  324. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-Dk-FIYPN.mjs +0 -4
  325. package/admin-dist/server/_ssr/content-types-D25lUE-j.mjs +0 -1312
  326. package/admin-dist/server/_ssr/label-PblVvdRv.mjs +0 -22
  327. package/admin-dist/server/_ssr/router-x6Ab8T4s.mjs +0 -1622
  328. package/admin-dist/server/_ssr/select-CrfEkFJw.mjs +0 -142
  329. package/admin-dist/server/_ssr/textarea-CZVaroMc.mjs +0 -18
@@ -0,0 +1,466 @@
1
+ /**
2
+ * Shared Content Type Entries Page Component
3
+ *
4
+ * Lists entries for a specific content type with search, filtering, and actions.
5
+ * Used by both CLI routes and embed pages.
6
+ */
7
+
8
+ import { useState, useMemo, useEffect, useCallback } from "react";
9
+ import { useQuery, useMutation } from "convex/react";
10
+ import { usePermissions } from "~/hooks";
11
+ import { CmsPageHeader } from "~/components/cmsds/CmsPageHeader";
12
+ import { CmsToolbar } from "~/components/cmsds/CmsToolbar";
13
+ import { CmsButton } from "~/components/cmsds/CmsButton";
14
+ import { CmsStatusBadge, type ContentStatus } from "~/components/cmsds/CmsStatusBadge";
15
+ import { CmsEmptyState } from "~/components/cmsds/CmsEmptyState";
16
+ import { CmsConfirmDialog } from "~/components/cmsds/CmsDialog";
17
+ import { Input } from "~/components/ui/input";
18
+ import {
19
+ Select,
20
+ SelectContent,
21
+ SelectItem,
22
+ SelectTrigger,
23
+ SelectValue,
24
+ } from "~/components/ui/select";
25
+ import {
26
+ Search,
27
+ Plus,
28
+ FileText,
29
+ ChevronUp,
30
+ ChevronDown,
31
+ ArrowUpDown,
32
+ } from "lucide-react";
33
+ import type { AdminNavigation } from "~/lib/navigation";
34
+ import type { CmsAdminApi } from "~/embed/contexts/ApiContext";
35
+
36
+ type SortField = "title" | "status" | "updatedAt" | "createdAt";
37
+ type SortDirection = "asc" | "desc";
38
+
39
+ export interface ContentTypeEntriesPageProps {
40
+ api: CmsAdminApi;
41
+ navigation: AdminNavigation;
42
+ contentTypeId: string;
43
+ }
44
+
45
+ export function ContentTypeEntriesPage({
46
+ api,
47
+ navigation,
48
+ contentTypeId,
49
+ }: ContentTypeEntriesPageProps) {
50
+ const [selectedStatus, setSelectedStatus] = useState<ContentStatus | "all">("all");
51
+ const [searchQuery, setSearchQuery] = useState("");
52
+ const [debouncedSearch, setDebouncedSearch] = useState("");
53
+ const [sortField, setSortField] = useState<SortField>("updatedAt");
54
+ const [sortDirection, setSortDirection] = useState<SortDirection>("desc");
55
+ const [currentPage, setCurrentPage] = useState(0);
56
+ const pageSize = 25;
57
+
58
+ const { canCreate, canUpdate, canDelete } = usePermissions();
59
+
60
+ const deleteEntry = useMutation(api.deleteEntry);
61
+
62
+ const [deleteModalOpen, setDeleteModalOpen] = useState(false);
63
+ const [entryToDelete, setEntryToDelete] = useState<{ _id: string; title: string } | null>(null);
64
+ const [isDeleting, setIsDeleting] = useState(false);
65
+ const [deleteError, setDeleteError] = useState<string | null>(null);
66
+
67
+ useEffect(() => {
68
+ const timer = setTimeout(() => {
69
+ setDebouncedSearch(searchQuery);
70
+ setCurrentPage(0);
71
+ }, 300);
72
+ return () => clearTimeout(timer);
73
+ }, [searchQuery]);
74
+
75
+ const contentType = useQuery(api.getContentType, { id: contentTypeId });
76
+
77
+ const entriesResult = useQuery(api.listEntries, {
78
+ contentTypeName: contentType?.name,
79
+ status: selectedStatus === "all" ? undefined : selectedStatus,
80
+ search: debouncedSearch || undefined,
81
+ paginationOpts: { numItems: 250, cursor: null },
82
+ });
83
+ const allEntries = entriesResult?.page ?? [];
84
+
85
+ const getEntryTitle = useCallback(
86
+ (entry: { data: Record<string, unknown> }) => {
87
+ const titleField = contentType?.titleField ?? "title";
88
+ const title = entry.data[titleField];
89
+ return typeof title === "string" && title ? title : "Untitled";
90
+ },
91
+ [contentType?.titleField]
92
+ );
93
+
94
+ const sortedEntries = useMemo(() => {
95
+ const entries = [...allEntries];
96
+
97
+ entries.sort((a, b) => {
98
+ let comparison = 0;
99
+
100
+ switch (sortField) {
101
+ case "title": {
102
+ const titleA = getEntryTitle(a).toLowerCase();
103
+ const titleB = getEntryTitle(b).toLowerCase();
104
+ comparison = titleA.localeCompare(titleB);
105
+ break;
106
+ }
107
+ case "status":
108
+ comparison = a.status.localeCompare(b.status);
109
+ break;
110
+ case "updatedAt": {
111
+ const updatedA = a.lastPublishedAt ?? a._creationTime ?? 0;
112
+ const updatedB = b.lastPublishedAt ?? b._creationTime ?? 0;
113
+ comparison = updatedA - updatedB;
114
+ break;
115
+ }
116
+ case "createdAt":
117
+ comparison = (a._creationTime ?? 0) - (b._creationTime ?? 0);
118
+ break;
119
+ default:
120
+ comparison = 0;
121
+ }
122
+
123
+ return sortDirection === "desc" ? -comparison : comparison;
124
+ });
125
+
126
+ return entries;
127
+ }, [allEntries, sortField, sortDirection, getEntryTitle]);
128
+
129
+ const paginatedEntries = useMemo(() => {
130
+ const start = currentPage * pageSize;
131
+ return sortedEntries.slice(start, start + pageSize);
132
+ }, [sortedEntries, currentPage, pageSize]);
133
+
134
+ const totalPages = Math.ceil(sortedEntries.length / pageSize);
135
+
136
+ const formatDate = (timestamp: number) => {
137
+ return new Date(timestamp).toLocaleDateString("en-US", {
138
+ year: "numeric",
139
+ month: "short",
140
+ day: "numeric",
141
+ hour: "2-digit",
142
+ minute: "2-digit",
143
+ });
144
+ };
145
+
146
+ const handleSort = (field: SortField) => {
147
+ if (sortField === field) {
148
+ setSortDirection(sortDirection === "asc" ? "desc" : "asc");
149
+ } else {
150
+ setSortField(field);
151
+ setSortDirection("desc");
152
+ }
153
+ };
154
+
155
+ const getSortIcon = (field: SortField) => {
156
+ if (sortField !== field) {
157
+ return <ArrowUpDown className="size-3.5 text-muted-foreground/50" />;
158
+ }
159
+ return sortDirection === "asc" ? (
160
+ <ChevronUp className="size-3.5" />
161
+ ) : (
162
+ <ChevronDown className="size-3.5" />
163
+ );
164
+ };
165
+
166
+ const handleDeleteClick = useCallback(
167
+ (entry: { _id: string; data: Record<string, unknown> }) => {
168
+ const title = getEntryTitle(entry);
169
+ setEntryToDelete({ _id: entry._id, title });
170
+ setDeleteError(null);
171
+ setDeleteModalOpen(true);
172
+ },
173
+ [getEntryTitle]
174
+ );
175
+
176
+ const handleDeleteConfirm = useCallback(async () => {
177
+ if (!entryToDelete) return;
178
+
179
+ setIsDeleting(true);
180
+ setDeleteError(null);
181
+
182
+ try {
183
+ await deleteEntry({
184
+ id: entryToDelete._id,
185
+ hardDelete: false,
186
+ });
187
+ setDeleteModalOpen(false);
188
+ setEntryToDelete(null);
189
+ } catch (error) {
190
+ const message = error instanceof Error ? error.message : "Failed to delete entry";
191
+ setDeleteError(message);
192
+ } finally {
193
+ setIsDeleting(false);
194
+ }
195
+ }, [entryToDelete, deleteEntry]);
196
+
197
+ const handleDeleteModalClose = useCallback(
198
+ (open: boolean) => {
199
+ if (!open && !isDeleting) {
200
+ setDeleteModalOpen(false);
201
+ setEntryToDelete(null);
202
+ setDeleteError(null);
203
+ }
204
+ },
205
+ [isDeleting]
206
+ );
207
+
208
+ const clearFilters = useCallback(() => {
209
+ setSearchQuery("");
210
+ setDebouncedSearch("");
211
+ setSelectedStatus("all");
212
+ setCurrentPage(0);
213
+ }, []);
214
+
215
+ if (contentType === undefined || entriesResult === undefined) {
216
+ return (
217
+ <div className="space-y-6 p-6">
218
+ <div className="flex flex-col items-center justify-center py-12">
219
+ <div className="size-8 animate-spin rounded-full border-2 border-muted border-t-primary" />
220
+ <p className="mt-4 text-sm text-muted-foreground">Loading entries...</p>
221
+ </div>
222
+ </div>
223
+ );
224
+ }
225
+
226
+ if (contentType === null) {
227
+ return (
228
+ <div className="space-y-6 p-6">
229
+ <CmsEmptyState
230
+ icon={<FileText className="size-6" />}
231
+ title="Content Type Not Found"
232
+ description="The content type you're looking for doesn't exist or has been deleted."
233
+ action={{
234
+ label: "Back to Content Types",
235
+ onClick: () => navigation.navigate("/content-types"),
236
+ }}
237
+ />
238
+ </div>
239
+ );
240
+ }
241
+
242
+ const hasFilters = searchQuery || selectedStatus !== "all";
243
+
244
+ return (
245
+ <div className="space-y-6 p-6">
246
+ <CmsPageHeader
247
+ title={contentType.displayName}
248
+ description={contentType.description}
249
+ actions={
250
+ canCreate("contentEntries") && (
251
+ <CmsButton onClick={() => navigation.navigateToNewEntry(contentTypeId)}>
252
+ <Plus className="size-4" />
253
+ Create {contentType.displayName}
254
+ </CmsButton>
255
+ )
256
+ }
257
+ />
258
+
259
+ <CmsToolbar
260
+ left={
261
+ <div className="flex items-center gap-3">
262
+ <div className="relative">
263
+ <Search className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
264
+ <Input
265
+ type="search"
266
+ placeholder="Search entries..."
267
+ value={searchQuery}
268
+ onChange={(e) => setSearchQuery(e.target.value)}
269
+ className="w-64 pl-9"
270
+ />
271
+ </div>
272
+ <Select
273
+ value={selectedStatus}
274
+ onValueChange={(value) => {
275
+ setSelectedStatus(value as ContentStatus | "all");
276
+ setCurrentPage(0);
277
+ }}
278
+ >
279
+ <SelectTrigger className="w-36">
280
+ <SelectValue placeholder="All Statuses" />
281
+ </SelectTrigger>
282
+ <SelectContent>
283
+ <SelectItem value="all">All Statuses</SelectItem>
284
+ <SelectItem value="draft">Draft</SelectItem>
285
+ <SelectItem value="published">Published</SelectItem>
286
+ <SelectItem value="scheduled">Scheduled</SelectItem>
287
+ <SelectItem value="archived">Archived</SelectItem>
288
+ </SelectContent>
289
+ </Select>
290
+ </div>
291
+ }
292
+ right={
293
+ <span className="text-sm text-muted-foreground">
294
+ {sortedEntries.length} {sortedEntries.length === 1 ? "entry" : "entries"}
295
+ </span>
296
+ }
297
+ />
298
+
299
+ {sortedEntries.length === 0 ? (
300
+ <CmsEmptyState
301
+ icon={<FileText className="size-6" />}
302
+ title={hasFilters ? "No matching entries" : `No ${contentType.displayName} entries yet`}
303
+ description={
304
+ hasFilters
305
+ ? "Try adjusting your search or filter criteria."
306
+ : `Click "Create ${contentType.displayName}" to add your first entry.`
307
+ }
308
+ action={
309
+ hasFilters
310
+ ? { label: "Clear Filters", onClick: clearFilters, variant: "secondary" }
311
+ : undefined
312
+ }
313
+ />
314
+ ) : (
315
+ <>
316
+ <div className="rounded-lg border bg-card">
317
+ <table className="w-full">
318
+ <thead>
319
+ <tr className="border-b">
320
+ <th className="p-3 text-left">
321
+ <button
322
+ className="flex items-center gap-1.5 text-sm font-medium text-muted-foreground hover:text-foreground"
323
+ onClick={() => handleSort("title")}
324
+ >
325
+ Title
326
+ {getSortIcon("title")}
327
+ </button>
328
+ </th>
329
+ <th className="p-3 text-left">
330
+ <button
331
+ className="flex items-center gap-1.5 text-sm font-medium text-muted-foreground hover:text-foreground"
332
+ onClick={() => handleSort("status")}
333
+ >
334
+ Status
335
+ {getSortIcon("status")}
336
+ </button>
337
+ </th>
338
+ <th className="p-3 text-left">
339
+ <button
340
+ className="flex items-center gap-1.5 text-sm font-medium text-muted-foreground hover:text-foreground"
341
+ onClick={() => handleSort("updatedAt")}
342
+ >
343
+ Updated
344
+ {getSortIcon("updatedAt")}
345
+ </button>
346
+ </th>
347
+ <th className="p-3 text-left text-sm font-medium text-muted-foreground">
348
+ Actions
349
+ </th>
350
+ </tr>
351
+ </thead>
352
+ <tbody>
353
+ {paginatedEntries.map((entry) => (
354
+ <tr
355
+ key={entry._id}
356
+ className="border-b last:border-0 transition-colors hover:bg-muted/50"
357
+ >
358
+ <td className="p-3">
359
+ <button
360
+ type="button"
361
+ onClick={() => navigation.navigateToEntry(entry._id)}
362
+ className="text-left font-medium text-foreground hover:text-primary hover:underline"
363
+ >
364
+ {getEntryTitle(entry)}
365
+ </button>
366
+ <p className="text-xs text-muted-foreground">{entry.slug}</p>
367
+ </td>
368
+ <td className="p-3">
369
+ <CmsStatusBadge status={entry.status as ContentStatus} />
370
+ </td>
371
+ <td className="p-3 text-sm text-muted-foreground">
372
+ {formatDate(entry.lastPublishedAt ?? entry._creationTime)}
373
+ </td>
374
+ <td className="p-3">
375
+ <div className="flex items-center gap-2">
376
+ <CmsButton
377
+ variant="outline"
378
+ size="sm"
379
+ onClick={() => navigation.navigateToEntry(entry._id)}
380
+ >
381
+ {canUpdate("contentEntries") ? "Edit" : "View"}
382
+ </CmsButton>
383
+ {canDelete("contentEntries") && (
384
+ <CmsButton
385
+ variant="danger"
386
+ size="sm"
387
+ onClick={() => handleDeleteClick(entry)}
388
+ >
389
+ Delete
390
+ </CmsButton>
391
+ )}
392
+ </div>
393
+ </td>
394
+ </tr>
395
+ ))}
396
+ </tbody>
397
+ </table>
398
+ </div>
399
+
400
+ {totalPages > 1 && (
401
+ <div className="flex items-center justify-center gap-2">
402
+ <CmsButton
403
+ variant="outline"
404
+ size="sm"
405
+ onClick={() => setCurrentPage(0)}
406
+ disabled={currentPage === 0}
407
+ >
408
+ First
409
+ </CmsButton>
410
+ <CmsButton
411
+ variant="outline"
412
+ size="sm"
413
+ onClick={() => setCurrentPage((p) => Math.max(0, p - 1))}
414
+ disabled={currentPage === 0}
415
+ >
416
+ Previous
417
+ </CmsButton>
418
+ <span className="px-3 text-sm text-muted-foreground">
419
+ Page {currentPage + 1} of {totalPages}
420
+ </span>
421
+ <CmsButton
422
+ variant="outline"
423
+ size="sm"
424
+ onClick={() => setCurrentPage((p) => Math.min(totalPages - 1, p + 1))}
425
+ disabled={currentPage >= totalPages - 1}
426
+ >
427
+ Next
428
+ </CmsButton>
429
+ <CmsButton
430
+ variant="outline"
431
+ size="sm"
432
+ onClick={() => setCurrentPage(totalPages - 1)}
433
+ disabled={currentPage >= totalPages - 1}
434
+ >
435
+ Last
436
+ </CmsButton>
437
+ </div>
438
+ )}
439
+ </>
440
+ )}
441
+
442
+ {sortedEntries.length > 0 && (
443
+ <p className="text-center text-sm text-muted-foreground">
444
+ Showing {paginatedEntries.length} of {sortedEntries.length}{" "}
445
+ {sortedEntries.length === 1 ? "entry" : "entries"}
446
+ </p>
447
+ )}
448
+
449
+ <CmsConfirmDialog
450
+ open={deleteModalOpen}
451
+ onOpenChange={handleDeleteModalClose}
452
+ title="Delete Entry"
453
+ description={
454
+ entryToDelete
455
+ ? `Are you sure you want to delete "${entryToDelete.title}"? It will be moved to the trash and can be restored within the retention period.`
456
+ : "Are you sure you want to delete this entry?"
457
+ }
458
+ confirmLabel="Delete"
459
+ variant="danger"
460
+ onConfirm={handleDeleteConfirm}
461
+ isLoading={isDeleting}
462
+ error={deleteError}
463
+ />
464
+ </div>
465
+ );
466
+ }
@@ -25,6 +25,7 @@ interface ContentTypeWithCount {
25
25
  singleton?: boolean;
26
26
  entryCount?: number;
27
27
  _creationTime: number;
28
+ source?: "code" | "database";
28
29
  }
29
30
  import { CmsPageHeader } from "~/components/cmsds/CmsPageHeader";
30
31
  import { CmsToolbar } from "~/components/cmsds/CmsToolbar";
@@ -51,6 +52,8 @@ import {
51
52
  FolderOpen,
52
53
  AlignLeft,
53
54
  Pencil,
55
+ Code2,
56
+ Eye,
54
57
  } from "lucide-react";
55
58
  import type { AdminNavigation } from "~/lib/navigation";
56
59
  import { CmsAdminApi } from "~/embed/contexts/ApiContext";
@@ -252,6 +255,16 @@ export function ContentTypesPage({ api, navigation }: ContentTypesPageProps) {
252
255
  <FileType className="size-5" />
253
256
  </div>
254
257
  <div className="flex items-center gap-1.5">
258
+ {contentType.source === "code" && (
259
+ <Badge
260
+ variant="secondary"
261
+ className="border-violet-200 bg-violet-50 text-xs font-normal text-violet-700"
262
+ title="Managed by code - edit in your codebase"
263
+ >
264
+ <Code2 className="mr-1 size-3" />
265
+ Code
266
+ </Badge>
267
+ )}
255
268
  {!contentType.isActive && (
256
269
  <Badge variant="secondary" className="text-xs font-normal">
257
270
  Inactive
@@ -260,19 +273,30 @@ export function ContentTypesPage({ api, navigation }: ContentTypesPageProps) {
260
273
  {contentType.singleton && (
261
274
  <Badge
262
275
  variant="secondary"
263
- className="border-amber-200 bg-amber-50 text-xs font-normal text-amber-700"
276
+ className="border-diff-modified-border bg-diff-modified-bg text-xs font-normal text-diff-modified-foreground"
264
277
  >
265
278
  Singleton
266
279
  </Badge>
267
280
  )}
268
- <button
269
- onClick={() => setEditingContentType(contentType)}
270
- className="rounded p-1.5 text-muted-foreground opacity-0 transition-all hover:bg-muted hover:text-foreground group-hover:opacity-100"
271
- title="Edit content type"
272
- aria-label="Edit content type"
273
- >
274
- <Pencil className="size-4" />
275
- </button>
281
+ {contentType.source === "code" ? (
282
+ <button
283
+ className="rounded p-1.5 text-muted-foreground opacity-0 transition-all hover:bg-muted hover:text-foreground group-hover:opacity-100"
284
+ title="View content type (managed by code)"
285
+ aria-label="View content type"
286
+ onClick={() => setEditingContentType(contentType)}
287
+ >
288
+ <Eye className="size-4" />
289
+ </button>
290
+ ) : (
291
+ <button
292
+ onClick={() => setEditingContentType(contentType)}
293
+ className="rounded p-1.5 text-muted-foreground opacity-0 transition-all hover:bg-muted hover:text-foreground group-hover:opacity-100"
294
+ title="Edit content type"
295
+ aria-label="Edit content type"
296
+ >
297
+ <Pencil className="size-4" />
298
+ </button>
299
+ )}
276
300
  </div>
277
301
  </div>
278
302
 
@@ -383,12 +407,22 @@ export function ContentTypesPage({ api, navigation }: ContentTypesPageProps) {
383
407
  </td>
384
408
  <td className="p-3">
385
409
  <div className="flex items-center gap-1.5">
410
+ {contentType.source === "code" && (
411
+ <Badge
412
+ variant="secondary"
413
+ className="border-violet-200 bg-violet-50 text-xs font-normal text-violet-700"
414
+ title="Managed by code"
415
+ >
416
+ <Code2 className="mr-1 size-3" />
417
+ Code
418
+ </Badge>
419
+ )}
386
420
  <Badge
387
421
  variant={contentType.isActive ? "default" : "secondary"}
388
422
  className={cn(
389
423
  "text-xs font-normal",
390
424
  contentType.isActive &&
391
- "border-emerald-200 bg-emerald-50 text-emerald-700",
425
+ "border-diff-added-border bg-diff-added-bg text-diff-added-foreground",
392
426
  )}
393
427
  >
394
428
  {contentType.isActive ? "Active" : "Inactive"}
@@ -396,7 +430,7 @@ export function ContentTypesPage({ api, navigation }: ContentTypesPageProps) {
396
430
  {contentType.singleton && (
397
431
  <Badge
398
432
  variant="secondary"
399
- className="border-amber-200 bg-amber-50 text-xs font-normal text-amber-700"
433
+ className="border-diff-modified-border bg-diff-modified-bg text-xs font-normal text-diff-modified-foreground"
400
434
  >
401
435
  Singleton
402
436
  </Badge>
@@ -408,14 +442,26 @@ export function ContentTypesPage({ api, navigation }: ContentTypesPageProps) {
408
442
  </td>
409
443
  <td className="p-3">
410
444
  <div className="flex items-center gap-2">
411
- <CmsButton
412
- variant="outline"
413
- size="sm"
414
- onClick={() => setEditingContentType(contentType)}
415
- >
416
- <Pencil className="size-3.5" />
417
- Edit
418
- </CmsButton>
445
+ {contentType.source === "code" ? (
446
+ <CmsButton
447
+ variant="outline"
448
+ size="sm"
449
+ onClick={() => setEditingContentType(contentType)}
450
+ title="View content type (managed by code)"
451
+ >
452
+ <Eye className="size-3.5" />
453
+ View
454
+ </CmsButton>
455
+ ) : (
456
+ <CmsButton
457
+ variant="outline"
458
+ size="sm"
459
+ onClick={() => setEditingContentType(contentType)}
460
+ >
461
+ <Pencil className="size-3.5" />
462
+ Edit
463
+ </CmsButton>
464
+ )}
419
465
  <CmsButton
420
466
  variant="outline"
421
467
  size="sm"
@@ -15,6 +15,7 @@ import {
15
15
  } from "~/components/ui/card";
16
16
  import { Skeleton } from "~/components/ui/skeleton";
17
17
  import { CmsPageHeader } from "~/components/cmsds";
18
+ import { SchemaDriftWarning } from "~/components/SchemaDriftWarning";
18
19
  import { FileText, Image, Layers, Settings, TrendingUp } from "lucide-react";
19
20
  import type { AdminNavigation } from "~/lib/navigation";
20
21
  import type { CmsAdminApi } from "~/embed/contexts/ApiContext";
@@ -36,6 +37,8 @@ export function DashboardPage({ api, navigation }: DashboardPageProps) {
36
37
  description="Welcome to Convex CMS Admin. Manage your content, media, and publishing workflows."
37
38
  />
38
39
 
40
+ <SchemaDriftWarning api={api} />
41
+
39
42
  <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
40
43
  <DashboardCard
41
44
  title="Content Entries"
@@ -135,7 +135,7 @@ export function SettingsPage({
135
135
  const adminConfig = useAdminConfig();
136
136
 
137
137
  const isConfigured = useMemo(() => {
138
- return typeof api.getSettings === "function";
138
+ return api.getSettings != null;
139
139
  }, [api]);
140
140
 
141
141
  const settings = useQuery(
@@ -371,7 +371,7 @@ export function SettingsPage({
371
371
  {feedbackStatus === "saved" && (
372
372
  <Badge
373
373
  variant="secondary"
374
- className="gap-1 bg-emerald-100 text-emerald-700"
374
+ className="gap-1 bg-diff-added-bg text-diff-added-foreground"
375
375
  >
376
376
  <Check className="size-3" />
377
377
  Settings saved successfully
@@ -517,9 +517,9 @@ export function SettingsPage({
517
517
  {canEdit && api.resetSettings && (
518
518
  <CmsSurface
519
519
  elevation="base"
520
- className="border-red-200 p-6 dark:border-red-900"
520
+ className="border-destructive/50 p-6"
521
521
  >
522
- <h2 className="mb-4 text-lg font-semibold text-red-600">
522
+ <h2 className="mb-4 text-lg font-semibold text-destructive">
523
523
  Danger Zone
524
524
  </h2>
525
525
  <div className="flex items-center justify-between">
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  export { ContentPage, type ContentPageProps } from "./ContentPage";
9
+ export { ContentTypeEntriesPage, type ContentTypeEntriesPageProps } from "./ContentTypeEntriesPage";
9
10
  export { ContentTypesPage, type ContentTypesPageProps } from "./ContentTypesPage";
10
11
  export { DashboardPage } from "./DashboardPage";
11
12
  export { MediaPage, type MediaPageProps } from "./MediaPage";