astro-tractstack 2.0.0-rc.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 (427) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +56 -0
  3. package/astro.d.ts +64 -0
  4. package/bin/create-tractstack.js +483 -0
  5. package/dist/config.js +80 -0
  6. package/dist/index.js +2129 -0
  7. package/package.json +89 -0
  8. package/templates/artpacks/kCz/captainBreakfast_1080px.webp +0 -0
  9. package/templates/artpacks/kCz/captainBreakfast_1920px.webp +0 -0
  10. package/templates/artpacks/kCz/captainBreakfast_600px.webp +0 -0
  11. package/templates/artpacks/kCz/cleanDrips_1080px.webp +0 -0
  12. package/templates/artpacks/kCz/cleanDrips_1920px.webp +0 -0
  13. package/templates/artpacks/kCz/cleanDrips_600px.webp +0 -0
  14. package/templates/artpacks/kCz/crispwaves_1080px.webp +0 -0
  15. package/templates/artpacks/kCz/crispwaves_1920px.webp +0 -0
  16. package/templates/artpacks/kCz/crispwaves_600px.webp +0 -0
  17. package/templates/artpacks/kCz/dragonSkin_1080px.webp +0 -0
  18. package/templates/artpacks/kCz/dragonSkin_1920px.webp +0 -0
  19. package/templates/artpacks/kCz/dragonSkin_600px.webp +0 -0
  20. package/templates/artpacks/kCz/dragon_1080px.webp +0 -0
  21. package/templates/artpacks/kCz/dragon_1920px.webp +0 -0
  22. package/templates/artpacks/kCz/dragon_600px.webp +0 -0
  23. package/templates/artpacks/kCz/nightcity_1080px.webp +0 -0
  24. package/templates/artpacks/kCz/nightcity_1920px.webp +0 -0
  25. package/templates/artpacks/kCz/nightcity_600px.webp +0 -0
  26. package/templates/artpacks/kCz/pattern1_1080px.webp +0 -0
  27. package/templates/artpacks/kCz/pattern1_1920px.webp +0 -0
  28. package/templates/artpacks/kCz/pattern1_600px.webp +0 -0
  29. package/templates/artpacks/kCz/pattern2_1080px.webp +0 -0
  30. package/templates/artpacks/kCz/pattern2_1920px.webp +0 -0
  31. package/templates/artpacks/kCz/pattern2_600px.webp +0 -0
  32. package/templates/artpacks/kCz/skindrips_1080px.webp +0 -0
  33. package/templates/artpacks/kCz/skindrips_1920px.webp +0 -0
  34. package/templates/artpacks/kCz/skindrips_600px.webp +0 -0
  35. package/templates/artpacks/kCz/slimetime_1080px.webp +0 -0
  36. package/templates/artpacks/kCz/slimetime_1920px.webp +0 -0
  37. package/templates/artpacks/kCz/slimetime_600px.webp +0 -0
  38. package/templates/artpacks/kCz/snake_1080px.webp +0 -0
  39. package/templates/artpacks/kCz/snake_1920px.webp +0 -0
  40. package/templates/artpacks/kCz/snake_600px.webp +0 -0
  41. package/templates/artpacks/kCz/toxicshock_1080px.webp +0 -0
  42. package/templates/artpacks/kCz/toxicshock_1920px.webp +0 -0
  43. package/templates/artpacks/kCz/toxicshock_600px.webp +0 -0
  44. package/templates/artpacks/kCz/tractstack_1080px.webp +0 -0
  45. package/templates/artpacks/kCz/tractstack_1920px.webp +0 -0
  46. package/templates/artpacks/kCz/tractstack_600px.webp +0 -0
  47. package/templates/artpacks/kCz/tripdrips_1080px.webp +0 -0
  48. package/templates/artpacks/kCz/tripdrips_1920px.webp +0 -0
  49. package/templates/artpacks/kCz/tripdrips_600px.webp +0 -0
  50. package/templates/artpacks/kCz/wavedrips_1080px.webp +0 -0
  51. package/templates/artpacks/kCz/wavedrips_1920px.webp +0 -0
  52. package/templates/artpacks/kCz/wavedrips_600px.webp +0 -0
  53. package/templates/artpacks/t8k/beach_1080px.webp +0 -0
  54. package/templates/artpacks/t8k/beach_1920px.webp +0 -0
  55. package/templates/artpacks/t8k/beach_600px.webp +0 -0
  56. package/templates/artpacks/t8k/blast_1080px.webp +0 -0
  57. package/templates/artpacks/t8k/blast_1920px.webp +0 -0
  58. package/templates/artpacks/t8k/blast_600px.webp +0 -0
  59. package/templates/artpacks/t8k/bokeh_1080px.webp +0 -0
  60. package/templates/artpacks/t8k/bokeh_1920px.webp +0 -0
  61. package/templates/artpacks/t8k/bokeh_600px.webp +0 -0
  62. package/templates/artpacks/t8k/cartoon_1080px.webp +0 -0
  63. package/templates/artpacks/t8k/cartoon_1920px.webp +0 -0
  64. package/templates/artpacks/t8k/cartoon_600px.webp +0 -0
  65. package/templates/artpacks/t8k/darkeggshell_1080px.webp +0 -0
  66. package/templates/artpacks/t8k/darkeggshell_1920px.webp +0 -0
  67. package/templates/artpacks/t8k/darkeggshell_600px.webp +0 -0
  68. package/templates/artpacks/t8k/explosion_1080px.webp +0 -0
  69. package/templates/artpacks/t8k/explosion_1920px.webp +0 -0
  70. package/templates/artpacks/t8k/explosion_600px.webp +0 -0
  71. package/templates/artpacks/t8k/floral_1080px.webp +0 -0
  72. package/templates/artpacks/t8k/floral_1920px.webp +0 -0
  73. package/templates/artpacks/t8k/floral_600px.webp +0 -0
  74. package/templates/artpacks/t8k/flower_1080px.webp +0 -0
  75. package/templates/artpacks/t8k/flower_1920px.webp +0 -0
  76. package/templates/artpacks/t8k/flower_600px.webp +0 -0
  77. package/templates/artpacks/t8k/foliage_1080px.webp +0 -0
  78. package/templates/artpacks/t8k/foliage_1920px.webp +0 -0
  79. package/templates/artpacks/t8k/foliage_600px.webp +0 -0
  80. package/templates/artpacks/t8k/mist_1080px.webp +0 -0
  81. package/templates/artpacks/t8k/mist_1920px.webp +0 -0
  82. package/templates/artpacks/t8k/mist_600px.webp +0 -0
  83. package/templates/artpacks/t8k/portal_1080px.webp +0 -0
  84. package/templates/artpacks/t8k/portal_1920px.webp +0 -0
  85. package/templates/artpacks/t8k/portal_600px.webp +0 -0
  86. package/templates/artpacks/t8k/storytime_1080px.webp +0 -0
  87. package/templates/artpacks/t8k/storytime_1920px.webp +0 -0
  88. package/templates/artpacks/t8k/storytime_600px.webp +0 -0
  89. package/templates/artpacks/t8k/tacky_1080px.webp +0 -0
  90. package/templates/artpacks/t8k/tacky_1920px.webp +0 -0
  91. package/templates/artpacks/t8k/tacky_600px.webp +0 -0
  92. package/templates/artpacks/t8k/wallpaper_1080px.webp +0 -0
  93. package/templates/artpacks/t8k/wallpaper_1920px.webp +0 -0
  94. package/templates/artpacks/t8k/wallpaper_600px.webp +0 -0
  95. package/templates/brand/favicon.ico +0 -0
  96. package/templates/brand/logo.svg +19 -0
  97. package/templates/brand/static.jpg +0 -0
  98. package/templates/brand/wordmark.svg +4 -0
  99. package/templates/css/custom.css +51 -0
  100. package/templates/css/frontend.css +3519 -0
  101. package/templates/css/storykeep.css +92872 -0
  102. package/templates/custom/minimal/CodeHook.astro +53 -0
  103. package/templates/custom/minimal/CustomRoutes.astro +46 -0
  104. package/templates/custom/with-examples/CodeHook.astro +49 -0
  105. package/templates/custom/with-examples/CustomHero.astro +13 -0
  106. package/templates/custom/with-examples/CustomRoutes.astro +39 -0
  107. package/templates/custom/with-examples/pages/Collections.astro +110 -0
  108. package/templates/env.example +8 -0
  109. package/templates/fonts/Inter-Black.woff2 +0 -0
  110. package/templates/fonts/Inter-Bold.woff2 +0 -0
  111. package/templates/fonts/Inter-Regular.woff2 +0 -0
  112. package/templates/icons/h2.svg +1 -0
  113. package/templates/icons/h3.svg +1 -0
  114. package/templates/icons/h4.svg +1 -0
  115. package/templates/icons/h5.svg +1 -0
  116. package/templates/icons/image.svg +7 -0
  117. package/templates/icons/text.svg +6 -0
  118. package/templates/socials/codepen.svg +1 -0
  119. package/templates/socials/discord.svg +1 -0
  120. package/templates/socials/facebook.svg +1 -0
  121. package/templates/socials/github.svg +1 -0
  122. package/templates/socials/instagram.svg +1 -0
  123. package/templates/socials/linkedin.svg +1 -0
  124. package/templates/socials/mail.svg +1 -0
  125. package/templates/socials/rumble.svg +1 -0
  126. package/templates/socials/tiktok.svg +1 -0
  127. package/templates/socials/twitch.svg +1 -0
  128. package/templates/socials/twitter.svg +1 -0
  129. package/templates/socials/x.svg +1 -0
  130. package/templates/socials/youtube.svg +1 -0
  131. package/templates/src/client/analytics-events.ts +213 -0
  132. package/templates/src/client/belief-events.ts +205 -0
  133. package/templates/src/client/sse.ts +667 -0
  134. package/templates/src/components/Footer.astro +246 -0
  135. package/templates/src/components/Fragment.astro +70 -0
  136. package/templates/src/components/Header.astro +458 -0
  137. package/templates/src/components/Menu.tsx +196 -0
  138. package/templates/src/components/codehooks/BunnyVideoSetup.tsx +692 -0
  139. package/templates/src/components/codehooks/BunnyVideoWrapper.astro +78 -0
  140. package/templates/src/components/codehooks/EpinetDurationSelector.tsx +1020 -0
  141. package/templates/src/components/codehooks/EpinetTableView.tsx +594 -0
  142. package/templates/src/components/codehooks/EpinetWrapper.tsx +424 -0
  143. package/templates/src/components/codehooks/FeaturedContent.astro +273 -0
  144. package/templates/src/components/codehooks/FeaturedContentSetup.tsx +738 -0
  145. package/templates/src/components/codehooks/ListContent.astro +460 -0
  146. package/templates/src/components/codehooks/ListContentSetup.tsx +649 -0
  147. package/templates/src/components/codehooks/SankeyDiagram.tsx +359 -0
  148. package/templates/src/components/compositor/Compositor.tsx +144 -0
  149. package/templates/src/components/compositor/Node.tsx +415 -0
  150. package/templates/src/components/compositor/NodeWithGuid.tsx +25 -0
  151. package/templates/src/components/compositor/PanelVisibilityWrapper.tsx +87 -0
  152. package/templates/src/components/compositor/elements/Belief.tsx +148 -0
  153. package/templates/src/components/compositor/elements/BgImage.tsx +118 -0
  154. package/templates/src/components/compositor/elements/BgVisualBreak.tsx +102 -0
  155. package/templates/src/components/compositor/elements/BunnyVideo.tsx +63 -0
  156. package/templates/src/components/compositor/elements/IdentifyAs.tsx +66 -0
  157. package/templates/src/components/compositor/elements/PlayButton.tsx +19 -0
  158. package/templates/src/components/compositor/elements/SignUp.tsx +179 -0
  159. package/templates/src/components/compositor/elements/Svg.tsx +33 -0
  160. package/templates/src/components/compositor/elements/ToggleBelief.tsx +36 -0
  161. package/templates/src/components/compositor/elements/YouTubeWrapper.tsx +33 -0
  162. package/templates/src/components/compositor/nodes/BgPaneWrapper.tsx +35 -0
  163. package/templates/src/components/compositor/nodes/GhostInsertBlock.tsx +189 -0
  164. package/templates/src/components/compositor/nodes/Markdown.tsx +179 -0
  165. package/templates/src/components/compositor/nodes/Pane.tsx +277 -0
  166. package/templates/src/components/compositor/nodes/Pane_eraser.tsx +69 -0
  167. package/templates/src/components/compositor/nodes/Pane_layout.tsx +77 -0
  168. package/templates/src/components/compositor/nodes/RenderChildren.tsx +19 -0
  169. package/templates/src/components/compositor/nodes/StoryFragment.tsx +35 -0
  170. package/templates/src/components/compositor/nodes/TagElement.tsx +14 -0
  171. package/templates/src/components/compositor/nodes/Widget.tsx +115 -0
  172. package/templates/src/components/compositor/nodes/tagElements/NodeA.tsx +4 -0
  173. package/templates/src/components/compositor/nodes/tagElements/NodeA_eraser.tsx +26 -0
  174. package/templates/src/components/compositor/nodes/tagElements/NodeAnchorComponent.tsx +248 -0
  175. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag.tsx +684 -0
  176. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_eraser.tsx +62 -0
  177. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_insert.tsx +120 -0
  178. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_settings.tsx +62 -0
  179. package/templates/src/components/compositor/nodes/tagElements/NodeButton.tsx +5 -0
  180. package/templates/src/components/compositor/nodes/tagElements/NodeButton_eraser.tsx +26 -0
  181. package/templates/src/components/compositor/nodes/tagElements/NodeImg.tsx +28 -0
  182. package/templates/src/components/compositor/nodes/tagElements/NodeText.tsx +18 -0
  183. package/templates/src/components/compositor/nodes/tagElements/TabIndicator.tsx +51 -0
  184. package/templates/src/components/compositor/preview/FeaturedContentPreview.tsx +128 -0
  185. package/templates/src/components/compositor/preview/ListContentPreview.tsx +213 -0
  186. package/templates/src/components/compositor/preview/OgImagePreview.tsx +223 -0
  187. package/templates/src/components/compositor/preview/PaneSnapshotGenerator.tsx +199 -0
  188. package/templates/src/components/compositor/preview/PanesPreviewGenerator.tsx +123 -0
  189. package/templates/src/components/compositor/preview/VisualBreakPreview.tsx +154 -0
  190. package/templates/src/components/edit/Header.tsx +181 -0
  191. package/templates/src/components/edit/PanelSwitch.tsx +446 -0
  192. package/templates/src/components/edit/SettingsPanel.tsx +70 -0
  193. package/templates/src/components/edit/ToolBar.tsx +101 -0
  194. package/templates/src/components/edit/ToolMode.tsx +121 -0
  195. package/templates/src/components/edit/context/ContextPaneConfig.tsx +91 -0
  196. package/templates/src/components/edit/context/ContextPaneConfig_slug.tsx +174 -0
  197. package/templates/src/components/edit/context/ContextPaneConfig_title.tsx +186 -0
  198. package/templates/src/components/edit/pane/AddPanePanel.tsx +136 -0
  199. package/templates/src/components/edit/pane/AddPanePanel_break.tsx +470 -0
  200. package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +264 -0
  201. package/templates/src/components/edit/pane/AddPanePanel_new.tsx +623 -0
  202. package/templates/src/components/edit/pane/AddPanePanel_newAICopy.tsx +107 -0
  203. package/templates/src/components/edit/pane/AddPanePanel_newAICopy_modal.tsx +217 -0
  204. package/templates/src/components/edit/pane/AddPanePanel_newCopyMode.tsx +109 -0
  205. package/templates/src/components/edit/pane/AddPanePanel_newCustomCopy.tsx +39 -0
  206. package/templates/src/components/edit/pane/AddPanePanel_reuse.tsx +445 -0
  207. package/templates/src/components/edit/pane/ConfigPanePanel.tsx +245 -0
  208. package/templates/src/components/edit/pane/PageGen.tsx +485 -0
  209. package/templates/src/components/edit/pane/PageGenSelector.tsx +238 -0
  210. package/templates/src/components/edit/pane/PageGenSpecial.tsx +362 -0
  211. package/templates/src/components/edit/pane/PageGen_preview.tsx +495 -0
  212. package/templates/src/components/edit/pane/PanePanel_impression.tsx +258 -0
  213. package/templates/src/components/edit/pane/PanePanel_path.tsx +268 -0
  214. package/templates/src/components/edit/pane/PanePanel_slug.tsx +219 -0
  215. package/templates/src/components/edit/pane/PanePanel_title.tsx +142 -0
  216. package/templates/src/components/edit/panels/StyleBreakPanel.tsx +182 -0
  217. package/templates/src/components/edit/panels/StyleCodeHookPanel.tsx +439 -0
  218. package/templates/src/components/edit/panels/StyleElementPanel.tsx +177 -0
  219. package/templates/src/components/edit/panels/StyleElementPanel_add.tsx +349 -0
  220. package/templates/src/components/edit/panels/StyleElementPanel_remove.tsx +159 -0
  221. package/templates/src/components/edit/panels/StyleElementPanel_update.tsx +320 -0
  222. package/templates/src/components/edit/panels/StyleImagePanel.tsx +460 -0
  223. package/templates/src/components/edit/panels/StyleImagePanel_add.tsx +296 -0
  224. package/templates/src/components/edit/panels/StyleImagePanel_remove.tsx +153 -0
  225. package/templates/src/components/edit/panels/StyleImagePanel_update.tsx +312 -0
  226. package/templates/src/components/edit/panels/StyleLiElementPanel.tsx +273 -0
  227. package/templates/src/components/edit/panels/StyleLiElementPanel_add.tsx +301 -0
  228. package/templates/src/components/edit/panels/StyleLiElementPanel_remove.tsx +132 -0
  229. package/templates/src/components/edit/panels/StyleLiElementPanel_update.tsx +313 -0
  230. package/templates/src/components/edit/panels/StyleLinkPanel.tsx +346 -0
  231. package/templates/src/components/edit/panels/StyleLinkPanel_add.tsx +265 -0
  232. package/templates/src/components/edit/panels/StyleLinkPanel_config.tsx +240 -0
  233. package/templates/src/components/edit/panels/StyleLinkPanel_remove.tsx +94 -0
  234. package/templates/src/components/edit/panels/StyleLinkPanel_update.tsx +110 -0
  235. package/templates/src/components/edit/panels/StyleParentPanel.tsx +263 -0
  236. package/templates/src/components/edit/panels/StyleParentPanel_add.tsx +275 -0
  237. package/templates/src/components/edit/panels/StyleParentPanel_deleteLayer.tsx +112 -0
  238. package/templates/src/components/edit/panels/StyleParentPanel_remove.tsx +87 -0
  239. package/templates/src/components/edit/panels/StyleParentPanel_update.tsx +141 -0
  240. package/templates/src/components/edit/panels/StyleWidgetPanel.tsx +428 -0
  241. package/templates/src/components/edit/panels/StyleWidgetPanel_add.tsx +292 -0
  242. package/templates/src/components/edit/panels/StyleWidgetPanel_config.tsx +190 -0
  243. package/templates/src/components/edit/panels/StyleWidgetPanel_remove.tsx +152 -0
  244. package/templates/src/components/edit/panels/StyleWidgetPanel_update.tsx +308 -0
  245. package/templates/src/components/edit/state/SaveModal.tsx +811 -0
  246. package/templates/src/components/edit/state/StylesMemory.tsx +310 -0
  247. package/templates/src/components/edit/storyfragment/StoryFragmentConfigPanel.tsx +289 -0
  248. package/templates/src/components/edit/storyfragment/StoryFragmentPanel_menu.tsx +320 -0
  249. package/templates/src/components/edit/storyfragment/StoryFragmentPanel_og.tsx +888 -0
  250. package/templates/src/components/edit/storyfragment/StoryFragmentPanel_slug.tsx +269 -0
  251. package/templates/src/components/edit/storyfragment/StoryFragmentPanel_title.tsx +190 -0
  252. package/templates/src/components/edit/widgets/BeliefWidget.tsx +183 -0
  253. package/templates/src/components/edit/widgets/BunnyWidget.tsx +134 -0
  254. package/templates/src/components/edit/widgets/IdentifyAsWidget.tsx +193 -0
  255. package/templates/src/components/edit/widgets/SignupWidget.tsx +177 -0
  256. package/templates/src/components/edit/widgets/ToggleWidget.tsx +152 -0
  257. package/templates/src/components/edit/widgets/YouTubeWidget.tsx +65 -0
  258. package/templates/src/components/fields/ActionBuilderTimeSelector.tsx +353 -0
  259. package/templates/src/components/fields/ArtpackImage.tsx +480 -0
  260. package/templates/src/components/fields/BackgroundImage.tsx +530 -0
  261. package/templates/src/components/fields/BackgroundImageWrapper.tsx +192 -0
  262. package/templates/src/components/fields/BooleanParam.tsx +67 -0
  263. package/templates/src/components/fields/BunnyMomentSelector.tsx +56 -0
  264. package/templates/src/components/fields/ColorPickerCombo.tsx +284 -0
  265. package/templates/src/components/fields/ImageUpload.tsx +405 -0
  266. package/templates/src/components/fields/MultiParam.tsx +75 -0
  267. package/templates/src/components/fields/PaneBreakCollectionSelector.tsx +97 -0
  268. package/templates/src/components/fields/PaneBreakShapeSelector.tsx +134 -0
  269. package/templates/src/components/fields/SelectedTailwindClass.tsx +44 -0
  270. package/templates/src/components/fields/SingleParam.tsx +73 -0
  271. package/templates/src/components/fields/ViewportComboBox.tsx +252 -0
  272. package/templates/src/components/form/ActionBuilderField.tsx +282 -0
  273. package/templates/src/components/form/ActionBuilderSlugSelector.tsx +182 -0
  274. package/templates/src/components/form/BooleanToggle.tsx +94 -0
  275. package/templates/src/components/form/ColorPicker.tsx +153 -0
  276. package/templates/src/components/form/DateTimeInput.tsx +638 -0
  277. package/templates/src/components/form/EnumSelect.tsx +88 -0
  278. package/templates/src/components/form/FileUpload.tsx +465 -0
  279. package/templates/src/components/form/MagicPathBuilder.tsx +546 -0
  280. package/templates/src/components/form/NumberInput.tsx +101 -0
  281. package/templates/src/components/form/ParagraphArrayInput.tsx +207 -0
  282. package/templates/src/components/form/StringArrayInput.tsx +163 -0
  283. package/templates/src/components/form/StringInput.tsx +88 -0
  284. package/templates/src/components/form/UnsavedChangesBar.tsx +295 -0
  285. package/templates/src/components/form/advanced/APIConfigSection.tsx +69 -0
  286. package/templates/src/components/form/advanced/AuthConfigSection.tsx +97 -0
  287. package/templates/src/components/form/brand/BrandAssetsSection.tsx +93 -0
  288. package/templates/src/components/form/brand/BrandColorsSection.tsx +201 -0
  289. package/templates/src/components/form/brand/SEOSection.tsx +101 -0
  290. package/templates/src/components/form/brand/SiteConfigSection.tsx +61 -0
  291. package/templates/src/components/form/brand/SocialLinksSection.tsx +393 -0
  292. package/templates/src/components/profile/ProfileConsent.tsx +65 -0
  293. package/templates/src/components/profile/ProfileCreate.tsx +462 -0
  294. package/templates/src/components/profile/ProfileEdit.tsx +409 -0
  295. package/templates/src/components/profile/ProfileSwitch.tsx +255 -0
  296. package/templates/src/components/profile/ProfileUnlock.tsx +221 -0
  297. package/templates/src/components/storykeep/Dashboard.tsx +160 -0
  298. package/templates/src/components/storykeep/Dashboard_Activity.tsx +56 -0
  299. package/templates/src/components/storykeep/Dashboard_Advanced.tsx +165 -0
  300. package/templates/src/components/storykeep/Dashboard_Analytics.tsx +451 -0
  301. package/templates/src/components/storykeep/Dashboard_Branding.tsx +95 -0
  302. package/templates/src/components/storykeep/Dashboard_Content.tsx +191 -0
  303. package/templates/src/components/storykeep/controls/UsageCell.tsx +71 -0
  304. package/templates/src/components/storykeep/controls/content/BeliefForm.tsx +378 -0
  305. package/templates/src/components/storykeep/controls/content/BeliefTable.tsx +329 -0
  306. package/templates/src/components/storykeep/controls/content/ContentBrowser.tsx +385 -0
  307. package/templates/src/components/storykeep/controls/content/ContentSummary.tsx +149 -0
  308. package/templates/src/components/storykeep/controls/content/KnownResourceForm.tsx +397 -0
  309. package/templates/src/components/storykeep/controls/content/KnownResourceTable.tsx +260 -0
  310. package/templates/src/components/storykeep/controls/content/ManageContent.tsx +439 -0
  311. package/templates/src/components/storykeep/controls/content/MenuForm.tsx +239 -0
  312. package/templates/src/components/storykeep/controls/content/MenuTable.tsx +332 -0
  313. package/templates/src/components/storykeep/controls/content/ResourceBulkIngest.tsx +724 -0
  314. package/templates/src/components/storykeep/controls/content/ResourceForm.tsx +355 -0
  315. package/templates/src/components/storykeep/controls/content/ResourceTable.tsx +222 -0
  316. package/templates/src/components/storykeep/controls/content/StoryFragmentTable.tsx +482 -0
  317. package/templates/src/components/storykeep/state/BrandingWrapper.tsx +42 -0
  318. package/templates/src/components/storykeep/state/FetchAnalytics.tsx +350 -0
  319. package/templates/src/components/storykeep/widgets/ResponsiveLine.tsx +319 -0
  320. package/templates/src/components/storykeep/widgets/Wizard.tsx +278 -0
  321. package/templates/src/components/tenant/RegistrationForm.tsx +447 -0
  322. package/templates/src/components/widgets/BunnyVideoHero.astro +775 -0
  323. package/templates/src/components/widgets/Impression.tsx +102 -0
  324. package/templates/src/components/widgets/ImpressionWrapper.tsx +214 -0
  325. package/templates/src/constants/beliefs.ts +61 -0
  326. package/templates/src/constants/brandThemes.ts +133 -0
  327. package/templates/src/constants/prompts.json +55 -0
  328. package/templates/src/constants/shapes.ts +556 -0
  329. package/templates/src/constants/stopWords.ts +116 -0
  330. package/templates/src/constants/tailwindColors.json +344 -0
  331. package/templates/src/constants.ts +274 -0
  332. package/templates/src/hooks/useFormState.ts +203 -0
  333. package/templates/src/layouts/Layout.astro +290 -0
  334. package/templates/src/lib/session.ts +126 -0
  335. package/templates/src/lib/storyData.ts +56 -0
  336. package/templates/src/middleware.ts +52 -0
  337. package/templates/src/pages/404.astro +54 -0
  338. package/templates/src/pages/[...slug]/edit.astro +216 -0
  339. package/templates/src/pages/[...slug].astro +148 -0
  340. package/templates/src/pages/api/auth/decode.ts +101 -0
  341. package/templates/src/pages/api/auth/login.ts +122 -0
  342. package/templates/src/pages/api/auth/logout.ts +37 -0
  343. package/templates/src/pages/api/auth/profile.ts +76 -0
  344. package/templates/src/pages/api/orphan-analysis.ts +106 -0
  345. package/templates/src/pages/api/tailwind.ts +116 -0
  346. package/templates/src/pages/collections/[param1].astro +65 -0
  347. package/templates/src/pages/context/[...contextSlug]/edit.astro +207 -0
  348. package/templates/src/pages/context/[...contextSlug].astro +161 -0
  349. package/templates/src/pages/llms.txt.ts +122 -0
  350. package/templates/src/pages/maint.astro +183 -0
  351. package/templates/src/pages/media/[...slug].astro +67 -0
  352. package/templates/src/pages/robots.txt.ts +36 -0
  353. package/templates/src/pages/sandbox/activate.astro +258 -0
  354. package/templates/src/pages/sandbox/register.astro +44 -0
  355. package/templates/src/pages/sandbox/success.astro +179 -0
  356. package/templates/src/pages/sitemap.xml.ts +119 -0
  357. package/templates/src/pages/storykeep/advanced.astro +69 -0
  358. package/templates/src/pages/storykeep/branding.astro +57 -0
  359. package/templates/src/pages/storykeep/content.astro +71 -0
  360. package/templates/src/pages/storykeep/init.astro +36 -0
  361. package/templates/src/pages/storykeep/login.astro +266 -0
  362. package/templates/src/pages/storykeep/logout.astro +84 -0
  363. package/templates/src/pages/storykeep/profile.astro +98 -0
  364. package/templates/src/pages/storykeep.astro +81 -0
  365. package/templates/src/stores/analytics.ts +171 -0
  366. package/templates/src/stores/backend.ts +16 -0
  367. package/templates/src/stores/navigation.ts +149 -0
  368. package/templates/src/stores/nodes.ts +2390 -0
  369. package/templates/src/stores/nodesHistory.ts +85 -0
  370. package/templates/src/stores/notificationSystem.ts +41 -0
  371. package/templates/src/stores/orphanAnalysis.ts +409 -0
  372. package/templates/src/stores/storykeep.ts +247 -0
  373. package/templates/src/types/astro.ts +86 -0
  374. package/templates/src/types/compositorTypes.ts +456 -0
  375. package/templates/src/types/formTypes.ts +281 -0
  376. package/templates/src/types/multiTenant.ts +77 -0
  377. package/templates/src/types/nodeProps.ts +66 -0
  378. package/templates/src/types/tractstack.ts +445 -0
  379. package/templates/src/utils/aai/getTitleSlug.ts +72 -0
  380. package/templates/src/utils/actions/actionButton.ts +101 -0
  381. package/templates/src/utils/actions/lispLexer.ts +57 -0
  382. package/templates/src/utils/actions/preParse_Action.ts +85 -0
  383. package/templates/src/utils/actions/preParse_Bunny.ts +50 -0
  384. package/templates/src/utils/actions/preParse_Clicked.ts +87 -0
  385. package/templates/src/utils/actions/preParse_Impression.ts +71 -0
  386. package/templates/src/utils/api/advancedConfig.ts +66 -0
  387. package/templates/src/utils/api/advancedHelpers.ts +134 -0
  388. package/templates/src/utils/api/beliefConfig.ts +87 -0
  389. package/templates/src/utils/api/beliefHelpers.ts +196 -0
  390. package/templates/src/utils/api/brandConfig.ts +126 -0
  391. package/templates/src/utils/api/brandHelpers.ts +155 -0
  392. package/templates/src/utils/api/fileHelpers.ts +306 -0
  393. package/templates/src/utils/api/menuConfig.ts +57 -0
  394. package/templates/src/utils/api/menuHelpers.ts +156 -0
  395. package/templates/src/utils/api/resourceConfig.ts +158 -0
  396. package/templates/src/utils/api/resourceHelpers.ts +72 -0
  397. package/templates/src/utils/api/tenantConfig.ts +97 -0
  398. package/templates/src/utils/api/tenantHelpers.ts +172 -0
  399. package/templates/src/utils/api.ts +183 -0
  400. package/templates/src/utils/auth.ts +150 -0
  401. package/templates/src/utils/backend.ts +243 -0
  402. package/templates/src/utils/compositor/TemplateMarkdowns.ts +118 -0
  403. package/templates/src/utils/compositor/TemplateNodes.ts +138 -0
  404. package/templates/src/utils/compositor/TemplatePanes.ts +100 -0
  405. package/templates/src/utils/compositor/allowInsert.ts +100 -0
  406. package/templates/src/utils/compositor/domHelpers.ts +37 -0
  407. package/templates/src/utils/compositor/handleClickEvent.ts +131 -0
  408. package/templates/src/utils/compositor/nodesHelper.ts +491 -0
  409. package/templates/src/utils/compositor/nodesMarkdownGenerator.ts +292 -0
  410. package/templates/src/utils/compositor/processMarkdown.ts +431 -0
  411. package/templates/src/utils/compositor/reduceNodesClassNames.ts +192 -0
  412. package/templates/src/utils/compositor/tailwindClasses.ts +1795 -0
  413. package/templates/src/utils/compositor/tailwindColors.ts +227 -0
  414. package/templates/src/utils/compositor/templateMarkdownStyles.ts +1265 -0
  415. package/templates/src/utils/compositor/typeGuards.ts +193 -0
  416. package/templates/src/utils/etl/extractor.ts +119 -0
  417. package/templates/src/utils/etl/index.ts +88 -0
  418. package/templates/src/utils/etl/loader.ts +36 -0
  419. package/templates/src/utils/etl/transformer.ts +286 -0
  420. package/templates/src/utils/helpers.ts +435 -0
  421. package/templates/src/utils/layout.ts +209 -0
  422. package/templates/src/utils/profileStorage.ts +306 -0
  423. package/templates/src/utils/useInterval.ts +27 -0
  424. package/templates/tailwind.config.cjs +169 -0
  425. package/utils/create-resolver.ts +10 -0
  426. package/utils/inject-files.ts +2140 -0
  427. package/utils/validate-config.ts +43 -0
