@prenta/admin 2.6.0 → 2.7.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 (801) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/design-system/tokens.css +179 -85
  3. package/design-system/tokens.json +276 -85
  4. package/design-system/tokens.scss +148 -44
  5. package/design-system/tokens.tailwind.cjs +50 -1
  6. package/dist/AdminRoot.d.ts.map +1 -1
  7. package/dist/AdminRoot.js +42 -20
  8. package/dist/AdminRoot.js.map +1 -1
  9. package/dist/LoginRoot.d.ts.map +1 -1
  10. package/dist/LoginRoot.js +2 -1
  11. package/dist/LoginRoot.js.map +1 -1
  12. package/dist/__tests__/components/author-avatar.test.js +3 -17
  13. package/dist/__tests__/components/author-avatar.test.js.map +1 -1
  14. package/dist/__tests__/components/notification-bell.test.js +86 -15
  15. package/dist/__tests__/components/notification-bell.test.js.map +1 -1
  16. package/dist/__tests__/components/responsive-tiers.render.test.d.ts +2 -0
  17. package/dist/__tests__/components/responsive-tiers.render.test.d.ts.map +1 -0
  18. package/dist/__tests__/components/responsive-tiers.render.test.js +313 -0
  19. package/dist/__tests__/components/responsive-tiers.render.test.js.map +1 -0
  20. package/dist/__tests__/components/serp-preview.render.test.js +6 -3
  21. package/dist/__tests__/components/serp-preview.render.test.js.map +1 -1
  22. package/dist/__tests__/components/shell-primitives.render.test.d.ts +2 -0
  23. package/dist/__tests__/components/shell-primitives.render.test.d.ts.map +1 -0
  24. package/dist/__tests__/components/shell-primitives.render.test.js +716 -0
  25. package/dist/__tests__/components/shell-primitives.render.test.js.map +1 -0
  26. package/dist/__tests__/components/theme-provider-accent.test.js +49 -7
  27. package/dist/__tests__/components/theme-provider-accent.test.js.map +1 -1
  28. package/dist/__tests__/components/toggle.test.js +10 -3
  29. package/dist/__tests__/components/toggle.test.js.map +1 -1
  30. package/dist/__tests__/components/ui-primitives.test.js +3 -7
  31. package/dist/__tests__/components/ui-primitives.test.js.map +1 -1
  32. package/dist/__tests__/layout/build-nav-items.test.js +1 -1
  33. package/dist/__tests__/layout/build-nav-items.test.js.map +1 -1
  34. package/dist/__tests__/layout/shell-nav.render.test.d.ts +2 -0
  35. package/dist/__tests__/layout/shell-nav.render.test.d.ts.map +1 -0
  36. package/dist/__tests__/layout/shell-nav.render.test.js +736 -0
  37. package/dist/__tests__/layout/shell-nav.render.test.js.map +1 -0
  38. package/dist/__tests__/layout/sidebar-forms-submenu.render.test.js +8 -4
  39. package/dist/__tests__/layout/sidebar-forms-submenu.render.test.js.map +1 -1
  40. package/dist/__tests__/layout/sidebar-groups.render.test.d.ts +2 -0
  41. package/dist/__tests__/layout/sidebar-groups.render.test.d.ts.map +1 -0
  42. package/dist/__tests__/layout/sidebar-groups.render.test.js +56 -0
  43. package/dist/__tests__/layout/sidebar-groups.render.test.js.map +1 -0
  44. package/dist/__tests__/layout/sidebar-menus.render.test.d.ts +2 -0
  45. package/dist/__tests__/layout/sidebar-menus.render.test.d.ts.map +1 -0
  46. package/dist/__tests__/layout/sidebar-menus.render.test.js +82 -0
  47. package/dist/__tests__/layout/sidebar-menus.render.test.js.map +1 -0
  48. package/dist/__tests__/layout/sidebar-plugin-nav.test.js +1 -1
  49. package/dist/__tests__/layout/sidebar-plugin-nav.test.js.map +1 -1
  50. package/dist/__tests__/layout/sidebar-posts.test.js +48 -38
  51. package/dist/__tests__/layout/sidebar-posts.test.js.map +1 -1
  52. package/dist/__tests__/layout/sidebar-submenu.render.test.js +26 -10
  53. package/dist/__tests__/layout/sidebar-submenu.render.test.js.map +1 -1
  54. package/dist/__tests__/layout/topbar.render.test.d.ts +2 -0
  55. package/dist/__tests__/layout/topbar.render.test.d.ts.map +1 -0
  56. package/dist/__tests__/layout/topbar.render.test.js +406 -0
  57. package/dist/__tests__/layout/topbar.render.test.js.map +1 -0
  58. package/dist/__tests__/lib/api.test.js +2 -0
  59. package/dist/__tests__/lib/api.test.js.map +1 -1
  60. package/dist/__tests__/lib/job-drawer.test.d.ts +2 -0
  61. package/dist/__tests__/lib/job-drawer.test.d.ts.map +1 -0
  62. package/dist/__tests__/lib/job-drawer.test.js +393 -0
  63. package/dist/__tests__/lib/job-drawer.test.js.map +1 -0
  64. package/dist/__tests__/lib/job-view.test.d.ts +2 -0
  65. package/dist/__tests__/lib/job-view.test.d.ts.map +1 -0
  66. package/dist/__tests__/lib/job-view.test.js +387 -0
  67. package/dist/__tests__/lib/job-view.test.js.map +1 -0
  68. package/dist/__tests__/lib/jobs-service.test.d.ts +2 -0
  69. package/dist/__tests__/lib/jobs-service.test.d.ts.map +1 -0
  70. package/dist/__tests__/lib/jobs-service.test.js +88 -0
  71. package/dist/__tests__/lib/jobs-service.test.js.map +1 -0
  72. package/dist/__tests__/router/admin-route-order.test.d.ts +2 -0
  73. package/dist/__tests__/router/admin-route-order.test.d.ts.map +1 -0
  74. package/dist/__tests__/router/admin-route-order.test.js +36 -0
  75. package/dist/__tests__/router/admin-route-order.test.js.map +1 -0
  76. package/dist/__tests__/styles/ai-gradient-contrast.test.d.ts +2 -0
  77. package/dist/__tests__/styles/ai-gradient-contrast.test.d.ts.map +1 -0
  78. package/dist/__tests__/styles/ai-gradient-contrast.test.js +110 -0
  79. package/dist/__tests__/styles/ai-gradient-contrast.test.js.map +1 -0
  80. package/dist/__tests__/styles/breakpoint-order.test.d.ts +2 -0
  81. package/dist/__tests__/styles/breakpoint-order.test.d.ts.map +1 -0
  82. package/dist/__tests__/styles/breakpoint-order.test.js +52 -0
  83. package/dist/__tests__/styles/breakpoint-order.test.js.map +1 -0
  84. package/dist/__tests__/styles/responsive-layer.test.js +303 -12
  85. package/dist/__tests__/styles/responsive-layer.test.js.map +1 -1
  86. package/dist/__tests__/styles/tailwind-preset.test.d.ts +2 -0
  87. package/dist/__tests__/styles/tailwind-preset.test.d.ts.map +1 -0
  88. package/dist/__tests__/styles/tailwind-preset.test.js +147 -0
  89. package/dist/__tests__/styles/tailwind-preset.test.js.map +1 -0
  90. package/dist/__tests__/styles/theme-token-scope.test.js +9 -3
  91. package/dist/__tests__/styles/theme-token-scope.test.js.map +1 -1
  92. package/dist/__tests__/styles/tiers.test.d.ts +2 -0
  93. package/dist/__tests__/styles/tiers.test.d.ts.map +1 -0
  94. package/dist/__tests__/styles/tiers.test.js +121 -0
  95. package/dist/__tests__/styles/tiers.test.js.map +1 -0
  96. package/dist/__tests__/styles/tokens-drift.test.js +57 -6
  97. package/dist/__tests__/styles/tokens-drift.test.js.map +1 -1
  98. package/dist/__tests__/views/admin-lazy-route.render.test.js +27 -1
  99. package/dist/__tests__/views/admin-lazy-route.render.test.js.map +1 -1
  100. package/dist/__tests__/views/ai-settings.render.test.js +4 -4
  101. package/dist/__tests__/views/appearance-menus-route.render.test.d.ts +2 -0
  102. package/dist/__tests__/views/appearance-menus-route.render.test.d.ts.map +1 -0
  103. package/dist/__tests__/views/appearance-menus-route.render.test.js +50 -0
  104. package/dist/__tests__/views/appearance-menus-route.render.test.js.map +1 -0
  105. package/dist/__tests__/views/appearance-settings.render.test.js +8 -6
  106. package/dist/__tests__/views/appearance-settings.render.test.js.map +1 -1
  107. package/dist/__tests__/views/appearance-theme-provider.render.test.d.ts +2 -0
  108. package/dist/__tests__/views/appearance-theme-provider.render.test.d.ts.map +1 -0
  109. package/dist/__tests__/views/appearance-theme-provider.render.test.js +286 -0
  110. package/dist/__tests__/views/appearance-theme-provider.render.test.js.map +1 -0
  111. package/dist/__tests__/views/dashboard.test.js +37 -0
  112. package/dist/__tests__/views/dashboard.test.js.map +1 -1
  113. package/dist/__tests__/views/document-edit-navigation.render.test.d.ts +2 -0
  114. package/dist/__tests__/views/document-edit-navigation.render.test.d.ts.map +1 -0
  115. package/dist/__tests__/views/document-edit-navigation.render.test.js +101 -0
  116. package/dist/__tests__/views/document-edit-navigation.render.test.js.map +1 -0
  117. package/dist/__tests__/views/document-edit-routes.render.test.d.ts +2 -0
  118. package/dist/__tests__/views/document-edit-routes.render.test.d.ts.map +1 -0
  119. package/dist/__tests__/views/document-edit-routes.render.test.js +113 -0
  120. package/dist/__tests__/views/document-edit-routes.render.test.js.map +1 -0
  121. package/dist/__tests__/views/email-settings.render.test.js +2 -2
  122. package/dist/__tests__/views/form-entries.render.test.js +15 -0
  123. package/dist/__tests__/views/form-entries.render.test.js.map +1 -1
  124. package/dist/__tests__/views/form-submissions.render.test.js +18 -0
  125. package/dist/__tests__/views/form-submissions.render.test.js.map +1 -1
  126. package/dist/__tests__/views/forms-list.render.test.js +12 -0
  127. package/dist/__tests__/views/forms-list.render.test.js.map +1 -1
  128. package/dist/__tests__/views/general-settings.render.test.js +26 -10
  129. package/dist/__tests__/views/general-settings.render.test.js.map +1 -1
  130. package/dist/__tests__/views/jobs-drawer.render.test.d.ts +2 -0
  131. package/dist/__tests__/views/jobs-drawer.render.test.d.ts.map +1 -0
  132. package/dist/__tests__/views/jobs-drawer.render.test.js +908 -0
  133. package/dist/__tests__/views/jobs-drawer.render.test.js.map +1 -0
  134. package/dist/__tests__/views/jobs-list.render.test.d.ts +2 -0
  135. package/dist/__tests__/views/jobs-list.render.test.d.ts.map +1 -0
  136. package/dist/__tests__/views/jobs-list.render.test.js +695 -0
  137. package/dist/__tests__/views/jobs-list.render.test.js.map +1 -0
  138. package/dist/__tests__/views/kpi-grid.test.d.ts +2 -0
  139. package/dist/__tests__/views/kpi-grid.test.d.ts.map +1 -0
  140. package/dist/__tests__/views/kpi-grid.test.js +26 -0
  141. package/dist/__tests__/views/kpi-grid.test.js.map +1 -0
  142. package/dist/__tests__/views/mcp-connect.render.test.js +1 -0
  143. package/dist/__tests__/views/mcp-connect.render.test.js.map +1 -1
  144. package/dist/__tests__/views/post-section-editor.test.js +3 -1
  145. package/dist/__tests__/views/post-section-editor.test.js.map +1 -1
  146. package/dist/__tests__/views/script-tags.render.test.js +25 -0
  147. package/dist/__tests__/views/script-tags.render.test.js.map +1 -1
  148. package/dist/__tests__/views/security-settings.render.test.js +9 -8
  149. package/dist/__tests__/views/security-settings.render.test.js.map +1 -1
  150. package/dist/__tests__/views/seo-settings.render.test.js +7 -7
  151. package/dist/__tests__/views/seo-settings.render.test.js.map +1 -1
  152. package/dist/__tests__/views/settings-save-bar.render.test.d.ts +2 -0
  153. package/dist/__tests__/views/settings-save-bar.render.test.d.ts.map +1 -0
  154. package/dist/__tests__/views/settings-save-bar.render.test.js +68 -0
  155. package/dist/__tests__/views/settings-save-bar.render.test.js.map +1 -0
  156. package/dist/__tests__/views/settings-save-footer.render.test.js +23 -15
  157. package/dist/__tests__/views/settings-save-footer.render.test.js.map +1 -1
  158. package/dist/__tests__/views/settings-tabs.render.test.d.ts +2 -0
  159. package/dist/__tests__/views/settings-tabs.render.test.d.ts.map +1 -0
  160. package/dist/__tests__/views/settings-tabs.render.test.js +319 -0
  161. package/dist/__tests__/views/settings-tabs.render.test.js.map +1 -0
  162. package/dist/__tests__/views/updates-tab.render.test.js +4 -3
  163. package/dist/__tests__/views/updates-tab.render.test.js.map +1 -1
  164. package/dist/components/Breadcrumbs.d.ts +8 -1
  165. package/dist/components/Breadcrumbs.d.ts.map +1 -1
  166. package/dist/components/Breadcrumbs.js +6 -0
  167. package/dist/components/Breadcrumbs.js.map +1 -1
  168. package/dist/components/CommandPalette.d.ts.map +1 -1
  169. package/dist/components/CommandPalette.js +40 -4
  170. package/dist/components/CommandPalette.js.map +1 -1
  171. package/dist/components/LocaleSwitcher.d.ts.map +1 -1
  172. package/dist/components/LocaleSwitcher.js +1 -1
  173. package/dist/components/LocaleSwitcher.js.map +1 -1
  174. package/dist/components/NotificationBell.d.ts.map +1 -1
  175. package/dist/components/NotificationBell.js +44 -3
  176. package/dist/components/NotificationBell.js.map +1 -1
  177. package/dist/components/OfflineStatus.js +1 -1
  178. package/dist/components/OfflineStatus.js.map +1 -1
  179. package/dist/components/PresenceIndicator.d.ts.map +1 -1
  180. package/dist/components/PresenceIndicator.js +2 -1
  181. package/dist/components/PresenceIndicator.js.map +1 -1
  182. package/dist/components/ReflowMeter.js +2 -2
  183. package/dist/components/ReflowMeter.js.map +1 -1
  184. package/dist/components/SEOPanel.js +2 -2
  185. package/dist/components/SEOPanel.js.map +1 -1
  186. package/dist/components/ThemeProvider.d.ts +24 -4
  187. package/dist/components/ThemeProvider.d.ts.map +1 -1
  188. package/dist/components/ThemeProvider.js +80 -22
  189. package/dist/components/ThemeProvider.js.map +1 -1
  190. package/dist/components/TipTapEditor.d.ts.map +1 -1
  191. package/dist/components/TipTapEditor.js +3 -4
  192. package/dist/components/TipTapEditor.js.map +1 -1
  193. package/dist/components/forms/EmbedPanel.js +1 -1
  194. package/dist/components/forms/EmbedPanel.js.map +1 -1
  195. package/dist/components/forms/FormEntryDetailPane.js +6 -1
  196. package/dist/components/forms/FormEntryDetailPane.js.map +1 -1
  197. package/dist/components/forms/ShortcodeGlossary.d.ts.map +1 -1
  198. package/dist/components/forms/ShortcodeGlossary.js +6 -1
  199. package/dist/components/forms/ShortcodeGlossary.js.map +1 -1
  200. package/dist/components/forms/primitives.d.ts +15 -5
  201. package/dist/components/forms/primitives.d.ts.map +1 -1
  202. package/dist/components/forms/primitives.js +11 -11
  203. package/dist/components/forms/primitives.js.map +1 -1
  204. package/dist/components/pages/tag-badges.d.ts +2 -1
  205. package/dist/components/pages/tag-badges.d.ts.map +1 -1
  206. package/dist/components/pages/tag-badges.js +4 -3
  207. package/dist/components/pages/tag-badges.js.map +1 -1
  208. package/dist/components/seo/PageAuditPanel.js +2 -2
  209. package/dist/components/seo/PageAuditPanel.js.map +1 -1
  210. package/dist/components/seo/SerpPreview.d.ts +4 -4
  211. package/dist/components/seo/SerpPreview.js +1 -1
  212. package/dist/components/seo/SerpPreview.js.map +1 -1
  213. package/dist/components/seo/primitives.js +2 -2
  214. package/dist/components/seo/primitives.js.map +1 -1
  215. package/dist/components/ui/AuthorAvatar.d.ts +4 -4
  216. package/dist/components/ui/AuthorAvatar.d.ts.map +1 -1
  217. package/dist/components/ui/AuthorAvatar.js +11 -10
  218. package/dist/components/ui/AuthorAvatar.js.map +1 -1
  219. package/dist/components/ui/Badge.d.ts +1 -1
  220. package/dist/components/ui/Badge.js +1 -1
  221. package/dist/components/ui/Badge.js.map +1 -1
  222. package/dist/components/ui/Breadcrumb.d.ts +27 -0
  223. package/dist/components/ui/Breadcrumb.d.ts.map +1 -0
  224. package/dist/components/ui/Breadcrumb.js +41 -0
  225. package/dist/components/ui/Breadcrumb.js.map +1 -0
  226. package/dist/components/ui/Button.d.ts +2 -2
  227. package/dist/components/ui/Button.d.ts.map +1 -1
  228. package/dist/components/ui/Button.js +31 -16
  229. package/dist/components/ui/Button.js.map +1 -1
  230. package/dist/components/ui/Card.d.ts +8 -4
  231. package/dist/components/ui/Card.d.ts.map +1 -1
  232. package/dist/components/ui/Card.js +21 -13
  233. package/dist/components/ui/Card.js.map +1 -1
  234. package/dist/components/ui/CardListControls.d.ts +34 -0
  235. package/dist/components/ui/CardListControls.d.ts.map +1 -0
  236. package/dist/components/ui/CardListControls.js +25 -0
  237. package/dist/components/ui/CardListControls.js.map +1 -0
  238. package/dist/components/ui/CountChip.d.ts +20 -0
  239. package/dist/components/ui/CountChip.d.ts.map +1 -0
  240. package/dist/components/ui/CountChip.js +48 -0
  241. package/dist/components/ui/CountChip.js.map +1 -0
  242. package/dist/components/ui/FilterPill.d.ts +2 -1
  243. package/dist/components/ui/FilterPill.d.ts.map +1 -1
  244. package/dist/components/ui/FilterPill.js +3 -2
  245. package/dist/components/ui/FilterPill.js.map +1 -1
  246. package/dist/components/ui/Input.d.ts +1 -1
  247. package/dist/components/ui/InspectorPane.d.ts +1 -1
  248. package/dist/components/ui/InspectorPane.d.ts.map +1 -1
  249. package/dist/components/ui/InspectorPane.js +15 -4
  250. package/dist/components/ui/InspectorPane.js.map +1 -1
  251. package/dist/components/ui/Modal.d.ts.map +1 -1
  252. package/dist/components/ui/Modal.js +10 -2
  253. package/dist/components/ui/Modal.js.map +1 -1
  254. package/dist/components/ui/PageHeader.d.ts +28 -0
  255. package/dist/components/ui/PageHeader.d.ts.map +1 -0
  256. package/dist/components/ui/PageHeader.js +18 -0
  257. package/dist/components/ui/PageHeader.js.map +1 -0
  258. package/dist/components/ui/RowActions.d.ts +5 -0
  259. package/dist/components/ui/RowActions.d.ts.map +1 -1
  260. package/dist/components/ui/RowActions.js +7 -2
  261. package/dist/components/ui/RowActions.js.map +1 -1
  262. package/dist/components/ui/Segmented.d.ts +21 -0
  263. package/dist/components/ui/Segmented.d.ts.map +1 -0
  264. package/dist/components/ui/Segmented.js +41 -0
  265. package/dist/components/ui/Segmented.js.map +1 -0
  266. package/dist/components/ui/Toaster.d.ts +12 -0
  267. package/dist/components/ui/Toaster.d.ts.map +1 -0
  268. package/dist/components/ui/Toaster.js +103 -0
  269. package/dist/components/ui/Toaster.js.map +1 -0
  270. package/dist/components/ui/Toggle.d.ts +4 -3
  271. package/dist/components/ui/Toggle.d.ts.map +1 -1
  272. package/dist/components/ui/Toggle.js +16 -12
  273. package/dist/components/ui/Toggle.js.map +1 -1
  274. package/dist/components/ui/UnderlineTabs.d.ts +56 -0
  275. package/dist/components/ui/UnderlineTabs.d.ts.map +1 -0
  276. package/dist/components/ui/UnderlineTabs.js +205 -0
  277. package/dist/components/ui/UnderlineTabs.js.map +1 -0
  278. package/dist/components/ui/UnsavedBar.d.ts +25 -0
  279. package/dist/components/ui/UnsavedBar.d.ts.map +1 -0
  280. package/dist/components/ui/UnsavedBar.js +22 -0
  281. package/dist/components/ui/UnsavedBar.js.map +1 -0
  282. package/dist/components/ui/admin-links.d.ts +11 -0
  283. package/dist/components/ui/admin-links.d.ts.map +1 -0
  284. package/dist/components/ui/admin-links.js +10 -0
  285. package/dist/components/ui/admin-links.js.map +1 -0
  286. package/dist/components/ui/card-table.d.ts +43 -0
  287. package/dist/components/ui/card-table.d.ts.map +1 -0
  288. package/dist/components/ui/card-table.js +31 -0
  289. package/dist/components/ui/card-table.js.map +1 -0
  290. package/dist/components/virtual-window.d.ts +7 -0
  291. package/dist/components/virtual-window.d.ts.map +1 -1
  292. package/dist/components/virtual-window.js +5 -2
  293. package/dist/components/virtual-window.js.map +1 -1
  294. package/dist/fields/RelationshipField.js +1 -1
  295. package/dist/fields/RelationshipField.js.map +1 -1
  296. package/dist/files/dm-mono-latin-400-normal.woff +0 -0
  297. package/dist/files/dm-mono-latin-400-normal.woff2 +0 -0
  298. package/dist/files/dm-mono-latin-500-normal.woff +0 -0
  299. package/dist/files/dm-mono-latin-500-normal.woff2 +0 -0
  300. package/dist/files/dm-mono-latin-ext-400-normal.woff +0 -0
  301. package/dist/files/dm-mono-latin-ext-400-normal.woff2 +0 -0
  302. package/dist/files/dm-mono-latin-ext-500-normal.woff +0 -0
  303. package/dist/files/dm-mono-latin-ext-500-normal.woff2 +0 -0
  304. package/dist/files/dm-sans-latin-400-normal.woff +0 -0
  305. package/dist/files/dm-sans-latin-400-normal.woff2 +0 -0
  306. package/dist/files/dm-sans-latin-500-normal.woff +0 -0
  307. package/dist/files/dm-sans-latin-500-normal.woff2 +0 -0
  308. package/dist/files/dm-sans-latin-600-normal.woff +0 -0
  309. package/dist/files/dm-sans-latin-600-normal.woff2 +0 -0
  310. package/dist/files/dm-sans-latin-700-normal.woff +0 -0
  311. package/dist/files/dm-sans-latin-700-normal.woff2 +0 -0
  312. package/dist/files/dm-sans-latin-ext-400-normal.woff +0 -0
  313. package/dist/files/dm-sans-latin-ext-400-normal.woff2 +0 -0
  314. package/dist/files/dm-sans-latin-ext-500-normal.woff +0 -0
  315. package/dist/files/dm-sans-latin-ext-500-normal.woff2 +0 -0
  316. package/dist/files/dm-sans-latin-ext-600-normal.woff +0 -0
  317. package/dist/files/dm-sans-latin-ext-600-normal.woff2 +0 -0
  318. package/dist/files/dm-sans-latin-ext-700-normal.woff +0 -0
  319. package/dist/files/dm-sans-latin-ext-700-normal.woff2 +0 -0
  320. package/dist/hooks/useAppearanceBootstrap.d.ts.map +1 -1
  321. package/dist/hooks/useAppearanceBootstrap.js +9 -3
  322. package/dist/hooks/useAppearanceBootstrap.js.map +1 -1
  323. package/dist/index.d.ts +15 -0
  324. package/dist/index.d.ts.map +1 -1
  325. package/dist/index.js +8 -0
  326. package/dist/index.js.map +1 -1
  327. package/dist/layout/Header.d.ts +14 -5
  328. package/dist/layout/Header.d.ts.map +1 -1
  329. package/dist/layout/Header.js +78 -13
  330. package/dist/layout/Header.js.map +1 -1
  331. package/dist/layout/Layout.d.ts +5 -3
  332. package/dist/layout/Layout.d.ts.map +1 -1
  333. package/dist/layout/Layout.js +45 -54
  334. package/dist/layout/Layout.js.map +1 -1
  335. package/dist/layout/MobileTabBar.d.ts +20 -0
  336. package/dist/layout/MobileTabBar.d.ts.map +1 -0
  337. package/dist/layout/MobileTabBar.js +29 -0
  338. package/dist/layout/MobileTabBar.js.map +1 -0
  339. package/dist/layout/Sidebar.d.ts +8 -26
  340. package/dist/layout/Sidebar.d.ts.map +1 -1
  341. package/dist/layout/Sidebar.js +309 -345
  342. package/dist/layout/Sidebar.js.map +1 -1
  343. package/dist/layout/nav-config.d.ts +101 -0
  344. package/dist/layout/nav-config.d.ts.map +1 -0
  345. package/dist/layout/nav-config.js +297 -0
  346. package/dist/layout/nav-config.js.map +1 -0
  347. package/dist/layout/primitives/AdminShell.d.ts +10 -2
  348. package/dist/layout/primitives/AdminShell.d.ts.map +1 -1
  349. package/dist/layout/primitives/AdminShell.js +114 -6
  350. package/dist/layout/primitives/AdminShell.js.map +1 -1
  351. package/dist/layout/topbar-classes.d.ts +8 -0
  352. package/dist/layout/topbar-classes.d.ts.map +1 -0
  353. package/dist/layout/topbar-classes.js +8 -0
  354. package/dist/layout/topbar-classes.js.map +1 -0
  355. package/dist/layout/use-nav-items.d.ts +10 -0
  356. package/dist/layout/use-nav-items.d.ts.map +1 -0
  357. package/dist/layout/use-nav-items.js +39 -0
  358. package/dist/layout/use-nav-items.js.map +1 -0
  359. package/dist/lib/api.d.ts +6 -0
  360. package/dist/lib/api.d.ts.map +1 -1
  361. package/dist/lib/api.js +1 -1
  362. package/dist/lib/api.js.map +1 -1
  363. package/dist/lib/appearance-api.d.ts +3 -1
  364. package/dist/lib/appearance-api.d.ts.map +1 -1
  365. package/dist/lib/appearance-api.js +1 -0
  366. package/dist/lib/appearance-api.js.map +1 -1
  367. package/dist/lib/job-drawer.d.ts +128 -0
  368. package/dist/lib/job-drawer.d.ts.map +1 -0
  369. package/dist/lib/job-drawer.js +351 -0
  370. package/dist/lib/job-drawer.js.map +1 -0
  371. package/dist/lib/job-view.d.ts +187 -0
  372. package/dist/lib/job-view.d.ts.map +1 -0
  373. package/dist/lib/job-view.js +363 -0
  374. package/dist/lib/job-view.js.map +1 -0
  375. package/dist/lib/jobs-service.d.ts +134 -0
  376. package/dist/lib/jobs-service.d.ts.map +1 -0
  377. package/dist/lib/jobs-service.js +179 -0
  378. package/dist/lib/jobs-service.js.map +1 -0
  379. package/dist/lib/sheet-focus.d.ts +24 -0
  380. package/dist/lib/sheet-focus.d.ts.map +1 -0
  381. package/dist/lib/sheet-focus.js +61 -0
  382. package/dist/lib/sheet-focus.js.map +1 -0
  383. package/dist/lib/tiers.d.ts +30 -0
  384. package/dist/lib/tiers.d.ts.map +1 -0
  385. package/dist/lib/tiers.js +43 -0
  386. package/dist/lib/tiers.js.map +1 -0
  387. package/dist/prenta-admin.css +1 -1
  388. package/dist/router/admin-routes.d.ts.map +1 -1
  389. package/dist/router/admin-routes.js +8 -0
  390. package/dist/router/admin-routes.js.map +1 -1
  391. package/dist/router/index.d.ts +5 -1
  392. package/dist/router/index.d.ts.map +1 -1
  393. package/dist/router/index.js +7 -0
  394. package/dist/router/index.js.map +1 -1
  395. package/dist/views/ApiKeys.js +2 -2
  396. package/dist/views/ApiKeys.js.map +1 -1
  397. package/dist/views/AppearanceChrome.d.ts +6 -0
  398. package/dist/views/AppearanceChrome.d.ts.map +1 -0
  399. package/dist/views/AppearanceChrome.js +25 -0
  400. package/dist/views/AppearanceChrome.js.map +1 -0
  401. package/dist/views/CollectionList.d.ts.map +1 -1
  402. package/dist/views/CollectionList.js +73 -53
  403. package/dist/views/CollectionList.js.map +1 -1
  404. package/dist/views/Dashboard.d.ts.map +1 -1
  405. package/dist/views/Dashboard.js +14 -8
  406. package/dist/views/Dashboard.js.map +1 -1
  407. package/dist/views/DocumentEdit.d.ts +6 -1
  408. package/dist/views/DocumentEdit.d.ts.map +1 -1
  409. package/dist/views/DocumentEdit.js +44 -8
  410. package/dist/views/DocumentEdit.js.map +1 -1
  411. package/dist/views/FormDeliveries.d.ts.map +1 -1
  412. package/dist/views/FormDeliveries.js +7 -1
  413. package/dist/views/FormDeliveries.js.map +1 -1
  414. package/dist/views/FormEntries.d.ts.map +1 -1
  415. package/dist/views/FormEntries.js +11 -2
  416. package/dist/views/FormEntries.js.map +1 -1
  417. package/dist/views/FormSubmissions.d.ts +1 -1
  418. package/dist/views/FormSubmissions.d.ts.map +1 -1
  419. package/dist/views/FormSubmissions.js +15 -4
  420. package/dist/views/FormSubmissions.js.map +1 -1
  421. package/dist/views/Forms.d.ts.map +1 -1
  422. package/dist/views/Forms.js +6 -4
  423. package/dist/views/Forms.js.map +1 -1
  424. package/dist/views/FormsSettings.d.ts +2 -0
  425. package/dist/views/FormsSettings.d.ts.map +1 -0
  426. package/dist/views/FormsSettings.js +37 -0
  427. package/dist/views/FormsSettings.js.map +1 -0
  428. package/dist/views/Jobs/BusyButton.d.ts +15 -0
  429. package/dist/views/Jobs/BusyButton.d.ts.map +1 -0
  430. package/dist/views/Jobs/BusyButton.js +26 -0
  431. package/dist/views/Jobs/BusyButton.js.map +1 -0
  432. package/dist/views/Jobs/CancelJobDialog.d.ts +21 -0
  433. package/dist/views/Jobs/CancelJobDialog.d.ts.map +1 -0
  434. package/dist/views/Jobs/CancelJobDialog.js +66 -0
  435. package/dist/views/Jobs/CancelJobDialog.js.map +1 -0
  436. package/dist/views/Jobs/DrawerActivity.d.ts +16 -0
  437. package/dist/views/Jobs/DrawerActivity.d.ts.map +1 -0
  438. package/dist/views/Jobs/DrawerActivity.js +59 -0
  439. package/dist/views/Jobs/DrawerActivity.js.map +1 -0
  440. package/dist/views/Jobs/DrawerOverview.d.ts +28 -0
  441. package/dist/views/Jobs/DrawerOverview.d.ts.map +1 -0
  442. package/dist/views/Jobs/DrawerOverview.js +32 -0
  443. package/dist/views/Jobs/DrawerOverview.js.map +1 -0
  444. package/dist/views/Jobs/DrawerResults.d.ts +25 -0
  445. package/dist/views/Jobs/DrawerResults.d.ts.map +1 -0
  446. package/dist/views/Jobs/DrawerResults.js +50 -0
  447. package/dist/views/Jobs/DrawerResults.js.map +1 -0
  448. package/dist/views/Jobs/DrawerReview.d.ts +44 -0
  449. package/dist/views/Jobs/DrawerReview.d.ts.map +1 -0
  450. package/dist/views/Jobs/DrawerReview.js +110 -0
  451. package/dist/views/Jobs/DrawerReview.js.map +1 -0
  452. package/dist/views/Jobs/JobDrawer.d.ts +31 -0
  453. package/dist/views/Jobs/JobDrawer.d.ts.map +1 -0
  454. package/dist/views/Jobs/JobDrawer.js +353 -0
  455. package/dist/views/Jobs/JobDrawer.js.map +1 -0
  456. package/dist/views/Jobs/JobsTable.d.ts +19 -0
  457. package/dist/views/Jobs/JobsTable.d.ts.map +1 -0
  458. package/dist/views/Jobs/JobsTable.js +80 -0
  459. package/dist/views/Jobs/JobsTable.js.map +1 -0
  460. package/dist/views/Jobs/WorkerStrip.d.ts +22 -0
  461. package/dist/views/Jobs/WorkerStrip.d.ts.map +1 -0
  462. package/dist/views/Jobs/WorkerStrip.js +63 -0
  463. package/dist/views/Jobs/WorkerStrip.js.map +1 -0
  464. package/dist/views/Jobs/atoms.d.ts +19 -0
  465. package/dist/views/Jobs/atoms.d.ts.map +1 -0
  466. package/dist/views/Jobs/atoms.js +52 -0
  467. package/dist/views/Jobs/atoms.js.map +1 -0
  468. package/dist/views/Jobs/focus.d.ts +23 -0
  469. package/dist/views/Jobs/focus.d.ts.map +1 -0
  470. package/dist/views/Jobs/focus.js +54 -0
  471. package/dist/views/Jobs/focus.js.map +1 -0
  472. package/dist/views/Jobs/icons.d.ts +22 -0
  473. package/dist/views/Jobs/icons.d.ts.map +1 -0
  474. package/dist/views/Jobs/icons.js +23 -0
  475. package/dist/views/Jobs/icons.js.map +1 -0
  476. package/dist/views/Jobs/placeholders.d.ts +6 -0
  477. package/dist/views/Jobs/placeholders.d.ts.map +1 -0
  478. package/dist/views/Jobs/placeholders.js +20 -0
  479. package/dist/views/Jobs/placeholders.js.map +1 -0
  480. package/dist/views/Jobs/useJobDetail.d.ts +21 -0
  481. package/dist/views/Jobs/useJobDetail.d.ts.map +1 -0
  482. package/dist/views/Jobs/useJobDetail.js +39 -0
  483. package/dist/views/Jobs/useJobDetail.js.map +1 -0
  484. package/dist/views/Jobs/useJobsFeed.d.ts +35 -0
  485. package/dist/views/Jobs/useJobsFeed.d.ts.map +1 -0
  486. package/dist/views/Jobs/useJobsFeed.js +231 -0
  487. package/dist/views/Jobs/useJobsFeed.js.map +1 -0
  488. package/dist/views/Jobs/useReviewItems.d.ts +39 -0
  489. package/dist/views/Jobs/useReviewItems.d.ts.map +1 -0
  490. package/dist/views/Jobs/useReviewItems.js +140 -0
  491. package/dist/views/Jobs/useReviewItems.js.map +1 -0
  492. package/dist/views/Jobs.d.ts +10 -1
  493. package/dist/views/Jobs.d.ts.map +1 -1
  494. package/dist/views/Jobs.js +126 -35
  495. package/dist/views/Jobs.js.map +1 -1
  496. package/dist/views/MediaBrowser.d.ts.map +1 -1
  497. package/dist/views/MediaBrowser.js +37 -9
  498. package/dist/views/MediaBrowser.js.map +1 -1
  499. package/dist/views/Pages/PagesListView.d.ts +1 -1
  500. package/dist/views/Pages/PagesListView.d.ts.map +1 -1
  501. package/dist/views/Pages/PagesListView.js +34 -5
  502. package/dist/views/Pages/PagesListView.js.map +1 -1
  503. package/dist/views/Posts/NewPostTypeInstructions.d.ts.map +1 -1
  504. package/dist/views/Posts/NewPostTypeInstructions.js +12 -2
  505. package/dist/views/Posts/NewPostTypeInstructions.js.map +1 -1
  506. package/dist/views/Posts/PostTypesView.d.ts.map +1 -1
  507. package/dist/views/Posts/PostTypesView.js +10 -1
  508. package/dist/views/Posts/PostTypesView.js.map +1 -1
  509. package/dist/views/Posts/PostsListView.d.ts +1 -2
  510. package/dist/views/Posts/PostsListView.d.ts.map +1 -1
  511. package/dist/views/Posts/PostsListView.js +31 -3
  512. package/dist/views/Posts/PostsListView.js.map +1 -1
  513. package/dist/views/SEO.d.ts.map +1 -1
  514. package/dist/views/SEO.js +3 -3
  515. package/dist/views/SEO.js.map +1 -1
  516. package/dist/views/ScriptTags.d.ts.map +1 -1
  517. package/dist/views/ScriptTags.js +20 -15
  518. package/dist/views/ScriptTags.js.map +1 -1
  519. package/dist/views/Settings.d.ts.map +1 -1
  520. package/dist/views/Settings.js +115 -51
  521. package/dist/views/Settings.js.map +1 -1
  522. package/dist/views/SpamFolder.d.ts +2 -0
  523. package/dist/views/SpamFolder.d.ts.map +1 -0
  524. package/dist/views/SpamFolder.js +14 -0
  525. package/dist/views/SpamFolder.js.map +1 -0
  526. package/dist/views/Trash.d.ts +6 -1
  527. package/dist/views/Trash.d.ts.map +1 -1
  528. package/dist/views/Trash.js +7 -2
  529. package/dist/views/Trash.js.map +1 -1
  530. package/dist/views/Users.js +2 -2
  531. package/dist/views/Users.js.map +1 -1
  532. package/dist/views/WidgetsPlaceholder.d.ts +2 -0
  533. package/dist/views/WidgetsPlaceholder.d.ts.map +1 -0
  534. package/dist/views/WidgetsPlaceholder.js +15 -0
  535. package/dist/views/WidgetsPlaceholder.js.map +1 -0
  536. package/dist/views/dashboard/kpi-grid.d.ts +18 -0
  537. package/dist/views/dashboard/kpi-grid.d.ts.map +1 -0
  538. package/dist/views/dashboard/kpi-grid.js +36 -0
  539. package/dist/views/dashboard/kpi-grid.js.map +1 -0
  540. package/dist/views/lazy-views.d.ts +4 -0
  541. package/dist/views/lazy-views.d.ts.map +1 -1
  542. package/dist/views/lazy-views.js +4 -0
  543. package/dist/views/lazy-views.js.map +1 -1
  544. package/dist/views/page-editor/PageTab.js +1 -1
  545. package/dist/views/page-editor/PageTab.js.map +1 -1
  546. package/dist/views/page-editor/ReviewBar.js +1 -1
  547. package/dist/views/page-editor/ReviewBar.js.map +1 -1
  548. package/dist/views/page-editor/VersionHistoryPanel.js +1 -1
  549. package/dist/views/page-editor/VersionHistoryPanel.js.map +1 -1
  550. package/dist/views/seo/AuditTab.js +1 -1
  551. package/dist/views/seo/AuditTab.js.map +1 -1
  552. package/dist/views/seo/OverviewTab.d.ts.map +1 -1
  553. package/dist/views/seo/OverviewTab.js +2 -2
  554. package/dist/views/seo/OverviewTab.js.map +1 -1
  555. package/dist/views/seo/ProposalsTab.js +1 -1
  556. package/dist/views/seo/ProposalsTab.js.map +1 -1
  557. package/dist/views/settings/AISettingsTab.d.ts.map +1 -1
  558. package/dist/views/settings/AISettingsTab.js +4 -2
  559. package/dist/views/settings/AISettingsTab.js.map +1 -1
  560. package/dist/views/settings/AccessProtectionCard.js +1 -1
  561. package/dist/views/settings/AccessProtectionCard.js.map +1 -1
  562. package/dist/views/settings/AdminThemeCard.d.ts.map +1 -1
  563. package/dist/views/settings/AdminThemeCard.js +63 -15
  564. package/dist/views/settings/AdminThemeCard.js.map +1 -1
  565. package/dist/views/settings/AppearanceTab.d.ts.map +1 -1
  566. package/dist/views/settings/AppearanceTab.js +4 -2
  567. package/dist/views/settings/AppearanceTab.js.map +1 -1
  568. package/dist/views/settings/BrandPreviewCard.js +1 -1
  569. package/dist/views/settings/BrandPreviewCard.js.map +1 -1
  570. package/dist/views/settings/BrandVoiceCard.js +1 -1
  571. package/dist/views/settings/BrandVoiceCard.js.map +1 -1
  572. package/dist/views/settings/EmailSettingsTab.d.ts.map +1 -1
  573. package/dist/views/settings/EmailSettingsTab.js +5 -3
  574. package/dist/views/settings/EmailSettingsTab.js.map +1 -1
  575. package/dist/views/settings/GeneralSettingsTab.d.ts.map +1 -1
  576. package/dist/views/settings/GeneralSettingsTab.js +4 -2
  577. package/dist/views/settings/GeneralSettingsTab.js.map +1 -1
  578. package/dist/views/settings/McpConnectTab.d.ts.map +1 -1
  579. package/dist/views/settings/McpConnectTab.js +1 -1
  580. package/dist/views/settings/McpConnectTab.js.map +1 -1
  581. package/dist/views/settings/ProviderConnectionCard.js +1 -1
  582. package/dist/views/settings/ProviderConnectionCard.js.map +1 -1
  583. package/dist/views/settings/SearchDataCard.js +1 -1
  584. package/dist/views/settings/SearchDataCard.js.map +1 -1
  585. package/dist/views/settings/SecurityStatusCard.js +2 -2
  586. package/dist/views/settings/SecurityStatusCard.js.map +1 -1
  587. package/dist/views/settings/SecurityTab.d.ts.map +1 -1
  588. package/dist/views/settings/SecurityTab.js +4 -2
  589. package/dist/views/settings/SecurityTab.js.map +1 -1
  590. package/dist/views/settings/SeoAutopilotCard.js +2 -2
  591. package/dist/views/settings/SeoAutopilotCard.js.map +1 -1
  592. package/dist/views/settings/SeoSettingsTab.d.ts.map +1 -1
  593. package/dist/views/settings/SeoSettingsTab.js +5 -3
  594. package/dist/views/settings/SeoSettingsTab.js.map +1 -1
  595. package/dist/views/settings/SiteIndexStatusCard.js +1 -1
  596. package/dist/views/settings/SiteIndexStatusCard.js.map +1 -1
  597. package/dist/views/settings/SiteThemeCard.js +1 -1
  598. package/dist/views/settings/UpdatesTab.d.ts.map +1 -1
  599. package/dist/views/settings/UpdatesTab.js +6 -5
  600. package/dist/views/settings/UpdatesTab.js.map +1 -1
  601. package/dist/views/settings/components.d.ts +7 -11
  602. package/dist/views/settings/components.d.ts.map +1 -1
  603. package/dist/views/settings/components.js +18 -12
  604. package/dist/views/settings/components.js.map +1 -1
  605. package/dist/views/settings/useAppearanceSettings.d.ts +7 -1
  606. package/dist/views/settings/useAppearanceSettings.d.ts.map +1 -1
  607. package/dist/views/settings/useAppearanceSettings.js +89 -22
  608. package/dist/views/settings/useAppearanceSettings.js.map +1 -1
  609. package/dist/views/users/UserDetailDrawer.js +1 -1
  610. package/dist/views/users/UserDetailDrawer.js.map +1 -1
  611. package/package.json +11 -9
  612. package/src/AdminRoot.tsx +88 -30
  613. package/src/LoginRoot.tsx +2 -1
  614. package/src/__tests__/components/author-avatar.test.tsx +3 -20
  615. package/src/__tests__/components/notification-bell.test.tsx +146 -14
  616. package/src/__tests__/components/responsive-tiers.render.test.tsx +461 -0
  617. package/src/__tests__/components/serp-preview.render.test.tsx +6 -3
  618. package/src/__tests__/components/shell-primitives.render.test.tsx +951 -0
  619. package/src/__tests__/components/theme-provider-accent.test.tsx +83 -8
  620. package/src/__tests__/components/toggle.test.tsx +11 -3
  621. package/src/__tests__/components/ui-primitives.test.tsx +5 -8
  622. package/src/__tests__/layout/build-nav-items.test.ts +1 -1
  623. package/src/__tests__/layout/shell-nav.render.test.tsx +983 -0
  624. package/src/__tests__/layout/sidebar-forms-submenu.render.test.tsx +8 -4
  625. package/src/__tests__/layout/sidebar-groups.render.test.tsx +116 -0
  626. package/src/__tests__/layout/sidebar-menus.render.test.tsx +116 -0
  627. package/src/__tests__/layout/sidebar-plugin-nav.test.ts +1 -1
  628. package/src/__tests__/layout/sidebar-posts.test.ts +48 -40
  629. package/src/__tests__/layout/sidebar-submenu.render.test.tsx +35 -10
  630. package/src/__tests__/layout/topbar.render.test.tsx +464 -0
  631. package/src/__tests__/lib/api.test.ts +2 -0
  632. package/src/__tests__/lib/job-drawer.test.ts +493 -0
  633. package/src/__tests__/lib/job-view.test.ts +437 -0
  634. package/src/__tests__/lib/jobs-service.test.ts +98 -0
  635. package/src/__tests__/router/admin-route-order.test.ts +39 -0
  636. package/src/__tests__/styles/ai-gradient-contrast.test.ts +135 -0
  637. package/src/__tests__/styles/breakpoint-order.test.ts +68 -0
  638. package/src/__tests__/styles/responsive-layer.test.ts +367 -12
  639. package/src/__tests__/styles/tailwind-preset.test.ts +154 -0
  640. package/src/__tests__/styles/theme-token-scope.test.ts +10 -3
  641. package/src/__tests__/styles/tiers.test.ts +136 -0
  642. package/src/__tests__/styles/tokens-drift.test.ts +67 -6
  643. package/src/__tests__/views/admin-lazy-route.render.test.tsx +41 -1
  644. package/src/__tests__/views/ai-settings.render.test.tsx +4 -4
  645. package/src/__tests__/views/appearance-menus-route.render.test.tsx +58 -0
  646. package/src/__tests__/views/appearance-settings.render.test.tsx +10 -8
  647. package/src/__tests__/views/appearance-theme-provider.render.test.tsx +347 -0
  648. package/src/__tests__/views/dashboard.test.tsx +48 -0
  649. package/src/__tests__/views/document-edit-navigation.render.test.tsx +130 -0
  650. package/src/__tests__/views/document-edit-routes.render.test.tsx +130 -0
  651. package/src/__tests__/views/email-settings.render.test.tsx +2 -2
  652. package/src/__tests__/views/form-entries.render.test.tsx +22 -0
  653. package/src/__tests__/views/form-submissions.render.test.tsx +22 -0
  654. package/src/__tests__/views/forms-list.render.test.tsx +13 -0
  655. package/src/__tests__/views/general-settings.render.test.tsx +38 -11
  656. package/src/__tests__/views/jobs-drawer.render.test.tsx +1047 -0
  657. package/src/__tests__/views/jobs-list.render.test.tsx +850 -0
  658. package/src/__tests__/views/kpi-grid.test.ts +29 -0
  659. package/src/__tests__/views/mcp-connect.render.test.tsx +1 -0
  660. package/src/__tests__/views/post-section-editor.test.tsx +5 -1
  661. package/src/__tests__/views/script-tags.render.test.tsx +29 -0
  662. package/src/__tests__/views/security-settings.render.test.tsx +9 -10
  663. package/src/__tests__/views/seo-settings.render.test.tsx +7 -9
  664. package/src/__tests__/views/settings-save-bar.render.test.tsx +91 -0
  665. package/src/__tests__/views/settings-save-footer.render.test.tsx +25 -15
  666. package/src/__tests__/views/settings-tabs.render.test.tsx +371 -0
  667. package/src/__tests__/views/updates-tab.render.test.tsx +4 -3
  668. package/src/components/Breadcrumbs.tsx +7 -1
  669. package/src/components/CommandPalette.tsx +51 -3
  670. package/src/components/LocaleSwitcher.tsx +5 -6
  671. package/src/components/NotificationBell.tsx +74 -18
  672. package/src/components/OfflineStatus.tsx +1 -1
  673. package/src/components/PresenceIndicator.tsx +2 -1
  674. package/src/components/ReflowMeter.tsx +3 -3
  675. package/src/components/SEOPanel.tsx +2 -2
  676. package/src/components/ThemeProvider.tsx +122 -42
  677. package/src/components/TipTapEditor.tsx +3 -4
  678. package/src/components/forms/EmbedPanel.tsx +1 -1
  679. package/src/components/forms/FormEntryDetailPane.tsx +7 -1
  680. package/src/components/forms/ShortcodeGlossary.tsx +7 -1
  681. package/src/components/forms/primitives.tsx +37 -21
  682. package/src/components/pages/tag-badges.tsx +4 -3
  683. package/src/components/seo/PageAuditPanel.tsx +2 -2
  684. package/src/components/seo/SerpPreview.tsx +5 -5
  685. package/src/components/seo/primitives.tsx +2 -2
  686. package/src/components/ui/AuthorAvatar.tsx +11 -10
  687. package/src/components/ui/Badge.tsx +1 -1
  688. package/src/components/ui/Breadcrumb.tsx +109 -0
  689. package/src/components/ui/Button.tsx +40 -15
  690. package/src/components/ui/Card.tsx +35 -32
  691. package/src/components/ui/CardListControls.tsx +90 -0
  692. package/src/components/ui/CountChip.tsx +90 -0
  693. package/src/components/ui/FilterPill.tsx +5 -3
  694. package/src/components/ui/InspectorPane.tsx +21 -7
  695. package/src/components/ui/Modal.tsx +20 -6
  696. package/src/components/ui/PageHeader.tsx +63 -0
  697. package/src/components/ui/RowActions.tsx +7 -2
  698. package/src/components/ui/Segmented.tsx +97 -0
  699. package/src/components/ui/Toaster.tsx +139 -0
  700. package/src/components/ui/Toggle.tsx +18 -14
  701. package/src/components/ui/UnderlineTabs.tsx +373 -0
  702. package/src/components/ui/UnsavedBar.tsx +119 -0
  703. package/src/components/ui/admin-links.tsx +20 -0
  704. package/src/components/ui/card-table.ts +34 -0
  705. package/src/components/virtual-window.tsx +13 -2
  706. package/src/fields/RelationshipField.tsx +1 -1
  707. package/src/hooks/useAppearanceBootstrap.ts +9 -3
  708. package/src/index.ts +19 -0
  709. package/src/layout/Header.tsx +210 -135
  710. package/src/layout/Layout.tsx +61 -108
  711. package/src/layout/MobileTabBar.tsx +92 -0
  712. package/src/layout/Sidebar.tsx +555 -593
  713. package/src/layout/nav-config.tsx +425 -0
  714. package/src/layout/primitives/AdminShell.tsx +154 -6
  715. package/src/layout/topbar-classes.ts +8 -0
  716. package/src/layout/use-nav-items.ts +40 -0
  717. package/src/lib/api.ts +7 -1
  718. package/src/lib/appearance-api.ts +4 -0
  719. package/src/lib/job-drawer.ts +424 -0
  720. package/src/lib/job-view.ts +456 -0
  721. package/src/lib/jobs-service.ts +290 -0
  722. package/src/lib/sheet-focus.ts +71 -0
  723. package/src/lib/tiers.ts +43 -0
  724. package/src/router/admin-routes.ts +8 -0
  725. package/src/router/index.ts +9 -1
  726. package/src/styles/prenta-tokens.css +263 -82
  727. package/src/styles/responsive.css +460 -22
  728. package/src/styles/theme.css +177 -28
  729. package/src/views/ApiKeys.tsx +2 -2
  730. package/src/views/AppearanceChrome.tsx +74 -0
  731. package/src/views/CollectionList.tsx +264 -205
  732. package/src/views/Dashboard.tsx +26 -13
  733. package/src/views/DocumentEdit.tsx +111 -56
  734. package/src/views/FormDeliveries.tsx +30 -17
  735. package/src/views/FormEntries.tsx +28 -20
  736. package/src/views/FormSubmissions.tsx +32 -34
  737. package/src/views/Forms.tsx +55 -34
  738. package/src/views/FormsSettings.tsx +94 -0
  739. package/src/views/Jobs/BusyButton.tsx +56 -0
  740. package/src/views/Jobs/CancelJobDialog.tsx +127 -0
  741. package/src/views/Jobs/DrawerActivity.tsx +142 -0
  742. package/src/views/Jobs/DrawerOverview.tsx +139 -0
  743. package/src/views/Jobs/DrawerResults.tsx +155 -0
  744. package/src/views/Jobs/DrawerReview.tsx +464 -0
  745. package/src/views/Jobs/JobDrawer.tsx +556 -0
  746. package/src/views/Jobs/JobsTable.tsx +260 -0
  747. package/src/views/Jobs/WorkerStrip.tsx +144 -0
  748. package/src/views/Jobs/atoms.tsx +93 -0
  749. package/src/views/Jobs/focus.ts +56 -0
  750. package/src/views/Jobs/icons.tsx +111 -0
  751. package/src/views/Jobs/placeholders.tsx +66 -0
  752. package/src/views/Jobs/useJobDetail.ts +64 -0
  753. package/src/views/Jobs/useJobsFeed.ts +249 -0
  754. package/src/views/Jobs/useReviewItems.ts +187 -0
  755. package/src/views/Jobs.tsx +282 -105
  756. package/src/views/MediaBrowser.tsx +71 -21
  757. package/src/views/Pages/PagesListView.tsx +115 -39
  758. package/src/views/Posts/NewPostTypeInstructions.tsx +15 -10
  759. package/src/views/Posts/PostTypesView.tsx +28 -6
  760. package/src/views/Posts/PostsListView.tsx +130 -40
  761. package/src/views/SEO.tsx +23 -8
  762. package/src/views/ScriptTags.tsx +233 -153
  763. package/src/views/Settings.tsx +215 -256
  764. package/src/views/SpamFolder.tsx +32 -0
  765. package/src/views/Trash.tsx +12 -1
  766. package/src/views/Users.tsx +2 -2
  767. package/src/views/WidgetsPlaceholder.tsx +33 -0
  768. package/src/views/dashboard/kpi-grid.ts +38 -0
  769. package/src/views/lazy-views.tsx +12 -0
  770. package/src/views/page-editor/PageTab.tsx +2 -2
  771. package/src/views/page-editor/ReviewBar.tsx +1 -1
  772. package/src/views/page-editor/VersionHistoryPanel.tsx +1 -1
  773. package/src/views/seo/AuditTab.tsx +1 -1
  774. package/src/views/seo/OverviewTab.tsx +6 -5
  775. package/src/views/seo/ProposalsTab.tsx +1 -1
  776. package/src/views/settings/AISettingsTab.tsx +10 -6
  777. package/src/views/settings/AccessProtectionCard.tsx +1 -1
  778. package/src/views/settings/AdminThemeCard.tsx +228 -35
  779. package/src/views/settings/AppearanceTab.tsx +10 -6
  780. package/src/views/settings/BrandPreviewCard.tsx +1 -1
  781. package/src/views/settings/BrandVoiceCard.tsx +1 -1
  782. package/src/views/settings/EmailSettingsTab.tsx +11 -7
  783. package/src/views/settings/GeneralSettingsTab.tsx +10 -6
  784. package/src/views/settings/McpConnectTab.tsx +2 -1
  785. package/src/views/settings/ProviderConnectionCard.tsx +1 -1
  786. package/src/views/settings/SearchDataCard.tsx +1 -1
  787. package/src/views/settings/SecurityStatusCard.tsx +2 -2
  788. package/src/views/settings/SecurityTab.tsx +10 -6
  789. package/src/views/settings/SeoAutopilotCard.tsx +2 -2
  790. package/src/views/settings/SeoSettingsTab.tsx +13 -9
  791. package/src/views/settings/SiteIndexStatusCard.tsx +1 -1
  792. package/src/views/settings/SiteThemeCard.tsx +1 -1
  793. package/src/views/settings/UpdatesTab.tsx +107 -101
  794. package/src/views/settings/components.tsx +26 -62
  795. package/src/views/settings/useAppearanceSettings.ts +116 -25
  796. package/src/views/users/UserDetailDrawer.tsx +1 -1
  797. package/dist/components/ui/StatPill.d.ts +0 -18
  798. package/dist/components/ui/StatPill.d.ts.map +0 -1
  799. package/dist/components/ui/StatPill.js +0 -5
  800. package/dist/components/ui/StatPill.js.map +0 -1
  801. package/src/components/ui/StatPill.tsx +0 -37
