convex-cms 0.0.5-alpha.5 → 0.0.7-alpha.0

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 (296) hide show
  1. package/README.md +59 -97
  2. package/admin/src/components/ContentEntryEditor.tsx +2 -2
  3. package/admin/src/components/ContentTypeFormModal.tsx +121 -81
  4. package/admin/src/components/fields/ReferenceField.tsx +9 -9
  5. package/admin/src/pages/ContentPage.tsx +11 -19
  6. package/admin/src/pages/ContentTypesPage.tsx +62 -16
  7. package/admin/src/routes/entries/$entryId.tsx +1 -1
  8. package/admin/src/routes/entries/type/$contentTypeId.tsx +1 -1
  9. package/admin-dist/nitro.json +1 -1
  10. package/admin-dist/public/assets/CmsEmptyState-CXVkI3FZ.js +1 -0
  11. package/admin-dist/public/assets/CmsPageHeader-DU9fD34s.js +1 -0
  12. package/admin-dist/public/assets/{CmsStatusBadge-Dd9uToHE.js → CmsStatusBadge-nZ9TeLBL.js} +1 -1
  13. package/admin-dist/public/assets/{CmsSurface-DBy5Lumx.js → CmsSurface-DF7OcKg_.js} +1 -1
  14. package/admin-dist/public/assets/CmsToolbar-5S8FQrSx.js +1 -0
  15. package/admin-dist/public/assets/ContentEntryEditor-BDb44eTo.js +4 -0
  16. package/admin-dist/public/assets/TaxonomyFilter-DEN2Q9Lo.js +1 -0
  17. package/admin-dist/public/assets/_contentTypeId-Ba5iowxH.js +1 -0
  18. package/admin-dist/public/assets/_entryId-OY3sLz6O.js +1 -0
  19. package/admin-dist/public/assets/alert-BbW1Q9CR.js +1 -0
  20. package/admin-dist/public/assets/badge-DdM8Eua8.js +1 -0
  21. package/admin-dist/public/assets/{circle-check-big-CpLxAvEj.js → circle-check-big-B7eCOM8r.js} +1 -1
  22. package/admin-dist/public/assets/command-BIjzeKOv.js +1 -0
  23. package/admin-dist/public/assets/content-BV3YeSSW.js +1 -0
  24. package/admin-dist/public/assets/content-types-Bm4b2tf8.js +1 -0
  25. package/admin-dist/public/assets/globals-D41WzvyZ.css +1 -0
  26. package/admin-dist/public/assets/index-DnJ5Twlv.js +1 -0
  27. package/admin-dist/public/assets/main-BZB1uYTH.js +102 -0
  28. package/admin-dist/public/assets/media-BIMN5jXt.js +1 -0
  29. package/admin-dist/public/assets/new._contentTypeId-DTWb8ZDl.js +1 -0
  30. package/admin-dist/public/assets/pencil-BDQ1ZWRw.js +1 -0
  31. package/admin-dist/public/assets/{rotate-ccw-BZpZtw0N.js → rotate-ccw-BWblSIsl.js} +1 -1
  32. package/admin-dist/public/assets/scroll-area-BoaB6x8v.js +1 -0
  33. package/admin-dist/public/assets/{search-BvgYr-c9.js → search-CYMIpd39.js} +1 -1
  34. package/admin-dist/public/assets/settings-DaNDUtr5.js +1 -0
  35. package/admin-dist/public/assets/switch-DN7TOCa5.js +1 -0
  36. package/admin-dist/public/assets/tabs-RN__emeJ.js +1 -0
  37. package/admin-dist/public/assets/tanstack-adapter-DQcKErwf.js +1 -0
  38. package/admin-dist/public/assets/taxonomies-DylY9HE1.js +1 -0
  39. package/admin-dist/public/assets/trash-Dp_a2mpb.js +1 -0
  40. package/admin-dist/public/assets/{useBreadcrumbLabel-D00rvqjw.js → useBreadcrumbLabel-BQ9dJI6T.js} +1 -1
  41. package/admin-dist/public/assets/usePermissions-WUBNg_Id.js +1 -0
  42. package/admin-dist/server/_chunks/_libs/@date-fns/tz.mjs +2 -2
  43. package/admin-dist/server/_chunks/_libs/@radix-ui/react-avatar.mjs +1 -1
  44. package/admin-dist/server/_chunks/_libs/@radix-ui/react-collection.mjs +1 -1
  45. package/admin-dist/server/_chunks/_libs/@radix-ui/react-context.mjs +2 -2
  46. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dialog.mjs +2 -2
  47. package/admin-dist/server/_chunks/_libs/@radix-ui/react-label.mjs +1 -1
  48. package/admin-dist/server/_chunks/_libs/@radix-ui/react-menu.mjs +1 -1
  49. package/admin-dist/server/_chunks/_libs/@radix-ui/react-popover.mjs +1 -1
  50. package/admin-dist/server/_chunks/_libs/@radix-ui/react-primitive.mjs +6 -72
  51. package/admin-dist/server/_chunks/_libs/@radix-ui/react-select.mjs +1 -1
  52. package/admin-dist/server/_chunks/_libs/@radix-ui/react-separator.mjs +1 -1
  53. package/admin-dist/server/_chunks/_libs/@radix-ui/react-slot.mjs +20 -435
  54. package/admin-dist/server/_chunks/_libs/@radix-ui/react-visually-hidden.mjs +30 -3
  55. package/admin-dist/server/_chunks/_libs/@tanstack/history.mjs +0 -376
  56. package/admin-dist/server/_chunks/_libs/@tanstack/react-router.mjs +168 -383
  57. package/admin-dist/server/_chunks/_libs/@tanstack/router-core.mjs +451 -1195
  58. package/admin-dist/server/_chunks/_libs/react-dom.mjs +5 -5
  59. package/admin-dist/server/_chunks/_libs/react.mjs +2 -2
  60. package/admin-dist/server/_libs/cmdk.mjs +1 -1
  61. package/admin-dist/server/_libs/convex.mjs +3 -3
  62. package/admin-dist/server/_libs/cookie-es.mjs +1 -58
  63. package/admin-dist/server/_libs/date-fns.mjs +1 -1
  64. package/admin-dist/server/_libs/lucide-react.mjs +110 -103
  65. package/admin-dist/server/_libs/seroval-plugins.mjs +1 -58
  66. package/admin-dist/server/_libs/seroval.mjs +1 -1765
  67. package/admin-dist/server/_libs/zod.mjs +1 -1
  68. package/admin-dist/server/_ssr/CmsEmptyState-DYh_PPQE.mjs +38 -0
  69. package/admin-dist/server/_ssr/{CmsPageHeader-ClNPU7Up.mjs → CmsPageHeader-BcniLh49.mjs} +1 -1
  70. package/admin-dist/server/_ssr/{CmsStatusBadge-CojMbrY7.mjs → CmsStatusBadge-BShWDxwE.mjs} +2 -2
  71. package/admin-dist/server/_ssr/{CmsSurface-Dcv440rp.mjs → CmsSurface-CHEv-Kba.mjs} +1 -1
  72. package/admin-dist/server/_ssr/{CmsToolbar-BKv1nL6u.mjs → CmsToolbar-Dqqb216_.mjs} +2 -3
  73. package/admin-dist/server/_ssr/{ContentEntryEditor-weiXSBdZ.mjs → ContentEntryEditor-DOIAyWME.mjs} +18 -21
  74. package/admin-dist/server/_ssr/{TaxonomyFilter-BPQ57Mwk.mjs → TaxonomyFilter-BfsPAZ-Y.mjs} +4 -5
  75. package/admin-dist/server/_ssr/{_contentTypeId-DyyauLOs.mjs → _contentTypeId-CPjmri90.mjs} +34 -43
  76. package/admin-dist/server/_ssr/{_entryId-9Cafwxmw.mjs → _entryId-D0yu8HuP.mjs} +35 -47
  77. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-DgCpSt_y.mjs +4 -0
  78. package/admin-dist/server/_ssr/badge-Cp61aQNc.mjs +39 -0
  79. package/admin-dist/server/_ssr/{command-CEf8YBxY.mjs → command-BfjE1WJf.mjs} +2 -2
  80. package/admin-dist/server/_ssr/{config.server-D7JHDcDv.mjs → config.server-BOr7Jxr4.mjs} +5 -14
  81. package/admin-dist/server/_ssr/{content-ZFWVzO25.mjs → content-DrODe6sA.mjs} +40 -49
  82. package/admin-dist/server/_ssr/content-types-BPgMwxiT.mjs +459 -0
  83. package/admin-dist/server/_ssr/{index-BlSIlH4Z.mjs → index-BTHmIC9W.mjs} +26 -28
  84. package/admin-dist/server/_ssr/index.mjs +3459 -62
  85. package/admin-dist/server/_ssr/{media-CD2_NUMw.mjs → media-DkvBfmD9.mjs} +31 -43
  86. package/admin-dist/server/_ssr/{new._contentTypeId-dmZy6PBX.mjs → new._contentTypeId-Co_73sDJ.mjs} +33 -45
  87. package/admin-dist/server/_ssr/router-CaDgRHfQ.mjs +3031 -0
  88. package/admin-dist/server/_ssr/{scroll-area-BH_1K-WT.mjs → scroll-area-D3v-O_jk.mjs} +1 -1
  89. package/admin-dist/server/_ssr/{settings-DVdsoWoh.mjs → settings-MaEXh2Hz.mjs} +30 -39
  90. package/admin-dist/server/_ssr/{switch-DX_X8vZl.mjs → switch-DmbR03dm.mjs} +1 -1
  91. package/admin-dist/server/_ssr/{tabs-4FWM0sn8.mjs → tabs-5oFlAGLz.mjs} +2 -3
  92. package/admin-dist/server/_ssr/{tanstack-adapter-D3ZcKtbY.mjs → tanstack-adapter-DNaUioIZ.mjs} +1 -1
  93. package/admin-dist/server/_ssr/{taxonomies-BHFfO9Yr.mjs → taxonomies-D3xMK23a.mjs} +30 -39
  94. package/admin-dist/server/_ssr/{trash-9tUB2KwI.mjs → trash-CNw1mtF1.mjs} +30 -39
  95. package/admin-dist/server/_ssr/{useBreadcrumbLabel-DVme3DSb.mjs → useBreadcrumbLabel-BQGjOTcy.mjs} +1 -1
  96. package/admin-dist/server/_ssr/{usePermissions-zAQj-ruE.mjs → usePermissions-D0qtvmNi.mjs} +1 -1
  97. package/admin-dist/server/index.mjs +162 -204
  98. package/dist/cli/templates/cmsClient.d.ts +1 -1
  99. package/dist/cli/templates/cmsClient.d.ts.map +1 -1
  100. package/dist/cli/templates/cmsClient.js +30 -11
  101. package/dist/cli/templates/cmsClient.js.map +1 -1
  102. package/dist/cli/templates/cmsConfig.d.ts +1 -1
  103. package/dist/cli/templates/cmsConfig.d.ts.map +1 -1
  104. package/dist/cli/templates/cmsConfig.js +3 -3
  105. package/dist/client/admin/contentLock.d.ts +4 -4
  106. package/dist/client/admin/contentLock.d.ts.map +1 -1
  107. package/dist/client/admin/contentLock.js +1 -1
  108. package/dist/client/admin/contentLock.js.map +1 -1
  109. package/dist/client/admin/contentTypes.d.ts +303 -290
  110. package/dist/client/admin/contentTypes.d.ts.map +1 -1
  111. package/dist/client/admin/contentTypes.js +101 -9
  112. package/dist/client/admin/contentTypes.js.map +1 -1
  113. package/dist/client/admin/entries.d.ts +18 -19
  114. package/dist/client/admin/entries.d.ts.map +1 -1
  115. package/dist/client/admin/entries.js +6 -8
  116. package/dist/client/admin/entries.js.map +1 -1
  117. package/dist/client/admin/index.d.ts +690 -642
  118. package/dist/client/admin/index.d.ts.map +1 -1
  119. package/dist/client/admin/index.js +29 -5
  120. package/dist/client/admin/index.js.map +1 -1
  121. package/dist/client/admin/media.d.ts.map +1 -1
  122. package/dist/client/admin/taxonomies.d.ts.map +1 -1
  123. package/dist/client/admin/trash.d.ts +3 -4
  124. package/dist/client/admin/trash.d.ts.map +1 -1
  125. package/dist/client/admin/types.d.ts +181 -4
  126. package/dist/client/admin/types.d.ts.map +1 -1
  127. package/dist/client/admin/validators.d.ts +2009 -25
  128. package/dist/client/admin/validators.d.ts.map +1 -1
  129. package/dist/client/admin/validators.js +15 -4
  130. package/dist/client/admin/validators.js.map +1 -1
  131. package/dist/client/admin/versions.d.ts +1 -1
  132. package/dist/client/admin/versions.d.ts.map +1 -1
  133. package/dist/client/agentTools.d.ts +1 -4
  134. package/dist/client/agentTools.d.ts.map +1 -1
  135. package/dist/client/agentTools.js +9 -21
  136. package/dist/client/agentTools.js.map +1 -1
  137. package/dist/client/config.d.ts +10 -0
  138. package/dist/client/config.d.ts.map +1 -1
  139. package/dist/client/config.js +1 -0
  140. package/dist/client/config.js.map +1 -1
  141. package/dist/client/defineContent.d.ts +338 -0
  142. package/dist/client/defineContent.d.ts.map +1 -0
  143. package/dist/client/defineContent.js +368 -0
  144. package/dist/client/defineContent.js.map +1 -0
  145. package/dist/client/index.d.ts +2 -0
  146. package/dist/client/index.d.ts.map +1 -1
  147. package/dist/client/index.js +2 -0
  148. package/dist/client/index.js.map +1 -1
  149. package/dist/client/queryBuilder.d.ts +0 -15
  150. package/dist/client/queryBuilder.d.ts.map +1 -1
  151. package/dist/client/queryBuilder.js +0 -23
  152. package/dist/client/queryBuilder.js.map +1 -1
  153. package/dist/client/registry.d.ts +77 -0
  154. package/dist/client/registry.d.ts.map +1 -0
  155. package/dist/client/registry.js +95 -0
  156. package/dist/client/registry.js.map +1 -0
  157. package/dist/client/schema/defineContentType.d.ts +36 -24
  158. package/dist/client/schema/defineContentType.d.ts.map +1 -1
  159. package/dist/client/schema/defineContentType.js +77 -48
  160. package/dist/client/schema/defineContentType.js.map +1 -1
  161. package/dist/client/schema/typedClient.d.ts.map +1 -1
  162. package/dist/client/schema/typedClient.js +2 -10
  163. package/dist/client/schema/typedClient.js.map +1 -1
  164. package/dist/client/schema/types.d.ts +16 -9
  165. package/dist/client/schema/types.d.ts.map +1 -1
  166. package/dist/client/schema/types.js.map +1 -1
  167. package/dist/client/utils/toSlug.d.ts +60 -0
  168. package/dist/client/utils/toSlug.d.ts.map +1 -0
  169. package/dist/client/utils/toSlug.js +31 -0
  170. package/dist/client/utils/toSlug.js.map +1 -0
  171. package/dist/client/wrapper.d.ts +2 -2
  172. package/dist/client/wrapper.d.ts.map +1 -1
  173. package/dist/client/wrapper.js +22 -30
  174. package/dist/client/wrapper.js.map +1 -1
  175. package/dist/component/_generated/component.d.ts +24 -28
  176. package/dist/component/_generated/component.d.ts.map +1 -1
  177. package/dist/component/authorizationHooks.d.ts +1 -1
  178. package/dist/component/authorizationHooks.d.ts.map +1 -1
  179. package/dist/component/authorizationHooks.js +2 -2
  180. package/dist/component/authorizationHooks.js.map +1 -1
  181. package/dist/component/bulkOperations.d.ts.map +1 -1
  182. package/dist/component/bulkOperations.js +7 -4
  183. package/dist/component/bulkOperations.js.map +1 -1
  184. package/dist/component/contentEntries.d.ts +18 -56
  185. package/dist/component/contentEntries.d.ts.map +1 -1
  186. package/dist/component/contentEntries.js +45 -137
  187. package/dist/component/contentEntries.js.map +1 -1
  188. package/dist/component/contentEntryMutations.d.ts +14 -14
  189. package/dist/component/contentEntryMutations.d.ts.map +1 -1
  190. package/dist/component/contentEntryMutations.js +40 -43
  191. package/dist/component/contentEntryMutations.js.map +1 -1
  192. package/dist/component/contentEntryValidation.d.ts +3 -3
  193. package/dist/component/contentEntryValidation.js +6 -9
  194. package/dist/component/contentEntryValidation.js.map +1 -1
  195. package/dist/component/contentLock.d.ts +7 -7
  196. package/dist/component/contentLock.js +3 -3
  197. package/dist/component/contentLock.js.map +1 -1
  198. package/dist/component/contentTypeMigration.d.ts +1 -1
  199. package/dist/component/contentTypeMigration.js +2 -2
  200. package/dist/component/contentTypeMigration.js.map +1 -1
  201. package/dist/component/contentTypeMutations.js +2 -2
  202. package/dist/component/contentTypeMutations.js.map +1 -1
  203. package/dist/component/convex.config.d.ts.map +1 -1
  204. package/dist/component/convex.config.js +1 -1
  205. package/dist/component/convex.config.js.map +1 -1
  206. package/dist/component/eventEmitter.d.ts +0 -1
  207. package/dist/component/eventEmitter.d.ts.map +1 -1
  208. package/dist/component/eventEmitter.js.map +1 -1
  209. package/dist/component/exportImport.d.ts +37 -37
  210. package/dist/component/exportImport.d.ts.map +1 -1
  211. package/dist/component/exportImport.js +34 -34
  212. package/dist/component/exportImport.js.map +1 -1
  213. package/dist/component/lib/deepReferenceResolver.d.ts +2 -2
  214. package/dist/component/lib/deepReferenceResolver.d.ts.map +1 -1
  215. package/dist/component/lib/deepReferenceResolver.js +13 -8
  216. package/dist/component/lib/deepReferenceResolver.js.map +1 -1
  217. package/dist/component/lib/ragContentChunker.d.ts +3 -3
  218. package/dist/component/lib/ragContentChunker.d.ts.map +1 -1
  219. package/dist/component/lib/ragContentChunker.js +4 -4
  220. package/dist/component/lib/ragContentChunker.js.map +1 -1
  221. package/dist/component/lib/referenceResolver.d.ts.map +1 -1
  222. package/dist/component/lib/referenceResolver.js +10 -17
  223. package/dist/component/lib/referenceResolver.js.map +1 -1
  224. package/dist/component/mediaAssetMutations.js +4 -4
  225. package/dist/component/mediaAssetMutations.js.map +1 -1
  226. package/dist/component/ragContentIndexer.d.ts +2 -2
  227. package/dist/component/ragContentIndexer.d.ts.map +1 -1
  228. package/dist/component/ragContentIndexer.js +44 -48
  229. package/dist/component/ragContentIndexer.js.map +1 -1
  230. package/dist/component/roles.d.ts +3 -3
  231. package/dist/component/scheduledPublish.d.ts +4 -4
  232. package/dist/component/scheduledPublish.js +3 -3
  233. package/dist/component/scheduledPublish.js.map +1 -1
  234. package/dist/component/schema.d.ts +18 -18
  235. package/dist/component/schema.js +5 -5
  236. package/dist/component/schema.js.map +1 -1
  237. package/dist/component/trash.d.ts +6 -9
  238. package/dist/component/trash.d.ts.map +1 -1
  239. package/dist/component/trash.js +12 -36
  240. package/dist/component/trash.js.map +1 -1
  241. package/dist/component/userContext.d.ts +1 -2
  242. package/dist/component/userContext.d.ts.map +1 -1
  243. package/dist/component/userContext.js +1 -2
  244. package/dist/component/userContext.js.map +1 -1
  245. package/dist/component/validators.d.ts +27 -33
  246. package/dist/component/validators.d.ts.map +1 -1
  247. package/dist/component/validators.js +3 -5
  248. package/dist/component/validators.js.map +1 -1
  249. package/dist/component/versionMutations.d.ts +1 -1
  250. package/dist/component/webhookTrigger.d.ts +14 -14
  251. package/dist/test.d.ts +30 -30
  252. package/dist/test.d.ts.map +1 -1
  253. package/dist/test.js +24 -24
  254. package/dist/test.js.map +1 -1
  255. package/package.json +1 -1
  256. package/admin-dist/public/assets/CmsEmptyState-Do_erIgn.js +0 -5
  257. package/admin-dist/public/assets/CmsPageHeader-qDwPGi48.js +0 -1
  258. package/admin-dist/public/assets/CmsToolbar-D1-Y-7SK.js +0 -1
  259. package/admin-dist/public/assets/ContentEntryEditor-CWBiIx52.js +0 -4
  260. package/admin-dist/public/assets/TaxonomyFilter-CdYQawxb.js +0 -1
  261. package/admin-dist/public/assets/_contentTypeId-D9VMP6Gs.js +0 -1
  262. package/admin-dist/public/assets/_entryId-2FlCfqE7.js +0 -1
  263. package/admin-dist/public/assets/alert-GxZx0y5c.js +0 -1
  264. package/admin-dist/public/assets/badge-BAlGIjop.js +0 -1
  265. package/admin-dist/public/assets/command-di7XCqcv.js +0 -1
  266. package/admin-dist/public/assets/content-D8zELsDG.js +0 -1
  267. package/admin-dist/public/assets/content-types-BmzD0krT.js +0 -2
  268. package/admin-dist/public/assets/globals-BvFfH-v9.css +0 -1
  269. package/admin-dist/public/assets/index-zqfj4T_v.js +0 -1
  270. package/admin-dist/public/assets/label-B6PPtKR5.js +0 -1
  271. package/admin-dist/public/assets/link-2-W2fVnVOf.js +0 -1
  272. package/admin-dist/public/assets/list-F8O0lZXC.js +0 -1
  273. package/admin-dist/public/assets/main-dZT72bAG.js +0 -97
  274. package/admin-dist/public/assets/media-CETueFbV.js +0 -1
  275. package/admin-dist/public/assets/new._contentTypeId-BV2-TyyR.js +0 -1
  276. package/admin-dist/public/assets/plus-AABQIF0N.js +0 -1
  277. package/admin-dist/public/assets/scroll-area-CDfk-zrz.js +0 -1
  278. package/admin-dist/public/assets/select-BuiHcMzS.js +0 -1
  279. package/admin-dist/public/assets/settings-DBxbYDvn.js +0 -1
  280. package/admin-dist/public/assets/switch-DiJvolcs.js +0 -1
  281. package/admin-dist/public/assets/tabs-Cgz6G_Xy.js +0 -1
  282. package/admin-dist/public/assets/tanstack-adapter-BknsSgra.js +0 -1
  283. package/admin-dist/public/assets/taxonomies-DOErsLl5.js +0 -1
  284. package/admin-dist/public/assets/textarea-CgggMxUX.js +0 -1
  285. package/admin-dist/public/assets/trash-BU4ANuaW.js +0 -1
  286. package/admin-dist/public/assets/triangle-alert-lvCbwp0s.js +0 -1
  287. package/admin-dist/public/assets/usePermissions-D7tQowaF.js +0 -1
  288. package/admin-dist/server/_libs/h3-v2.mjs +0 -277
  289. package/admin-dist/server/_ssr/CmsButton-DbzfJru_.mjs +0 -125
  290. package/admin-dist/server/_ssr/CmsEmptyState-CuvcXr3Z.mjs +0 -290
  291. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-Dk-FIYPN.mjs +0 -4
  292. package/admin-dist/server/_ssr/content-types-D25lUE-j.mjs +0 -1312
  293. package/admin-dist/server/_ssr/label-PblVvdRv.mjs +0 -22
  294. package/admin-dist/server/_ssr/router-x6Ab8T4s.mjs +0 -1622
  295. package/admin-dist/server/_ssr/select-CrfEkFJw.mjs +0 -142
  296. package/admin-dist/server/_ssr/textarea-CZVaroMc.mjs +0 -18
