PluginProbe
Extendify / 0.10.1
Extendify v0.10.1
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.1, at src/Onboarding/pages/CreatingSite.js

239 lines 9.3 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(window.extOnbData.home)
146 })
147 }, [doEverything])
148
149 useConfetti(
150 {
151 particleCount: 2,
152 angle: 320,
153 spread: 120,
154 origin: { x: 0, y: 0 },
155 colors: ['var(--ext-partner-theme-primary-text, #ffffff)'],
156 },
157 2500,
158 confettiReady,
159 )
160
161 return (
162 <Transition
163 show={isShowing}
164 appear={true}
165 enter="transition-all ease-in-out duration-500"
166 enterFrom="md:w-40vw md:max-w-md"
167 enterTo="md:w-full md:max-w-full"
168 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">
169 <div className="max-w-prose">
170 <div className="md:min-h-48">
171 {window.extOnbData?.partnerLogo && (
172 <div className="pb-8">
173 <img
174 style={{ maxWidth: '200px' }}
175 src={window.extOnbData.partnerLogo}
176 alt={window.extOnbData?.partnerName ?? ''}
177 />
178 </div>
179 )}
180 <div>
181 {info.map((step, index) => {
182 if (!index) {
183 return (
184 <Transition
185 appear={true}
186 show={isShowing}
187 enter="transition-opacity duration-1000"
188 enterFrom="opacity-0"
189 enterTo="opacity-100"
190 leave="transition-opacity duration-1000"
191 leaveFrom="opacity-100"
192 leaveTo="opacity-0"
193 className="text-4xl flex space-x-4 items-center"
194 key={step}>
195 {step}
196 </Transition>
197 )
198 }
199 })}
200 <div className="flex space-x-4 items-center mt-6">
201 <Spinner className="animate-spin" />
202 {infoDesc.map((step, index) => {
203 if (!index) {
204 return (
205 <Transition
206 appear={true}
207 show={isShowing}
208 enter="transition-opacity duration-1000"
209 enterFrom="opacity-0"
210 enterTo="opacity-100"
211 leave="transition-opacity duration-1000"
212 leaveFrom="opacity-100"
213 leaveTo="opacity-0"
214 className="text-lg"
215 key={step}>
216 {step}
217 </Transition>
218 )
219 }
220 })}
221 </div>
222 </div>
223 </div>
224 </div>
225 <div className="hidden md:flex items-center space-x-3">
226 <span className="opacity-70 text-xs">
227 {__('Powered by', 'extendify')}
228 </span>
229 <span className="relative">
230 <Logo className="logo text-partner-primary-text w-28" />
231 <span className="absolute -bottom-2 right-3 font-semibold tracking-tight">
232 Launch
233 </span>
234 </span>
235 </div>
236 </Transition>
237 )
238 }
239