← All changes
|
src/Shared/components/ProductAccountActivation/ProductAccountActivation.jsx
+50
-48
3.2.0
→
trunk
View file →
| @@ -1,14 +1,15 @@ | ||
| 1 | 1 | import { Dialog, DialogBackdrop, DialogPanel } from '@headlessui/react'; |
| 2 | 2 | import { prewarmRecaptcha } from '@shared/api/pluginsActivation'; |
| 3 | 3 | import { useEffect, useState } from '@wordpress/element'; |
| 4 | 4 | import { isEmail } from '@wordpress/url'; |
| 5 | +import { accountContext } from './accountContext'; | |
| 5 | 6 | import { createAccount } from './createAccount'; |
| 6 | -import { Loading } from './Loading'; | |
| 7 | 7 | import { partitionPlugins } from './partitionPlugins'; |
| 8 | 8 | import { SetupComplete } from './SetupComplete'; |
| 9 | 9 | import { SetupPlugins } from './SetupPlugins'; |
| 10 | 10 | import { |
| 11 | + ACCOUNT_STATUS, | |
| 11 | 12 | ACTIVATION_STATUS, |
| 12 | 13 | usePluginsActivation, |
| 13 | 14 | } from './usePluginsActivation'; |
| 14 | 15 | |
| @@ -13,10 +14,9 @@ | ||
| 13 | 14 | } from './usePluginsActivation'; |
| 14 | 15 | |
| 15 | 16 | export const ProductAccountActivation = () => { |
| 16 | 17 | const [isOpen, setIsOpen] = useState(true); |
| 17 | - const [isLoading, setIsLoading] = useState(false); | |
| 18 | - const [isFinished, setIsFinished] = useState(false); | |
| 18 | + const [submitted, setSubmitted] = useState(null); | |
| 19 | 19 | const { offered, ineligible } = partitionPlugins( |
| 20 | 20 | window.extSharedData?.showProductActivation, |
| 21 | 21 | ); |
| 22 | 22 | const [plugins, setPlugins] = useState(offered); |
| @@ -49,59 +49,62 @@ | ||
| 49 | 49 | }); |
| 50 | 50 | setIsOpen(false); |
| 51 | 51 | }; |
| 52 | 52 | |
| 53 | + const trackStatus = (slug, request) => { | |
| 54 | + const record = (status) => | |
| 55 | + setSubmitted((current) => | |
| 56 | + current.map((plugin) => | |
| 57 | + plugin.slug === slug ? { ...plugin, status } : plugin, | |
| 58 | + ), | |
| 59 | + ); | |
| 60 | + | |
| 61 | + request.then( | |
| 62 | + () => record(ACCOUNT_STATUS.success), | |
| 63 | + () => record(ACCOUNT_STATUS.error), | |
| 64 | + ); | |
| 65 | + | |
| 66 | + return request; | |
| 67 | + }; | |
| 68 | + | |
| 53 | 69 | const handleCreateAccounts = async () => { |
| 54 | 70 | if (!isEmail(email)) return; |
| 55 | 71 | |
| 56 | - setIsLoading(true); | |
| 72 | + const selectedPlugins = plugins.filter((plugin) => plugin.selected); | |
| 57 | 73 | |
| 58 | - const selectedPlugins = plugins?.filter((plugin) => plugin.selected) ?? []; | |
| 74 | + setSubmitted( | |
| 75 | + selectedPlugins.map((plugin) => ({ | |
| 76 | + ...plugin, | |
| 77 | + status: ACCOUNT_STATUS.pending, | |
| 78 | + })), | |
| 79 | + ); | |
| 59 | 80 | |
| 60 | - const results = await Promise.allSettled( | |
| 81 | + const settling = Promise.allSettled( | |
| 61 | 82 | selectedPlugins.map((plugin) => |
| 62 | - createAccount(plugin, { | |
| 63 | - email, | |
| 64 | - marketingConsent, | |
| 65 | - termsAgreed, | |
| 66 | - scriptData: { ...scriptData?.[plugin.slug], ...plugin.scriptData }, | |
| 67 | - }), | |
| 83 | + trackStatus( | |
| 84 | + plugin.slug, | |
| 85 | + createAccount(plugin, { | |
| 86 | + email, | |
| 87 | + marketingConsent, | |
| 88 | + termsAgreed, | |
| 89 | + scriptData: { ...scriptData?.[plugin.slug], ...plugin.scriptData }, | |
| 90 | + }), | |
| 91 | + ), | |
| 68 | 92 | ), |
| 69 | 93 | ); |
| 70 | 94 | |
| 71 | - const context = Object.fromEntries( | |
| 72 | - selectedPlugins.map((plugin, index) => { | |
| 73 | - const result = results[index]; | |
| 74 | - const { | |
| 75 | - requestTimeInMs, | |
| 76 | - captchaTimeInMs, | |
| 77 | - captchaWasWarm, | |
| 78 | - stepTimeInMs, | |
| 79 | - retries, | |
| 80 | - errors, | |
| 81 | - } = result.status === 'fulfilled' ? result.value : result.reason; | |
| 82 | - const entry = { | |
| 83 | - status: result.status === 'fulfilled' ? 'success' : 'error', | |
| 84 | - requestTimeInMs, | |
| 85 | - captchaTimeInMs, | |
| 86 | - captchaWasWarm, | |
| 87 | - stepTimeInMs, | |
| 88 | - endpoint: plugin.endpoint, | |
| 89 | - extendifyVersion: window.extSharedData?.version, | |
| 90 | - retries, | |
| 91 | - ...(errors.length > 0 && { errors }), | |
| 92 | - }; | |
| 93 | - return [plugin.slug, entry]; | |
| 94 | - }), | |
| 95 | - ); | |
| 95 | + // A record stuck on pending is a user who left before the answer. | |
| 96 | + await activatePlugins({ | |
| 97 | + status: ACTIVATION_STATUS.completed, | |
| 98 | + context: accountContext(selectedPlugins), | |
| 99 | + }); | |
| 96 | 100 | |
| 101 | + const results = await settling; | |
| 102 | + | |
| 97 | 103 | await activatePlugins({ |
| 98 | 104 | status: ACTIVATION_STATUS.completed, |
| 99 | - context, | |
| 105 | + context: accountContext(selectedPlugins, results), | |
| 100 | 106 | }); |
| 101 | - | |
| 102 | - setIsFinished(true); | |
| 103 | - setIsLoading(false); | |
| 104 | 107 | }; |
| 105 | 108 | |
| 106 | 109 | return ( |
| 107 | 110 | plugins.length > 0 && ( |
| @@ -118,9 +121,14 @@ | ||
| 118 | 121 | transition |
| 119 | 122 | className="relative w-full max-w-208 max-h-full overflow-hidden flex flex-col bg-white rounded-lg shadow-xl transition-all data-closed:opacity-0 data-closed:scale-95" |
| 120 | 123 | > |
| 121 | 124 | <div className="overflow-y-auto"> |
| 122 | - {!isFinished && !isLoading && ( | |
| 125 | + {submitted ? ( | |
| 126 | + <SetupComplete | |
| 127 | + plugins={submitted} | |
| 128 | + handleClose={() => setIsOpen(false)} | |
| 129 | + /> | |
| 130 | + ) : ( | |
| 123 | 131 | <SetupPlugins |
| 124 | 132 | plugins={plugins} |
| 125 | 133 | setPlugins={setPlugins} |
| 126 | 134 | handleCreateAccounts={handleCreateAccounts} |
| @@ -131,14 +139,8 @@ | ||
| 131 | 139 | setMarketingConsent={setMarketingConsent} |
| 132 | 140 | termsAgreed={termsAgreed} |
| 133 | 141 | setTermsAgreed={setTermsAgreed} |
| 134 | 142 | /> |
| 135 | - )} | |
| 136 | - | |
| 137 | - {!isFinished && isLoading && <Loading />} | |
| 138 | - | |
| 139 | - {isFinished && ( | |
| 140 | - <SetupComplete handleClose={() => setIsOpen(false)} /> | |
| 141 | 143 | )} |
| 142 | 144 | </div> |
| 143 | 145 | </DialogPanel> |
| 144 | 146 | </div> |