@alpaca-editor/core 1.0.3896 → 1.0.3898
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/dist/components/ActionButton.js +2 -2
- package/dist/components/ActionButton.js.map +1 -1
- package/dist/components/ui/button.js +3 -3
- package/dist/components/ui/button.js.map +1 -1
- package/dist/config/config.js +44 -22
- package/dist/config/config.js.map +1 -1
- package/dist/editor/FieldListField.js +1 -1
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/Titlebar.js +2 -1
- package/dist/editor/Titlebar.js.map +1 -1
- package/dist/editor/client/EditorClient.d.ts +27 -2
- package/dist/editor/client/EditorClient.js +140 -1
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +6 -1
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/itemsRepository.js +1 -1
- package/dist/editor/client/itemsRepository.js.map +1 -1
- package/dist/editor/client/operations.js +1 -1
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/control-center/About.d.ts +1 -0
- package/dist/editor/control-center/About.js +8 -0
- package/dist/editor/control-center/About.js.map +1 -0
- package/dist/editor/control-center/ControlCenterMenu.js +3 -0
- package/dist/editor/control-center/ControlCenterMenu.js.map +1 -1
- package/dist/editor/control-center/Info.d.ts +1 -0
- package/dist/editor/control-center/Info.js +10 -0
- package/dist/editor/control-center/Info.js.map +1 -0
- package/dist/editor/control-center/QuotaInfo.d.ts +1 -0
- package/dist/editor/control-center/QuotaInfo.js +102 -0
- package/dist/editor/control-center/QuotaInfo.js.map +1 -0
- package/dist/editor/control-center/Status.js +69 -2
- package/dist/editor/control-center/Status.js.map +1 -1
- package/dist/editor/control-center/WebSocketMessages.d.ts +1 -0
- package/dist/editor/control-center/WebSocketMessages.js +66 -0
- package/dist/editor/control-center/WebSocketMessages.js.map +1 -0
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js +7 -6
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +7 -1
- package/dist/editor/services/aiService.js +8 -1
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.js +1 -1
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/ViewSelector.js +9 -4
- package/dist/editor/sidebar/ViewSelector.js.map +1 -1
- package/dist/editor/ui/Icons.d.ts +19 -1
- package/dist/editor/ui/Icons.js +23 -5
- package/dist/editor/ui/Icons.js.map +1 -1
- package/dist/editor/ui/SimpleMenu.js +1 -1
- package/dist/editor/ui/SimpleMenu.js.map +1 -1
- package/dist/fonts/index.d.ts +4 -0
- package/dist/fonts/index.js +9 -0
- package/dist/fonts/index.js.map +1 -0
- package/dist/images/wizard-bg.png +0 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/page-wizard/WizardBox.d.ts +8 -0
- package/dist/page-wizard/WizardBox.js +6 -0
- package/dist/page-wizard/WizardBox.js.map +1 -0
- package/dist/page-wizard/WizardBoxConnector.d.ts +3 -0
- package/dist/page-wizard/WizardBoxConnector.js +6 -0
- package/dist/page-wizard/WizardBoxConnector.js.map +1 -0
- package/dist/page-wizard/WizardSteps.d.ts +4 -2
- package/dist/page-wizard/WizardSteps.js +44 -18
- package/dist/page-wizard/WizardSteps.js.map +1 -1
- package/dist/page-wizard/steps/CollectStep.js +16 -21
- package/dist/page-wizard/steps/CollectStep.js.map +1 -1
- package/dist/page-wizard/steps/ComponentTypesSelector.js +50 -45
- package/dist/page-wizard/steps/ComponentTypesSelector.js.map +1 -1
- package/dist/page-wizard/steps/CreatePage.js +6 -3
- package/dist/page-wizard/steps/CreatePage.js.map +1 -1
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.js +21 -28
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.js.map +1 -1
- package/dist/page-wizard/steps/Generate.js +27 -5
- package/dist/page-wizard/steps/Generate.js.map +1 -1
- package/dist/page-wizard/steps/ImagesStep.js +46 -44
- package/dist/page-wizard/steps/ImagesStep.js.map +1 -1
- package/dist/page-wizard/steps/SelectStep.js +11 -19
- package/dist/page-wizard/steps/SelectStep.js.map +1 -1
- package/dist/page-wizard/steps/usePageCreator.js +41 -12
- package/dist/page-wizard/steps/usePageCreator.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/styles.css +236 -120
- package/images/wizard-bg.png +0 -0
- package/package.json +1 -1
- package/src/components/ActionButton.tsx +6 -8
- package/src/components/ui/button.tsx +3 -3
- package/src/config/config.tsx +54 -22
- package/src/editor/FieldListField.tsx +2 -2
- package/src/editor/Titlebar.tsx +2 -1
- package/src/editor/client/EditorClient.tsx +192 -9
- package/src/editor/client/editContext.ts +12 -2
- package/src/editor/client/itemsRepository.ts +1 -1
- package/src/editor/client/operations.ts +1 -1
- package/src/editor/control-center/About.tsx +342 -0
- package/src/editor/control-center/ControlCenterMenu.tsx +5 -0
- package/src/editor/control-center/Info.tsx +104 -0
- package/src/editor/control-center/QuotaInfo.tsx +301 -0
- package/src/editor/control-center/Status.tsx +108 -2
- package/src/editor/control-center/WebSocketMessages.tsx +155 -0
- package/src/editor/page-editor-chrome/FieldActionIndicator.tsx +20 -5
- package/src/editor/page-viewer/PageViewer.tsx +1 -1
- package/src/editor/services/aiService.ts +17 -2
- package/src/editor/sidebar/ComponentTree.tsx +1 -1
- package/src/editor/sidebar/ViewSelector.tsx +10 -11
- package/src/editor/ui/Icons.tsx +146 -26
- package/src/editor/ui/SimpleMenu.tsx +1 -1
- package/src/fonts/index.ts +10 -0
- package/src/index.ts +7 -1
- package/src/page-wizard/WizardBox.tsx +40 -0
- package/src/page-wizard/WizardBoxConnector.tsx +21 -0
- package/src/page-wizard/WizardSteps.tsx +236 -116
- package/src/page-wizard/steps/CollectStep.tsx +129 -67
- package/src/page-wizard/steps/ComponentTypesSelector.tsx +32 -11
- package/src/page-wizard/steps/CreatePage.tsx +130 -84
- package/src/page-wizard/steps/CreatePageAndLayoutStep.tsx +47 -30
- package/src/page-wizard/steps/Generate.tsx +45 -17
- package/src/page-wizard/steps/ImagesStep.tsx +161 -141
- package/src/page-wizard/steps/SelectStep.tsx +92 -76
- package/src/page-wizard/steps/usePageCreator.ts +40 -14
- package/src/revision.ts +2 -2
- package/styles.css +49 -8
|
@@ -1,21 +1,222 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
import { Wizard, WizardData, WizardPageModel } from "./PageWizard";
|
|
3
|
-
|
|
4
|
-
import { ItemDescriptor
|
|
5
|
-
import {
|
|
3
|
+
|
|
4
|
+
import { ItemDescriptor } from "../editor/pageModel";
|
|
5
|
+
import { Logo } from "../editor/ui/Icons";
|
|
6
6
|
|
|
7
7
|
import { flushSync } from "react-dom";
|
|
8
8
|
import { useEditContext } from "../editor/client/editContext";
|
|
9
9
|
import { classNames } from "primereact/utils";
|
|
10
|
-
import {
|
|
10
|
+
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
import { Button } from "../components/ui/button";
|
|
13
|
+
import { cn } from "../lib/utils";
|
|
14
|
+
|
|
15
|
+
interface WizardStepsProps {
|
|
16
16
|
wizard: Wizard;
|
|
17
17
|
parentItem: ItemDescriptor;
|
|
18
|
-
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface NavigationStepsProps {
|
|
21
|
+
wizard: Wizard;
|
|
22
|
+
currentStepIndex: number;
|
|
23
|
+
onStepClick: (index: number) => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface PreviousButtonProps {
|
|
27
|
+
currentStepIndex: number;
|
|
28
|
+
wizard: Wizard;
|
|
29
|
+
onPrevious: () => void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface NextButtonProps {
|
|
33
|
+
currentStepIndex: number;
|
|
34
|
+
wizard: Wizard;
|
|
35
|
+
stepCompleted: number;
|
|
36
|
+
onNext: () => void;
|
|
37
|
+
onFinish: () => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface WizardHeaderProps {
|
|
41
|
+
wizard: Wizard;
|
|
42
|
+
currentStepIndex: number;
|
|
43
|
+
onStepClick: (index: number) => void;
|
|
44
|
+
onPrevious: () => void;
|
|
45
|
+
onNext: () => void;
|
|
46
|
+
onFinish: () => void;
|
|
47
|
+
stepCompleted: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface WizardContentProps {
|
|
51
|
+
currentStep: any;
|
|
52
|
+
children: React.ReactNode;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function PreviousButton({
|
|
56
|
+
currentStepIndex,
|
|
57
|
+
wizard,
|
|
58
|
+
onPrevious,
|
|
59
|
+
}: PreviousButtonProps) {
|
|
60
|
+
if (currentStepIndex === 0) return null;
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<Button onClick={onPrevious} variant="outline">
|
|
64
|
+
<ChevronLeft /> {wizard.steps[currentStepIndex - 1]?.name}
|
|
65
|
+
</Button>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function NextButton({
|
|
70
|
+
currentStepIndex,
|
|
71
|
+
wizard,
|
|
72
|
+
stepCompleted,
|
|
73
|
+
onNext,
|
|
74
|
+
onFinish,
|
|
75
|
+
}: NextButtonProps) {
|
|
76
|
+
const isLastStep = currentStepIndex === wizard.steps.length - 1;
|
|
77
|
+
const isDisabled = stepCompleted < currentStepIndex;
|
|
78
|
+
|
|
79
|
+
if (isLastStep) {
|
|
80
|
+
return (
|
|
81
|
+
<Button disabled={isDisabled} onClick={onFinish}>
|
|
82
|
+
Finish <ChevronRight />
|
|
83
|
+
</Button>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<Button disabled={isDisabled} onClick={onNext}>
|
|
89
|
+
{wizard.steps[currentStepIndex + 1]?.name}
|
|
90
|
+
<ChevronRight />
|
|
91
|
+
</Button>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function NavigationSteps({
|
|
96
|
+
wizard,
|
|
97
|
+
currentStepIndex,
|
|
98
|
+
onStepClick,
|
|
99
|
+
}: NavigationStepsProps) {
|
|
100
|
+
return (
|
|
101
|
+
<div className="flex-1 overflow-hidden">
|
|
102
|
+
<div className="scrollbar-hide flex flex-1 justify-center overflow-x-auto p-2.5 text-xs md:gap-3">
|
|
103
|
+
<div className="flex min-w-max items-center gap-3 md:gap-3">
|
|
104
|
+
{wizard.steps.map((step, index) => (
|
|
105
|
+
<>
|
|
106
|
+
<div
|
|
107
|
+
key={step.id}
|
|
108
|
+
className={classNames(
|
|
109
|
+
"flex min-w-max flex-col items-center gap-1",
|
|
110
|
+
currentStepIndex > index && "cursor-pointer",
|
|
111
|
+
)}
|
|
112
|
+
onClick={() =>
|
|
113
|
+
index < currentStepIndex ? onStepClick(index) : undefined
|
|
114
|
+
}
|
|
115
|
+
>
|
|
116
|
+
<span
|
|
117
|
+
className={cn(
|
|
118
|
+
"relative flex h-6 w-6 items-center justify-center rounded-full border-1 p-2 text-xs font-medium",
|
|
119
|
+
currentStepIndex === index &&
|
|
120
|
+
"border-theme-secondary text-theme-secondary bg-theme-secondary-light",
|
|
121
|
+
currentStepIndex < index && "border-gray-400 text-gray-400",
|
|
122
|
+
currentStepIndex > index &&
|
|
123
|
+
"bg-theme-secondary text-gray-200",
|
|
124
|
+
)}
|
|
125
|
+
>
|
|
126
|
+
{currentStepIndex > index ? "✓" : index + 1}
|
|
127
|
+
</span>
|
|
128
|
+
<div
|
|
129
|
+
className={classNames(
|
|
130
|
+
"w-auto text-center whitespace-nowrap opacity-100",
|
|
131
|
+
currentStepIndex === index
|
|
132
|
+
? "text-theme-secondary font-semibold"
|
|
133
|
+
: currentStepIndex >= index
|
|
134
|
+
? "text-gray-600"
|
|
135
|
+
: "text-gray-400",
|
|
136
|
+
)}
|
|
137
|
+
>
|
|
138
|
+
{step.name}
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
{index < wizard.steps.length - 1 && (
|
|
143
|
+
<div className="mt-[-20px] h-0 w-8 border-t border-gray-300 bg-gray-300 md:w-10" />
|
|
144
|
+
)}
|
|
145
|
+
</>
|
|
146
|
+
))}
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function WizardHeader({
|
|
154
|
+
wizard,
|
|
155
|
+
currentStepIndex,
|
|
156
|
+
onStepClick,
|
|
157
|
+
onPrevious,
|
|
158
|
+
onNext,
|
|
159
|
+
onFinish,
|
|
160
|
+
stepCompleted,
|
|
161
|
+
}: WizardHeaderProps) {
|
|
162
|
+
return (
|
|
163
|
+
<div className="flex items-center gap-3 border-b border-gray-300 bg-white md:pr-8">
|
|
164
|
+
<div className="text-md flex items-center justify-center self-stretch border-r border-gray-300 p-2 px-10 text-sm font-semibold text-neutral-800">
|
|
165
|
+
{wizard.name}
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<PreviousButton
|
|
169
|
+
currentStepIndex={currentStepIndex}
|
|
170
|
+
wizard={wizard}
|
|
171
|
+
onPrevious={onPrevious}
|
|
172
|
+
/>
|
|
173
|
+
|
|
174
|
+
<NavigationSteps
|
|
175
|
+
wizard={wizard}
|
|
176
|
+
currentStepIndex={currentStepIndex}
|
|
177
|
+
onStepClick={onStepClick}
|
|
178
|
+
/>
|
|
179
|
+
|
|
180
|
+
<div>
|
|
181
|
+
<NextButton
|
|
182
|
+
currentStepIndex={currentStepIndex}
|
|
183
|
+
wizard={wizard}
|
|
184
|
+
stepCompleted={stepCompleted}
|
|
185
|
+
onNext={onNext}
|
|
186
|
+
onFinish={onFinish}
|
|
187
|
+
/>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function WizardContent({ currentStep, children }: WizardContentProps) {
|
|
194
|
+
return (
|
|
195
|
+
<div className="relative flex-1 bg-neutral-100">
|
|
196
|
+
<div className="h-full p-8">
|
|
197
|
+
<div className="relative z-10 h-full">
|
|
198
|
+
<div className="flex h-full flex-col">
|
|
199
|
+
<div className="mb-10 flex gap-4">
|
|
200
|
+
<Logo className="h-8 w-8" />
|
|
201
|
+
<div className="flex-1 text-neutral-800">
|
|
202
|
+
<div className="text-xl font-semibold">{currentStep?.name}</div>
|
|
203
|
+
{currentStep?.description && (
|
|
204
|
+
<div className="mt-1 font-light">
|
|
205
|
+
{currentStep.description}
|
|
206
|
+
</div>
|
|
207
|
+
)}
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
<div className="relative flex-1">{children}</div>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
<div className="bg-wizard absolute inset-0" />
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export function WizardSteps({ wizard, parentItem }: WizardStepsProps) {
|
|
19
220
|
const [currentStepIndex, setCurrentStepIndex] = useState(0);
|
|
20
221
|
const [data, setData] = useState<WizardData>({});
|
|
21
222
|
const [pageModel, setPageModel] = useState<WizardPageModel>({
|
|
@@ -81,118 +282,37 @@ export function WizardSteps({
|
|
|
81
282
|
});
|
|
82
283
|
};
|
|
83
284
|
|
|
285
|
+
const handlePrevious = () => {
|
|
286
|
+
switchStep(currentStepIndex - 1);
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const handleNext = () => {
|
|
290
|
+
switchStep(currentStepIndex + 1);
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const handleFinish = () => {
|
|
294
|
+
editContext?.switchView("editor", { skipConfirmation: true });
|
|
295
|
+
};
|
|
296
|
+
|
|
84
297
|
const currentStep = wizard.steps[currentStepIndex];
|
|
85
298
|
|
|
86
299
|
if (!currentStep) return null;
|
|
87
300
|
|
|
88
|
-
const panels = [
|
|
89
|
-
<Allotment.Pane key="left" minSize={200}>
|
|
90
|
-
<div className="absolute inset-0 overflow-y-auto">
|
|
91
|
-
<div className="flex h-full flex-col bg-gray-50 text-sm text-gray-700">
|
|
92
|
-
<div className="flex gap-3 border-b border-gray-200 bg-gray-100 p-2">
|
|
93
|
-
<PageWizardLogo />
|
|
94
|
-
<div className="gap-1p-2 flex flex-col justify-center">
|
|
95
|
-
<div className="text-md font-semibold">{wizard.name}</div>
|
|
96
|
-
<div className="text-sm font-light">{wizard.description}</div>
|
|
97
|
-
</div>
|
|
98
|
-
</div>
|
|
99
|
-
<div className="flex flex-1 flex-col gap-3 p-4">
|
|
100
|
-
{wizard.steps.map((step, index) => (
|
|
101
|
-
<div
|
|
102
|
-
key={step.id}
|
|
103
|
-
className={classNames(
|
|
104
|
-
"flex items-center gap-4",
|
|
105
|
-
currentStepIndex > index && "cursor-pointer",
|
|
106
|
-
)}
|
|
107
|
-
onClick={() =>
|
|
108
|
-
index < currentStepIndex ? switchStep(index) : undefined
|
|
109
|
-
}
|
|
110
|
-
>
|
|
111
|
-
<span
|
|
112
|
-
className={classNames(
|
|
113
|
-
"text-activeStepColor flex h-7 w-7 items-center justify-center rounded-full border-2 p-2 text-xs font-medium",
|
|
114
|
-
currentStepIndex === index
|
|
115
|
-
? "border-canvas-red text-canvas-red"
|
|
116
|
-
: "border-gray-400",
|
|
117
|
-
)}
|
|
118
|
-
>
|
|
119
|
-
{index + 1}
|
|
120
|
-
</span>
|
|
121
|
-
<div
|
|
122
|
-
className={classNames(
|
|
123
|
-
"w-auto opacity-100",
|
|
124
|
-
currentStepIndex === index
|
|
125
|
-
? "text-canvas-red font-semibold"
|
|
126
|
-
: currentStepIndex >= index
|
|
127
|
-
? "text-sm text-gray-600"
|
|
128
|
-
: "text-sm text-gray-400",
|
|
129
|
-
)}
|
|
130
|
-
>
|
|
131
|
-
{step.name}
|
|
132
|
-
</div>
|
|
133
|
-
</div>
|
|
134
|
-
))}
|
|
135
|
-
</div>
|
|
136
|
-
</div>
|
|
137
|
-
</div>
|
|
138
|
-
</Allotment.Pane>,
|
|
139
|
-
<Allotment.Pane key="right">
|
|
140
|
-
<div className="absolute inset-0 overflow-y-auto">
|
|
141
|
-
<div className="bg-secondary animate-fadeIn flex h-full flex-col px-4 pt-4 transition-all duration-500 lg:pr-20 xl:pr-32">
|
|
142
|
-
<div className="border-b border-gray-200 pb-4">
|
|
143
|
-
<div className="text-xl font-semibold">{currentStep?.name}</div>
|
|
144
|
-
{currentStep?.description && (
|
|
145
|
-
<div className="mt-2 text-base font-light">
|
|
146
|
-
{currentStep.description}
|
|
147
|
-
</div>
|
|
148
|
-
)}
|
|
149
|
-
</div>
|
|
150
|
-
<div className="flex-1 pt-4 pb-4">{getCurrentStep()}</div>
|
|
151
|
-
</div>
|
|
152
|
-
</div>
|
|
153
|
-
</Allotment.Pane>,
|
|
154
|
-
];
|
|
155
|
-
|
|
156
301
|
return (
|
|
157
|
-
<div className="flex h-full flex-col
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
)}
|
|
172
|
-
</div>
|
|
173
|
-
<div>
|
|
174
|
-
{currentStepIndex < wizard.steps.length - 1 && (
|
|
175
|
-
<Button
|
|
176
|
-
icon="pi pi-arrow-right mr-2"
|
|
177
|
-
disabled={stepCompleted < currentStepIndex}
|
|
178
|
-
onClick={() => switchStep(currentStepIndex + 1)}
|
|
179
|
-
>
|
|
180
|
-
{wizard.steps[currentStepIndex + 1]?.name}
|
|
181
|
-
</Button>
|
|
182
|
-
)}
|
|
183
|
-
{currentStepIndex === wizard.steps.length - 1 && (
|
|
184
|
-
<Button
|
|
185
|
-
icon="pi pi-check"
|
|
186
|
-
disabled={stepCompleted < currentStepIndex}
|
|
187
|
-
onClick={() => {
|
|
188
|
-
editContext?.switchView("editor", { skipConfirmation: true });
|
|
189
|
-
}}
|
|
190
|
-
label="Finish"
|
|
191
|
-
className="ml-2"
|
|
192
|
-
/>
|
|
193
|
-
)}
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
302
|
+
<div className="flex h-full flex-col">
|
|
303
|
+
<WizardHeader
|
|
304
|
+
wizard={wizard}
|
|
305
|
+
currentStepIndex={currentStepIndex}
|
|
306
|
+
onStepClick={switchStep}
|
|
307
|
+
onPrevious={handlePrevious}
|
|
308
|
+
onNext={handleNext}
|
|
309
|
+
onFinish={handleFinish}
|
|
310
|
+
stepCompleted={stepCompleted}
|
|
311
|
+
/>
|
|
312
|
+
|
|
313
|
+
<WizardContent currentStep={currentStep}>
|
|
314
|
+
{getCurrentStep()}
|
|
315
|
+
</WizardContent>
|
|
196
316
|
</div>
|
|
197
317
|
);
|
|
198
318
|
}
|
|
@@ -5,8 +5,11 @@ import { Splitter, SplitterPanel } from "../../editor/ui/Splitter";
|
|
|
5
5
|
import MDEditor from "@uiw/react-md-editor";
|
|
6
6
|
import { StepComponentProps } from "../../config/types";
|
|
7
7
|
import { ActionButton } from "../../components/ActionButton";
|
|
8
|
-
import {
|
|
8
|
+
import { UploadIcon, DocumentIcon } from "../../editor/ui/Icons";
|
|
9
9
|
import { Spinner } from "../../editor/ui/Spinner";
|
|
10
|
+
import { WizardBox } from "../WizardBox";
|
|
11
|
+
import { LinkIcon } from "lucide-react";
|
|
12
|
+
import { InputTextarea } from "primereact/inputtextarea";
|
|
10
13
|
|
|
11
14
|
export function CollectStep({
|
|
12
15
|
data,
|
|
@@ -129,45 +132,6 @@ export function CollectStep({
|
|
|
129
132
|
<div className="text-sm font-semibold text-gray-700">
|
|
130
133
|
Upload a file
|
|
131
134
|
</div>
|
|
132
|
-
|
|
133
|
-
<div
|
|
134
|
-
className={`flex h-40 w-40 flex-col items-center justify-center border border-dashed border-gray-300 p-5 ${
|
|
135
|
-
isUploading ? "bg-gray-200" : "bg-white"
|
|
136
|
-
}`}
|
|
137
|
-
onDrop={handleDrop}
|
|
138
|
-
onDragOver={(e) => e.preventDefault()}
|
|
139
|
-
>
|
|
140
|
-
<div className="flex flex-col items-center justify-center gap-1 text-center text-sm font-medium">
|
|
141
|
-
{!isUploading && <UploadCloudIcon />}
|
|
142
|
-
{isUploading && <Spinner />}
|
|
143
|
-
<input
|
|
144
|
-
ref={fileInputRef}
|
|
145
|
-
type="file"
|
|
146
|
-
multiple
|
|
147
|
-
accept=".pdf,.doc,.docx"
|
|
148
|
-
style={{ display: "none" }}
|
|
149
|
-
onChange={(e) => {
|
|
150
|
-
const file = e.target.files?.[0];
|
|
151
|
-
if (file) {
|
|
152
|
-
uploadFile(file);
|
|
153
|
-
}
|
|
154
|
-
}}
|
|
155
|
-
onDrop={handleDrop}
|
|
156
|
-
disabled={isUploading}
|
|
157
|
-
/>
|
|
158
|
-
Drag & Drop to upload or
|
|
159
|
-
<span
|
|
160
|
-
className={`text-sm font-medium ${
|
|
161
|
-
isUploading
|
|
162
|
-
? "text-gray-500"
|
|
163
|
-
: "text-canvas-pink cursor-pointer underline"
|
|
164
|
-
} `}
|
|
165
|
-
onClick={triggerFileInput}
|
|
166
|
-
>
|
|
167
|
-
browse
|
|
168
|
-
</span>
|
|
169
|
-
</div>
|
|
170
|
-
</div>
|
|
171
135
|
</div>
|
|
172
136
|
|
|
173
137
|
{error && <div className="mt-2 text-sm text-red-500">{error}</div>}
|
|
@@ -204,33 +168,131 @@ export function CollectStep({
|
|
|
204
168
|
),
|
|
205
169
|
};
|
|
206
170
|
|
|
207
|
-
const resultPanel: SplitterPanel = {
|
|
208
|
-
name: "result",
|
|
209
|
-
defaultSize: "auto",
|
|
210
|
-
collapsible: false,
|
|
211
|
-
content: (
|
|
212
|
-
<div className="absolute inset-0 h-full w-full px-4 pb-4">
|
|
213
|
-
<MDEditor
|
|
214
|
-
height="100%"
|
|
215
|
-
className="max-h-full"
|
|
216
|
-
value={data.htmlContent}
|
|
217
|
-
preview="edit"
|
|
218
|
-
enableScroll={true}
|
|
219
|
-
onChange={(val) =>
|
|
220
|
-
setData((prev: WizardData) => ({
|
|
221
|
-
...prev,
|
|
222
|
-
htmlContent: val || "",
|
|
223
|
-
}))
|
|
224
|
-
}
|
|
225
|
-
/>
|
|
226
|
-
</div>
|
|
227
|
-
),
|
|
228
|
-
};
|
|
229
|
-
|
|
230
171
|
return (
|
|
231
|
-
<
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
172
|
+
<div className="absolute inset-0 overflow-auto">
|
|
173
|
+
<div className="grid grid-cols-2 gap-4">
|
|
174
|
+
<WizardBox
|
|
175
|
+
icon={<UploadIcon className="text-theme-secondary" />}
|
|
176
|
+
title="Upload a file (optional)"
|
|
177
|
+
description="Upload a file to the page"
|
|
178
|
+
className="flex-1"
|
|
179
|
+
>
|
|
180
|
+
<div
|
|
181
|
+
className={`flex flex-col items-center justify-center border border-dashed border-gray-300 p-8 ${
|
|
182
|
+
isUploading ? "bg-gray-200" : "bg-white"
|
|
183
|
+
}`}
|
|
184
|
+
onDrop={handleDrop}
|
|
185
|
+
onDragOver={(e) => e.preventDefault()}
|
|
186
|
+
>
|
|
187
|
+
<div className="flex flex-col items-center justify-center gap-1 text-center text-sm">
|
|
188
|
+
{!isUploading && (
|
|
189
|
+
<svg
|
|
190
|
+
width="49"
|
|
191
|
+
height="48"
|
|
192
|
+
viewBox="0 0 49 48"
|
|
193
|
+
fill="none"
|
|
194
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
195
|
+
>
|
|
196
|
+
<rect
|
|
197
|
+
x="0.666992"
|
|
198
|
+
width="48"
|
|
199
|
+
height="48"
|
|
200
|
+
rx="24"
|
|
201
|
+
fill="#F6EEFF"
|
|
202
|
+
/>
|
|
203
|
+
<path
|
|
204
|
+
d="M32.604 20.68C32.594 20.648 32.583 20.6167 32.571 20.586C32.5235 20.4775 32.4572 20.3783 32.375 20.293L26.375 14.293C26.2897 14.2108 26.1905 14.1445 26.082 14.097C26.052 14.083 26.02 14.075 25.988 14.064C25.9043 14.0356 25.8172 14.0185 25.729 14.013C25.707 14.011 25.688 14 25.667 14H18.667C17.564 14 16.667 14.897 16.667 16V32C16.667 33.103 17.564 34 18.667 34H30.667C31.77 34 32.667 33.103 32.667 32V21C32.667 20.979 32.656 20.96 32.654 20.938C32.6487 20.8502 32.6319 20.7634 32.604 20.68ZM29.253 20H26.667V17.414L29.253 20ZM18.667 32V16H24.667V21C24.667 21.2652 24.7723 21.5196 24.9599 21.7071C25.1474 21.8946 25.4018 22 25.667 22H30.667L30.669 32H18.667Z"
|
|
205
|
+
fill="#9650FB"
|
|
206
|
+
/>
|
|
207
|
+
</svg>
|
|
208
|
+
)}
|
|
209
|
+
{isUploading && <Spinner />}
|
|
210
|
+
<input
|
|
211
|
+
ref={fileInputRef}
|
|
212
|
+
type="file"
|
|
213
|
+
multiple
|
|
214
|
+
accept=".pdf,.doc,.docx"
|
|
215
|
+
style={{ display: "none" }}
|
|
216
|
+
onChange={(e) => {
|
|
217
|
+
const file = e.target.files?.[0];
|
|
218
|
+
if (file) {
|
|
219
|
+
uploadFile(file);
|
|
220
|
+
}
|
|
221
|
+
}}
|
|
222
|
+
onDrop={handleDrop}
|
|
223
|
+
disabled={isUploading}
|
|
224
|
+
/>
|
|
225
|
+
<div className="flex items-center gap-1">
|
|
226
|
+
<span
|
|
227
|
+
className={`text-sm font-medium ${
|
|
228
|
+
isUploading
|
|
229
|
+
? "text-gray-500"
|
|
230
|
+
: "text-theme-secondary cursor-pointer underline"
|
|
231
|
+
} `}
|
|
232
|
+
onClick={triggerFileInput}
|
|
233
|
+
>
|
|
234
|
+
Click
|
|
235
|
+
</span>
|
|
236
|
+
or drag & drop to upload
|
|
237
|
+
</div>
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
</WizardBox>
|
|
241
|
+
<WizardBox
|
|
242
|
+
icon={<LinkIcon className="text-theme-secondary" />}
|
|
243
|
+
title="Scrape page from URL (optional)"
|
|
244
|
+
description="Upload a file to the page"
|
|
245
|
+
className="flex-1"
|
|
246
|
+
>
|
|
247
|
+
{error && <div className="mt-2 text-sm text-red-500">{error}</div>}
|
|
248
|
+
|
|
249
|
+
<div className="flex flex-col gap-2">
|
|
250
|
+
<div className="text-sm font-semibold text-gray-700">
|
|
251
|
+
<div className="text-xs font-normal text-gray-500">
|
|
252
|
+
Only scrape websites you have permission to access. You are
|
|
253
|
+
responsible for complying with the website's terms of service
|
|
254
|
+
and all applicable laws.
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
<InputText
|
|
258
|
+
type="text"
|
|
259
|
+
className="rounded-md border border-gray-300 px-3 py-2"
|
|
260
|
+
onChange={(e) => setScrapeUrl(e.target.value)}
|
|
261
|
+
/>
|
|
262
|
+
{scrapeError && (
|
|
263
|
+
<div className="mt-2 text-sm text-red-500">{scrapeError}</div>
|
|
264
|
+
)}
|
|
265
|
+
<div className="flex gap-2">
|
|
266
|
+
<ActionButton
|
|
267
|
+
type="submit"
|
|
268
|
+
isLoading={isScraping}
|
|
269
|
+
onClick={handleScrape}
|
|
270
|
+
loadingText="Scraping..."
|
|
271
|
+
>
|
|
272
|
+
Scrape
|
|
273
|
+
</ActionButton>
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
</WizardBox>
|
|
277
|
+
<WizardBox
|
|
278
|
+
icon={<DocumentIcon className="text-theme-secondary" />}
|
|
279
|
+
title="Text"
|
|
280
|
+
description="Provide the text you want to use for the page"
|
|
281
|
+
className="col-span-2"
|
|
282
|
+
>
|
|
283
|
+
<InputTextarea
|
|
284
|
+
className="max-h-full w-full"
|
|
285
|
+
value={data.htmlContent}
|
|
286
|
+
rows={20}
|
|
287
|
+
onChange={(e) =>
|
|
288
|
+
setData((prev: WizardData) => ({
|
|
289
|
+
...prev,
|
|
290
|
+
htmlContent: e.target.value || "",
|
|
291
|
+
}))
|
|
292
|
+
}
|
|
293
|
+
/>
|
|
294
|
+
</WizardBox>
|
|
295
|
+
</div>
|
|
296
|
+
</div>
|
|
235
297
|
);
|
|
236
298
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Dispatch, SetStateAction, useEffect, useState } from "react";
|
|
1
|
+
import { Dispatch, SetStateAction, useEffect, useState, useRef } from "react";
|
|
2
2
|
import { WizardStep } from "../PageWizard";
|
|
3
3
|
import {
|
|
4
4
|
PageSchema,
|
|
@@ -30,6 +30,7 @@ export function ComponentTypeSelector({
|
|
|
30
30
|
useState(true);
|
|
31
31
|
const [preselectedTypes, setPreselectedTypes] = useState<string[]>([]);
|
|
32
32
|
const [searchFilter, setSearchFilter] = useState<string>("");
|
|
33
|
+
const contentRef = useRef<HTMLDivElement>(null);
|
|
33
34
|
|
|
34
35
|
// Ensure selectedComponentTypes is always an array
|
|
35
36
|
useEffect(() => {
|
|
@@ -270,22 +271,42 @@ export function ComponentTypeSelector({
|
|
|
270
271
|
</div>
|
|
271
272
|
<button
|
|
272
273
|
onClick={() => setIsSettingsPanelCollapsed(!isSettingsPanelCollapsed)}
|
|
273
|
-
className="flex h-6 w-6 items-center justify-center rounded bg-gray-200 p-1 text-gray-700 hover:bg-gray-300"
|
|
274
|
+
className="flex h-6 w-6 items-center justify-center rounded bg-gray-200 p-1 text-gray-700 transition-colors duration-200 hover:bg-gray-300"
|
|
274
275
|
title={
|
|
275
276
|
isSettingsPanelCollapsed ? "Expand settings" : "Collapse settings"
|
|
276
277
|
}
|
|
277
278
|
aria-expanded={!isSettingsPanelCollapsed}
|
|
278
279
|
>
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
280
|
+
<svg
|
|
281
|
+
className={`h-4 w-4 transition-transform duration-300 ease-in-out ${
|
|
282
|
+
isSettingsPanelCollapsed ? "rotate-0" : "rotate-180"
|
|
283
|
+
}`}
|
|
284
|
+
fill="none"
|
|
285
|
+
stroke="currentColor"
|
|
286
|
+
viewBox="0 0 24 24"
|
|
287
|
+
>
|
|
288
|
+
<path
|
|
289
|
+
strokeLinecap="round"
|
|
290
|
+
strokeLinejoin="round"
|
|
291
|
+
strokeWidth={2}
|
|
292
|
+
d="M19 9l-7 7-7-7"
|
|
293
|
+
/>
|
|
294
|
+
</svg>
|
|
284
295
|
</button>
|
|
285
296
|
</div>
|
|
286
297
|
|
|
287
|
-
|
|
288
|
-
|
|
298
|
+
<div
|
|
299
|
+
ref={contentRef}
|
|
300
|
+
className={`overflow-hidden transition-all duration-300 ease-in-out ${
|
|
301
|
+
isSettingsPanelCollapsed
|
|
302
|
+
? "max-h-0 opacity-0"
|
|
303
|
+
: "max-h-[1000px] opacity-100"
|
|
304
|
+
}`}
|
|
305
|
+
style={{
|
|
306
|
+
transitionProperty: "max-height, opacity",
|
|
307
|
+
}}
|
|
308
|
+
>
|
|
309
|
+
<div className="pt-2">
|
|
289
310
|
<div className="mb-2">
|
|
290
311
|
<input
|
|
291
312
|
type="text"
|
|
@@ -467,8 +488,8 @@ export function ComponentTypeSelector({
|
|
|
467
488
|
</div>
|
|
468
489
|
</div>
|
|
469
490
|
</div>
|
|
470
|
-
|
|
471
|
-
|
|
491
|
+
</div>
|
|
492
|
+
</div>
|
|
472
493
|
</div>
|
|
473
494
|
);
|
|
474
495
|
}
|