@@ -1,18 +1,7 @@
1
1
  'use client'
2
2
 
3
- import * as Tabs from '@radix-ui/react-tabs'
4
- import {
5
- Bot,
6
- Loader2,
7
- AlertTriangle,
8
- Download,
9
- Layers,
10
- Mail,
11
- Users as UsersIcon,
12
- KeyRound,
13
- Plug,
14
- } from 'lucide-react'
15
- import { useState, useEffect, useCallback, useMemo } from 'react'
3
+ import { Loader2, AlertTriangle } from 'lucide-react'
4
+ import { useState, useEffect, useCallback, useMemo, type ReactNode } from 'react'
16
5
  import { toast } from 'sonner'
17
6
  import { parseRouteQuery } from '../router/index.js'
18
7
  import { useApiData } from '../lib/useApiData.js'
@@ -25,6 +14,10 @@ import { EmailSettingsTab } from './settings/EmailSettingsTab.js'
25
14
  import { AppearanceTab } from './settings/AppearanceTab.js'
26
15
  import { SecurityTab } from './settings/SecurityTab.js'
27
16
  import { SettingsCard } from './settings/components.js'
17
+ import { PageHeader } from '../components/ui/PageHeader.js'
18
+ import { UnderlineTabPanel, UnderlineTabs } from '../components/ui/UnderlineTabs.js'
19
+ import { UnsavedBar } from '../components/ui/UnsavedBar.js'
20
+ import { SETTINGS_TABS } from '../layout/nav-config.js'
28
21
  import { UpdatesTab } from './settings/UpdatesTab.js'
