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

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 (94) 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 +165 -91
  17. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  18. package/src/lib/jobs/ai-job-drafts.d.ts +14 -0
  19. package/src/lib/jobs/ai-job-drafts.js +24 -0
  20. package/src/lib/jobs/ai-job-drafts.js.map +1 -1
  21. package/src/lib/jobs/ai-job-import-step.d.ts +136 -0
  22. package/src/lib/jobs/ai-job-import-step.js +809 -0
  23. package/src/lib/jobs/ai-job-import-step.js.map +1 -0
  24. package/src/lib/jobs/ai-job-page-language.d.ts +39 -1
  25. package/src/lib/jobs/ai-job-page-language.js +62 -4
  26. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  27. package/src/lib/jobs/ai-job-page-step.d.ts +2 -2
  28. package/src/lib/jobs/ai-job-page-step.js +5 -2
  29. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  30. package/src/lib/jobs/ai-job-text-step.d.ts +7 -0
  31. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  32. package/src/lib/jobs/ai-jobs.d.ts +5 -0
  33. package/src/lib/jobs/ai-jobs.js +15 -3
  34. package/src/lib/jobs/ai-jobs.js.map +1 -1
  35. package/src/lib/jobs/ai-layout-owner-photos.d.ts +16 -1
  36. package/src/lib/jobs/ai-layout-owner-photos.js +47 -0
  37. package/src/lib/jobs/ai-layout-owner-photos.js.map +1 -1
  38. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +61 -3
  39. package/src/lib/jobs/ai-theme-brand-inputs.js +117 -27
  40. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
  41. package/src/lib/model/ai-credit-estimate.d.ts +20 -0
  42. package/src/lib/model/ai-credit-estimate.js +13 -0
  43. package/src/lib/model/ai-credit-estimate.js.map +1 -1
  44. package/src/lib/model/ai-job-activity.d.ts +2 -2
  45. package/src/lib/model/ai-job-activity.js +6 -4
  46. package/src/lib/model/ai-job-activity.js.map +1 -1
  47. package/src/lib/model/ai-job-notice.js +18 -4
  48. package/src/lib/model/ai-job-notice.js.map +1 -1
  49. package/src/lib/model/ai-jobs.types.d.ts +29 -2
  50. package/src/lib/model/ai-jobs.types.js +2 -1
  51. package/src/lib/model/ai-jobs.types.js.map +1 -1
  52. package/src/lib/model/ai-site-import-view.d.ts +130 -0
  53. package/src/lib/model/ai-site-import-view.js +182 -0
  54. package/src/lib/model/ai-site-import-view.js.map +1 -0
  55. package/src/lib/model/ai-site-import.d.ts +302 -0
  56. package/src/lib/model/ai-site-import.js +526 -0
  57. package/src/lib/model/ai-site-import.js.map +1 -0
  58. package/src/lib/model/ai-site-start.d.ts +22 -9
  59. package/src/lib/model/ai-site-start.js +64 -23
  60. package/src/lib/model/ai-site-start.js.map +1 -1
  61. package/src/lib/server/ai-jobs-route.js +11 -0
  62. package/src/lib/server/ai-jobs-route.js.map +1 -1
  63. package/src/lib/server/ai-site-import-route.d.ts +89 -0
  64. package/src/lib/server/ai-site-import-route.js +356 -0
  65. package/src/lib/server/ai-site-import-route.js.map +1 -0
  66. package/src/lib/server.js +14 -0
  67. package/src/lib/server.js.map +1 -1
  68. package/src/lib/site-import/fixtures/site-import-crawl-recordings.d.ts +45 -0
  69. package/src/lib/site-import/fixtures/site-import-crawl-recordings.js +313 -0
  70. package/src/lib/site-import/fixtures/site-import-crawl-recordings.js.map +1 -0
  71. package/src/lib/site-import/fixtures/site-import-wave-recordings.d.ts +50 -0
  72. package/src/lib/site-import/fixtures/site-import-wave-recordings.js +217 -0
  73. package/src/lib/site-import/fixtures/site-import-wave-recordings.js.map +1 -0
  74. package/src/lib/site-import/site-import-crawl.d.ts +163 -0
  75. package/src/lib/site-import/site-import-crawl.js +467 -0
  76. package/src/lib/site-import/site-import-crawl.js.map +1 -0
  77. package/src/lib/site-import/site-import-flag.d.ts +23 -0
  78. package/src/lib/site-import/site-import-flag.js +23 -0
  79. package/src/lib/site-import/site-import-flag.js.map +1 -0
  80. package/src/lib/site-import/site-import-html.d.ts +94 -0
  81. package/src/lib/site-import/site-import-html.js +462 -0
  82. package/src/lib/site-import/site-import-html.js.map +1 -0
  83. package/src/lib/site-import/site-import-images.d.ts +54 -0
  84. package/src/lib/site-import/site-import-images.js +204 -0
  85. package/src/lib/site-import/site-import-images.js.map +1 -0
  86. package/src/lib/site-import/site-import-page.d.ts +48 -0
  87. package/src/lib/site-import/site-import-page.js +150 -0
  88. package/src/lib/site-import/site-import-page.js.map +1 -0
  89. package/src/lib/site-import/site-import-review.d.ts +40 -0
  90. package/src/lib/site-import/site-import-review.js +149 -0
  91. package/src/lib/site-import/site-import-review.js.map +1 -0
  92. package/src/lib/site-import/site-import-robots.d.ts +52 -0
  93. package/src/lib/site-import/site-import-robots.js +126 -0
  94. package/src/lib/site-import/site-import-robots.js.map +1 -0