@@ -0,0 +1,3031 @@
1
+ import { c as createRouter, a as createRootRoute, b as createFileRoute, l as lazyRouteComponent, O as Outlet, H as HeadContent, S as Scripts, u as useRouterState, L as Link, d as useNavigate } from "../_chunks/_libs/@tanstack/react-router.mjs";
2
+ import { r as reactExports, j as jsxRuntimeExports } from "../_chunks/_libs/react.mjs";
3
+ import { c as clsx } from "../_libs/clsx.mjs";
4
+ import { t as twMerge } from "../_libs/tailwind-merge.mjs";
5
+ import { R as Root$1, C as CollapsibleTrigger$1, a as CollapsibleContent$1 } from "../_chunks/_libs/@radix-ui/react-collapsible.mjs";
6
+ import { R as Root$3, C as Content, a as Close, T as Title, D as Description, P as Portal$2, O as Overlay } from "../_chunks/_libs/@radix-ui/react-dialog.mjs";
7
+ import { S as Slot } from "../_chunks/_libs/@radix-ui/react-slot.mjs";
8
+ import { c as cva } from "../_libs/class-variance-authority.mjs";
9
+ import { R as Root$2 } from "../_chunks/_libs/@radix-ui/react-label.mjs";
10
+ import { C as Checkbox$1, a as CheckboxIndicator } from "../_chunks/_libs/@radix-ui/react-checkbox.mjs";
11
+ import { R as Root2$2, T as Trigger$2, I as Icon$1, V as Value, P as Portal$1, C as Content2$2, a as Viewport, b as Item, c as ItemIndicator, d as ItemText, S as ScrollUpButton, e as ScrollDownButton } from "../_chunks/_libs/@radix-ui/react-select.mjs";
12
+ import { R as Root2$1, T as Trigger$1, P as Portal2, C as Content2$1, L as Label2, S as Separator2, I as Item2 } from "../_chunks/_libs/@radix-ui/react-dropdown-menu.mjs";
13
+ import { R as Root, I as Image, F as Fallback } from "../_chunks/_libs/@radix-ui/react-avatar.mjs";
14
+ import { R as Root2, T as Trigger, P as Portal, C as Content2 } from "../_chunks/_libs/@radix-ui/react-popover.mjs";
15
+ import { c as createServerFn, T as TSS_SERVER_FUNCTION, g as getServerFnById } from "./index.mjs";
16
+ import { v, c as componentsGeneric, C as ConvexReactClient, a as ConvexProvider, u as useQuery, b as anyApi, d as useMutation } from "../_libs/convex.mjs";
17
+ import { L as LoaderCircle, a as Layers, H as House, B as Bell, C as CircleQuestionMark, b as Book, c as Code, M as MessageSquare, E as ExternalLink, d as ChevronDown, U as User, e as LogOut, f as CodeXml, P as Plus, g as ChevronUp, X, h as ChevronRight, i as Check, j as CircleAlert, k as Eye, S as SquarePen, A as Archive, l as Bookmark, F as Flag, m as Heart, n as Star, o as Package, p as Phone, q as Mail, D as DollarSign, r as MapPin, s as Folder, t as Braces, u as SquareCheckBig, T as ToggleLeft, v as Hash, w as Link$1, x as Clock, y as Calendar, G as Globe, z as Lock, I as Trash2, J as Settings, K as FileCode, N as Tags, O as Image$1, Q as FileText, R as LayoutDashboard, V as FolderOpen, W as Tag, Y as List, Z as Link2, _ as FileType, $ as TextAlignStart, a0 as TriangleAlert } from "../_libs/lucide-react.mjs";
18
+ import { o as object, b as boolean, s as string, _ as _enum, n as number, a as array, r as record } from "../_libs/zod.mjs";
19
+ import "../_libs/tiny-warning.mjs";
20
+ import "../_chunks/_libs/@tanstack/router-core.mjs";
21
+ import "../_chunks/_libs/@tanstack/store.mjs";
22
+ import "../_chunks/_libs/@tanstack/history.mjs";
23
+ import "../_libs/tiny-invariant.mjs";
24
+ import "node:stream/web";
25
+ import "node:stream";
26
+ import "../_chunks/_libs/react-dom.mjs";
27
+ import "util";
28
+ import "crypto";
29
+ import "async_hooks";
30
+ import "stream";
31
+ import "../_libs/isbot.mjs";
32
+ import "../_chunks/_libs/@tanstack/react-store.mjs";
33
+ import "../_libs/use-sync-external-store.mjs";
34
+ import "../_chunks/_libs/@radix-ui/primitive.mjs";
35
+ import "../_chunks/_libs/@radix-ui/react-context.mjs";
36
+ import "../_chunks/_libs/@radix-ui/react-use-controllable-state.mjs";
37
+ import "../_chunks/_libs/@radix-ui/react-use-layout-effect.mjs";
38
+ import "../_chunks/_libs/@radix-ui/react-compose-refs.mjs";
39
+ import "../_chunks/_libs/@radix-ui/react-primitive.mjs";
40
+ import "../_chunks/_libs/@radix-ui/react-presence.mjs";
41
+ import "../_chunks/_libs/@radix-ui/react-id.mjs";
42
+ import "../_chunks/_libs/@radix-ui/react-dismissable-layer.mjs";
43
+ import "../_chunks/_libs/@radix-ui/react-use-callback-ref.mjs";
44
+ import "../_chunks/_libs/@radix-ui/react-use-escape-keydown.mjs";
45
+ import "../_chunks/_libs/@radix-ui/react-focus-scope.mjs";
46
+ import "../_chunks/_libs/@radix-ui/react-portal.mjs";
47
+ import "../_chunks/_libs/@radix-ui/react-focus-guards.mjs";
48
+ import "../_libs/react-remove-scroll.mjs";
49
+ import "../_libs/tslib.mjs";
50
+ import "../_libs/react-remove-scroll-bar.mjs";
51
+ import "../_libs/react-style-singleton.mjs";
52
+ import "../_libs/get-nonce.mjs";
53
+ import "../_libs/use-sidecar.mjs";
54
+ import "../_libs/use-callback-ref.mjs";
55
+ import "../_libs/aria-hidden.mjs";
56
+ import "../_chunks/_libs/@radix-ui/react-use-previous.mjs";
57
+ import "../_chunks/_libs/@radix-ui/react-use-size.mjs";
58
+ import "../_chunks/_libs/@radix-ui/number.mjs";
59
+ import "../_chunks/_libs/@radix-ui/react-collection.mjs";
60
+ import "../_chunks/_libs/@radix-ui/react-direction.mjs";
61
+ import "../_chunks/_libs/@radix-ui/react-popper.mjs";
62
+ import "../_chunks/_libs/@floating-ui/react-dom.mjs";
63
+ import "../_chunks/_libs/@floating-ui/dom.mjs";
64
+ import "../_chunks/_libs/@floating-ui/core.mjs";
65
+ import "../_chunks/_libs/@floating-ui/utils.mjs";
66
+ import "../_chunks/_libs/@radix-ui/react-arrow.mjs";
67
+ import "../_chunks/_libs/@radix-ui/react-visually-hidden.mjs";
68
+ import "../_chunks/_libs/@radix-ui/react-menu.mjs";
69
+ import "../_chunks/_libs/@radix-ui/react-roving-focus.mjs";
70
+ import "../_chunks/_libs/@radix-ui/react-use-is-hydrated.mjs";
71
+ import "node:async_hooks";
72
+ const globalsCss = "/assets/globals-D41WzvyZ.css";
73
+ function cn(...inputs) {
74
+ return twMerge(clsx(inputs));
75
+ }
76
+ v.union(
77
+ v.literal("admin"),
78
+ v.literal("editor"),
79
+ v.literal("author"),
80
+ v.literal("viewer")
81
+ );
82
+ const resourceValidator = v.union(
83
+ v.literal("contentTypes"),
84
+ v.literal("contentEntries"),
85
+ v.literal("mediaItems"),
86
+ v.literal("settings")
87
+ );
88
+ const actionValidator = v.union(
89
+ v.literal("create"),
90
+ v.literal("read"),
91
+ v.literal("update"),
92
+ v.literal("delete"),
93
+ v.literal("publish"),
94
+ v.literal("unpublish"),
95
+ v.literal("restore"),
96
+ v.literal("manage"),
97
+ v.literal("move")
98
+ );
99
+ v.object({
100
+ resource: resourceValidator,
101
+ action: actionValidator,
102
+ scope: v.optional(v.union(v.literal("all"), v.literal("own")))
103
+ });
104
+ function fullCrud(resource, scope = "all") {
105
+ return [
106
+ { resource, action: "create", scope },
107
+ { resource, action: "read", scope },
108
+ { resource, action: "update", scope },
109
+ { resource, action: "delete", scope }
110
+ ];
111
+ }
112
+ function readOnly(resource, scope = "all") {
113
+ return [{ resource, action: "read", scope }];
114
+ }
115
+ function publishPermissions(scope = "all") {
116
+ return [
117
+ { resource: "contentEntries", action: "publish", scope },
118
+ { resource: "contentEntries", action: "unpublish", scope }
119
+ ];
120
+ }
121
+ const ADMIN_ROLE = {
122
+ name: "admin",
123
+ displayName: "Administrator",
124
+ description: "Full access to all CMS features including settings and content type management",
125
+ isSystem: true,
126
+ permissions: [
127
+ // Content types - full management
128
+ ...fullCrud("contentTypes"),
129
+ // Content entries - full CRUD + publish
130
+ ...fullCrud("contentEntries"),
131
+ ...publishPermissions(),
132
+ { resource: "contentEntries", action: "restore" },
133
+ // Media - full management
134
+ ...fullCrud("mediaItems"),
135
+ // Settings - full access
136
+ { resource: "settings", action: "manage" },
137
+ ...readOnly("settings")
138
+ ]
139
+ };
140
+ const EDITOR_ROLE = {
141
+ name: "editor",
142
+ displayName: "Editor",
143
+ description: "Can manage all content and media, but cannot modify settings or content types",
144
+ isSystem: true,
145
+ permissions: [
146
+ // Content types - read only
147
+ ...readOnly("contentTypes"),
148
+ // Content entries - full CRUD + publish
149
+ ...fullCrud("contentEntries"),
150
+ ...publishPermissions(),
151
+ { resource: "contentEntries", action: "restore" },
152
+ // Media - full management
153
+ ...fullCrud("mediaItems")
154
+ ]
155
+ };
156
+ const AUTHOR_ROLE = {
157
+ name: "author",
158
+ displayName: "Author",
159
+ description: "Can create and manage own content and media",
160
+ isSystem: true,
161
+ permissions: [
162
+ // Content types - read only
163
+ ...readOnly("contentTypes"),
164
+ // Content entries - own content only
165
+ { resource: "contentEntries", action: "create" },
166
+ { resource: "contentEntries", action: "read", scope: "own" },
167
+ { resource: "contentEntries", action: "update", scope: "own" },
168
+ { resource: "contentEntries", action: "delete", scope: "own" },
169
+ // Authors can publish/unpublish their own content
170
+ { resource: "contentEntries", action: "publish", scope: "own" },
171
+ { resource: "contentEntries", action: "unpublish", scope: "own" },
172
+ // Media - can create and manage own, read all (for embedding)
173
+ { resource: "mediaItems", action: "create" },
174
+ { resource: "mediaItems", action: "read", scope: "all" },
175
+ // Can read all for embedding
176
+ { resource: "mediaItems", action: "update", scope: "own" },
177
+ { resource: "mediaItems", action: "delete", scope: "own" }
178
+ ]
179
+ };
180
+ const VIEWER_ROLE = {
181
+ name: "viewer",
182
+ displayName: "Viewer",
183
+ description: "Read-only access to published content and media",
184
+ isSystem: true,
185
+ permissions: [
186
+ // Content types - read only
187
+ ...readOnly("contentTypes"),
188
+ // Content entries - read published only (scope: "all" means all published)
189
+ ...readOnly("contentEntries"),
190
+ // Media - read only
191
+ ...readOnly("mediaItems")
192
+ ]
193
+ };
194
+ const DEFAULT_ROLES = {
195
+ admin: ADMIN_ROLE,
196
+ editor: EDITOR_ROLE,
197
+ author: AUTHOR_ROLE,
198
+ viewer: VIEWER_ROLE
199
+ };
200
+ function permissionMatches(granted, requested) {
201
+ if (granted.resource !== requested.resource || granted.action !== requested.action) {
202
+ return false;
203
+ }
204
+ const grantedScope = granted.scope ?? "all";
205
+ const requestedScope = requested.scope ?? "all";
206
+ if (grantedScope === "all") {
207
+ return true;
208
+ }
209
+ return requestedScope === "own";
210
+ }
211
+ function hasPermission(roleName, permission, customRoles) {
212
+ const role = DEFAULT_ROLES[roleName] ?? customRoles?.[roleName];
213
+ if (!role) {
214
+ return false;
215
+ }
216
+ return role.permissions.some((p) => permissionMatches(p, permission));
217
+ }
218
+ function getRolePermissions(roleName, customRoles) {
219
+ const role = DEFAULT_ROLES[roleName] ?? customRoles?.[roleName];
220
+ return role?.permissions ?? [];
221
+ }
222
+ function getRole(roleName, customRoles) {
223
+ return DEFAULT_ROLES[roleName] ?? customRoles?.[roleName];
224
+ }
225
+ function getResourcePermissions(roleName, resource, customRoles) {
226
+ return getRolePermissions(roleName, customRoles).filter(
227
+ (p) => p.resource === resource
228
+ );
229
+ }
230
+ function canAccessResource(roleName, resource, customRoles) {
231
+ return getResourcePermissions(roleName, resource, customRoles).length > 0;
232
+ }
233
+ const AuthContext = reactExports.createContext(null);
234
+ function AuthProvider({
235
+ children,
236
+ getUser,
237
+ getUserRole,
238
+ onLogout,
239
+ autoRedirectToLogin = false,
240
+ loginUrl = "/login"
241
+ }) {
242
+ const [user, setUser] = reactExports.useState(null);
243
+ const [role, setRole] = reactExports.useState(null);
244
+ const [authState, setAuthState] = reactExports.useState("loading");
245
+ const [error, setError] = reactExports.useState(null);
246
+ const loadAuth = reactExports.useCallback(async () => {
247
+ setAuthState("loading");
248
+ setError(null);
249
+ try {
250
+ const currentUser = await getUser();
251
+ if (!currentUser) {
252
+ setUser(null);
253
+ setRole(null);
254
+ setAuthState("unauthenticated");
255
+ if (autoRedirectToLogin && typeof window !== "undefined") {
256
+ window.location.href = loginUrl;
257
+ }
258
+ return;
259
+ }
260
+ const userRole = await getUserRole({ userId: currentUser.id });
261
+ setUser(currentUser);
262
+ setRole(userRole);
263
+ setAuthState("authenticated");
264
+ } catch (err) {
265
+ console.error("Authentication error:", err);
266
+ setUser(null);
267
+ setRole(null);
268
+ setError(err instanceof Error ? err.message : "Authentication failed");
269
+ setAuthState("error");
270
+ }
271
+ }, [getUser, getUserRole, autoRedirectToLogin, loginUrl]);
272
+ reactExports.useEffect(() => {
273
+ loadAuth();
274
+ }, [loadAuth]);
275
+ const checkPermission = reactExports.useCallback(
276
+ (permission) => {
277
+ if (!role) {
278
+ return false;
279
+ }
280
+ return hasPermission(role, permission);
281
+ },
282
+ [role]
283
+ );
284
+ const logout = reactExports.useCallback(async () => {
285
+ try {
286
+ if (onLogout) {
287
+ await onLogout();
288
+ }
289
+ setUser(null);
290
+ setRole(null);
291
+ setAuthState("unauthenticated");
292
+ if (autoRedirectToLogin && typeof window !== "undefined") {
293
+ window.location.href = loginUrl;
294
+ }
295
+ } catch (err) {
296
+ console.error("Logout error:", err);
297
+ setError(err instanceof Error ? err.message : "Logout failed");
298
+ }
299
+ }, [onLogout, autoRedirectToLogin, loginUrl]);
300
+ const refresh = reactExports.useCallback(async () => {
301
+ await loadAuth();
302
+ }, [loadAuth]);
303
+ const value = {
304
+ user,
305
+ role,
306
+ authState,
307
+ isLoading: authState === "loading",
308
+ isAuthenticated: authState === "authenticated",
309
+ error,
310
+ checkPermission,
311
+ logout,
312
+ refresh
313
+ };
314
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(AuthContext.Provider, { value, children });
315
+ }
316
+ function useAuth() {
317
+ const context = reactExports.useContext(AuthContext);
318
+ if (!context) {
319
+ throw new Error("useAuth must be used within an AuthProvider");
320
+ }
321
+ return context;
322
+ }
323
+ const ThemeContext = reactExports.createContext(null);
324
+ const STORAGE_KEY = "convex-cms-theme";
325
+ function getSystemTheme() {
326
+ if (typeof window === "undefined") return "light";
327
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
328
+ }
329
+ function getStoredTheme() {
330
+ if (typeof window === "undefined") return "system";
331
+ const stored = localStorage.getItem(STORAGE_KEY);
332
+ if (stored === "light" || stored === "dark" || stored === "system") {
333
+ return stored;
334
+ }
335
+ return "system";
336
+ }
337
+ function ThemeProvider({ children }) {
338
+ const [theme, setThemeState] = reactExports.useState(() => getStoredTheme());
339
+ const [resolvedTheme, setResolvedTheme] = reactExports.useState(() => {
340
+ const stored = getStoredTheme();
341
+ return stored === "system" ? getSystemTheme() : stored;
342
+ });
343
+ const applyTheme = reactExports.useCallback((newTheme) => {
344
+ const resolved = newTheme === "system" ? getSystemTheme() : newTheme;
345
+ setResolvedTheme(resolved);
346
+ const root = document.documentElement;
347
+ root.classList.remove("light", "dark");
348
+ root.classList.add(resolved);
349
+ }, []);
350
+ const setTheme = reactExports.useCallback(
351
+ (newTheme) => {
352
+ setThemeState(newTheme);
353
+ localStorage.setItem(STORAGE_KEY, newTheme);
354
+ applyTheme(newTheme);
355
+ },
356
+ [applyTheme]
357
+ );
358
+ reactExports.useEffect(() => {
359
+ applyTheme(theme);
360
+ }, [theme, applyTheme]);
361
+ reactExports.useEffect(() => {
362
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
363
+ const handleChange = () => {
364
+ if (theme === "system") {
365
+ applyTheme("system");
366
+ }
367
+ };
368
+ mediaQuery.addEventListener("change", handleChange);
369
+ return () => mediaQuery.removeEventListener("change", handleChange);
370
+ }, [theme, applyTheme]);
371
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ThemeContext.Provider, { value: { theme, resolvedTheme, setTheme }, children });
372
+ }
373
+ function useTheme() {
374
+ const context = reactExports.useContext(ThemeContext);
375
+ if (!context) {
376
+ throw new Error("useTheme must be used within a ThemeProvider");
377
+ }
378
+ return context;
379
+ }
380
+ const navItemSchema = object({
381
+ id: string(),
382
+ path: string(),
383
+ label: string(),
384
+ icon: string(),
385
+ visible: boolean().default(true),
386
+ section: _enum(["main", "config"]).default("main"),
387
+ badge: string().optional(),
388
+ exact: boolean().optional()
389
+ });
390
+ const brandingSchema = object({
391
+ appName: string().default("Convex CMS"),
392
+ logo: string().optional(),
393
+ favicon: string().optional()
394
+ });
395
+ const layoutSchema = object({
396
+ sidebarWidth: number().min(200).max(400).default(256),
397
+ sidebarCollapsible: boolean().default(false)
398
+ });
399
+ const navigationSchema = object({
400
+ showDashboard: boolean().default(true),
401
+ showContent: boolean().default(true),
402
+ showMedia: boolean().default(true),
403
+ showTaxonomies: boolean().default(true),
404
+ showContentTypes: boolean().default(true),
405
+ showTrash: boolean().default(true),
406
+ showSettings: boolean().default(true),
407
+ customItems: array(navItemSchema).default([])
408
+ });
409
+ const themeSchema = object({
410
+ mode: _enum(["light", "dark", "system"]).default("system"),
411
+ allowModeSwitch: boolean().default(true),
412
+ tokens: record(string(), string()).optional()
413
+ });
414
+ const adminConfigSchema = object({
415
+ branding: brandingSchema.default(() => brandingSchema.parse({})),
416
+ layout: layoutSchema.default(() => layoutSchema.parse({})),
417
+ navigation: navigationSchema.default(() => navigationSchema.parse({})),
418
+ theme: themeSchema.default(() => themeSchema.parse({}))
419
+ });
420
+ const DEFAULT_NAV_ITEMS = [
421
+ {
422
+ id: "dashboard",
423
+ path: "/",
424
+ label: "Dashboard",
425
+ icon: "LayoutDashboard",
426
+ section: "main",
427
+ exact: true
428
+ },
429
+ { id: "content", path: "/content", label: "Content", icon: "FileText", section: "main" },
430
+ { id: "media", path: "/media", label: "Media", icon: "Image", section: "main" },
431
+ { id: "taxonomies", path: "/taxonomies", label: "Taxonomies", icon: "Tags", section: "main" },
432
+ {
433
+ id: "content-types",
434
+ path: "/content-types",
435
+ label: "Content Types",
436
+ icon: "Layers",
437
+ section: "config"
438
+ },
439
+ { id: "trash", path: "/trash", label: "Trash", icon: "Trash2", section: "config" },
440
+ { id: "settings", path: "/settings", label: "Settings", icon: "Settings", section: "config" }
441
+ ];
442
+ function resolveAdminConfig(input) {
443
+ return adminConfigSchema.parse(input ?? {});
444
+ }
445
+ function getVisibleNavItems(config) {
446
+ const visibilityMap = {
447
+ dashboard: config.navigation.showDashboard,
448
+ content: config.navigation.showContent,
449
+ media: config.navigation.showMedia,
450
+ taxonomies: config.navigation.showTaxonomies,
451
+ "content-types": config.navigation.showContentTypes,
452
+ trash: config.navigation.showTrash,
453
+ settings: config.navigation.showSettings
454
+ };
455
+ const filtered = DEFAULT_NAV_ITEMS.filter((item) => visibilityMap[item.id] !== false);
456
+ const allItems = [...filtered, ...config.navigation.customItems.filter((i) => i.visible !== false)];
457
+ return {
458
+ main: allItems.filter((i) => i.section === "main"),
459
+ config: allItems.filter((i) => i.section === "config")
460
+ };
461
+ }
462
+ const AdminConfigContext = reactExports.createContext(null);
463
+ function AdminConfigProvider({
464
+ config,
465
+ children
466
+ }) {
467
+ const navItems = getVisibleNavItems(config);
468
+ const value = { ...config, navItems };
469
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(AdminConfigContext.Provider, { value, children });
470
+ }
471
+ function useAdminConfig() {
472
+ const config = reactExports.useContext(AdminConfigContext);
473
+ if (!config) {
474
+ throw new Error("useAdminConfig must be used within AdminConfigProvider");
475
+ }
476
+ return config;
477
+ }
478
+ const api = anyApi;
479
+ componentsGeneric();
480
+ const SettingsConfigContext = reactExports.createContext(null);
481
+ function SettingsConfigProvider({
482
+ baseConfig,
483
+ children
484
+ }) {
485
+ const settings = useQuery(api.admin.getSettings);
486
+ const mergedConfig = reactExports.useMemo(() => {
487
+ if (!settings) return baseConfig;
488
+ return {
489
+ ...baseConfig,
490
+ navigation: {
491
+ ...baseConfig.navigation,
492
+ showMedia: baseConfig.navigation.showMedia && settings.features.mediaManagement
493
+ }
494
+ };
495
+ }, [baseConfig, settings]);
496
+ const contextValue = reactExports.useMemo(
497
+ () => ({ baseConfig, settings }),
498
+ [baseConfig, settings]
499
+ );
500
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsConfigContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntimeExports.jsx(AdminConfigProvider, { config: mergedConfig, children }) });
501
+ }
502
+ function useSettingsConfig() {
503
+ const ctx = reactExports.useContext(SettingsConfigContext);
504
+ if (!ctx) {
505
+ throw new Error("useSettingsConfig must be used within SettingsConfigProvider");
506
+ }
507
+ return ctx;
508
+ }
509
+ const BreadcrumbContext = reactExports.createContext(null);
510
+ function BreadcrumbProvider({ children }) {
511
+ const [overrides, setOverrides] = reactExports.useState(/* @__PURE__ */ new Map());
512
+ const setOverride = reactExports.useCallback((path, label) => {
513
+ setOverrides((prev) => {
514
+ const next = new Map(prev);
515
+ next.set(path, label);
516
+ return next;
517
+ });
518
+ }, []);
519
+ const clearOverride = reactExports.useCallback((path) => {
520
+ setOverrides((prev) => {
521
+ const next = new Map(prev);
522
+ next.delete(path);
523
+ return next;
524
+ });
525
+ }, []);
526
+ const value = reactExports.useMemo(
527
+ () => ({ overrides, setOverride, clearOverride }),
528
+ [overrides, setOverride, clearOverride]
529
+ );
530
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(BreadcrumbContext.Provider, { value, children });
531
+ }
532
+ function useBreadcrumbContext() {
533
+ const context = reactExports.useContext(BreadcrumbContext);
534
+ if (!context) {
535
+ throw new Error("useBreadcrumbContext must be used within a BreadcrumbProvider");
536
+ }
537
+ return context;
538
+ }
539
+ const iconRegistry = {
540
+ LayoutDashboard,
541
+ FileText,
542
+ Image: Image$1,
543
+ Layers,
544
+ Tags,
545
+ FileCode,
546
+ Settings,
547
+ Trash2,
548
+ HelpCircle: CircleQuestionMark,
549
+ Home: House,
550
+ User,
551
+ Bell,
552
+ Lock,
553
+ Globe,
554
+ Calendar,
555
+ Clock,
556
+ Link: Link$1,
557
+ Hash,
558
+ ToggleLeft,
559
+ ChevronDown,
560
+ CheckSquare: SquareCheckBig,
561
+ Braces,
562
+ Folder,
563
+ MapPin,
564
+ DollarSign,
565
+ Mail,
566
+ Phone,
567
+ Package,
568
+ Star,
569
+ Heart,
570
+ Flag,
571
+ Bookmark,
572
+ Archive,
573
+ Edit: SquarePen,
574
+ Eye,
575
+ AlertCircle: CircleAlert
576
+ };
577
+ function Icon({
578
+ name,
579
+ className = "size-5"
580
+ }) {
581
+ const IconComponent = iconRegistry[name];
582
+ if (!IconComponent) {
583
+ return null;
584
+ }
585
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(IconComponent, { className });
586
+ }
587
+ const Collapsible = Root$1;
588
+ const CollapsibleTrigger = CollapsibleTrigger$1;
589
+ const CollapsibleContent = CollapsibleContent$1;
590
+ function Dialog({
591
+ ...props
592
+ }) {
593
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Root$3, { "data-slot": "dialog", ...props });
594
+ }
595
+ function DialogPortal({
596
+ ...props
597
+ }) {
598
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal$2, { "data-slot": "dialog-portal", ...props });
599
+ }
600
+ function DialogOverlay({
601
+ className,
602
+ ...props
603
+ }) {
604
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
605
+ Overlay,
606
+ {
607
+ "data-slot": "dialog-overlay",
608
+ className: cn(
609
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
610
+ className
611
+ ),
612
+ ...props
613
+ }
614
+ );
615
+ }
616
+ function DialogContent({
617
+ className,
618
+ children,
619
+ showCloseButton = true,
620
+ ...props
621
+ }) {
622
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
623
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DialogOverlay, {}),
624
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
625
+ Content,
626
+ {
627
+ "data-slot": "dialog-content",
628
+ className: cn(
629
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
630
+ className
631
+ ),
632
+ ...props,
633
+ children: [
634
+ children,
635
+ showCloseButton && /* @__PURE__ */ jsxRuntimeExports.jsxs(
636
+ Close,
637
+ {
638
+ "data-slot": "dialog-close",
639
+ className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
640
+ children: [
641
+ /* @__PURE__ */ jsxRuntimeExports.jsx(X, {}),
642
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Close" })
643
+ ]
644
+ }
645
+ )
646
+ ]
647
+ }
648
+ )
649
+ ] });
650
+ }
651
+ function DialogHeader({ className, ...props }) {
652
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
653
+ "div",
654
+ {
655
+ "data-slot": "dialog-header",
656
+ className: cn("flex flex-col gap-2 text-center sm:text-left", className),
657
+ ...props
658
+ }
659
+ );
660
+ }
661
+ function DialogFooter({ className, ...props }) {
662
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
663
+ "div",
664
+ {
665
+ "data-slot": "dialog-footer",
666
+ className: cn(
667
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
668
+ className
669
+ ),
670
+ ...props
671
+ }
672
+ );
673
+ }
674
+ function DialogTitle({
675
+ className,
676
+ ...props
677
+ }) {
678
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
679
+ Title,
680
+ {
681
+ "data-slot": "dialog-title",
682
+ className: cn("text-lg leading-none font-semibold", className),
683
+ ...props
684
+ }
685
+ );
686
+ }
687
+ function DialogDescription({
688
+ className,
689
+ ...props
690
+ }) {
691
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
692
+ Description,
693
+ {
694
+ "data-slot": "dialog-description",
695
+ className: cn("text-muted-foreground text-sm", className),
696
+ ...props
697
+ }
698
+ );
699
+ }
700
+ const buttonVariants = cva(
701
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
702
+ {
703
+ variants: {
704
+ variant: {
705
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
706
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
707
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
708
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
709
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
710
+ link: "text-primary underline-offset-4 hover:underline"
711
+ },
712
+ size: {
713
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
714
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
715
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
716
+ icon: "size-9",
717
+ "icon-sm": "size-8",
718
+ "icon-lg": "size-10"
719
+ }
720
+ },
721
+ defaultVariants: {
722
+ variant: "default",
723
+ size: "default"
724
+ }
725
+ }
726
+ );
727
+ function Button({
728
+ className,
729
+ variant = "default",
730
+ size = "default",
731
+ asChild = false,
732
+ ...props
733
+ }) {
734
+ const Comp = asChild ? Slot : "button";
735
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
736
+ Comp,
737
+ {
738
+ "data-slot": "button",
739
+ "data-variant": variant,
740
+ "data-size": size,
741
+ className: cn(buttonVariants({ variant, size, className })),
742
+ ...props
743
+ }
744
+ );
745
+ }
746
+ const motion = {
747
+ fast: "duration-100 ease-out"
748
+ };
749
+ const variantMap = {
750
+ primary: "default",
751
+ secondary: "secondary",
752
+ danger: "destructive",
753
+ ghost: "ghost",
754
+ outline: "outline",
755
+ link: "link",
756
+ success: "default",
757
+ warning: "default"
758
+ };
759
+ const customVariantClasses = {
760
+ success: "bg-emerald-600 text-white hover:bg-emerald-700 focus-visible:ring-emerald-500",
761
+ warning: "bg-amber-500 text-white hover:bg-amber-600 focus-visible:ring-amber-500"
762
+ };
763
+ const LoadingSpinner = () => /* @__PURE__ */ jsxRuntimeExports.jsxs(
764
+ "svg",
765
+ {
766
+ className: "size-4 animate-spin",
767
+ xmlns: "http://www.w3.org/2000/svg",
768
+ fill: "none",
769
+ viewBox: "0 0 24 24",
770
+ children: [
771
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
772
+ "circle",
773
+ {
774
+ className: "opacity-25",
775
+ cx: "12",
776
+ cy: "12",
777
+ r: "10",
778
+ stroke: "currentColor",
779
+ strokeWidth: "4"
780
+ }
781
+ ),
782
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
783
+ "path",
784
+ {
785
+ className: "opacity-75",
786
+ fill: "currentColor",
787
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
788
+ }
789
+ )
790
+ ]
791
+ }
792
+ );
793
+ function CmsButton({
794
+ variant = "primary",
795
+ loading,
796
+ disabled,
797
+ children,
798
+ className,
799
+ asChild,
800
+ ...props
801
+ }) {
802
+ const mappedVariant = variantMap[variant];
803
+ const customClass = customVariantClasses[variant];
804
+ if (asChild) {
805
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
806
+ Button,
807
+ {
808
+ variant: mappedVariant,
809
+ disabled: disabled || loading,
810
+ className: cn(motion.fast, customClass, className),
811
+ asChild: true,
812
+ ...props,
813
+ children
814
+ }
815
+ );
816
+ }
817
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
818
+ Button,
819
+ {
820
+ variant: mappedVariant,
821
+ disabled: disabled || loading,
822
+ className: cn(motion.fast, customClass, className),
823
+ ...props,
824
+ children: [
825
+ loading && /* @__PURE__ */ jsxRuntimeExports.jsx(LoadingSpinner, {}),
826
+ children
827
+ ]
828
+ }
829
+ );
830
+ }
831
+ const sizeClasses = {
832
+ sm: "max-w-sm",
833
+ md: "max-w-md",
834
+ lg: "max-w-lg",
835
+ xl: "max-w-xl",
836
+ "2xl": "max-w-2xl"
837
+ };
838
+ function CmsDialog({
839
+ open,
840
+ onOpenChange,
841
+ title,
842
+ description,
843
+ children,
844
+ footer,
845
+ size = "md",
846
+ className
847
+ }) {
848
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
849
+ DialogContent,
850
+ {
851
+ className: cn(
852
+ "flex max-h-[85vh] flex-col overflow-hidden",
853
+ sizeClasses[size],
854
+ className
855
+ ),
856
+ children: [
857
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { className: "shrink-0", children: [
858
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: title }),
859
+ description && /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: description })
860
+ ] }),
861
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-0 flex-1 py-4 scrollbar-none", children }),
862
+ footer && /* @__PURE__ */ jsxRuntimeExports.jsx(DialogFooter, { className: "shrink-0 border-t pt-4", children: footer })
863
+ ]
864
+ }
865
+ ) });
866
+ }
867
+ function CmsConfirmDialog({
868
+ open,
869
+ onOpenChange,
870
+ title,
871
+ description,
872
+ confirmLabel = "Confirm",
873
+ cancelLabel = "Cancel",
874
+ onConfirm,
875
+ onCancel,
876
+ variant = "default",
877
+ loading,
878
+ isLoading,
879
+ error
880
+ }) {
881
+ const isLoadingState = loading ?? isLoading ?? false;
882
+ const handleCancel = () => {
883
+ onCancel?.();
884
+ onOpenChange(false);
885
+ };
886
+ const handleConfirm = () => {
887
+ onConfirm();
888
+ };
889
+ const getButtonVariant = () => {
890
+ if (variant === "danger") return "danger";
891
+ if (variant === "warning") return "warning";
892
+ return "primary";
893
+ };
894
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
895
+ CmsDialog,
896
+ {
897
+ open,
898
+ onOpenChange,
899
+ title,
900
+ size: "sm",
901
+ footer: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
902
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { variant: "outline", onClick: handleCancel, disabled: isLoadingState, children: cancelLabel }),
903
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
904
+ CmsButton,
905
+ {
906
+ variant: getButtonVariant(),
907
+ onClick: handleConfirm,
908
+ loading: isLoadingState,
909
+ children: confirmLabel
910
+ }
911
+ )
912
+ ] }),
913
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
914
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground", children: description }),
915
+ error && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-destructive", children: error })
916
+ ] })
917
+ }
918
+ );
919
+ }
920
+ function Input({ className, type, ...props }) {
921
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
922
+ "input",
923
+ {
924
+ type,
925
+ "data-slot": "input",
926
+ className: cn(
927
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
928
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
929
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
930
+ className
931
+ ),
932
+ ...props
933
+ }
934
+ );
935
+ }
936
+ function Label({
937
+ className,
938
+ ...props
939
+ }) {
940
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
941
+ Root$2,
942
+ {
943
+ "data-slot": "label",
944
+ className: cn(
945
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
946
+ className
947
+ ),
948
+ ...props
949
+ }
950
+ );
951
+ }
952
+ function Textarea({ className, ...props }) {
953
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
954
+ "textarea",
955
+ {
956
+ "data-slot": "textarea",
957
+ className: cn(
958
+ "border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
959
+ className
960
+ ),
961
+ ...props
962
+ }
963
+ );
964
+ }
965
+ function Checkbox({
966
+ className,
967
+ ...props
968
+ }) {
969
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
970
+ Checkbox$1,
971
+ {
972
+ "data-slot": "checkbox",
973
+ className: cn(
974
+ "peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
975
+ className
976
+ ),
977
+ ...props,
978
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
979
+ CheckboxIndicator,
980
+ {
981
+ "data-slot": "checkbox-indicator",
982
+ className: "grid place-content-center text-current transition-none",
983
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5" })
984
+ }
985
+ )
986
+ }
987
+ );
988
+ }
989
+ function Select({
990
+ ...props
991
+ }) {
992
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$2, { "data-slot": "select", ...props });
993
+ }
994
+ function SelectValue({
995
+ ...props
996
+ }) {
997
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Value, { "data-slot": "select-value", ...props });
998
+ }
999
+ function SelectTrigger({
1000
+ className,
1001
+ size = "default",
1002
+ children,
1003
+ ...props
1004
+ }) {
1005
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1006
+ Trigger$2,
1007
+ {
1008
+ "data-slot": "select-trigger",
1009
+ "data-size": size,
1010
+ className: cn(
1011
+ "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1012
+ className
1013
+ ),
1014
+ ...props,
1015
+ children: [
1016
+ children,
1017
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Icon$1, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 opacity-50" }) })
1018
+ ]
1019
+ }
1020
+ );
1021
+ }
1022
+ function SelectContent({
1023
+ className,
1024
+ children,
1025
+ position = "item-aligned",
1026
+ align = "center",
1027
+ ...props
1028
+ }) {
1029
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
1030
+ Content2$2,
1031
+ {
1032
+ "data-slot": "select-content",
1033
+ className: cn(
1034
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
1035
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
1036
+ className
1037
+ ),
1038
+ position,
1039
+ align,
1040
+ ...props,
1041
+ children: [
1042
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectScrollUpButton, {}),
1043
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1044
+ Viewport,
1045
+ {
1046
+ className: cn(
1047
+ "p-1",
1048
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
1049
+ ),
1050
+ children
1051
+ }
1052
+ ),
1053
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectScrollDownButton, {})
1054
+ ]
1055
+ }
1056
+ ) });
1057
+ }
1058
+ function SelectItem({
1059
+ className,
1060
+ children,
1061
+ ...props
1062
+ }) {
1063
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1064
+ Item,
1065
+ {
1066
+ "data-slot": "select-item",
1067
+ className: cn(
1068
+ "focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
1069
+ className
1070
+ ),
1071
+ ...props,
1072
+ children: [
1073
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1074
+ "span",
1075
+ {
1076
+ "data-slot": "select-item-indicator",
1077
+ className: "absolute right-2 flex size-3.5 items-center justify-center",
1078
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ItemIndicator, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-4" }) })
1079
+ }
1080
+ ),
1081
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ItemText, { children })
1082
+ ]
1083
+ }
1084
+ );
1085
+ }
1086
+ function SelectScrollUpButton({
1087
+ className,
1088
+ ...props
1089
+ }) {
1090
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
1091
+ ScrollUpButton,
1092
+ {
1093
+ "data-slot": "select-scroll-up-button",
1094
+ className: cn(
1095
+ "flex cursor-default items-center justify-center py-1",
1096
+ className
1097
+ ),
1098
+ ...props,
1099
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "size-4" })
1100
+ }
1101
+ );
1102
+ }
1103
+ function SelectScrollDownButton({
1104
+ className,
1105
+ ...props
1106
+ }) {
1107
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
1108
+ ScrollDownButton,
1109
+ {
1110
+ "data-slot": "select-scroll-down-button",
1111
+ className: cn(
1112
+ "flex cursor-default items-center justify-center py-1",
1113
+ className
1114
+ ),
1115
+ ...props,
1116
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" })
1117
+ }
1118
+ );
1119
+ }
1120
+ function BreakingChangesWarningDialog({
1121
+ isOpen,
1122
+ onClose,
1123
+ breakingChanges,
1124
+ onForceUpdate,
1125
+ onCancel,
1126
+ isLoading
1127
+ }) {
1128
+ const handleCancel = () => {
1129
+ onCancel();
1130
+ onClose();
1131
+ };
1132
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
1133
+ CmsDialog,
1134
+ {
1135
+ open: isOpen,
1136
+ onOpenChange: (open) => !open && !isLoading && handleCancel(),
1137
+ title: "Breaking Changes Detected",
1138
+ size: "lg",
1139
+ footer: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1140
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { variant: "outline", onClick: handleCancel, disabled: isLoading, children: "Cancel" }),
1141
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { variant: "danger", onClick: onForceUpdate, loading: isLoading, children: "Force Update" })
1142
+ ] }),
1143
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
1144
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3 rounded-lg border border-amber-200 bg-amber-50 p-3", children: [
1145
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "mt-0.5 size-5 shrink-0 text-amber-600" }),
1146
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
1147
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-amber-800", children: "These changes may affect existing content" }),
1148
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-amber-700", children: "The following changes could cause data loss or validation errors for existing entries. Review carefully before proceeding." })
1149
+ ] })
1150
+ ] }),
1151
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1152
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-medium text-foreground", children: [
1153
+ breakingChanges.length,
1154
+ " breaking change",
1155
+ breakingChanges.length !== 1 ? "s" : "",
1156
+ " detected:"
1157
+ ] }),
1158
+ /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "space-y-2", children: breakingChanges.map((change, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
1159
+ "li",
1160
+ {
1161
+ className: "flex items-start gap-2 rounded-md border bg-muted/30 px-3 py-2 text-sm",
1162
+ children: [
1163
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mt-0.5 size-1.5 shrink-0 rounded-full bg-amber-500" }),
1164
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: change })
1165
+ ]
1166
+ },
1167
+ index
1168
+ )) })
1169
+ ] }),
1170
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: 'Click "Force Update" to apply these changes anyway, or "Cancel" to go back and modify your changes.' })
1171
+ ] })
1172
+ }
1173
+ );
1174
+ }
1175
+ const FIELD_TYPE_INFO = {
1176
+ text: {
1177
+ label: "Text",
1178
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(TextAlignStart, { className: "size-4" }),
1179
+ description: "Single line text input"
1180
+ },
1181
+ richText: {
1182
+ label: "Rich Text",
1183
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FileType, { className: "size-4" }),
1184
+ description: "Multi-line formatted text"
1185
+ },
1186
+ number: {
1187
+ label: "Number",
1188
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Hash, { className: "size-4" }),
1189
+ description: "Numeric value"
1190
+ },
1191
+ boolean: {
1192
+ label: "Boolean",
1193
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(ToggleLeft, { className: "size-4" }),
1194
+ description: "True/false toggle"
1195
+ },
1196
+ date: {
1197
+ label: "Date",
1198
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "size-4" }),
1199
+ description: "Date picker"
1200
+ },
1201
+ datetime: {
1202
+ label: "Date & Time",
1203
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "size-4" }),
1204
+ description: "Date and time picker"
1205
+ },
1206
+ reference: {
1207
+ label: "Reference",
1208
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Link2, { className: "size-4" }),
1209
+ description: "Link to another content entry"
1210
+ },
1211
+ media: {
1212
+ label: "Media",
1213
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Image$1, { className: "size-4" }),
1214
+ description: "Image, video, or file"
1215
+ },
1216
+ json: {
1217
+ label: "JSON",
1218
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Braces, { className: "size-4" }),
1219
+ description: "Custom JSON data"
1220
+ },
1221
+ select: {
1222
+ label: "Select",
1223
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" }),
1224
+ description: "Dropdown selection"
1225
+ },
1226
+ multiSelect: {
1227
+ label: "Multi-Select",
1228
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(List, { className: "size-4" }),
1229
+ description: "Multiple selections"
1230
+ },
1231
+ tags: {
1232
+ label: "Tags",
1233
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Tag, { className: "size-4" }),
1234
+ description: "Free-form tag list"
1235
+ },
1236
+ category: {
1237
+ label: "Category",
1238
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-4" }),
1239
+ description: "Taxonomy category selection"
1240
+ }
1241
+ };
1242
+ function generateMachineName(displayName) {
1243
+ return displayName.toLowerCase().trim().replace(/[^a-z0-9\s]/g, "").replace(/\s+/g, "_").replace(/^[0-9]/, "_$&").slice(0, 64);
1244
+ }
1245
+ function isValidMachineName(name) {
1246
+ return /^[a-z][a-z0-9_]{0,63}$/.test(name);
1247
+ }
1248
+ function ContentTypeFormModal({
1249
+ isOpen,
1250
+ onClose,
1251
+ onCreated,
1252
+ onUpdated,
1253
+ contentType
1254
+ }) {
1255
+ const isEditing = !!contentType;
1256
+ const isCodeDefined = contentType?.source === "code";
1257
+ const isReadOnly = isCodeDefined;
1258
+ const [displayName, setDisplayName] = reactExports.useState("");
1259
+ const [machineName, setMachineName] = reactExports.useState("");
1260
+ const [machineNameManuallyEdited, setMachineNameManuallyEdited] = reactExports.useState(
1261
+ false
1262
+ );
1263
+ const [description, setDescription] = reactExports.useState("");
1264
+ const [singleton, setSingleton] = reactExports.useState(false);
1265
+ const [fields, setFields] = reactExports.useState([
1266
+ { name: "title", label: "Title", type: "text", required: true }
1267
+ ]);
1268
+ const [titleField, setTitleField] = reactExports.useState("title");
1269
+ const [slugField, setSlugField] = reactExports.useState("title");
1270
+ const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
1271
+ const [submitError, setSubmitError] = reactExports.useState(null);
1272
+ const [activeFieldIndex, setActiveFieldIndex] = reactExports.useState(null);
1273
+ const [showFieldEditor, setShowFieldEditor] = reactExports.useState(false);
1274
+ const [breakingChanges, setBreakingChanges] = reactExports.useState([]);
1275
+ const [showBreakingWarning, setShowBreakingWarning] = reactExports.useState(false);
1276
+ const [isForceUpdating, setIsForceUpdating] = reactExports.useState(false);
1277
+ const createContentType = useMutation(api.admin.createContentType);
1278
+ const updateContentType = useMutation(api.admin.updateContentType);
1279
+ reactExports.useEffect(() => {
1280
+ if (contentType && isOpen) {
1281
+ setDisplayName(contentType.displayName);
1282
+ setMachineName(contentType.name);
1283
+ setMachineNameManuallyEdited(true);
1284
+ setDescription(contentType.description || "");
1285
+ setSingleton(contentType.singleton || false);
1286
+ setFields(contentType.fields);
1287
+ setTitleField(contentType.titleField || "");
1288
+ setSlugField(contentType.slugField || "");
1289
+ }
1290
+ }, [contentType, isOpen]);
1291
+ const resetForm = reactExports.useCallback(() => {
1292
+ setDisplayName("");
1293
+ setMachineName("");
1294
+ setMachineNameManuallyEdited(false);
1295
+ setDescription("");
1296
+ setSingleton(false);
1297
+ setFields([
1298
+ { name: "title", label: "Title", type: "text", required: true }
1299
+ ]);
1300
+ setTitleField("title");
1301
+ setSlugField("title");
1302
+ setIsSubmitting(false);
1303
+ setSubmitError(null);
1304
+ setActiveFieldIndex(null);
1305
+ setShowFieldEditor(false);
1306
+ setBreakingChanges([]);
1307
+ setShowBreakingWarning(false);
1308
+ setIsForceUpdating(false);
1309
+ }, []);
1310
+ const handleDisplayNameChange = reactExports.useCallback(
1311
+ (value) => {
1312
+ setDisplayName(value);
1313
+ if (!machineNameManuallyEdited) {
1314
+ setMachineName(generateMachineName(value));
1315
+ }
1316
+ },
1317
+ [machineNameManuallyEdited]
1318
+ );
1319
+ const handleMachineNameChange = reactExports.useCallback((value) => {
1320
+ setMachineNameManuallyEdited(true);
1321
+ setMachineName(value.toLowerCase().replace(/[^a-z0-9_]/g, ""));
1322
+ }, []);
1323
+ const addField = reactExports.useCallback(() => {
1324
+ const newFieldName = `field_${fields.length + 1}`;
1325
+ setFields((prev) => [
1326
+ ...prev,
1327
+ {
1328
+ name: newFieldName,
1329
+ label: `Field ${prev.length + 1}`,
1330
+ type: "text",
1331
+ required: false
1332
+ }
1333
+ ]);
1334
+ setActiveFieldIndex(fields.length);
1335
+ setShowFieldEditor(true);
1336
+ }, [fields.length]);
1337
+ const removeField = reactExports.useCallback(
1338
+ (index) => {
1339
+ const fieldToRemove = fields[index];
1340
+ setFields((prev) => prev.filter((_, i) => i !== index));
1341
+ if (titleField === fieldToRemove.name) {
1342
+ const firstTextField = fields.find(
1343
+ (f, i) => i !== index && f.type === "text"
1344
+ );
1345
+ setTitleField(firstTextField?.name || "");
1346
+ }
1347
+ if (slugField === fieldToRemove.name) {
1348
+ const firstTextField = fields.find(
1349
+ (f, i) => i !== index && f.type === "text"
1350
+ );
1351
+ setSlugField(firstTextField?.name || "");
1352
+ }
1353
+ if (activeFieldIndex === index) {
1354
+ setActiveFieldIndex(null);
1355
+ setShowFieldEditor(false);
1356
+ } else if (activeFieldIndex !== null && activeFieldIndex > index) {
1357
+ setActiveFieldIndex(activeFieldIndex - 1);
1358
+ }
1359
+ },
1360
+ [fields, activeFieldIndex, titleField, slugField]
1361
+ );
1362
+ const updateField = reactExports.useCallback(
1363
+ (index, updates) => {
1364
+ setFields(
1365
+ (prev) => prev.map(
1366
+ (field, i) => i === index ? { ...field, ...updates } : field
1367
+ )
1368
+ );
1369
+ },
1370
+ []
1371
+ );
1372
+ const moveField = reactExports.useCallback((fromIndex, toIndex) => {
1373
+ setFields((prev) => {
1374
+ const newFields = [...prev];
1375
+ const [movedField] = newFields.splice(fromIndex, 1);
1376
+ newFields.splice(toIndex, 0, movedField);
1377
+ return newFields;
1378
+ });
1379
+ setActiveFieldIndex(toIndex);
1380
+ }, []);
1381
+ const validationErrors = reactExports.useMemo(() => {
1382
+ const errors = [];
1383
+ if (!displayName.trim()) {
1384
+ errors.push("Display name is required");
1385
+ }
1386
+ if (!machineName.trim()) {
1387
+ errors.push("System Name is required");
1388
+ } else if (!isValidMachineName(machineName)) {
1389
+ errors.push(
1390
+ "System Name must start with a letter and contain only lowercase letters, numbers, and underscores"
1391
+ );
1392
+ }
1393
+ if (fields.length === 0) {
1394
+ errors.push("At least one field is required");
1395
+ }
1396
+ const fieldNames = fields.map((f) => f.name);
1397
+ const duplicates = fieldNames.filter(
1398
+ (name, index) => fieldNames.indexOf(name) !== index
1399
+ );
1400
+ if (duplicates.length > 0) {
1401
+ errors.push(
1402
+ `Duplicate field names: ${[...new Set(duplicates)].join(", ")}`
1403
+ );
1404
+ }
1405
+ for (const field of fields) {
1406
+ if (!field.name.trim()) {
1407
+ errors.push(`Field "${field.label}" has an empty name`);
1408
+ } else if (!/^[a-z][a-z0-9_]{0,63}$/.test(field.name)) {
1409
+ errors.push(`Field "${field.name}" has an invalid name format`);
1410
+ }
1411
+ if (!field.label.trim()) {
1412
+ errors.push(`Field with name "${field.name}" has an empty label`);
1413
+ }
1414
+ if ((field.type === "select" || field.type === "multiSelect") && (!field.options?.options || field.options.options.length === 0)) {
1415
+ errors.push(
1416
+ `${field.type} field "${field.label}" requires at least one option`
1417
+ );
1418
+ }
1419
+ }
1420
+ return errors;
1421
+ }, [displayName, machineName, fields]);
1422
+ const textFields = reactExports.useMemo(() => fields.filter((f) => f.type === "text"), [
1423
+ fields
1424
+ ]);
1425
+ const parseBreakingChanges = (errorMessage) => {
1426
+ const lines = errorMessage.split("\n");
1427
+ return lines.filter((line) => line.trim().startsWith("-")).map((line) => line.trim().substring(2));
1428
+ };
1429
+ const handleSubmit = reactExports.useCallback(
1430
+ async (e, force = false) => {
1431
+ e.preventDefault();
1432
+ if (validationErrors.length > 0) {
1433
+ setSubmitError(validationErrors.join(". "));
1434
+ return;
1435
+ }
1436
+ setIsSubmitting(true);
1437
+ setSubmitError(null);
1438
+ try {
1439
+ if (isEditing && contentType) {
1440
+ const result = await updateContentType({
1441
+ id: contentType._id,
1442
+ displayName: displayName.trim(),
1443
+ description: description.trim() || void 0,
1444
+ fields,
1445
+ singleton,
1446
+ titleField: titleField || void 0,
1447
+ slugField: slugField || void 0,
1448
+ force
1449
+ });
1450
+ onUpdated?.(result);
1451
+ resetForm();
1452
+ onClose();
1453
+ } else {
1454
+ const result = await createContentType({
1455
+ name: machineName,
1456
+ displayName: displayName.trim(),
1457
+ description: description.trim() || void 0,
1458
+ fields,
1459
+ singleton,
1460
+ titleField: titleField || void 0,
1461
+ slugField: slugField || void 0
1462
+ });
1463
+ onCreated?.(result);
1464
+ resetForm();
1465
+ onClose();
1466
+ }
1467
+ } catch (error) {
1468
+ const message = error instanceof Error ? error.message : isEditing ? "Failed to update content type" : "Failed to create content type";
1469
+ if (isEditing && !force && message.includes("breaking change")) {
1470
+ const changes = parseBreakingChanges(message);
1471
+ setBreakingChanges(changes);
1472
+ setShowBreakingWarning(true);
1473
+ } else {
1474
+ setSubmitError(message);
1475
+ }
1476
+ } finally {
1477
+ setIsSubmitting(false);
1478
+ }
1479
+ },
1480
+ [
1481
+ validationErrors,
1482
+ isEditing,
1483
+ contentType,
1484
+ createContentType,
1485
+ updateContentType,
1486
+ machineName,
1487
+ displayName,
1488
+ description,
1489
+ fields,
1490
+ singleton,
1491
+ titleField,
1492
+ slugField,
1493
+ onCreated,
1494
+ onUpdated,
1495
+ resetForm,
1496
+ onClose
1497
+ ]
1498
+ );
1499
+ const handleForceUpdate = reactExports.useCallback(async () => {
1500
+ setIsForceUpdating(true);
1501
+ try {
1502
+ if (contentType) {
1503
+ const result = await updateContentType({
1504
+ id: contentType._id,
1505
+ displayName: displayName.trim(),
1506
+ description: description.trim() || void 0,
1507
+ fields,
1508
+ singleton,
1509
+ titleField: titleField || void 0,
1510
+ slugField: slugField || void 0,
1511
+ force: true
1512
+ });
1513
+ onUpdated?.(result);
1514
+ resetForm();
1515
+ setShowBreakingWarning(false);
1516
+ onClose();
1517
+ }
1518
+ } catch (error) {
1519
+ const message = error instanceof Error ? error.message : "Failed to update content type";
1520
+ setSubmitError(message);
1521
+ setShowBreakingWarning(false);
1522
+ } finally {
1523
+ setIsForceUpdating(false);
1524
+ }
1525
+ }, [
1526
+ contentType,
1527
+ updateContentType,
1528
+ displayName,
1529
+ description,
1530
+ fields,
1531
+ singleton,
1532
+ titleField,
1533
+ slugField,
1534
+ onUpdated,
1535
+ resetForm,
1536
+ onClose
1537
+ ]);
1538
+ const handleClose = reactExports.useCallback(() => {
1539
+ if (isSubmitting) return;
1540
+ resetForm();
1541
+ onClose();
1542
+ }, [isSubmitting, resetForm, onClose]);
1543
+ if (!isOpen) return null;
1544
+ const activeField = activeFieldIndex !== null ? fields[activeFieldIndex] : null;
1545
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1546
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1547
+ CmsDialog,
1548
+ {
1549
+ open: isOpen,
1550
+ onOpenChange: (open) => !open && handleClose(),
1551
+ title: isCodeDefined ? "View Content Type" : isEditing ? "Edit Content Type" : "Create Content Type",
1552
+ size: "2xl",
1553
+ footer: isReadOnly ? /* @__PURE__ */ jsxRuntimeExports.jsx(CmsButton, { variant: "outline", onClick: handleClose, children: "Close" }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1554
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1555
+ CmsButton,
1556
+ {
1557
+ variant: "outline",
1558
+ onClick: handleClose,
1559
+ disabled: isSubmitting,
1560
+ children: "Cancel"
1561
+ }
1562
+ ),
1563
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1564
+ CmsButton,
1565
+ {
1566
+ variant: "primary",
1567
+ onClick: handleSubmit,
1568
+ disabled: validationErrors.length > 0,
1569
+ loading: isSubmitting,
1570
+ "data-testid": isEditing ? "update-content-type-submit" : "create-content-type-submit",
1571
+ children: isEditing ? "Save Changes" : "Create Content Type"
1572
+ }
1573
+ )
1574
+ ] }),
1575
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [
1576
+ isCodeDefined && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3 rounded-lg border border-violet-200 bg-violet-50 p-3", children: [
1577
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CodeXml, { className: "mt-0.5 size-5 shrink-0 text-violet-600" }),
1578
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
1579
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-violet-900", children: "Managed by Code" }),
1580
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-violet-700", children: "This content type is defined in your codebase and cannot be edited through the admin interface. To make changes, update the definition in your code." })
1581
+ ] })
1582
+ ] }),
1583
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
1584
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-semibold text-foreground", children: "Basic Information" }),
1585
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1586
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Label, { htmlFor: "displayName", children: [
1587
+ "Display Name ",
1588
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
1589
+ ] }),
1590
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1591
+ Input,
1592
+ {
1593
+ id: "displayName",
1594
+ value: displayName,
1595
+ onChange: (e) => handleDisplayNameChange(e.target.value),
1596
+ placeholder: "e.g., Blog Post",
1597
+ disabled: isSubmitting || isReadOnly,
1598
+ autoFocus: !isReadOnly,
1599
+ "data-testid": "display-name-input"
1600
+ }
1601
+ )
1602
+ ] }),
1603
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1604
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Label, { htmlFor: "machineName", children: [
1605
+ "System Name ",
1606
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
1607
+ ] }),
1608
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1609
+ Input,
1610
+ {
1611
+ id: "machineName",
1612
+ value: machineName,
1613
+ onChange: (e) => handleMachineNameChange(e.target.value),
1614
+ placeholder: "e.g., blog_post",
1615
+ disabled: isSubmitting || isEditing || isReadOnly,
1616
+ className: cn(
1617
+ !isValidMachineName(machineName) && machineName && "border-destructive"
1618
+ ),
1619
+ "data-testid": "machine-name-input"
1620
+ }
1621
+ ),
1622
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: isEditing ? "System name cannot be changed after creation" : "Lowercase letters, numbers, and underscores only. Used in API queries." })
1623
+ ] }),
1624
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1625
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "description", children: "Description" }),
1626
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1627
+ Textarea,
1628
+ {
1629
+ id: "description",
1630
+ value: description,
1631
+ onChange: (e) => setDescription(e.target.value),
1632
+ placeholder: "Optional description of this content type",
1633
+ disabled: isSubmitting || isReadOnly,
1634
+ rows: 2
1635
+ }
1636
+ )
1637
+ ] }),
1638
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1639
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1640
+ Checkbox,
1641
+ {
1642
+ id: "singleton",
1643
+ checked: singleton,
1644
+ onCheckedChange: (checked) => setSingleton(checked),
1645
+ disabled: isSubmitting || isReadOnly
1646
+ }
1647
+ ),
1648
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "singleton", className: "cursor-pointer", children: "Singleton (only one entry allowed)" })
1649
+ ] })
1650
+ ] }),
1651
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
1652
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
1653
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-semibold text-foreground", children: "Fields" }),
1654
+ !isReadOnly && /* @__PURE__ */ jsxRuntimeExports.jsxs(
1655
+ CmsButton,
1656
+ {
1657
+ type: "button",
1658
+ variant: "secondary",
1659
+ size: "sm",
1660
+ onClick: addField,
1661
+ disabled: isSubmitting,
1662
+ "data-testid": "add-field-button",
1663
+ children: [
1664
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-3.5" }),
1665
+ "Add Field"
1666
+ ]
1667
+ }
1668
+ )
1669
+ ] }),
1670
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: fields.map((field, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
1671
+ "div",
1672
+ {
1673
+ className: cn(
1674
+ "flex items-center gap-2 rounded-lg border p-2 transition-colors",
1675
+ !isReadOnly && "cursor-pointer hover:bg-muted/50",
1676
+ activeFieldIndex === index && "border-primary bg-primary/5"
1677
+ ),
1678
+ onClick: () => {
1679
+ if (!isReadOnly) {
1680
+ setActiveFieldIndex(index);
1681
+ setShowFieldEditor(true);
1682
+ }
1683
+ },
1684
+ "data-testid": `field-item-${index}`,
1685
+ children: [
1686
+ !isReadOnly && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-0.5", children: [
1687
+ index > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
1688
+ "button",
1689
+ {
1690
+ type: "button",
1691
+ onClick: (e) => {
1692
+ e.stopPropagation();
1693
+ moveField(index, index - 1);
1694
+ },
1695
+ className: "rounded p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground",
1696
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "size-3" })
1697
+ }
1698
+ ),
1699
+ index < fields.length - 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
1700
+ "button",
1701
+ {
1702
+ type: "button",
1703
+ onClick: (e) => {
1704
+ e.stopPropagation();
1705
+ moveField(index, index + 1);
1706
+ },
1707
+ className: "rounded p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground",
1708
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3" })
1709
+ }
1710
+ )
1711
+ ] }),
1712
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-8 items-center justify-center rounded bg-muted text-muted-foreground", children: FIELD_TYPE_INFO[field.type].icon }),
1713
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [
1714
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "truncate text-sm font-medium", children: field.label }),
1715
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground", children: [
1716
+ FIELD_TYPE_INFO[field.type].label,
1717
+ field.required && " *"
1718
+ ] })
1719
+ ] }),
1720
+ !isReadOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
1721
+ "button",
1722
+ {
1723
+ type: "button",
1724
+ onClick: (e) => {
1725
+ e.stopPropagation();
1726
+ removeField(index);
1727
+ },
1728
+ disabled: isSubmitting || fields.length === 1,
1729
+ className: "rounded p-1 text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive disabled:opacity-50",
1730
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-4" })
1731
+ }
1732
+ )
1733
+ ]
1734
+ },
1735
+ index
1736
+ )) }),
1737
+ !isReadOnly && showFieldEditor && activeField && activeFieldIndex !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
1738
+ "div",
1739
+ {
1740
+ className: "rounded-lg border bg-muted/30 p-4",
1741
+ "data-testid": "field-editor",
1742
+ children: [
1743
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4 flex items-center justify-between", children: [
1744
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h5", { className: "font-medium", children: [
1745
+ "Edit Field: ",
1746
+ activeField.label
1747
+ ] }),
1748
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1749
+ "button",
1750
+ {
1751
+ type: "button",
1752
+ onClick: () => {
1753
+ setShowFieldEditor(false);
1754
+ setActiveFieldIndex(null);
1755
+ },
1756
+ className: "rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground",
1757
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-4" })
1758
+ }
1759
+ )
1760
+ ] }),
1761
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
1762
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1763
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Label, { htmlFor: "fieldLabel", children: [
1764
+ "Label ",
1765
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
1766
+ ] }),
1767
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1768
+ Input,
1769
+ {
1770
+ id: "fieldLabel",
1771
+ value: activeField.label,
1772
+ onChange: (e) => updateField(activeFieldIndex, {
1773
+ label: e.target.value,
1774
+ name: machineNameManuallyEdited ? activeField.name : generateMachineName(e.target.value) || activeField.name
1775
+ }),
1776
+ disabled: isSubmitting,
1777
+ "data-testid": "field-label-input"
1778
+ }
1779
+ )
1780
+ ] }),
1781
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1782
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Label, { htmlFor: "fieldName", children: [
1783
+ "Name ",
1784
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
1785
+ ] }),
1786
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1787
+ Input,
1788
+ {
1789
+ id: "fieldName",
1790
+ value: activeField.name,
1791
+ onChange: (e) => updateField(activeFieldIndex, {
1792
+ name: e.target.value.toLowerCase().replace(/[^a-z0-9_]/g, "")
1793
+ }),
1794
+ disabled: isSubmitting,
1795
+ "data-testid": "field-name-input"
1796
+ }
1797
+ )
1798
+ ] }),
1799
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1800
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Label, { htmlFor: "fieldType", children: [
1801
+ "Type ",
1802
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
1803
+ ] }),
1804
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1805
+ Select,
1806
+ {
1807
+ value: activeField.type,
1808
+ onValueChange: (value) => updateField(activeFieldIndex, {
1809
+ type: value,
1810
+ options: void 0
1811
+ }),
1812
+ disabled: isSubmitting,
1813
+ children: [
1814
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { "data-testid": "field-type-select", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, {}) }),
1815
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: Object.entries(FIELD_TYPE_INFO).map(([type, info]) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: type, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1816
+ info.icon,
1817
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: info.label }),
1818
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground", children: [
1819
+ "- ",
1820
+ info.description
1821
+ ] })
1822
+ ] }) }, type)) })
1823
+ ]
1824
+ }
1825
+ )
1826
+ ] }),
1827
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1828
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1829
+ Checkbox,
1830
+ {
1831
+ id: "fieldRequired",
1832
+ checked: activeField.required,
1833
+ onCheckedChange: (checked) => updateField(activeFieldIndex, {
1834
+ required: checked
1835
+ }),
1836
+ disabled: isSubmitting
1837
+ }
1838
+ ),
1839
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "fieldRequired", className: "cursor-pointer", children: "Required" })
1840
+ ] }),
1841
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1842
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "fieldDescription", children: "Help Text" }),
1843
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1844
+ Input,
1845
+ {
1846
+ id: "fieldDescription",
1847
+ value: activeField.description || "",
1848
+ onChange: (e) => updateField(activeFieldIndex, {
1849
+ description: e.target.value || void 0
1850
+ }),
1851
+ placeholder: "Help text shown below the field",
1852
+ disabled: isSubmitting
1853
+ }
1854
+ )
1855
+ ] }),
1856
+ (activeField.type === "select" || activeField.type === "multiSelect") && /* @__PURE__ */ jsxRuntimeExports.jsx(
1857
+ SelectOptionsEditor,
1858
+ {
1859
+ options: activeField.options?.options || [],
1860
+ onChange: (options) => updateField(activeFieldIndex, {
1861
+ options: { ...activeField.options, options }
1862
+ }),
1863
+ disabled: isSubmitting
1864
+ }
1865
+ )
1866
+ ] })
1867
+ ]
1868
+ }
1869
+ )
1870
+ ] }),
1871
+ textFields.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
1872
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-semibold text-foreground", children: "Display Settings" }),
1873
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1874
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "titleField", children: "Title Field" }),
1875
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1876
+ Select,
1877
+ {
1878
+ value: titleField || "none",
1879
+ onValueChange: (v2) => setTitleField(v2 === "none" ? "" : v2),
1880
+ disabled: isSubmitting,
1881
+ children: [
1882
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "None" }) }),
1883
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
1884
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "none", children: "None" }),
1885
+ textFields.map((field) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: field.name, children: field.label }, field.name))
1886
+ ] })
1887
+ ]
1888
+ }
1889
+ ),
1890
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Field to display as the entry title in lists" })
1891
+ ] }),
1892
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1893
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "slugField", children: "Slug Field" }),
1894
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
1895
+ Select,
1896
+ {
1897
+ value: slugField || "none",
1898
+ onValueChange: (v2) => setSlugField(v2 === "none" ? "" : v2),
1899
+ disabled: isSubmitting,
1900
+ children: [
1901
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "None (auto-generate)" }) }),
1902
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
1903
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "none", children: "None (auto-generate)" }),
1904
+ textFields.map((field) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: field.name, children: field.label }, field.name))
1905
+ ] })
1906
+ ]
1907
+ }
1908
+ ),
1909
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Field to use for generating URL-friendly slugs" })
1910
+ ] })
1911
+ ] }),
1912
+ submitError && /* @__PURE__ */ jsxRuntimeExports.jsx(
1913
+ "div",
1914
+ {
1915
+ className: "rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-800",
1916
+ role: "alert",
1917
+ "data-testid": "submit-error",
1918
+ children: submitError
1919
+ }
1920
+ )
1921
+ ] })
1922
+ }
1923
+ ),
1924
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1925
+ BreakingChangesWarningDialog,
1926
+ {
1927
+ isOpen: showBreakingWarning,
1928
+ onClose: () => setShowBreakingWarning(false),
1929
+ breakingChanges,
1930
+ onForceUpdate: handleForceUpdate,
1931
+ onCancel: () => {
1932
+ setShowBreakingWarning(false);
1933
+ setBreakingChanges([]);
1934
+ },
1935
+ isLoading: isForceUpdating
1936
+ }
1937
+ )
1938
+ ] });
1939
+ }
1940
+ function SelectOptionsEditor({
1941
+ options,
1942
+ onChange,
1943
+ disabled
1944
+ }) {
1945
+ const addOption = () => {
1946
+ onChange([
1947
+ ...options,
1948
+ { value: `option_${options.length + 1}`, label: "" }
1949
+ ]);
1950
+ };
1951
+ const removeOption = (index) => {
1952
+ onChange(options.filter((_, i) => i !== index));
1953
+ };
1954
+ const updateOption = (index, updates) => {
1955
+ onChange(
1956
+ options.map((opt, i) => i === index ? { ...opt, ...updates } : opt)
1957
+ );
1958
+ };
1959
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1960
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Label, { children: [
1961
+ "Options ",
1962
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
1963
+ ] }),
1964
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: options.map((option, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
1965
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1966
+ Input,
1967
+ {
1968
+ value: option.label,
1969
+ onChange: (e) => {
1970
+ const label = e.target.value;
1971
+ const value = label.toLowerCase().replace(/[^a-z0-9]/g, "_").replace(/^_+|_+$/g, "");
1972
+ updateOption(index, { label, value });
1973
+ },
1974
+ placeholder: "Option label",
1975
+ disabled,
1976
+ className: "flex-1"
1977
+ }
1978
+ ),
1979
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1980
+ Input,
1981
+ {
1982
+ value: option.value,
1983
+ onChange: (e) => updateOption(index, {
1984
+ value: e.target.value.toLowerCase().replace(/[^a-z0-9_]/g, "")
1985
+ }),
1986
+ placeholder: "value",
1987
+ disabled,
1988
+ className: "w-32"
1989
+ }
1990
+ ),
1991
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1992
+ "button",
1993
+ {
1994
+ type: "button",
1995
+ onClick: () => removeOption(index),
1996
+ disabled,
1997
+ className: "rounded p-1 text-muted-foreground hover:bg-destructive/10 hover:text-destructive",
1998
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-4" })
1999
+ }
2000
+ )
2001
+ ] }, index)) }),
2002
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
2003
+ CmsButton,
2004
+ {
2005
+ type: "button",
2006
+ variant: "secondary",
2007
+ size: "sm",
2008
+ onClick: addOption,
2009
+ disabled,
2010
+ children: [
2011
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-3.5" }),
2012
+ "Add Option"
2013
+ ]
2014
+ }
2015
+ )
2016
+ ] });
2017
+ }
2018
+ function Sidebar() {
2019
+ const routerState = useRouterState();
2020
+ const currentPath = routerState.location.pathname;
2021
+ const config = useAdminConfig();
2022
+ const { navItems, branding, layout } = config;
2023
+ const [isCreateModalOpen, setIsCreateModalOpen] = reactExports.useState(false);
2024
+ const contentTypesResult = useQuery(api.admin.listContentTypes, {
2025
+ isActive: true
2026
+ });
2027
+ const contentTypes = contentTypesResult?.page ?? [];
2028
+ const isActive = (to, exact) => {
2029
+ if (exact) {
2030
+ return currentPath === to;
2031
+ }
2032
+ return currentPath.startsWith(to);
2033
+ };
2034
+ const isContentActive = currentPath === "/content" || currentPath.startsWith("/entries/type/") || currentPath.startsWith("/entries/new/") || currentPath.startsWith("/entries/");
2035
+ const renderNavItem = (item) => {
2036
+ if (item.id === "content") {
2037
+ return renderContentMenu(item);
2038
+ }
2039
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
2040
+ Link,
2041
+ {
2042
+ to: item.path,
2043
+ className: cn(
2044
+ "flex items-center gap-3 rounded-md px-2 py-2 text-sm font-medium transition-colors",
2045
+ isActive(item.path, item.exact) ? "bg-sidebar-accent text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground"
2046
+ ),
2047
+ children: [
2048
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { name: item.icon, className: "size-5" }),
2049
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1", children: item.label }),
2050
+ item.badge && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded-full bg-sidebar-primary px-2 py-0.5 text-xs text-sidebar-primary-foreground", children: item.badge })
2051
+ ]
2052
+ },
2053
+ item.id
2054
+ );
2055
+ };
2056
+ const renderContentMenu = (item) => /* @__PURE__ */ jsxRuntimeExports.jsxs(Collapsible, { defaultOpen: isContentActive, children: [
2057
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
2058
+ CollapsibleTrigger,
2059
+ {
2060
+ className: cn(
2061
+ "flex w-full items-center gap-3 rounded-md px-2 py-2 text-sm font-medium transition-colors",
2062
+ isContentActive ? "bg-sidebar-accent text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground",
2063
+ "group"
2064
+ ),
2065
+ children: [
2066
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { name: item.icon, className: "size-5" }),
2067
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 text-left", children: item.label }),
2068
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 transition-transform duration-200 group-data-[state=open]:rotate-180" })
2069
+ ]
2070
+ }
2071
+ ),
2072
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ml-5 mt-1 space-y-1 border-l border-sidebar-border pl-3", children: [
2073
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2074
+ Link,
2075
+ {
2076
+ to: "/content",
2077
+ className: cn(
2078
+ "flex items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors",
2079
+ currentPath === "/content" ? "bg-sidebar-accent/60 text-sidebar-accent-foreground" : "text-sidebar-foreground/80 hover:bg-sidebar-accent/30 hover:text-sidebar-accent-foreground"
2080
+ ),
2081
+ children: "All Entries"
2082
+ }
2083
+ ),
2084
+ contentTypes.map((type) => /* @__PURE__ */ jsxRuntimeExports.jsx(
2085
+ Link,
2086
+ {
2087
+ to: "/entries/type/$contentTypeId",
2088
+ params: { contentTypeId: type._id },
2089
+ className: cn(
2090
+ "flex items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors",
2091
+ currentPath === `/entries/type/${type._id}` ? "bg-sidebar-accent/60 text-sidebar-accent-foreground" : "text-sidebar-foreground/80 hover:bg-sidebar-accent/30 hover:text-sidebar-accent-foreground"
2092
+ ),
2093
+ children: type.displayName
2094
+ },
2095
+ type._id
2096
+ )),
2097
+ contentTypes.length === 0 && contentTypesResult !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
2098
+ "button",
2099
+ {
2100
+ type: "button",
2101
+ onClick: () => setIsCreateModalOpen(true),
2102
+ className: "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm text-sidebar-foreground/60 hover:bg-sidebar-accent/30 hover:text-sidebar-accent-foreground",
2103
+ children: "+ Create content type"
2104
+ }
2105
+ )
2106
+ ] }) })
2107
+ ] }, item.id);
2108
+ const sidebarWidth = layout.sidebarWidth;
2109
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
2110
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
2111
+ "aside",
2112
+ {
2113
+ className: "fixed inset-y-0 left-0 z-50 flex flex-col border-r border-sidebar-border bg-sidebar",
2114
+ style: { width: sidebarWidth },
2115
+ children: [
2116
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-14 items-center gap-2 border-b border-sidebar-border px-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Link, { to: "/", className: "flex items-center gap-2 font-semibold text-sidebar-foreground", children: [
2117
+ branding.logo ? /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: branding.logo, alt: branding.appName, className: "size-8" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Layers, { className: "size-4" }) }),
2118
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-base", children: branding.appName })
2119
+ ] }) }),
2120
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("nav", { className: "flex-1 space-y-6 overflow-y-auto p-4", children: [
2121
+ navItems.main.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
2122
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/60", children: "Main" }),
2123
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1 pt-2", children: navItems.main.map(renderNavItem) })
2124
+ ] }),
2125
+ navItems.config.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
2126
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/60", children: "Configuration" }),
2127
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1 pt-2", children: navItems.config.map(renderNavItem) })
2128
+ ] })
2129
+ ] }),
2130
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t border-sidebar-border p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs text-sidebar-foreground/60", children: [
2131
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Version" }),
2132
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: "0.1.0" })
2133
+ ] }) })
2134
+ ]
2135
+ }
2136
+ ),
2137
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2138
+ ContentTypeFormModal,
2139
+ {
2140
+ isOpen: isCreateModalOpen,
2141
+ onClose: () => setIsCreateModalOpen(false)
2142
+ }
2143
+ )
2144
+ ] });
2145
+ }
2146
+ function Breadcrumb({ ...props }) {
2147
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("nav", { "aria-label": "breadcrumb", "data-slot": "breadcrumb", ...props });
2148
+ }
2149
+ function BreadcrumbList({ className, ...props }) {
2150
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2151
+ "ol",
2152
+ {
2153
+ "data-slot": "breadcrumb-list",
2154
+ className: cn(
2155
+ "text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5",
2156
+ className
2157
+ ),
2158
+ ...props
2159
+ }
2160
+ );
2161
+ }
2162
+ function BreadcrumbItem({ className, ...props }) {
2163
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2164
+ "li",
2165
+ {
2166
+ "data-slot": "breadcrumb-item",
2167
+ className: cn("inline-flex items-center gap-1.5", className),
2168
+ ...props
2169
+ }
2170
+ );
2171
+ }
2172
+ function BreadcrumbLink({
2173
+ asChild,
2174
+ className,
2175
+ ...props
2176
+ }) {
2177
+ const Comp = asChild ? Slot : "a";
2178
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2179
+ Comp,
2180
+ {
2181
+ "data-slot": "breadcrumb-link",
2182
+ className: cn("hover:text-foreground transition-colors", className),
2183
+ ...props
2184
+ }
2185
+ );
2186
+ }
2187
+ function BreadcrumbPage({ className, ...props }) {
2188
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2189
+ "span",
2190
+ {
2191
+ "data-slot": "breadcrumb-page",
2192
+ role: "link",
2193
+ "aria-disabled": "true",
2194
+ "aria-current": "page",
2195
+ className: cn("text-foreground font-normal", className),
2196
+ ...props
2197
+ }
2198
+ );
2199
+ }
2200
+ function BreadcrumbSeparator({
2201
+ children,
2202
+ className,
2203
+ ...props
2204
+ }) {
2205
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2206
+ "li",
2207
+ {
2208
+ "data-slot": "breadcrumb-separator",
2209
+ role: "presentation",
2210
+ "aria-hidden": "true",
2211
+ className: cn("[&>svg]:size-3.5", className),
2212
+ ...props,
2213
+ children: children ?? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, {})
2214
+ }
2215
+ );
2216
+ }
2217
+ function DropdownMenu({
2218
+ ...props
2219
+ }) {
2220
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$1, { "data-slot": "dropdown-menu", ...props });
2221
+ }
2222
+ function DropdownMenuTrigger({
2223
+ ...props
2224
+ }) {
2225
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2226
+ Trigger$1,
2227
+ {
2228
+ "data-slot": "dropdown-menu-trigger",
2229
+ ...props
2230
+ }
2231
+ );
2232
+ }
2233
+ function DropdownMenuContent({
2234
+ className,
2235
+ sideOffset = 4,
2236
+ ...props
2237
+ }) {
2238
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
2239
+ Content2$1,
2240
+ {
2241
+ "data-slot": "dropdown-menu-content",
2242
+ sideOffset,
2243
+ className: cn(
2244
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
2245
+ className
2246
+ ),
2247
+ ...props
2248
+ }
2249
+ ) });
2250
+ }
2251
+ function DropdownMenuItem({
2252
+ className,
2253
+ inset,
2254
+ variant = "default",
2255
+ ...props
2256
+ }) {
2257
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2258
+ Item2,
2259
+ {
2260
+ "data-slot": "dropdown-menu-item",
2261
+ "data-inset": inset,
2262
+ "data-variant": variant,
2263
+ className: cn(
2264
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
2265
+ className
2266
+ ),
2267
+ ...props
2268
+ }
2269
+ );
2270
+ }
2271
+ function DropdownMenuLabel({
2272
+ className,
2273
+ inset,
2274
+ ...props
2275
+ }) {
2276
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2277
+ Label2,
2278
+ {
2279
+ "data-slot": "dropdown-menu-label",
2280
+ "data-inset": inset,
2281
+ className: cn(
2282
+ "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
2283
+ className
2284
+ ),
2285
+ ...props
2286
+ }
2287
+ );
2288
+ }
2289
+ function DropdownMenuSeparator({
2290
+ className,
2291
+ ...props
2292
+ }) {
2293
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2294
+ Separator2,
2295
+ {
2296
+ "data-slot": "dropdown-menu-separator",
2297
+ className: cn("bg-border -mx-1 my-1 h-px", className),
2298
+ ...props
2299
+ }
2300
+ );
2301
+ }
2302
+ function Avatar({
2303
+ className,
2304
+ ...props
2305
+ }) {
2306
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2307
+ Root,
2308
+ {
2309
+ "data-slot": "avatar",
2310
+ className: cn(
2311
+ "relative flex size-8 shrink-0 overflow-hidden rounded-full",
2312
+ className
2313
+ ),
2314
+ ...props
2315
+ }
2316
+ );
2317
+ }
2318
+ function AvatarImage({
2319
+ className,
2320
+ ...props
2321
+ }) {
2322
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2323
+ Image,
2324
+ {
2325
+ "data-slot": "avatar-image",
2326
+ className: cn("aspect-square size-full", className),
2327
+ ...props
2328
+ }
2329
+ );
2330
+ }
2331
+ function AvatarFallback({
2332
+ className,
2333
+ ...props
2334
+ }) {
2335
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
2336
+ Fallback,
2337
+ {
2338
+ "data-slot": "avatar-fallback",
2339
+ className: cn(
2340
+ "bg-muted flex size-full items-center justify-center rounded-full",
2341
+ className
2342
+ ),
2343
+ ...props
2344
+ }
2345
+ );
2346
+ }
2347
+ function Popover({
2348
+ ...props
2349
+ }) {
2350
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2, { "data-slot": "popover", ...props });
2351
+ }
2352
+ function PopoverTrigger({
2353
+ ...props
2354
+ }) {
2355
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Trigger, { "data-slot": "popover-trigger", ...props });
2356
+ }
2357
+ function PopoverContent({
2358
+ className,
2359
+ align = "center",
2360
+ sideOffset = 4,
2361
+ ...props
2362
+ }) {
2363
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
2364
+ Content2,
2365
+ {
2366
+ "data-slot": "popover-content",
2367
+ align,
2368
+ sideOffset,
2369
+ className: cn(
2370
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
2371
+ className
2372
+ ),
2373
+ ...props
2374
+ }
2375
+ ) });
2376
+ }
2377
+ const KEYBOARD_SHORTCUTS = [
2378
+ { keys: ["⌘", "S"], description: "Save entry" },
2379
+ { keys: ["⌘", "⇧", "P"], description: "Publish entry" },
2380
+ { keys: ["⌘", "K"], description: "Quick search" },
2381
+ { keys: ["Esc"], description: "Close modal/panel" }
2382
+ ];
2383
+ const HELP_RESOURCES = [
2384
+ { label: "Documentation", url: "https://docs.convex.dev", icon: Book },
2385
+ { label: "API Reference", url: "https://docs.convex.dev/api", icon: Code },
2386
+ { label: "Community Discord", url: "https://discord.gg/convex", icon: MessageSquare }
2387
+ ];
2388
+ const routeLabels = {
2389
+ "/": "Dashboard",
2390
+ "/content": "Content",
2391
+ "/media": "Media Library",
2392
+ "/content-types": "Content Types",
2393
+ "/settings": "Settings",
2394
+ "/taxonomies": "Taxonomies",
2395
+ "/trash": "Trash",
2396
+ "/entries": "Entries",
2397
+ "/entries/type": "Content Types",
2398
+ "/entries/new": "New Entry"
2399
+ };
2400
+ function getBreadcrumbs(pathname, appName, overrides) {
2401
+ const breadcrumbs = [{ label: appName, to: "/" }];
2402
+ if (pathname === "/") {
2403
+ return breadcrumbs;
2404
+ }
2405
+ const segments = pathname.split("/").filter(Boolean);
2406
+ let currentPath = "";
2407
+ segments.forEach((segment, index) => {
2408
+ currentPath += `/${segment}`;
2409
+ const isLast = index === segments.length - 1;
2410
+ let label = overrides.get(currentPath) ?? routeLabels[currentPath];
2411
+ if (!label) {
2412
+ label = segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, " ");
2413
+ }
2414
+ if (isLast) {
2415
+ breadcrumbs.push({ label });
2416
+ } else {
2417
+ breadcrumbs.push({ label, to: currentPath });
2418
+ }
2419
+ });
2420
+ return breadcrumbs;
2421
+ }
2422
+ function Header() {
2423
+ const routerState = useRouterState();
2424
+ const navigate = useNavigate();
2425
+ const { branding } = useAdminConfig();
2426
+ let overrides = /* @__PURE__ */ new Map();
2427
+ try {
2428
+ const breadcrumbContext = useBreadcrumbContext();
2429
+ overrides = breadcrumbContext.overrides;
2430
+ } catch {
2431
+ }
2432
+ const breadcrumbs = getBreadcrumbs(routerState.location.pathname, branding.appName, overrides);
2433
+ let user = null;
2434
+ let role = null;
2435
+ let logout = async () => {
2436
+ };
2437
+ let isAuthenticated = false;
2438
+ try {
2439
+ const auth = useAuth();
2440
+ user = auth.user;
2441
+ role = auth.role;
2442
+ logout = auth.logout;
2443
+ isAuthenticated = auth.isAuthenticated;
2444
+ } catch {
2445
+ }
2446
+ const roleDefinition = role ? getRole(role) : null;
2447
+ const roleDisplayName = roleDefinition?.displayName ?? role ?? "No Role";
2448
+ const userDisplayName = user?.name ?? user?.email ?? "User";
2449
+ const getInitials = (name) => {
2450
+ const parts = name.split(" ");
2451
+ if (parts.length >= 2) {
2452
+ return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
2453
+ }
2454
+ return name.slice(0, 2).toUpperCase();
2455
+ };
2456
+ const userInitials = user?.name ? getInitials(user.name) : "U";
2457
+ const handleLogout = async () => {
2458
+ await logout();
2459
+ };
2460
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("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", children: [
2461
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Breadcrumb, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(BreadcrumbList, { children: breadcrumbs.map((crumb, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(reactExports.Fragment, { children: [
2462
+ index > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(BreadcrumbSeparator, {}),
2463
+ /* @__PURE__ */ jsxRuntimeExports.jsx(BreadcrumbItem, { children: crumb.to ? /* @__PURE__ */ jsxRuntimeExports.jsx(BreadcrumbLink, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Link, { to: crumb.to, className: "flex items-center gap-1.5", children: [
2464
+ index === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(House, { className: "size-3.5" }),
2465
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: crumb.label })
2466
+ ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(BreadcrumbPage, { children: crumb.label }) })
2467
+ ] }, index)) }) }),
2468
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
2469
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Popover, { children: [
2470
+ /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "ghost", size: "icon", className: "size-9", children: [
2471
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Bell, { className: "size-4" }),
2472
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Notifications" })
2473
+ ] }) }),
2474
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(PopoverContent, { align: "end", className: "w-80", children: [
2475
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-medium", children: "Notifications" }) }),
2476
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
2477
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Bell, { className: "size-8 text-muted-foreground/50" }),
2478
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-sm font-medium", children: "No notifications yet" }),
2479
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "You're all caught up!" })
2480
+ ] })
2481
+ ] })
2482
+ ] }),
2483
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Popover, { children: [
2484
+ /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "ghost", size: "icon", className: "size-9", children: [
2485
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleQuestionMark, { className: "size-4" }),
2486
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Help" })
2487
+ ] }) }),
2488
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(PopoverContent, { align: "end", className: "w-72", children: [
2489
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-medium", children: "Help & Resources" }) }),
2490
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
2491
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2492
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h5", { className: "mb-2 text-xs font-medium text-muted-foreground", children: "Keyboard Shortcuts" }),
2493
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: KEYBOARD_SHORTCUTS.map((shortcut, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-sm", children: [
2494
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: shortcut.description }),
2495
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-0.5", children: shortcut.keys.map((key, keyIndex) => /* @__PURE__ */ jsxRuntimeExports.jsx(
2496
+ "kbd",
2497
+ {
2498
+ className: "rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-xs",
2499
+ children: key
2500
+ },
2501
+ keyIndex
2502
+ )) })
2503
+ ] }, index)) })
2504
+ ] }),
2505
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2506
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h5", { className: "mb-2 text-xs font-medium text-muted-foreground", children: "Resources" }),
2507
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: HELP_RESOURCES.map((resource) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
2508
+ "a",
2509
+ {
2510
+ href: resource.url,
2511
+ target: "_blank",
2512
+ rel: "noopener noreferrer",
2513
+ className: "flex items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-accent",
2514
+ children: [
2515
+ /* @__PURE__ */ jsxRuntimeExports.jsx(resource.icon, { className: "size-4 text-muted-foreground" }),
2516
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1", children: resource.label }),
2517
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3 text-muted-foreground" })
2518
+ ]
2519
+ },
2520
+ resource.label
2521
+ )) })
2522
+ ] })
2523
+ ] })
2524
+ ] })
2525
+ ] }),
2526
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
2527
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "ghost", className: "h-9 gap-2 pl-2 pr-3", children: [
2528
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Avatar, { className: "size-6", children: [
2529
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AvatarImage, { src: user?.avatarUrl, alt: userDisplayName }),
2530
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AvatarFallback, { className: "text-xs", children: userInitials })
2531
+ ] }),
2532
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: userDisplayName }),
2533
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5 text-muted-foreground" })
2534
+ ] }) }),
2535
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [
2536
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuLabel, { className: "font-normal", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col space-y-1", children: [
2537
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: userDisplayName }),
2538
+ user?.email && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: user.email }),
2539
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: roleDisplayName })
2540
+ ] }) }),
2541
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuSeparator, {}),
2542
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: () => navigate({ to: "/settings" }), children: [
2543
+ /* @__PURE__ */ jsxRuntimeExports.jsx(User, { className: "mr-2 size-4" }),
2544
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Profile & Settings" })
2545
+ ] }),
2546
+ isAuthenticated && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
2547
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuSeparator, {}),
2548
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onClick: handleLogout, className: "text-destructive focus:text-destructive", children: [
2549
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LogOut, { className: "mr-2 size-4" }),
2550
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Logout" })
2551
+ ] })
2552
+ ] })
2553
+ ] })
2554
+ ] })
2555
+ ] })
2556
+ ] });
2557
+ }
2558
+ function AdminLayout({ children }) {
2559
+ const { layout } = useAdminConfig();
2560
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-h-screen bg-background", children: [
2561
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Sidebar, {}),
2562
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col", style: { marginLeft: layout.sidebarWidth }, children: [
2563
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Header, {}),
2564
+ /* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: "flex-1 overflow-auto p-6", children })
2565
+ ] })
2566
+ ] });
2567
+ }
2568
+ function DefaultLoading() {
2569
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "route-guard route-guard--loading bg-background flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-8 w-8 animate-spin text-muted-foreground" }) });
2570
+ }
2571
+ function DefaultUnauthenticated() {
2572
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "route-guard route-guard--unauthenticated", children: [
2573
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "route-guard-icon", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
2574
+ "svg",
2575
+ {
2576
+ xmlns: "http://www.w3.org/2000/svg",
2577
+ width: "48",
2578
+ height: "48",
2579
+ viewBox: "0 0 24 24",
2580
+ fill: "none",
2581
+ stroke: "currentColor",
2582
+ strokeWidth: "2",
2583
+ strokeLinecap: "round",
2584
+ strokeLinejoin: "round",
2585
+ children: [
2586
+ /* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
2587
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
2588
+ ]
2589
+ }
2590
+ ) }),
2591
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { children: "Authentication Required" }),
2592
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Please log in to access the admin panel." })
2593
+ ] });
2594
+ }
2595
+ function DefaultUnauthorized({
2596
+ requiredRole,
2597
+ requiredPermission
2598
+ }) {
2599
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "route-guard route-guard--unauthorized", children: [
2600
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "route-guard-icon", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
2601
+ "svg",
2602
+ {
2603
+ xmlns: "http://www.w3.org/2000/svg",
2604
+ width: "48",
2605
+ height: "48",
2606
+ viewBox: "0 0 24 24",
2607
+ fill: "none",
2608
+ stroke: "currentColor",
2609
+ strokeWidth: "2",
2610
+ strokeLinecap: "round",
2611
+ strokeLinejoin: "round",
2612
+ children: [
2613
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "10" }),
2614
+ /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4.93", y1: "4.93", x2: "19.07", y2: "19.07" })
2615
+ ]
2616
+ }
2617
+ ) }),
2618
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { children: "Access Denied" }),
2619
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "You don't have permission to access this page." }),
2620
+ requiredRole && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "route-guard-detail", children: [
2621
+ "Required role: ",
2622
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: requiredRole })
2623
+ ] }),
2624
+ requiredPermission && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "route-guard-detail", children: [
2625
+ "Required permission:",
2626
+ " ",
2627
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [
2628
+ requiredPermission.action,
2629
+ " on ",
2630
+ requiredPermission.resource
2631
+ ] })
2632
+ ] })
2633
+ ] });
2634
+ }
2635
+ function DefaultError({ error }) {
2636
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "route-guard route-guard--error", children: [
2637
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "route-guard-icon", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
2638
+ "svg",
2639
+ {
2640
+ xmlns: "http://www.w3.org/2000/svg",
2641
+ width: "48",
2642
+ height: "48",
2643
+ viewBox: "0 0 24 24",
2644
+ fill: "none",
2645
+ stroke: "currentColor",
2646
+ strokeWidth: "2",
2647
+ strokeLinecap: "round",
2648
+ strokeLinejoin: "round",
2649
+ children: [
2650
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "10" }),
2651
+ /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
2652
+ /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
2653
+ ]
2654
+ }
2655
+ ) }),
2656
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { children: "Authentication Error" }),
2657
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: error })
2658
+ ] });
2659
+ }
2660
+ function RouteGuard({
2661
+ children,
2662
+ requiredPermission,
2663
+ requiredRole,
2664
+ loadingComponent,
2665
+ unauthenticatedComponent,
2666
+ unauthorizedComponent,
2667
+ onUnauthenticated,
2668
+ onUnauthorized
2669
+ }) {
2670
+ const { authState, role, checkPermission, error } = useAuth();
2671
+ if (authState === "loading") {
2672
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: loadingComponent ?? /* @__PURE__ */ jsxRuntimeExports.jsx(DefaultLoading, {}) });
2673
+ }
2674
+ if (authState === "error") {
2675
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(DefaultError, { error: error ?? "An error occurred" });
2676
+ }
2677
+ if (authState === "unauthenticated") {
2678
+ onUnauthenticated?.();
2679
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: unauthenticatedComponent ?? /* @__PURE__ */ jsxRuntimeExports.jsx(DefaultUnauthenticated, {}) });
2680
+ }
2681
+ if (!role) {
2682
+ onUnauthorized?.();
2683
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: unauthorizedComponent ?? /* @__PURE__ */ jsxRuntimeExports.jsx(
2684
+ DefaultUnauthorized,
2685
+ {
2686
+ requiredRole,
2687
+ requiredPermission
2688
+ }
2689
+ ) });
2690
+ }
2691
+ if (requiredRole && role !== requiredRole) {
2692
+ onUnauthorized?.();
2693
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: unauthorizedComponent ?? /* @__PURE__ */ jsxRuntimeExports.jsx(
2694
+ DefaultUnauthorized,
2695
+ {
2696
+ requiredRole,
2697
+ requiredPermission
2698
+ }
2699
+ ) });
2700
+ }
2701
+ if (requiredPermission && !checkPermission(requiredPermission)) {
2702
+ onUnauthorized?.();
2703
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: unauthorizedComponent ?? /* @__PURE__ */ jsxRuntimeExports.jsx(
2704
+ DefaultUnauthorized,
2705
+ {
2706
+ requiredRole,
2707
+ requiredPermission
2708
+ }
2709
+ ) });
2710
+ }
2711
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children });
2712
+ }
2713
+ const createSsrRpc = (functionId, importer) => {
2714
+ const url = "/_serverFn/" + functionId;
2715
+ const serverFnMeta = { id: functionId };
2716
+ const fn = async (...args) => {
2717
+ const serverFn = await getServerFnById(functionId);
2718
+ return serverFn(...args);
2719
+ };
2720
+ return Object.assign(fn, {
2721
+ url,
2722
+ serverFnMeta,
2723
+ [TSS_SERVER_FUNCTION]: true
2724
+ });
2725
+ };
2726
+ const getServerConfig = createServerFn({
2727
+ method: "GET"
2728
+ }).handler(createSsrRpc("dff4e5b7f7b29b6a323200a2df0a5335d739cf583e83c9e514598af6b5ade819"));
2729
+ const mockGetUser = () => {
2730
+ return {
2731
+ id: "mock_user_123",
2732
+ name: "Demo Admin",
2733
+ email: "admin@example.com"
2734
+ };
2735
+ };
2736
+ const mockGetUserRole = () => {
2737
+ return "admin";
2738
+ };
2739
+ const mockLogout = () => {
2740
+ console.log("Logout called (mock mode)");
2741
+ };
2742
+ const noAuthGetUser = () => null;
2743
+ const noAuthGetUserRole = () => null;
2744
+ const noAuthLogout = () => {
2745
+ };
2746
+ function getAuthConfig(authMode) {
2747
+ switch (authMode) {
2748
+ case "mock":
2749
+ case "demo":
2750
+ return {
2751
+ getUser: mockGetUser,
2752
+ getUserRole: mockGetUserRole,
2753
+ onLogout: mockLogout
2754
+ };
2755
+ case "none":
2756
+ case "disabled":
2757
+ return {
2758
+ getUser: noAuthGetUser,
2759
+ getUserRole: noAuthGetUserRole,
2760
+ onLogout: noAuthLogout
2761
+ };
2762
+ default:
2763
+ return {
2764
+ getUser: mockGetUser,
2765
+ getUserRole: mockGetUserRole,
2766
+ onLogout: mockLogout
2767
+ };
2768
+ }
2769
+ }
2770
+ const Route$a = createRootRoute({
2771
+ head: () => ({
2772
+ meta: [
2773
+ {
2774
+ charSet: "utf-8"
2775
+ },
2776
+ {
2777
+ name: "viewport",
2778
+ content: "width=device-width, initial-scale=1"
2779
+ },
2780
+ {
2781
+ title: "Convex CMS Admin"
2782
+ },
2783
+ {
2784
+ name: "description",
2785
+ content: "Admin interface for Convex CMS - manage content, media, and publishing workflows"
2786
+ }
2787
+ ],
2788
+ links: [
2789
+ { rel: "stylesheet", href: globalsCss },
2790
+ { rel: "icon", href: "/favicon.ico" }
2791
+ ]
2792
+ }),
2793
+ // Load server config at route initialization
2794
+ loader: async () => {
2795
+ const config = await getServerConfig();
2796
+ return { config };
2797
+ },
2798
+ component: RootComponent
2799
+ });
2800
+ function RootComponent() {
2801
+ const { config } = Route$a.useLoaderData();
2802
+ const authConfig = reactExports.useMemo(() => getAuthConfig(config.authMode), [config.authMode]);
2803
+ const adminConfig = reactExports.useMemo(
2804
+ () => resolveAdminConfig(config.adminConfig),
2805
+ [config.adminConfig]
2806
+ );
2807
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(RootDocument, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(ThemeProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(BreadcrumbProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(ConvexProviderWrapper, { config, adminConfig, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
2808
+ AuthProvider,
2809
+ {
2810
+ getUser: authConfig.getUser,
2811
+ getUserRole: authConfig.getUserRole,
2812
+ onLogout: authConfig.onLogout,
2813
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(RouteGuard, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(AdminLayout, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Outlet, {}) }) })
2814
+ }
2815
+ ) }) }) }) });
2816
+ }
2817
+ function ConvexProviderWrapper({
2818
+ children,
2819
+ config,
2820
+ adminConfig
2821
+ }) {
2822
+ const convex = reactExports.useMemo(() => {
2823
+ if (!config.convexUrl) return null;
2824
+ return new ConvexReactClient(config.convexUrl);
2825
+ }, [config.convexUrl]);
2826
+ if (!convex) {
2827
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex min-h-screen items-center justify-center bg-background p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-lg space-y-4 rounded-lg border border-amber-200 bg-amber-50 p-6 text-center", children: [
2828
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold text-amber-900", children: "Convex Configuration Required" }),
2829
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-amber-800", children: "Please provide a Convex deployment URL to connect to your backend." }),
2830
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 text-left text-sm text-amber-700", children: [
2831
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium", children: "Options:" }),
2832
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { className: "list-inside list-disc space-y-1", children: [
2833
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
2834
+ "Run with URL:",
2835
+ " ",
2836
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "rounded bg-amber-100 px-1", children: "npx convex-cms admin --url YOUR_URL" })
2837
+ ] }),
2838
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
2839
+ "Set environment variable:",
2840
+ " ",
2841
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "rounded bg-amber-100 px-1", children: "CONVEX_URL=YOUR_URL" })
2842
+ ] }),
2843
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
2844
+ "Add to",
2845
+ " ",
2846
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "rounded bg-amber-100 px-1", children: ".env.local" }),
2847
+ ":",
2848
+ " ",
2849
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "rounded bg-amber-100 px-1", children: "CONVEX_URL=YOUR_URL" })
2850
+ ] })
2851
+ ] })
2852
+ ] }),
2853
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-amber-700", children: [
2854
+ "Run",
2855
+ " ",
2856
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "rounded bg-amber-100 px-1", children: "npx convex dev" }),
2857
+ " to start Convex and get your URL."
2858
+ ] })
2859
+ ] }) });
2860
+ }
2861
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ConvexProvider, { client: convex, children: /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsConfigProvider, { baseConfig: adminConfig, children }) });
2862
+ }
2863
+ function RootDocument({ children }) {
2864
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("html", { lang: "en", children: [
2865
+ /* @__PURE__ */ jsxRuntimeExports.jsx("head", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(HeadContent, {}) }),
2866
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("body", { children: [
2867
+ children,
2868
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Scripts, {})
2869
+ ] })
2870
+ ] });
2871
+ }
2872
+ const $$splitComponentImporter$9 = () => import("./trash-CNw1mtF1.mjs");
2873
+ const Route$9 = createFileRoute("/trash")({
2874
+ component: lazyRouteComponent($$splitComponentImporter$9, "component")
2875
+ });
2876
+ const $$splitComponentImporter$8 = () => import("./taxonomies-D3xMK23a.mjs");
2877
+ const Route$8 = createFileRoute("/taxonomies")({
2878
+ component: lazyRouteComponent($$splitComponentImporter$8, "component")
2879
+ });
2880
+ const $$splitComponentImporter$7 = () => import("./settings-MaEXh2Hz.mjs");
2881
+ const Route$7 = createFileRoute("/settings")({
2882
+ component: lazyRouteComponent($$splitComponentImporter$7, "component")
2883
+ });
2884
+ const $$splitComponentImporter$6 = () => import("./media-DkvBfmD9.mjs");
2885
+ const Route$6 = createFileRoute("/media")({
2886
+ component: lazyRouteComponent($$splitComponentImporter$6, "component")
2887
+ });
2888
+ const $$splitComponentImporter$5 = () => import("./content-types-BPgMwxiT.mjs");
2889
+ const Route$5 = createFileRoute("/content-types")({
2890
+ component: lazyRouteComponent($$splitComponentImporter$5, "component")
2891
+ });
2892
+ const $$splitComponentImporter$4 = () => import("./content-DrODe6sA.mjs");
2893
+ const Route$4 = createFileRoute("/content")({
2894
+ component: lazyRouteComponent($$splitComponentImporter$4, "component")
2895
+ });
2896
+ const $$splitComponentImporter$3 = () => import("./index-BTHmIC9W.mjs");
2897
+ const Route$3 = createFileRoute("/")({
2898
+ component: lazyRouteComponent($$splitComponentImporter$3, "component")
2899
+ });
2900
+ const $$splitComponentImporter$2 = () => import("./_entryId-D0yu8HuP.mjs");
2901
+ const Route$2 = createFileRoute("/entries/$entryId")({
2902
+ component: lazyRouteComponent($$splitComponentImporter$2, "component")
2903
+ });
2904
+ const $$splitComponentImporter$1 = () => import("./_contentTypeId-CPjmri90.mjs");
2905
+ const Route$1 = createFileRoute("/entries/type/$contentTypeId")({
2906
+ component: lazyRouteComponent($$splitComponentImporter$1, "component")
2907
+ });
2908
+ const $$splitComponentImporter = () => import("./new._contentTypeId-Co_73sDJ.mjs");
2909
+ const Route = createFileRoute("/entries/new/$contentTypeId")({
2910
+ component: lazyRouteComponent($$splitComponentImporter, "component")
2911
+ });
2912
+ const TrashRoute = Route$9.update({
2913
+ id: "/trash",
2914
+ path: "/trash",
2915
+ getParentRoute: () => Route$a
2916
+ });
2917
+ const TaxonomiesRoute = Route$8.update({
2918
+ id: "/taxonomies",
2919
+ path: "/taxonomies",
2920
+ getParentRoute: () => Route$a
2921
+ });
2922
+ const SettingsRoute = Route$7.update({
2923
+ id: "/settings",
2924
+ path: "/settings",
2925
+ getParentRoute: () => Route$a
2926
+ });
2927
+ const MediaRoute = Route$6.update({
2928
+ id: "/media",
2929
+ path: "/media",
2930
+ getParentRoute: () => Route$a
2931
+ });
2932
+ const ContentTypesRoute = Route$5.update({
2933
+ id: "/content-types",
2934
+ path: "/content-types",
2935
+ getParentRoute: () => Route$a
2936
+ });
2937
+ const ContentRoute = Route$4.update({
2938
+ id: "/content",
2939
+ path: "/content",
2940
+ getParentRoute: () => Route$a
2941
+ });
2942
+ const IndexRoute = Route$3.update({
2943
+ id: "/",
2944
+ path: "/",
2945
+ getParentRoute: () => Route$a
2946
+ });
2947
+ const EntriesEntryIdRoute = Route$2.update({
2948
+ id: "/entries/$entryId",
2949
+ path: "/entries/$entryId",
2950
+ getParentRoute: () => Route$a
2951
+ });
2952
+ const EntriesTypeContentTypeIdRoute = Route$1.update({
2953
+ id: "/entries/type/$contentTypeId",
2954
+ path: "/entries/type/$contentTypeId",
2955
+ getParentRoute: () => Route$a
2956
+ });
2957
+ const EntriesNewContentTypeIdRoute = Route.update({
2958
+ id: "/entries/new/$contentTypeId",
2959
+ path: "/entries/new/$contentTypeId",
2960
+ getParentRoute: () => Route$a
2961
+ });
2962
+ const rootRouteChildren = {
2963
+ IndexRoute,
2964
+ ContentRoute,
2965
+ ContentTypesRoute,
2966
+ MediaRoute,
2967
+ SettingsRoute,
2968
+ TaxonomiesRoute,
2969
+ TrashRoute,
2970
+ EntriesEntryIdRoute,
2971
+ EntriesNewContentTypeIdRoute,
2972
+ EntriesTypeContentTypeIdRoute
2973
+ };
2974
+ const routeTree = Route$a._addFileChildren(rootRouteChildren)._addFileTypes();
2975
+ function getRouter() {
2976
+ const router2 = createRouter({
2977
+ routeTree,
2978
+ scrollRestoration: true,
2979
+ defaultPreload: "intent"
2980
+ });
2981
+ return router2;
2982
+ }
2983
+ const router = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2984
+ __proto__: null,
2985
+ getRouter
2986
+ }, Symbol.toStringTag, { value: "Module" }));
2987
+ export {
2988
+ useAuth as A,
2989
+ Button as B,
2990
+ CmsButton as C,
2991
+ Dialog as D,
2992
+ getResourcePermissions as E,
2993
+ canAccessResource as F,
2994
+ hasPermission as G,
2995
+ Route as H,
2996
+ Input as I,
2997
+ buttonVariants as J,
2998
+ useBreadcrumbContext as K,
2999
+ Label as L,
3000
+ router as M,
3001
+ Popover as P,
3002
+ RouteGuard as R,
3003
+ Select as S,
3004
+ Textarea as T,
3005
+ SelectTrigger as a,
3006
+ SelectValue as b,
3007
+ SelectContent as c,
3008
+ SelectItem as d,
3009
+ Checkbox as e,
3010
+ cn as f,
3011
+ CmsConfirmDialog as g,
3012
+ api as h,
3013
+ CmsDialog as i,
3014
+ useTheme as j,
3015
+ DialogContent as k,
3016
+ DialogTitle as l,
3017
+ DropdownMenu as m,
3018
+ DropdownMenuTrigger as n,
3019
+ DropdownMenuContent as o,
3020
+ DropdownMenuItem as p,
3021
+ DropdownMenuSeparator as q,
3022
+ DialogHeader as r,
3023
+ DialogFooter as s,
3024
+ useSettingsConfig as t,
3025
+ useAdminConfig as u,
3026
+ ContentTypeFormModal as v,
3027
+ Route$2 as w,
3028
+ Route$1 as x,
3029
+ PopoverTrigger as y,
3030
+ PopoverContent as z
3031
+ };