29
22
  import { WebhooksTab } from './settings/WebhooksTab.js'
30
23
  import { Users as UsersView } from './Users.js'
@@ -44,18 +37,30 @@ export interface SettingsProps {
44
37
  currentPath?: string
45
38
  }
46
39
 
40
+ /** Every tab id, in strip order. `layout` exists only with layout regions. */
41
+ const SETTINGS_TAB_IDS: readonly string[] = SETTINGS_TABS.map((tab) => tab.id)
42
+
43
+ /** Kit tab ids (Settings.html `#hash`) that differ from the `?tab=` ids. */
44
+ const KIT_HASH_TABS: Record<string, string> = { keys: 'api-keys' }
45
+
47
46
  /**
48
- * Tabs that persist through the shared footer's `handleSave` (which writes
49
- * `defaultLayout` into the settings global). Every other tab owns its own
50
- * saving, so the footer must NOT render there — otherwise it shows a
51
- * "Settings saved successfully!" toast while persisting nothing relevant.
52
- * This is an allowlist on purpose: new tabs default to self-managed.
47
+ * The tab in the URL: `?tab=appearance`, else the kit's `#appearance` form,
48
+ * so links written against the prototype land on the same tab. A hash that
49
+ * names no tab is ignored, so the route's own `initialTab` still applies.
53
50
  */