@@ -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;
@@ -820,7 +856,7 @@ function SectionLabel({ children, help }) {
820
856
  width: '100%',
821
857
  mx: 'auto'
822
858
  },
823
- children: /*#__PURE__*/ _jsx(StartProgress, {
859
+ children: importing ? null : /*#__PURE__*/ _jsx(StartProgress, {
824
860
  step: step,
825
861
  compact: compact,
826
862
  onStep: started ? undefined : goBackTo
@@ -856,7 +892,7 @@ function SectionLabel({ children, help }) {
856
892
  sx: {
857
893
  float: 'right'
858
894
  }
859
- }, START_HELP.choose)) : /*#__PURE__*/ _jsx(StepHelp, {
895
+ }, START_HELP.choose)) : importing ? null : /*#__PURE__*/ _jsx(StepHelp, {
860
896
  step: step
861
897
  }),
862
898
  heading.lede
@@ -891,46 +927,84 @@ function SectionLabel({ children, help }) {
891
927
  pendingSite.fields
892
928
  ]
893
929
  }) : 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'
901
- },
902
- gap: 3
903
- },
930
+ importing && orgId ? /*#__PURE__*/ _jsx(AiSiteImportStart, {
931
+ orgId: orgId,
932
+ orgSlug: orgSlug,
933
+ hostId: hostId,
934
+ host: host,
935
+ user: user,
936
+ pendingSite: pendingSite,
937
+ onBack: ()=>setImporting(false),
938
+ leave: leave
939
+ }) : choosing ? /*#__PURE__*/ _jsxs(Stack, {
940
+ spacing: 2,
904
941
  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,
942
+ /*#__PURE__*/ _jsxs(Box, {
943
+ "data-start-area": "choose-cards",
944
+ sx: {
945
+ display: 'grid',
946
+ gridTemplateColumns: showsImport ? {
947
+ xs: '1fr',
948
+ sm: '1fr 1fr',
949
+ md: '1fr 1fr 1fr'
950
+ } : {
951
+ xs: '1fr',
952
+ sm: '1fr 1fr'
953
+ },
954
+ gap: 3
955
+ },
921
956
  children: [
922
- /*#__PURE__*/ _jsx(Chip, {
923
- size: "small",
924
- color: "primary",
925
- label: "Recommended"
957
+ /*#__PURE__*/ _jsx(ChoiceCard, {
958
+ accent: "secondary",
959
+ icon: mdiPageLayoutHeaderFooter.path,
960
+ iconId: "page-layout-header-footer",
961
+ title: "Start from the starter site",
962
+ description: "A ready-made home page with a header, footer and contact form you can edit.",
963
+ busy: startingStarter,
964
+ onChoose: chooseStarter
926
965
  }),
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`
966
+ /*#__PURE__*/ _jsxs(ChoiceCard, {
967
+ accent: "primary",
968
+ icon: mdiCreation.path,
969
+ iconId: "creation",
970
+ title: "Start with AI",
971
+ description: `Answer a few questions and ${PLATFORM_BRAND_NAME} AI plans your pages.`,
972
+ onChoose: chooseAi,
973
+ children: [
974
+ /*#__PURE__*/ _jsx(Chip, {
975
+ size: "small",
976
+ color: "primary",
977
+ label: "Recommended"
978
+ }),
979
+ freeTaste && /*#__PURE__*/ _jsx(Typography, {
980
+ variant: "caption",
981
+ color: "text.secondary",
982
+ children: `Up to ${AI_SITE_FREE_PAGES.max} pages on the Free plan`
983
+ })
984
+ ]
985
+ }),
986
+ showsImport && /*#__PURE__*/ _jsx(ChoiceCard, {
987
+ accent: "secondary",
988
+ icon: mdiWebSync.path,
989
+ iconId: "web-sync",
990
+ title: "Bring my site",
991
+ description: `Bring the website you have now into ${PLATFORM_BRAND_NAME}: its pages, words and photos, rewritten in your new design.`,
992
+ blocked: importAvailability.state === 'blocked' ? importAvailability.message : null,
993
+ onChoose: chooseImport,
994
+ children: importAvailability.state === 'blocked' && importAvailability.reason === 'plan' ? /*#__PURE__*/ _jsx(Chip, {
995
+ size: "small",
996
+ variant: "outlined",
997
+ label: "Paid plans"
998
+ }) : null
931
999
  })
932
1000
  ]
933
- })
1001
+ }),
1002
+ importAvailability.state === 'blocked' ? /*#__PURE__*/ _jsx(PrerequisiteNotice, _extends({}, importAvailability.reason === 'plan' && orgSlug ? {
1003
+ href: aiCreditsBillingHref(orgSlug),
1004
+ actionLabel: 'Upgrade'
1005
+ } : {}, {
1006
+ children: importAvailability.message
1007
+ })) : null
934
1008
  ]
935
1009
  }) : started && orgId ? /*#__PURE__*/ _jsx(Card, {
936
1010
  variant: "outlined",