PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.0.1
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.0.1
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 All 162 releases
cartflows / wizard / assets / src / wizard-steps / OptinStep.js

OptinStep.js in CartFlows – Funnel Builder & Checkout Plugin for WooCommerce 3.0.1, at wizard/assets/src/wizard-steps/OptinStep.js

356 lines 10.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import React, { useState, useEffect, useCallback } from 'react';
2 import { useHistory } from 'react-router-dom';
3 import { sprintf, __ } from '@wordpress/i18n';
4 import apiFetch from '@wordpress/api-fetch';
5 import parse from 'html-react-parser';
6 import { useStateValue } from '../utils/StateProvider';
7 import {
8 ExclamationCircleIcon,
9 ArrowRightIcon,
10 } from '@heroicons/react/24/outline';
11
12 import { CheckboxField } from '@WizardFields';
13
14 function OptinStep() {
15 const history = useHistory();
16
17 const [ requestError, setRequestError ] = useState( false );
18 const [ { action_button }, dispatch ] = useStateValue();
19
20 const [ formErrors, setFormErrors ] = useState( {
21 name_error_message: '',
22 email_error_message: '',
23 error_class: '',
24 } );
25
26 const { name_error_message, email_error_message, error_class } = formErrors;
27
28 const changeOptinButtonText = useCallback( ( data ) => {
29 dispatch( {
30 status: 'SET_NEXT_STEP',
31 action_button: data,
32 } );
33 }, [] );
34
35 const default_button_text = __( 'Save & Continue', 'cartflows' ),
36 toggle_link_title = __(
37 'Learn more about usage tracking',
38 'cartflows'
39 );
40
41 useEffect( () => {
42 // Set Foooter button text.
43 changeOptinButtonText( {
44 button_text: default_button_text,
45 button_class: 'wcf-enrol-optin',
46 } );
47 }, [ changeOptinButtonText ] );
48
49 const validateForm = function ( posted_data ) {
50 let is_errors = false;
51 const errors = {};
52
53 if ( ! posted_data.name || '' === posted_data.name ) {
54 errors.name_error_message = __( 'Please Enter Name', 'cartflows' );
55 is_errors = true;
56 }
57
58 if ( ! posted_data.email || '' === posted_data.email ) {
59 errors.email_error_message = __(
60 'Please Enter Email ID',
61 'cartflows'
62 );
63 is_errors = true;
64 } else if (
65 ! /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(
66 posted_data.email
67 )
68 ) {
69 errors.email_error_message = __(
70 'Entered email address is not a valid email',
71 'cartflows'
72 );
73 is_errors = true;
74 }
75
76 if ( is_errors ) {
77 setFormErrors( {
78 name_error_message: errors.name_error_message
79 ? errors.name_error_message
80 : '',
81 email_error_message: errors.email_error_message
82 ? errors.email_error_message
83 : '',
84 error_class:
85 '!border-red-500 focus:!ring-red-100 focus:!border-red-500',
86 } );
87 }
88
89 return is_errors;
90 };
91
92 const submitOptinForm = function ( e ) {
93 e.preventDefault();
94
95 changeOptinButtonText( {
96 button_text: __( 'Processing', 'cartflows' ),
97 button_class: 'wcf-enrol-optin',
98 } );
99
100 dispatch( {
101 status: 'PROCESSING',
102 } );
103
104 const ajaxData = new window.FormData();
105
106 ajaxData.append( 'action', 'cartflows_user_onboarding' );
107 ajaxData.append( 'security', cartflows_wizard.user_onboarding_nonce );
108
109 const name = document.getElementById( 'wcf-user-name' ).value;
110 const email = document.getElementById( 'wcf-user-email' ).value;
111 const usage_tracking_enabled = document.querySelector(
112 'input[type=checkbox][name="cf_usage_optin"]'
113 ).checked;
114
115 if ( validateForm( { name, email } ) ) {
116 changeOptinButtonText( {
117 button_text: default_button_text,
118 button_class: 'wcf-enrol-optin',
119 } );
120
121 dispatch( {
122 status: 'RESET',
123 } );
124 return;
125 }
126
127 ajaxData.append( 'user_fname', name );
128 ajaxData.append( 'user_email', email );
129 ajaxData.append(
130 'usage_tracking',
131 usage_tracking_enabled ? 'yes' : 'no'
132 );
133
134 apiFetch( {
135 url: ajaxurl,
136 method: 'POST',
137 body: ajaxData,
138 } ).then( ( response ) => {
139 if ( response.data.success ) {
140 history.push( {
141 pathname: 'index.php',
142 search: `?page=cartflow-setup&step=ready`,
143 } );
144 dispatch( {
145 status: 'RESET',
146 } );
147 } else {
148 setRequestError( response.data.message );
149 }
150
151 changeOptinButtonText( {
152 button_text: default_button_text,
153 button_class: 'wcf-enrol-optin',
154 } );
155 } );
156 };
157
158 return (
159 <div className="wcf-container">
160 <div className="wcf-row mt-12 !max-w-5xl">
161 <div className="bg-white rounded text-center mx-auto px-11">
162 <span className="text-sm font-medium text-primary-600 mb-10 text-center block tracking-[.24em] uppercase">
163 { __( 'Step 5 of 6', 'cartflows' ) }
164 </span>
165 <h1 className="wcf-step-heading mb-4">
166 { parse(
167 sprintf(
168 /* translators: %s: html tag*/
169 __(
170 "One last step. %s Let's setup email reports on how your store is doing.",
171 'cartflows'
172 ),
173 '<br />'
174 )
175 ) }
176 </h1>
177 <p className="mt-4 text-[#4B5563] text-base">
178 { parse(
179 sprintf(
180 /* translators: %1$s: html tag, %2$s: html tag*/
181 __(
182 'Let CartFlows take the guesswork out of your checkout results. Each week your store will send %1$s you an email report with key metrics and insights. You also will receive emails from us to %2$s help your store sell more.',
183 'cartflows'
184 ),
185 '<br class="hidden lg:block" />',
186 '<br class="hidden lg:block" />'
187 )
188 ) }
189 </p>
190 <form action="#" className="max-w-lg mx-auto mt-10">
191 <div className="wcf-form-fields sm:flex flex-col gap-5 text-left">
192 <div className="w-full">
193 <label
194 htmlFor="wcf-user-name"
195 className="text-slate-800 text-base font-semibold block"
196 >
197 { __( 'First Name', 'cartflows' ) }
198 </label>
199 <div className="relative block">
200 <input
201 id="wcf-user-name"
202 type="text"
203 className={ `wcf-input !my-2 !px-3.5 !py-2.5 !shadow-sm block w-full !text-sm !border-gray-300 !rounded !text-gray-500 !placeholder-slate-400 focus:ring focus:!shadow-none ${
204 error_class
205 ? error_class
206 : 'focus:!ring-indigo-100 focus:!border-indigo-500'
207 }` }
208 placeholder={ __(
209 'Please enter your name',
210 'cartflows'
211 ) }
212 defaultValue={
213 cartflows_wizard.current_user_name
214 }
215 />
216 { name_error_message && (
217 <div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
218 <ExclamationCircleIcon
219 className="h-5 w-5 text-red-500"
220 aria-hidden="true"
221 />
222 </div>
223 ) }
224 </div>
225 { name_error_message && (
226 <>
227 <span className="text-red-500 text-sm block">
228 { name_error_message }
229 </span>
230 </>
231 ) }
232 </div>
233 <div className="w-full">
234 <label
235 htmlFor="wcf-user-email"
236 className="text-slate-800 text-base font-semibold block"
237 >
238 { __( 'Email address', 'cartflows' ) }
239 </label>
240 <div className="relative block">
241 <input
242 id="wcf-user-email"
243 type="email"
244 className={ `wcf-input !my-2 !px-3.5 !py-2.5 !shadow-sm block w-full !text-sm !border-gray-300 !rounded !text-gray-500 !placeholder-slate-400 focus:ring focus:!shadow-none ${
245 error_class
246 ? error_class
247 : 'focus:!ring-indigo-100 focus:!border-indigo-500'
248 }` }
249 placeholder={ __(
250 'Enter Your Email',
251 'cartflows'
252 ) }
253 defaultValue={
254 cartflows_wizard.current_user_email
255 }
256 />
257 { email_error_message && (
258 <div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
259 <ExclamationCircleIcon
260 className="h-5 w-5 text-red-500"
261 aria-hidden="true"
262 />
263 </div>
264 ) }
265 </div>
266
267 { email_error_message && (
268 <>
269 <span className="text-red-500 text-sm block">
270 { email_error_message }
271 </span>
272 </>
273 ) }
274 </div>
275
276 <div className="w-ful">
277 <div className="relative block">
278 <CheckboxField
279 class="wcf-analytics_optin"
280 name="cf_usage_optin"
281 value="yes"
282 label={ __(
283 'I agree to share usage data to help improve CartFlows.',
284 'cartflows'
285 ) }
286 desc={ sprintf(
287 /* translators: %1$s: anchor tag start, %2$s: anchor tag close*/
288 __(
289 "We don't collect any personal information—just basic details like your PHP version, admin language, and which features you use. %1$sLearn more%2$s about what we collect and why.",
290 'cartflows'
291 ),
292 '<a href="https://my.cartflows.com/usage-tracking/" target="_blank" class="text-primary-500 hover:text-primary-600" title="' +
293 toggle_link_title +
294 '">',
295 '</a>'
296 ) }
297 />
298 </div>
299 </div>
300 </div>
301
302 <div className="wcf-action-buttons mt-[40px] block w-full">
303 { requestError && (
304 <span className="text-red-700 mb-2 text-sm block">
305 { requestError }
306 </span>
307 ) }
308 <button
309 onClick={ submitOptinForm }
310 className={ `wcf-wizard--button w-full ${
311 action_button.button_class
312 ? action_button.button_class
313 : ''
314 }` }
315 >
316 { action_button.button_text }
317 <ArrowRightIcon
318 className="w-5 ml-1.5 stroke-2"
319 aria-hidden="true"
320 />
321 </button>
322 </div>
323 <p className="wcf-tc-statement mt-6 text-sm text-[#4B5563]">
324 { parse(
325 sprintf(
326 /* translators: %1$s: Anchor tag one start, %2$s: Anchor tag one close, %3$s: Anchor tag two start, %4$s: Anchor tag two close. */
327 __(
328 'By continuing you agree to our %1$sTerms%2$s and %3$sPrivacy Policy%4$s.',
329 'cartflows'
330 ),
331 '<a href="https://cartflows.com/terms-and-conditions/?utm_source=dashboard&utm_medium=free-cartflows&utm_campaign=terms_conditions" target="_blank" class="text-primary-500 hover:text-primary-600">',
332 '</a>',
333 '<a href="https://cartflows.com/privacy-policy/?utm_source=dashboard&utm_medium=free-cartflows&utm_campaign=privacy_policy" target="_blank" class="text-primary-500 hover:text-primary-600">',
334 '</a>'
335 )
336 ) }
337 </p>
338 </form>
339 { /* { 'processing' !== settingsProcess && (
340 <p className="mt-6 flex justify-center">
341 <button
342 onClick={ handleNextStep }
343 className="p-2 font-normal text-gray-300 hover:text-gray-500 cursor-pointer"
344 >
345 { __( 'Maybe Later', 'cartflows' ) }
346 </button>
347 </p>
348 ) } */ }
349 </div>
350 </div>
351 </div>
352 );
353 }
354
355 export default OptinStep;
356