@aglyn/plugins-ai 1.0.0-beta.264 → 1.0.0-beta.266
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 +17 -17
- package/src/lib/assets/site-styles/beauty.webp +0 -0
- package/src/lib/assets/site-styles/blog.webp +0 -0
- package/src/lib/assets/site-styles/business.webp +0 -0
- package/src/lib/assets/site-styles/coming-soon.webp +0 -0
- package/src/lib/assets/site-styles/education.webp +0 -0
- package/src/lib/assets/site-styles/events.webp +0 -0
- package/src/lib/assets/site-styles/fitness.webp +0 -0
- package/src/lib/assets/site-styles/landing.webp +0 -0
- package/src/lib/assets/site-styles/music.webp +0 -0
- package/src/lib/assets/site-styles/nonprofit.webp +0 -0
- package/src/lib/assets/site-styles/personal.webp +0 -0
- package/src/lib/assets/site-styles/photography.webp +0 -0
- package/src/lib/assets/site-styles/portfolio.webp +0 -0
- package/src/lib/assets/site-styles/professional.webp +0 -0
- package/src/lib/assets/site-styles/realestate.webp +0 -0
- package/src/lib/assets/site-styles/restaurant.webp +0 -0
- package/src/lib/assets/site-styles/store.webp +0 -0
- package/src/lib/assets/site-styles/studio.webp +0 -0
- package/src/lib/assets/site-styles/trades.webp +0 -0
- package/src/lib/assets/site-styles/wellness.webp +0 -0
- package/src/lib/assets/site-styles/yoga.webp +0 -0
- package/src/lib/components/ai-site-start-card.component.d.ts +12 -0
- package/src/lib/components/ai-site-start-card.component.js +256 -236
- package/src/lib/components/ai-site-start-card.component.js.map +1 -1
- package/src/lib/components/ai-site-start-steps.component.d.ts +108 -0
- package/src/lib/components/ai-site-start-steps.component.js +451 -0
- package/src/lib/components/ai-site-start-steps.component.js.map +1 -0
- package/src/lib/components/ai-site-start-tracking.d.ts +114 -0
- package/src/lib/components/ai-site-start-tracking.js +277 -0
- package/src/lib/components/ai-site-start-tracking.js.map +1 -0
- package/src/lib/components/ai-site-style-previews.d.ts +26 -0
- package/src/lib/components/ai-site-style-previews.js +115 -0
- package/src/lib/components/ai-site-style-previews.js.map +1 -0
- package/src/lib/insights/ai-insight-digest.d.ts +9 -0
- package/src/lib/insights/ai-insight-digest.js +35 -11
- package/src/lib/insights/ai-insight-digest.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.d.ts +9 -0
- package/src/lib/jobs/ai-job-page-language.js +20 -2
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +43 -8
- package/src/lib/jobs/ai-job-plan-step.js +99 -18
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-datasets.d.ts +82 -1
- package/src/lib/jobs/ai-job-site-datasets.js +276 -14
- package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
- package/src/lib/jobs/ai-layout-stock-photos.d.ts +108 -10
- package/src/lib/jobs/ai-layout-stock-photos.js +729 -87
- package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
- package/src/lib/jobs/fixtures/ai-site-foreign-datasets-recording.d.ts +58 -0
- package/src/lib/jobs/fixtures/ai-site-foreign-datasets-recording.js +678 -0
- package/src/lib/jobs/fixtures/ai-site-foreign-datasets-recording.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3856-beta265-recordings.d.ts +33 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3856-beta265-recordings.js +270 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3856-beta265-recordings.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3856-people-recordings.d.ts +33 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3856-people-recordings.js +277 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3856-people-recordings.js.map +1 -0
- package/src/lib/layout-language/ai-layout-compiler.js +49 -12
- package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
- package/src/lib/layout-language/ai-layout-design.d.ts +6 -3
- package/src/lib/layout-language/ai-layout-design.js +14 -13
- package/src/lib/layout-language/ai-layout-design.js.map +1 -1
- package/src/lib/layout-language/ai-layout-listings.d.ts +48 -0
- package/src/lib/layout-language/ai-layout-listings.js +91 -5
- package/src/lib/layout-language/ai-layout-listings.js.map +1 -1
- package/src/lib/layout-language/ai-layout-pictures.d.ts +15 -0
- package/src/lib/layout-language/ai-layout-pictures.js +6 -2
- package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
- package/src/lib/model/ai-site-home-arcs.d.ts +75 -0
- package/src/lib/model/ai-site-home-arcs.js +741 -0
- package/src/lib/model/ai-site-home-arcs.js.map +1 -0
- package/src/lib/model/ai-site-inventory.d.ts +18 -0
- package/src/lib/model/ai-site-inventory.js.map +1 -1
- package/src/lib/model/ai-site-job.d.ts +9 -6
- package/src/lib/model/ai-site-job.js +8 -5
- package/src/lib/model/ai-site-job.js.map +1 -1
- package/src/lib/model/ai-site-kinds.js +24 -24
- package/src/lib/model/ai-site-kinds.js.map +1 -1
- package/src/lib/model/ai-site-start-steps.d.ts +67 -0
- package/src/lib/model/ai-site-start-steps.js +127 -0
- package/src/lib/model/ai-site-start-steps.js.map +1 -0
- package/src/lib/model/ai-site-start.js +4 -1
- package/src/lib/model/ai-site-start.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.d.ts +32 -0
- package/src/lib/runtime/ai-doctrine-validators.js +119 -2
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.d.ts +6 -1
- package/src/lib/runtime/ai-doctrine.js +9 -5
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/runtime/ai-palette.generated.js +5 -2
- package/src/lib/runtime/ai-palette.generated.js.map +1 -1
- package/src/lib/runtime/site-inventory.js +6 -0
- package/src/lib/runtime/site-inventory.js.map +1 -1
- package/src/lib/server/ai-insight-digest-route.js +2 -2
- package/src/lib/server/ai-insight-digest-route.js.map +1 -1
- package/src/lib/usage/assist-free-taste.js +3 -0
- package/src/lib/usage/assist-free-taste.js.map +1 -1
|
@@ -15,49 +15,28 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/ 'use client';
|
|
17
17
|
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
19
|
import { lockdownRefusalText, parseLockdownRefusal, PLATFORM_BRAND_NAME } from "@aglyn/aglyn";
|
|
20
20
|
import { trackEvent } from "@aglyn/aglyn/app-utils/analytics-events";
|
|
21
21
|
import { ICON_VARIANT_CLOSE } from "@aglyn/shared-data-enums";
|
|
22
|
-
import {
|
|
22
|
+
import { mdiCreation, mdiPageLayoutHeaderFooter } from "@aglyn/shared-data-mdi";
|
|
23
23
|
import { pluginDocsHelp } from "@aglyn/aglyn/app-utils/docs-help";
|
|
24
24
|
import { HelpTip, MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
25
|
-
import { OptionCardGrid } from "@aglyn/shared-ui-jsx/components/option-card-grid.component";
|
|
26
25
|
import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
27
26
|
import { useUser } from "@aglyn/tenant-feature-instance";
|
|
28
|
-
import { Alert, AppBar, Box, Button, Card, CardActionArea, Chip, CircularProgress, Container, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, IconButton,
|
|
29
|
-
import { alpha } from "@mui/material/styles";
|
|
27
|
+
import { Alert, AppBar, Box, Button, Card, CardActionArea, Chip, CircularProgress, Container, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, IconButton, Stack, Toolbar, Typography, useMediaQuery } from "@mui/material";
|
|
28
|
+
import { alpha, useTheme } from "@mui/material/styles";
|
|
30
29
|
import { useRouter } from "next/navigation";
|
|
31
30
|
import { useCallback, useEffect, useId, useRef, useState } from "react";
|
|
32
|
-
import { AI_JOB_AUTO_CONFIRM_INPUT, AI_SITE_FREE_PAGES,
|
|
31
|
+
import { AI_JOB_AUTO_CONFIRM_INPUT, AI_SITE_FREE_PAGES, aiFreeCreditsNoneLeftText, aiFreeCreditsResetLabel, aiFreeSiteCreditRange, aiFreeSitePrompt, aiSiteCreditRange, aiSitePagesBand } from "../model/ai-site-job.js";
|
|
33
32
|
import { FREE_AI_TASTE_CREDITS_PER_MONTH } from "../plan-entitlements.js";
|
|
34
33
|
import { AI_CREDITS_CONFIRM_CODE, aiCreditRangeText } from "../model/ai-credit-estimate.js";
|
|
35
34
|
import { AiCreditsPromptNotice } from "./ai-credits-prompt.component.js";
|
|
36
|
-
import { AI_SITE_START_ANSWERS,
|
|
37
|
-
import {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
professional: mdiScaleBalance.path,
|
|
42
|
-
wellness: mdiHeartPulse.path,
|
|
43
|
-
restaurant: mdiSilverwareForkKnife.path,
|
|
44
|
-
store: mdiShopping.path,
|
|
45
|
-
portfolio: mdiViewGridOutline.path,
|
|
46
|
-
studio: mdiPaletteOutline.path,
|
|
47
|
-
photography: mdiCamera.path,
|
|
48
|
-
blog: mdiBookOpenPageVariant.path,
|
|
49
|
-
events: mdiCalendarHeart.path,
|
|
50
|
-
fitness: mdiDumbbell.path,
|
|
51
|
-
yoga: mdiYoga.path,
|
|
52
|
-
beauty: mdiContentCut.path,
|
|
53
|
-
realestate: mdiHomeCity.path,
|
|
54
|
-
education: mdiSchool.path,
|
|
55
|
-
nonprofit: mdiHandHeart.path,
|
|
56
|
-
music: mdiMusic.path,
|
|
57
|
-
personal: mdiAccount.path,
|
|
58
|
-
landing: mdiRocketLaunch.path,
|
|
59
|
-
'coming-soon': mdiClockOutline.path
|
|
60
|
-
};
|
|
35
|
+
import { AI_SITE_START_ANSWERS, aiSiteStartBrief, aiSiteStartInputs, aiSiteStartRefusal } from "../model/ai-site-start.js";
|
|
36
|
+
import { aiSiteStartFieldErrors, aiSiteStartFirstInvalidStep, aiSiteStartNextStep, aiSiteStartPreviousStep, aiSiteStartStepErrors, AI_SITE_START_STEP_FIELDS } from "../model/ai-site-start-steps.js";
|
|
37
|
+
import { aiSiteKindOfInputs } from "../model/ai-site-kinds.js";
|
|
38
|
+
import { aiSiteStartClickOf, useAiSiteStartTracking } from "./ai-site-start-tracking.js";
|
|
39
|
+
import { AudienceStep, DetailsStep, KindStep, ReviewStep, StartProgress, StepHelp, StyleStep } from "./ai-site-start-steps.component.js";
|
|
61
40
|
import { AiJobFollow } from "./ai-job-follow.component.js";
|
|
62
41
|
import { AiModelSelector } from "./ai-model-selector.component.js";
|
|
63
42
|
import { useAiModelChoice } from "./use-ai-model-choice.js";
|
|
@@ -71,10 +50,6 @@ import { publishAiJob } from "./ai-jobs-store.js";
|
|
|
71
50
|
*/ export const AI_SITE_START_SURFACE_SX = {
|
|
72
51
|
bgcolor: 'background.default'
|
|
73
52
|
};
|
|
74
|
-
/** The two steps, as the indicator under the header names them. */ const STEP_LABELS = [
|
|
75
|
-
'Choose',
|
|
76
|
-
'Describe'
|
|
77
|
-
];
|
|
78
53
|
/** The soft round badge an icon sits in, in its accent's tint. */ function IconBadge({ accent, children }) {
|
|
79
54
|
return /*#__PURE__*/ _jsx(Box, {
|
|
80
55
|
"aria-hidden": true,
|
|
@@ -179,18 +154,6 @@ import { publishAiJob } from "./ai-jobs-store.js";
|
|
|
179
154
|
anchor: '#how-do-you-want-to-start',
|
|
180
155
|
excerpt: 'The starter site gives you a ready-made home page to edit. Start with AI asks a few questions, then plans, writes and publishes your pages.'
|
|
181
156
|
}),
|
|
182
|
-
business: pluginDocsHelp('aiStart', {
|
|
183
|
-
anchor: '#your-business',
|
|
184
|
-
excerpt: 'What kind of site it is picks its style and pages; who it is for is who every page and the contact form are written for.'
|
|
185
|
-
}),
|
|
186
|
-
style: pluginDocsHelp('aiSiteLooks', {
|
|
187
|
-
anchor: '#choose-a-style',
|
|
188
|
-
excerpt: 'The style decides the look — theme, colors, fonts, buttons — and which pages the site usually has. Every site gets its own variation.'
|
|
189
|
-
}),
|
|
190
|
-
details: pluginDocsHelp('aiStart', {
|
|
191
|
-
anchor: '#details',
|
|
192
|
-
excerpt: 'Where contact form messages go, how many pages to write, and on paid plans whether to draft a welcome email. All can be changed later.'
|
|
193
|
-
}),
|
|
194
157
|
estimate: pluginDocsHelp('aiCredits', {
|
|
195
158
|
anchor: '#before-a-job-starts',
|
|
196
159
|
excerpt: 'About what a start like this costs, measured on real builds, and the most it can cost. What it really costs is what each step spends, and you can watch that add up while it runs.'
|
|
@@ -217,7 +180,18 @@ function SectionLabel({ children, help }) {
|
|
|
217
180
|
]
|
|
218
181
|
});
|
|
219
182
|
}
|
|
220
|
-
|
|
183
|
+
/**
|
|
184
|
+
* The questions are one decision a step (AGL-3898): what kind of site it is
|
|
185
|
+
* (typed, or a card), who it is for, the style (cards that show each one,
|
|
186
|
+
* "Pick for me" first and picked), the details, and a review that plans the
|
|
187
|
+
* site (`ai-site-start-steps.component.tsx`). Back and Next keep every
|
|
188
|
+
* answer; Enter in a text answer is Next; each step's heading takes the focus
|
|
189
|
+
* when it is drawn; a step that cannot go forward says why beside the field
|
|
190
|
+
* and puts the cursor in it. The answers are the same object the single form
|
|
191
|
+
* held, and only the review turns them into the job, through the same
|
|
192
|
+
* `aiSiteStartBrief` and `aiSiteStartInputs`. Each step is reported as a
|
|
193
|
+
* funnel, with where people struggle (`ai-site-start-tracking.ts`).
|
|
194
|
+
*/ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leave, pendingSite, initialAnswers = null }) {
|
|
221
195
|
var _ref, _ref1, _aiFreeSitePrompt;
|
|
222
196
|
var _aiSiteKindOfInputs, _modelChoice_options_options_find, _modelChoice_options;
|
|
223
197
|
const { data: user } = useUser();
|
|
@@ -230,8 +204,21 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
230
204
|
const [verdict, setVerdict] = useState('checking');
|
|
231
205
|
// Read once: a start reopened on its answers stays one while it is open.
|
|
232
206
|
const reopened = useRef(initialAnswers !== null);
|
|
233
|
-
|
|
207
|
+
// A start reopened on its answers opens on the review, every answer there to change.
|
|
208
|
+
const [step, setStep] = useState(initialAnswers ? 'review' : 'choose');
|
|
234
209
|
const [answers, setAnswers] = useState(initialAnswers != null ? initialAnswers : AI_SITE_START_ANSWERS);
|
|
210
|
+
// The steps whose reasons not to go forward are shown: the ones Next was refused on.
|
|
211
|
+
const [checked, setChecked] = useState(()=>new Set());
|
|
212
|
+
// A step opened from the review's Edit goes back to the review on Next.
|
|
213
|
+
const [returnTo, setReturnTo] = useState(null);
|
|
214
|
+
// Each step's heading takes the focus when the step changes, never on the first draw.
|
|
215
|
+
const headingRef = useRef(null);
|
|
216
|
+
const drawnStep = useRef(null);
|
|
217
|
+
const fieldRefs = useRef({});
|
|
218
|
+
const theme = useTheme();
|
|
219
|
+
const compact = useMediaQuery(theme.breakpoints.down('sm'), {
|
|
220
|
+
noSsr: true
|
|
221
|
+
});
|
|
235
222
|
const [busy, setBusy] = useState(false);
|
|
236
223
|
// The starter card's own busy state while `startBlank` runs (AGL-3594).
|
|
237
224
|
const [startingStarter, setStartingStarter] = useState(false);
|
|
@@ -254,6 +241,8 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
254
241
|
const pendingRef = useRef(pendingSite);
|
|
255
242
|
pendingRef.current = pendingSite;
|
|
256
243
|
const creating = Boolean(pendingSite) && !(pendingSite == null ? void 0 : pendingSite.created);
|
|
244
|
+
// The funnel (AGL-3898): each step drawn, left and abandoned, and where people struggle.
|
|
245
|
+
const tracker = useAiSiteStartTracking(step, verdict === 'ready');
|
|
257
246
|
useEffect(()=>{
|
|
258
247
|
if (!orgId || !uid) return;
|
|
259
248
|
let active = true;
|
|
@@ -328,7 +317,7 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
328
317
|
// and the list is otherwise read when the picker opens.
|
|
329
318
|
const { load: loadModels, model: rememberedModel } = modelChoice;
|
|
330
319
|
useEffect(()=>{
|
|
331
|
-
if (!freeTaste && step === '
|
|
320
|
+
if (!freeTaste && step === 'review' && rememberedModel) loadModels();
|
|
332
321
|
}, [
|
|
333
322
|
freeTaste,
|
|
334
323
|
step,
|
|
@@ -425,6 +414,9 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
425
414
|
}
|
|
426
415
|
// The indicator and the launcher count it from the moment it exists.
|
|
427
416
|
publishAiJob(created);
|
|
417
|
+
// The funnel's last step: the site is started, and nothing after is leaving it.
|
|
418
|
+
tracker.complete();
|
|
419
|
+
tracker.finish();
|
|
428
420
|
// Where the next step is (AGL-3594): the site's "Building your site"
|
|
429
421
|
// page for this job. The zone closes without the starter first, so the
|
|
430
422
|
// setup page does not ask again behind it.
|
|
@@ -455,7 +447,8 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
455
447
|
router,
|
|
456
448
|
pickedModel,
|
|
457
449
|
pendingSite,
|
|
458
|
-
siteKind
|
|
450
|
+
siteKind,
|
|
451
|
+
tracker
|
|
459
452
|
]);
|
|
460
453
|
// The zone's `startBlank`. Before the site exists it creates it with the
|
|
461
454
|
// starter, and answers `false` when it could not — most often a name or
|
|
@@ -478,24 +471,96 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
478
471
|
trackEvent('site_start_choice', {
|
|
479
472
|
choice: 'starter'
|
|
480
473
|
});
|
|
474
|
+
// The starter is a way to start, not a way to leave: no abandonment after it.
|
|
475
|
+
tracker.finish();
|
|
481
476
|
runStartBlank();
|
|
482
477
|
}, [
|
|
483
478
|
pendingSite,
|
|
484
|
-
runStartBlank
|
|
479
|
+
runStartBlank,
|
|
480
|
+
tracker
|
|
485
481
|
]);
|
|
486
482
|
const chooseAi = useCallback(()=>{
|
|
487
483
|
if (pendingSite && !pendingSite.created && !pendingSite.check()) return;
|
|
488
484
|
trackEvent('site_start_choice', {
|
|
489
485
|
choice: 'ai'
|
|
490
486
|
});
|
|
491
|
-
|
|
487
|
+
tracker.complete();
|
|
488
|
+
setStep('kind');
|
|
489
|
+
}, [
|
|
490
|
+
pendingSite,
|
|
491
|
+
tracker
|
|
492
|
+
]);
|
|
493
|
+
// The heading of each step takes the focus as the step is drawn, so a
|
|
494
|
+
// keyboard and a screen reader start where the new question does.
|
|
495
|
+
useEffect(()=>{
|
|
496
|
+
var _headingRef_current;
|
|
497
|
+
if (verdict !== 'ready') return;
|
|
498
|
+
if (drawnStep.current !== null && drawnStep.current !== step) (_headingRef_current = headingRef.current) == null ? void 0 : _headingRef_current.focus();
|
|
499
|
+
drawnStep.current = step;
|
|
500
|
+
}, [
|
|
501
|
+
step,
|
|
502
|
+
verdict
|
|
503
|
+
]);
|
|
504
|
+
/** Forward from a question step, when its answers may go forward. */ const next = useCallback(()=>{
|
|
505
|
+
if (step === 'choose' || step === 'review') return;
|
|
506
|
+
const errors = aiSiteStartStepErrors(step, answers, {
|
|
507
|
+
freeTaste
|
|
508
|
+
});
|
|
509
|
+
if (errors.length) {
|
|
510
|
+
var _fieldRefs_current_errors__field;
|
|
511
|
+
setChecked((current)=>new Set(current).add(step));
|
|
512
|
+
for (const error of errors)tracker.fieldError(error.field, error.code);
|
|
513
|
+
(_fieldRefs_current_errors__field = fieldRefs.current[errors[0].field]) == null ? void 0 : _fieldRefs_current_errors__field.focus();
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
tracker.complete();
|
|
517
|
+
const target = returnTo != null ? returnTo : aiSiteStartNextStep(step);
|
|
518
|
+
setReturnTo(null);
|
|
519
|
+
// A review reached with an answer that cannot go forward opens on that answer instead.
|
|
520
|
+
if (target === 'review') {
|
|
521
|
+
const invalid = aiSiteStartFirstInvalidStep(answers, {
|
|
522
|
+
freeTaste
|
|
523
|
+
});
|
|
524
|
+
if (invalid && invalid !== 'review') {
|
|
525
|
+
setChecked((current)=>new Set(current).add(invalid));
|
|
526
|
+
setStep(invalid);
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (target) setStep(target);
|
|
531
|
+
}, [
|
|
532
|
+
step,
|
|
533
|
+
answers,
|
|
534
|
+
freeTaste,
|
|
535
|
+
returnTo,
|
|
536
|
+
tracker
|
|
537
|
+
]);
|
|
538
|
+
/** Back one step, keeping every answer. */ const back = useCallback(()=>{
|
|
539
|
+
const target = aiSiteStartPreviousStep(step);
|
|
540
|
+
if (!target) return;
|
|
541
|
+
tracker.back();
|
|
542
|
+
setReturnTo(null);
|
|
543
|
+
setStep(target);
|
|
492
544
|
}, [
|
|
493
|
-
|
|
545
|
+
step,
|
|
546
|
+
tracker
|
|
547
|
+
]);
|
|
548
|
+
/** From the review, to the step that asks an answer, and back to the review on Next. */ const edit = useCallback((target)=>{
|
|
549
|
+
tracker.back();
|
|
550
|
+
setReturnTo('review');
|
|
551
|
+
setStep(target);
|
|
552
|
+
}, [
|
|
553
|
+
tracker
|
|
494
554
|
]);
|
|
495
555
|
if (verdict !== 'ready') return null;
|
|
496
556
|
// Before a job is started Skip is the blank site, which writes the starter
|
|
497
557
|
// (AGL-3594); after, it only closes — the job builds the site.
|
|
498
558
|
const exit = started ? leave != null ? leave : runStartBlank : runStartBlank;
|
|
559
|
+
// Skip, as the header draws it: before a site is started it is leaving the questions.
|
|
560
|
+
const skip = ()=>{
|
|
561
|
+
if (!started) tracker.abandon('skip');
|
|
562
|
+
exit();
|
|
563
|
+
};
|
|
499
564
|
// Escape and the close control. Before "Create site" has made the site
|
|
500
565
|
// (AGL-3761) there is nothing to give a starter to, so they only close,
|
|
501
566
|
// and nothing is created; otherwise they are the same way out as Skip.
|
|
@@ -513,11 +578,16 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
513
578
|
if (root && target instanceof Node && !root.contains(target)) return;
|
|
514
579
|
}
|
|
515
580
|
if (drafted) setConfirmingLeave(true);
|
|
516
|
-
else
|
|
581
|
+
else closeTo();
|
|
582
|
+
};
|
|
583
|
+
// The dismissal itself, once nothing typed is in the way of it.
|
|
584
|
+
const closeTo = ()=>{
|
|
585
|
+
if (!started) tracker.abandon('close');
|
|
586
|
+
dismissTo();
|
|
517
587
|
};
|
|
518
588
|
const leaveDraft = ()=>{
|
|
519
589
|
setConfirmingLeave(false);
|
|
520
|
-
|
|
590
|
+
closeTo();
|
|
521
591
|
};
|
|
522
592
|
// The chosen model's cost against Auto's, as the model list states it.
|
|
523
593
|
const modelMultiplier = pickedModel && ((_modelChoice_options = modelChoice.options) == null ? void 0 : (_modelChoice_options_options_find = _modelChoice_options.options.find((option)=>option.id === pickedModel)) == null ? void 0 : _modelChoice_options_options_find.multiplier) || 1;
|
|
@@ -538,12 +608,71 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
538
608
|
// Free workspaces — never the month's whole allowance as if none were spent.
|
|
539
609
|
const estimateText = freeTaste ? freeCredits ? `${aiCreditRangeText(estimate)}. You have ${freeCredits.left.toLocaleString('en-US')} of your ${freeCredits.total.toLocaleString('en-US')} free AI credits left this month, until ${aiFreeCreditsResetLabel(freeCredits.resetsOn)}` : `${aiCreditRangeText(estimate)}, of the ${FREE_AI_TASTE_CREDITS_PER_MONTH} AI credits you get free each month` : `${aiCreditRangeText(estimate)}, estimated`;
|
|
540
610
|
const choosing = step === 'choose' && !started;
|
|
611
|
+
const reviewing = step === 'review' && !started;
|
|
612
|
+
const asking = step !== 'choose' && !started;
|
|
613
|
+
// Each answer's reason not to go forward, shown on a step once Next was refused there.
|
|
614
|
+
const fieldErrors = aiSiteStartFieldErrors(answers, {
|
|
615
|
+
freeTaste
|
|
616
|
+
});
|
|
617
|
+
const shownErrors = Object.fromEntries(AI_SITE_START_STEP_FIELDS[step].filter((field)=>checked.has(step) && fieldErrors[field]).map((field)=>[
|
|
618
|
+
field,
|
|
619
|
+
fieldErrors[field]
|
|
620
|
+
]));
|
|
621
|
+
const stepProps = {
|
|
622
|
+
answers,
|
|
623
|
+
answer,
|
|
624
|
+
tracker,
|
|
625
|
+
errors: shownErrors,
|
|
626
|
+
fieldRef: (field)=>(node)=>{
|
|
627
|
+
fieldRefs.current[field] = node;
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
const HEADINGS = {
|
|
631
|
+
choose: {
|
|
632
|
+
title: 'How do you want to start?',
|
|
633
|
+
lede: creating ? 'Name your site, then choose how it starts. You can change everything later.' : 'You can change everything later.'
|
|
634
|
+
},
|
|
635
|
+
kind: {
|
|
636
|
+
title: 'What are you building?',
|
|
637
|
+
lede: `Say it in a few words, or pick the closest. ${PLATFORM_BRAND_NAME} AI plans and writes your pages from it.`
|
|
638
|
+
},
|
|
639
|
+
audience: {
|
|
640
|
+
title: 'Who is it for?',
|
|
641
|
+
lede: 'The pages and the contact form are written for them.'
|
|
642
|
+
},
|
|
643
|
+
style: {
|
|
644
|
+
title: 'Choose a style',
|
|
645
|
+
lede: 'Each picture is an example home page in that style. Yours is written for your business, with its own colors and fonts within the style you pick.'
|
|
646
|
+
},
|
|
647
|
+
details: {
|
|
648
|
+
title: 'A few details',
|
|
649
|
+
lede: 'Where messages go, how many pages, and what else to draft. All can be changed later.'
|
|
650
|
+
},
|
|
651
|
+
review: {
|
|
652
|
+
title: 'Review your site',
|
|
653
|
+
lede: started ? `${PLATFORM_BRAND_NAME} AI is on it.` : `${PLATFORM_BRAND_NAME} AI plans and writes your pages from these answers, then publishes your site.`
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
const heading = HEADINGS[step];
|
|
657
|
+
// Enter in a text answer is Next. A select, a card or a button keeps its own Enter.
|
|
658
|
+
const onStepKeyDown = (event)=>{
|
|
659
|
+
if (event.key !== 'Enter' || event.nativeEvent.isComposing || !asking || reviewing) return;
|
|
660
|
+
const target = event.target;
|
|
661
|
+
if (target.tagName !== 'INPUT' || target.type === 'hidden') return;
|
|
662
|
+
event.preventDefault();
|
|
663
|
+
next();
|
|
664
|
+
};
|
|
541
665
|
return /*#__PURE__*/ _jsxs(Dialog, {
|
|
542
666
|
open: true,
|
|
543
667
|
fullScreen: true,
|
|
544
668
|
ref: dialogRef,
|
|
545
669
|
onClose: dismiss,
|
|
546
670
|
"aria-labelledby": TITLE_ID,
|
|
671
|
+
// Where people get lost (AGL-3898): any input puts off the idle signal,
|
|
672
|
+
// and every click is read for rage and dead clicks.
|
|
673
|
+
onClickCapture: (event)=>tracker.click(aiSiteStartClickOf(event)),
|
|
674
|
+
onKeyDownCapture: ()=>tracker.activity(),
|
|
675
|
+
onInputCapture: ()=>tracker.activity(),
|
|
547
676
|
// The console's own page surface, in both modes. A Dialog's paper sits
|
|
548
677
|
// at elevation 24 by default, and in dark mode MUI lightens an elevated
|
|
549
678
|
// paper with a white overlay, which turned the whole takeover a
|
|
@@ -561,6 +690,7 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
561
690
|
color: "inherit",
|
|
562
691
|
elevation: 0,
|
|
563
692
|
enableColorOnDark: true,
|
|
693
|
+
"data-start-area": "header",
|
|
564
694
|
sx: _extends({}, AI_SITE_START_SURFACE_SX, {
|
|
565
695
|
borderBottom: 1,
|
|
566
696
|
borderColor: 'divider'
|
|
@@ -593,7 +723,7 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
593
723
|
}),
|
|
594
724
|
/*#__PURE__*/ _jsx(Button, {
|
|
595
725
|
color: "inherit",
|
|
596
|
-
onClick:
|
|
726
|
+
onClick: skip,
|
|
597
727
|
"aria-label": started ? 'Close' : 'Skip and start blank',
|
|
598
728
|
children: started ? 'Close' : 'Skip'
|
|
599
729
|
})
|
|
@@ -607,8 +737,9 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
607
737
|
sm: 3
|
|
608
738
|
}
|
|
609
739
|
},
|
|
740
|
+
onKeyDown: onStepKeyDown,
|
|
610
741
|
children: /*#__PURE__*/ _jsx(Container, {
|
|
611
|
-
maxWidth: choosing ? 'md' : 'sm',
|
|
742
|
+
maxWidth: choosing || step === 'kind' || step === 'style' ? 'md' : 'sm',
|
|
612
743
|
disableGutters: true,
|
|
613
744
|
sx: {
|
|
614
745
|
py: {
|
|
@@ -619,30 +750,38 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
619
750
|
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
620
751
|
spacing: 4,
|
|
621
752
|
children: [
|
|
622
|
-
/*#__PURE__*/ _jsx(
|
|
623
|
-
activeStep: choosing ? 0 : 1,
|
|
624
|
-
"aria-label": choosing ? 'Step 1 of 2' : 'Step 2 of 2',
|
|
753
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
625
754
|
sx: {
|
|
626
|
-
maxWidth: (
|
|
755
|
+
maxWidth: (t)=>t.spacing(80),
|
|
627
756
|
width: '100%',
|
|
628
757
|
mx: 'auto'
|
|
629
758
|
},
|
|
630
|
-
children:
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
}, label))
|
|
759
|
+
children: /*#__PURE__*/ _jsx(StartProgress, {
|
|
760
|
+
step: step,
|
|
761
|
+
compact: compact
|
|
762
|
+
})
|
|
635
763
|
}),
|
|
636
764
|
/*#__PURE__*/ _jsxs(Stack, {
|
|
637
765
|
spacing: 1,
|
|
638
766
|
sx: {
|
|
639
767
|
textAlign: choosing ? 'center' : 'left'
|
|
640
768
|
},
|
|
769
|
+
"data-start-area": "heading",
|
|
641
770
|
children: [
|
|
642
771
|
/*#__PURE__*/ _jsx(Typography, {
|
|
772
|
+
ref: headingRef,
|
|
773
|
+
tabIndex: -1,
|
|
643
774
|
variant: "h4",
|
|
644
775
|
component: "h1",
|
|
645
|
-
|
|
776
|
+
sx: {
|
|
777
|
+
'&:focus': {
|
|
778
|
+
outline: 'none'
|
|
779
|
+
},
|
|
780
|
+
'&:focus-visible': {
|
|
781
|
+
outline: 'none'
|
|
782
|
+
}
|
|
783
|
+
},
|
|
784
|
+
children: heading.title
|
|
646
785
|
}),
|
|
647
786
|
/*#__PURE__*/ _jsxs(Typography, {
|
|
648
787
|
variant: "body1",
|
|
@@ -652,18 +791,22 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
652
791
|
sx: {
|
|
653
792
|
float: 'right'
|
|
654
793
|
}
|
|
655
|
-
}, START_HELP.choose)) :
|
|
656
|
-
|
|
794
|
+
}, START_HELP.choose)) : /*#__PURE__*/ _jsx(StepHelp, {
|
|
795
|
+
step: step
|
|
796
|
+
}),
|
|
797
|
+
heading.lede
|
|
657
798
|
]
|
|
658
799
|
})
|
|
659
800
|
]
|
|
660
801
|
}),
|
|
661
802
|
notice && /*#__PURE__*/ _jsx(Alert, {
|
|
662
803
|
severity: "info",
|
|
804
|
+
"data-start-area": "notice",
|
|
663
805
|
children: notice
|
|
664
806
|
}),
|
|
665
|
-
|
|
807
|
+
asking && noneLeft && freeCredits && /*#__PURE__*/ _jsx(Alert, {
|
|
666
808
|
severity: "warning",
|
|
809
|
+
"data-start-area": "notice",
|
|
667
810
|
action: orgSlug ? /*#__PURE__*/ _jsx(Button, {
|
|
668
811
|
color: "inherit",
|
|
669
812
|
size: "small",
|
|
@@ -672,19 +815,6 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
672
815
|
}) : undefined,
|
|
673
816
|
children: aiFreeCreditsNoneLeftText(freeCredits.resetsOn)
|
|
674
817
|
}),
|
|
675
|
-
step === 'describe' && !started && !noneLeft && prompt && /*#__PURE__*/ _jsx(AiCreditsPromptNotice, {
|
|
676
|
-
prompt: prompt,
|
|
677
|
-
noun: "site",
|
|
678
|
-
orgSlug: orgSlug,
|
|
679
|
-
busy: busy,
|
|
680
|
-
onBuildWhatFits: ()=>void plan({
|
|
681
|
-
creditsConfirmed: true
|
|
682
|
-
}),
|
|
683
|
-
onSmaller: ()=>void plan({
|
|
684
|
-
creditsConfirmed: true,
|
|
685
|
-
pages: 1
|
|
686
|
-
})
|
|
687
|
-
}),
|
|
688
818
|
choosing && creating && pendingSite ? /*#__PURE__*/ _jsxs(Stack, {
|
|
689
819
|
spacing: 2,
|
|
690
820
|
component: "section",
|
|
@@ -697,6 +827,7 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
697
827
|
]
|
|
698
828
|
}) : null,
|
|
699
829
|
choosing ? /*#__PURE__*/ _jsxs(Box, {
|
|
830
|
+
"data-start-area": "choose-cards",
|
|
700
831
|
sx: {
|
|
701
832
|
display: 'grid',
|
|
702
833
|
gridTemplateColumns: {
|
|
@@ -754,153 +885,33 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
754
885
|
// Full screen: AI jobs opens in the panel this dialog covers.
|
|
755
886
|
onOpenJobs: exit
|
|
756
887
|
})
|
|
757
|
-
}) : /*#__PURE__*/ _jsxs(
|
|
888
|
+
}) : /*#__PURE__*/ _jsxs(Box, {
|
|
889
|
+
component: "section",
|
|
758
890
|
children: [
|
|
759
|
-
/*#__PURE__*/
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
gap: 1
|
|
784
|
-
},
|
|
785
|
-
children: AI_SITE_START_TYPES.map((type)=>/*#__PURE__*/ _jsx(Chip, {
|
|
786
|
-
label: type,
|
|
787
|
-
size: "small",
|
|
788
|
-
color: answers.siteType === type ? 'primary' : 'default',
|
|
789
|
-
variant: answers.siteType === type ? 'filled' : 'outlined',
|
|
790
|
-
onClick: ()=>answer({
|
|
791
|
-
siteType: type
|
|
792
|
-
})
|
|
793
|
-
}, type))
|
|
794
|
-
}),
|
|
795
|
-
/*#__PURE__*/ _jsx(TextField, {
|
|
796
|
-
fullWidth: true,
|
|
797
|
-
label: "Who is it for?",
|
|
798
|
-
placeholder: "local dog owners who want a regular groom booked online",
|
|
799
|
-
value: answers.audience,
|
|
800
|
-
onChange: (event)=>answer({
|
|
801
|
-
audience: event.target.value
|
|
802
|
-
}),
|
|
803
|
-
helperText: "Optional. It narrows who the pages are written for."
|
|
804
|
-
})
|
|
805
|
-
]
|
|
806
|
-
}),
|
|
807
|
-
/*#__PURE__*/ _jsxs(Stack, {
|
|
808
|
-
spacing: 2,
|
|
809
|
-
component: "section",
|
|
810
|
-
"aria-label": "Style",
|
|
811
|
-
children: [
|
|
812
|
-
/*#__PURE__*/ _jsx(SectionLabel, {
|
|
813
|
-
help: START_HELP.style,
|
|
814
|
-
children: 'Style'
|
|
815
|
-
}),
|
|
816
|
-
/*#__PURE__*/ _jsx(Typography, {
|
|
817
|
-
variant: "body2",
|
|
818
|
-
color: "text.secondary",
|
|
819
|
-
children: answers.kind ? 'This decides how your site looks and which pages it usually has.' : 'Picked from your answer above. Choose another to change how your site looks and which pages it usually has.'
|
|
820
|
-
}),
|
|
821
|
-
/*#__PURE__*/ _jsx(OptionCardGrid, {
|
|
822
|
-
label: "Style of site",
|
|
823
|
-
options: AI_SITE_KINDS.map((kind)=>({
|
|
824
|
-
id: kind.id,
|
|
825
|
-
title: kind.label,
|
|
826
|
-
description: kind.blurb,
|
|
827
|
-
icon: AI_SITE_KIND_ICONS[kind.id]
|
|
828
|
-
})),
|
|
829
|
-
value: aiSiteStartKind(answers).id,
|
|
830
|
-
onChange: (kind)=>answer({
|
|
831
|
-
kind
|
|
832
|
-
})
|
|
833
|
-
})
|
|
834
|
-
]
|
|
835
|
-
}),
|
|
836
|
-
/*#__PURE__*/ _jsxs(Stack, {
|
|
837
|
-
spacing: 2,
|
|
838
|
-
component: "section",
|
|
839
|
-
"aria-label": "Details",
|
|
840
|
-
children: [
|
|
841
|
-
/*#__PURE__*/ _jsx(SectionLabel, {
|
|
842
|
-
help: START_HELP.details,
|
|
843
|
-
children: 'Details'
|
|
844
|
-
}),
|
|
845
|
-
/*#__PURE__*/ _jsx(TextField, {
|
|
846
|
-
select: true,
|
|
847
|
-
fullWidth: true,
|
|
848
|
-
label: "Where do form submissions go?",
|
|
849
|
-
value: answers.submissions,
|
|
850
|
-
onChange: (event)=>answer({
|
|
851
|
-
submissions: event.target.value
|
|
852
|
-
}),
|
|
853
|
-
helperText: "You can change this on the form itself afterwards.",
|
|
854
|
-
children: AI_SITE_SUBMISSION_CHOICES.map((option)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
855
|
-
value: option.id,
|
|
856
|
-
children: `${option.label} — ${option.blurb}`
|
|
857
|
-
}, option.id))
|
|
858
|
-
}),
|
|
859
|
-
/*#__PURE__*/ _jsxs(Stack, {
|
|
860
|
-
direction: {
|
|
861
|
-
xs: 'column',
|
|
862
|
-
sm: 'row'
|
|
863
|
-
},
|
|
864
|
-
spacing: 2,
|
|
865
|
-
children: [
|
|
866
|
-
/*#__PURE__*/ _jsx(TextField, {
|
|
867
|
-
select: true,
|
|
868
|
-
fullWidth: true,
|
|
869
|
-
label: "Pages",
|
|
870
|
-
value: answers.pages,
|
|
871
|
-
onChange: (event)=>answer({
|
|
872
|
-
pages: Number(event.target.value)
|
|
873
|
-
}),
|
|
874
|
-
helperText: freeTaste ? AI_SITE_FREE_PAGES_NOTE : undefined,
|
|
875
|
-
children: Array.from({
|
|
876
|
-
length: band.max - band.min + 1
|
|
877
|
-
}, (_, index)=>band.min + index).map((count)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
878
|
-
value: count,
|
|
879
|
-
children: count
|
|
880
|
-
}, count))
|
|
881
|
-
}),
|
|
882
|
-
!freeTaste && /*#__PURE__*/ _jsxs(TextField, {
|
|
883
|
-
select: true,
|
|
884
|
-
fullWidth: true,
|
|
885
|
-
label: "Welcome email",
|
|
886
|
-
value: answers.welcomeEmail ? 'yes' : 'no',
|
|
887
|
-
onChange: (event)=>answer({
|
|
888
|
-
welcomeEmail: event.target.value === 'yes'
|
|
889
|
-
}),
|
|
890
|
-
children: [
|
|
891
|
-
/*#__PURE__*/ _jsx(MenuItem, {
|
|
892
|
-
value: "yes",
|
|
893
|
-
children: 'Draft one'
|
|
894
|
-
}),
|
|
895
|
-
/*#__PURE__*/ _jsx(MenuItem, {
|
|
896
|
-
value: "no",
|
|
897
|
-
children: 'No'
|
|
898
|
-
})
|
|
899
|
-
]
|
|
900
|
-
})
|
|
901
|
-
]
|
|
902
|
-
})
|
|
903
|
-
]
|
|
891
|
+
step === 'kind' && /*#__PURE__*/ _jsx(KindStep, _extends({}, stepProps)),
|
|
892
|
+
step === 'audience' && /*#__PURE__*/ _jsx(AudienceStep, _extends({}, stepProps)),
|
|
893
|
+
step === 'style' && /*#__PURE__*/ _jsx(StyleStep, _extends({}, stepProps)),
|
|
894
|
+
step === 'details' && /*#__PURE__*/ _jsx(DetailsStep, _extends({}, stepProps, {
|
|
895
|
+
freeTaste: freeTaste,
|
|
896
|
+
band: band
|
|
897
|
+
})),
|
|
898
|
+
step === 'review' && /*#__PURE__*/ _jsx(ReviewStep, {
|
|
899
|
+
answers: answers,
|
|
900
|
+
freeTaste: freeTaste,
|
|
901
|
+
onEdit: edit,
|
|
902
|
+
children: !noneLeft && prompt && /*#__PURE__*/ _jsx(AiCreditsPromptNotice, {
|
|
903
|
+
prompt: prompt,
|
|
904
|
+
noun: "site",
|
|
905
|
+
orgSlug: orgSlug,
|
|
906
|
+
busy: busy,
|
|
907
|
+
onBuildWhatFits: ()=>void plan({
|
|
908
|
+
creditsConfirmed: true
|
|
909
|
+
}),
|
|
910
|
+
onSmaller: ()=>void plan({
|
|
911
|
+
creditsConfirmed: true,
|
|
912
|
+
pages: 1
|
|
913
|
+
})
|
|
914
|
+
})
|
|
904
915
|
})
|
|
905
916
|
]
|
|
906
917
|
})
|
|
@@ -908,8 +919,9 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
908
919
|
})
|
|
909
920
|
})
|
|
910
921
|
}),
|
|
911
|
-
|
|
922
|
+
asking && /* The footer stays put while the questions scroll. It wraps, because
|
|
912
923
|
the estimate, the reason and the buttons are wider than a phone. */ /*#__PURE__*/ _jsxs(DialogActions, {
|
|
924
|
+
"data-start-area": "footer",
|
|
913
925
|
sx: _extends({
|
|
914
926
|
px: {
|
|
915
927
|
xs: 2,
|
|
@@ -923,7 +935,7 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
923
935
|
borderColor: 'divider'
|
|
924
936
|
}, AI_SITE_START_SURFACE_SX),
|
|
925
937
|
children: [
|
|
926
|
-
/*#__PURE__*/ _jsxs(Stack, {
|
|
938
|
+
reviewing && /*#__PURE__*/ _jsxs(Stack, {
|
|
927
939
|
direction: "row",
|
|
928
940
|
spacing: 0.5,
|
|
929
941
|
sx: {
|
|
@@ -942,20 +954,23 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
942
954
|
}))
|
|
943
955
|
]
|
|
944
956
|
}),
|
|
945
|
-
refusal && /*#__PURE__*/ _jsx(Typography, {
|
|
957
|
+
reviewing && refusal && /*#__PURE__*/ _jsx(Typography, {
|
|
946
958
|
variant: "body2",
|
|
947
959
|
color: "text.secondary",
|
|
948
960
|
children: refusal
|
|
949
961
|
}),
|
|
950
|
-
!freeTaste && /*#__PURE__*/ _jsx(AiModelSelector, {
|
|
962
|
+
reviewing && !freeTaste && /*#__PURE__*/ _jsx(AiModelSelector, {
|
|
951
963
|
choice: modelChoice,
|
|
952
964
|
disabled: busy
|
|
953
965
|
}),
|
|
954
966
|
/*#__PURE__*/ _jsx(Button, {
|
|
955
|
-
onClick:
|
|
967
|
+
onClick: back,
|
|
968
|
+
sx: reviewing ? undefined : {
|
|
969
|
+
mr: 'auto'
|
|
970
|
+
},
|
|
956
971
|
children: 'Back'
|
|
957
972
|
}),
|
|
958
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
973
|
+
reviewing ? /*#__PURE__*/ _jsx(Button, {
|
|
959
974
|
variant: "contained",
|
|
960
975
|
size: "large",
|
|
961
976
|
disabled: busy || Boolean(refusal) || Boolean(prompt) || noneLeft,
|
|
@@ -964,6 +979,11 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
964
979
|
path: mdiCreation.path
|
|
965
980
|
}),
|
|
966
981
|
children: busy ? 'Starting…' : 'Plan my site'
|
|
982
|
+
}) : /*#__PURE__*/ _jsx(Button, {
|
|
983
|
+
variant: "contained",
|
|
984
|
+
size: "large",
|
|
985
|
+
onClick: next,
|
|
986
|
+
children: returnTo === 'review' ? 'Back to review' : 'Next'
|
|
967
987
|
})
|
|
968
988
|
]
|
|
969
989
|
}),
|