astro-tractstack 2.0.0-rc.9 → 2.0.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 +8 -97
- package/README.md +7 -5
- package/bin/create-tractstack.js +31 -8
- package/dist/index.js +106 -29
- package/package.json +10 -5
- package/templates/css/frontend.css +1 -1
- package/templates/custom/minimal/CodeHook.astro +13 -12
- package/templates/custom/minimal/CustomRoutes.astro +25 -31
- package/templates/custom/with-examples/CodeHook.astro +22 -11
- package/templates/custom/with-examples/CustomRoutes.astro +4 -8
- package/templates/custom/with-examples/ProductCard.astro +29 -0
- package/templates/custom/with-examples/ProductCardWrapper.astro +43 -0
- package/templates/custom/with-examples/ProductGrid.astro +64 -0
- package/templates/custom/with-examples/pages/Collections.astro +58 -98
- package/templates/gitignore +42 -0
- package/templates/prettierignore +5 -0
- package/templates/prettierrc +19 -0
- package/templates/src/client/app.js +127 -0
- package/templates/src/client/htmx.min.js +3519 -0
- package/templates/src/client/view.js +429 -0
- package/templates/src/components/Footer.astro +4 -9
- package/templates/src/components/Header.astro +67 -60
- package/templates/src/components/Menu.tsx +188 -52
- package/templates/src/components/codehooks/BunnyVideoSetup.tsx +2 -2
- package/templates/src/components/codehooks/EpinetDurationSelector.tsx +9 -13
- package/templates/src/components/codehooks/EpinetTableView.tsx +11 -7
- package/templates/src/components/codehooks/EpinetWrapper.tsx +1 -0
- package/templates/src/components/codehooks/FeaturedArticle.astro +105 -0
- package/templates/src/components/codehooks/FeaturedArticleSetup.tsx +318 -0
- package/templates/src/components/codehooks/ListContent.astro +32 -162
- package/templates/src/components/codehooks/ListContentSetup.tsx +43 -138
- package/templates/src/components/codehooks/ProductCardSetup.tsx +152 -0
- package/templates/src/components/codehooks/ProductGridSetup.tsx +274 -0
- package/templates/src/components/codehooks/SearchWidget.tsx +453 -0
- package/templates/src/components/compositor/Node.tsx +3 -6
- package/templates/src/components/compositor/PanelVisibilityWrapper.tsx +21 -11
- package/templates/src/components/compositor/elements/BunnyVideo.tsx +21 -20
- package/templates/src/components/compositor/nodes/Pane.tsx +51 -21
- package/templates/src/components/compositor/nodes/RenderChildren.tsx +6 -1
- package/templates/src/components/compositor/nodes/Widget.tsx +16 -2
- package/templates/src/components/compositor/preview/FeaturedArticlePreview.tsx +155 -0
- package/templates/src/components/compositor/preview/PaneSnapshotGenerator.tsx +20 -1
- package/templates/src/components/edit/Header.tsx +10 -4
- package/templates/src/components/edit/PanelSwitch.tsx +11 -7
- package/templates/src/components/edit/SettingsPanel.tsx +29 -18
- package/templates/src/components/edit/ToolBar.tsx +1 -28
- package/templates/src/components/edit/ToolMode.tsx +45 -32
- package/templates/src/components/edit/pane/AddPanePanel_break.tsx +12 -2
- package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +8 -2
- package/templates/src/components/edit/pane/AddPanePanel_newAICopy_modal.tsx +1 -1
- package/templates/src/components/edit/pane/ConfigPanePanel.tsx +17 -27
- package/templates/src/components/edit/pane/PageGenSelector.tsx +16 -16
- package/templates/src/components/edit/pane/PageGenSpecial.tsx +26 -49
- package/templates/src/components/edit/pane/PageGen_preview.tsx +17 -2
- package/templates/src/components/edit/pane/PanePanel_path.tsx +2 -4
- package/templates/src/components/edit/pane/PanePanel_title.tsx +243 -76
- package/templates/src/components/edit/panels/StyleBreakPanel.tsx +17 -19
- package/templates/src/components/edit/panels/StyleCodeHookPanel.tsx +48 -37
- package/templates/src/components/edit/panels/StyleElementPanel_add.tsx +60 -55
- package/templates/src/components/edit/panels/StyleImagePanel_add.tsx +56 -50
- package/templates/src/components/edit/panels/StyleLiElementPanel_add.tsx +54 -47
- package/templates/src/components/edit/panels/StyleLinkPanel_add.tsx +54 -44
- package/templates/src/components/edit/panels/StyleLinkPanel_config.tsx +113 -138
- package/templates/src/components/edit/panels/StyleParentPanel_add.tsx +54 -40
- package/templates/src/components/edit/panels/StyleWidgetPanel.tsx +3 -3
- package/templates/src/components/edit/panels/StyleWidgetPanel_add.tsx +56 -49
- package/templates/src/components/edit/panels/StyleWidgetPanel_config.tsx +14 -5
- package/templates/src/components/edit/state/SaveModal.tsx +316 -169
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_og.tsx +1 -1
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_slug.tsx +56 -55
- package/templates/src/components/edit/widgets/BunnyWidget.tsx +538 -59
- package/templates/src/components/edit/widgets/InteractiveDisclosureWidget.tsx +656 -0
- package/templates/src/components/edit/widgets/ToggleWidget.tsx +9 -16
- package/templates/src/components/fields/ArtpackImage.tsx +4 -1
- package/templates/src/components/fields/BackgroundImage.tsx +1 -1
- package/templates/src/components/fields/BackgroundImageWrapper.tsx +127 -35
- package/templates/src/components/fields/ColorPickerCombo.tsx +66 -62
- package/templates/src/components/fields/ImageUpload.tsx +1 -1
- package/templates/src/components/fields/ViewportComboBox.tsx +59 -42
- package/templates/src/components/form/ActionBuilderBeliefSelector.tsx +117 -0
- package/templates/src/components/form/ActionBuilderField.tsx +306 -87
- package/templates/src/components/search/SearchModal.tsx +420 -0
- package/templates/src/components/search/SearchResults.tsx +367 -0
- package/templates/src/components/search/SearchWrapper.tsx +46 -0
- package/templates/src/components/storykeep/Dashboard_Advanced.tsx +1 -1
- package/templates/src/components/storykeep/Dashboard_Analytics.tsx +34 -8
- package/templates/src/components/storykeep/Dashboard_Branding.tsx +1 -1
- package/templates/src/components/storykeep/Dashboard_Content.tsx +6 -0
- package/templates/src/components/storykeep/StoryKeepBackdrop.astro +87 -0
- package/templates/src/components/storykeep/controls/content/BeliefForm.tsx +38 -34
- package/templates/src/components/storykeep/controls/content/KnownResourceForm.tsx +1 -1
- package/templates/src/components/storykeep/controls/content/MenuForm.tsx +56 -8
- package/templates/src/components/storykeep/controls/content/ResourceForm.tsx +18 -3
- package/templates/src/components/storykeep/controls/content/StoryFragmentTable.tsx +5 -8
- package/templates/src/components/storykeep/state/FetchAnalytics.tsx +274 -228
- package/templates/src/components/storykeep/widgets/Wizard.tsx +14 -7
- package/templates/src/components/widgets/ImpressionWrapper.tsx +0 -1
- package/templates/src/constants/shapes.ts +9 -0
- package/templates/src/constants.ts +2121 -16
- package/templates/src/hooks/useSearch.ts +228 -0
- package/templates/src/layouts/Layout.astro +213 -104
- package/templates/src/lib/storyData.ts +4 -1
- package/templates/src/pages/[...slug]/edit.astro +14 -14
- package/templates/src/pages/[...slug].astro +82 -21
- package/templates/src/pages/api/orphan-analysis.ts +0 -1
- package/templates/src/pages/api/tailwind.ts +23 -21
- package/templates/src/pages/context/[...contextSlug]/edit.astro +14 -14
- package/templates/src/pages/context/[...contextSlug].astro +7 -2
- package/templates/src/pages/storykeep/advanced.astro +5 -4
- package/templates/src/pages/storykeep/branding.astro +5 -4
- package/templates/src/pages/storykeep/content.astro +5 -4
- package/templates/src/pages/storykeep/init.astro +40 -1
- package/templates/src/pages/storykeep/login.astro +1 -1
- package/templates/src/pages/storykeep.astro +5 -4
- package/templates/src/stores/nodes.ts +59 -88
- package/templates/src/stores/orphanAnalysis.ts +19 -21
- package/templates/src/stores/storykeep.ts +7 -0
- package/templates/src/types/compositorTypes.ts +6 -0
- package/templates/src/types/tractstack.ts +17 -0
- package/templates/src/utils/actions/lispLexer.ts +2 -2
- package/templates/src/utils/actions/preParse_Action.ts +3 -0
- package/templates/src/utils/api/beliefHelpers.ts +12 -36
- package/templates/src/utils/api/menuHelpers.ts +2 -2
- package/templates/src/utils/api.ts +26 -0
- package/templates/src/utils/compositor/TemplateNodes.ts +7 -0
- package/templates/src/utils/compositor/allowInsert.ts +5 -3
- package/templates/src/utils/compositor/nodesHelper.ts +4 -0
- package/templates/src/utils/compositor/processMarkdown.ts +16 -2
- package/templates/src/utils/compositor/reduceNodesClassNames.ts +4 -0
- package/templates/src/utils/compositor/templateMarkdownStyles.ts +13 -13
- package/templates/src/utils/compositor/typeGuards.ts +1 -0
- package/templates/src/utils/customHelpers.ts +38 -0
- package/templates/src/utils/helpers.ts +2 -2
- package/templates/src/utils/layout.ts +65 -144
- package/utils/inject-files.ts +95 -18
- package/templates/src/client/analytics-events.js +0 -207
- package/templates/src/client/belief-events.js +0 -191
- package/templates/src/client/sse.js +0 -613
- package/templates/src/components/codehooks/FeaturedContent.astro +0 -273
- package/templates/src/components/codehooks/FeaturedContentSetup.tsx +0 -738
- package/templates/src/components/compositor/preview/FeaturedContentPreview.tsx +0 -128
- package/templates/src/components/edit/pane/PanePanel_slug.tsx +0 -219
|
@@ -168,16 +168,10 @@ for (const [key, value] of Astro.url.searchParams) {
|
|
|
168
168
|
<StoryKeepToolMode isContext={false} client:only="react" />
|
|
169
169
|
|
|
170
170
|
<!-- Main Content Area -->
|
|
171
|
-
<main
|
|
172
|
-
id="mainContent"
|
|
173
|
-
class="relative flex-1"
|
|
174
|
-
style={{
|
|
175
|
-
paddingBottom: 'var(--bottom-right-controls-bottom-offset, 16px)',
|
|
176
|
-
}}
|
|
177
|
-
>
|
|
171
|
+
<main id="mainContent" class="relative flex-1 overflow-x-auto">
|
|
178
172
|
<div class="bg-myblue/20 bg-mylightgrey h-full p-1.5">
|
|
179
173
|
<div
|
|
180
|
-
class="h-fit min-h-screen"
|
|
174
|
+
class="h-fit min-h-screen pb-96"
|
|
181
175
|
style={{
|
|
182
176
|
backgroundImage:
|
|
183
177
|
'repeating-linear-gradient(135deg, transparent, transparent 10px, rgba(0,0,0,0.05) 10px, rgba(0,0,0,0.05) 20px)',
|
|
@@ -201,15 +195,22 @@ for (const [key, value] of Astro.url.searchParams) {
|
|
|
201
195
|
<!-- Floating Controls (Settings Panel & HUD OR ToolBar) -->
|
|
202
196
|
<aside
|
|
203
197
|
id="settingsControls"
|
|
204
|
-
class="z-101 pointer-events-none fixed bottom-
|
|
198
|
+
class="z-101 pointer-events-none fixed bottom-16 right-2 flex flex-col items-end gap-2 md:bottom-2"
|
|
205
199
|
>
|
|
206
|
-
<div class="pointer-events-
|
|
200
|
+
<div class="pointer-events-none flex-grow"></div>
|
|
201
|
+
|
|
202
|
+
{/* Toolbar's wrapper: Does not grow or shrink */}
|
|
203
|
+
<div class="pointer-events-auto flex-shrink-0">
|
|
207
204
|
<StoryKeepToolBar client:only="react" />
|
|
208
205
|
</div>
|
|
209
|
-
|
|
206
|
+
|
|
207
|
+
{
|
|
208
|
+
/* Settings Panel's wrapper: Grows, shrinks, and will be positioned by our script */
|
|
209
|
+
}
|
|
210
|
+
<div class="pointer-events-auto max-h-full">
|
|
210
211
|
<SettingsPanel
|
|
211
212
|
config={brandConfig}
|
|
212
|
-
availableCodeHooks={
|
|
213
|
+
availableCodeHooks={Object.keys(codeHookComponents)}
|
|
213
214
|
client:only="react"
|
|
214
215
|
/>
|
|
215
216
|
</div>
|
|
@@ -217,7 +218,6 @@ for (const [key, value] of Astro.url.searchParams) {
|
|
|
217
218
|
</Layout>
|
|
218
219
|
|
|
219
220
|
<script>
|
|
220
|
-
import { setupLayoutObservers
|
|
221
|
-
setupLayoutStyles();
|
|
221
|
+
import { setupLayoutObservers } from '@/utils/layout';
|
|
222
222
|
setupLayoutObservers();
|
|
223
223
|
</script>
|
|
@@ -30,7 +30,9 @@ let storyData;
|
|
|
30
30
|
try {
|
|
31
31
|
storyData = await getStoryData(Astro, lookup, sessionId, tenantId);
|
|
32
32
|
} catch (error) {
|
|
33
|
-
if (error instanceof Response) {
|
|
33
|
+
if (error instanceof Response && error.status === 404) {
|
|
34
|
+
return Astro.redirect('/404');
|
|
35
|
+
} else if (error instanceof Response) {
|
|
34
36
|
return error;
|
|
35
37
|
}
|
|
36
38
|
console.error('Error fetching storyfragment:', error);
|
|
@@ -43,6 +45,7 @@ const storyfragmentId = storyData.id;
|
|
|
43
45
|
const storyfragmentTitle = storyData.title || 'Untitled Story';
|
|
44
46
|
const paneIds = storyData.paneIds || [];
|
|
45
47
|
const codeHookTargets = storyData.codeHookTargets || {};
|
|
48
|
+
const resourcesPayload = storyData.resourcesPayload || {};
|
|
46
49
|
|
|
47
50
|
if (paneIds.length === 0) {
|
|
48
51
|
console.log(`Empty Story Fragment. Redirecting to /storykeep`);
|
|
@@ -101,11 +104,22 @@ const brandConfig = await getBrandConfig(tenantId);
|
|
|
101
104
|
if (!brandConfig.SITE_INIT) {
|
|
102
105
|
return Astro.redirect('/storykeep');
|
|
103
106
|
}
|
|
107
|
+
|
|
108
|
+
const ogImage =
|
|
109
|
+
typeof storyData.socialImagePath === `string`
|
|
110
|
+
? storyData.socialImagePath
|
|
111
|
+
: undefined;
|
|
112
|
+
const paneSlugLookup: Record<string, string> = {};
|
|
113
|
+
paneIds.forEach((paneId: string) => {
|
|
114
|
+
const paneData = fullContentMap.find((item) => item.id === paneId);
|
|
115
|
+
paneSlugLookup[paneId] = paneData?.slug || paneId;
|
|
116
|
+
});
|
|
104
117
|
---
|
|
105
118
|
|
|
106
119
|
<Layout
|
|
107
120
|
title={storyfragmentTitle}
|
|
108
121
|
slug={lookup || brandConfig.HOME_SLUG}
|
|
122
|
+
ogImage={ogImage}
|
|
109
123
|
menu={storyData.menu || null}
|
|
110
124
|
created={storyData.created}
|
|
111
125
|
isContext={false}
|
|
@@ -120,26 +134,73 @@ if (!brandConfig.SITE_INIT) {
|
|
|
120
134
|
<div class="panes-container">
|
|
121
135
|
{
|
|
122
136
|
paneIds.map((paneId: string) => (
|
|
123
|
-
<div
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
<div id={paneSlugLookup[paneId]}>
|
|
138
|
+
<div
|
|
139
|
+
id={`pane-${paneId}`}
|
|
140
|
+
data-pane-id={paneId}
|
|
141
|
+
class="pane-fragment-container"
|
|
142
|
+
style={
|
|
143
|
+
!codeHookTargets[paneId]
|
|
144
|
+
? undefined
|
|
145
|
+
: !storyData.codeHookVisibility?.[paneId]
|
|
146
|
+
? 'display:none;'
|
|
147
|
+
: 'display:block;'
|
|
148
|
+
}
|
|
149
|
+
hx-get={`/api/v1/fragments/panes/${paneId}`}
|
|
150
|
+
hx-trigger="refresh"
|
|
151
|
+
hx-swap="innerHTML scroll:none"
|
|
152
|
+
>
|
|
153
|
+
{codeHookTargets[paneId] ? (
|
|
154
|
+
<div class="relative overflow-hidden">
|
|
155
|
+
<CodeHook
|
|
156
|
+
target={codeHookTargets[paneId]}
|
|
157
|
+
options={(() => {
|
|
158
|
+
const optionsStr =
|
|
159
|
+
codeHookTargets[paneId + '-' + codeHookTargets[paneId]];
|
|
160
|
+
return optionsStr
|
|
161
|
+
? { params: { options: optionsStr } }
|
|
162
|
+
: undefined;
|
|
163
|
+
})()}
|
|
164
|
+
fullContentMap={fullContentMap}
|
|
165
|
+
resourcesPayload={resourcesPayload}
|
|
166
|
+
/>
|
|
167
|
+
<div id={`pane-${paneId}-unset`}>
|
|
168
|
+
{Array.isArray(storyData.codeHookVisibility?.[paneId]) && (
|
|
169
|
+
<button
|
|
170
|
+
type="button"
|
|
171
|
+
class="text-mydarkgrey absolute right-2 top-2 z-10 rounded-full bg-white p-1.5 hover:bg-black hover:text-white"
|
|
172
|
+
title="Go Back"
|
|
173
|
+
hx-post="/api/v1/state"
|
|
174
|
+
hx-trigger="click"
|
|
175
|
+
hx-swap="none"
|
|
176
|
+
hx-vals={JSON.stringify({
|
|
177
|
+
unsetBeliefIds:
|
|
178
|
+
storyData.codeHookVisibility[paneId].join(','),
|
|
179
|
+
paneId: paneId,
|
|
180
|
+
})}
|
|
181
|
+
hx-preserve="true"
|
|
182
|
+
>
|
|
183
|
+
<svg
|
|
184
|
+
class="h-6 w-6"
|
|
185
|
+
fill="none"
|
|
186
|
+
viewBox="0 0 24 24"
|
|
187
|
+
stroke-width="1.5"
|
|
188
|
+
stroke="currentColor"
|
|
189
|
+
>
|
|
190
|
+
<path
|
|
191
|
+
stroke-linecap="round"
|
|
192
|
+
stroke-linejoin="round"
|
|
193
|
+
d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3"
|
|
194
|
+
/>
|
|
195
|
+
</svg>
|
|
196
|
+
</button>
|
|
197
|
+
)}
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
) : (
|
|
201
|
+
<Fragment set:html={fragmentsData[paneId] || ''} />
|
|
202
|
+
)}
|
|
203
|
+
</div>
|
|
143
204
|
</div>
|
|
144
205
|
))
|
|
145
206
|
}
|
|
@@ -11,24 +11,6 @@ export const POST: APIRoute = async ({ request }) => {
|
|
|
11
11
|
request.headers.get('X-Tenant-ID') ||
|
|
12
12
|
import.meta.env.PUBLIC_TENANTID ||
|
|
13
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
14
|
|
|
33
15
|
const goBackend =
|
|
34
16
|
import.meta.env.PUBLIC_GO_BACKEND || 'http://localhost:8080';
|
|
@@ -63,9 +45,29 @@ export const POST: APIRoute = async ({ request }) => {
|
|
|
63
45
|
...new Set([...(cleanClasses || []), ...(dirtyClasses || [])]),
|
|
64
46
|
];
|
|
65
47
|
|
|
66
|
-
//
|
|
67
|
-
const
|
|
68
|
-
const
|
|
48
|
+
// Read base tailwind config from project root
|
|
49
|
+
const configPath = path.join(process.cwd(), 'tailwind.config.cjs');
|
|
50
|
+
const configContent = await fs.readFile(configPath, 'utf-8');
|
|
51
|
+
const baseTailwindConfig = new Function(
|
|
52
|
+
'module',
|
|
53
|
+
'exports',
|
|
54
|
+
configContent + '; return module.exports;'
|
|
55
|
+
)({ exports: {} }, {});
|
|
56
|
+
|
|
57
|
+
// Create config with safelist
|
|
58
|
+
const tailwindConfigWithSafelist = {
|
|
59
|
+
...baseTailwindConfig,
|
|
60
|
+
safelist: allClasses,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Generate CSS using JIT with safelist
|
|
64
|
+
const tailwindCss = createTailwindcss({
|
|
65
|
+
tailwindConfig: tailwindConfigWithSafelist,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Use simple HTML content since safelist should handle class generation
|
|
69
|
+
const htmlContent = ['<div>Using the safelist</div>'];
|
|
70
|
+
|
|
69
71
|
const generatedCss = await tailwindCss.generateStylesFromContent(
|
|
70
72
|
`@tailwind base; @tailwind utilities;`,
|
|
71
73
|
htmlContent
|
|
@@ -159,16 +159,10 @@ for (const [key, value] of Astro.url.searchParams) {
|
|
|
159
159
|
<StoryKeepToolMode isContext={true} client:only="react" />
|
|
160
160
|
|
|
161
161
|
<!-- Main Content Area -->
|
|
162
|
-
<main
|
|
163
|
-
id="mainContent"
|
|
164
|
-
class="relative flex-1"
|
|
165
|
-
style={{
|
|
166
|
-
paddingBottom: 'var(--bottom-right-controls-bottom-offset, 16px)',
|
|
167
|
-
}}
|
|
168
|
-
>
|
|
162
|
+
<main id="mainContent" class="relative flex-1 overflow-x-auto">
|
|
169
163
|
<div class="bg-myblue/20 bg-mylightgrey h-full p-1.5">
|
|
170
164
|
<div
|
|
171
|
-
class="h-fit min-h-screen"
|
|
165
|
+
class="h-fit min-h-screen pb-96"
|
|
172
166
|
style={{
|
|
173
167
|
backgroundImage:
|
|
174
168
|
'repeating-linear-gradient(135deg, transparent, transparent 10px, rgba(0,0,0,0.05) 10px, rgba(0,0,0,0.05) 20px)',
|
|
@@ -192,15 +186,22 @@ for (const [key, value] of Astro.url.searchParams) {
|
|
|
192
186
|
<!-- Floating Controls (Settings Panel & HUD OR ToolBar) -->
|
|
193
187
|
<aside
|
|
194
188
|
id="settingsControls"
|
|
195
|
-
class="z-101 pointer-events-none fixed bottom-
|
|
189
|
+
class="z-101 pointer-events-none fixed bottom-16 right-2 flex flex-col items-end gap-2 md:bottom-2"
|
|
196
190
|
>
|
|
197
|
-
<div class="pointer-events-
|
|
191
|
+
<div class="pointer-events-none flex-grow"></div>
|
|
192
|
+
|
|
193
|
+
{/* Toolbar's wrapper: Does not grow or shrink */}
|
|
194
|
+
<div class="pointer-events-auto flex-shrink-0">
|
|
198
195
|
<StoryKeepToolBar client:only="react" />
|
|
199
196
|
</div>
|
|
200
|
-
|
|
197
|
+
|
|
198
|
+
{
|
|
199
|
+
/* Settings Panel's wrapper: Grows, shrinks, and will be positioned by our script */
|
|
200
|
+
}
|
|
201
|
+
<div class="pointer-events-auto max-h-full">
|
|
201
202
|
<SettingsPanel
|
|
202
203
|
config={brandConfig}
|
|
203
|
-
availableCodeHooks={
|
|
204
|
+
availableCodeHooks={Object.keys(codeHookComponents)}
|
|
204
205
|
client:only="react"
|
|
205
206
|
/>
|
|
206
207
|
</div>
|
|
@@ -208,7 +209,6 @@ for (const [key, value] of Astro.url.searchParams) {
|
|
|
208
209
|
</Layout>
|
|
209
210
|
|
|
210
211
|
<script>
|
|
211
|
-
import { setupLayoutObservers
|
|
212
|
-
setupLayoutStyles();
|
|
212
|
+
import { setupLayoutObservers } from '@/utils/layout';
|
|
213
213
|
setupLayoutObservers();
|
|
214
214
|
</script>
|
|
@@ -59,6 +59,7 @@ try {
|
|
|
59
59
|
const paneId = contextPaneData.id;
|
|
60
60
|
const paneTitle = contextPaneData.title || 'Context';
|
|
61
61
|
const codeHookTarget = contextPaneData.codeHookTarget || null;
|
|
62
|
+
const resourcesPayload = storyData.resourcesPayload || {};
|
|
62
63
|
|
|
63
64
|
// Get rendered fragment for the context pane
|
|
64
65
|
let fragmentData = '';
|
|
@@ -119,11 +120,15 @@ if (!brandConfig.SITE_INIT) {
|
|
|
119
120
|
class="context-pane-container"
|
|
120
121
|
hx-get={`/api/v1/fragments/panes/${paneId}`}
|
|
121
122
|
hx-trigger="refresh"
|
|
122
|
-
hx-swap="innerHTML"
|
|
123
|
+
hx-swap="innerHTML scroll:none"
|
|
123
124
|
>
|
|
124
125
|
{
|
|
125
126
|
codeHookTarget ? (
|
|
126
|
-
<CodeHook
|
|
127
|
+
<CodeHook
|
|
128
|
+
target={codeHookTarget}
|
|
129
|
+
resourcesPayload={resourcesPayload}
|
|
130
|
+
fullContentMap={fullContentMap}
|
|
131
|
+
/>
|
|
127
132
|
) : (
|
|
128
133
|
<Fragment set:html={fragmentData} />
|
|
129
134
|
)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Layout from '@/layouts/Layout.astro';
|
|
3
|
+
import StoryKeepBackdrop from '@/components/storykeep/StoryKeepBackdrop.astro';
|
|
3
4
|
import StoryKeepDashboard from '@/components/storykeep/Dashboard';
|
|
4
5
|
import StoryKeepDashboard_Advanced from '@/components/storykeep/Dashboard_Advanced';
|
|
5
6
|
import { requireAdminOrEditor, isAuthenticated, isAdmin } from '@/utils/auth';
|
|
@@ -40,11 +41,10 @@ if (initializing) {
|
|
|
40
41
|
const title = 'Advanced | StoryKeep';
|
|
41
42
|
|
|
42
43
|
let fullContentMap;
|
|
43
|
-
|
|
44
|
+
const homeSlug = brandConfig.HOME_SLUG || 'hello';
|
|
44
45
|
|
|
45
46
|
try {
|
|
46
47
|
fullContentMap = await getFullContentMap(tenantId);
|
|
47
|
-
homeSlug = fullContentMap.find((item) => item.isHome)?.slug || 'hello';
|
|
48
48
|
} catch (error) {
|
|
49
49
|
return Astro.redirect(
|
|
50
50
|
`/maint?from=${encodeURIComponent(Astro.url.pathname)}`
|
|
@@ -53,8 +53,9 @@ try {
|
|
|
53
53
|
---
|
|
54
54
|
|
|
55
55
|
<Layout title={title} slug="storykeep" isStoryKeep={true}>
|
|
56
|
-
<main id="main-content" class="min-h-screen w-full">
|
|
57
|
-
<
|
|
56
|
+
<main id="main-content" class="relative min-h-screen w-full">
|
|
57
|
+
<StoryKeepBackdrop brandConfig={brandConfig} />
|
|
58
|
+
<div class="max-w-5xl p-3.5 md:p-8">
|
|
58
59
|
<StoryKeepDashboard
|
|
59
60
|
client:only="react"
|
|
60
61
|
fullContentMap={fullContentMap}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Layout from '@/layouts/Layout.astro';
|
|
3
|
+
import StoryKeepBackdrop from '@/components/storykeep/StoryKeepBackdrop.astro';
|
|
3
4
|
import BrandingPageWrapper from '@/components/storykeep/state/BrandingWrapper';
|
|
4
5
|
import { requireAdminOrEditor, isAuthenticated, isAdmin } from '@/utils/auth';
|
|
5
6
|
import { getFullContentMap } from '@/stores/analytics';
|
|
@@ -29,11 +30,10 @@ const initializing = !brandConfig.SITE_INIT;
|
|
|
29
30
|
const title = 'Branding | StoryKeep';
|
|
30
31
|
|
|
31
32
|
let fullContentMap;
|
|
32
|
-
|
|
33
|
+
const homeSlug = brandConfig.HOME_SLUG || 'hello';
|
|
33
34
|
|
|
34
35
|
try {
|
|
35
36
|
fullContentMap = await getFullContentMap(tenantId);
|
|
36
|
-
homeSlug = fullContentMap.find((item) => item.isHome)?.slug || 'hello';
|
|
37
37
|
} catch (error) {
|
|
38
38
|
return Astro.redirect(
|
|
39
39
|
`/maint?from=${encodeURIComponent(Astro.url.pathname)}`
|
|
@@ -42,8 +42,9 @@ try {
|
|
|
42
42
|
---
|
|
43
43
|
|
|
44
44
|
<Layout title={title} slug="storykeep" isStoryKeep={true}>
|
|
45
|
-
<main id="main-content" class="min-h-screen w-full">
|
|
46
|
-
<
|
|
45
|
+
<main id="main-content" class="relative min-h-screen w-full">
|
|
46
|
+
<StoryKeepBackdrop brandConfig={brandConfig} />
|
|
47
|
+
<div class="max-w-5xl p-3.5 md:p-8">
|
|
47
48
|
<BrandingPageWrapper
|
|
48
49
|
client:only="react"
|
|
49
50
|
fullContentMap={fullContentMap}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Layout from '@/layouts/Layout.astro';
|
|
3
|
+
import StoryKeepBackdrop from '@/components/storykeep/StoryKeepBackdrop.astro';
|
|
3
4
|
import StoryKeepDashboard from '@/components/storykeep/Dashboard';
|
|
4
5
|
import StoryKeepDashboard_Content from '@/components/storykeep/Dashboard_Content';
|
|
5
6
|
import { requireAdminOrEditor, isAuthenticated, isAdmin } from '@/utils/auth';
|
|
@@ -36,11 +37,10 @@ const title = 'Content | StoryKeep';
|
|
|
36
37
|
const createMenu = Astro.url.searchParams.has('create-menu');
|
|
37
38
|
|
|
38
39
|
let fullContentMap;
|
|
39
|
-
|
|
40
|
+
const homeSlug = brandConfig.HOME_SLUG || 'hello';
|
|
40
41
|
|
|
41
42
|
try {
|
|
42
43
|
fullContentMap = await getFullContentMap(tenantId);
|
|
43
|
-
homeSlug = fullContentMap.find((item) => item.isHome)?.slug || 'hello';
|
|
44
44
|
} catch (error) {
|
|
45
45
|
return Astro.redirect(
|
|
46
46
|
`/maint?from=${encodeURIComponent(Astro.url.pathname)}`
|
|
@@ -49,8 +49,9 @@ try {
|
|
|
49
49
|
---
|
|
50
50
|
|
|
51
51
|
<Layout title={title} slug="storykeep" isStoryKeep={true}>
|
|
52
|
-
<main id="main-content" class="min-h-screen w-full">
|
|
53
|
-
<
|
|
52
|
+
<main id="main-content" class="relative min-h-screen w-full">
|
|
53
|
+
<StoryKeepBackdrop brandConfig={brandConfig} />
|
|
54
|
+
<div class="max-w-5xl p-3.5 md:p-8">
|
|
54
55
|
<StoryKeepDashboard
|
|
55
56
|
client:only="react"
|
|
56
57
|
fullContentMap={fullContentMap}
|
|
@@ -31,6 +31,45 @@ const mainStylesUrl = isDev
|
|
|
31
31
|
<link rel="stylesheet" href={mainStylesUrl} />
|
|
32
32
|
</head>
|
|
33
33
|
<body class="h-full">
|
|
34
|
-
<
|
|
34
|
+
<div class="max-w-5xl p-3.5 md:p-8">
|
|
35
|
+
<RegistrationForm client:load isInitMode={true} />
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<script>
|
|
39
|
+
// Ensure clean slate for fresh installation
|
|
40
|
+
(function initCleanSlate() {
|
|
41
|
+
try {
|
|
42
|
+
// Clear admin/editor auth cookies
|
|
43
|
+
document.cookie =
|
|
44
|
+
'admin_auth=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax';
|
|
45
|
+
document.cookie =
|
|
46
|
+
'editor_auth=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax';
|
|
47
|
+
|
|
48
|
+
// Clear all TractStack localStorage items
|
|
49
|
+
const tractStackKeys = [];
|
|
50
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
51
|
+
const key = localStorage.key(i);
|
|
52
|
+
if (key && key.startsWith('tractstack_')) {
|
|
53
|
+
tractStackKeys.push(key);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
tractStackKeys.forEach((key) => localStorage.removeItem(key));
|
|
57
|
+
|
|
58
|
+
// Clear session-related items
|
|
59
|
+
localStorage.removeItem('tractstack_session_id');
|
|
60
|
+
localStorage.removeItem('tractstack_fingerprint');
|
|
61
|
+
localStorage.removeItem('tractstack_visit');
|
|
62
|
+
localStorage.removeItem('tractstack_entered_tracked');
|
|
63
|
+
|
|
64
|
+
// Clear session cookie
|
|
65
|
+
document.cookie =
|
|
66
|
+
'tractstack_session_id=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax';
|
|
67
|
+
|
|
68
|
+
console.log('TractStack: Clean slate initialization complete');
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.warn('TractStack: Error during clean slate init:', error);
|
|
71
|
+
}
|
|
72
|
+
})();
|
|
73
|
+
</script>
|
|
35
74
|
</body>
|
|
36
75
|
</html>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Layout from '@/layouts/Layout.astro';
|
|
3
|
+
import StoryKeepBackdrop from '@/components/storykeep/StoryKeepBackdrop.astro';
|
|
3
4
|
import StoryKeepDashboard from '@/components/storykeep/Dashboard';
|
|
4
5
|
import StoryKeepDashboard_Analytics from '@/components/storykeep/Dashboard_Analytics';
|
|
5
6
|
import { requireAdminOrEditor, isAuthenticated, isAdmin } from '@/utils/auth';
|
|
@@ -35,14 +36,13 @@ if (initializing) {
|
|
|
35
36
|
|
|
36
37
|
const title = 'Analytics | StoryKeep';
|
|
37
38
|
|
|
39
|
+
const homeSlug = brandConfig.HOME_SLUG || 'hello';
|
|
38
40
|
let fullContentMap;
|
|
39
|
-
let homeSlug = 'hello';
|
|
40
41
|
|
|
41
42
|
try {
|
|
42
43
|
fullContentMap = await getFullContentMap(
|
|
43
44
|
Astro.locals.tenant?.id || import.meta.env.PUBLIC_TENANTID || 'default'
|
|
44
45
|
);
|
|
45
|
-
homeSlug = fullContentMap.find((item) => item.isHome)?.slug || 'hello';
|
|
46
46
|
} catch (error) {
|
|
47
47
|
return Astro.redirect(
|
|
48
48
|
`/maint?from=${encodeURIComponent(Astro.url.pathname)}`
|
|
@@ -51,8 +51,9 @@ try {
|
|
|
51
51
|
---
|
|
52
52
|
|
|
53
53
|
<Layout title={title} isStoryKeep={true} slug="storykeep">
|
|
54
|
-
<main id="main-content" class="min-h-screen w-full">
|
|
55
|
-
<
|
|
54
|
+
<main id="main-content" class="relative min-h-screen w-full">
|
|
55
|
+
<StoryKeepBackdrop brandConfig={brandConfig} />
|
|
56
|
+
<div class="max-w-5xl p-3.5 md:p-8">
|
|
56
57
|
<StoryKeepDashboard
|
|
57
58
|
client:only="react"
|
|
58
59
|
fullContentMap={fullContentMap}
|