PluginProbe
Extendify / 0.10.2
Extendify v0.10.2
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 / Onboarding / pages / CreatingSite.js

CreatingSite.js in Extendify 0.10.2, at src/Onboarding/pages/CreatingSite.js

242 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useEffect, useState, useCallback, useRef } from '@wordpress/element'
2 import { __ } from '@wordpress/i18n'
3 import { Transition } from '@headlessui/react'
4 import {
5 installPlugin,
6 updateTemplatePart,
7 addLaunchPagesToNav,
8 updateOption,
9 } from '@onboarding/api/WPApi'
10 import { useConfetti } from '@onboarding/hooks/useConfetti'
11 import { useWarnOnLeave } from '@onboarding/hooks/useWarnOnLeave'
12 import { runAtLeastFor } from '@onboarding/lib/util'
13 import {
14 createWordpressPages,
15 trashWordpressPages,
16 updateGlobalStyleVariant,
17 } from '@onboarding/lib/wp'
18 import { useUserSelectionStore } from '@onboarding/state/UserSelections'
19 import { Logo, Spinner } from '@onboarding/svg'
20
21 export const CreatingSite = () => {
22 const [isShowing] = useState(true)
23 const [confettiReady, setConfettiReady] = useState(false)
24 const [warnOnLeaveReady, setWarnOnLeaveReady] = useState(true)
25 const canLaunch = useUserSelectionStore((state) => state.canLaunch())
26 const { siteType, siteInformation, pages, style, plugins } =
27 useUserSelectionStore()
28 const [info, setInfo] = useState([])
29 const [infoDesc, setInfoDesc] = useState([])
30 const inform = (msg) => setInfo((info) => [msg, ...info])
31 const informDesc = (msg) => setInfoDesc((infoDesc) => [msg, ...infoDesc])
32 const dryRun = useRef()
33 useWarnOnLeave(warnOnLeaveReady)
34
35 const doEverything = useCallback(async () => {
36 if (!canLaunch) {
37 throw new Error(__('Site is not ready to launch.', 'extendify'))
38 }
39 inform(__('Applying site styles', 'extendify'))
40 informDesc(__('A beautiful site in... 3, 2, 1', 'extendify'))
41 await runAtLeastFor(
42 async () => await updateOption('blogname', siteInformation.title),
43 2000,
44 { dryRun: dryRun.current },
45 )
46 await runAtLeastFor(
47 async () => await updateGlobalStyleVariant(style?.variation ?? {}),
48 2000,
49 { dryRun: dryRun.current },
50 )
51 await runAtLeastFor(
52 async () =>
53 await updateTemplatePart(
54 'extendable//header',
55 style?.headerCode,
56 ),
57 2000,
58 { dryRun: dryRun.current },
59 )
60 await runAtLeastFor(
61 async () =>
62 await updateTemplatePart(
63 'extendable//footer',
64 style?.footerCode,
65 ),
66 2000,
67 { dryRun: dryRun.current },
68 )
69
70 inform(__('Creating site pages', 'extendify'))
71 informDesc(__('Starting off with a full site...', 'extendify'))
72 let pageIds
73 try {
74 inform(__('Generating page content', 'extendify'))
75 await runAtLeastFor(
76 async () => {
77 pageIds = await createWordpressPages(pages, siteType, style)
78 const updatedHeaderCode = addLaunchPagesToNav(
79 pages,
80 pageIds,
81 style?.headerCode,
82 )
83 await updateTemplatePart(
84 'extendable//header',
85 updatedHeaderCode,
86 )
87 },
88 2000,
89 { dryRun: dryRun.current },
90 )
91 await new Promise((resolve) => setTimeout(resolve, 2000))
92 } catch (e) {
93 /* do nothing */
94 }
95
96 if (plugins?.length) {
97 inform(__('Installing suggested plugins', 'extendify'))
98 for (const [index, plugin] of plugins.entries()) {
99 // TODO: instead of updating here, we could have a progress component
100 // that we can update a % of the width every index/n
101 informDesc(
102 __(
103 `${index + 1}/${plugins.length}: ${plugin.name}`,
104 'extendify',
105 ),
106 )
107 try {
108 await installPlugin(plugin)
109 } catch (e) {
110 /* do nothing */
111 }
112 await new Promise((resolve) => setTimeout(resolve, 2000))
113 }
114 }
115
116 inform(__('Setting up your site assistant', 'extendify'))
117 informDesc(__('Helping your site to be successful...', 'extendify'))
118 await runAtLeastFor(
119 async () =>
120 await trashWordpressPages([
121 { slug: 'hello-world', type: 'post' },
122 { slug: 'sample-page', type: 'page' },
123 ]),
124 2000,
125 { dryRun: dryRun.current },
126 )
127
128 inform(__('Your site has been created!', 'extendify'))
129 informDesc(__('Redirecting in 3, 2, 1...', 'extendify'))
130 // fire confetti here
131 setConfettiReady(true)
132 setWarnOnLeaveReady(false)
133 await new Promise((resolve) => setTimeout(resolve, 2500))
134
135 return pageIds
136 }, [pages, plugins, siteType, style, canLaunch, siteInformation.title])
137
138 useEffect(() => {
139 const q = new URLSearchParams(window.location.search)
140 dryRun.current = q.has('dry-run')
141 }, [])
142
143 useEffect(() => {
144 doEverything().then(() => {
145 window.location.replace(
146 window.extOnbData.adminUrl +
147 'admin.php?page=extendify-assist&extendify-launch-successful',
148 )
149 })
150 }, [doEverything])
151
152 useConfetti(
153 {
154 particleCount: 2,
155 angle: 320,
156 spread: 120,
157 origin: { x: 0, y: 0 },
158 colors: ['var(--ext-partner-theme-primary-text, #ffffff)'],
159 },
160 2500,
161 confettiReady,
162 )
163
164 return (
165 <Transition
166 show={isShowing}
167 appear={true}
168 enter="transition-all ease-in-out duration-500"
169 enterFrom="md:w-40vw md:max-w-md"
170 enterTo="md:w-full md:max-w-full"
171 className="bg-partner-primary-bg text-partner-primary-text py-12 px-10 md:h-screen flex flex-col justify-between md:w-40vw md:max-w-md flex-shrink-0">
172 <div className="max-w-prose">
173 <div className="md:min-h-48">
174 {window.extOnbData?.partnerLogo && (
175 <div className="pb-8">
176 <img
177 style={{ maxWidth: '200px' }}
178 src={window.extOnbData.partnerLogo}
179 alt={window.extOnbData?.partnerName ?? ''}
180 />
181 </div>
182 )}
183 <div>
184 {info.map((step, index) => {
185 if (!index) {
186 return (
187 <Transition
188 appear={true}
189 show={isShowing}
190 enter="transition-opacity duration-1000"
191 enterFrom="opacity-0"
192 enterTo="opacity-100"
193 leave="transition-opacity duration-1000"
194 leaveFrom="opacity-100"
195 leaveTo="opacity-0"
196 className="text-4xl flex space-x-4 items-center"
197 key={step}>
198 {step}
199 </Transition>
200 )
201 }
202 })}
203 <div className="flex space-x-4 items-center mt-6">
204 <Spinner className="animate-spin" />
205 {infoDesc.map((step, index) => {
206 if (!index) {
207 return (
208 <Transition
209 appear={true}
210 show={isShowing}
211 enter="transition-opacity duration-1000"
212 enterFrom="opacity-0"
213 enterTo="opacity-100"
214 leave="transition-opacity duration-1000"
215 leaveFrom="opacity-100"
216 leaveTo="opacity-0"
217 className="text-lg"
218 key={step}>
219 {step}
220 </Transition>
221 )
222 }
223 })}
224 </div>
225 </div>
226 </div>
227 </div>
228 <div className="hidden md:flex items-center space-x-3">
229 <span className="opacity-70 text-xs">
230 {__('Powered by', 'extendify')}
231 </span>
232 <span className="relative">
233 <Logo className="logo text-partner-primary-text w-28" />
234 <span className="absolute -bottom-2 right-3 font-semibold tracking-tight">
235 Launch
236 </span>
237 </span>
238 </div>
239 </Transition>
240 )
241 }
242