astro-tractstack 2.1.3 → 2.2.1
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/README.md +54 -266
- package/bin/create-tractstack.js +9 -6
- package/dist/index.js +109 -71
- package/package.json +4 -2
- package/templates/css/custom.css +5 -0
- package/templates/icons/code.svg +18 -0
- package/templates/icons/li.svg +4 -0
- package/templates/icons/link.svg +22 -0
- package/templates/icons/p.svg +3 -0
- package/templates/src/client/app.js +80 -1
- package/templates/src/components/Footer.astro +1 -1
- package/templates/src/components/codehooks/BunnyVideoSetup.tsx +6 -6
- package/templates/src/components/codehooks/EpinetDurationSelector.tsx +3 -3
- package/templates/src/components/codehooks/FeaturedArticleSetup.tsx +1 -1
- package/templates/src/components/codehooks/ListContentSetup.tsx +2 -2
- package/templates/src/components/codehooks/ProductCardSetup.tsx +1 -1
- package/templates/src/components/codehooks/ProductGridSetup.tsx +2 -2
- package/templates/src/components/codehooks/SandboxRegisterForm.tsx +3 -3
- package/templates/src/components/compositor/Compositor.tsx +25 -9
- package/templates/src/components/compositor/Node.tsx +168 -496
- package/templates/src/components/compositor/PanelVisibilityWrapper.tsx +1 -0
- package/templates/src/components/compositor/elements/SignUp.tsx +1 -1
- package/templates/src/components/compositor/elements/YouTubeWrapper.tsx +2 -0
- package/templates/src/components/compositor/nodes/CreativePane.tsx +262 -0
- package/templates/src/components/compositor/nodes/GhostInsertBlock.tsx +4 -6
- package/templates/src/components/compositor/nodes/GridLayout.tsx +4 -2
- package/templates/src/components/compositor/nodes/Markdown.tsx +18 -3
- package/templates/src/components/compositor/nodes/Pane.tsx +11 -5
- package/templates/src/components/compositor/nodes/RenderChildren.tsx +1 -1
- package/templates/src/components/compositor/nodes/tagElements/NodeAnchorComponent.tsx +5 -5
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag.tsx +90 -42
- package/templates/src/components/compositor/nodes/tagElements/NodeImg.tsx +2 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeText.tsx +27 -1
- package/templates/src/components/compositor/preview/PaneSnapshotGenerator.tsx +10 -8
- package/templates/src/components/compositor/tools/NodeOverlay.tsx +224 -0
- package/templates/src/components/compositor/tools/PaneOverlay.tsx +122 -0
- package/templates/src/components/edit/Header.tsx +68 -9
- package/templates/src/components/edit/PanelSwitch.tsx +42 -4
- package/templates/src/components/edit/SettingsPanel.tsx +2 -3
- package/templates/src/components/edit/ToolMode.tsx +1 -31
- package/templates/src/components/edit/pane/AddPanePanel_break.tsx +2 -2
- package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +1 -1
- package/templates/src/components/edit/pane/AddPanePanel_new.tsx +193 -659
- package/templates/src/components/edit/pane/AddPanePanel_reuse.tsx +15 -82
- package/templates/src/components/edit/pane/AiRestylePaneModal.tsx +95 -45
- package/templates/src/components/edit/pane/ConfigPanePanel.tsx +137 -49
- package/templates/src/components/edit/pane/RestylePaneModal.tsx +1 -1
- package/templates/src/components/edit/pane/steps/AiCreativeDesignStep.tsx +375 -0
- package/templates/src/components/edit/pane/steps/AiDesignStep.tsx +1 -23
- package/templates/src/components/edit/pane/steps/AiLibraryCopyStep.tsx +327 -0
- package/templates/src/components/edit/pane/steps/AiRefineDesignStep.tsx +267 -0
- package/templates/src/components/edit/pane/steps/AiStandardDesignStep.tsx +371 -0
- package/templates/src/components/edit/pane/steps/CopyInputStep.tsx +201 -76
- package/templates/src/components/edit/pane/steps/CreativeInjectStep.tsx +141 -0
- package/templates/src/components/edit/panels/CreativeImagePanel.tsx +435 -0
- package/templates/src/components/edit/panels/CreativeLinkPanel.tsx +110 -0
- package/templates/src/components/edit/panels/StyleCodeHookPanel.tsx +1 -1
- package/templates/src/components/edit/panels/StyleParentPanel.tsx +118 -126
- package/templates/src/components/edit/panels/StyleParentPanel_add.tsx +3 -2
- package/templates/src/components/edit/panels/StyleParentPanel_deleteLayer.tsx +1 -0
- package/templates/src/components/edit/panels/StyleParentPanel_remove.tsx +3 -1
- package/templates/src/components/edit/panels/StyleParentPanel_update.tsx +3 -1
- package/templates/src/components/edit/panels/StyleWidgetPanel.tsx +1 -1
- package/templates/src/components/edit/state/SaveModal.tsx +19 -787
- package/templates/src/components/edit/state/SaveToLibraryModal.tsx +2 -2
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_menu.tsx +1 -1
- package/templates/src/components/edit/widgets/BunnyWidget.tsx +5 -5
- package/templates/src/components/edit/widgets/InteractiveDisclosureWidget.tsx +1 -1
- package/templates/src/components/edit/widgets/SignupWidget.tsx +1 -1
- package/templates/src/components/fields/ActionBuilderTimeSelector.tsx +1 -1
- package/templates/src/components/fields/ArtpackImage.tsx +11 -3
- package/templates/src/components/fields/BackgroundImage.tsx +8 -0
- package/templates/src/components/fields/BackgroundImageWrapper.tsx +15 -9
- package/templates/src/components/fields/ImageUpload.tsx +6 -0
- package/templates/src/components/form/ActionBuilderField.tsx +15 -5
- package/templates/src/components/form/ActionBuilderSlugSelector.tsx +1 -1
- package/templates/src/components/form/ColorPicker.tsx +1 -1
- package/templates/src/components/form/EnumSelect.tsx +1 -1
- package/templates/src/components/form/NumberInput.tsx +1 -1
- package/templates/src/components/form/StringArrayInput.tsx +1 -1
- package/templates/src/components/form/StringInput.tsx +1 -1
- package/templates/src/components/form/UnsavedChangesBar.tsx +1 -1
- package/templates/src/components/form/advanced/APIConfigSection.tsx +2 -2
- package/templates/src/components/form/advanced/AuthConfigSection.tsx +2 -2
- package/templates/src/components/profile/ProfileCreate.tsx +1 -1
- package/templates/src/components/profile/ProfileEdit.tsx +1 -1
- package/templates/src/components/storykeep/Dashboard_Advanced.tsx +2 -2
- package/templates/src/components/storykeep/controls/content/BeliefForm.tsx +1 -1
- package/templates/src/components/storykeep/controls/content/ContentSummary.tsx +2 -2
- package/templates/src/components/storykeep/controls/content/KnownResourceTable.tsx +1 -1
- package/templates/src/components/storykeep/controls/content/ManageContent.tsx +6 -6
- package/templates/src/components/storykeep/controls/content/MenuForm.tsx +1 -1
- package/templates/src/components/storykeep/controls/content/PaneTable.tsx +358 -0
- package/templates/src/components/storykeep/controls/content/ResourceTable.tsx +1 -1
- package/templates/src/constants/prompts.json +18 -10
- package/templates/src/constants.ts +3 -0
- package/templates/src/hooks/usePaneFragments.ts +60 -0
- package/templates/src/lib/session.ts +71 -16
- package/templates/src/pages/[...slug].astro +4 -46
- package/templates/src/pages/api/css.ts +149 -0
- package/templates/src/pages/maint.astro +1 -1
- package/templates/src/pages/storykeep/login.astro +2 -2
- package/templates/src/stores/nodes.ts +162 -49
- package/templates/src/stores/orphanAnalysis.ts +6 -30
- package/templates/src/stores/previews.ts +7 -0
- package/templates/src/stores/storykeep.ts +0 -8
- package/templates/src/types/compositorTypes.ts +53 -10
- package/templates/src/utils/compositor/aiGeneration.ts +93 -0
- package/templates/src/utils/compositor/allowInsert.ts +2 -0
- package/templates/src/utils/compositor/htmlAst.ts +704 -0
- package/templates/src/utils/compositor/nodesHelper.ts +281 -102
- package/templates/src/utils/compositor/savePipeline.ts +893 -0
- package/templates/src/utils/etl/index.ts +3 -0
- package/templates/src/utils/etl/transformer.ts +10 -0
- package/templates/src/utils/helpers.ts +101 -0
- package/utils/inject-files.ts +100 -62
- package/templates/icons/text.svg +0 -6
- package/templates/src/components/compositor/NodeWithGuid.tsx +0 -69
- package/templates/src/components/compositor/nodes/GridLayout_eraser.tsx +0 -33
- package/templates/src/components/compositor/nodes/Markdown_eraser.tsx +0 -56
- package/templates/src/components/compositor/nodes/Pane_DesignLibrary.tsx +0 -269
- package/templates/src/components/compositor/nodes/Pane_eraser.tsx +0 -186
- package/templates/src/components/compositor/nodes/Pane_layout.tsx +0 -79
- package/templates/src/components/compositor/nodes/tagElements/NodeA_eraser.tsx +0 -26
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_eraser.tsx +0 -61
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_insert.tsx +0 -120
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_settings.tsx +0 -62
- package/templates/src/components/compositor/nodes/tagElements/NodeButton_eraser.tsx +0 -26
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
1
2
|
import BooleanToggle from '@/components/form/BooleanToggle';
|
|
2
3
|
import EnumSelect from '@/components/form/EnumSelect';
|
|
3
4
|
|
|
@@ -17,7 +18,7 @@ interface CopyInputStepProps {
|
|
|
17
18
|
onTopicChange: (value: string) => void;
|
|
18
19
|
|
|
19
20
|
showAdvancedPrompts: boolean;
|
|
20
|
-
onShowAdvancedPromptsChange
|
|
21
|
+
onShowAdvancedPromptsChange?: (value: boolean) => void;
|
|
21
22
|
|
|
22
23
|
promptValue: string;
|
|
23
24
|
onPromptValueChange: (value: string) => void;
|
|
@@ -42,6 +43,18 @@ interface CopyInputStepProps {
|
|
|
42
43
|
isAiStyling: boolean;
|
|
43
44
|
onIsAiStylingChange: (checked: boolean) => void;
|
|
44
45
|
showStyleToggle?: boolean;
|
|
46
|
+
onDirectInject?: () => void;
|
|
47
|
+
|
|
48
|
+
masterShellSystem?: string;
|
|
49
|
+
setMasterShellSystem?: (val: string) => void;
|
|
50
|
+
masterShellUser?: string;
|
|
51
|
+
setMasterShellUser?: (val: string) => void;
|
|
52
|
+
masterCopySystem?: string;
|
|
53
|
+
setMasterCopySystem?: (val: string) => void;
|
|
54
|
+
masterCopyUser?: string;
|
|
55
|
+
setMasterCopyUser?: (val: string) => void;
|
|
56
|
+
|
|
57
|
+
children?: ReactNode;
|
|
45
58
|
}
|
|
46
59
|
|
|
47
60
|
export const CopyInputStep = ({
|
|
@@ -73,6 +86,16 @@ export const CopyInputStep = ({
|
|
|
73
86
|
isAiStyling,
|
|
74
87
|
onIsAiStylingChange,
|
|
75
88
|
showStyleToggle = true,
|
|
89
|
+
onDirectInject,
|
|
90
|
+
masterShellSystem,
|
|
91
|
+
setMasterShellSystem,
|
|
92
|
+
masterShellUser,
|
|
93
|
+
setMasterShellUser,
|
|
94
|
+
masterCopySystem,
|
|
95
|
+
setMasterCopySystem,
|
|
96
|
+
masterCopyUser,
|
|
97
|
+
setMasterCopyUser,
|
|
98
|
+
children,
|
|
76
99
|
}: CopyInputStepProps) => {
|
|
77
100
|
const renderModeSelection = () => (
|
|
78
101
|
<div className="my-2 flex flex-wrap gap-4">
|
|
@@ -132,99 +155,190 @@ export const CopyInputStep = ({
|
|
|
132
155
|
</div>
|
|
133
156
|
);
|
|
134
157
|
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
158
|
+
const renderAdvancedEditors = () => {
|
|
159
|
+
if (
|
|
160
|
+
masterShellSystem !== undefined &&
|
|
161
|
+
masterShellUser !== undefined &&
|
|
162
|
+
masterCopySystem !== undefined &&
|
|
163
|
+
masterCopyUser !== undefined &&
|
|
164
|
+
setMasterShellSystem &&
|
|
165
|
+
setMasterShellUser &&
|
|
166
|
+
setMasterCopySystem &&
|
|
167
|
+
setMasterCopyUser
|
|
168
|
+
) {
|
|
169
|
+
return (
|
|
170
|
+
<div className="mt-4 space-y-6 rounded-md border border-yellow-200 bg-yellow-50 p-4">
|
|
171
|
+
<div className="flex items-start gap-2">
|
|
172
|
+
<div className="mt-0.5 text-xl">⚡</div>
|
|
173
|
+
<div>
|
|
174
|
+
<p className="font-bold text-gray-900">Master Template Mode</p>
|
|
175
|
+
<p className="text-xs text-gray-600">
|
|
176
|
+
You are editing the raw source prompts. Variables like{' '}
|
|
177
|
+
<code className="bg-gray-100 px-1 font-mono font-bold">{`{{DESIGN_INPUT}}`}</code>{' '}
|
|
178
|
+
will be replaced by your settings unless you remove them.
|
|
179
|
+
</p>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
147
182
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
</div>
|
|
183
|
+
<div>
|
|
184
|
+
<label className="mb-2 block text-sm font-bold text-gray-800">
|
|
185
|
+
Shell System Prompt
|
|
186
|
+
</label>
|
|
187
|
+
<textarea
|
|
188
|
+
value={masterShellSystem}
|
|
189
|
+
onChange={(e) => setMasterShellSystem(e.target.value)}
|
|
190
|
+
rows={4}
|
|
191
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-xs shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
192
|
+
/>
|
|
193
|
+
</div>
|
|
160
194
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
195
|
+
<div>
|
|
196
|
+
<label className="mb-2 block text-sm font-bold text-gray-800">
|
|
197
|
+
Shell User Template
|
|
198
|
+
</label>
|
|
199
|
+
<textarea
|
|
200
|
+
value={masterShellUser}
|
|
201
|
+
onChange={(e) => setMasterShellUser(e.target.value)}
|
|
202
|
+
rows={10}
|
|
203
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-xs shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
204
|
+
/>
|
|
205
|
+
</div>
|
|
169
206
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
207
|
+
<div>
|
|
208
|
+
<label className="mb-2 block text-sm font-bold text-gray-800">
|
|
209
|
+
Copy System Prompt
|
|
210
|
+
</label>
|
|
211
|
+
<textarea
|
|
212
|
+
value={masterCopySystem}
|
|
213
|
+
onChange={(e) => setMasterCopySystem(e.target.value)}
|
|
214
|
+
rows={4}
|
|
215
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-xs shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
216
|
+
/>
|
|
217
|
+
</div>
|
|
218
|
+
|
|
219
|
+
<div>
|
|
220
|
+
<label className="mb-2 block text-sm font-bold text-gray-800">
|
|
221
|
+
Copy User Template
|
|
222
|
+
</label>
|
|
223
|
+
<textarea
|
|
224
|
+
value={masterCopyUser}
|
|
225
|
+
onChange={(e) => setMasterCopyUser(e.target.value)}
|
|
226
|
+
rows={10}
|
|
227
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-xs shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
228
|
+
/>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
<div className="mt-4 space-y-4 rounded-md border border-gray-200 bg-white p-4">
|
|
236
|
+
<p className="mb-3 text-xs text-gray-600">
|
|
237
|
+
Edit the raw prompts sent to the AI. Variables like{' '}
|
|
238
|
+
<code className="bg-gray-100 px-1 font-mono font-bold">
|
|
239
|
+
{`{{TOPIC}}`}
|
|
240
|
+
</code>{' '}
|
|
241
|
+
will still be replaced.
|
|
242
|
+
</p>
|
|
243
|
+
{layoutChoice === 'standard' ? (
|
|
244
|
+
<div>
|
|
245
|
+
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
246
|
+
Full Prompt
|
|
247
|
+
</label>
|
|
248
|
+
<textarea
|
|
249
|
+
value={promptValue}
|
|
250
|
+
onChange={(e) => onPromptValueChange(e.target.value)}
|
|
251
|
+
rows={12}
|
|
252
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-xs shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
253
|
+
/>
|
|
254
|
+
</div>
|
|
255
|
+
) : (
|
|
256
|
+
<>
|
|
173
257
|
<div>
|
|
174
258
|
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
175
|
-
|
|
259
|
+
Overall Component Brief
|
|
176
260
|
</label>
|
|
177
261
|
<textarea
|
|
178
|
-
value={
|
|
179
|
-
onChange={(e) =>
|
|
180
|
-
rows={
|
|
181
|
-
className="
|
|
262
|
+
value={overallPrompt}
|
|
263
|
+
onChange={(e) => onOverallPromptChange(e.target.value)}
|
|
264
|
+
rows={3}
|
|
265
|
+
className="block w-full rounded-md border-gray-300 p-2 shadow-sm focus:border-cyan-500 focus:ring-cyan-500 md:text-sm"
|
|
182
266
|
/>
|
|
183
|
-
<p className="mt-1 text-xs text-gray-500">
|
|
184
|
-
Leave [topic] as it will be replaced with your prompt.
|
|
185
|
-
</p>
|
|
186
267
|
</div>
|
|
187
|
-
|
|
188
|
-
<>
|
|
268
|
+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
189
269
|
<div>
|
|
190
270
|
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
191
|
-
|
|
271
|
+
Left Column Prompt
|
|
192
272
|
</label>
|
|
193
273
|
<textarea
|
|
194
|
-
value={
|
|
195
|
-
onChange={(e) =>
|
|
196
|
-
rows={
|
|
197
|
-
className="
|
|
274
|
+
value={promptValueCol1}
|
|
275
|
+
onChange={(e) => onPromptValueCol1Change(e.target.value)}
|
|
276
|
+
rows={8}
|
|
277
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-xs shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
198
278
|
/>
|
|
199
279
|
</div>
|
|
200
|
-
<div
|
|
201
|
-
<
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
/>
|
|
211
|
-
</div>
|
|
212
|
-
<div>
|
|
213
|
-
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
214
|
-
Right Column Prompt
|
|
215
|
-
</label>
|
|
216
|
-
<textarea
|
|
217
|
-
value={promptValueCol2}
|
|
218
|
-
onChange={(e) => onPromptValueCol2Change(e.target.value)}
|
|
219
|
-
rows={4}
|
|
220
|
-
className="sm:text-sm block w-full rounded-md border-gray-300 p-2 shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
221
|
-
/>
|
|
222
|
-
</div>
|
|
280
|
+
<div>
|
|
281
|
+
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
282
|
+
Right Column Prompt
|
|
283
|
+
</label>
|
|
284
|
+
<textarea
|
|
285
|
+
value={promptValueCol2}
|
|
286
|
+
onChange={(e) => onPromptValueCol2Change(e.target.value)}
|
|
287
|
+
rows={8}
|
|
288
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-xs shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
289
|
+
/>
|
|
223
290
|
</div>
|
|
224
|
-
|
|
225
|
-
|
|
291
|
+
</div>
|
|
292
|
+
</>
|
|
293
|
+
)}
|
|
294
|
+
</div>
|
|
295
|
+
);
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const renderPromptMode = () => (
|
|
299
|
+
<>
|
|
300
|
+
{!showAdvancedPrompts && (
|
|
301
|
+
<>
|
|
302
|
+
<div className="mb-4">
|
|
303
|
+
<EnumSelect
|
|
304
|
+
label="Section Type"
|
|
305
|
+
value={selectedPromptId}
|
|
306
|
+
onChange={onSelectedPromptIdChange}
|
|
307
|
+
options={promptOptions}
|
|
308
|
+
placeholder="Select a type..."
|
|
309
|
+
className="w-full"
|
|
310
|
+
/>
|
|
311
|
+
</div>
|
|
312
|
+
|
|
313
|
+
<div className="mb-4">
|
|
314
|
+
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
315
|
+
Topic / Context
|
|
316
|
+
</label>
|
|
317
|
+
<textarea
|
|
318
|
+
value={topic}
|
|
319
|
+
onChange={(e) => onTopicChange(e.target.value)}
|
|
320
|
+
placeholder="e.g. a SaaS product for team collaboration"
|
|
321
|
+
rows={2}
|
|
322
|
+
className="block w-full rounded-md border-gray-300 p-2 shadow-sm focus:border-cyan-500 focus:ring-cyan-500 md:text-sm"
|
|
323
|
+
/>
|
|
324
|
+
</div>
|
|
325
|
+
|
|
326
|
+
{children}
|
|
327
|
+
</>
|
|
328
|
+
)}
|
|
329
|
+
|
|
330
|
+
{onShowAdvancedPromptsChange && (
|
|
331
|
+
<div className="mt-4 flex items-center border-t border-gray-100 pt-4">
|
|
332
|
+
<BooleanToggle
|
|
333
|
+
label="Advanced: Edit Full Prompts"
|
|
334
|
+
value={showAdvancedPrompts}
|
|
335
|
+
onChange={onShowAdvancedPromptsChange}
|
|
336
|
+
size="sm"
|
|
337
|
+
/>
|
|
226
338
|
</div>
|
|
227
339
|
)}
|
|
340
|
+
|
|
341
|
+
{showAdvancedPrompts && renderAdvancedEditors()}
|
|
228
342
|
</>
|
|
229
343
|
);
|
|
230
344
|
|
|
@@ -315,6 +429,17 @@ export const CopyInputStep = ({
|
|
|
315
429
|
</p>
|
|
316
430
|
</div>
|
|
317
431
|
)}
|
|
432
|
+
|
|
433
|
+
{onDirectInject && (
|
|
434
|
+
<div className="mt-4 text-center">
|
|
435
|
+
<button
|
|
436
|
+
onClick={onDirectInject}
|
|
437
|
+
className="text-xs text-gray-400 underline hover:text-gray-600"
|
|
438
|
+
>
|
|
439
|
+
Direct Inject HTML+CSS
|
|
440
|
+
</button>
|
|
441
|
+
</div>
|
|
442
|
+
)}
|
|
318
443
|
</>
|
|
319
444
|
);
|
|
320
445
|
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { getCtx } from '@/stores/nodes';
|
|
3
|
+
import { htmlToHtmlAst } from '@/utils/compositor/htmlAst';
|
|
4
|
+
import type { TemplatePane } from '@/types/compositorTypes';
|
|
5
|
+
|
|
6
|
+
interface CreativeInjectStepProps {
|
|
7
|
+
onBack: () => void;
|
|
8
|
+
onCreatePane: (template: TemplatePane) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const CreativeInjectStep = ({
|
|
12
|
+
onBack,
|
|
13
|
+
onCreatePane,
|
|
14
|
+
}: CreativeInjectStepProps) => {
|
|
15
|
+
const [html, setHtml] = useState('');
|
|
16
|
+
const [css, setCss] = useState('');
|
|
17
|
+
const [isCompiling, setIsCompiling] = useState(false);
|
|
18
|
+
const [error, setError] = useState<string | null>(null);
|
|
19
|
+
|
|
20
|
+
const handleCreate = async () => {
|
|
21
|
+
setError(null);
|
|
22
|
+
if (!html.trim()) {
|
|
23
|
+
setError('HTML content is required.');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setIsCompiling(true);
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const htmlAst = await htmlToHtmlAst(html, css);
|
|
31
|
+
|
|
32
|
+
const template: TemplatePane = {
|
|
33
|
+
id: '',
|
|
34
|
+
nodeType: 'Pane',
|
|
35
|
+
parentId: '',
|
|
36
|
+
title: 'Creative Pane',
|
|
37
|
+
slug: '',
|
|
38
|
+
isDecorative: false,
|
|
39
|
+
htmlAst,
|
|
40
|
+
markdown: {
|
|
41
|
+
id: '',
|
|
42
|
+
nodeType: 'Markdown',
|
|
43
|
+
parentId: '',
|
|
44
|
+
type: 'markdown',
|
|
45
|
+
markdownId: '',
|
|
46
|
+
defaultClasses: {},
|
|
47
|
+
parentClasses: [],
|
|
48
|
+
nodes: [],
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
onCreatePane(template);
|
|
53
|
+
const ctx = getCtx();
|
|
54
|
+
ctx.showSaveBypass.set(true);
|
|
55
|
+
} catch (err: any) {
|
|
56
|
+
console.error('Compiler Error:', err);
|
|
57
|
+
setError(`Compilation failed: ${err.message}`);
|
|
58
|
+
} finally {
|
|
59
|
+
setIsCompiling(false);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div className="space-y-6 p-4">
|
|
65
|
+
<div className="rounded-md bg-blue-50 p-4">
|
|
66
|
+
<p className="text-sm text-blue-800">
|
|
67
|
+
<strong>Creative Mode:</strong> Input raw HTML and CSS. Tailwind
|
|
68
|
+
classes will be compiled and bucketed into an optimized structure.
|
|
69
|
+
</p>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<div className="grid gap-6 md:grid-cols-2">
|
|
73
|
+
<div className="space-y-2">
|
|
74
|
+
<label
|
|
75
|
+
htmlFor="htmlInput"
|
|
76
|
+
className="block text-sm font-bold text-gray-700"
|
|
77
|
+
>
|
|
78
|
+
HTML Structure
|
|
79
|
+
</label>
|
|
80
|
+
<textarea
|
|
81
|
+
id="htmlInput"
|
|
82
|
+
rows={15}
|
|
83
|
+
value={html}
|
|
84
|
+
onChange={(e) => setHtml(e.target.value)}
|
|
85
|
+
disabled={isCompiling}
|
|
86
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-xs shadow-sm focus:border-cyan-500 focus:ring-cyan-500 disabled:bg-gray-100"
|
|
87
|
+
placeholder={`<div class="p-8 bg-blue-500 hover:bg-blue-600">\n <h1 class="text-white text-4xl">Hello</h1>\n</div>`}
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<div className="space-y-2">
|
|
92
|
+
<label
|
|
93
|
+
htmlFor="cssInput"
|
|
94
|
+
className="block text-sm font-bold text-gray-700"
|
|
95
|
+
>
|
|
96
|
+
Custom CSS Styles
|
|
97
|
+
</label>
|
|
98
|
+
<textarea
|
|
99
|
+
id="cssInput"
|
|
100
|
+
rows={15}
|
|
101
|
+
value={css}
|
|
102
|
+
onChange={(e) => setCss(e.target.value)}
|
|
103
|
+
disabled={isCompiling}
|
|
104
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-xs shadow-sm focus:border-cyan-500 focus:ring-cyan-500 disabled:bg-gray-100"
|
|
105
|
+
placeholder={`.my-class {\n border: 1px solid red;\n}`}
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
{error && (
|
|
111
|
+
<div className="rounded-md bg-red-50 p-4">
|
|
112
|
+
<p className="text-sm font-bold text-red-800">{error}</p>
|
|
113
|
+
</div>
|
|
114
|
+
)}
|
|
115
|
+
|
|
116
|
+
<div className="flex justify-between border-t pt-4">
|
|
117
|
+
<button
|
|
118
|
+
onClick={onBack}
|
|
119
|
+
disabled={isCompiling}
|
|
120
|
+
className="rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-bold text-gray-700 shadow-sm hover:bg-gray-50 disabled:opacity-50"
|
|
121
|
+
>
|
|
122
|
+
← Back
|
|
123
|
+
</button>
|
|
124
|
+
<button
|
|
125
|
+
onClick={handleCreate}
|
|
126
|
+
disabled={isCompiling}
|
|
127
|
+
className="flex items-center gap-2 rounded-md bg-cyan-600 px-6 py-2 text-sm font-bold text-white shadow-sm hover:bg-cyan-700 disabled:opacity-50"
|
|
128
|
+
>
|
|
129
|
+
{isCompiling ? (
|
|
130
|
+
<>
|
|
131
|
+
<span className="h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent"></span>
|
|
132
|
+
Compiling...
|
|
133
|
+
</>
|
|
134
|
+
) : (
|
|
135
|
+
'Compile & Create'
|
|
136
|
+
)}
|
|
137
|
+
</button>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
);
|
|
141
|
+
};
|