@@ -0,0 +1,295 @@
1
+ import { useEffect, useState } from 'react';
2
+ import type { FormStateReturn, SaveState } from '@/hooks/useFormState';
3
+
4
+ interface UnsavedChangesBarProps<T> {
5
+ formState: FormStateReturn<T>;
6
+ message?: string;
7
+ saveLabel?: string;
8
+ cancelLabel?: string;
9
+ className?: string;
10
+ }
11
+
12
+ export default function UnsavedChangesBar<T>({
13
+ formState,
14
+ message = 'You have unsaved changes',
15
+ saveLabel = 'Save',
16
+ cancelLabel = 'Discard',
17
+ className = '',
18
+ }: UnsavedChangesBarProps<T>) {
19
+ const { isDirty, isValid, save, cancel, saveState, errorMessage } = formState;
20
+ const [isVisible, setIsVisible] = useState(false);
21
+ const [isAnimating, setIsAnimating] = useState(false);
22
+
23
+ // Handle visibility with smooth animations
24
+ useEffect(() => {
25
+ if (isDirty && !isVisible) {
26
+ setIsVisible(true);
27
+ setTimeout(() => setIsAnimating(true), 10); // Trigger entrance animation
28
+ } else if (!isDirty && isVisible && saveState !== 'saving') {
29
+ setIsAnimating(false);
30
+ setTimeout(() => setIsVisible(false), 1000); // 1 second delay before hiding
31
+ }
32
+ }, [isDirty, isVisible, saveState]);
33
+
34
+ // Early return if not visible
35
+ if (!isVisible) return null;
36
+
37
+ // Determine bar styling based on save state
38
+ const getBarStyling = (state: SaveState) => {
39
+ switch (state) {
40
+ case 'saving':
41
+ return {
42
+ bgColor: 'bg-blue-50',
43
+ borderColor: 'border-blue-200',
44
+ iconColor: 'text-blue-600',
45
+ textColor: 'text-blue-800',
46
+ icon: (
47
+ <svg
48
+ className="h-5 w-5 animate-spin"
49
+ fill="none"
50
+ viewBox="0 0 24 24"
51
+ >
52
+ <circle
53
+ className="opacity-25"
54
+ cx="12"
55
+ cy="12"
56
+ r="10"
57
+ stroke="currentColor"
58
+ strokeWidth="4"
59
+ />
60
+ <path
61
+ className="opacity-75"
62
+ fill="currentColor"
63
+ d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
64
+ />
65
+ </svg>
66
+ ),
67
+ };
68
+ case 'success':
69
+ return {
70
+ bgColor: 'bg-green-50',
71
+ borderColor: 'border-green-200',
72
+ iconColor: 'text-green-600',
73
+ textColor: 'text-green-800',
74
+ icon: (
75
+ <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
76
+ <path
77
+ fillRule="evenodd"
78
+ d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
79
+ clipRule="evenodd"
80
+ />
81
+ </svg>
82
+ ),
83
+ };
84
+ case 'error':
85
+ return {
86
+ bgColor: 'bg-red-50',
87
+ borderColor: 'border-red-200',
88
+ iconColor: 'text-red-600',
89
+ textColor: 'text-red-800',
90
+ icon: (
91
+ <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
92
+ <path
93
+ fillRule="evenodd"
94
+ d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
95
+ clipRule="evenodd"
96
+ />
97
+ </svg>
98
+ ),
99
+ };
100
+ default: // 'idle' or unsaved changes
101
+ return {
102
+ bgColor: 'bg-amber-50',
103
+ borderColor: 'border-amber-200',
104
+ iconColor: 'text-amber-600',
105
+ textColor: 'text-amber-800',
106
+ icon: (
107
+ <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
108
+ <path
109
+ fillRule="evenodd"
110
+ d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z"
111
+ clipRule="evenodd"
112
+ />
113
+ </svg>
114
+ ),
115
+ };
116
+ }
117
+ };
118
+
119
+ const styling = getBarStyling(saveState);
120
+
121
+ // Get message based on save state
122
+ const getMessage = () => {
123
+ switch (saveState) {
124
+ case 'saving':
125
+ return 'Saving changes...';
126
+ case 'success':
127
+ return 'Changes saved successfully!';
128
+ case 'error':
129
+ return errorMessage || 'Failed to save changes';
130
+ default:
131
+ return message;
132
+ }
133
+ };
134
+
135
+ // Handle save button click
136
+ const handleSave = async () => {
137
+ await save();
138
+ };
139
+
140
+ return (
141
+ <div
142
+ className={`fixed bottom-0 left-0 right-0 z-50 transform pr-12 transition-all duration-300 ease-in-out ${
143
+ isAnimating ? 'translate-y-0 opacity-100' : 'translate-y-full opacity-0'
144
+ } ${className}`}
145
+ >
146
+ {/* Backdrop blur overlay */}
147
+ <div className="absolute inset-0 bg-black/10 backdrop-blur-sm" />
148
+
149
+ {/* Main content bar */}
150
+ <div className="relative mx-auto max-w-7xl px-4 py-4 sm:px-6 lg:px-8">
151
+ <div
152
+ className={`flex items-center justify-between rounded-lg border px-4 py-3 shadow-lg ${styling.bgColor} ${styling.borderColor}`}
153
+ >
154
+ {/* Icon + message */}
155
+ <div className="flex items-center space-x-3">
156
+ <div className={`flex-shrink-0 ${styling.iconColor}`}>
157
+ {styling.icon}
158
+ </div>
159
+ <div>
160
+ <p className={`text-sm font-bold ${styling.textColor}`}>
161
+ {getMessage()}
162
+ </p>
163
+ {saveState === 'error' && errorMessage && (
164
+ <p className="mt-1 text-xs text-red-600">
165
+ Click save to try again
166
+ </p>
167
+ )}
168
+ </div>
169
+ </div>
170
+
171
+ {/* Action buttons */}
172
+ <div className="flex items-center space-x-3">
173
+ {/* Cancel/Discard button - only show when not saving or showing success */}
174
+ {saveState !== 'saving' && saveState !== 'success' && (
175
+ <button
176
+ type="button"
177
+ onClick={cancel}
178
+ className={`rounded-md border px-3 py-2 text-sm font-bold shadow-sm transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-offset-2 ${
179
+ saveState === 'error'
180
+ ? 'border-red-300 bg-white text-red-800 hover:bg-red-50 focus:ring-red-500'
181
+ : 'border-amber-300 bg-white text-amber-800 hover:bg-amber-50 focus:ring-amber-500'
182
+ }`}
183
+ >
184
+ {cancelLabel}
185
+ </button>
186
+ )}
187
+
188
+ {/* Save button - only show when changes exist and not showing success */}
189
+ {isDirty && saveState !== 'success' && (
190
+ <button
191
+ type="button"
192
+ onClick={handleSave}
193
+ disabled={!isValid || saveState === 'saving'}
194
+ className={`rounded-md border border-transparent px-4 py-2 text-sm font-bold text-white shadow-sm transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed ${
195
+ saveState === 'saving'
196
+ ? 'bg-blue-500 opacity-75'
197
+ : saveState === 'error'
198
+ ? isValid
199
+ ? 'bg-red-600 hover:bg-red-700 focus:ring-red-500'
200
+ : 'bg-red-400 opacity-50'
201
+ : isValid
202
+ ? 'bg-amber-600 hover:bg-amber-700 focus:ring-amber-500'
203
+ : 'bg-amber-400 opacity-50'
204
+ }`}
205
+ >
206
+ {saveState === 'saving' ? 'Saving...' : saveLabel}
207
+ </button>
208
+ )}
209
+ </div>
210
+ </div>
211
+ </div>
212
+ </div>
213
+ );
214
+ }
215
+
216
+ // Alternative minimal version for tighter spaces
217
+ export function UnsavedChangesBarMini<T>({
218
+ formState,
219
+ message = 'Unsaved changes',
220
+ }: Pick<UnsavedChangesBarProps<T>, 'formState' | 'message'>) {
221
+ const { isDirty, isValid, save, cancel, saveState } = formState;
222
+ const [isVisible, setIsVisible] = useState(false);
223
+
224
+ useEffect(() => {
225
+ setIsVisible(isDirty);
226
+ }, [isDirty]);
227
+
228
+ if (!isVisible) return null;
229
+
230
+ const handleSave = async () => {
231
+ await save();
232
+ };
233
+
234
+ return (
235
+ <div className="animate-in slide-in-from-bottom-2 fixed bottom-4 right-4 z-50 duration-300">
236
+ <div
237
+ className={`flex items-center space-x-2 rounded-lg border px-3 py-2 shadow-lg ${
238
+ saveState === 'success'
239
+ ? 'border-green-200 bg-green-50'
240
+ : saveState === 'error'
241
+ ? 'border-red-200 bg-red-50'
242
+ : 'border-amber-200 bg-amber-50'
243
+ }`}
244
+ >
245
+ <span
246
+ className={`text-xs font-bold ${
247
+ saveState === 'success'
248
+ ? 'text-green-800'
249
+ : saveState === 'error'
250
+ ? 'text-red-800'
251
+ : 'text-amber-800'
252
+ }`}
253
+ >
254
+ {saveState === 'success'
255
+ ? 'Saved!'
256
+ : saveState === 'error'
257
+ ? 'Error'
258
+ : message}
259
+ </span>
260
+
261
+ {saveState !== 'success' && (
262
+ <>
263
+ <button
264
+ onClick={cancel}
265
+ className={`text-xs hover:font-bold ${
266
+ saveState === 'error'
267
+ ? 'text-red-600 hover:text-red-800'
268
+ : 'text-amber-600 hover:text-amber-800'
269
+ }`}
270
+ >
271
+ Discard
272
+ </button>
273
+ <button
274
+ onClick={handleSave}
275
+ disabled={!isValid || saveState === 'saving'}
276
+ className={`rounded px-2 py-1 text-xs text-white transition-colors disabled:cursor-not-allowed ${
277
+ saveState === 'saving'
278
+ ? 'bg-blue-500 opacity-75'
279
+ : saveState === 'error'
280
+ ? isValid
281
+ ? 'bg-red-600 hover:bg-red-700'
282
+ : 'bg-red-400 opacity-50'
283
+ : isValid
284
+ ? 'bg-amber-600 hover:bg-amber-700'
285
+ : 'bg-amber-400 opacity-50'
286
+ }`}
287
+ >
288
+ {saveState === 'saving' ? 'Saving...' : 'Save'}
289
+ </button>
290
+ </>
291
+ )}
292
+ </div>
293
+ </div>
294
+ );
295
+ }
@@ -0,0 +1,69 @@
1
+ import StringInput from '../StringInput';
2
+ import type { FormStateReturn } from '@/hooks/useFormState';
3
+ import type {
4
+ AdvancedConfigState,
5
+ AdvancedConfigStatus,
6
+ } from '@/types/tractstack';
7
+
8
+ interface APIConfigSectionProps {
9
+ formState: FormStateReturn<AdvancedConfigState>;
10
+ status: AdvancedConfigStatus | null;
11
+ }
12
+
13
+ export default function APIConfigSection({
14
+ formState,
15
+ status,
16
+ }: APIConfigSectionProps) {
17
+ const { state, updateField, errors } = formState;
18
+
19
+ const aaiConfigured = status?.aaiAPIKeySet;
20
+
21
+ return (
22
+ <div className="bg-white shadow sm:rounded-lg">
23
+ <div className="px-4 py-5 sm:p-6">
24
+ <div className="flex items-center justify-between">
25
+ <h3 className="text-base font-bold leading-6 text-gray-900">
26
+ API Configuration
27
+ </h3>
28
+ <div className="flex items-center">
29
+ {aaiConfigured ? (
30
+ <span className="inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-bold text-green-800">
31
+ ✓ Configured
32
+ </span>
33
+ ) : status !== null ? (
34
+ <span className="inline-flex items-center rounded-full bg-yellow-100 px-2.5 py-0.5 text-xs font-bold text-yellow-800">
35
+ Optional
36
+ </span>
37
+ ) : (
38
+ <span className="inline-flex items-center rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-bold text-gray-800">
39
+ Loading...
40
+ </span>
41
+ )}
42
+ </div>
43
+ </div>
44
+ <div className="mt-2 max-w-xl text-sm text-gray-500">
45
+ <p>Configure external API keys for enhanced functionality.</p>
46
+ </div>
47
+ <div className="mt-5">
48
+ <StringInput
49
+ label="AssemblyAI API Key"
50
+ value={state.aaiApiKey}
51
+ onChange={(value) => updateField('aaiApiKey', value)}
52
+ type="password"
53
+ placeholder={
54
+ aaiConfigured ? '••••••••••••••••' : 'Enter AssemblyAI API key'
55
+ }
56
+ error={errors.aaiApiKey}
57
+ />
58
+ </div>
59
+ <div className="mt-3 text-xs text-gray-500">
60
+ <p>
61
+ Used for audio transcription and analysis features. Optional but
62
+ required for audio processing.
63
+ {aaiConfigured && ' Leave blank to keep existing key.'}
64
+ </p>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ );
69
+ }
@@ -0,0 +1,97 @@
1
+ import StringInput from '../StringInput';
2
+ import type { FormStateReturn } from '@/hooks/useFormState';
3
+ import type {
4
+ AdvancedConfigState,
5
+ AdvancedConfigStatus,
6
+ } from '@/types/tractstack';
7
+
8
+ interface AuthConfigSectionProps {
9
+ formState: FormStateReturn<AdvancedConfigState>;
10
+ status: AdvancedConfigStatus | null;
11
+ }
12
+
13
+ export default function AuthConfigSection({
14
+ formState,
15
+ status,
16
+ }: AuthConfigSectionProps) {
17
+ const { state, updateField, errors } = formState;
18
+
19
+ const adminConfigured = status?.adminPasswordSet;
20
+ const editorConfigured = status?.editorPasswordSet;
21
+
22
+ return (
23
+ <div className="bg-white shadow sm:rounded-lg">
24
+ <div className="px-4 py-5 sm:p-6">
25
+ <h3 className="text-base font-bold leading-6 text-gray-900">
26
+ Authentication Configuration
27
+ </h3>
28
+ <div className="mt-2 max-w-xl text-sm text-gray-500">
29
+ <p>
30
+ Set passwords for admin and editor access to the StoryKeep
31
+ dashboard.
32
+ </p>
33
+ </div>
34
+ <div className="mt-5 space-y-4">
35
+ <div>
36
+ <div className="mb-1 flex items-center justify-between">
37
+ <label className="block text-sm font-bold text-gray-700">
38
+ Admin Password
39
+ </label>
40
+ {adminConfigured ? (
41
+ <span className="inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-bold text-green-800">
42
+ ✓ Set
43
+ </span>
44
+ ) : status !== null ? (
45
+ <span className="inline-flex items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-bold text-red-800">
46
+ ! Not Set
47
+ </span>
48
+ ) : null}
49
+ </div>
50
+ <StringInput
51
+ value={state.adminPassword}
52
+ onChange={(value) => updateField('adminPassword', value)}
53
+ type="password"
54
+ placeholder={
55
+ adminConfigured ? '••••••••••••••••' : 'Enter admin password'
56
+ }
57
+ error={errors.adminPassword}
58
+ />
59
+ </div>
60
+ <div>
61
+ <div className="mb-1 flex items-center justify-between">
62
+ <label className="block text-sm font-bold text-gray-700">
63
+ Editor Password
64
+ </label>
65
+ {editorConfigured ? (
66
+ <span className="inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-bold text-green-800">
67
+ ✓ Set
68
+ </span>
69
+ ) : status !== null ? (
70
+ <span className="inline-flex items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-bold text-red-800">
71
+ ! Not Set
72
+ </span>
73
+ ) : null}
74
+ </div>
75
+ <StringInput
76
+ value={state.editorPassword}
77
+ onChange={(value) => updateField('editorPassword', value)}
78
+ type="password"
79
+ placeholder={
80
+ editorConfigured ? '••••••••••••••••' : 'Enter editor password'
81
+ }
82
+ error={errors.editorPassword}
83
+ />
84
+ </div>
85
+ </div>
86
+ <div className="mt-3 text-xs text-gray-500">
87
+ <p>
88
+ Admin has full access. Editor has limited access to content
89
+ management only.
90
+ {(adminConfigured || editorConfigured) &&
91
+ ' Leave blank to keep existing passwords.'}
92
+ </p>
93
+ </div>
94
+ </div>
95
+ </div>
96
+ );
97
+ }
@@ -0,0 +1,93 @@
1
+ import EnumSelect from '../EnumSelect';
2
+ import FileUpload from '../FileUpload';
3
+ import type { BrandConfigState } from '@/types/tractstack';
4
+ import type { FormStateReturn } from '@/hooks/useFormState';
5
+
6
+ interface BrandAssetsSectionProps {
7
+ formState: FormStateReturn<BrandConfigState>;
8
+ }
9
+
10
+ // Wordmark mode options
11
+ const WORDMARK_MODE_OPTIONS = [
12
+ { value: 'default', label: 'Show Logo and Wordmark' },
13
+ { value: 'wordmark', label: 'Wordmark Only' },
14
+ { value: 'logo', label: 'Logo Only' },
15
+ ];
16
+
17
+ export default function BrandAssetsSection({
18
+ formState,
19
+ }: BrandAssetsSectionProps) {
20
+ const { state, updateField, errors } = formState;
21
+
22
+ return (
23
+ <div className="rounded-lg border border-gray-200 bg-white p-6">
24
+ <h3 id="assets" className="mb-4 text-lg font-bold text-gray-900">
25
+ Brand Assets
26
+ </h3>
27
+
28
+ <div className="space-y-6">
29
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
30
+ {/* Logo - SVG preferred for scalability */}
31
+ <FileUpload
32
+ value={state.logoBase64 || state.logo}
33
+ onChange={(value) => updateField('logoBase64', value)}
34
+ label="Logo"
35
+ allowedFormats={['svg', 'png', 'jpg', 'jpeg']}
36
+ maxSizeKB={1024}
37
+ showPreview={true}
38
+ allowAnyImageWithWarning={true}
39
+ error={errors.logo}
40
+ />
41
+
42
+ {/* Wordmark - SVG preferred for scalability */}
43
+ <FileUpload
44
+ value={state.wordmarkBase64 || state.wordmark}
45
+ onChange={(value) => updateField('wordmarkBase64', value)}
46
+ label="Wordmark"
47
+ allowedFormats={['svg', 'png', 'jpg', 'jpeg']}
48
+ maxSizeKB={1024}
49
+ showPreview={true}
50
+ allowAnyImageWithWarning={true}
51
+ error={errors.wordmark}
52
+ />
53
+ </div>
54
+
55
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
56
+ {/* Favicon - ICO or SVG only */}
57
+ <FileUpload
58
+ value={state.faviconBase64 || state.favicon}
59
+ onChange={(value) => updateField('faviconBase64', value)}
60
+ label="Favicon"
61
+ allowedFormats={['ico', 'svg']}
62
+ maxSizeKB={100}
63
+ showPreview={true}
64
+ error={errors.favicon}
65
+ />
66
+
67
+ {/* OG Logo - Auto-resized to 512x512 */}
68
+ <FileUpload
69
+ value={state.oglogoBase64 || state.oglogo}
70
+ onChange={(value) => updateField('oglogoBase64', value)}
71
+ label="Open Graph Logo"
72
+ autoResize={{ width: 512, height: 512 }}
73
+ allowAnyImageWithWarning={true}
74
+ maxSizeKB={1024}
75
+ showPreview={true}
76
+ error={errors.oglogo}
77
+ />
78
+ </div>
79
+
80
+ {/* Wordmark Mode */}
81
+ <EnumSelect
82
+ value={state.wordmarkMode}
83
+ onChange={(value) => updateField('wordmarkMode', value)}
84
+ label="Display Mode"
85
+ options={WORDMARK_MODE_OPTIONS}
86
+ error={errors.wordmarkMode}
87
+ id="wordmark-mode"
88
+ placeholder="Select display mode"
89
+ />
90
+ </div>
91
+ </div>
92
+ );
93
+ }