@aglyn/plugins-ai 1.0.0-beta.271 → 1.0.0-beta.273

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.
Files changed (132) hide show
  1. package/package.json +17 -17
  2. package/src/lib/activity/ai-activity-actions.d.ts +4 -3
  3. package/src/lib/activity/ai-activity-actions.js +3 -0
  4. package/src/lib/activity/ai-activity-actions.js.map +1 -1
  5. package/src/lib/components/ai-site-build-page.component.js +18 -0
  6. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  7. package/src/lib/components/ai-site-import-job.component.d.ts +41 -0
  8. package/src/lib/components/ai-site-import-job.component.js +707 -0
  9. package/src/lib/components/ai-site-import-job.component.js.map +1 -0
  10. package/src/lib/components/ai-site-import-start.component.d.ts +64 -0
  11. package/src/lib/components/ai-site-import-start.component.js +335 -0
  12. package/src/lib/components/ai-site-import-start.component.js.map +1 -0
  13. package/src/lib/components/ai-site-ownership-proof.component.d.ts +42 -0
  14. package/src/lib/components/ai-site-ownership-proof.component.js +353 -0
  15. package/src/lib/components/ai-site-ownership-proof.component.js.map +1 -0
  16. package/src/lib/components/ai-site-start-card.component.js +329 -252
  17. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  18. package/src/lib/jobs/ai-empty-site-sweep.d.ts +12 -1
  19. package/src/lib/jobs/ai-empty-site-sweep.js +15 -3
  20. package/src/lib/jobs/ai-empty-site-sweep.js.map +1 -1
  21. package/src/lib/jobs/ai-job-drafts.d.ts +14 -0
  22. package/src/lib/jobs/ai-job-drafts.js +24 -0
  23. package/src/lib/jobs/ai-job-drafts.js.map +1 -1
  24. package/src/lib/jobs/ai-job-import-step.d.ts +136 -0
  25. package/src/lib/jobs/ai-job-import-step.js +809 -0
  26. package/src/lib/jobs/ai-job-import-step.js.map +1 -0
  27. package/src/lib/jobs/ai-job-page-language.d.ts +39 -1
  28. package/src/lib/jobs/ai-job-page-language.js +62 -4
  29. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  30. package/src/lib/jobs/ai-job-page-step.d.ts +2 -2
  31. package/src/lib/jobs/ai-job-page-step.js +26 -4
  32. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  33. package/src/lib/jobs/ai-job-seo-step.js +8 -4
  34. package/src/lib/jobs/ai-job-seo-step.js.map +1 -1
  35. package/src/lib/jobs/ai-job-site-datasets.d.ts +39 -1
  36. package/src/lib/jobs/ai-job-site-datasets.js +111 -15
  37. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  38. package/src/lib/jobs/ai-job-site-step.d.ts +12 -3
  39. package/src/lib/jobs/ai-job-site-step.js +85 -11
  40. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  41. package/src/lib/jobs/ai-job-text-step.d.ts +15 -0
  42. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  43. package/src/lib/jobs/ai-jobs.d.ts +8 -0
  44. package/src/lib/jobs/ai-jobs.js +19 -3
  45. package/src/lib/jobs/ai-jobs.js.map +1 -1
  46. package/src/lib/jobs/ai-layout-owner-photos.d.ts +16 -1
  47. package/src/lib/jobs/ai-layout-owner-photos.js +49 -2
  48. package/src/lib/jobs/ai-layout-owner-photos.js.map +1 -1
  49. package/src/lib/jobs/ai-layout-stock-photos.d.ts +35 -0
  50. package/src/lib/jobs/ai-layout-stock-photos.js +114 -43
  51. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  52. package/src/lib/jobs/ai-site-late-photos.d.ts +143 -0
  53. package/src/lib/jobs/ai-site-late-photos.js +486 -0
  54. package/src/lib/jobs/ai-site-late-photos.js.map +1 -0
  55. package/src/lib/jobs/ai-site-publish.d.ts +18 -0
  56. package/src/lib/jobs/ai-site-publish.js +123 -5
  57. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  58. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +61 -3
  59. package/src/lib/jobs/ai-theme-brand-inputs.js +117 -27
  60. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
  61. package/src/lib/jobs/fixtures/ai-site-late-photos-laurel-fork.d.ts +83 -0
  62. package/src/lib/jobs/fixtures/ai-site-late-photos-laurel-fork.js +1553 -0
  63. package/src/lib/jobs/fixtures/ai-site-late-photos-laurel-fork.js.map +1 -0
  64. package/src/lib/layout-language/ai-layout-pictures.d.ts +50 -13
  65. package/src/lib/layout-language/ai-layout-pictures.js +81 -19
  66. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
  67. package/src/lib/model/ai-credit-estimate.d.ts +20 -0
  68. package/src/lib/model/ai-credit-estimate.js +13 -0
  69. package/src/lib/model/ai-credit-estimate.js.map +1 -1
  70. package/src/lib/model/ai-job-activity.d.ts +2 -2
  71. package/src/lib/model/ai-job-activity.js +6 -4
  72. package/src/lib/model/ai-job-activity.js.map +1 -1
  73. package/src/lib/model/ai-job-notice.js +18 -4
  74. package/src/lib/model/ai-job-notice.js.map +1 -1
  75. package/src/lib/model/ai-jobs.types.d.ts +39 -2
  76. package/src/lib/model/ai-jobs.types.js +2 -1
  77. package/src/lib/model/ai-jobs.types.js.map +1 -1
  78. package/src/lib/model/ai-site-import-view.d.ts +130 -0
  79. package/src/lib/model/ai-site-import-view.js +182 -0
  80. package/src/lib/model/ai-site-import-view.js.map +1 -0
  81. package/src/lib/model/ai-site-import.d.ts +302 -0
  82. package/src/lib/model/ai-site-import.js +526 -0
  83. package/src/lib/model/ai-site-import.js.map +1 -0
  84. package/src/lib/model/ai-site-photos.d.ts +119 -0
  85. package/src/lib/model/ai-site-photos.js +128 -0
  86. package/src/lib/model/ai-site-photos.js.map +1 -0
  87. package/src/lib/model/ai-site-start.d.ts +22 -9
  88. package/src/lib/model/ai-site-start.js +64 -23
  89. package/src/lib/model/ai-site-start.js.map +1 -1
  90. package/src/lib/runtime/ai-doctrine-validators.d.ts +3 -1
  91. package/src/lib/runtime/ai-doctrine-validators.js +3 -1
  92. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  93. package/src/lib/runtime/seo-fields.d.ts +29 -4
  94. package/src/lib/runtime/seo-fields.js +58 -11
  95. package/src/lib/runtime/seo-fields.js.map +1 -1
  96. package/src/lib/server/ai-jobs-route.js +11 -0
  97. package/src/lib/server/ai-jobs-route.js.map +1 -1
  98. package/src/lib/server/ai-site-import-route.d.ts +89 -0
  99. package/src/lib/server/ai-site-import-route.js +356 -0
  100. package/src/lib/server/ai-site-import-route.js.map +1 -0
  101. package/src/lib/server.js +14 -0
  102. package/src/lib/server.js.map +1 -1
  103. package/src/lib/site-import/fixtures/site-import-crawl-recordings.d.ts +45 -0
  104. package/src/lib/site-import/fixtures/site-import-crawl-recordings.js +313 -0
  105. package/src/lib/site-import/fixtures/site-import-crawl-recordings.js.map +1 -0
  106. package/src/lib/site-import/fixtures/site-import-wave-recordings.d.ts +50 -0
  107. package/src/lib/site-import/fixtures/site-import-wave-recordings.js +217 -0
  108. package/src/lib/site-import/fixtures/site-import-wave-recordings.js.map +1 -0
  109. package/src/lib/site-import/site-import-crawl.d.ts +163 -0
  110. package/src/lib/site-import/site-import-crawl.js +467 -0
  111. package/src/lib/site-import/site-import-crawl.js.map +1 -0
  112. package/src/lib/site-import/site-import-flag.d.ts +23 -0
  113. package/src/lib/site-import/site-import-flag.js +23 -0
  114. package/src/lib/site-import/site-import-flag.js.map +1 -0
  115. package/src/lib/site-import/site-import-html.d.ts +94 -0
  116. package/src/lib/site-import/site-import-html.js +462 -0
  117. package/src/lib/site-import/site-import-html.js.map +1 -0
  118. package/src/lib/site-import/site-import-images.d.ts +54 -0
  119. package/src/lib/site-import/site-import-images.js +204 -0
  120. package/src/lib/site-import/site-import-images.js.map +1 -0
  121. package/src/lib/site-import/site-import-page.d.ts +48 -0
  122. package/src/lib/site-import/site-import-page.js +150 -0
  123. package/src/lib/site-import/site-import-page.js.map +1 -0
  124. package/src/lib/site-import/site-import-review.d.ts +40 -0
  125. package/src/lib/site-import/site-import-review.js +149 -0
  126. package/src/lib/site-import/site-import-review.js.map +1 -0
  127. package/src/lib/site-import/site-import-robots.d.ts +52 -0
  128. package/src/lib/site-import/site-import-robots.js +126 -0
  129. package/src/lib/site-import/site-import-robots.js.map +1 -0
  130. package/src/lib/tools/ai-seo-tool.d.ts +25 -1
  131. package/src/lib/tools/ai-seo-tool.js +61 -0
  132. package/src/lib/tools/ai-seo-tool.js.map +1 -1
