PluginProbe
Extendify / 3.1.3
Extendify v3.1.3
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / AutoLaunch / LaunchPage.jsx

LaunchPage.jsx in Extendify 3.1.3, at src/AutoLaunch/LaunchPage.jsx

229 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { ExtendifyCodeConnector } from '@auto-launch/components/ExtendifyCodeConnector';
2 import { Launch } from '@auto-launch/components/Launch';
3 import { Logo } from '@auto-launch/components/Logo';
4 import { MigrateChoice } from '@auto-launch/components/MigrateChoice';
5 import { MovingGradient } from '@auto-launch/components/MovingGradients';
6 import { NeedsTheme } from '@auto-launch/components/NeedsTheme';
7 import { RestartLaunchModal } from '@auto-launch/components/RestartLaunchModal';
8 import { ViewportPulse } from '@auto-launch/components/ViewportPulse';
9 import { getAbTest } from '@auto-launch/functions/getAbTest';
10 import { preLaunchFunctions } from '@auto-launch/functions/setup';
11 import { updateOption } from '@auto-launch/functions/wp';
12 import { useLaunchDataStore } from '@auto-launch/state/launch-data';
13 import { registerCoreBlocks } from '@wordpress/block-library';
14 import { getBlockTypes } from '@wordpress/blocks';
15 import { useSelect } from '@wordpress/data';
16 import { useEffect, useRef, useState } from '@wordpress/element';
17 import { __ } from '@wordpress/i18n';
18 import { chevronLeft, Icon } from '@wordpress/icons';
19 import classNames from 'classnames';
20 import { AnimatePresence, motion } from 'framer-motion';
21 import { checkIn, reportRestApiStatus } from './functions/insights';
22
23 export const LaunchPage = () => {
24 const theme = useSelect((select) => select('core').getCurrentTheme());
25 // Checking `theme` here makes sure the data is populated
26 const needsTheme = theme && theme?.textdomain !== 'extendable';
27
28 const oldPages = window.extLaunchData.resetSiteInformation.pagesIds ?? [];
29 const needsToReset = oldPages.length > 0;
30
31 const {
32 title,
33 descriptionRaw,
34 go,
35 urlParams,
36 designBuild,
37 setData,
38 showExtendifyCodeScreen,
39 } = useLaunchDataStore();
40 const skipDescription =
41 Boolean(urlParams?.['build-id']) ||
42 designBuild ||
43 ((title || descriptionRaw) && go);
44 const showConnector = !skipDescription && showExtendifyCodeScreen;
45 const showExitLink =
46 !skipDescription && !window.extLaunchData?.hideAutoLaunchExitLink;
47 const inMigrateVariant =
48 getAbTest('AutoLaunch.MigrateScreen').variant === 'B';
49 const [choosingMigration, setChoosingMigration] = useState(inMigrateVariant);
50 const showMigrateChoice = !skipDescription && choosingMigration;
51
52 const containerRef = useRef(null);
53
54 useEffect(() => {
55 // translators: Launch is a noun.
56 document.title = __('Launch - AI-Powered Web Creation', 'extendify-local');
57 updateOption('extendify_launch_loaded', new Date().toISOString());
58 // We load core blocks so we can parse them
59 if (getBlockTypes().length === 0) registerCoreBlocks();
60
61 preLaunchFunctions();
62 checkIn({ stage: 'launch_page' });
63 reportRestApiStatus();
64 }, []);
65
66 if (needsTheme) {
67 return (
68 <Wrapper>
69 <div className="bg-white w-full max-w-3xl rounded-lg border border-design-main/60 relative z-10">
70 <NeedsTheme />
71 </div>
72 </Wrapper>
73 );
74 }
75
76 if (needsToReset) {
77 return (
78 <Wrapper>
79 <div className="w-full max-w-2xl rounded-3xl border bg-gray-100/80 backdrop-blur-2xl shadow-md relative z-10 border-gray-300">
80 <RestartLaunchModal pages={oldPages} />
81 </div>
82 </Wrapper>
83 );
84 }
85
86 return (
87 <Wrapper
88 footer={
89 showConnector ? (
90 <BackLink onClick={() => setData('showExtendifyCodeScreen', false)} />
91 ) : showExitLink ? (
92 <ExitLink />
93 ) : null
94 }
95 >
96 <AnimatePresence mode="wait" initial={false}>
97 <TheTitle
98 key={showMigrateChoice ? 'migrate' : 'description'}
99 // The connector renders its own heading, so hide the shared one.
100 hide={skipDescription || showConnector}
101 migrate={showMigrateChoice}
102 />
103 </AnimatePresence>
104 <div
105 ref={containerRef}
106 className={classNames('w-full relative z-10', {
107 'max-w-3xl': inMigrateVariant || showConnector,
108 'max-w-2xl': !inMigrateVariant && !showConnector,
109 'md:h-72.75': inMigrateVariant && !skipDescription,
110 })}
111 >
112 <AnimatePresence mode="wait">
113 {showConnector && (
114 <ExtendifyCodeConnector
115 key="extendify-code"
116 onProceed={() => setData('go', true)}
117 />
118 )}
119 {!showConnector && showMigrateChoice && (
120 <MigrateChoice
121 key="migrate-choice"
122 onBuildNew={() => setChoosingMigration(false)}
123 />
124 )}
125 {!showConnector && !showMigrateChoice && (
126 <Launch
127 key={skipDescription ? 'description-launch' : 'creating-launch'}
128 skipDescription={skipDescription}
129 lastHeight={containerRef.current?.offsetHeight}
130 />
131 )}
132 </AnimatePresence>
133 </div>
134 </Wrapper>
135 );
136 };
137
138 const Wrapper = ({ children, footer }) => {
139 const { pulse } = useLaunchDataStore();
140
141 return (
142 <div style={{ zIndex: 99999 + 1 }} className="fixed inset-0 bg-white">
143 <div className="relative h-dvh bg-banner-main text-banner-text text-base overflow-y-auto">
144 <div className="relative z-10 min-h-dvh w-full flex flex-col items-center justify-between p-6">
145 <div className="w-full flex flex-col items-center gap-5 md:gap-8 m-auto">
146 <div className="mb-4">
147 <Logo />
148 </div>
149 {children}
150 </div>
151 {footer && <div className="w-full pt-8 shrink-0">{footer}</div>}
152 </div>
153 </div>
154 <MovingGradient />
155 {pulse ? <ViewportPulse /> : null}
156 </div>
157 );
158 };
159
160 const ExitLink = () => {
161 return (
162 <a
163 className="inline-flex items-center gap-0.5 text-sm text-banner-text opacity-70 hover:opacity-100 transition-opacity"
164 href={window.extSharedData.adminUrl}
165 onClick={() => checkIn({ stage: 'exit_to_wp_admin' })}
166 >
167 <Icon fill="currentColor" icon={chevronLeft} size={20} />
168 {__('WP Admin Dashboard', 'extendify-local')}
169 </a>
170 );
171 };
172
173 const BackLink = ({ onClick }) => {
174 return (
175 <button
176 type="button"
177 onClick={onClick}
178 className="inline-flex items-center gap-0.5 border-0 bg-transparent cursor-pointer text-sm text-banner-text opacity-70 hover:opacity-100 transition-opacity"
179 >
180 <Icon fill="currentColor" icon={chevronLeft} size={20} />
181 {__('Back', 'extendify-local')}
182 </button>
183 );
184 };
185
186 const TheTitle = ({ hide, migrate }) => {
187 const useOldHeader =
188 getAbTest('AutoLaunch.HeaderParagraphOld').variant === 'B';
189 if (hide) return null;
190
191 const headingClass =
192 'text-xl md:text-2xl text-pretty text-banner-text font-semibold p-0 m-0 text-center';
193 const transition = {
194 animate: { opacity: 1 },
195 exit: { opacity: 0 },
196 transition: { duration: 0.4 },
197 };
198
199 if (migrate) {
200 return (
201 <motion.h2 className={headingClass} {...transition}>
202 {__('How would you like to start your website?', 'extendify-local')}
203 </motion.h2>
204 );
205 }
206
207 if (useOldHeader) {
208 return (
209 <motion.div className="flex flex-col items-center gap-2" {...transition}>
210 <h2 className={headingClass}>
211 {__('Tell Us About Your Website', 'extendify-local')}
212 </h2>
213 <p className="text-sm md:text-base text-pretty text-banner-text opacity-70 p-0 m-0 text-center max-w-xl">
214 {__(
215 "Share your vision, and we'll craft a website that's perfectly tailored to your needs, ready to launch in no time.",
216 'extendify-local',
217 )}
218 </p>
219 </motion.div>
220 );
221 }
222
223 return (
224 <motion.h2 className={headingClass} {...transition}>
225 {__('Describe the website you want to build', 'extendify-local')}
226 </motion.h2>
227 );
228 };
229