astro-tractstack 2.1.3 → 2.2.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/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
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { PaneAddMode, type StoryFragmentNode } from '@/types/compositorTypes';
|
|
12
12
|
import type { FullContentMapItem } from '@/types/tractstack';
|
|
13
13
|
import { TractStackAPI } from '@/utils/api';
|
|
14
|
+
import { usePaneFragments } from '@/hooks/usePaneFragments';
|
|
14
15
|
|
|
15
16
|
interface AddPaneReUsePanelProps {
|
|
16
17
|
nodeId: string;
|
|
@@ -21,8 +22,6 @@ interface AddPaneReUsePanelProps {
|
|
|
21
22
|
interface PreviewItem {
|
|
22
23
|
ctx: NodesContext;
|
|
23
24
|
snapshot?: SnapshotData;
|
|
24
|
-
htmlFragment?: string;
|
|
25
|
-
fragmentError?: string;
|
|
26
25
|
pane: FullContentMapItem;
|
|
27
26
|
index: number;
|
|
28
27
|
}
|
|
@@ -43,9 +42,7 @@ const AddPaneReUsePanel = ({
|
|
|
43
42
|
const [availablePanes, setAvailablePanes] = useState<FullContentMapItem[]>(
|
|
44
43
|
[]
|
|
45
44
|
);
|
|
46
|
-
const [fragmentsLoaded, setFragmentsLoaded] = useState(false);
|
|
47
45
|
const [currentPage, setCurrentPage] = useState(0);
|
|
48
|
-
const [renderedPages, setRenderedPages] = useState<Set<number>>(new Set([0]));
|
|
49
46
|
|
|
50
47
|
useEffect(() => {
|
|
51
48
|
const ctx = getCtx();
|
|
@@ -67,7 +64,6 @@ const AddPaneReUsePanel = ({
|
|
|
67
64
|
setAvailablePanes(unusedPanes);
|
|
68
65
|
}, [nodeId]);
|
|
69
66
|
|
|
70
|
-
// Create collection for Ark UI Combobox
|
|
71
67
|
const collection = useMemo(() => {
|
|
72
68
|
const filteredPanes =
|
|
73
69
|
query === ''
|
|
@@ -85,7 +81,6 @@ const AddPaneReUsePanel = ({
|
|
|
85
81
|
});
|
|
86
82
|
}, [availablePanes, query]);
|
|
87
83
|
|
|
88
|
-
// Create previews from filtered panes
|
|
89
84
|
useEffect(() => {
|
|
90
85
|
const filteredPanes =
|
|
91
86
|
query === ''
|
|
@@ -100,14 +95,10 @@ const AddPaneReUsePanel = ({
|
|
|
100
95
|
ctx: new NodesContext(),
|
|
101
96
|
pane,
|
|
102
97
|
index,
|
|
103
|
-
htmlFragment: undefined,
|
|
104
|
-
fragmentError: undefined,
|
|
105
98
|
}));
|
|
106
99
|
|
|
107
100
|
setPreviews(newPreviews);
|
|
108
101
|
setCurrentPage(0);
|
|
109
|
-
setRenderedPages(new Set([0]));
|
|
110
|
-
setFragmentsLoaded(false);
|
|
111
102
|
}, [availablePanes, query]);
|
|
112
103
|
|
|
113
104
|
const totalPages = Math.ceil(previews.length / ITEMS_PER_PAGE);
|
|
@@ -115,8 +106,6 @@ const AddPaneReUsePanel = ({
|
|
|
115
106
|
const handlePageChange = (newPage: number) => {
|
|
116
107
|
if (newPage >= 0 && newPage < totalPages) {
|
|
117
108
|
setCurrentPage(newPage);
|
|
118
|
-
setRenderedPages((prev) => new Set([...prev, newPage]));
|
|
119
|
-
setFragmentsLoaded(false);
|
|
120
109
|
}
|
|
121
110
|
};
|
|
122
111
|
|
|
@@ -125,66 +114,15 @@ const AddPaneReUsePanel = ({
|
|
|
125
114
|
return previews.slice(startIndex, startIndex + ITEMS_PER_PAGE);
|
|
126
115
|
}, [previews, currentPage]);
|
|
127
116
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const response = await api.post('/api/v1/fragments/panes', { paneIds });
|
|
138
|
-
|
|
139
|
-
if (!response.success) {
|
|
140
|
-
throw new Error(response.error || `Fragment API failed`);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const data = response.data;
|
|
144
|
-
|
|
145
|
-
setPreviews((prevPreviews) => {
|
|
146
|
-
const updated = [...prevPreviews];
|
|
147
|
-
visiblePreviews.forEach((visiblePreview) => {
|
|
148
|
-
const globalIndex = prevPreviews.findIndex(
|
|
149
|
-
(p) => p.pane.id === visiblePreview.pane.id
|
|
150
|
-
);
|
|
151
|
-
if (globalIndex !== -1) {
|
|
152
|
-
updated[globalIndex] = {
|
|
153
|
-
...updated[globalIndex],
|
|
154
|
-
htmlFragment: data.fragments?.[visiblePreview.pane.id] || '',
|
|
155
|
-
fragmentError:
|
|
156
|
-
data.errors?.[visiblePreview.pane.id] || undefined,
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
return updated;
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
setFragmentsLoaded(true);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
console.error('Failed to fetch fragments:', error);
|
|
166
|
-
setPreviews((prevPreviews) => {
|
|
167
|
-
const updated = [...prevPreviews];
|
|
168
|
-
visiblePreviews.forEach((visiblePreview) => {
|
|
169
|
-
const globalIndex = prevPreviews.findIndex(
|
|
170
|
-
(p) => p.pane.id === visiblePreview.pane.id
|
|
171
|
-
);
|
|
172
|
-
if (globalIndex !== -1) {
|
|
173
|
-
updated[globalIndex] = {
|
|
174
|
-
...updated[globalIndex],
|
|
175
|
-
fragmentError:
|
|
176
|
-
error instanceof Error ? error.message : 'Unknown error',
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
return updated;
|
|
181
|
-
});
|
|
182
|
-
setFragmentsLoaded(true);
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
fetchFragments();
|
|
187
|
-
}, [visiblePreviews, fragmentsLoaded]);
|
|
117
|
+
const visiblePaneIds = useMemo(
|
|
118
|
+
() => visiblePreviews.map((p) => p.pane.id),
|
|
119
|
+
[visiblePreviews]
|
|
120
|
+
);
|
|
121
|
+
const {
|
|
122
|
+
fragments,
|
|
123
|
+
errors,
|
|
124
|
+
isLoading: fragmentsLoading,
|
|
125
|
+
} = usePaneFragments(visiblePaneIds);
|
|
188
126
|
|
|
189
127
|
const handleSnapshotComplete = (id: string, snapshot: SnapshotData) => {
|
|
190
128
|
const paneId = id.replace('reuse-', '');
|
|
@@ -215,7 +153,6 @@ const AddPaneReUsePanel = ({
|
|
|
215
153
|
const templateData = response.data;
|
|
216
154
|
const ctx = getCtx();
|
|
217
155
|
|
|
218
|
-
// Find storyfragment
|
|
219
156
|
const storyfragmentId = ctx.getClosestNodeTypeFromId(
|
|
220
157
|
nodeId,
|
|
221
158
|
'StoryFragment'
|
|
@@ -231,7 +168,6 @@ const AddPaneReUsePanel = ({
|
|
|
231
168
|
throw new Error('No storyfragment found');
|
|
232
169
|
}
|
|
233
170
|
|
|
234
|
-
// Set pane parentId
|
|
235
171
|
templateData.paneNode.parentId = storyfragmentId;
|
|
236
172
|
|
|
237
173
|
let specificIdx = -1;
|
|
@@ -260,7 +196,6 @@ const AddPaneReUsePanel = ({
|
|
|
260
196
|
}
|
|
261
197
|
storyFragmentNode.isChanged = true;
|
|
262
198
|
|
|
263
|
-
// Add nodes using exact same pattern as addTemplatePane
|
|
264
199
|
ctx.addNode(templateData.paneNode);
|
|
265
200
|
ctx.linkChildToParent(
|
|
266
201
|
templateData.paneNode.id,
|
|
@@ -276,7 +211,6 @@ const AddPaneReUsePanel = ({
|
|
|
276
211
|
}
|
|
277
212
|
};
|
|
278
213
|
|
|
279
|
-
// CSS to properly style the combobox items with hover and selection
|
|
280
214
|
const comboboxItemStyles = `
|
|
281
215
|
.pane-item[data-highlighted] {
|
|
282
216
|
background-color: #0891b2; /* bg-cyan-600 */
|
|
@@ -354,25 +288,24 @@ const AddPaneReUsePanel = ({
|
|
|
354
288
|
...(!preview.snapshot ? { minHeight: '75px' } : {}),
|
|
355
289
|
}}
|
|
356
290
|
>
|
|
357
|
-
{
|
|
291
|
+
{fragmentsLoading && !fragments[preview.pane.id] && (
|
|
358
292
|
<div className="flex h-24 items-center justify-center">
|
|
359
293
|
<div className="text-gray-500">Loading...</div>
|
|
360
294
|
</div>
|
|
361
295
|
)}
|
|
362
296
|
|
|
363
|
-
{
|
|
297
|
+
{errors[preview.pane.id] && (
|
|
364
298
|
<div className="flex h-24 items-center justify-center">
|
|
365
299
|
<div className="text-red-500">Preview error</div>
|
|
366
300
|
</div>
|
|
367
301
|
)}
|
|
368
302
|
|
|
369
|
-
{
|
|
370
|
-
preview.htmlFragment &&
|
|
303
|
+
{fragments[preview.pane.id] &&
|
|
371
304
|
!preview.snapshot &&
|
|
372
|
-
!preview.
|
|
305
|
+
!errors[preview.pane.id] && (
|
|
373
306
|
<PaneSnapshotGenerator
|
|
374
307
|
id={`reuse-${preview.pane.id}`}
|
|
375
|
-
htmlString={preview.
|
|
308
|
+
htmlString={fragments[preview.pane.id]}
|
|
376
309
|
onComplete={handleSnapshotComplete}
|
|
377
310
|
onError={(id, error) =>
|
|
378
311
|
console.error(`Snapshot error for ${id}:`, error)
|
|
@@ -6,11 +6,14 @@ import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon';
|
|
|
6
6
|
import SparklesIcon from '@heroicons/react/24/outline/SparklesIcon';
|
|
7
7
|
import { getCtx } from '@/stores/nodes';
|
|
8
8
|
import { selectionStore } from '@/stores/selection';
|
|
9
|
+
import { renderedPreviews } from '@/stores/previews';
|
|
9
10
|
import { sandboxTokenStore } from '@/stores/storykeep';
|
|
10
11
|
import { AiDesignStep, type AiDesignConfig } from './steps/AiDesignStep';
|
|
12
|
+
import { AiRefineDesignStep } from './steps/AiRefineDesignStep';
|
|
11
13
|
import prompts from '@/constants/prompts.json';
|
|
12
14
|
import { TractStackAPI } from '@/utils/api';
|
|
13
15
|
import { parseAiPane } from '@/utils/compositor/aiPaneParser';
|
|
16
|
+
import type { PaneNode, TemplatePane } from '@/types/compositorTypes';
|
|
14
17
|
|
|
15
18
|
const callAskLemurAPI = async (
|
|
16
19
|
prompt: string,
|
|
@@ -29,7 +32,7 @@ const callAskLemurAPI = async (
|
|
|
29
32
|
input_text: context,
|
|
30
33
|
final_model: '',
|
|
31
34
|
temperature: 0.5,
|
|
32
|
-
max_tokens:
|
|
35
|
+
max_tokens: 6000,
|
|
33
36
|
};
|
|
34
37
|
|
|
35
38
|
let resultData: any;
|
|
@@ -82,22 +85,34 @@ export const AiRestylePaneModal = ({
|
|
|
82
85
|
}: AiRestylePaneModalProps) => {
|
|
83
86
|
const ctx = getCtx();
|
|
84
87
|
const { isAiRestyleModalOpen, paneToRestyleId } = useStore(selectionStore);
|
|
88
|
+
const previews = useStore(renderedPreviews);
|
|
85
89
|
|
|
86
90
|
const [loading, setLoading] = useState(false);
|
|
87
91
|
const [error, setError] = useState<string | null>(null);
|
|
92
|
+
const [additionalNotes, setAdditionalNotes] = useState('');
|
|
88
93
|
const [aiDesignConfig, setAiDesignConfig] = useState<AiDesignConfig>({
|
|
89
94
|
harmony: 'Analogous',
|
|
90
95
|
baseColor: '',
|
|
91
96
|
accentColor: '',
|
|
92
97
|
theme: 'Light',
|
|
93
|
-
additionalNotes: '',
|
|
94
98
|
});
|
|
95
99
|
|
|
100
|
+
const node = paneToRestyleId
|
|
101
|
+
? (ctx.allNodes.get().get(paneToRestyleId) as PaneNode)
|
|
102
|
+
: null;
|
|
103
|
+
const isCreative = !!node?.htmlAst;
|
|
104
|
+
|
|
96
105
|
const handleClose = () => {
|
|
97
106
|
if (loading) return;
|
|
98
107
|
selectionStore.setKey('isAiRestyleModalOpen', false);
|
|
99
108
|
selectionStore.setKey('paneToRestyleId', null);
|
|
100
109
|
setError(null);
|
|
110
|
+
setAdditionalNotes('');
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const handleCreativeUpdate = (template: TemplatePane) => {
|
|
114
|
+
if (!paneToRestyleId) return;
|
|
115
|
+
ctx.applyShellToPane(paneToRestyleId, template);
|
|
101
116
|
};
|
|
102
117
|
|
|
103
118
|
const handleGenerate = async () => {
|
|
@@ -124,8 +139,7 @@ export const AiRestylePaneModal = ({
|
|
|
124
139
|
designInput += ` Base around **${aiDesignConfig.baseColor}**.`;
|
|
125
140
|
if (aiDesignConfig.accentColor)
|
|
126
141
|
designInput += ` Accent with **${aiDesignConfig.accentColor}**.`;
|
|
127
|
-
if (
|
|
128
|
-
designInput += ` Notes: "${aiDesignConfig.additionalNotes}"`;
|
|
142
|
+
if (additionalNotes) designInput += ` Notes: "${additionalNotes}"`;
|
|
129
143
|
|
|
130
144
|
const shellPromptKey = promptConfig.prompts.shell as keyof typeof prompts;
|
|
131
145
|
const shellPromptDetails = prompts[shellPromptKey] as any;
|
|
@@ -168,11 +182,11 @@ export const AiRestylePaneModal = ({
|
|
|
168
182
|
>
|
|
169
183
|
<Dialog.Backdrop className="fixed inset-0 z-103 bg-black bg-opacity-75" />
|
|
170
184
|
<Dialog.Positioner className="fixed inset-0 z-104 flex items-center justify-center p-4">
|
|
171
|
-
<Dialog.Content className="flex max-w-
|
|
185
|
+
<Dialog.Content className="flex w-full max-w-7xl flex-col rounded-lg bg-white shadow-2xl">
|
|
172
186
|
<div className="flex items-center justify-between border-b p-4">
|
|
173
187
|
<h3 className="flex items-center gap-2 text-lg font-bold">
|
|
174
188
|
<SparklesIcon className="h-5 w-5 text-purple-600" />
|
|
175
|
-
Re-Color Pane
|
|
189
|
+
{isCreative ? 'Refine Creative Pane' : 'Re-Color Pane'}
|
|
176
190
|
</h3>
|
|
177
191
|
<button
|
|
178
192
|
onClick={handleClose}
|
|
@@ -183,49 +197,85 @@ export const AiRestylePaneModal = ({
|
|
|
183
197
|
</button>
|
|
184
198
|
</div>
|
|
185
199
|
|
|
186
|
-
|
|
187
|
-
<div className=
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
|
|
200
|
+
{isCreative ? (
|
|
201
|
+
<div className="overflow-y-auto" style={{ maxHeight: `80vh` }}>
|
|
202
|
+
<AiRefineDesignStep
|
|
203
|
+
onBack={handleClose}
|
|
204
|
+
onSuccess={handleClose}
|
|
205
|
+
onUpdatePane={handleCreativeUpdate}
|
|
206
|
+
isSandboxMode={isSandboxMode}
|
|
207
|
+
initialHtml={
|
|
208
|
+
paneToRestyleId ? previews[paneToRestyleId] || '' : ''
|
|
209
|
+
}
|
|
210
|
+
initialCss={node?.htmlAst?.css || ''}
|
|
191
211
|
/>
|
|
192
212
|
</div>
|
|
213
|
+
) : (
|
|
214
|
+
<form className="p-6" onSubmit={(e) => e.preventDefault()}>
|
|
215
|
+
<div className={loading ? 'pointer-events-none opacity-50' : ''}>
|
|
216
|
+
<AiDesignStep
|
|
217
|
+
designConfig={aiDesignConfig}
|
|
218
|
+
onDesignConfigChange={setAiDesignConfig}
|
|
219
|
+
/>
|
|
193
220
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
221
|
+
<div className="mt-6">
|
|
222
|
+
<label
|
|
223
|
+
htmlFor="restyle-notes"
|
|
224
|
+
className="block text-base font-bold text-gray-800"
|
|
225
|
+
>
|
|
226
|
+
Additional Design Notes (Optional)
|
|
227
|
+
</label>
|
|
228
|
+
<p className="mb-2 mt-1 text-sm text-gray-500">
|
|
229
|
+
Add specific requests like "use rounded corners", "add
|
|
230
|
+
subtle texture".
|
|
231
|
+
</p>
|
|
232
|
+
<textarea
|
|
233
|
+
id="restyle-notes"
|
|
234
|
+
value={additionalNotes}
|
|
235
|
+
onChange={(e) => setAdditionalNotes(e.target.value)}
|
|
236
|
+
placeholder="Enter additional notes..."
|
|
237
|
+
rows={3}
|
|
238
|
+
className="block w-full rounded-md border-gray-300 p-2 text-sm shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
239
|
+
/>
|
|
240
|
+
</div>
|
|
197
241
|
</div>
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
242
|
+
|
|
243
|
+
{error && (
|
|
244
|
+
<div className="mt-4 rounded border border-red-200 bg-red-50 p-3 text-sm text-red-700">
|
|
245
|
+
{error}
|
|
246
|
+
</div>
|
|
247
|
+
)}
|
|
248
|
+
|
|
249
|
+
<div className="mt-8 flex justify-end gap-3">
|
|
250
|
+
<button
|
|
251
|
+
type="button"
|
|
252
|
+
onClick={handleClose}
|
|
253
|
+
disabled={loading}
|
|
254
|
+
className="rounded-lg px-4 py-2 font-bold text-gray-600 hover:bg-gray-100 disabled:opacity-50"
|
|
255
|
+
>
|
|
256
|
+
Cancel
|
|
257
|
+
</button>
|
|
258
|
+
<button
|
|
259
|
+
type="button"
|
|
260
|
+
onClick={handleGenerate}
|
|
261
|
+
disabled={loading}
|
|
262
|
+
className="flex items-center gap-2 rounded-lg bg-gradient-to-r from-purple-600 to-indigo-600 px-6 py-2 font-bold text-white shadow transition-all hover:from-purple-500 hover:to-indigo-500 hover:shadow-lg disabled:cursor-not-allowed disabled:opacity-75"
|
|
263
|
+
>
|
|
264
|
+
{loading ? (
|
|
265
|
+
<>
|
|
266
|
+
<div className="h-5 w-5 animate-spin rounded-full border-2 border-white/30 border-t-white" />
|
|
267
|
+
Generating...
|
|
268
|
+
</>
|
|
269
|
+
) : (
|
|
270
|
+
<>
|
|
271
|
+
<SparklesIcon className="h-5 w-5" />
|
|
272
|
+
Apply Re-Color
|
|
273
|
+
</>
|
|
274
|
+
)}
|
|
275
|
+
</button>
|
|
276
|
+
</div>
|
|
277
|
+
</form>
|
|
278
|
+
)}
|
|
229
279
|
</Dialog.Content>
|
|
230
280
|
</Dialog.Positioner>
|
|
231
281
|
</Dialog.Root>
|