@prenta/admin 0.98.1 → 1.1.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 (371) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/AdminRoot.d.ts.map +1 -1
  3. package/dist/AdminRoot.js +22 -84
  4. package/dist/AdminRoot.js.map +1 -1
  5. package/dist/__tests__/components/breakpoint-controls.render.test.js +4 -4
  6. package/dist/__tests__/components/breakpoint-controls.render.test.js.map +1 -1
  7. package/dist/__tests__/components/seo-score-bands.test.js +0 -3
  8. package/dist/__tests__/components/seo-score-bands.test.js.map +1 -1
  9. package/dist/__tests__/layout/sidebar-posts.test.js +6 -11
  10. package/dist/__tests__/layout/sidebar-posts.test.js.map +1 -1
  11. package/dist/__tests__/layout/sidebar-submenu.render.test.js +3 -2
  12. package/dist/__tests__/layout/sidebar-submenu.render.test.js.map +1 -1
  13. package/dist/__tests__/lib/open-public-site-tab.test.d.ts +2 -0
  14. package/dist/__tests__/lib/open-public-site-tab.test.d.ts.map +1 -0
  15. package/dist/__tests__/lib/open-public-site-tab.test.js +64 -0
  16. package/dist/__tests__/lib/open-public-site-tab.test.js.map +1 -0
  17. package/dist/__tests__/lib/page-editor-service-api.test.js +26 -23
  18. package/dist/__tests__/lib/page-editor-service-api.test.js.map +1 -1
  19. package/dist/__tests__/lib/view-site-chrome.test.d.ts +2 -0
  20. package/dist/__tests__/lib/view-site-chrome.test.d.ts.map +1 -0
  21. package/dist/__tests__/lib/view-site-chrome.test.js +59 -0
  22. package/dist/__tests__/lib/view-site-chrome.test.js.map +1 -0
  23. package/dist/__tests__/router/admin-routes.test.js +4 -0
  24. package/dist/__tests__/router/admin-routes.test.js.map +1 -1
  25. package/dist/__tests__/views/canvas-surface-shared.test.js +0 -16
  26. package/dist/__tests__/views/canvas-surface-shared.test.js.map +1 -1
  27. package/dist/__tests__/views/editor-top-bar.render.test.js +44 -22
  28. package/dist/__tests__/views/editor-top-bar.render.test.js.map +1 -1
  29. package/dist/__tests__/views/page-section-editor.test.js +30 -10
  30. package/dist/__tests__/views/page-section-editor.test.js.map +1 -1
  31. package/dist/__tests__/views/page-tab.render.test.js +0 -1
  32. package/dist/__tests__/views/page-tab.render.test.js.map +1 -1
  33. package/dist/__tests__/views/post-section-editor.test.js +23 -0
  34. package/dist/__tests__/views/post-section-editor.test.js.map +1 -1
  35. package/dist/components/BreakpointPicker.d.ts +3 -2
  36. package/dist/components/BreakpointPicker.d.ts.map +1 -1
  37. package/dist/components/BreakpointPicker.js +5 -3
  38. package/dist/components/BreakpointPicker.js.map +1 -1
  39. package/dist/components/CanvasEditTip.js +1 -1
  40. package/dist/components/CanvasEditTip.js.map +1 -1
  41. package/dist/index.d.ts +1 -4
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +1 -3
  44. package/dist/index.js.map +1 -1
  45. package/dist/layout/Sidebar.d.ts +3 -4
  46. package/dist/layout/Sidebar.d.ts.map +1 -1
  47. package/dist/layout/Sidebar.js +7 -38
  48. package/dist/layout/Sidebar.js.map +1 -1
  49. package/dist/lib/editor-preview.d.ts +4 -1
  50. package/dist/lib/editor-preview.d.ts.map +1 -1
  51. package/dist/lib/editor-preview.js +4 -1
  52. package/dist/lib/editor-preview.js.map +1 -1
  53. package/dist/lib/open-public-site-tab.d.ts +14 -0
  54. package/dist/lib/open-public-site-tab.d.ts.map +1 -0
  55. package/dist/lib/open-public-site-tab.js +46 -0
  56. package/dist/lib/open-public-site-tab.js.map +1 -0
  57. package/dist/lib/page-editor-service.d.ts +0 -7
  58. package/dist/lib/page-editor-service.d.ts.map +1 -1
  59. package/dist/lib/page-editor-service.js +9 -9
  60. package/dist/lib/page-editor-service.js.map +1 -1
  61. package/dist/lib/view-site-chrome.d.ts +16 -0
  62. package/dist/lib/view-site-chrome.d.ts.map +1 -0
  63. package/dist/lib/view-site-chrome.js +15 -0
  64. package/dist/lib/view-site-chrome.js.map +1 -0
  65. package/dist/prenta-admin.css +1 -1
  66. package/dist/router/admin-routes.d.ts.map +1 -1
  67. package/dist/router/admin-routes.js +0 -2
  68. package/dist/router/admin-routes.js.map +1 -1
  69. package/dist/views/PageEditor.d.ts +2 -2
  70. package/dist/views/PageEditor.js +2 -2
  71. package/dist/views/page-editor/EditorCanvas.d.ts +1 -2
  72. package/dist/views/page-editor/EditorCanvas.d.ts.map +1 -1
  73. package/dist/views/page-editor/EditorCanvas.js +2 -2
  74. package/dist/views/page-editor/EditorCanvas.js.map +1 -1
  75. package/dist/views/page-editor/EditorTopBar.d.ts +13 -17
  76. package/dist/views/page-editor/EditorTopBar.d.ts.map +1 -1
  77. package/dist/views/page-editor/EditorTopBar.js +19 -21
  78. package/dist/views/page-editor/EditorTopBar.js.map +1 -1
  79. package/dist/views/page-editor/PageSectionEditor.d.ts +1 -7
  80. package/dist/views/page-editor/PageSectionEditor.d.ts.map +1 -1
  81. package/dist/views/page-editor/PageSectionEditor.js +38 -110
  82. package/dist/views/page-editor/PageSectionEditor.js.map +1 -1
  83. package/dist/views/page-editor/StructureNotice.d.ts +2 -5
  84. package/dist/views/page-editor/StructureNotice.d.ts.map +1 -1
  85. package/dist/views/page-editor/StructureNotice.js +6 -10
  86. package/dist/views/page-editor/StructureNotice.js.map +1 -1
  87. package/dist/views/post-editor/PostEditorCanvas.d.ts +1 -3
  88. package/dist/views/post-editor/PostEditorCanvas.d.ts.map +1 -1
  89. package/dist/views/post-editor/PostEditorCanvas.js +3 -3
  90. package/dist/views/post-editor/PostEditorCanvas.js.map +1 -1
  91. package/dist/views/post-editor/PostSectionEditor.d.ts +1 -15
  92. package/dist/views/post-editor/PostSectionEditor.d.ts.map +1 -1
  93. package/dist/views/post-editor/PostSectionEditor.js +30 -88
  94. package/dist/views/post-editor/PostSectionEditor.js.map +1 -1
  95. package/package.json +3 -3
  96. package/src/AdminRoot.tsx +18 -138
  97. package/src/__tests__/components/breakpoint-controls.render.test.tsx +6 -4
  98. package/src/__tests__/components/seo-score-bands.test.ts +0 -3
  99. package/src/__tests__/layout/sidebar-posts.test.ts +6 -11
  100. package/src/__tests__/layout/sidebar-submenu.render.test.tsx +3 -2
  101. package/src/__tests__/lib/open-public-site-tab.test.ts +74 -0
  102. package/src/__tests__/lib/page-editor-service-api.test.ts +27 -25
  103. package/src/__tests__/lib/view-site-chrome.test.ts +65 -0
  104. package/src/__tests__/router/admin-routes.test.ts +5 -0
  105. package/src/__tests__/views/canvas-surface-shared.test.ts +0 -19
  106. package/src/__tests__/views/editor-top-bar.render.test.tsx +85 -22
  107. package/src/__tests__/views/page-section-editor.test.tsx +42 -10
  108. package/src/__tests__/views/page-tab.render.test.tsx +0 -1
  109. package/src/__tests__/views/post-section-editor.test.tsx +35 -0
  110. package/src/components/BreakpointPicker.tsx +6 -3
  111. package/src/components/CanvasEditTip.tsx +2 -2
  112. package/src/index.ts +1 -11
  113. package/src/layout/Sidebar.tsx +6 -41
  114. package/src/lib/editor-preview.ts +4 -1
  115. package/src/lib/open-public-site-tab.ts +57 -0
  116. package/src/lib/page-editor-service.ts +9 -16
  117. package/src/lib/view-site-chrome.ts +34 -0
  118. package/src/router/admin-routes.ts +0 -2
  119. package/src/styles/theme.css +4 -4
  120. package/src/views/PageEditor.tsx +2 -2
  121. package/src/views/page-editor/EditorCanvas.tsx +1 -6
  122. package/src/views/page-editor/EditorTopBar.tsx +81 -82
  123. package/src/views/page-editor/PageSectionEditor.tsx +85 -194
  124. package/src/views/page-editor/StructureNotice.tsx +7 -42
  125. package/src/views/post-editor/PostEditorCanvas.tsx +2 -8
  126. package/src/views/post-editor/PostSectionEditor.tsx +66 -138
  127. package/dist/__tests__/views/page-builder-block-renderer.render.test.d.ts +0 -2
  128. package/dist/__tests__/views/page-builder-block-renderer.render.test.d.ts.map +0 -1
  129. package/dist/__tests__/views/page-builder-block-renderer.render.test.js +0 -48
  130. package/dist/__tests__/views/page-builder-block-renderer.render.test.js.map +0 -1
  131. package/dist/__tests__/views/page-builder-form-picker.render.test.d.ts +0 -2
  132. package/dist/__tests__/views/page-builder-form-picker.render.test.d.ts.map +0 -1
  133. package/dist/__tests__/views/page-builder-form-picker.render.test.js +0 -44
  134. package/dist/__tests__/views/page-builder-form-picker.render.test.js.map +0 -1
  135. package/dist/__tests__/views/page-builder-sections-panel.render.test.d.ts +0 -2
  136. package/dist/__tests__/views/page-builder-sections-panel.render.test.d.ts.map +0 -1
  137. package/dist/__tests__/views/page-builder-sections-panel.render.test.js +0 -121
  138. package/dist/__tests__/views/page-builder-sections-panel.render.test.js.map +0 -1
  139. package/dist/__tests__/views/page-builder-seo-panel.render.test.d.ts +0 -2
  140. package/dist/__tests__/views/page-builder-seo-panel.render.test.d.ts.map +0 -1
  141. package/dist/__tests__/views/page-builder-seo-panel.render.test.js +0 -65
  142. package/dist/__tests__/views/page-builder-seo-panel.render.test.js.map +0 -1
  143. package/dist/__tests__/views/page-builder-template-seed.render.test.d.ts +0 -2
  144. package/dist/__tests__/views/page-builder-template-seed.render.test.d.ts.map +0 -1
  145. package/dist/__tests__/views/page-builder-template-seed.render.test.js +0 -48
  146. package/dist/__tests__/views/page-builder-template-seed.render.test.js.map +0 -1
  147. package/dist/__tests__/views/page-templates.render.test.d.ts +0 -2
  148. package/dist/__tests__/views/page-templates.render.test.d.ts.map +0 -1
  149. package/dist/__tests__/views/page-templates.render.test.js +0 -126
  150. package/dist/__tests__/views/page-templates.render.test.js.map +0 -1
  151. package/dist/__tests__/views/use-site-preview.render.test.d.ts +0 -2
  152. package/dist/__tests__/views/use-site-preview.render.test.d.ts.map +0 -1
  153. package/dist/__tests__/views/use-site-preview.render.test.js +0 -120
  154. package/dist/__tests__/views/use-site-preview.render.test.js.map +0 -1
  155. package/dist/hooks/useBuilderState.d.ts +0 -49
  156. package/dist/hooks/useBuilderState.d.ts.map +0 -1
  157. package/dist/hooks/useBuilderState.js +0 -238
  158. package/dist/hooks/useBuilderState.js.map +0 -1
  159. package/dist/views/page-builder/AIBlockAssist.d.ts +0 -9
  160. package/dist/views/page-builder/AIBlockAssist.d.ts.map +0 -1
  161. package/dist/views/page-builder/AIBlockAssist.js +0 -40
  162. package/dist/views/page-builder/AIBlockAssist.js.map +0 -1
  163. package/dist/views/page-builder/AIGenerateDialog.d.ts +0 -8
  164. package/dist/views/page-builder/AIGenerateDialog.d.ts.map +0 -1
  165. package/dist/views/page-builder/AIGenerateDialog.js +0 -173
  166. package/dist/views/page-builder/AIGenerateDialog.js.map +0 -1
  167. package/dist/views/page-builder/BlockEditor.d.ts +0 -11
  168. package/dist/views/page-builder/BlockEditor.d.ts.map +0 -1
  169. package/dist/views/page-builder/BlockEditor.js +0 -159
  170. package/dist/views/page-builder/BlockEditor.js.map +0 -1
  171. package/dist/views/page-builder/BlockPicker.d.ts +0 -7
  172. package/dist/views/page-builder/BlockPicker.d.ts.map +0 -1
  173. package/dist/views/page-builder/BlockPicker.js +0 -103
  174. package/dist/views/page-builder/BlockPicker.js.map +0 -1
  175. package/dist/views/page-builder/BottomBar.d.ts +0 -9
  176. package/dist/views/page-builder/BottomBar.d.ts.map +0 -1
  177. package/dist/views/page-builder/BottomBar.js +0 -13
  178. package/dist/views/page-builder/BottomBar.js.map +0 -1
  179. package/dist/views/page-builder/BuilderSectionsPanel.d.ts +0 -20
  180. package/dist/views/page-builder/BuilderSectionsPanel.d.ts.map +0 -1
  181. package/dist/views/page-builder/BuilderSectionsPanel.js +0 -105
  182. package/dist/views/page-builder/BuilderSectionsPanel.js.map +0 -1
  183. package/dist/views/page-builder/BuilderToolbar.d.ts +0 -21
  184. package/dist/views/page-builder/BuilderToolbar.d.ts.map +0 -1
  185. package/dist/views/page-builder/BuilderToolbar.js +0 -18
  186. package/dist/views/page-builder/BuilderToolbar.js.map +0 -1
  187. package/dist/views/page-builder/ContextPanel.d.ts +0 -20
  188. package/dist/views/page-builder/ContextPanel.d.ts.map +0 -1
  189. package/dist/views/page-builder/ContextPanel.js +0 -43
  190. package/dist/views/page-builder/ContextPanel.js.map +0 -1
  191. package/dist/views/page-builder/DesignScore.d.ts +0 -6
  192. package/dist/views/page-builder/DesignScore.d.ts.map +0 -1
  193. package/dist/views/page-builder/DesignScore.js +0 -93
  194. package/dist/views/page-builder/DesignScore.js.map +0 -1
  195. package/dist/views/page-builder/NodeSettings.d.ts +0 -12
  196. package/dist/views/page-builder/NodeSettings.d.ts.map +0 -1
  197. package/dist/views/page-builder/NodeSettings.js +0 -80
  198. package/dist/views/page-builder/NodeSettings.js.map +0 -1
  199. package/dist/views/page-builder/PageBuilder.d.ts +0 -10
  200. package/dist/views/page-builder/PageBuilder.d.ts.map +0 -1
  201. package/dist/views/page-builder/PageBuilder.js +0 -222
  202. package/dist/views/page-builder/PageBuilder.js.map +0 -1
  203. package/dist/views/page-builder/PageSettings.d.ts +0 -7
  204. package/dist/views/page-builder/PageSettings.d.ts.map +0 -1
  205. package/dist/views/page-builder/PageSettings.js +0 -27
  206. package/dist/views/page-builder/PageSettings.js.map +0 -1
  207. package/dist/views/page-builder/PageTemplates.d.ts +0 -5
  208. package/dist/views/page-builder/PageTemplates.d.ts.map +0 -1
  209. package/dist/views/page-builder/PageTemplates.js +0 -146
  210. package/dist/views/page-builder/PageTemplates.js.map +0 -1
  211. package/dist/views/page-builder/RelationshipField.d.ts +0 -15
  212. package/dist/views/page-builder/RelationshipField.d.ts.map +0 -1
  213. package/dist/views/page-builder/RelationshipField.js +0 -65
  214. package/dist/views/page-builder/RelationshipField.js.map +0 -1
  215. package/dist/views/page-builder/SEOPanel.d.ts +0 -9
  216. package/dist/views/page-builder/SEOPanel.d.ts.map +0 -1
  217. package/dist/views/page-builder/SEOPanel.js +0 -38
  218. package/dist/views/page-builder/SEOPanel.js.map +0 -1
  219. package/dist/views/page-builder/SavedSections.d.ts +0 -6
  220. package/dist/views/page-builder/SavedSections.d.ts.map +0 -1
  221. package/dist/views/page-builder/SavedSections.js +0 -141
  222. package/dist/views/page-builder/SavedSections.js.map +0 -1
  223. package/dist/views/page-builder/TemplatePicker.d.ts +0 -7
  224. package/dist/views/page-builder/TemplatePicker.d.ts.map +0 -1
  225. package/dist/views/page-builder/TemplatePicker.js +0 -68
  226. package/dist/views/page-builder/TemplatePicker.js.map +0 -1
  227. package/dist/views/page-builder/Widgets.d.ts +0 -13
  228. package/dist/views/page-builder/Widgets.d.ts.map +0 -1
  229. package/dist/views/page-builder/Widgets.js +0 -15
  230. package/dist/views/page-builder/Widgets.js.map +0 -1
  231. package/dist/views/page-builder/block-renderers/CTAPreview.d.ts +0 -3
  232. package/dist/views/page-builder/block-renderers/CTAPreview.d.ts.map +0 -1
  233. package/dist/views/page-builder/block-renderers/CTAPreview.js +0 -19
  234. package/dist/views/page-builder/block-renderers/CTAPreview.js.map +0 -1
  235. package/dist/views/page-builder/block-renderers/CardsPreview.d.ts +0 -3
  236. package/dist/views/page-builder/block-renderers/CardsPreview.d.ts.map +0 -1
  237. package/dist/views/page-builder/block-renderers/CardsPreview.js +0 -22
  238. package/dist/views/page-builder/block-renderers/CardsPreview.js.map +0 -1
  239. package/dist/views/page-builder/block-renderers/CodePreview.d.ts +0 -3
  240. package/dist/views/page-builder/block-renderers/CodePreview.d.ts.map +0 -1
  241. package/dist/views/page-builder/block-renderers/CodePreview.js +0 -12
  242. package/dist/views/page-builder/block-renderers/CodePreview.js.map +0 -1
  243. package/dist/views/page-builder/block-renderers/FAQPreview.d.ts +0 -3
  244. package/dist/views/page-builder/block-renderers/FAQPreview.d.ts.map +0 -1
  245. package/dist/views/page-builder/block-renderers/FAQPreview.js +0 -27
  246. package/dist/views/page-builder/block-renderers/FAQPreview.js.map +0 -1
  247. package/dist/views/page-builder/block-renderers/FallbackPreview.d.ts +0 -6
  248. package/dist/views/page-builder/block-renderers/FallbackPreview.d.ts.map +0 -1
  249. package/dist/views/page-builder/block-renderers/FallbackPreview.js +0 -7
  250. package/dist/views/page-builder/block-renderers/FallbackPreview.js.map +0 -1
  251. package/dist/views/page-builder/block-renderers/FormPreview.d.ts +0 -9
  252. package/dist/views/page-builder/block-renderers/FormPreview.d.ts.map +0 -1
  253. package/dist/views/page-builder/block-renderers/FormPreview.js +0 -52
  254. package/dist/views/page-builder/block-renderers/FormPreview.js.map +0 -1
  255. package/dist/views/page-builder/block-renderers/GalleryPreview.d.ts +0 -3
  256. package/dist/views/page-builder/block-renderers/GalleryPreview.d.ts.map +0 -1
  257. package/dist/views/page-builder/block-renderers/GalleryPreview.js +0 -19
  258. package/dist/views/page-builder/block-renderers/GalleryPreview.js.map +0 -1
  259. package/dist/views/page-builder/block-renderers/HeroPreview.d.ts +0 -3
  260. package/dist/views/page-builder/block-renderers/HeroPreview.d.ts.map +0 -1
  261. package/dist/views/page-builder/block-renderers/HeroPreview.js +0 -19
  262. package/dist/views/page-builder/block-renderers/HeroPreview.js.map +0 -1
  263. package/dist/views/page-builder/block-renderers/ImagePreview.d.ts +0 -3
  264. package/dist/views/page-builder/block-renderers/ImagePreview.d.ts.map +0 -1
  265. package/dist/views/page-builder/block-renderers/ImagePreview.js +0 -17
  266. package/dist/views/page-builder/block-renderers/ImagePreview.js.map +0 -1
  267. package/dist/views/page-builder/block-renderers/TextPreview.d.ts +0 -3
  268. package/dist/views/page-builder/block-renderers/TextPreview.d.ts.map +0 -1
  269. package/dist/views/page-builder/block-renderers/TextPreview.js +0 -22
  270. package/dist/views/page-builder/block-renderers/TextPreview.js.map +0 -1
  271. package/dist/views/page-builder/block-renderers/VideoPreview.d.ts +0 -3
  272. package/dist/views/page-builder/block-renderers/VideoPreview.d.ts.map +0 -1
  273. package/dist/views/page-builder/block-renderers/VideoPreview.js +0 -18
  274. package/dist/views/page-builder/block-renderers/VideoPreview.js.map +0 -1
  275. package/dist/views/page-builder/block-renderers/index.d.ts +0 -9
  276. package/dist/views/page-builder/block-renderers/index.d.ts.map +0 -1
  277. package/dist/views/page-builder/block-renderers/index.js +0 -25
  278. package/dist/views/page-builder/block-renderers/index.js.map +0 -1
  279. package/dist/views/page-builder/canvas/BlockRenderer.d.ts +0 -8
  280. package/dist/views/page-builder/canvas/BlockRenderer.d.ts.map +0 -1
  281. package/dist/views/page-builder/canvas/BlockRenderer.js +0 -20
  282. package/dist/views/page-builder/canvas/BlockRenderer.js.map +0 -1
  283. package/dist/views/page-builder/canvas/BuilderCanvas.d.ts +0 -10
  284. package/dist/views/page-builder/canvas/BuilderCanvas.d.ts.map +0 -1
  285. package/dist/views/page-builder/canvas/BuilderCanvas.js +0 -26
  286. package/dist/views/page-builder/canvas/BuilderCanvas.js.map +0 -1
  287. package/dist/views/page-builder/canvas/ColumnRenderer.d.ts +0 -8
  288. package/dist/views/page-builder/canvas/ColumnRenderer.d.ts.map +0 -1
  289. package/dist/views/page-builder/canvas/ColumnRenderer.js +0 -32
  290. package/dist/views/page-builder/canvas/ColumnRenderer.js.map +0 -1
  291. package/dist/views/page-builder/canvas/ContainerRenderer.d.ts +0 -8
  292. package/dist/views/page-builder/canvas/ContainerRenderer.d.ts.map +0 -1
  293. package/dist/views/page-builder/canvas/ContainerRenderer.js +0 -29
  294. package/dist/views/page-builder/canvas/ContainerRenderer.js.map +0 -1
  295. package/dist/views/page-builder/canvas/RowRenderer.d.ts +0 -8
  296. package/dist/views/page-builder/canvas/RowRenderer.d.ts.map +0 -1
  297. package/dist/views/page-builder/canvas/RowRenderer.js +0 -28
  298. package/dist/views/page-builder/canvas/RowRenderer.js.map +0 -1
  299. package/dist/views/page-builder/canvas/SectionRenderer.d.ts +0 -8
  300. package/dist/views/page-builder/canvas/SectionRenderer.d.ts.map +0 -1
  301. package/dist/views/page-builder/canvas/SectionRenderer.js +0 -50
  302. package/dist/views/page-builder/canvas/SectionRenderer.js.map +0 -1
  303. package/dist/views/page-builder/canvas/index.d.ts +0 -3
  304. package/dist/views/page-builder/canvas/index.d.ts.map +0 -1
  305. package/dist/views/page-builder/canvas/index.js +0 -2
  306. package/dist/views/page-builder/canvas/index.js.map +0 -1
  307. package/dist/views/page-editor/PagePreview.d.ts +0 -13
  308. package/dist/views/page-editor/PagePreview.d.ts.map +0 -1
  309. package/dist/views/page-editor/PagePreview.js +0 -46
  310. package/dist/views/page-editor/PagePreview.js.map +0 -1
  311. package/dist/views/page-editor/SitePreviewFrame.d.ts +0 -43
  312. package/dist/views/page-editor/SitePreviewFrame.d.ts.map +0 -1
  313. package/dist/views/page-editor/SitePreviewFrame.js +0 -165
  314. package/dist/views/page-editor/SitePreviewFrame.js.map +0 -1
  315. package/dist/views/page-editor/useSitePreview.d.ts +0 -47
  316. package/dist/views/page-editor/useSitePreview.d.ts.map +0 -1
  317. package/dist/views/page-editor/useSitePreview.js +0 -96
  318. package/dist/views/page-editor/useSitePreview.js.map +0 -1
  319. package/dist/views/post-editor/PostPreview.d.ts +0 -14
  320. package/dist/views/post-editor/PostPreview.d.ts.map +0 -1
  321. package/dist/views/post-editor/PostPreview.js +0 -63
  322. package/dist/views/post-editor/PostPreview.js.map +0 -1
  323. package/src/__tests__/views/page-builder-block-renderer.render.test.tsx +0 -66
  324. package/src/__tests__/views/page-builder-form-picker.render.test.tsx +0 -54
  325. package/src/__tests__/views/page-builder-sections-panel.render.test.tsx +0 -138
  326. package/src/__tests__/views/page-builder-seo-panel.render.test.tsx +0 -77
  327. package/src/__tests__/views/page-builder-template-seed.render.test.tsx +0 -59
  328. package/src/__tests__/views/page-templates.render.test.tsx +0 -182
  329. package/src/__tests__/views/use-site-preview.render.test.tsx +0 -164
  330. package/src/hooks/useBuilderState.ts +0 -361
  331. package/src/views/page-builder/AIBlockAssist.tsx +0 -64
  332. package/src/views/page-builder/AIGenerateDialog.tsx +0 -593
  333. package/src/views/page-builder/BlockEditor.tsx +0 -523
  334. package/src/views/page-builder/BlockPicker.tsx +0 -324
  335. package/src/views/page-builder/BottomBar.tsx +0 -65
  336. package/src/views/page-builder/BuilderSectionsPanel.tsx +0 -304
  337. package/src/views/page-builder/BuilderToolbar.tsx +0 -221
  338. package/src/views/page-builder/ContextPanel.tsx +0 -144
  339. package/src/views/page-builder/DesignScore.tsx +0 -251
  340. package/src/views/page-builder/NodeSettings.tsx +0 -500
  341. package/src/views/page-builder/PageBuilder.tsx +0 -405
  342. package/src/views/page-builder/PageSettings.tsx +0 -162
  343. package/src/views/page-builder/PageTemplates.tsx +0 -435
  344. package/src/views/page-builder/RelationshipField.tsx +0 -113
  345. package/src/views/page-builder/SEOPanel.tsx +0 -222
  346. package/src/views/page-builder/SavedSections.tsx +0 -480
  347. package/src/views/page-builder/TemplatePicker.tsx +0 -197
  348. package/src/views/page-builder/Widgets.tsx +0 -44
  349. package/src/views/page-builder/block-renderers/CTAPreview.tsx +0 -79
  350. package/src/views/page-builder/block-renderers/CardsPreview.tsx +0 -69
  351. package/src/views/page-builder/block-renderers/CodePreview.tsx +0 -46
  352. package/src/views/page-builder/block-renderers/FAQPreview.tsx +0 -87
  353. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +0 -18
  354. package/src/views/page-builder/block-renderers/FormPreview.tsx +0 -117
  355. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +0 -87
  356. package/src/views/page-builder/block-renderers/HeroPreview.tsx +0 -90
  357. package/src/views/page-builder/block-renderers/ImagePreview.tsx +0 -54
  358. package/src/views/page-builder/block-renderers/TextPreview.tsx +0 -81
  359. package/src/views/page-builder/block-renderers/VideoPreview.tsx +0 -73
  360. package/src/views/page-builder/block-renderers/index.ts +0 -34
  361. package/src/views/page-builder/canvas/BlockRenderer.tsx +0 -56
  362. package/src/views/page-builder/canvas/BuilderCanvas.tsx +0 -87
  363. package/src/views/page-builder/canvas/ColumnRenderer.tsx +0 -82
  364. package/src/views/page-builder/canvas/ContainerRenderer.tsx +0 -67
  365. package/src/views/page-builder/canvas/RowRenderer.tsx +0 -68
  366. package/src/views/page-builder/canvas/SectionRenderer.tsx +0 -93
  367. package/src/views/page-builder/canvas/index.ts +0 -2
  368. package/src/views/page-editor/PagePreview.tsx +0 -105
  369. package/src/views/page-editor/SitePreviewFrame.tsx +0 -250
  370. package/src/views/page-editor/useSitePreview.ts +0 -158
  371. package/src/views/post-editor/PostPreview.tsx +0 -125
