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.
- package/LICENSE +110 -0
- package/README.md +56 -0
- package/astro.d.ts +64 -0
- package/bin/create-tractstack.js +483 -0
- package/dist/config.js +80 -0
- package/dist/index.js +2129 -0
- package/package.json +89 -0
- package/templates/artpacks/kCz/captainBreakfast_1080px.webp +0 -0
- package/templates/artpacks/kCz/captainBreakfast_1920px.webp +0 -0
- package/templates/artpacks/kCz/captainBreakfast_600px.webp +0 -0
- package/templates/artpacks/kCz/cleanDrips_1080px.webp +0 -0
- package/templates/artpacks/kCz/cleanDrips_1920px.webp +0 -0
- package/templates/artpacks/kCz/cleanDrips_600px.webp +0 -0
- package/templates/artpacks/kCz/crispwaves_1080px.webp +0 -0
- package/templates/artpacks/kCz/crispwaves_1920px.webp +0 -0
- package/templates/artpacks/kCz/crispwaves_600px.webp +0 -0
- package/templates/artpacks/kCz/dragonSkin_1080px.webp +0 -0
- package/templates/artpacks/kCz/dragonSkin_1920px.webp +0 -0
- package/templates/artpacks/kCz/dragonSkin_600px.webp +0 -0
- package/templates/artpacks/kCz/dragon_1080px.webp +0 -0
- package/templates/artpacks/kCz/dragon_1920px.webp +0 -0
- package/templates/artpacks/kCz/dragon_600px.webp +0 -0
- package/templates/artpacks/kCz/nightcity_1080px.webp +0 -0
- package/templates/artpacks/kCz/nightcity_1920px.webp +0 -0
- package/templates/artpacks/kCz/nightcity_600px.webp +0 -0
- package/templates/artpacks/kCz/pattern1_1080px.webp +0 -0
- package/templates/artpacks/kCz/pattern1_1920px.webp +0 -0
- package/templates/artpacks/kCz/pattern1_600px.webp +0 -0
- package/templates/artpacks/kCz/pattern2_1080px.webp +0 -0
- package/templates/artpacks/kCz/pattern2_1920px.webp +0 -0
- package/templates/artpacks/kCz/pattern2_600px.webp +0 -0
- package/templates/artpacks/kCz/skindrips_1080px.webp +0 -0
- package/templates/artpacks/kCz/skindrips_1920px.webp +0 -0
- package/templates/artpacks/kCz/skindrips_600px.webp +0 -0
- package/templates/artpacks/kCz/slimetime_1080px.webp +0 -0
- package/templates/artpacks/kCz/slimetime_1920px.webp +0 -0
- package/templates/artpacks/kCz/slimetime_600px.webp +0 -0
- package/templates/artpacks/kCz/snake_1080px.webp +0 -0
- package/templates/artpacks/kCz/snake_1920px.webp +0 -0
- package/templates/artpacks/kCz/snake_600px.webp +0 -0
- package/templates/artpacks/kCz/toxicshock_1080px.webp +0 -0
- package/templates/artpacks/kCz/toxicshock_1920px.webp +0 -0
- package/templates/artpacks/kCz/toxicshock_600px.webp +0 -0
- package/templates/artpacks/kCz/tractstack_1080px.webp +0 -0
- package/templates/artpacks/kCz/tractstack_1920px.webp +0 -0
- package/templates/artpacks/kCz/tractstack_600px.webp +0 -0
- package/templates/artpacks/kCz/tripdrips_1080px.webp +0 -0
- package/templates/artpacks/kCz/tripdrips_1920px.webp +0 -0
- package/templates/artpacks/kCz/tripdrips_600px.webp +0 -0
- package/templates/artpacks/kCz/wavedrips_1080px.webp +0 -0
- package/templates/artpacks/kCz/wavedrips_1920px.webp +0 -0
- package/templates/artpacks/kCz/wavedrips_600px.webp +0 -0
- package/templates/artpacks/t8k/beach_1080px.webp +0 -0
- package/templates/artpacks/t8k/beach_1920px.webp +0 -0
- package/templates/artpacks/t8k/beach_600px.webp +0 -0
- package/templates/artpacks/t8k/blast_1080px.webp +0 -0
- package/templates/artpacks/t8k/blast_1920px.webp +0 -0
- package/templates/artpacks/t8k/blast_600px.webp +0 -0
- package/templates/artpacks/t8k/bokeh_1080px.webp +0 -0
- package/templates/artpacks/t8k/bokeh_1920px.webp +0 -0
- package/templates/artpacks/t8k/bokeh_600px.webp +0 -0
- package/templates/artpacks/t8k/cartoon_1080px.webp +0 -0
- package/templates/artpacks/t8k/cartoon_1920px.webp +0 -0
- package/templates/artpacks/t8k/cartoon_600px.webp +0 -0
- package/templates/artpacks/t8k/darkeggshell_1080px.webp +0 -0
- package/templates/artpacks/t8k/darkeggshell_1920px.webp +0 -0
- package/templates/artpacks/t8k/darkeggshell_600px.webp +0 -0
- package/templates/artpacks/t8k/explosion_1080px.webp +0 -0
- package/templates/artpacks/t8k/explosion_1920px.webp +0 -0
- package/templates/artpacks/t8k/explosion_600px.webp +0 -0
- package/templates/artpacks/t8k/floral_1080px.webp +0 -0
- package/templates/artpacks/t8k/floral_1920px.webp +0 -0
- package/templates/artpacks/t8k/floral_600px.webp +0 -0
- package/templates/artpacks/t8k/flower_1080px.webp +0 -0
- package/templates/artpacks/t8k/flower_1920px.webp +0 -0
- package/templates/artpacks/t8k/flower_600px.webp +0 -0
- package/templates/artpacks/t8k/foliage_1080px.webp +0 -0
- package/templates/artpacks/t8k/foliage_1920px.webp +0 -0
- package/templates/artpacks/t8k/foliage_600px.webp +0 -0
- package/templates/artpacks/t8k/mist_1080px.webp +0 -0
- package/templates/artpacks/t8k/mist_1920px.webp +0 -0
- package/templates/artpacks/t8k/mist_600px.webp +0 -0
- package/templates/artpacks/t8k/portal_1080px.webp +0 -0
- package/templates/artpacks/t8k/portal_1920px.webp +0 -0
- package/templates/artpacks/t8k/portal_600px.webp +0 -0
- package/templates/artpacks/t8k/storytime_1080px.webp +0 -0
- package/templates/artpacks/t8k/storytime_1920px.webp +0 -0
- package/templates/artpacks/t8k/storytime_600px.webp +0 -0
- package/templates/artpacks/t8k/tacky_1080px.webp +0 -0
- package/templates/artpacks/t8k/tacky_1920px.webp +0 -0
- package/templates/artpacks/t8k/tacky_600px.webp +0 -0
- package/templates/artpacks/t8k/wallpaper_1080px.webp +0 -0
- package/templates/artpacks/t8k/wallpaper_1920px.webp +0 -0
- package/templates/artpacks/t8k/wallpaper_600px.webp +0 -0
- package/templates/brand/favicon.ico +0 -0
- package/templates/brand/logo.svg +19 -0
- package/templates/brand/static.jpg +0 -0
- package/templates/brand/wordmark.svg +4 -0
- package/templates/css/custom.css +51 -0
- package/templates/css/frontend.css +3519 -0
- package/templates/css/storykeep.css +92872 -0
- package/templates/custom/minimal/CodeHook.astro +53 -0
- package/templates/custom/minimal/CustomRoutes.astro +46 -0
- package/templates/custom/with-examples/CodeHook.astro +49 -0
- package/templates/custom/with-examples/CustomHero.astro +13 -0
- package/templates/custom/with-examples/CustomRoutes.astro +39 -0
- package/templates/custom/with-examples/pages/Collections.astro +110 -0
- package/templates/env.example +8 -0
- package/templates/fonts/Inter-Black.woff2 +0 -0
- package/templates/fonts/Inter-Bold.woff2 +0 -0
- package/templates/fonts/Inter-Regular.woff2 +0 -0
- package/templates/icons/h2.svg +1 -0
- package/templates/icons/h3.svg +1 -0
- package/templates/icons/h4.svg +1 -0
- package/templates/icons/h5.svg +1 -0
- package/templates/icons/image.svg +7 -0
- package/templates/icons/text.svg +6 -0
- package/templates/socials/codepen.svg +1 -0
- package/templates/socials/discord.svg +1 -0
- package/templates/socials/facebook.svg +1 -0
- package/templates/socials/github.svg +1 -0
- package/templates/socials/instagram.svg +1 -0
- package/templates/socials/linkedin.svg +1 -0
- package/templates/socials/mail.svg +1 -0
- package/templates/socials/rumble.svg +1 -0
- package/templates/socials/tiktok.svg +1 -0
- package/templates/socials/twitch.svg +1 -0
- package/templates/socials/twitter.svg +1 -0
- package/templates/socials/x.svg +1 -0
- package/templates/socials/youtube.svg +1 -0
- package/templates/src/client/analytics-events.ts +213 -0
- package/templates/src/client/belief-events.ts +205 -0
- package/templates/src/client/sse.ts +667 -0
- package/templates/src/components/Footer.astro +246 -0
- package/templates/src/components/Fragment.astro +70 -0
- package/templates/src/components/Header.astro +458 -0
- package/templates/src/components/Menu.tsx +196 -0
- package/templates/src/components/codehooks/BunnyVideoSetup.tsx +692 -0
- package/templates/src/components/codehooks/BunnyVideoWrapper.astro +78 -0
- package/templates/src/components/codehooks/EpinetDurationSelector.tsx +1020 -0
- package/templates/src/components/codehooks/EpinetTableView.tsx +594 -0
- package/templates/src/components/codehooks/EpinetWrapper.tsx +424 -0
- package/templates/src/components/codehooks/FeaturedContent.astro +273 -0
- package/templates/src/components/codehooks/FeaturedContentSetup.tsx +738 -0
- package/templates/src/components/codehooks/ListContent.astro +460 -0
- package/templates/src/components/codehooks/ListContentSetup.tsx +649 -0
- package/templates/src/components/codehooks/SankeyDiagram.tsx +359 -0
- package/templates/src/components/compositor/Compositor.tsx +144 -0
- package/templates/src/components/compositor/Node.tsx +415 -0
- package/templates/src/components/compositor/NodeWithGuid.tsx +25 -0
- package/templates/src/components/compositor/PanelVisibilityWrapper.tsx +87 -0
- package/templates/src/components/compositor/elements/Belief.tsx +148 -0
- package/templates/src/components/compositor/elements/BgImage.tsx +118 -0
- package/templates/src/components/compositor/elements/BgVisualBreak.tsx +102 -0
- package/templates/src/components/compositor/elements/BunnyVideo.tsx +63 -0
- package/templates/src/components/compositor/elements/IdentifyAs.tsx +66 -0
- package/templates/src/components/compositor/elements/PlayButton.tsx +19 -0
- package/templates/src/components/compositor/elements/SignUp.tsx +179 -0
- package/templates/src/components/compositor/elements/Svg.tsx +33 -0
- package/templates/src/components/compositor/elements/ToggleBelief.tsx +36 -0
- package/templates/src/components/compositor/elements/YouTubeWrapper.tsx +33 -0
- package/templates/src/components/compositor/nodes/BgPaneWrapper.tsx +35 -0
- package/templates/src/components/compositor/nodes/GhostInsertBlock.tsx +189 -0
- package/templates/src/components/compositor/nodes/Markdown.tsx +179 -0
- package/templates/src/components/compositor/nodes/Pane.tsx +277 -0
- package/templates/src/components/compositor/nodes/Pane_eraser.tsx +69 -0
- package/templates/src/components/compositor/nodes/Pane_layout.tsx +77 -0
- package/templates/src/components/compositor/nodes/RenderChildren.tsx +19 -0
- package/templates/src/components/compositor/nodes/StoryFragment.tsx +35 -0
- package/templates/src/components/compositor/nodes/TagElement.tsx +14 -0
- package/templates/src/components/compositor/nodes/Widget.tsx +115 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeA.tsx +4 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeA_eraser.tsx +26 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeAnchorComponent.tsx +248 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag.tsx +684 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_eraser.tsx +62 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_insert.tsx +120 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_settings.tsx +62 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeButton.tsx +5 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeButton_eraser.tsx +26 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeImg.tsx +28 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeText.tsx +18 -0
- package/templates/src/components/compositor/nodes/tagElements/TabIndicator.tsx +51 -0
- package/templates/src/components/compositor/preview/FeaturedContentPreview.tsx +128 -0
- package/templates/src/components/compositor/preview/ListContentPreview.tsx +213 -0
- package/templates/src/components/compositor/preview/OgImagePreview.tsx +223 -0
- package/templates/src/components/compositor/preview/PaneSnapshotGenerator.tsx +199 -0
- package/templates/src/components/compositor/preview/PanesPreviewGenerator.tsx +123 -0
- package/templates/src/components/compositor/preview/VisualBreakPreview.tsx +154 -0
- package/templates/src/components/edit/Header.tsx +181 -0
- package/templates/src/components/edit/PanelSwitch.tsx +446 -0
- package/templates/src/components/edit/SettingsPanel.tsx +70 -0
- package/templates/src/components/edit/ToolBar.tsx +101 -0
- package/templates/src/components/edit/ToolMode.tsx +121 -0
- package/templates/src/components/edit/context/ContextPaneConfig.tsx +91 -0
- package/templates/src/components/edit/context/ContextPaneConfig_slug.tsx +174 -0
- package/templates/src/components/edit/context/ContextPaneConfig_title.tsx +186 -0
- package/templates/src/components/edit/pane/AddPanePanel.tsx +136 -0
- package/templates/src/components/edit/pane/AddPanePanel_break.tsx +470 -0
- package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +264 -0
- package/templates/src/components/edit/pane/AddPanePanel_new.tsx +623 -0
- package/templates/src/components/edit/pane/AddPanePanel_newAICopy.tsx +107 -0
- package/templates/src/components/edit/pane/AddPanePanel_newAICopy_modal.tsx +217 -0
- package/templates/src/components/edit/pane/AddPanePanel_newCopyMode.tsx +109 -0
- package/templates/src/components/edit/pane/AddPanePanel_newCustomCopy.tsx +39 -0
- package/templates/src/components/edit/pane/AddPanePanel_reuse.tsx +445 -0
- package/templates/src/components/edit/pane/ConfigPanePanel.tsx +245 -0
- package/templates/src/components/edit/pane/PageGen.tsx +485 -0
- package/templates/src/components/edit/pane/PageGenSelector.tsx +238 -0
- package/templates/src/components/edit/pane/PageGenSpecial.tsx +362 -0
- package/templates/src/components/edit/pane/PageGen_preview.tsx +495 -0
- package/templates/src/components/edit/pane/PanePanel_impression.tsx +258 -0
- package/templates/src/components/edit/pane/PanePanel_path.tsx +268 -0
- package/templates/src/components/edit/pane/PanePanel_slug.tsx +219 -0
- package/templates/src/components/edit/pane/PanePanel_title.tsx +142 -0
- package/templates/src/components/edit/panels/StyleBreakPanel.tsx +182 -0
- package/templates/src/components/edit/panels/StyleCodeHookPanel.tsx +439 -0
- package/templates/src/components/edit/panels/StyleElementPanel.tsx +177 -0
- package/templates/src/components/edit/panels/StyleElementPanel_add.tsx +349 -0
- package/templates/src/components/edit/panels/StyleElementPanel_remove.tsx +159 -0
- package/templates/src/components/edit/panels/StyleElementPanel_update.tsx +320 -0
- package/templates/src/components/edit/panels/StyleImagePanel.tsx +460 -0
- package/templates/src/components/edit/panels/StyleImagePanel_add.tsx +296 -0
- package/templates/src/components/edit/panels/StyleImagePanel_remove.tsx +153 -0
- package/templates/src/components/edit/panels/StyleImagePanel_update.tsx +312 -0
- package/templates/src/components/edit/panels/StyleLiElementPanel.tsx +273 -0
- package/templates/src/components/edit/panels/StyleLiElementPanel_add.tsx +301 -0
- package/templates/src/components/edit/panels/StyleLiElementPanel_remove.tsx +132 -0
- package/templates/src/components/edit/panels/StyleLiElementPanel_update.tsx +313 -0
- package/templates/src/components/edit/panels/StyleLinkPanel.tsx +346 -0
- package/templates/src/components/edit/panels/StyleLinkPanel_add.tsx +265 -0
- package/templates/src/components/edit/panels/StyleLinkPanel_config.tsx +240 -0
- package/templates/src/components/edit/panels/StyleLinkPanel_remove.tsx +94 -0
- package/templates/src/components/edit/panels/StyleLinkPanel_update.tsx +110 -0
- package/templates/src/components/edit/panels/StyleParentPanel.tsx +263 -0
- package/templates/src/components/edit/panels/StyleParentPanel_add.tsx +275 -0
- package/templates/src/components/edit/panels/StyleParentPanel_deleteLayer.tsx +112 -0
- package/templates/src/components/edit/panels/StyleParentPanel_remove.tsx +87 -0
- package/templates/src/components/edit/panels/StyleParentPanel_update.tsx +141 -0
- package/templates/src/components/edit/panels/StyleWidgetPanel.tsx +428 -0
- package/templates/src/components/edit/panels/StyleWidgetPanel_add.tsx +292 -0
- package/templates/src/components/edit/panels/StyleWidgetPanel_config.tsx +190 -0
- package/templates/src/components/edit/panels/StyleWidgetPanel_remove.tsx +152 -0
- package/templates/src/components/edit/panels/StyleWidgetPanel_update.tsx +308 -0
- package/templates/src/components/edit/state/SaveModal.tsx +811 -0
- package/templates/src/components/edit/state/StylesMemory.tsx +310 -0
- package/templates/src/components/edit/storyfragment/StoryFragmentConfigPanel.tsx +289 -0
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_menu.tsx +320 -0
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_og.tsx +888 -0
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_slug.tsx +269 -0
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_title.tsx +190 -0
- package/templates/src/components/edit/widgets/BeliefWidget.tsx +183 -0
- package/templates/src/components/edit/widgets/BunnyWidget.tsx +134 -0
- package/templates/src/components/edit/widgets/IdentifyAsWidget.tsx +193 -0
- package/templates/src/components/edit/widgets/SignupWidget.tsx +177 -0
- package/templates/src/components/edit/widgets/ToggleWidget.tsx +152 -0
- package/templates/src/components/edit/widgets/YouTubeWidget.tsx +65 -0
- package/templates/src/components/fields/ActionBuilderTimeSelector.tsx +353 -0
- package/templates/src/components/fields/ArtpackImage.tsx +480 -0
- package/templates/src/components/fields/BackgroundImage.tsx +530 -0
- package/templates/src/components/fields/BackgroundImageWrapper.tsx +192 -0
- package/templates/src/components/fields/BooleanParam.tsx +67 -0
- package/templates/src/components/fields/BunnyMomentSelector.tsx +56 -0
- package/templates/src/components/fields/ColorPickerCombo.tsx +284 -0
- package/templates/src/components/fields/ImageUpload.tsx +405 -0
- package/templates/src/components/fields/MultiParam.tsx +75 -0
- package/templates/src/components/fields/PaneBreakCollectionSelector.tsx +97 -0
- package/templates/src/components/fields/PaneBreakShapeSelector.tsx +134 -0
- package/templates/src/components/fields/SelectedTailwindClass.tsx +44 -0
- package/templates/src/components/fields/SingleParam.tsx +73 -0
- package/templates/src/components/fields/ViewportComboBox.tsx +252 -0
- package/templates/src/components/form/ActionBuilderField.tsx +282 -0
- package/templates/src/components/form/ActionBuilderSlugSelector.tsx +182 -0
- package/templates/src/components/form/BooleanToggle.tsx +94 -0
- package/templates/src/components/form/ColorPicker.tsx +153 -0
- package/templates/src/components/form/DateTimeInput.tsx +638 -0
- package/templates/src/components/form/EnumSelect.tsx +88 -0
- package/templates/src/components/form/FileUpload.tsx +465 -0
- package/templates/src/components/form/MagicPathBuilder.tsx +546 -0
- package/templates/src/components/form/NumberInput.tsx +101 -0
- package/templates/src/components/form/ParagraphArrayInput.tsx +207 -0
- package/templates/src/components/form/StringArrayInput.tsx +163 -0
- package/templates/src/components/form/StringInput.tsx +88 -0
- package/templates/src/components/form/UnsavedChangesBar.tsx +295 -0
- package/templates/src/components/form/advanced/APIConfigSection.tsx +69 -0
- package/templates/src/components/form/advanced/AuthConfigSection.tsx +97 -0
- package/templates/src/components/form/brand/BrandAssetsSection.tsx +93 -0
- package/templates/src/components/form/brand/BrandColorsSection.tsx +201 -0
- package/templates/src/components/form/brand/SEOSection.tsx +101 -0
- package/templates/src/components/form/brand/SiteConfigSection.tsx +61 -0
- package/templates/src/components/form/brand/SocialLinksSection.tsx +393 -0
- package/templates/src/components/profile/ProfileConsent.tsx +65 -0
- package/templates/src/components/profile/ProfileCreate.tsx +462 -0
- package/templates/src/components/profile/ProfileEdit.tsx +409 -0
- package/templates/src/components/profile/ProfileSwitch.tsx +255 -0
- package/templates/src/components/profile/ProfileUnlock.tsx +221 -0
- package/templates/src/components/storykeep/Dashboard.tsx +160 -0
- package/templates/src/components/storykeep/Dashboard_Activity.tsx +56 -0
- package/templates/src/components/storykeep/Dashboard_Advanced.tsx +165 -0
- package/templates/src/components/storykeep/Dashboard_Analytics.tsx +451 -0
- package/templates/src/components/storykeep/Dashboard_Branding.tsx +95 -0
- package/templates/src/components/storykeep/Dashboard_Content.tsx +191 -0
- package/templates/src/components/storykeep/controls/UsageCell.tsx +71 -0
- package/templates/src/components/storykeep/controls/content/BeliefForm.tsx +378 -0
- package/templates/src/components/storykeep/controls/content/BeliefTable.tsx +329 -0
- package/templates/src/components/storykeep/controls/content/ContentBrowser.tsx +385 -0
- package/templates/src/components/storykeep/controls/content/ContentSummary.tsx +149 -0
- package/templates/src/components/storykeep/controls/content/KnownResourceForm.tsx +397 -0
- package/templates/src/components/storykeep/controls/content/KnownResourceTable.tsx +260 -0
- package/templates/src/components/storykeep/controls/content/ManageContent.tsx +439 -0
- package/templates/src/components/storykeep/controls/content/MenuForm.tsx +239 -0
- package/templates/src/components/storykeep/controls/content/MenuTable.tsx +332 -0
- package/templates/src/components/storykeep/controls/content/ResourceBulkIngest.tsx +724 -0
- package/templates/src/components/storykeep/controls/content/ResourceForm.tsx +355 -0
- package/templates/src/components/storykeep/controls/content/ResourceTable.tsx +222 -0
- package/templates/src/components/storykeep/controls/content/StoryFragmentTable.tsx +482 -0
- package/templates/src/components/storykeep/state/BrandingWrapper.tsx +42 -0
- package/templates/src/components/storykeep/state/FetchAnalytics.tsx +350 -0
- package/templates/src/components/storykeep/widgets/ResponsiveLine.tsx +319 -0
- package/templates/src/components/storykeep/widgets/Wizard.tsx +278 -0
- package/templates/src/components/tenant/RegistrationForm.tsx +447 -0
- package/templates/src/components/widgets/BunnyVideoHero.astro +775 -0
- package/templates/src/components/widgets/Impression.tsx +102 -0
- package/templates/src/components/widgets/ImpressionWrapper.tsx +214 -0
- package/templates/src/constants/beliefs.ts +61 -0
- package/templates/src/constants/brandThemes.ts +133 -0
- package/templates/src/constants/prompts.json +55 -0
- package/templates/src/constants/shapes.ts +556 -0
- package/templates/src/constants/stopWords.ts +116 -0
- package/templates/src/constants/tailwindColors.json +344 -0
- package/templates/src/constants.ts +274 -0
- package/templates/src/hooks/useFormState.ts +203 -0
- package/templates/src/layouts/Layout.astro +290 -0
- package/templates/src/lib/session.ts +126 -0
- package/templates/src/lib/storyData.ts +56 -0
- package/templates/src/middleware.ts +52 -0
- package/templates/src/pages/404.astro +54 -0
- package/templates/src/pages/[...slug]/edit.astro +216 -0
- package/templates/src/pages/[...slug].astro +148 -0
- package/templates/src/pages/api/auth/decode.ts +101 -0
- package/templates/src/pages/api/auth/login.ts +122 -0
- package/templates/src/pages/api/auth/logout.ts +37 -0
- package/templates/src/pages/api/auth/profile.ts +76 -0
- package/templates/src/pages/api/orphan-analysis.ts +106 -0
- package/templates/src/pages/api/tailwind.ts +116 -0
- package/templates/src/pages/collections/[param1].astro +65 -0
- package/templates/src/pages/context/[...contextSlug]/edit.astro +207 -0
- package/templates/src/pages/context/[...contextSlug].astro +161 -0
- package/templates/src/pages/llms.txt.ts +122 -0
- package/templates/src/pages/maint.astro +183 -0
- package/templates/src/pages/media/[...slug].astro +67 -0
- package/templates/src/pages/robots.txt.ts +36 -0
- package/templates/src/pages/sandbox/activate.astro +258 -0
- package/templates/src/pages/sandbox/register.astro +44 -0
- package/templates/src/pages/sandbox/success.astro +179 -0
- package/templates/src/pages/sitemap.xml.ts +119 -0
- package/templates/src/pages/storykeep/advanced.astro +69 -0
- package/templates/src/pages/storykeep/branding.astro +57 -0
- package/templates/src/pages/storykeep/content.astro +71 -0
- package/templates/src/pages/storykeep/init.astro +36 -0
- package/templates/src/pages/storykeep/login.astro +266 -0
- package/templates/src/pages/storykeep/logout.astro +84 -0
- package/templates/src/pages/storykeep/profile.astro +98 -0
- package/templates/src/pages/storykeep.astro +81 -0
- package/templates/src/stores/analytics.ts +171 -0
- package/templates/src/stores/backend.ts +16 -0
- package/templates/src/stores/navigation.ts +149 -0
- package/templates/src/stores/nodes.ts +2390 -0
- package/templates/src/stores/nodesHistory.ts +85 -0
- package/templates/src/stores/notificationSystem.ts +41 -0
- package/templates/src/stores/orphanAnalysis.ts +409 -0
- package/templates/src/stores/storykeep.ts +247 -0
- package/templates/src/types/astro.ts +86 -0
- package/templates/src/types/compositorTypes.ts +456 -0
- package/templates/src/types/formTypes.ts +281 -0
- package/templates/src/types/multiTenant.ts +77 -0
- package/templates/src/types/nodeProps.ts +66 -0
- package/templates/src/types/tractstack.ts +445 -0
- package/templates/src/utils/aai/getTitleSlug.ts +72 -0
- package/templates/src/utils/actions/actionButton.ts +101 -0
- package/templates/src/utils/actions/lispLexer.ts +57 -0
- package/templates/src/utils/actions/preParse_Action.ts +85 -0
- package/templates/src/utils/actions/preParse_Bunny.ts +50 -0
- package/templates/src/utils/actions/preParse_Clicked.ts +87 -0
- package/templates/src/utils/actions/preParse_Impression.ts +71 -0
- package/templates/src/utils/api/advancedConfig.ts +66 -0
- package/templates/src/utils/api/advancedHelpers.ts +134 -0
- package/templates/src/utils/api/beliefConfig.ts +87 -0
- package/templates/src/utils/api/beliefHelpers.ts +196 -0
- package/templates/src/utils/api/brandConfig.ts +126 -0
- package/templates/src/utils/api/brandHelpers.ts +155 -0
- package/templates/src/utils/api/fileHelpers.ts +306 -0
- package/templates/src/utils/api/menuConfig.ts +57 -0
- package/templates/src/utils/api/menuHelpers.ts +156 -0
- package/templates/src/utils/api/resourceConfig.ts +158 -0
- package/templates/src/utils/api/resourceHelpers.ts +72 -0
- package/templates/src/utils/api/tenantConfig.ts +97 -0
- package/templates/src/utils/api/tenantHelpers.ts +172 -0
- package/templates/src/utils/api.ts +183 -0
- package/templates/src/utils/auth.ts +150 -0
- package/templates/src/utils/backend.ts +243 -0
- package/templates/src/utils/compositor/TemplateMarkdowns.ts +118 -0
- package/templates/src/utils/compositor/TemplateNodes.ts +138 -0
- package/templates/src/utils/compositor/TemplatePanes.ts +100 -0
- package/templates/src/utils/compositor/allowInsert.ts +100 -0
- package/templates/src/utils/compositor/domHelpers.ts +37 -0
- package/templates/src/utils/compositor/handleClickEvent.ts +131 -0
- package/templates/src/utils/compositor/nodesHelper.ts +491 -0
- package/templates/src/utils/compositor/nodesMarkdownGenerator.ts +292 -0
- package/templates/src/utils/compositor/processMarkdown.ts +431 -0
- package/templates/src/utils/compositor/reduceNodesClassNames.ts +192 -0
- package/templates/src/utils/compositor/tailwindClasses.ts +1795 -0
- package/templates/src/utils/compositor/tailwindColors.ts +227 -0
- package/templates/src/utils/compositor/templateMarkdownStyles.ts +1265 -0
- package/templates/src/utils/compositor/typeGuards.ts +193 -0
- package/templates/src/utils/etl/extractor.ts +119 -0
- package/templates/src/utils/etl/index.ts +88 -0
- package/templates/src/utils/etl/loader.ts +36 -0
- package/templates/src/utils/etl/transformer.ts +286 -0
- package/templates/src/utils/helpers.ts +435 -0
- package/templates/src/utils/layout.ts +209 -0
- package/templates/src/utils/profileStorage.ts +306 -0
- package/templates/src/utils/useInterval.ts +27 -0
- package/templates/tailwind.config.cjs +169 -0
- package/utils/create-resolver.ts +10 -0
- package/utils/inject-files.ts +2140 -0
- package/utils/validate-config.ts +43 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { APIRoute } from '@/types/astro';
|
|
2
|
+
|
|
3
|
+
export const prerender = false;
|
|
4
|
+
|
|
5
|
+
export const GET: APIRoute = async ({ request }) => {
|
|
6
|
+
const goBackend =
|
|
7
|
+
import.meta.env.PUBLIC_GO_BACKEND || 'http://localhost:8080';
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
// Forward authentication cookies to the backend
|
|
11
|
+
const cookieHeader = request.headers.get('cookie') || '';
|
|
12
|
+
|
|
13
|
+
// Create abort controller for request timeout
|
|
14
|
+
const controller = new AbortController();
|
|
15
|
+
const timeoutId = setTimeout(() => controller.abort(), 30000); // 30s timeout for analysis
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const goResponse = await fetch(
|
|
19
|
+
`${goBackend}/api/v1/admin/orphan-analysis`,
|
|
20
|
+
{
|
|
21
|
+
method: 'GET',
|
|
22
|
+
headers: {
|
|
23
|
+
'Content-Type': 'application/json',
|
|
24
|
+
Cookie: cookieHeader,
|
|
25
|
+
'X-Tenant-ID': request.headers.get('X-Tenant-ID') || 'default',
|
|
26
|
+
Origin: request.headers.get('Origin') || 'http://localhost:4321',
|
|
27
|
+
},
|
|
28
|
+
signal: controller.signal,
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
clearTimeout(timeoutId);
|
|
33
|
+
|
|
34
|
+
if (!goResponse.ok) {
|
|
35
|
+
console.error(
|
|
36
|
+
'Orphan Analysis API: Go backend error:',
|
|
37
|
+
goResponse.status
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// Handle authentication errors
|
|
41
|
+
if (goResponse.status === 401 || goResponse.status === 403) {
|
|
42
|
+
return new Response(
|
|
43
|
+
JSON.stringify({
|
|
44
|
+
error: 'Authentication required',
|
|
45
|
+
status: 'error',
|
|
46
|
+
}),
|
|
47
|
+
{
|
|
48
|
+
status: goResponse.status,
|
|
49
|
+
headers: { 'Content-Type': 'application/json' },
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return new Response(
|
|
55
|
+
JSON.stringify({
|
|
56
|
+
error: 'Backend error',
|
|
57
|
+
status: 'error',
|
|
58
|
+
}),
|
|
59
|
+
{
|
|
60
|
+
status: goResponse.status,
|
|
61
|
+
headers: { 'Content-Type': 'application/json' },
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const responseData = await goResponse.json();
|
|
67
|
+
|
|
68
|
+
return new Response(JSON.stringify(responseData), {
|
|
69
|
+
status: 200,
|
|
70
|
+
headers: {
|
|
71
|
+
'Content-Type': 'application/json',
|
|
72
|
+
'Cache-Control': 'public, max-age=300', // Cache for 5 minutes
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
} catch (fetchError) {
|
|
76
|
+
clearTimeout(timeoutId);
|
|
77
|
+
|
|
78
|
+
if (fetchError instanceof Error && fetchError.name === 'AbortError') {
|
|
79
|
+
console.error('Orphan analysis request timeout');
|
|
80
|
+
return new Response(
|
|
81
|
+
JSON.stringify({
|
|
82
|
+
error: 'Analysis timeout - this may indicate a large dataset',
|
|
83
|
+
status: 'error',
|
|
84
|
+
}),
|
|
85
|
+
{
|
|
86
|
+
status: 408,
|
|
87
|
+
headers: { 'Content-Type': 'application/json' },
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
throw fetchError;
|
|
92
|
+
}
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error('Orphan Analysis API Proxy: Error:', error);
|
|
95
|
+
return new Response(
|
|
96
|
+
JSON.stringify({
|
|
97
|
+
error: 'Proxy error',
|
|
98
|
+
status: 'error',
|
|
99
|
+
}),
|
|
100
|
+
{
|
|
101
|
+
status: 500,
|
|
102
|
+
headers: { 'Content-Type': 'application/json' },
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { APIRoute } from '@/types/astro';
|
|
2
|
+
import { createTailwindcss } from '@mhsdesign/jit-browser-tailwindcss';
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
export const POST: APIRoute = async ({ request }) => {
|
|
7
|
+
try {
|
|
8
|
+
const { dirtyPaneIds, dirtyClasses } = await request.json();
|
|
9
|
+
|
|
10
|
+
const tenantId =
|
|
11
|
+
request.headers.get('X-Tenant-ID') ||
|
|
12
|
+
import.meta.env.PUBLIC_TENANTID ||
|
|
13
|
+
'default';
|
|
14
|
+
const isMultiTenant =
|
|
15
|
+
import.meta.env.PUBLIC_ENABLE_MULTI_TENANT === 'true' &&
|
|
16
|
+
tenantId !== 'default';
|
|
17
|
+
|
|
18
|
+
if (isMultiTenant) {
|
|
19
|
+
return new Response('CSS generation disabled in multi-tenant mode', {
|
|
20
|
+
status: 403,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Read tailwind config from project root
|
|
25
|
+
const configPath = path.join(process.cwd(), 'tailwind.config.cjs');
|
|
26
|
+
const configContent = await fs.readFile(configPath, 'utf-8');
|
|
27
|
+
const tailwindConfig = new Function(
|
|
28
|
+
'module',
|
|
29
|
+
'exports',
|
|
30
|
+
configContent + '; return module.exports;'
|
|
31
|
+
)({ exports: {} }, {});
|
|
32
|
+
|
|
33
|
+
const goBackend =
|
|
34
|
+
import.meta.env.PUBLIC_GO_BACKEND || 'http://localhost:8080';
|
|
35
|
+
|
|
36
|
+
// Authenticate with Go backend
|
|
37
|
+
const authResponse = await fetch(`${goBackend}/api/v1/auth/login`, {
|
|
38
|
+
method: 'POST',
|
|
39
|
+
headers: {
|
|
40
|
+
'Content-Type': 'application/json',
|
|
41
|
+
'X-Tenant-ID': tenantId,
|
|
42
|
+
},
|
|
43
|
+
body: JSON.stringify({
|
|
44
|
+
password: import.meta.env.ADMIN_PASSWORD || 'letmein',
|
|
45
|
+
}),
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (!authResponse.ok) {
|
|
49
|
+
throw new Error('Failed to authenticate with Go backend');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const { token } = await authResponse.json();
|
|
53
|
+
|
|
54
|
+
// Get classes from Go backend (includes whitelist + clean panes)
|
|
55
|
+
const classesResponse = await fetch(
|
|
56
|
+
`${goBackend}/api/v1/tailwind/classes`,
|
|
57
|
+
{
|
|
58
|
+
method: 'POST',
|
|
59
|
+
headers: {
|
|
60
|
+
'Content-Type': 'application/json',
|
|
61
|
+
Authorization: `Bearer ${token}`,
|
|
62
|
+
'X-Tenant-ID': tenantId,
|
|
63
|
+
},
|
|
64
|
+
body: JSON.stringify({ excludePaneIds: dirtyPaneIds || [] }),
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
if (!classesResponse.ok) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`Failed to get classes from Go backend: ${classesResponse.status}`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const { classes: cleanClasses } = await classesResponse.json();
|
|
75
|
+
|
|
76
|
+
// Combine clean classes from backend with dirty classes from frontend
|
|
77
|
+
const allClasses = [
|
|
78
|
+
...new Set([...(cleanClasses || []), ...(dirtyClasses || [])]),
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
// Generate CSS using JIT
|
|
82
|
+
const tailwindCss = createTailwindcss({ tailwindConfig });
|
|
83
|
+
const htmlContent = [`<span class="${allClasses.join(' ')}"></span>`];
|
|
84
|
+
const generatedCss = await tailwindCss.generateStylesFromContent(
|
|
85
|
+
`@tailwind base; @tailwind utilities;`,
|
|
86
|
+
htmlContent
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
// Return result (SaveModal will handle the update call logging)
|
|
90
|
+
return new Response(
|
|
91
|
+
JSON.stringify({
|
|
92
|
+
success: true,
|
|
93
|
+
classes: allClasses.length,
|
|
94
|
+
frontend: generatedCss.length,
|
|
95
|
+
stylesVer: Date.now(), // Simple version for demo
|
|
96
|
+
generatedCss, // Include actual CSS for potential update call
|
|
97
|
+
}),
|
|
98
|
+
{
|
|
99
|
+
status: 200,
|
|
100
|
+
headers: { 'Content-Type': 'application/json' },
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error('Tailwind Error:', error);
|
|
105
|
+
return new Response(
|
|
106
|
+
JSON.stringify({
|
|
107
|
+
success: false,
|
|
108
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
109
|
+
}),
|
|
110
|
+
{
|
|
111
|
+
status: 500,
|
|
112
|
+
headers: { 'Content-Type': 'application/json' },
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
import CustomRoutes, { routes } from '@/custom/CustomRoutes.astro';
|
|
3
|
+
import { preHealthCheck } from '@/utils/backend';
|
|
4
|
+
import type { ResourceNode } from '@/types/compositorTypes';
|
|
5
|
+
|
|
6
|
+
const tenantId =
|
|
7
|
+
Astro.locals.tenant?.id || import.meta.env.PUBLIC_TENANTID || 'default';
|
|
8
|
+
|
|
9
|
+
const healthCheckRedirect = await preHealthCheck(tenantId);
|
|
10
|
+
if (healthCheckRedirect !== undefined) {
|
|
11
|
+
return healthCheckRedirect;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { param1 } = Astro.params;
|
|
15
|
+
const route = `collections`;
|
|
16
|
+
|
|
17
|
+
// Check if route is enabled
|
|
18
|
+
if (!param1 || !routes[route]) {
|
|
19
|
+
return new Response(null, {
|
|
20
|
+
status: 404,
|
|
21
|
+
statusText: 'Not Found',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const CATEGORIES = [`collections`];
|
|
26
|
+
|
|
27
|
+
let resources = [];
|
|
28
|
+
const goBackend = import.meta.env.PUBLIC_GO_BACKEND || 'http://localhost:8080';
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const resourcesResponse = await fetch(`${goBackend}/api/v1/nodes/resources`, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: { 'Content-Type': 'application/json' },
|
|
34
|
+
body: JSON.stringify({ categories: CATEGORIES }),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (resourcesResponse.ok) {
|
|
38
|
+
const { resources: fetchedResources } = await resourcesResponse.json();
|
|
39
|
+
resources = fetchedResources || [];
|
|
40
|
+
}
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('Error fetching resources:', error);
|
|
43
|
+
return new Response(null, {
|
|
44
|
+
status: 500,
|
|
45
|
+
statusText: 'Internal Server Error',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Check if the specific resource exists
|
|
50
|
+
const targetSlug = `${route}-${param1}`;
|
|
51
|
+
console.log(`check category vs categorySlug`, resources);
|
|
52
|
+
const resourceExists = resources.some(
|
|
53
|
+
(resource: ResourceNode) =>
|
|
54
|
+
resource.category === route && resource.slug === targetSlug
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
if (!resourceExists) {
|
|
58
|
+
return new Response(null, {
|
|
59
|
+
status: 404,
|
|
60
|
+
statusText: 'Not Found',
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
<CustomRoutes route={route} slug={param1} resources={resources} />
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { ulid } from 'ulid';
|
|
3
|
+
import Layout from '@/layouts/Layout.astro';
|
|
4
|
+
import Header from '@/components/Header.astro';
|
|
5
|
+
import { getFullContentMap } from '@/stores/analytics';
|
|
6
|
+
import { getBrandConfig } from '@/utils/api/brandConfig';
|
|
7
|
+
import { joinUrlPaths } from '@/utils/helpers';
|
|
8
|
+
import { handleFailedResponse } from '@/utils/backend';
|
|
9
|
+
import { components as codeHookComponents } from '@/custom/CodeHook.astro';
|
|
10
|
+
import StoryKeepHeader from '@/components/edit/Header';
|
|
11
|
+
import StoryKeepToolBar from '@/components/edit/ToolBar';
|
|
12
|
+
import StoryKeepToolMode from '@/components/edit/ToolMode';
|
|
13
|
+
import SettingsPanel from '@/components/edit/SettingsPanel';
|
|
14
|
+
import { Compositor } from '@/components/compositor/Compositor';
|
|
15
|
+
import { requireAdminOrEditor } from '@/utils/auth';
|
|
16
|
+
import { preHealthCheck } from '@/utils/backend';
|
|
17
|
+
|
|
18
|
+
const tenantId =
|
|
19
|
+
Astro.locals.tenant?.id || import.meta.env.PUBLIC_TENANTID || 'default';
|
|
20
|
+
|
|
21
|
+
const healthCheckRedirect = await preHealthCheck(tenantId);
|
|
22
|
+
if (healthCheckRedirect !== undefined) {
|
|
23
|
+
return healthCheckRedirect;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { contextSlug } = Astro.params;
|
|
27
|
+
if (!contextSlug) return Astro.redirect('/404');
|
|
28
|
+
|
|
29
|
+
// Authentication check - redirect to login if not authenticated
|
|
30
|
+
const authCheck = requireAdminOrEditor(Astro);
|
|
31
|
+
if (authCheck) {
|
|
32
|
+
return authCheck;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const goBackend = import.meta.env.PUBLIC_GO_BACKEND || 'http://localhost:8080';
|
|
36
|
+
|
|
37
|
+
const brandConfig = await getBrandConfig(tenantId);
|
|
38
|
+
if (!brandConfig.SITE_INIT) {
|
|
39
|
+
return Astro.redirect('/storykeep');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let loadData;
|
|
43
|
+
let contextPane;
|
|
44
|
+
let title;
|
|
45
|
+
let contextPaneID;
|
|
46
|
+
|
|
47
|
+
// Handle create mode
|
|
48
|
+
if (contextSlug === 'create') {
|
|
49
|
+
// Create empty context pane in memory
|
|
50
|
+
const emptyContextPane = {
|
|
51
|
+
id: ulid(),
|
|
52
|
+
nodeType: 'Pane' as const,
|
|
53
|
+
parentId: null,
|
|
54
|
+
title: '',
|
|
55
|
+
slug: '',
|
|
56
|
+
isContextPane: true,
|
|
57
|
+
created: new Date(),
|
|
58
|
+
changed: new Date(),
|
|
59
|
+
isDecorative: false,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
loadData = {
|
|
63
|
+
paneNodes: [emptyContextPane],
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
contextPane = emptyContextPane;
|
|
67
|
+
title = 'Create New Context Page - TractStack Editor';
|
|
68
|
+
contextPaneID = emptyContextPane.id;
|
|
69
|
+
} else {
|
|
70
|
+
// Existing backend fetch logic - use full-payload endpoint
|
|
71
|
+
const endpoint = `${goBackend}/api/v1/nodes/panes/slug/${contextSlug}/full-payload`;
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const response = await fetch(endpoint, {
|
|
75
|
+
headers: {
|
|
76
|
+
'X-Tenant-ID': tenantId,
|
|
77
|
+
Cookie: Astro.request.headers.get('cookie') || '',
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const failedResponse = await handleFailedResponse(
|
|
82
|
+
response,
|
|
83
|
+
goBackend,
|
|
84
|
+
tenantId,
|
|
85
|
+
Astro.url.pathname
|
|
86
|
+
);
|
|
87
|
+
if (failedResponse) {
|
|
88
|
+
return failedResponse;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
loadData = await response.json();
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error('Error fetching context pane full payload:', error);
|
|
94
|
+
return Astro.redirect(
|
|
95
|
+
`/maint?from=${encodeURIComponent(Astro.url.pathname)}`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Extract data from the response (same pattern as storyfragment)
|
|
100
|
+
contextPane = loadData?.paneNodes?.at(0);
|
|
101
|
+
title = contextPane?.title || `Context Editor`;
|
|
102
|
+
contextPaneID = contextPane?.id;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const canonicalURL = `/context/${contextSlug}`;
|
|
106
|
+
|
|
107
|
+
// Extract dates if available
|
|
108
|
+
const pubDatetime = contextPane?.created
|
|
109
|
+
? new Date(contextPane.created)
|
|
110
|
+
: undefined;
|
|
111
|
+
const modDatetime = contextPane?.changed ? new Date(contextPane.changed) : null;
|
|
112
|
+
|
|
113
|
+
// Social image from the context pane
|
|
114
|
+
const ogImage = contextPane?.socialImagePath
|
|
115
|
+
? joinUrlPaths(brandConfig?.SITE_URL || ``, contextPane.socialImagePath)
|
|
116
|
+
: undefined;
|
|
117
|
+
|
|
118
|
+
const fullContentMap = await getFullContentMap(tenantId);
|
|
119
|
+
const urlParams: Record<string, string | boolean> = {};
|
|
120
|
+
for (const [key, value] of Astro.url.searchParams) {
|
|
121
|
+
urlParams[key] = value === '' ? true : value;
|
|
122
|
+
}
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
<Layout
|
|
126
|
+
title={title}
|
|
127
|
+
slug={contextSlug}
|
|
128
|
+
canonicalURL={canonicalURL}
|
|
129
|
+
pubDatetime={pubDatetime}
|
|
130
|
+
modDatetime={modDatetime}
|
|
131
|
+
ogImage={ogImage}
|
|
132
|
+
brandConfig={brandConfig}
|
|
133
|
+
storyfragmentId={contextPaneID}
|
|
134
|
+
isEditor={true}
|
|
135
|
+
>
|
|
136
|
+
<!-- Standard Header (scrollable) -->
|
|
137
|
+
<Header
|
|
138
|
+
title={title}
|
|
139
|
+
slug={contextSlug}
|
|
140
|
+
brandConfig={brandConfig}
|
|
141
|
+
isContext={true}
|
|
142
|
+
isStoryKeep={true}
|
|
143
|
+
isEditable={false}
|
|
144
|
+
menu={null}
|
|
145
|
+
/>
|
|
146
|
+
|
|
147
|
+
<!-- StoryKeep Editor Header (scroll-aware positioning) -->
|
|
148
|
+
<section
|
|
149
|
+
id="storykeepHeader"
|
|
150
|
+
role="banner"
|
|
151
|
+
class="z-101 bg-mywhite left-0 right-0 drop-shadow transition-all duration-200"
|
|
152
|
+
>
|
|
153
|
+
<StoryKeepHeader slug={contextSlug} isContext={true} client:only="react" />
|
|
154
|
+
</section>
|
|
155
|
+
|
|
156
|
+
<div class="flex min-h-screen">
|
|
157
|
+
<!-- Tool Navigation (mobile bottom, desktop side) -->
|
|
158
|
+
<StoryKeepToolMode isContext={true} client:only="react" />
|
|
159
|
+
|
|
160
|
+
<!-- Main Content Area -->
|
|
161
|
+
<main id="mainContent" class="relative flex-1">
|
|
162
|
+
<div class="bg-myblue/20 bg-mylightgrey h-full p-1.5">
|
|
163
|
+
<div
|
|
164
|
+
class="h-fit min-h-screen"
|
|
165
|
+
style={{
|
|
166
|
+
backgroundImage:
|
|
167
|
+
'repeating-linear-gradient(135deg, transparent, transparent 10px, rgba(0,0,0,0.05) 10px, rgba(0,0,0,0.05) 20px)',
|
|
168
|
+
}}
|
|
169
|
+
>
|
|
170
|
+
<Compositor
|
|
171
|
+
id={contextPaneID}
|
|
172
|
+
nodes={loadData}
|
|
173
|
+
config={brandConfig}
|
|
174
|
+
fullContentMap={fullContentMap}
|
|
175
|
+
fullCanonicalURL={canonicalURL}
|
|
176
|
+
urlParams={urlParams}
|
|
177
|
+
availableCodeHooks={Object.keys(codeHookComponents)}
|
|
178
|
+
client:only="react"
|
|
179
|
+
/>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
</main>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<!-- Floating Controls (Settings Panel & HUD OR ToolBar) -->
|
|
186
|
+
<aside
|
|
187
|
+
id="settingsControls"
|
|
188
|
+
class="z-101 pointer-events-none fixed bottom-24 right-0 flex max-h-screen flex-col items-end gap-2 overflow-y-auto p-4 md:bottom-0"
|
|
189
|
+
>
|
|
190
|
+
<div class="pointer-events-auto">
|
|
191
|
+
<StoryKeepToolBar client:only="react" />
|
|
192
|
+
</div>
|
|
193
|
+
<div class="pointer-events-auto">
|
|
194
|
+
<SettingsPanel
|
|
195
|
+
config={brandConfig}
|
|
196
|
+
availableCodeHooks={['featured-content', 'list-content', 'bunny-video']}
|
|
197
|
+
client:only="react"
|
|
198
|
+
/>
|
|
199
|
+
</div>
|
|
200
|
+
</aside>
|
|
201
|
+
</Layout>
|
|
202
|
+
|
|
203
|
+
<script>
|
|
204
|
+
import { setupLayoutObservers, setupLayoutStyles } from '@/utils/layout';
|
|
205
|
+
setupLayoutStyles();
|
|
206
|
+
setupLayoutObservers();
|
|
207
|
+
</script>
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Layout from '@/layouts/Layout.astro';
|
|
3
|
+
import CodeHook from '@/custom/CodeHook.astro';
|
|
4
|
+
import { getBrandConfig } from '@/utils/api/brandConfig';
|
|
5
|
+
import { handleFailedResponse } from '@/utils/backend';
|
|
6
|
+
import { getFullContentMap } from '@/stores/analytics';
|
|
7
|
+
import { preHealthCheck } from '@/utils/backend';
|
|
8
|
+
|
|
9
|
+
const tenantId =
|
|
10
|
+
Astro.locals.tenant?.id || import.meta.env.PUBLIC_TENANTID || 'default';
|
|
11
|
+
|
|
12
|
+
const healthCheckRedirect = await preHealthCheck(tenantId);
|
|
13
|
+
if (healthCheckRedirect !== undefined) {
|
|
14
|
+
return healthCheckRedirect;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const { contextSlug } = Astro.params || {};
|
|
18
|
+
|
|
19
|
+
const goBackend = import.meta.env.PUBLIC_GO_BACKEND || 'http://localhost:8080';
|
|
20
|
+
|
|
21
|
+
// Get context pane data by slug
|
|
22
|
+
let contextPaneData;
|
|
23
|
+
try {
|
|
24
|
+
const response = await fetch(
|
|
25
|
+
`${goBackend}/api/v1/nodes/panes/slug/${contextSlug}`,
|
|
26
|
+
{
|
|
27
|
+
headers: {
|
|
28
|
+
'X-Tenant-ID': tenantId,
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const failedResponse = await handleFailedResponse(
|
|
34
|
+
response,
|
|
35
|
+
goBackend,
|
|
36
|
+
tenantId,
|
|
37
|
+
Astro.url.pathname
|
|
38
|
+
);
|
|
39
|
+
if (failedResponse) {
|
|
40
|
+
return failedResponse;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
contextPaneData = await response.json();
|
|
44
|
+
|
|
45
|
+
// Verify this is actually a context pane
|
|
46
|
+
if (!contextPaneData.isContextPane) {
|
|
47
|
+
return new Response(null, {
|
|
48
|
+
status: 404,
|
|
49
|
+
statusText: 'Not Found - Not a context pane',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('Error fetching context pane:', error);
|
|
54
|
+
return Astro.redirect(
|
|
55
|
+
`/maint?from=${encodeURIComponent(Astro.url.pathname)}`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const paneId = contextPaneData.id;
|
|
60
|
+
const paneTitle = contextPaneData.title || 'Context';
|
|
61
|
+
const codeHookTarget = contextPaneData.codeHookTarget || null;
|
|
62
|
+
|
|
63
|
+
// Get rendered fragment for the context pane
|
|
64
|
+
let fragmentData = '';
|
|
65
|
+
try {
|
|
66
|
+
const fragmentResponse = await fetch(
|
|
67
|
+
`${goBackend}/api/v1/fragments/panes/${paneId}/static`,
|
|
68
|
+
{
|
|
69
|
+
headers: {
|
|
70
|
+
'X-Tenant-ID': tenantId,
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
if (fragmentResponse.ok) {
|
|
76
|
+
fragmentData = await fragmentResponse.text();
|
|
77
|
+
} else {
|
|
78
|
+
const failedFragmentResponse = await handleFailedResponse(
|
|
79
|
+
fragmentResponse,
|
|
80
|
+
goBackend,
|
|
81
|
+
tenantId,
|
|
82
|
+
Astro.url.pathname
|
|
83
|
+
);
|
|
84
|
+
if (failedFragmentResponse) {
|
|
85
|
+
return failedFragmentResponse;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error('Error fetching context fragment:', error);
|
|
90
|
+
return Astro.redirect(
|
|
91
|
+
`/maint?from=${encodeURIComponent(Astro.url.pathname)}`
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Get supporting data
|
|
96
|
+
const fullContentMap = await getFullContentMap(tenantId);
|
|
97
|
+
const brandConfig = await getBrandConfig(tenantId);
|
|
98
|
+
|
|
99
|
+
if (!brandConfig.SITE_INIT) {
|
|
100
|
+
return Astro.redirect('/storykeep');
|
|
101
|
+
}
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
<Layout
|
|
105
|
+
title={paneTitle}
|
|
106
|
+
slug={contextSlug}
|
|
107
|
+
menu={null}
|
|
108
|
+
created={contextPaneData.created}
|
|
109
|
+
isContext={true}
|
|
110
|
+
isStoryKeep={false}
|
|
111
|
+
isEditable={true}
|
|
112
|
+
brandConfig={brandConfig}
|
|
113
|
+
storyfragmentId={paneId}
|
|
114
|
+
>
|
|
115
|
+
<main id="main-content" class="min-h-screen w-full">
|
|
116
|
+
<div
|
|
117
|
+
id={`pane-${paneId}`}
|
|
118
|
+
data-pane-id={paneId}
|
|
119
|
+
class="context-pane-container"
|
|
120
|
+
hx-get={`/api/v1/fragments/panes/${paneId}`}
|
|
121
|
+
hx-trigger="refresh"
|
|
122
|
+
hx-swap="innerHTML"
|
|
123
|
+
>
|
|
124
|
+
{
|
|
125
|
+
codeHookTarget ? (
|
|
126
|
+
<CodeHook target={codeHookTarget} fullContentMap={fullContentMap} />
|
|
127
|
+
) : (
|
|
128
|
+
<Fragment set:html={fragmentData} />
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<div class="py-12 text-center text-2xl md:text-3xl">
|
|
134
|
+
<button
|
|
135
|
+
id="context-close-btn"
|
|
136
|
+
class="rounded-lg bg-black px-3.5 py-2.5 text-white transition-all duration-200 hover:rotate-1 hover:bg-orange-500"
|
|
137
|
+
>
|
|
138
|
+
Close
|
|
139
|
+
</button>
|
|
140
|
+
</div>
|
|
141
|
+
</main>
|
|
142
|
+
</Layout>
|
|
143
|
+
|
|
144
|
+
<script>
|
|
145
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
146
|
+
const closeBtn = document.getElementById('context-close-btn');
|
|
147
|
+
|
|
148
|
+
if (closeBtn) {
|
|
149
|
+
closeBtn.addEventListener('click', function () {
|
|
150
|
+
// Check if we have history to go back to
|
|
151
|
+
if (window.history.length > 1 && document.referrer) {
|
|
152
|
+
// Go back to previous page
|
|
153
|
+
window.history.back();
|
|
154
|
+
} else {
|
|
155
|
+
// Fallback to home page
|
|
156
|
+
window.location.href = '/';
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
</script>
|