54
- const GLOBAL_SAVE_TABS = new Set(['layout'])
55
-
56
51
  function readSettingsTabFromUrl(): string | null {
57
52
  if (typeof window === 'undefined') return null
58
- return parseRouteQuery(window.location.search).get('tab')
53
+ const fromQuery = parseRouteQuery(window.location.search).get('tab')
54
+ if (fromQuery) return fromQuery
55
+ const hash = window.location.hash.slice(1)
56
+ const fromHash = KIT_HASH_TABS[hash] ?? hash
57
+ return SETTINGS_TAB_IDS.includes(fromHash) ? fromHash : null
58
+ }
59
+
60
+ /** Same regions with the same variants, whatever the key order. */
61
+ function sameLayout(a: Record<string, string>, b: Record<string, string>): boolean {
62
+ const keys = Object.keys(a)
63
+ return keys.length === Object.keys(b).length && keys.every((k) => a[k] === b[k])
59
64
  }
60
65
 
61
66
  export function Settings({
@@ -70,8 +75,10 @@ export function Settings({
70
75
  const [activeTab, setActiveTab] = useState<string>(() => readSettingsTabFromUrl() ?? initialTab)
71
76
  const [saving, setSaving] = useState(false)
72
77
 
73
- // Layout defaults
78
+ // Layout defaults, and the last saved copy the Layout tab's bar diffs against.
74
79
  const [defaultLayout, setDefaultLayout] = useState<Record<string, string>>({})
80
+ const [savedLayout, setSavedLayout] = useState<Record<string, string>>({})
81
+ const layoutDirty = !sameLayout(defaultLayout, savedLayout)
75
82
  const layoutConfig = config?.layout
76
83
  const layoutRegions: Array<{ name: string; collection: string; label: string }> =
77
84
  layoutConfig?.regions
@@ -86,40 +93,48 @@ export function Settings({
86
93
  // Valid tab ids, with `layout` only available when the project configures
87
94
  // layout regions. Used to normalise deep links and keep the URL honest.
88
95
  const availableTabs = useMemo(
89
- () =>
90
- [
91
- 'general',
92
- 'appearance',
93
- ...(hasLayoutRegions ? ['layout'] : []),
94
- 'security',
95
- 'users',
96
- 'mcp',
97
- 'api-keys',
98
- 'seo',
99
- 'email',
100
- 'webhooks',
101
- 'ai',
102
- 'updates',
103
- ] as const,
96
+ () => SETTINGS_TABS.filter((tab) => tab.id !== 'layout' || hasLayoutRegions),
104
97
  [hasLayoutRegions],
105
98
  )
106
99
  const normalizeTab = useCallback(
107
100
  (tab: string | null | undefined): string =>
108
- tab && (availableTabs as readonly string[]).includes(tab) ? tab : 'general',
101
+ tab && availableTabs.some((available) => available.id === tab) ? tab : 'general',
102
+ [availableTabs],
103
+ )
104
+ // Settings.html `TABS`: each tab with its 15px icon.
105
+ const stripTabs = useMemo(
106
+ () =>
107
+ availableTabs.map(({ id, label, icon: Icon }) => ({
108
+ id,
109
+ label,
110
+ icon: <Icon strokeWidth={1.8} />,
111
+ })),
109
112
  [availableTabs],
110
113
  )
111
114
 
112
115
  // Drive the active tab from the `?tab=` query param so tabs are deep-linkable
113
116
  // and survive browser back/forward (the legacy /users and /api-keys routes
114
- // land here via `initialTab`).
117
+ // land here via `initialTab`). Re-read on in-app navigation too: the mobile
118
+ // nav drawer links straight to `/settings?tab=…`.
115
119
  useEffect(() => {
116
120
  function sync() {
117
- setActiveTab(normalizeTab(readSettingsTabFromUrl() ?? initialTab))
121
+ const fromUrl = readSettingsTabFromUrl()
122
+ // A hash that names no tab (the skip link's `#prenta-main`, an in-page
123
+ // anchor) is not a tab change: keep the open tab, if it exists here.
124
+ if (fromUrl === null && window.location.hash) {
125
+ setActiveTab((current) => normalizeTab(current))
126
+ return
127
+ }
128
+ setActiveTab(normalizeTab(fromUrl ?? initialTab))
118
129
  }
119
130
  sync()
120
131
  window.addEventListener('popstate', sync)
121
- return () => window.removeEventListener('popstate', sync)
122
- }, [normalizeTab, initialTab])
132
+ window.addEventListener('hashchange', sync)
133
+ return () => {
134
+ window.removeEventListener('popstate', sync)
135
+ window.removeEventListener('hashchange', sync)
136
+ }
137
+ }, [normalizeTab, initialTab, currentPath])
123
138
 
124
139
  const changeTab = useCallback(
125
140
  (tab: string) => {
@@ -134,252 +149,196 @@ export function Settings({
134
149
  if (data) {
135
150
  if (data.defaultLayout && typeof data.defaultLayout === 'object') {
136
151
  setDefaultLayout(data.defaultLayout)
152
+ setSavedLayout(data.defaultLayout)
137
153
  }
138
154
  }
139
155
  }, [data])
140
156
 
141
- const handleSave = async () => {
157
+ const saveLayout = async () => {
142
158
  setSaving(true)
143
- const layoutPayload = Object.keys(defaultLayout).length > 0 ? { defaultLayout } : {}
159
+ const layout = defaultLayout
144
160
  // Read-modify-write: the General tab owns site info / SEO defaults in the
145
161
  // same global blob, so merge against a fresh fetch instead of overwriting.
162
+ // A failed read must not turn into a write of `defaultLayout` alone.
146
163
  const current = await cmsApi<Record<string, unknown>>('/globals/settings')
164
+ if (current.error) {
165
+ setSaving(false)
166
+ toast.error(current.error)
167
+ return
168
+ }
169
+ // Always sent, so clearing every default is saved too (the server reads a
170
+ // missing `defaultLayout` as `{}`).
147
171
  const res = await cmsApi('/globals/settings', {
148
172
  method: 'PUT',
149
- body: JSON.stringify({
150
- ...(current.data ?? {}),
151
- ...layoutPayload,
152
- }),
173
+ body: JSON.stringify({ ...(current.data ?? {}), defaultLayout: layout }),
153
174
  })
154
175
  setSaving(false)
155
176
  if (res.error) {
156
177
  toast.error(res.error)
157
178
  } else {
158
- toast.success('Settings saved successfully!')
179
+ setSavedLayout(layout)
180
+ toast.success('Saved')
159
181
  }
160
182
  }
161
183
 
162
- const tabTriggerClass =
163
- 'text-muted-foreground hover:text-foreground data-[state=active]:border-brand data-[state=active]:text-brand px-4 py-2 text-base font-medium transition-colors data-[state=active]:border-b-2'
184
+ // One panel at a time, as Radix Tabs rendered them: each tab loads its own
185
+ // data when it opens. `className` keeps each panel's previous spacing.
186
+ const panels: Record<string, { body: ReactNode; className?: string }> = {
187
+ general: { body: <GeneralSettingsTab onNavigate={onNavigate} role={session?.user?.role} /> },
188
+ appearance: {
189
+ body: <AppearanceTab role={session?.user?.role} config={config} />,
190
+ className: 'space-y-4',
191
+ },
192
+ layout: {
193
+ body: (
194
+ <>
195
+ <SettingsCard
196
+ title="Default Layout Variants"
197
+ description="Select the default header, footer, and other layout variants used site-wide. Pages can override these individually or inherit from parent pages."
198
+ >
199
+ <div className="space-y-4">
200
+ {layoutRegions.map((region) => (
201
+ <RelationshipField
202
+ key={region.name}
203
+ label={`Default ${region.label}`}
204
+ value={defaultLayout[region.name] ?? ''}
205
+ onChange={(val) => {
206
+ setDefaultLayout((prev) => {
207
+ const next = { ...prev }
208
+ if (val && typeof val === 'string') {
209
+ next[region.name] = val
210
+ } else {
211
+ delete next[region.name]
212
+ }
213
+ return next
214
+ })
215
+ }}
216
+ relationTo={region.collection}
217
+ helpText={`The ${region.label.toLowerCase()} variant used when no page in the ancestor chain specifies one`}
218
+ />
219
+ ))}
220
+ </div>
221
+ </SettingsCard>
222
+ <SettingsCard title="How Layout Inheritance Works">
223
+ <ul className="text-muted-foreground space-y-1.5 text-sm">
224
+ <li className="flex items-start gap-2">
225
+ <span className="bg-brand/10 text-brand mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-medium">
226
+ 1
227
+ </span>
228
+ <span>
229
+ Each page can assign specific layout variants (header, footer, etc.) from the
230
+ document editor.
231
+ </span>
232
+ </li>
233
+ <li className="flex items-start gap-2">
234
+ <span className="bg-brand/10 text-brand mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-medium">
235
+ 2
236
+ </span>
237
+ <span>
238
+ Child pages automatically inherit their parent&apos;s layout. For example,{' '}
239
+ <code className="bg-muted rounded px-1 font-mono">/hampton-roads/thank-you</code>{' '}
240
+ inherits from{' '}
241
+ <code className="bg-muted rounded px-1 font-mono">/hampton-roads</code>.
242
+ </span>
243
+ </li>
244
+ <li className="flex items-start gap-2">
245
+ <span className="bg-brand/10 text-brand mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-medium">
246
+ 3
247
+ </span>
248
+ <span>
249
+ If no page in the ancestor chain sets a variant, the defaults configured above are
250
+ used.
251
+ </span>
252
+ </li>
253
+ </ul>
254
+ </SettingsCard>
255
+ <UnsavedBar
256
+ dirty={layoutDirty}
257
+ saving={saving}
258
+ onSave={saveLayout}
259
+ onDiscard={() => setDefaultLayout(savedLayout)}
260
+ discardLabel="Reset"
261
+ saveLabel="Save changes"
262
+ variant="card"
263
+ />
264
+ </>
265
+ ),
266
+ className: 'space-y-4',
267
+ },
268
+ security: {
269
+ body: <SecurityTab role={session?.user?.role} onNavigate={onNavigate} />,
270
+ className: 'space-y-4',
271
+ },
272
+ seo: {
273
+ body: <SeoSettingsTab onNavigate={onNavigate} role={session?.user?.role} />,
274
+ className: 'space-y-4',
275
+ },
276
+ email: { body: <EmailSettingsTab role={session?.user?.role} />, className: 'space-y-4' },
277
+ webhooks: { body: <WebhooksTab role={session?.user?.role} />, className: 'space-y-4' },
278
+ ai: {
279
+ body: <AISettingsTab role={session?.user?.role} config={config} />,
280
+ className: 'space-y-4',
281
+ },
282
+ users: { body: <UsersView onNavigate={onNavigate} embedded currentPath={currentPath} /> },
283
+ mcp: { body: <McpConnectTab onNavigate={onNavigate} /> },
284
+ 'api-keys': { body: <ApiKeysView onNavigate={onNavigate} embedded /> },
285
+ updates: { body: <UpdatesTab role={session?.user?.role} />, className: 'space-y-4' },
286
+ }
287
+ const panel = panels[activeTab]
164
288
 
165
289
  if (loading) {
166
290
  return (
167
- <div className="flex h-64 items-center justify-center p-3 pr-6 sm:p-4 sm:pr-8">
291
+ <div className="flex h-64 items-center justify-center px-[var(--gut)] pt-6">
168
292
  <Loader2 className="text-primary h-6 w-6 animate-spin" />
169
293
  </div>
170
294
  )
171
295
  }
172
296
 
297
+ // Settings.html: `.pg-hdr` (24px var(--gut) 0, 16px above the strip), the
298
+ // full-width `.pg-tabs` strip with the gutter inside it, then `.scroll-area`
299
+ // (20px var(--gut)). Its 48px bottom padding is left at 16px: the kit
300
+ // cancels it under the sticky save bar with a -48px margin, which would
301
+ // pull Updates' help card over the bar.
173
302
  return (
174
- <div className="p-3 pr-6 sm:p-4 sm:pr-8">
175
- {error && (
176
- <div
177
- role="alert"
178
- className="border-destructive/30 bg-destructive/10 text-destructive mb-4 flex items-center gap-3 rounded-lg border p-3 text-sm"
179
- >
180
- <AlertTriangle size={20} className="shrink-0" aria-hidden="true" />
181
- <span className="flex-1">{error}</span>
182
- <button
183
- onClick={refetch}
184
- className="border-destructive/40 rounded-md border px-3 py-1 transition-colors hover:opacity-80"
303
+ <div className="pb-4">
304
+ <div className="px-[var(--gut)] pt-6 pb-4">
305
+ {error && (
306
+ <div
307
+ role="alert"
308
+ className="border-destructive/30 bg-destructive/10 text-destructive mb-4 flex items-center gap-3 rounded-lg border p-3 text-sm"
185
309
  >
186
- Retry
187
- </button>
188
- </div>
189
- )}
190
-
191
- <div className="mb-4">
192
- <h1 className="text-foreground mb-1">Settings</h1>
193
- <p className="text-muted-foreground text-sm">Manage your CMS configuration</p>
194
- </div>
195
-
196
- <Tabs.Root value={activeTab} onValueChange={changeTab}>
197
- <Tabs.List className="border-border mb-4 flex gap-1 overflow-x-auto border-b">
198
- <Tabs.Trigger value="general" className={tabTriggerClass}>
199
- General
200
- </Tabs.Trigger>
201
- <Tabs.Trigger value="appearance" className={tabTriggerClass}>
202
- Appearance
203
- </Tabs.Trigger>
204
- {hasLayoutRegions && (
205
- <Tabs.Trigger value="layout" className={tabTriggerClass}>
206
- <span className="flex items-center gap-1.5">
207
- <Layers className="h-4 w-4" />
208
- Layout
209
- </span>
210
- </Tabs.Trigger>
211
- )}
212
- <Tabs.Trigger value="security" className={tabTriggerClass}>
213
- Security
214
- </Tabs.Trigger>
215
- <Tabs.Trigger value="users" className={tabTriggerClass}>
216
- <span className="flex items-center gap-1.5">
217
- <UsersIcon className="h-4 w-4" />
218
- Users
219
- </span>
220
- </Tabs.Trigger>
221
- <Tabs.Trigger value="mcp" className={tabTriggerClass}>
222
- <span className="flex items-center gap-1.5">
223
- <Plug className="h-4 w-4" />
224
- MCP
225
- </span>
226
- </Tabs.Trigger>
227
- <Tabs.Trigger value="api-keys" className={tabTriggerClass}>
228
- <span className="flex items-center gap-1.5">
229
- <KeyRound className="h-4 w-4" />
230
- API Keys
231
- </span>
232
- </Tabs.Trigger>
233
- <Tabs.Trigger value="seo" className={tabTriggerClass}>
234
- SEO
235
- </Tabs.Trigger>
236
- <Tabs.Trigger value="email" className={tabTriggerClass}>
237
- <span className="flex items-center gap-1.5">
238
- <Mail className="h-4 w-4" />
239
- Email
240
- </span>
241
- </Tabs.Trigger>
242
- <Tabs.Trigger value="webhooks" className={tabTriggerClass}>
243
- Webhooks
244
- </Tabs.Trigger>
245
- <Tabs.Trigger value="ai" className={tabTriggerClass}>
246
- <span className="flex items-center gap-1.5">
247
- <Bot className="h-4 w-4" />
248
- AI
249
- </span>
250
- </Tabs.Trigger>
251
- <Tabs.Trigger value="updates" className={tabTriggerClass}>
252
- <span className="flex items-center gap-1.5">
253
- <Download className="h-4 w-4" />
254
- Updates
255
- </span>
256
- </Tabs.Trigger>
257
- </Tabs.List>
258
-
259
- <Tabs.Content value="general">
260
- <GeneralSettingsTab onNavigate={onNavigate} role={session?.user?.role} />
261
- </Tabs.Content>
262
-
263
- <Tabs.Content value="appearance" className="space-y-4">
264
- <AppearanceTab role={session?.user?.role} config={config} />
265
- </Tabs.Content>
266
-
267
- {hasLayoutRegions && (
268
- <Tabs.Content value="layout" className="space-y-4">
269
- <SettingsCard
270
- title="Default Layout Variants"
271
- description="Select the default header, footer, and other layout variants used site-wide. Pages can override these individually or inherit from parent pages."
310
+ <AlertTriangle size={20} className="shrink-0" aria-hidden="true" />
311
+ <span className="flex-1">{error}</span>
312
+ <button
313
+ onClick={refetch}
314
+ className="border-destructive/40 rounded-md border px-3 py-1 transition-colors hover:opacity-80"
272
315
  >
273
- <div className="space-y-4">
274
- {layoutRegions.map((region) => (
275
- <RelationshipField
276
- key={region.name}
277
- label={`Default ${region.label}`}
278
- value={defaultLayout[region.name] ?? ''}
279
- onChange={(val) => {
280
- setDefaultLayout((prev) => {
281
- const next = { ...prev }
282
- if (val && typeof val === 'string') {
283
- next[region.name] = val
284
- } else {
285
- delete next[region.name]
286
- }
287
- return next
288
- })
289
- }}
290
- relationTo={region.collection}
291
- helpText={`The ${region.label.toLowerCase()} variant used when no page in the ancestor chain specifies one`}
292
- />
293
- ))}
294
- </div>
295
- </SettingsCard>
296
- <SettingsCard title="How Layout Inheritance Works">
297
- <ul className="text-muted-foreground space-y-1.5 text-sm">
298
- <li className="flex items-start gap-2">
299
- <span className="bg-brand/10 text-brand mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-medium">
300
- 1
301
- </span>
302
- <span>
303
- Each page can assign specific layout variants (header, footer, etc.) from the
304
- document editor.
305
- </span>
306
- </li>
307
- <li className="flex items-start gap-2">
308
- <span className="bg-brand/10 text-brand mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-medium">
309
- 2
310
- </span>
311
- <span>
312
- Child pages automatically inherit their parent&apos;s layout. For example,{' '}
313
- <code className="bg-muted rounded px-1 font-mono">
314
- /hampton-roads/thank-you
315
- </code>{' '}
316
- inherits from{' '}
317
- <code className="bg-muted rounded px-1 font-mono">/hampton-roads</code>.
318
- </span>
319
- </li>
320
- <li className="flex items-start gap-2">
321
- <span className="bg-brand/10 text-brand mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-medium">
322
- 3
323
- </span>
324
- <span>
325
- If no page in the ancestor chain sets a variant, the defaults configured above
326
- are used.
327
- </span>
328
- </li>
329
- </ul>
330
- </SettingsCard>
331
- </Tabs.Content>
316
+ Retry
317
+ </button>
318
+ </div>
332
319
  )}
320
+ <PageHeader flush title="Settings" subtitle="Manage your CMS configuration" />
321
+ </div>
333
322
 
334
- <Tabs.Content value="security" className="space-y-4">
335
- <SecurityTab role={session?.user?.role} onNavigate={onNavigate} />
336
- </Tabs.Content>
337
-
338
- <Tabs.Content value="seo" className="space-y-4">
339
- <SeoSettingsTab onNavigate={onNavigate} role={session?.user?.role} />
340
- </Tabs.Content>
341
-
342
- <Tabs.Content value="email" className="space-y-4">
343
- <EmailSettingsTab role={session?.user?.role} />
344
- </Tabs.Content>
345
-
346
- <Tabs.Content value="webhooks" className="space-y-4">
347
- <WebhooksTab role={session?.user?.role} />
348
- </Tabs.Content>
349
-
350
- <Tabs.Content value="ai" className="space-y-4">
351
- <AISettingsTab role={session?.user?.role} config={config} />
352
- </Tabs.Content>
353
-
354
- <Tabs.Content value="users">
355
- <UsersView onNavigate={onNavigate} embedded currentPath={currentPath} />
356
- </Tabs.Content>
357
-
358
- <Tabs.Content value="mcp">
359
- <McpConnectTab onNavigate={onNavigate} />
360
- </Tabs.Content>
361
-
362
- <Tabs.Content value="api-keys">
363
- <ApiKeysView onNavigate={onNavigate} embedded />
364
- </Tabs.Content>
365
-
366
- <Tabs.Content value="updates" className="space-y-4">
367
- <UpdatesTab role={session?.user?.role} />
368
- </Tabs.Content>
369
- </Tabs.Root>
323
+ <UnderlineTabs
324
+ variant="page"
325
+ label="Settings"
326
+ idBase="settings"
327
+ tabs={stripTabs}
328
+ value={activeTab}
329
+ onChange={changeTab}
330
+ className="px-[var(--gut)]"
331
+ />
370
332
 
371
- {GLOBAL_SAVE_TABS.has(activeTab) && (
372
- <div className="mt-6 flex justify-end">
373
- <button
374
- type="button"
375
- onClick={handleSave}
376
- disabled={saving}
377
- className="bg-primary hover:bg-primary/90 rounded-lg px-6 py-2 text-sm text-white transition-colors disabled:opacity-50"
378
- >
379
- {saving ? 'Saving...' : 'Save Changes'}
380
- </button>
381
- </div>
382
- )}
333
+ {panel ? (
334
+ <UnderlineTabPanel
335
+ idBase="settings"
336
+ tabId={activeTab}
337
+ className={`px-[var(--gut)] pt-5 ${panel.className ?? ''}`}
338
+ >
339
+ {panel.body}
340
+ </UnderlineTabPanel>
341
+ ) : null}
383
342
  </div>
384
343
  )
385
344
  }
@@ -0,0 +1,32 @@
1
+ 'use client'
2
+
3
+ import { Breadcrumb } from '../components/ui/Breadcrumb.js'
4
+ import { PageHeader } from '../components/ui/PageHeader.js'
5
+ import { EmptyState } from '../components/ui/EmptyState.js'
6
+ import { ShieldAlert } from 'lucide-react'
7
+
8
+ export function SpamFolder() {
9
+ return (
10
+ <div className="flex flex-col gap-6 p-6">
11
+ <PageHeader
12
+ flush
13
+ title="Spam"
14
+ subtitle="Entries caught by the blocklist stay out of the inbox."
15
+ breadcrumb={
16
+ <Breadcrumb
17
+ items={[
18
+ { label: 'Dashboard', path: '/' },
19
+ { label: 'Forms', path: '/forms' },
20
+ { label: 'Spam' },
21
+ ]}
22
+ />
23
+ }
24
+ />
25
+ <EmptyState
26
+ icon={<ShieldAlert size={24} aria-hidden />}
27
+ title="Spam folder is empty"
28
+ description="Not spam restores an entry and sends a held notification once."
29
+ />
30
+ </div>
31
+ )
32
+ }
@@ -4,11 +4,14 @@ import { useCallback, useEffect, useMemo, useState } from 'react'
4
4
  import { Loader2, RotateCcw, Trash2 } from 'lucide-react'
5
5
  import { toast } from 'sonner'
6
6
  import { cmsApi } from '../lib/api.js'
7
+ import { Breadcrumb } from '../components/ui/Breadcrumb.js'
7
8
  import { ConfirmDialog } from '../components/ui/ConfirmDialog.js'
8
9
  import { EmptyState } from '../components/ui/EmptyState.js'
9
10
 
10
11
  export interface TrashProps {
11
12
  onNavigate: (path: string) => void
13
+ /** The section this Trash belongs to (Pages or Posts), for the breadcrumb. */
14
+ parent?: { label: string; path: string }
12
15
  config?: {
13
16
  collections?:
14
17
  | Record<string, { slug?: string; admin?: { hidden?: boolean } } | undefined>
@@ -68,7 +71,7 @@ function asRow(collection: string, doc: Record<string, unknown>): TrashRow {
68
71
  }
69
72
  }
70
73
 
71
- export function Trash({ onNavigate, config }: TrashProps) {
74
+ export function Trash({ onNavigate, config, parent }: TrashProps) {
72
75
  const collections = useMemo(() => {
73
76
  const raw = config?.collections
74
77
  const list = Array.isArray(raw) ? raw : Object.values(raw ?? {})
@@ -158,6 +161,14 @@ export function Trash({ onNavigate, config }: TrashProps) {
158
161
  return (
159
162
  <div className="p-4 pr-8">
160
163
  <div className="mb-4">
164
+ <Breadcrumb
165
+ className="mb-1"
166
+ items={[
167
+ { label: 'Dashboard', path: '/' },
168
+ ...(parent ? [parent] : []),
169
+ { label: 'Trash' },
170
+ ]}
171
+ />
161
172
  <h1 className="text-foreground mb-1">Trash</h1>
162
173
  <p className="text-muted-foreground text-sm">
163
174
  Soft-deleted pages and posts stay here for 30 days. Restore one, or delete it permanently
@@ -505,7 +505,7 @@ function InviteModal({
505
505
  </div>
506
506
 
507
507
  {seatsFull && (
508
- <div className="border-warning/30 bg-warning/10 text-warning mb-4 flex items-start gap-2 rounded-md border p-3 text-sm">
508
+ <div className="border-warning/30 bg-warn-l text-warning mb-4 flex items-start gap-2 rounded-md border p-3 text-sm">
509
509
  <AlertTriangle size={16} className="mt-0.5 shrink-0" aria-hidden />
510
510
  <span>
511
511
  All seats are in use. Remove a member or raise the seat limit before inviting.
@@ -1081,7 +1081,7 @@ export function Users({ embedded = false, currentPath }: UsersProps = {}) {
1081
1081
  </span>
1082
1082
  )}
1083
1083
  {row.externalDomain && (
1084
- <span className="bg-warning/10 text-warning rounded px-1 text-[10px]">
1084
+ <span className="bg-warn-l text-warning rounded px-1 text-[10px]">
1085
1085
  External
1086
1086
  </span>
1087
1087
  )}