@@ -1,435 +0,0 @@
1
- 'use client'
2
-
3
- import { useMemo, useState } from 'react'
4
- import { AlertTriangle, Copy, FilePlus, Layers, Pencil, RefreshCw, Trash2 } from 'lucide-react'
5
- import { toast } from 'sonner'
6
- import { cmsApi } from '../../lib/api.js'
7
- import { useApiData } from '../../lib/useApiData.js'
8
- import { ConfirmDialog } from '../../components/ui/ConfirmDialog.js'
9
- import { EmptyState } from '../../components/ui/EmptyState.js'
10
- import { FilterPill } from '../../components/ui/FilterPill.js'
11
- import { Input } from '../../components/ui/Input.js'
12
- import { Modal } from '../../components/ui/Modal.js'
13
- import { Button } from '../../components/ui/Button.js'
14
- import { RowActions, RowActionButton } from '../../components/ui/RowActions.js'
15
- import { SearchInput } from '../../components/ui/SearchInput.js'
16
- import { Select } from '../../components/ui/Select.js'
17
- import { Skeleton } from '../../components/ui/Skeleton.js'
18
-
19
- interface PageTemplate {
20
- id: string
21
- name?: string
22
- description?: string | null
23
- category?: string
24
- builtIn?: boolean
25
- updatedAt?: string
26
- thumbnail?: string | null
27
- tree?: { children?: unknown[] } | null
28
- }
29
-
30
- type CategoryId = 'content' | 'landing' | 'utility'
31
-
32
- const CATEGORIES: Record<CategoryId, { label: string; dot: string; text: string }> = {
33
- content: { label: 'Content', dot: 'bg-[var(--acc)]', text: 'text-[var(--acc)]' },
34
- landing: { label: 'Landing', dot: 'bg-[var(--suc)]', text: 'text-[var(--suc)]' },
35
- utility: { label: 'Utility', dot: 'bg-[var(--warn)]', text: 'text-[var(--warn)]' },
36
- }
37
-
38
- function categoryOf(template: PageTemplate): CategoryId {
39
- const cat = template.category
40
- return cat === 'landing' || cat === 'utility' ? cat : 'content'
41
- }
42
-
43
- function sectionCountOf(template: PageTemplate): number {
44
- return Array.isArray(template.tree?.children) ? template.tree.children.length : 0
45
- }
46
-
47
- export interface PageTemplatesProps {
48
- onNavigate?: (path: string) => void
49
- }
50
-
51
- export function PageTemplates({ onNavigate }: PageTemplatesProps) {
52
- const { data, loading, error, refetch } = useApiData<PageTemplate[]>('/page-templates')
53
- const templates = useMemo(() => data ?? [], [data])
54
-
55
- const [search, setSearch] = useState('')
56
- const [category, setCategory] = useState<CategoryId | 'all'>('all')
57
- const [editTarget, setEditTarget] = useState<PageTemplate | null>(null)
58
- const [deleteTarget, setDeleteTarget] = useState<PageTemplate | null>(null)
59
-
60
- const filtered = useMemo(() => {
61
- const q = search.trim().toLowerCase()
62
- return templates.filter((t) => {
63
- const matchesQuery =
64
- !q ||
65
- (t.name ?? '').toLowerCase().includes(q) ||
66
- (t.description ?? '').toLowerCase().includes(q)
67
- const matchesCategory = category === 'all' || categoryOf(t) === category
68
- return matchesQuery && matchesCategory
69
- })
70
- }, [templates, search, category])
71
-
72
- async function confirmDelete() {
73
- if (!deleteTarget) return
74
- const res = await cmsApi(`/page-templates/${deleteTarget.id}`, { method: 'DELETE' })
75
- if (res.error) {
76
- toast.error(res.error)
77
- } else {
78
- toast.success('Template deleted')
79
- refetch()
80
- }
81
- }
82
-
83
- async function duplicateTemplate(template: PageTemplate) {
84
- // The list payload carries the full tree, so no extra fetch is needed.
85
- // Duplicating a built-in is the supported way to customize one (built-ins
86
- // themselves are locked against edits).
87
- if (!template.tree) {
88
- toast.error('Template has no layout to duplicate')
89
- return
90
- }
91
- const res = await cmsApi('/page-templates', {
92
- method: 'POST',
93
- body: JSON.stringify({
94
- name: `${template.name ?? 'Untitled template'} (copy)`,
95
- description: template.description ?? null,
96
- category: categoryOf(template),
97
- tree: template.tree,
98
- thumbnail: template.thumbnail ?? null,
99
- }),
100
- })
101
- if (res.error) {
102
- toast.error(res.error)
103
- } else {
104
- toast.success('Template duplicated')
105
- refetch()
106
- }
107
- }
108
-
109
- return (
110
- <div className="p-4 pr-8">
111
- {error && (
112
- <div className="mb-4 flex items-center gap-3 rounded-[var(--r)] border border-[var(--bdr)] bg-[var(--card)] p-3">
113
- <AlertTriangle className="h-5 w-5 shrink-0 text-[var(--muted)]" aria-hidden />
114
- <span className="flex-1 text-sm text-[var(--txt)]">{error}</span>
115
- <button
116
- type="button"
117
- onClick={refetch}
118
- className="rounded-md border border-[var(--bdr)] px-3 py-1 text-sm text-[var(--txt)] hover:bg-[var(--acc-l)]"
119
- >
120
- Retry
121
- </button>
122
- </div>
123
- )}
124
-
125
- <div className="mb-4 flex items-center justify-between gap-4">
126
- <div>
127
- <h1 className="text-foreground mb-1">Page Templates</h1>
128
- <p className="text-sm text-[var(--sub)]">
129
- {templates.length} saved template{templates.length === 1 ? '' : 's'}
130
- </p>
131
- </div>
132
- <Button
133
- type="button"
134
- variant="outline"
135
- size="md"
136
- onClick={refetch}
137
- leftIcon={<RefreshCw size={16} aria-hidden />}
138
- >
139
- Refresh
140
- </Button>
141
- </div>
142
-
143
- {!loading && templates.length > 0 && (
144
- <div className="mb-4 flex flex-wrap items-center gap-2">
145
- <div className="max-w-xs min-w-52 flex-1">
146
- <SearchInput value={search} onChange={setSearch} placeholder="Search templates…" />
147
- </div>
148
- <div className="flex gap-1.5" role="group" aria-label="Filter templates by category">
149
- <FilterPill active={category === 'all'} onClick={() => setCategory('all')}>
150
- All
151
- </FilterPill>
152
- {(Object.keys(CATEGORIES) as CategoryId[]).map((cat) => (
153
- <FilterPill key={cat} active={category === cat} onClick={() => setCategory(cat)}>
154
- {CATEGORIES[cat].label}
155
- </FilterPill>
156
- ))}
157
- </div>
158
- <span className="ml-auto text-[12.5px] whitespace-nowrap text-[var(--muted)]">
159
- {filtered.length} of {templates.length}
160
- </span>
161
- </div>
162
- )}
163
-
164
- {loading ? (
165
- <div
166
- className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3"
167
- role="status"
168
- aria-live="polite"
169
- aria-label="Loading page templates"
170
- >
171
- {Array.from({ length: 6 }, (_, i) => (
172
- <Skeleton key={i} variant="card" />
173
- ))}
174
- </div>
175
- ) : templates.length === 0 ? (
176
- <EmptyState
177
- icon={<Layers size={24} aria-hidden />}
178
- title="No page templates yet"
179
- description="Built-in templates are seeded by the CMS when the templates API is available."
180
- actionLabel="View Saved Sections"
181
- onAction={() => onNavigate?.('/saved-sections')}
182
- />
183
- ) : filtered.length === 0 ? (
184
- <p className="py-12 text-center text-sm text-[var(--muted)]">
185
- No templates match your search.
186
- </p>
187
- ) : (
188
- <ul
189
- className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3"
190
- aria-label="Page templates"
191
- >
192
- {filtered.map((template) => (
193
- <TemplateCard
194
- key={template.id}
195
- template={template}
196
- onUse={() => onNavigate?.(`/page-builder/new?template=${template.id}`)}
197
- onDuplicate={() => void duplicateTemplate(template)}
198
- onEdit={() => setEditTarget(template)}
199
- onDelete={() => setDeleteTarget(template)}
200
- />
201
- ))}
202
- </ul>
203
- )}
204
-
205
- <TemplateEditModal
206
- template={editTarget}
207
- onClose={() => setEditTarget(null)}
208
- onSaved={() => {
209
- setEditTarget(null)
210
- refetch()
211
- }}
212
- />
213
-
214
- <ConfirmDialog
215
- open={deleteTarget !== null}
216
- onClose={() => setDeleteTarget(null)}
217
- onConfirm={() => void confirmDelete()}
218
- title="Delete template?"
219
- description={`"${deleteTarget?.name ?? 'This template'}" will be permanently removed. Pages already created from it are not affected.`}
220
- confirmLabel="Delete"
221
- destructive
222
- />
223
- </div>
224
- )
225
- }
226
-
227
- function TemplateCard({
228
- template,
229
- onUse,
230
- onDuplicate,
231
- onEdit,
232
- onDelete,
233
- }: {
234
- template: PageTemplate
235
- onUse: () => void
236
- onDuplicate: () => void
237
- onEdit: () => void
238
- onDelete: () => void
239
- }) {
240
- const cat = CATEGORIES[categoryOf(template)]
241
- const sections = sectionCountOf(template)
242
- const name = template.name ?? 'Untitled template'
243
- const updated = template.updatedAt ? new Date(template.updatedAt).toLocaleDateString() : null
244
-
245
- return (
246
- <li className="group relative flex flex-col overflow-hidden rounded-[var(--r)] border border-[var(--bdr)] bg-[var(--card)] shadow-[var(--shd)] transition-[border-color,box-shadow,transform] duration-[var(--motion-fast)] focus-within:border-[var(--acc-m)] focus-within:shadow-[var(--shd2)] hover:-translate-y-0.5 hover:border-[var(--acc-m)] hover:shadow-[var(--shd2)] motion-reduce:hover:translate-y-0">
247
- <TemplatePreview template={template} sections={sections} />
248
-
249
- <div className="flex flex-1 flex-col p-4 pb-0">
250
- <div className="flex items-start justify-between gap-3">
251
- <h2 className="text-[15px] leading-snug font-medium text-[var(--txt)]">{name}</h2>
252
- {template.builtIn && (
253
- <span className="shrink-0 rounded-full border border-[var(--bdr)] bg-[var(--bg)] px-2 py-0.5 text-[10.5px] font-medium whitespace-nowrap text-[var(--sub)]">
254
- Built-in
255
- </span>
256
- )}
257
- </div>
258
- <p className="mt-2 min-h-10 text-[12.5px] leading-relaxed text-[var(--sub)]">
259
- {template.description ?? 'No description provided.'}
260
- </p>
261
-
262
- <div className="relative mt-3 flex h-[46px] items-center justify-between border-t border-[var(--bdr)] py-2.5">
263
- <span
264
- className={`inline-flex items-center gap-1.5 text-[11.5px] font-medium ${cat.text}`}
265
- >
266
- <span aria-hidden className={`h-[7px] w-[7px] shrink-0 rounded-full ${cat.dot}`} />
267
- {cat.label}
268
- </span>
269
- <span className="text-[11.5px] text-[var(--muted)] transition-opacity duration-[var(--motion-fast)] group-focus-within:opacity-0 group-hover:opacity-0">
270
- {sections} section{sections === 1 ? '' : 's'}
271
- {updated ? ` · ${updated}` : ''}
272
- </span>
273
- <RowActions className="absolute top-1/2 right-0 -translate-y-1/2">
274
- <RowActionButton aria-label={`Create page from ${name}`} onClick={onUse}>
275
- <FilePlus size={14} aria-hidden />
276
- </RowActionButton>
277
- <RowActionButton aria-label={`Duplicate ${name}`} onClick={onDuplicate}>
278
- <Copy size={14} aria-hidden />
279
- </RowActionButton>
280
- {!template.builtIn && (
281
- <>
282
- <RowActionButton aria-label={`Edit ${name}`} onClick={onEdit}>
283
- <Pencil size={14} aria-hidden />
284
- </RowActionButton>
285
- <RowActionButton aria-label={`Delete ${name}`} danger onClick={onDelete}>
286
- <Trash2 size={14} aria-hidden />
287
- </RowActionButton>
288
- </>
289
- )}
290
- </RowActions>
291
- </div>
292
- </div>
293
- </li>
294
- )
295
- }
296
-
297
- /**
298
- * Card preview area. Uses the stored thumbnail when one exists; otherwise
299
- * renders an honest wireframe placeholder built from the template's section
300
- * count (a hero band plus one bar per section) — no fake screenshots.
301
- */
302
- function TemplatePreview({ template, sections }: { template: PageTemplate; sections: number }) {
303
- if (template.thumbnail) {
304
- return (
305
- <div className="h-28 shrink-0 overflow-hidden border-b border-[var(--bdr)] bg-[var(--bg)]">
306
- <img
307
- src={template.thumbnail}
308
- alt={`Preview of ${template.name ?? 'template'}`}
309
- className="h-full w-full object-cover"
310
- />
311
- </div>
312
- )
313
- }
314
-
315
- const bars = Math.max(0, Math.min(sections - 1, 3))
316
- return (
317
- <div
318
- aria-hidden
319
- className="flex h-28 shrink-0 flex-col gap-1.5 border-b border-[var(--bdr)] bg-[var(--bg)] p-3"
320
- >
321
- <div className="h-9 rounded-[5px] bg-[var(--acc-l)]" />
322
- {Array.from({ length: bars }, (_, i) => (
323
- <div
324
- key={i}
325
- className="h-3.5 rounded-[4px] bg-[var(--bdr)]"
326
- style={{ width: `${88 - i * 14}%` }}
327
- />
328
- ))}
329
- </div>
330
- )
331
- }
332
-
333
- function TemplateEditModal({
334
- template,
335
- onClose,
336
- onSaved,
337
- }: {
338
- template: PageTemplate | null
339
- onClose: () => void
340
- onSaved: () => void
341
- }) {
342
- // Keyed remount seeds the form state from the selected template each time
343
- // the modal opens, without effect-based state syncing.
344
- if (!template) return null
345
- return (
346
- <TemplateEditForm key={template.id} template={template} onClose={onClose} onSaved={onSaved} />
347
- )
348
- }
349
-
350
- function TemplateEditForm({
351
- template,
352
- onClose,
353
- onSaved,
354
- }: {
355
- template: PageTemplate
356
- onClose: () => void
357
- onSaved: () => void
358
- }) {
359
- const [name, setName] = useState(template.name ?? '')
360
- const [description, setDescription] = useState(template.description ?? '')
361
- const [category, setCategory] = useState<CategoryId>(categoryOf(template))
362
- const [saving, setSaving] = useState(false)
363
-
364
- async function handleSave() {
365
- if (!name.trim()) {
366
- toast.error('Template name is required')
367
- return
368
- }
369
- setSaving(true)
370
- const res = await cmsApi(`/page-templates/${template.id}`, {
371
- method: 'PUT',
372
- body: JSON.stringify({
373
- name: name.trim(),
374
- description: description.trim() || null,
375
- category,
376
- }),
377
- })
378
- setSaving(false)
379
- if (res.error) {
380
- toast.error(res.error)
381
- } else {
382
- toast.success('Template updated')
383
- onSaved()
384
- }
385
- }
386
-
387
- return (
388
- <Modal
389
- open
390
- onClose={onClose}
391
- title="Edit template"
392
- actions={
393
- <>
394
- <Button variant="ghost" onClick={onClose} disabled={saving}>
395
- Cancel
396
- </Button>
397
- <Button variant="primary" onClick={() => void handleSave()} loading={saving}>
398
- Save changes
399
- </Button>
400
- </>
401
- }
402
- >
403
- <div className="flex flex-col gap-4">
404
- <label className="flex flex-col gap-1.5">
405
- <span className="text-sm font-medium text-[var(--txt)]">Name</span>
406
- <Input
407
- value={name}
408
- onChange={(e) => setName(e.target.value)}
409
- placeholder="Template name"
410
- />
411
- </label>
412
- <label className="flex flex-col gap-1.5">
413
- <span className="text-sm font-medium text-[var(--txt)]">Description</span>
414
- <textarea
415
- value={description}
416
- onChange={(e) => setDescription(e.target.value)}
417
- rows={3}
418
- placeholder="What this template is for…"
419
- className="w-full resize-y rounded-[var(--r-control)] border border-[var(--bdr)] bg-[var(--input-background)] px-3 py-2 text-sm text-[var(--txt)] placeholder:text-[var(--muted)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none"
420
- />
421
- </label>
422
- <label className="flex flex-col gap-1.5">
423
- <span className="text-sm font-medium text-[var(--txt)]">Category</span>
424
- <Select value={category} onChange={(e) => setCategory(e.target.value as CategoryId)}>
425
- {(Object.keys(CATEGORIES) as CategoryId[]).map((cat) => (
426
- <option key={cat} value={cat}>
427
- {CATEGORIES[cat].label}
428
- </option>
429
- ))}
430
- </Select>
431
- </label>
432
- </div>
433
- </Modal>
434
- )
435
- }
@@ -1,113 +0,0 @@
1
- 'use client'
2
-
3
- import { useEffect, useMemo, useState } from 'react'
4
- import type { FieldDefinition } from '@prenta/core'
5
- import { cmsApi } from '../../lib/api.js'
6
-
7
- const INPUT_CLASS =
8
- 'w-full px-3 py-2 text-sm bg-background border border-input rounded-md focus:outline-none focus:ring-2 focus:ring-ring'
9
- const LABEL_CLASS = 'text-sm font-medium text-foreground mb-1 block'
10
-
11
- interface RelationshipOption {
12
- id: string
13
- label: string
14
- }
15
-
16
- export interface RelationshipFieldProps {
17
- definition: FieldDefinition
18
- value: unknown
19
- onChange: (value: unknown) => void
20
- label: string
21
- }
22
-
23
- /**
24
- * Relationship picker for page-builder block fields (e.g. the form block's
25
- * `formId`). Loads the target collection via the admin API and renders a
26
- * labelled dropdown. If the collection can't be loaded it degrades to a plain
27
- * id input so the field is never a dead end.
28
- */
29
- export function RelationshipField({ definition, value, onChange, label }: RelationshipFieldProps) {
30
- const relationTo = useMemo(() => {
31
- if (definition.type !== 'relationship') return ''
32
- return Array.isArray(definition.relationTo)
33
- ? (definition.relationTo[0] ?? '')
34
- : definition.relationTo
35
- }, [definition])
36
-
37
- const [options, setOptions] = useState<RelationshipOption[]>([])
38
- const [loading, setLoading] = useState(false)
39
- const [failed, setFailed] = useState(false)
40
-
41
- useEffect(() => {
42
- if (!relationTo) return
43
- let cancelled = false
44
- setLoading(true)
45
- setFailed(false)
46
- cmsApi<Array<Record<string, unknown>>>(`/${relationTo}`)
47
- .then((res) => {
48
- if (cancelled) return
49
- if (Array.isArray(res.data)) {
50
- setOptions(
51
- res.data
52
- .map((item) => ({
53
- id: String(item.id ?? ''),
54
- label: String(item.name ?? item.title ?? item.slug ?? item.id ?? 'Untitled'),
55
- }))
56
- .filter((option) => option.id),
57
- )
58
- } else {
59
- setFailed(true)
60
- }
61
- })
62
- .catch(() => {
63
- if (!cancelled) setFailed(true)
64
- })
65
- .finally(() => {
66
- if (!cancelled) setLoading(false)
67
- })
68
- return () => {
69
- cancelled = true
70
- }
71
- }, [relationTo])
72
-
73
- const current = (value as string) ?? ''
74
- const noun = relationTo === 'forms' ? 'a form' : 'an item'
75
-
76
- if (failed) {
77
- return (
78
- <div>
79
- <label className={LABEL_CLASS}>{label}</label>
80
- <input
81
- type="text"
82
- value={current}
83
- onChange={(e) => onChange(e.target.value || undefined)}
84
- placeholder={`Enter ${relationTo} id…`}
85
- className={INPUT_CLASS}
86
- />
87
- </div>
88
- )
89
- }
90
-
91
- return (
92
- <div>
93
- <label className={LABEL_CLASS}>{label}</label>
94
- <select
95
- value={current}
96
- onChange={(e) => onChange(e.target.value || undefined)}
97
- disabled={loading}
98
- aria-label={label}
99
- className={INPUT_CLASS}
100
- >
101
- <option value="">{loading ? 'Loading…' : `Select ${noun}…`}</option>
102
- {options.map((option) => (
103
- <option key={option.id} value={option.id}>
104
- {option.label}
105
- </option>
106
- ))}
107
- </select>
108
- {!loading && options.length === 0 && (
109
- <p className="text-muted-foreground mt-1 text-xs">No {relationTo} found.</p>
110
- )}
111
- </div>
112
- )
113
- }