PluginProbe
Extendify / 0.11.1
Extendify v0.11.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.11.1, at src/Onboarding/pages/CreatingSite.js

244 lines 9.5 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 if (!dryRun.current) {
128 await updateOption('permalink_structure', '/%postname%/')
129 }
130 inform(__('Your site has been created!', 'extendify'))
131 informDesc(__('Redirecting in 3, 2, 1...', 'extendify'))
132 // fire confetti here
133 setConfettiReady(true)
134 setWarnOnLeaveReady(false)
135 await new Promise((resolve) => setTimeout(resolve, 2500))
136
137 return pageIds
138 }, [pages, plugins, siteType, style, canLaunch, siteInformation.title])
139
140 useEffect(() => {
141 const q = new URLSearchParams(window.location.search)
142 dryRun.current = q.has('dry-run')
143 }, [])
144
145 useEffect(() => {
146 doEverything().then(() => {
147 window.location.replace(
148 window.extOnbData.adminUrl +
149 'admin.php?page=extendify-assist&extendify-launch-success',
150 )
151 })
152 }, [doEverything])
153
154 useConfetti(
155 {
156 particleCount: 2,
157 angle: 320,
158 spread: 120,
159 origin: { x: 0, y: 0 },
160 colors: ['var(--ext-partner-theme-primary-text, #ffffff)'],
161 },
162 2500,
163 confettiReady,
164 )
165
166 return (
167 <Transition
168 show={isShowing}
169 appear={true}
170 enter="transition-all ease-in-out duration-500"
171 enterFrom="md:w-40vw md:max-w-md"
172 enterTo="md:w-full md:max-w-full"
173 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">
174 <div className="max-w-prose">
175 <div className="md:min-h-48">
176 {window.extOnbData?.partnerLogo && (
177 <div className="pb-8">
178 <img
179 style={{ maxWidth: '200px' }}
180 src={window.extOnbData.partnerLogo}
181 alt={window.extOnbData?.partnerName ?? ''}
182 />
183 </div>
184 )}
185 <div>
186 {info.map((step, index) => {
187 if (!index) {
188 return (
189 <Transition
190 appear={true}
191 show={isShowing}
192 enter="transition-opacity duration-1000"
193 enterFrom="opacity-0"
194 enterTo="opacity-100"
195 leave="transition-opacity duration-1000"
196 leaveFrom="opacity-100"
197 leaveTo="opacity-0"
198 className="text-4xl flex space-x-4 items-center"
199 key={step}>
200 {step}
201 </Transition>
202 )
203 }
204 })}
205 <div className="flex space-x-4 items-center mt-6">
206 <Spinner className="animate-spin" />
207 {infoDesc.map((step, index) => {
208 if (!index) {
209 return (
210 <Transition
211 appear={true}
212 show={isShowing}
213 enter="transition-opacity duration-1000"
214 enterFrom="opacity-0"
215 enterTo="opacity-100"
216 leave="transition-opacity duration-1000"
217 leaveFrom="opacity-100"
218 leaveTo="opacity-0"
219 className="text-lg"
220 key={step}>
221 {step}
222 </Transition>
223 )
224 }
225 })}
226 </div>
227 </div>
228 </div>
229 </div>
230 <div className="hidden md:flex items-center space-x-3">
231 <span className="opacity-70 text-xs">
232 {__('Powered by', 'extendify')}
233 </span>
234 <span className="relative">
235 <Logo className="logo text-partner-primary-text w-28" />
236 <span className="absolute -bottom-2 right-3 font-semibold tracking-tight">
237 Launch
238 </span>
239 </span>
240 </div>
241 </Transition>
242 )
243 }
244