@@ -19,9 +19,11 @@ 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 { mdiCreation, mdiPageLayoutHeaderFooter } from "@aglyn/shared-data-mdi";
22
+ import { mdiCreation, mdiPageLayoutHeaderFooter, mdiWebSync } 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 BlockedControl from "@aglyn/shared-ui-jsx/components/blocked-control.component";
26
+ import { PrerequisiteNotice } from "@aglyn/shared-ui-jsx/components/prerequisite-notice.component";
25
27
  import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
26
28
  import { useUser } from "@aglyn/tenant-feature-instance";
27
29
  import { Alert, AppBar, Box, Button, Card, CardActionArea, Chip, CircularProgress, Container, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, IconButton, Stack, Toolbar, Typography, useMediaQuery } from "@mui/material";
@@ -44,6 +46,8 @@ import { useAiModelChoice } from "./use-ai-model-choice.js";
44
46
  import { aiCreditsBillingHref, aiSiteBuildHref } from "./ai-job-links.js";
45
47
  import { publishAiJob } from "./ai-jobs-store.js";
46
48
  import { clearAiSiteStartAnswers, readAiSiteStartAnswers } from "../model/ai-site-start-handoff.js";
49
+ import { AiSiteImportStart } from "./ai-site-import-start.component.js";
50
+ import { aiSiteImportOfferOf } from "../model/ai-site-import-view.js";
47
51
  /** Labels the dialog for a reader, from its own heading. */ const TITLE_ID = 'ai-site-start-title';
