PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 3.10.6
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v3.10.6
3.13.3 3.13.2 3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 All 261 releases
wpfunnels / admin / modules / setup-wizard / components / Content / Setup.vue

Setup.vue in WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell 3.10.6, at admin/modules/setup-wizard/components/Content/Setup.vue

416 lines 11.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <div class="wpfnl-mm-setup">
3 <!-- Header -->
4 <div class="wpfnl-mm-setup-header">
5 <h2 class="wpfnl-mm-setup-title">Let’s Make Sure Your Store Is Ready</h2>
6 <p class="wpfnl-mm-setup-subtitle">
7 We're checking your {{ selectedGoal === 'sales' ? 'WooCommerce setup,' : '' }} page builder, and essential plugins.
8 </p>
9 </div>
10
11 <WooCommerce
12 v-if="selectedGoal === 'sales'"
13 :isInstalled="wooCommerce.installed"
14 :isActive="wooCommerce.active"
15 />
16 <PageBuilders
17 :selectedBuilder="selectedBuilder"
18 :builderStatuses="builderStatuses"
19 @update:selectedBuilder="updateSelectedBuilder"
20 />
21 <EssentialPlugins
22 :selectedGoal="selectedGoal"
23 :pluginStatuses="pluginStatuses"
24 :selectedPlugins="selectedPlugins"
25 @update:selectedPlugins="updateSelectedPlugins"
26 />
27
28 <!-- Buttons -->
29 <div class="wpfnl-mm-choose-goal-buttons wpfnl-mm-buttons-container">
30 <button class="wpfnl-mm-btn wpfnl-mm-btn-secondary" @click="goBack" :disabled="isProcessing">
31 Back
32 </button>
33 <div class="wpfnl-mm-btn-group">
34 <button
35 class="wpfnl-mm-btn wpfnl-mm-btn-primary"
36 @click="handleContinue"
37 :disabled="isProcessing"
38 >
39 <span v-if="!isProcessing">Continue</span>
40 <span v-else>Processing...</span>
41 <svg v-if="!isProcessing" width="17" height="12" viewBox="0 0 17 12" fill="none" xmlns="http://www.w3.org/2000/svg">>
42 <path d="M1 6H16M16 6L11 1M16 6L11 11" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
43 </svg>
44 <svg v-else class="wpfnl-spinner" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">>
45 <circle cx="8" cy="8" r="6" stroke="white" stroke-width="2" stroke-dasharray="30 10" stroke-linecap="round"/>
46 </svg>
47 </button>
48 </div>
49 </div>
50
51 </div>
52 </template>
53
54 <script>
55 import WooCommerce from './WooCommerce.vue';
56 import PageBuilders from './PageBuilders.vue';
57 import EssentialPlugins from './EssentialPlugins.vue';
58
59 export default {
60 name: 'Setup',
61 props: {
62 selectedGoal: {
63 type: String,
64 default: 'sales'
65 }
66 },
67 components: {
68 WooCommerce,
69 PageBuilders,
70 EssentialPlugins,
71 },
72 data() {
73 return {
74 // WooCommerce states
75 wooCommerce: {
76 installed: false,
77 active: false
78 },
79
80 // Builder states
81 selectedBuilder: 'gutenberg',
82 builderStatuses: {},
83
84 // Plugin states
85 pluginStatuses: {},
86 selectedPlugins: [],
87
88 // Processing state
89 isProcessing: false,
90 }
91 },
92 mounted() {
93 this.checkPluginStatuses();
94 },
95 watch: {
96 selectedGoal() {
97 this.checkPluginStatuses();
98 }
99 },
100 methods: {
101 async checkPluginStatuses() {
102 // Check WooCommerce status if sales goal is selected
103 if (this.selectedGoal === 'sales') {
104 const isWooInstalled = window?.setup_wizard_obj?.is_woo_installed === 'yes';
105 const isWooActive = window?.setup_wizard_obj?.is_woo_active === 'yes';
106
107 this.wooCommerce.installed = isWooInstalled;
108 this.wooCommerce.active = isWooActive;
109 }
110
111 // Check page builder statuses and auto-select
112 this.detectAndSelectBuilder();
113
114 // Check essential plugin statuses
115 this.checkEssentialPlugins();
116 },
117
118 detectAndSelectBuilder() {
119 // Get plugin/theme statuses from server-provided getPlugins data
120 const getPlugins = window?.setup_wizard_obj?.getPlugins || [];
121 const oxygenData = getPlugins.find(p => p.name === 'oxygen');
122 const bricksData = getPlugins.find(p => p.name === 'bricks');
123 const diviData = getPlugins.find(p => p.name === 'divi');
124
125 const builderChecks = [
126 { id: 'elementor', installed: window?.setup_wizard_obj?.is_elementor_installed === 'yes', active: window?.setup_wizard_obj?.is_elementor_active === 'yes' },
127 { id: 'bricks', installed: bricksData?.status === 'activated' || bricksData?.status === 'installed', active: bricksData?.status === 'activated' },
128 { id: 'divi', installed: diviData?.status === 'activated' || diviData?.status === 'installed', active: diviData?.status === 'activated' },
129 { id: 'oxygen', installed: oxygenData?.status === 'activated' || oxygenData?.status === 'installed', active: oxygenData?.status === 'activated' }
130 ];
131
132 // Build builder statuses map for the PageBuilders component
133 const statuses = {};
134 builderChecks.forEach(b => {
135 statuses[b.id] = { installed: b.installed, active: b.active };
136 });
137 // Gutenberg and Others are always available
138 statuses['gutenberg'] = { installed: true, active: true };
139 statuses['others'] = { installed: true, active: true };
140 this.builderStatuses = statuses;
141
142 // Find first installed and active builder
143 const activeBuilder = builderChecks.find(b => b.installed && b.active);
144
145 if (activeBuilder) {
146 this.selectedBuilder = activeBuilder.id;
147 } else {
148 // Default to Gutenberg
149 this.selectedBuilder = 'gutenberg';
150 }
151 },
152
153 checkEssentialPlugins() {
154 const statuses = {};
155
156 // Check Mail Mint
157 statuses['mail-mint'] = {
158 installed: window?.setup_wizard_obj?.is_mrm_installed === 'yes',
159 active: window?.setup_wizard_obj?.is_mrm_active === 'yes'
160 };
161
162 // Initialize selected plugins based on installation status
163 this.selectedPlugins = ['mail-mint']; // Mail Mint always selected by default
164
165 if (this.selectedGoal === 'sales') {
166 // For sales goal, add payment plugins if installed
167 // These would need to be checked from the server
168 // For now, we'll add them to the list
169 }
170
171 this.pluginStatuses = statuses;
172 },
173
174 updateSelectedBuilder(builderId) {
175 this.selectedBuilder = builderId;
176 },
177
178 updateSelectedPlugins(plugins) {
179 this.selectedPlugins = plugins;
180 },
181
182 async installPlugin(slug) {
183 return new Promise((resolve, reject) => {
184 // Use WordPress native plugin installer
185 wp.updates.ajax('install-plugin', {
186 slug: slug,
187 success: () => {
188 resolve(true);
189 },
190 error: (error) => {
191 console.error(`Error installing plugin ${slug}:`, error);
192 resolve(false);
193 }
194 });
195 });
196 },
197
198 async activatePlugin(basename) {
199 return new Promise((resolve, reject) => {
200 // Use WordPress AJAX to activate plugin
201 const ajaxUrl = window.ajaxurl || window.location.origin + '/wp-admin/admin-ajax.php';
202
203 // Use special handler for Mail Mint to ensure database initialization
204 const action = basename === 'mail-mint/mail-mint.php'
205 ? 'wpfnl_activate_mail_mint'
206 : 'wpfnl_activate_plugin';
207
208 const data = {
209 action: action
210 };
211
212 // Add plugin parameter for generic activation
213 if (action === 'wpfnl_activate_plugin') {
214 data.plugin = basename;
215 }
216
217 jQuery.ajax({
218 url: ajaxUrl,
219 type: 'POST',
220 data: data,
221 success: (response) => {
222
223 if (response.success) {
224 resolve(true);
225 } else {
226 console.error(`Plugin activation failed:`, response.data);
227 resolve(false);
228 }
229 },
230 error: (xhr, status, error) => {
231 console.error(`AJAX Error activating plugin ${basename}:`, {
232 status: xhr.status,
233 statusText: xhr.statusText,
234 responseText: xhr.responseText,
235 error: error
236 });
237 // Try to continue even if activation fails (might already be active)
238 resolve(false);
239 }
240 });
241 });
242 },
243
244 async installAndActivatePlugin(slug, basename, isInstalled = false) {
245 try {
246 // If not installed, install it first
247 if (!isInstalled) {
248 const installed = await this.installPlugin(slug);
249
250 if (!installed) {
251 console.error(`Failed to install plugin: ${slug}`);
252 return false;
253 }
254
255 // Small delay to ensure plugin files are ready
256 await new Promise(resolve => setTimeout(resolve, 1500));
257 }
258
259 // Activate the plugin
260 const activated = await this.activatePlugin(basename);
261
262 return activated;
263 } catch (error) {
264 console.error('Error installing and activating plugin:', error);
265 return false;
266 }
267 },
268
269 async installWooCommerce() {
270 if (this.selectedGoal !== 'sales') return true;
271
272 // If WooCommerce is already installed and active, skip
273 if (this.wooCommerce.installed && this.wooCommerce.active) {
274 return true;
275 }
276
277 try {
278 const success = await this.installAndActivatePlugin(
279 'woocommerce',
280 'woocommerce/woocommerce.php',
281 this.wooCommerce.installed
282 );
283
284 if (success) {
285 this.wooCommerce.installed = true;
286 this.wooCommerce.active = true;
287 }
288
289 return success;
290 } catch (error) {
291 console.error('Error installing WooCommerce:', error);
292 return false;
293 }
294 },
295
296 async installBuilder() {
297 // If Gutenberg or Others selected, no installation needed
298 if (this.selectedBuilder === 'gutenberg' || this.selectedBuilder === 'others') {
299 return true;
300 }
301
302 const builderMap = {
303 'elementor': { slug: 'elementor', basename: 'elementor/elementor.php', installedKey: 'is_elementor_installed', activeKey: 'is_elementor_active' },
304 'divi': { slug: 'divi-builder', basename: 'divi-builder/divi-builder.php', installedKey: null, activeKey: null },
305 'oxygen': { slug: 'oxygen', basename: 'oxygen/functions.php', installedKey: null, activeKey: null },
306 'bricks': { slug: 'bricks', basename: 'bricks', isTheme: true, installedKey: null, activeKey: null }
307 };
308
309 const builder = builderMap[this.selectedBuilder];
310 if (!builder) return true;
311
312 // Check if already installed and active
313 const isInstalled = builder.installedKey ? window?.setup_wizard_obj?.[builder.installedKey] === 'yes' : false;
314 const isActive = builder.activeKey ? window?.setup_wizard_obj?.[builder.activeKey] === 'yes' : false;
315
316 if (isInstalled && isActive) {
317 return true;
318 }
319
320 try {
321 if (builder.isTheme) {
322 // For themes, we'd need a different approach
323 return true;
324 }
325
326 const success = await this.installAndActivatePlugin(builder.slug, builder.basename, isInstalled);
327 return success;
328 } catch (error) {
329 console.error('Error installing builder:', error);
330 return false;
331 }
332 },
333
334 async installSelectedPlugins() {
335 const pluginMap = {
336 'mail-mint': {
337 slug: 'mail-mint',
338 basename: 'mail-mint/mail-mint.php',
339 installedKey: 'is_mrm_installed',
340 activeKey: 'is_mrm_active'
341 },
342 'woocommerce-payments': {
343 slug: 'woocommerce-payments',
344 basename: 'woocommerce-payments/woocommerce-payments.php',
345 installedKey: null,
346 activeKey: null
347 },
348 'stripe': {
349 slug: 'woo-stripe-payment',
350 basename: 'woo-stripe-payment/stripe-payments.php',
351 installedKey: null,
352 activeKey: null
353 }
354 };
355
356 for (const pluginId of this.selectedPlugins) {
357 const plugin = pluginMap[pluginId];
358 if (!plugin) continue;
359
360 // Check if already installed and active
361 const isInstalled = plugin.installedKey ? window?.setup_wizard_obj?.[plugin.installedKey] === 'yes' : false;
362 const isActive = plugin.activeKey ? window?.setup_wizard_obj?.[plugin.activeKey] === 'yes' : false;
363
364 if (isInstalled && isActive) {
365 continue;
366 }
367
368 try {
369 await this.installAndActivatePlugin(plugin.slug, plugin.basename, isInstalled);
370 } catch (error) {
371 console.error(`Error installing ${pluginId}:`, error);
372 }
373 }
374
375 return true;
376 },
377
378 async handleContinue() {
379 this.isProcessing = true;
380
381 try {
382 // Step 1: Install WooCommerce if needed (for sales goal)
383 if (this.selectedGoal === 'sales') {
384 await this.installWooCommerce();
385 }
386
387 // Step 2: Install selected page builder if needed
388 await this.installBuilder();
389
390 // Step 3: Install selected essential plugins
391 await this.installSelectedPlugins();
392
393 // Map "others" to "gutenberg" for template compatibility
394 const builderForTemplates = this.selectedBuilder === 'others' ? 'gutenberg' : this.selectedBuilder;
395
396 // Proceed to next step
397 this.$emit('next-step', {
398 builder: builderForTemplates,
399 wooInstalled: this.wooCommerce.installed,
400 wooActivated: this.wooCommerce.active
401 });
402 } catch (error) {
403 console.error('Error during setup:', error);
404 alert('An error occurred during setup. Please try again.');
405 } finally {
406 this.isProcessing = false;
407 }
408 },
409
410 goBack() {
411 this.$emit('prev-step');
412 }
413 }
414 }
415 </script>
416