astro-tractstack 2.0.42 → 2.0.44
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/package.json +1 -1
- package/templates/src/components/Header.astro +0 -1
- package/templates/src/components/edit/pane/AddPanePanel_new.tsx +156 -343
- package/templates/src/components/edit/pane/RestylePaneModal.tsx +7 -5
- package/templates/src/components/edit/pane/steps/AiDesignStep.tsx +1 -4
- package/templates/src/components/edit/pane/steps/CopyInputStep.tsx +238 -96
- package/templates/src/pages/storykeep/init.astro +23 -21
- package/templates/src/utils/layout.ts +85 -75
|
@@ -211,7 +211,8 @@ export const RestylePaneModal = () => {
|
|
|
211
211
|
(entry: DesignLibraryEntry) =>
|
|
212
212
|
(selectedCategory === 'all' || entry.category === selectedCategory) &&
|
|
213
213
|
entry.title.toLowerCase().includes(searchTerm.toLowerCase()) &&
|
|
214
|
-
entry.markdownCount === targetMarkdownCount
|
|
214
|
+
entry.markdownCount === targetMarkdownCount &&
|
|
215
|
+
!entry.locked
|
|
215
216
|
);
|
|
216
217
|
}, [designLibrary, selectedCategory, searchTerm, targetMarkdownCount]);
|
|
217
218
|
|
|
@@ -350,14 +351,15 @@ export const RestylePaneModal = () => {
|
|
|
350
351
|
<Dialog.Root
|
|
351
352
|
open={isRestyleModalOpen}
|
|
352
353
|
onOpenChange={handleDialogStateChange}
|
|
353
|
-
modal={
|
|
354
|
+
modal={true}
|
|
355
|
+
preventScroll={true}
|
|
354
356
|
>
|
|
355
|
-
<Dialog.Backdrop className="z-103 fixed inset-0 bg-black
|
|
357
|
+
<Dialog.Backdrop className="z-103 fixed inset-0 bg-black bg-opacity-75" />
|
|
356
358
|
<Dialog.Positioner className="z-104 fixed inset-0 flex items-center justify-center">
|
|
357
359
|
<Dialog.Content
|
|
358
360
|
ref={contentRef}
|
|
359
|
-
className="flex flex-col rounded-lg bg-white shadow-2xl"
|
|
360
|
-
style={{ maxHeight: '
|
|
361
|
+
className="flex max-w-5xl flex-col rounded-lg bg-white shadow-2xl xl:max-w-7xl"
|
|
362
|
+
style={{ maxHeight: '90vh', width: '90vw' }}
|
|
361
363
|
>
|
|
362
364
|
<header className="flex items-center justify-between border-b p-4">
|
|
363
365
|
<Dialog.Title className="text-xl font-bold">
|
|
@@ -33,10 +33,7 @@ export const AiDesignStep = ({
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
return (
|
|
36
|
-
<div className="space-y-6
|
|
37
|
-
<label className="block text-lg font-bold text-gray-800">
|
|
38
|
-
2. Configure AI Design
|
|
39
|
-
</label>
|
|
36
|
+
<div className="space-y-6">
|
|
40
37
|
<div>
|
|
41
38
|
<label className="block text-base font-bold text-gray-800">
|
|
42
39
|
Color Harmony
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
1
|
import BooleanToggle from '@/components/form/BooleanToggle';
|
|
3
2
|
import EnumSelect from '@/components/form/EnumSelect';
|
|
4
3
|
|
|
@@ -10,13 +9,32 @@ interface PromptOption {
|
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
interface CopyInputStepProps {
|
|
12
|
+
layoutChoice: 'standard' | 'grid';
|
|
13
13
|
copyMode: CopyMode;
|
|
14
14
|
onCopyModeChange: (mode: CopyMode) => void;
|
|
15
|
+
|
|
16
|
+
topic: string;
|
|
17
|
+
onTopicChange: (value: string) => void;
|
|
18
|
+
|
|
19
|
+
showAdvancedPrompts: boolean;
|
|
20
|
+
onShowAdvancedPromptsChange: (value: boolean) => void;
|
|
21
|
+
|
|
15
22
|
promptValue: string;
|
|
16
23
|
onPromptValueChange: (value: string) => void;
|
|
17
24
|
copyValue: string;
|
|
18
25
|
onCopyValueChange: (value: string) => void;
|
|
19
|
-
|
|
26
|
+
|
|
27
|
+
overallPrompt: string;
|
|
28
|
+
onOverallPromptChange: (value: string) => void;
|
|
29
|
+
promptValueCol1: string;
|
|
30
|
+
onPromptValueCol1Change: (value: string) => void;
|
|
31
|
+
promptValueCol2: string;
|
|
32
|
+
onPromptValueCol2Change: (value: string) => void;
|
|
33
|
+
col1Copy: string;
|
|
34
|
+
onCol1CopyChange: (value: string) => void;
|
|
35
|
+
col2Copy: string;
|
|
36
|
+
onCol2CopyChange: (value: string) => void;
|
|
37
|
+
|
|
20
38
|
hasRetainedContent?: boolean;
|
|
21
39
|
promptOptions: PromptOption[];
|
|
22
40
|
selectedPromptId: string;
|
|
@@ -27,13 +45,27 @@ interface CopyInputStepProps {
|
|
|
27
45
|
}
|
|
28
46
|
|
|
29
47
|
export const CopyInputStep = ({
|
|
48
|
+
layoutChoice,
|
|
30
49
|
copyMode,
|
|
31
50
|
onCopyModeChange,
|
|
51
|
+
topic,
|
|
52
|
+
onTopicChange,
|
|
53
|
+
showAdvancedPrompts,
|
|
54
|
+
onShowAdvancedPromptsChange,
|
|
32
55
|
promptValue,
|
|
33
56
|
onPromptValueChange,
|
|
34
57
|
copyValue,
|
|
35
58
|
onCopyValueChange,
|
|
36
|
-
|
|
59
|
+
overallPrompt,
|
|
60
|
+
onOverallPromptChange,
|
|
61
|
+
promptValueCol1,
|
|
62
|
+
onPromptValueCol1Change,
|
|
63
|
+
promptValueCol2,
|
|
64
|
+
onPromptValueCol2Change,
|
|
65
|
+
col1Copy,
|
|
66
|
+
onCol1CopyChange,
|
|
67
|
+
col2Copy,
|
|
68
|
+
onCol2CopyChange,
|
|
37
69
|
hasRetainedContent = false,
|
|
38
70
|
promptOptions,
|
|
39
71
|
selectedPromptId,
|
|
@@ -42,77 +74,182 @@ export const CopyInputStep = ({
|
|
|
42
74
|
onIsAiStylingChange,
|
|
43
75
|
showStyleToggle = true,
|
|
44
76
|
}: CopyInputStepProps) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
77
|
+
const renderModeSelection = () => (
|
|
78
|
+
<div className="my-2 flex flex-wrap gap-4">
|
|
79
|
+
<div className="flex items-center space-x-2">
|
|
80
|
+
<input
|
|
81
|
+
type="radio"
|
|
82
|
+
id="copy-prompt-mode"
|
|
83
|
+
name="copyModeOptions"
|
|
84
|
+
value="prompt"
|
|
85
|
+
checked={copyMode === 'prompt'}
|
|
86
|
+
onChange={(e) => onCopyModeChange(e.target.value as CopyMode)}
|
|
87
|
+
className="h-4 w-4 border-gray-300 text-cyan-600 focus:ring-cyan-500"
|
|
88
|
+
/>
|
|
89
|
+
<label
|
|
90
|
+
htmlFor="copy-prompt-mode"
|
|
91
|
+
className="text-sm font-bold text-gray-700"
|
|
92
|
+
>
|
|
93
|
+
Write a prompt
|
|
94
|
+
</label>
|
|
95
|
+
</div>
|
|
96
|
+
<div className="flex items-center space-x-2">
|
|
97
|
+
<input
|
|
98
|
+
type="radio"
|
|
99
|
+
id="copy-raw-mode"
|
|
100
|
+
name="copyModeOptions"
|
|
101
|
+
value="raw"
|
|
102
|
+
checked={copyMode === 'raw'}
|
|
103
|
+
onChange={(e) => onCopyModeChange(e.target.value as CopyMode)}
|
|
104
|
+
className="h-4 w-4 border-gray-300 text-cyan-600 focus:ring-cyan-500"
|
|
105
|
+
/>
|
|
106
|
+
<label
|
|
107
|
+
htmlFor="copy-raw-mode"
|
|
108
|
+
className="text-sm font-bold text-gray-700"
|
|
109
|
+
>
|
|
110
|
+
Provide Copy (Markdown)
|
|
111
|
+
</label>
|
|
112
|
+
</div>
|
|
113
|
+
{hasRetainedContent && (
|
|
57
114
|
<div className="flex items-center space-x-2">
|
|
58
115
|
<input
|
|
59
116
|
type="radio"
|
|
60
|
-
id="copy-
|
|
117
|
+
id="copy-original-mode"
|
|
61
118
|
name="copyModeOptions"
|
|
62
|
-
value="
|
|
63
|
-
checked={copyMode === '
|
|
119
|
+
value="original"
|
|
120
|
+
checked={copyMode === 'original'}
|
|
64
121
|
onChange={(e) => onCopyModeChange(e.target.value as CopyMode)}
|
|
65
122
|
className="h-4 w-4 border-gray-300 text-cyan-600 focus:ring-cyan-500"
|
|
66
123
|
/>
|
|
67
124
|
<label
|
|
68
|
-
htmlFor="copy-
|
|
125
|
+
htmlFor="copy-original-mode"
|
|
69
126
|
className="text-sm font-bold text-gray-700"
|
|
70
127
|
>
|
|
71
|
-
|
|
128
|
+
Use Original
|
|
72
129
|
</label>
|
|
73
130
|
</div>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
131
|
+
)}
|
|
132
|
+
</div>
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const renderPromptMode = () => (
|
|
136
|
+
<>
|
|
137
|
+
<div className="mb-4">
|
|
138
|
+
<EnumSelect
|
|
139
|
+
label="Section Type"
|
|
140
|
+
value={selectedPromptId}
|
|
141
|
+
onChange={onSelectedPromptIdChange}
|
|
142
|
+
options={promptOptions}
|
|
143
|
+
placeholder="Select a type..."
|
|
144
|
+
className="w-full"
|
|
145
|
+
/>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<div className="mb-4">
|
|
149
|
+
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
150
|
+
Topic / Context
|
|
151
|
+
</label>
|
|
152
|
+
<textarea
|
|
153
|
+
value={topic}
|
|
154
|
+
onChange={(e) => onTopicChange(e.target.value)}
|
|
155
|
+
placeholder="e.g. a SaaS product for team collaboration"
|
|
156
|
+
rows={2}
|
|
157
|
+
className="block w-full rounded-md border-gray-300 p-2 shadow-sm focus:border-cyan-500 focus:ring-cyan-500 sm:text-sm"
|
|
158
|
+
/>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<div className="mb-4 flex items-center">
|
|
162
|
+
<BooleanToggle
|
|
163
|
+
label="Advanced: Edit Full Prompts"
|
|
164
|
+
value={showAdvancedPrompts}
|
|
165
|
+
onChange={onShowAdvancedPromptsChange}
|
|
166
|
+
size="sm"
|
|
167
|
+
/>
|
|
168
|
+
</div>
|
|
169
|
+
|
|
170
|
+
{showAdvancedPrompts && (
|
|
171
|
+
<div className="mt-4 space-y-4 rounded-md border border-gray-200 bg-white p-4">
|
|
172
|
+
{layoutChoice === 'standard' ? (
|
|
173
|
+
<div>
|
|
174
|
+
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
175
|
+
Full Prompt
|
|
176
|
+
</label>
|
|
177
|
+
<textarea
|
|
178
|
+
value={promptValue}
|
|
179
|
+
onChange={(e) => onPromptValueChange(e.target.value)}
|
|
180
|
+
rows={4}
|
|
181
|
+
className="block w-full rounded-md border-gray-300 p-2 shadow-sm focus:border-cyan-500 focus:ring-cyan-500 sm:text-sm"
|
|
182
|
+
/>
|
|
183
|
+
<p className="mt-1 text-xs text-gray-500">
|
|
184
|
+
Leave [topic] as it will be replaced with your prompt.
|
|
185
|
+
</p>
|
|
186
|
+
</div>
|
|
187
|
+
) : (
|
|
188
|
+
<>
|
|
189
|
+
<div>
|
|
190
|
+
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
191
|
+
Overall Component Brief
|
|
192
|
+
</label>
|
|
193
|
+
<textarea
|
|
194
|
+
value={overallPrompt}
|
|
195
|
+
onChange={(e) => onOverallPromptChange(e.target.value)}
|
|
196
|
+
rows={3}
|
|
197
|
+
className="block w-full rounded-md border-gray-300 p-2 shadow-sm focus:border-cyan-500 focus:ring-cyan-500 sm:text-sm"
|
|
198
|
+
/>
|
|
199
|
+
</div>
|
|
200
|
+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
201
|
+
<div>
|
|
202
|
+
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
203
|
+
Left Column Prompt
|
|
204
|
+
</label>
|
|
205
|
+
<textarea
|
|
206
|
+
value={promptValueCol1}
|
|
207
|
+
onChange={(e) => onPromptValueCol1Change(e.target.value)}
|
|
208
|
+
rows={4}
|
|
209
|
+
className="block w-full rounded-md border-gray-300 p-2 shadow-sm focus:border-cyan-500 focus:ring-cyan-500 sm:text-sm"
|
|
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="block w-full rounded-md border-gray-300 p-2 shadow-sm focus:border-cyan-500 focus:ring-cyan-500 sm:text-sm"
|
|
221
|
+
/>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</>
|
|
225
|
+
)}
|
|
90
226
|
</div>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
227
|
+
)}
|
|
228
|
+
</>
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
const renderRawMode = () => (
|
|
232
|
+
<>
|
|
233
|
+
<div className="mb-2 flex items-center justify-between">
|
|
234
|
+
<p className="text-sm text-gray-500">
|
|
235
|
+
Provide your raw copy here. Use Markdown.
|
|
236
|
+
</p>
|
|
237
|
+
{showStyleToggle && (
|
|
238
|
+
<div className="flex items-center">
|
|
239
|
+
<BooleanToggle
|
|
240
|
+
label="Style with AI"
|
|
241
|
+
value={isAiStyling}
|
|
242
|
+
onChange={onIsAiStylingChange}
|
|
243
|
+
size="sm"
|
|
101
244
|
/>
|
|
102
|
-
<label
|
|
103
|
-
htmlFor="copy-original-mode"
|
|
104
|
-
className="text-sm font-bold text-gray-700"
|
|
105
|
-
>
|
|
106
|
-
Use Original
|
|
107
|
-
</label>
|
|
108
245
|
</div>
|
|
109
246
|
)}
|
|
110
247
|
</div>
|
|
111
248
|
|
|
112
|
-
{
|
|
249
|
+
{isAiStyling && (
|
|
113
250
|
<div className="mb-4">
|
|
114
251
|
<EnumSelect
|
|
115
|
-
label="Section Type"
|
|
252
|
+
label="Section Type (for Styling)"
|
|
116
253
|
value={selectedPromptId}
|
|
117
254
|
onChange={onSelectedPromptIdChange}
|
|
118
255
|
options={promptOptions}
|
|
@@ -122,49 +259,54 @@ export const CopyInputStep = ({
|
|
|
122
259
|
</div>
|
|
123
260
|
)}
|
|
124
261
|
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
</p>
|
|
147
|
-
{showStyleToggle && (
|
|
148
|
-
<div className="flex items-center">
|
|
149
|
-
<BooleanToggle
|
|
150
|
-
label="Style with AI"
|
|
151
|
-
value={isAiStyling}
|
|
152
|
-
onChange={onIsAiStylingChange}
|
|
153
|
-
size="sm"
|
|
154
|
-
/>
|
|
155
|
-
</div>
|
|
156
|
-
)}
|
|
262
|
+
{layoutChoice === 'standard' ? (
|
|
263
|
+
<textarea
|
|
264
|
+
id="raw-copy"
|
|
265
|
+
value={copyValue}
|
|
266
|
+
onChange={(e) => onCopyValueChange(e.target.value)}
|
|
267
|
+
placeholder="## My Awesome Headline..."
|
|
268
|
+
rows={6}
|
|
269
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-sm shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
270
|
+
/>
|
|
271
|
+
) : (
|
|
272
|
+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
273
|
+
<div>
|
|
274
|
+
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
275
|
+
Left Column Markdown
|
|
276
|
+
</label>
|
|
277
|
+
<textarea
|
|
278
|
+
value={col1Copy}
|
|
279
|
+
onChange={(e) => onCol1CopyChange(e.target.value)}
|
|
280
|
+
rows={8}
|
|
281
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-sm shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
282
|
+
/>
|
|
157
283
|
</div>
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
284
|
+
<div>
|
|
285
|
+
<label className="mb-2 block text-sm font-bold text-gray-700">
|
|
286
|
+
Right Column Markdown
|
|
287
|
+
</label>
|
|
288
|
+
<textarea
|
|
289
|
+
value={col2Copy}
|
|
290
|
+
onChange={(e) => onCol2CopyChange(e.target.value)}
|
|
291
|
+
rows={8}
|
|
292
|
+
className="block w-full rounded-md border-gray-300 p-2 font-mono text-sm shadow-sm focus:border-cyan-500 focus:ring-cyan-500"
|
|
293
|
+
/>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
167
296
|
)}
|
|
297
|
+
</>
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
return (
|
|
301
|
+
<>
|
|
302
|
+
<label className="block text-lg font-bold text-gray-800">
|
|
303
|
+
Content Configuration
|
|
304
|
+
</label>
|
|
305
|
+
|
|
306
|
+
{renderModeSelection()}
|
|
307
|
+
|
|
308
|
+
{copyMode === 'prompt' && renderPromptMode()}
|
|
309
|
+
{copyMode === 'raw' && renderRawMode()}
|
|
168
310
|
|
|
169
311
|
{copyMode === 'original' && (
|
|
170
312
|
<div className="rounded-md border border-blue-200 bg-blue-50 p-4 text-blue-700">
|
|
@@ -173,6 +315,6 @@ export const CopyInputStep = ({
|
|
|
173
315
|
</p>
|
|
174
316
|
</div>
|
|
175
317
|
)}
|
|
176
|
-
|
|
318
|
+
</>
|
|
177
319
|
);
|
|
178
320
|
};
|
|
@@ -46,30 +46,32 @@ const mainStylesUrl = isDev
|
|
|
46
46
|
)
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
<script>
|
|
50
|
-
(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
<script is:inline>
|
|
50
|
+
if (typeof document !== 'undefined') {
|
|
51
|
+
(function initCleanSlate() {
|
|
52
|
+
try {
|
|
53
|
+
document.cookie =
|
|
54
|
+
'admin_auth=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax';
|
|
55
|
+
document.cookie =
|
|
56
|
+
'editor_auth=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax';
|
|
57
|
+
document.cookie =
|
|
58
|
+
'tractstack_session_id=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax';
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
const tractStackKeys = [];
|
|
61
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
62
|
+
const key = localStorage.key(i);
|
|
63
|
+
if (key && key.startsWith('tractstack_')) {
|
|
64
|
+
tractStackKeys.push(key);
|
|
65
|
+
}
|
|
64
66
|
}
|
|
65
|
-
|
|
66
|
-
tractStackKeys.forEach((key) => localStorage.removeItem(key));
|
|
67
|
+
tractStackKeys.forEach((key) => localStorage.removeItem(key));
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
console.log('TractStack: Clean slate initialization complete');
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.warn('TractStack: Error during clean slate init:', error);
|
|
72
|
+
}
|
|
73
|
+
})();
|
|
74
|
+
}
|
|
73
75
|
</script>
|
|
74
76
|
</body>
|
|
75
77
|
</html>
|