48
52
  /**
49
53
  * The takeover's surface, for its paper, its bar and its footer alike: the
@@ -72,7 +76,7 @@ import { clearAiSiteStartAnswers, readAiSiteStartAnswers } from "../model/ai-sit
72
76
  /**
73
77
  * One way to start, as a card the whole of which is the button. Its accessible
74
78
  * name is its title; its description describes it.
75
- */ function ChoiceCard({ accent, icon, iconId, title, description, busy = false, onChoose, children }) {
79
+ */ function ChoiceCard({ accent, icon, iconId, title, description, busy = false, blocked = null, onChoose, children }) {
76
80
  const id = useId();
77
81
  return /*#__PURE__*/ _jsx(Card, {
78
82
  variant: "outlined",
@@ -98,52 +102,57 @@ import { clearAiSiteStartAnswers, readAiSiteStartAnswers } from "../model/ai-sit
98
102
  }
99
103
  }
100
104
  }),
101
- children: /*#__PURE__*/ _jsx(CardActionArea, {
102
- onClick: onChoose,
103
- disabled: busy,
104
- "aria-labelledby": `${id}-title`,
105
- "aria-describedby": `${id}-description`,
106
- "aria-busy": busy || undefined,
107
- sx: {
108
- height: '100%',
109
- p: {
110
- xs: 3,
111
- sm: 4
112
- }
113
- },
114
- children: /*#__PURE__*/ _jsxs(Stack, {
115
- spacing: 2,
105
+ children: /*#__PURE__*/ _jsx(BlockedControl, {
106
+ blocked: Boolean(blocked),
107
+ reason: blocked != null ? blocked : '',
108
+ fullWidth: true,
109
+ children: /*#__PURE__*/ _jsx(CardActionArea, {
110
+ onClick: onChoose,
111
+ disabled: busy,
112
+ "aria-labelledby": `${id}-title`,
113
+ "aria-describedby": `${id}-description`,
114
+ "aria-busy": busy || undefined,
116
115
  sx: {
117
- alignItems: 'center',
118
- textAlign: 'center'
116
+ height: '100%',
117
+ p: {
118
+ xs: 3,
119
+ sm: 4
120
+ }
119
121
  },
120
- children: [
121
- /*#__PURE__*/ _jsx(IconBadge, {
122
- accent: accent,
123
- children: busy ? /*#__PURE__*/ _jsx(CircularProgress, {
124
- size: "1em",
125
- color: accent,
126
- "aria-label": `${title}…`
127
- }) : /*#__PURE__*/ _jsx(MdiIcon, {
128
- path: icon,
129
- "data-icon": iconId,
130
- "aria-hidden": true
131
- })
132
- }),
133
- /*#__PURE__*/ _jsx(Typography, {
134
- id: `${id}-title`,
135
- variant: "h6",
136
- component: "h2",
137
- children: title
138
- }),
139
- /*#__PURE__*/ _jsx(Typography, {
140
- id: `${id}-description`,
141
- variant: "body2",
142
- color: "text.secondary",
143
- children: description
144
- }),
145
- children
146
- ]
122
+ children: /*#__PURE__*/ _jsxs(Stack, {
123
+ spacing: 2,
124
+ sx: {
125
+ alignItems: 'center',
126
+ textAlign: 'center'
127
+ },
128
+ children: [
129
+ /*#__PURE__*/ _jsx(IconBadge, {
130
+ accent: accent,
131
+ children: busy ? /*#__PURE__*/ _jsx(CircularProgress, {
132
+ size: "1em",
133
+ color: accent,
134
+ "aria-label": `${title}…`
135
+ }) : /*#__PURE__*/ _jsx(MdiIcon, {
136
+ path: icon,
137
+ "data-icon": iconId,
138
+ "aria-hidden": true
139
+ })
140
+ }),
141
+ /*#__PURE__*/ _jsx(Typography, {
142
+ id: `${id}-title`,
143
+ variant: "h6",
144
+ component: "h2",
145
+ children: title
146
+ }),
147
+ /*#__PURE__*/ _jsx(Typography, {
148
+ id: `${id}-description`,
149
+ variant: "body2",
150
+ color: "text.secondary",
151
+ children: description
152
+ }),
153
+ children
154
+ ]
155
+ })
147
156
  })
148
157
  })
149
158
  });
@@ -263,12 +272,19 @@ function SectionLabel({ children, help }) {
263
272
  const creating = Boolean(pendingSite) && !(pendingSite == null ? void 0 : pendingSite.created);
264
273
  // The funnel (AGL-3898): each step drawn, left and abandoned, and where people struggle.
265
274
  const tracker = useAiSiteStartTracking(step, verdict === 'ready');
275
+ // "Bring my site" (AGL-3976): asked of its own door, absent while its flag
276
+ // is off, drawn disabled with the reason where the workspace can change it.
277
+ const [importAvailability, setImportAvailability] = useState({
278
+ state: 'checking'
279
+ });
280
+ const [importing, setImporting] = useState(false);
266
281
  useEffect(()=>{
267
282
  if (!orgId || !uid) return;
268
283
  let active = true;
269
284
  void (async ()=>{
270
285
  try {
271
- const response = await authorizedFetch(userRef.current, `/api/ai/jobs?orgId=${encodeURIComponent(orgId)}&limit=1`);
286
+ const response = await authorizedFetch(userRef.current, // `siteImport=1`: whether "Bring my site" is offered here (AGL-3976), on the same read.
287
+ `/api/ai/jobs?orgId=${encodeURIComponent(orgId)}&limit=1&siteImport=1`);
272
288
  const payload = response.ok ? await response.json().catch(()=>null) : null;
273
289
  if (active) {
274
290
  var // "Create site" shows its own dialog when this one will not draw.
@@ -285,6 +301,7 @@ function SectionLabel({ children, help }) {
285
301
  }));
286
302
  }
287
303
  const shown = response.status !== 404 && response.status !== 403;
304
+ setImportAvailability(aiSiteImportOfferOf(payload == null ? void 0 : payload.siteImport));
288
305
  setVerdict(shown ? 'ready' : 'hidden');
289
306
  (_pendingRef_current = pendingRef.current) == null ? void 0 : _pendingRef_current.ready(shown);
290
307
  (_clientBuildRef_current = clientBuildRef.current) == null ? void 0 : (_clientBuildRef_current_ready = _clientBuildRef_current.ready) == null ? void 0 : _clientBuildRef_current_ready.call(_clientBuildRef_current, shown);
@@ -377,8 +394,9 @@ function SectionLabel({ children, help }) {
377
394
  hostId: siteId,
378
395
  kind: 'site',
379
396
  // A client build's intake rides along (AGL-3958): the name and
380
- // towns as the inputs the questions leave empty, and how to reach
381
- // the business, its hours and the owner's words in the brief.
397
+ // towns as the inputs the questions leave empty (the towns only
398
+ // while no address is given, AGL-3995), and how to reach the
399
+ // business, its hours and the owner's words in the brief.
382
400
  brief: [
383
401
  aiSiteStartBrief(asked),
384
402
  clientIntake ? aiSiteStartClientBrief(clientIntake) : ''
@@ -388,7 +406,7 @@ function SectionLabel({ children, help }) {
388
406
  // The sites they like go only while the start asks for them (AGL-3975).
389
407
  inputs: _extends({}, aiSiteStartInputs(siteInspiration ? asked : _extends({}, asked, {
390
408
  inspiration: []
391
- })), clientIntake ? aiSiteStartClientInputs(clientIntake) : {}, {
409
+ })), clientIntake ? aiSiteStartClientInputs(clientIntake, asked) : {}, {
392
410
  [AI_JOB_AUTO_CONFIRM_INPUT]: true
393
411
  })
394
412
  }, pickedModel ? {
@@ -533,6 +551,19 @@ function SectionLabel({ children, help }) {
533
551
  runStartBlank,
534
552
  tracker
535
553
  ]);
554
+ const chooseImport = useCallback(()=>{
555
+ if (importAvailability.state !== 'ready') return;
556
+ if (pendingSite && !pendingSite.created && !pendingSite.check()) return;
557
+ trackEvent('site_start_choice', {
558
+ choice: 'import'
559
+ });
560
+ tracker.complete();
561
+ setImporting(true);
562
+ }, [
563
+ importAvailability.state,
564
+ pendingSite,
565
+ tracker
566
+ ]);
536
567
  const chooseAi = useCallback(()=>{
537
568
  if (pendingSite && !pendingSite.created && !pendingSite.check()) return;
538
569
  trackEvent('site_start_choice', {
@@ -671,9 +702,11 @@ function SectionLabel({ children, help }) {
671
702
  // A Free start quotes what is LEFT (AGL-3660), shared across the owner's
672
703
  // Free workspaces — never the month's whole allowance as if none were spent.
673
704
  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`;
674
- const choosing = step === 'choose' && !started;
675
- const reviewing = step === 'review' && !started;
676
- const asking = step !== 'choose' && !started;
705
+ // The card is drawn wherever the workspace could use it, disabled where it cannot yet.
706
+ const showsImport = importAvailability.state === 'ready' || importAvailability.state === 'blocked';
707
+ const choosing = step === 'choose' && !started && !importing;
708
+ const reviewing = step === 'review' && !started && !importing;
709
+ const asking = step !== 'choose' && !started && !importing;
677
710
  // Each answer's reason not to go forward, shown on a step once Next was refused there.
678
711
  const fieldErrors = aiSiteStartFieldErrors(answers, {
679
712
  freeTaste
@@ -717,7 +750,10 @@ function SectionLabel({ children, help }) {
717
750
  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.`
718
751
  }
719
752
  };
720
- const heading = HEADINGS[step];
753
+ const heading = importing ? {
754
+ title: 'Bring my site',
755
+ lede: `Bring the website you have now into ${PLATFORM_BRAND_NAME}: its pages, words and photos. First, prove it is yours.`
756
+ } : HEADINGS[step];
721
757
  // Enter in a text answer is Next. A select, a card or a button keeps its own Enter.
722
758
  const onStepKeyDown = (event)=>{
723
759
  if (event.key !== 'Enter' || event.nativeEvent.isComposing || !asking || reviewing) return;
@@ -794,7 +830,7 @@ function SectionLabel({ children, help }) {
794
830
  ]
795
831
  })
796
832
  }),
797
- /*#__PURE__*/ _jsx(DialogContent, {
833
+ /*#__PURE__*/ _jsxs(DialogContent, {
798
834
  sx: {
799
835
  px: {
800
836
  xs: 2,
@@ -802,209 +838,250 @@ function SectionLabel({ children, help }) {
802
838
  }
803
839
  },
804
840
  onKeyDown: onStepKeyDown,
805
- children: /*#__PURE__*/ _jsx(Container, {
806
- maxWidth: choosing || step === 'kind' || step === 'style' ? 'md' : 'sm',
807
- disableGutters: true,
808
- sx: {
809
- py: {
810
- xs: 3,
811
- sm: 5
812
- }
813
- },
814
- children: /*#__PURE__*/ _jsxs(Stack, {
815
- spacing: 4,
816
- children: [
817
- /*#__PURE__*/ _jsx(Box, {
818
- sx: {
819
- maxWidth: (t)=>t.spacing(80),
820
- width: '100%',
821
- mx: 'auto'
822
- },
823
- children: /*#__PURE__*/ _jsx(StartProgress, {
824
- step: step,
825
- compact: compact,
826
- onStep: started ? undefined : goBackTo
827
- })
828
- }),
829
- /*#__PURE__*/ _jsxs(Stack, {
830
- spacing: 1,
831
- sx: {
832
- textAlign: choosing ? 'center' : 'left'
833
- },
834
- "data-start-area": "heading",
835
- children: [
836
- /*#__PURE__*/ _jsx(Typography, {
837
- ref: headingRef,
838
- tabIndex: -1,
839
- variant: "h4",
840
- component: "h1",
841
- sx: {
842
- '&:focus': {
843
- outline: 'none'
844
- },
845
- '&:focus-visible': {
846
- outline: 'none'
847
- }
848
- },
849
- children: heading.title
850
- }),
851
- /*#__PURE__*/ _jsxs(Typography, {
852
- variant: "body1",
853
- color: "text.secondary",
854
- children: [
855
- choosing ? /*#__PURE__*/ _jsx(HelpTip, _extends({
856
- sx: {
857
- float: 'right'
858
- }
859
- }, START_HELP.choose)) : /*#__PURE__*/ _jsx(StepHelp, {
860
- step: step
861
- }),
862
- heading.lede
863
- ]
864
- })
865
- ]
866
- }),
867
- notice && /*#__PURE__*/ _jsx(Alert, {
868
- severity: "info",
869
- "data-start-area": "notice",
870
- children: notice
871
- }),
872
- asking && noneLeft && freeCredits && /*#__PURE__*/ _jsx(Alert, {
873
- severity: "warning",
874
- "data-start-area": "notice",
875
- action: orgSlug ? /*#__PURE__*/ _jsx(Button, {
876
- color: "inherit",
877
- size: "small",
878
- href: aiCreditsBillingHref(orgSlug),
879
- children: 'Upgrade'
880
- }) : undefined,
881
- children: aiFreeCreditsNoneLeftText(freeCredits.resetsOn)
882
- }),
883
- choosing && creating && pendingSite ? /*#__PURE__*/ _jsxs(Stack, {
884
- spacing: 2,
885
- component: "section",
886
- "aria-label": "Your site",
887
- children: [
888
- /*#__PURE__*/ _jsx(SectionLabel, {
889
- children: 'Your site'
890
- }),
891
- pendingSite.fields
892
- ]
893
- }) : null,
894
- choosing ? /*#__PURE__*/ _jsxs(Box, {
895
- "data-start-area": "choose-cards",
896
- sx: {
897
- display: 'grid',
898
- gridTemplateColumns: {
899
- xs: '1fr',
900
- sm: '1fr 1fr'
841
+ children: [
842
+ importing ? null : /*#__PURE__*/ _jsx(Box, {
843
+ sx: {
844
+ pt: {
845
+ xs: 3,
846
+ sm: 4
847
+ }
848
+ },
849
+ children: /*#__PURE__*/ _jsx(StartProgress, {
850
+ step: step,
851
+ compact: compact,
852
+ onStep: started ? undefined : goBackTo
853
+ })
854
+ }),
855
+ /*#__PURE__*/ _jsx(Container, {
856
+ maxWidth: choosing || step === 'kind' || step === 'style' ? 'md' : 'sm',
857
+ disableGutters: true,
858
+ sx: {
859
+ py: {
860
+ xs: 3,
861
+ sm: 5
862
+ }
863
+ },
864
+ children: /*#__PURE__*/ _jsxs(Stack, {
865
+ spacing: 4,
866
+ children: [
867
+ /*#__PURE__*/ _jsxs(Stack, {
868
+ spacing: 1,
869
+ sx: {
870
+ textAlign: choosing ? 'center' : 'left'
901
871
  },
902
- gap: 3
903
- },
904
- children: [
905
- /*#__PURE__*/ _jsx(ChoiceCard, {
906
- accent: "secondary",
907
- icon: mdiPageLayoutHeaderFooter.path,
908
- iconId: "page-layout-header-footer",
909
- title: "Start from the starter site",
910
- description: "A ready-made home page with a header, footer and contact form you can edit.",
911
- busy: startingStarter,
912
- onChoose: chooseStarter
913
- }),
914
- /*#__PURE__*/ _jsxs(ChoiceCard, {
915
- accent: "primary",
916
- icon: mdiCreation.path,
917
- iconId: "creation",
918
- title: "Start with AI",
919
- description: `Answer a few questions and ${PLATFORM_BRAND_NAME} AI plans your pages.`,
920
- onChoose: chooseAi,
921
- children: [
922
- /*#__PURE__*/ _jsx(Chip, {
923
- size: "small",
924
- color: "primary",
925
- label: "Recommended"
926
- }),
927
- freeTaste && /*#__PURE__*/ _jsx(Typography, {
928
- variant: "caption",
929
- color: "text.secondary",
930
- children: `Up to ${AI_SITE_FREE_PAGES.max} pages on the Free plan`
931
- })
932
- ]
933
- })
934
- ]
935
- }) : started && orgId ? /*#__PURE__*/ _jsx(Card, {
936
- variant: "outlined",
937
- sx: {
938
- borderRadius: 2,
939
- p: {
940
- xs: 2,
941
- sm: 3
942
- }
943
- },
944
- children: /*#__PURE__*/ _jsx(AiJobFollow, {
945
- job: started,
872
+ "data-start-area": "heading",
873
+ children: [
874
+ /*#__PURE__*/ _jsx(Typography, {
875
+ ref: headingRef,
876
+ tabIndex: -1,
877
+ variant: "h4",
878
+ component: "h1",
879
+ sx: {
880
+ '&:focus': {
881
+ outline: 'none'
882
+ },
883
+ '&:focus-visible': {
884
+ outline: 'none'
885
+ }
886
+ },
887
+ children: heading.title
888
+ }),
889
+ /*#__PURE__*/ _jsxs(Typography, {
890
+ variant: "body1",
891
+ color: "text.secondary",
892
+ children: [
893
+ choosing ? /*#__PURE__*/ _jsx(HelpTip, _extends({
894
+ sx: {
895
+ float: 'right'
896
+ }
897
+ }, START_HELP.choose)) : importing ? null : /*#__PURE__*/ _jsx(StepHelp, {
898
+ step: step
899
+ }),
900
+ heading.lede
901
+ ]
902
+ })
903
+ ]
904
+ }),
905
+ notice && /*#__PURE__*/ _jsx(Alert, {
906
+ severity: "info",
907
+ "data-start-area": "notice",
908
+ children: notice
909
+ }),
910
+ asking && noneLeft && freeCredits && /*#__PURE__*/ _jsx(Alert, {
911
+ severity: "warning",
912
+ "data-start-area": "notice",
913
+ action: orgSlug ? /*#__PURE__*/ _jsx(Button, {
914
+ color: "inherit",
915
+ size: "small",
916
+ href: aiCreditsBillingHref(orgSlug),
917
+ children: 'Upgrade'
918
+ }) : undefined,
919
+ children: aiFreeCreditsNoneLeftText(freeCredits.resetsOn)
920
+ }),
921
+ choosing && creating && pendingSite ? /*#__PURE__*/ _jsxs(Stack, {
922
+ spacing: 2,
923
+ component: "section",
924
+ "aria-label": "Your site",
925
+ children: [
926
+ /*#__PURE__*/ _jsx(SectionLabel, {
927
+ children: 'Your site'
928
+ }),
929
+ pendingSite.fields
930
+ ]
931
+ }) : null,
932
+ importing && orgId ? /*#__PURE__*/ _jsx(AiSiteImportStart, {
946
933
  orgId: orgId,
947
934
  orgSlug: orgSlug,
935
+ hostId: hostId,
936
+ host: host,
948
937
  user: user,
949
- intro: 'Your site is being planned. It is then built and published for you, with ' + 'nothing to approve. You can edit or unpublish it afterwards.',
950
- // Full screen: AI jobs opens in the panel this dialog covers.
951
- onOpenJobs: exit
952
- })
953
- }) : /*#__PURE__*/ _jsxs(Box, {
954
- component: "section",
955
- children: [
956
- step === 'kind' && /*#__PURE__*/ _jsx(KindStep, _extends({}, stepProps)),
957
- step === 'audience' && /*#__PURE__*/ _jsx(AudienceStep, _extends({}, stepProps)),
958
- step === 'style' && /*#__PURE__*/ _jsx(StyleStep, _extends({}, stepProps, {
959
- inspiration: siteInspiration ? {
960
- limit: aiSiteInspirationLimit(freeTaste),
961
- upgradeHref: orgSlug ? aiCreditsBillingHref(orgSlug) : null
962
- } : null
963
- })),
964
- step === 'details' && /*#__PURE__*/ _jsx(DetailsStep, _extends({}, stepProps, {
965
- freeTaste: freeTaste,
966
- band: band
967
- })),
968
- step !== 'review' && /*#__PURE__*/ _jsx(Box, {
969
- sx: {
970
- mt: 3
971
- },
972
- children: /*#__PURE__*/ _jsx(MoreDetails, _extends({
973
- step: step
974
- }, stepProps), step)
975
- }),
976
- step === 'review' && /*#__PURE__*/ _jsxs(ReviewStep, {
977
- answers: answers,
978
- freeTaste: freeTaste,
979
- onEdit: edit,
980
- inspiration: siteInspiration,
981
- children: [
982
- clientIntake && /*#__PURE__*/ _jsx(Alert, {
983
- severity: "info",
984
- variant: "outlined",
985
- "data-start-area": "client-intake",
986
- children: aiSiteStartClientNote(clientIntake)
987
- }),
988
- !noneLeft && prompt && /*#__PURE__*/ _jsx(AiCreditsPromptNotice, {
989
- prompt: prompt,
990
- noun: "site",
991
- orgSlug: orgSlug,
992
- busy: busy,
993
- onBuildWhatFits: ()=>void plan({
994
- creditsConfirmed: true
995
- }),
996
- onSmaller: ()=>void plan({
997
- creditsConfirmed: true,
998
- pages: 1
999
- })
1000
- })
1001
- ]
938
+ pendingSite: pendingSite,
939
+ onBack: ()=>setImporting(false),
940
+ leave: leave
941
+ }) : choosing ? /*#__PURE__*/ _jsxs(Stack, {
942
+ spacing: 2,
943
+ children: [
944
+ /*#__PURE__*/ _jsxs(Box, {
945
+ "data-start-area": "choose-cards",
946
+ sx: {
947
+ display: 'grid',
948
+ gridTemplateColumns: showsImport ? {
949
+ xs: '1fr',
950
+ sm: '1fr 1fr',
951
+ md: '1fr 1fr 1fr'
952
+ } : {
953
+ xs: '1fr',
954
+ sm: '1fr 1fr'
955
+ },
956
+ gap: 3
957
+ },
958
+ children: [
959
+ /*#__PURE__*/ _jsx(ChoiceCard, {
960
+ accent: "secondary",
961
+ icon: mdiPageLayoutHeaderFooter.path,
962
+ iconId: "page-layout-header-footer",
963
+ title: "Start from the starter site",
964
+ description: "A ready-made home page with a header, footer and contact form you can edit.",
965
+ busy: startingStarter,
966
+ onChoose: chooseStarter
967
+ }),
968
+ /*#__PURE__*/ _jsxs(ChoiceCard, {
969
+ accent: "primary",
970
+ icon: mdiCreation.path,
971
+ iconId: "creation",
972
+ title: "Start with AI",
973
+ description: `Answer a few questions and ${PLATFORM_BRAND_NAME} AI plans your pages.`,
974
+ onChoose: chooseAi,
975
+ children: [
976
+ /*#__PURE__*/ _jsx(Chip, {
977
+ size: "small",
978
+ color: "primary",
979
+ label: "Recommended"
980
+ }),
981
+ freeTaste && /*#__PURE__*/ _jsx(Typography, {
982
+ variant: "caption",
983
+ color: "text.secondary",
984
+ children: `Up to ${AI_SITE_FREE_PAGES.max} pages on the Free plan`
985
+ })
986
+ ]
987
+ }),
988
+ showsImport && /*#__PURE__*/ _jsx(ChoiceCard, {
989
+ accent: "secondary",
990
+ icon: mdiWebSync.path,
991
+ iconId: "web-sync",
992
+ title: "Bring my site",
993
+ description: `Bring the website you have now into ${PLATFORM_BRAND_NAME}: its pages, words and photos, rewritten in your new design.`,
994
+ blocked: importAvailability.state === 'blocked' ? importAvailability.message : null,
995
+ onChoose: chooseImport,
996
+ children: importAvailability.state === 'blocked' && importAvailability.reason === 'plan' ? /*#__PURE__*/ _jsx(Chip, {
997
+ size: "small",
998
+ variant: "outlined",
999
+ label: "Paid plans"
1000
+ }) : null
1001
+ })
1002
+ ]
1003
+ }),
1004
+ importAvailability.state === 'blocked' ? /*#__PURE__*/ _jsx(PrerequisiteNotice, _extends({}, importAvailability.reason === 'plan' && orgSlug ? {
1005
+ href: aiCreditsBillingHref(orgSlug),
1006
+ actionLabel: 'Upgrade'
1007
+ } : {}, {
1008
+ children: importAvailability.message
1009
+ })) : null
1010
+ ]
1011
+ }) : started && orgId ? /*#__PURE__*/ _jsx(Card, {
1012
+ variant: "outlined",
1013
+ sx: {
1014
+ borderRadius: 2,
1015
+ p: {
1016
+ xs: 2,
1017
+ sm: 3
1018
+ }
1019
+ },
1020
+ children: /*#__PURE__*/ _jsx(AiJobFollow, {
1021
+ job: started,
1022
+ orgId: orgId,
1023
+ orgSlug: orgSlug,
1024
+ user: user,
1025
+ intro: 'Your site is being planned. It is then built and published for you, with ' + 'nothing to approve. You can edit or unpublish it afterwards.',
1026
+ // Full screen: AI jobs opens in the panel this dialog covers.
1027
+ onOpenJobs: exit
1002
1028
  })
1003
- ]
1004
- })
1005
- ]
1029
+ }) : /*#__PURE__*/ _jsxs(Box, {
1030
+ component: "section",
1031
+ children: [
1032
+ step === 'kind' && /*#__PURE__*/ _jsx(KindStep, _extends({}, stepProps)),
1033
+ step === 'audience' && /*#__PURE__*/ _jsx(AudienceStep, _extends({}, stepProps)),
1034
+ step === 'style' && /*#__PURE__*/ _jsx(StyleStep, _extends({}, stepProps, {
1035
+ inspiration: siteInspiration ? {
1036
+ limit: aiSiteInspirationLimit(freeTaste),
1037
+ upgradeHref: orgSlug ? aiCreditsBillingHref(orgSlug) : null
1038
+ } : null
1039
+ })),
1040
+ step === 'details' && /*#__PURE__*/ _jsx(DetailsStep, _extends({}, stepProps, {
1041
+ freeTaste: freeTaste,
1042
+ band: band
1043
+ })),
1044
+ step !== 'review' && /*#__PURE__*/ _jsx(Box, {
1045
+ sx: {
1046
+ mt: 3
1047
+ },
1048
+ children: /*#__PURE__*/ _jsx(MoreDetails, _extends({
1049
+ step: step
1050
+ }, stepProps), step)
1051
+ }),
1052
+ step === 'review' && /*#__PURE__*/ _jsxs(ReviewStep, {
1053
+ answers: answers,
1054
+ freeTaste: freeTaste,
1055
+ onEdit: edit,
1056
+ inspiration: siteInspiration,
1057
+ children: [
1058
+ clientIntake && /*#__PURE__*/ _jsx(Alert, {
1059
+ severity: "info",
1060
+ variant: "outlined",
1061
+ "data-start-area": "client-intake",
1062
+ children: aiSiteStartClientNote(clientIntake)
1063
+ }),
1064
+ !noneLeft && prompt && /*#__PURE__*/ _jsx(AiCreditsPromptNotice, {
1065
+ prompt: prompt,
1066
+ noun: "site",
1067
+ orgSlug: orgSlug,
1068
+ busy: busy,
1069
+ onBuildWhatFits: ()=>void plan({
1070
+ creditsConfirmed: true
1071
+ }),
1072
+ onSmaller: ()=>void plan({
1073
+ creditsConfirmed: true,
1074
+ pages: 1
1075
+ })
1076
+ })
1077
+ ]
1078
+ })
1079
+ ]
1080
+ })
1081
+ ]
1082
+ })
1006
1083
  })
1007
- })
1084
+ ]
1008
1085
  }),
1009
1086
  asking && /* The footer stays put while the questions scroll. It wraps, because
1010
1087
  the estimate, the reason and the buttons are wider than a phone. */ /*#__PURE__*/ _jsxs(DialogActions, {