PluginProbe ʕ •ᴥ•ʔ
Flex Import / 1.9
Flex Import v1.9
2.9 trunk 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8
flex-import / assets / js / template-admin.js
flex-import / assets / js Last commit date
admin-script.js 11 months ago dashboard-posts.js 11 months ago front-script.js 11 months ago jquery.notify.min.js 11 months ago license_script.js 11 months ago plugin-admin.js 11 months ago template-admin.js 11 months ago
template-admin.js
500 lines
1 document.addEventListener('DOMContentLoaded', function () {
2 const templatesApiEndpoint = fleximp_template_ajax_object.apiEndpoint;
3 let isFetchingTemplates = false;
4 let isFetchingCategories = false;
5
6 // Fetch Templates
7 function fetchTemplates() {
8 if (isFetchingTemplates) return;
9 isFetchingTemplates = true;
10
11 fetch(templatesApiEndpoint, {
12 method: 'POST',
13 headers: {
14 'Content-Type': 'application/json'
15 },
16 body: JSON.stringify({
17 action: 'getTemplates'
18 })
19 })
20 .then(response => response.json())
21 .then(data => {
22 if (data.success && data.data && Array.isArray(data.data.data.posts)) {
23 displayTemplates(data.data.data.posts);
24 } else {
25 console.error('Error fetching templates:', data);
26 }
27 })
28 .catch(error => {
29 console.error('Error:', error);
30 })
31 .finally(() => {
32 isFetchingTemplates = false;
33 });
34 }
35
36 // Fetch Categories
37 function fetchCategories() {
38 if (isFetchingCategories) return;
39 isFetchingCategories = true;
40
41 fetch(templatesApiEndpoint, {
42 method: 'POST',
43 headers: {
44 'Content-Type': 'application/json'
45 },
46 body: JSON.stringify({
47 action: 'getCategories'
48 })
49 })
50 .then(response => response.json())
51 .then(data => {
52 if (data.success && Array.isArray(data.data
53 .data)) {
54 displayCategories(data.data.data);
55 } else {
56 console.error('Error fetching categories:', data);
57 }
58 })
59 .catch(error => {
60 console.error('Error:', error);
61 })
62 .finally(() => {
63 isFetchingCategories = false;
64 });
65 }
66
67 // Display Templates
68 function displayTemplates(templates) {
69 const templatesListContainer = document.getElementById('templates-list');
70 templatesListContainer.innerHTML = '';
71
72 templates.forEach(template => {
73 const templateSlug = template.title.toLowerCase().replace(/ /g, '-');
74 const demoUrl = template.metafields?.demo_url || '#';
75 const selectedPlugins = template.metafields?.selected_plugins || [];
76 const jsonPath = template.metafields?.json_path || '';
77 const templateMainImage = template.metafields?.template_main_image || '';
78 const templateMobileImage = template.metafields?.template_mobile_image || '';
79 const templateResponsiveImage = template.metafields?.template_responsive_image || '';
80 const contentPath = template.metafields?.content_path || '';
81 const textDomain = template.template_domain || '';
82 const templateCss = template.metafields?.template_css_path || '';
83 const templateJs = template.metafields?.template_js_path || '';
84 const isPremium = template.metafields?.free_pro === 'Pro';
85 // const isUserPremium = fleximp_template_ajax_object.isPremiumUser === true || fleximp_template_ajax_object.isPremiumUser === '1';
86 const isUserPremium = fleximp_template_ajax_object.isPremiumUser;
87 const isImported = fleximp_template_ajax_object.imported_template;
88 const fleximpCurrentTextDomain = fleximp_template_ajax_object.fleximp_current_text_domain;
89 let buttonHTML = '';
90 // new add
91 if (isPremium && !isUserPremium) {
92 buttonHTML = `
93 <a href="https://www.flextheme.net/products/flex-pro-wordpress-theme" target="_blank" class="btn flex-template-buttons get-pro-btn">
94 <svg viewBox="0 0 64 64" width="512" xmlns="http://www.w3.org/2000/svg" id="fi_3777733"><g id="Icon"><path d="m59.45 19.31a1 1 0 0 0 -1.15.18l-12.08 11.89-13.35-23.17a1.06 1.06 0 0 0 -1.74 0l-13.35 23.17-12.08-11.89a1 1 0 0 0 -1.7.86l4 26.8a1 1 0 0 0 1 .85h46a1 1 0 0 0 1-.85l4-26.8a1 1 0 0 0 -.55-1.04z"></path></g></svg>
95 Get Pro
96 </a>`;
97 } else {
98 if (isImported === textDomain) {
99 // Show Uninstall Button
100 buttonHTML = `
101 <button
102 class="btn flex-template-buttons uninstall-btn"
103 data-template="${templateSlug}" data-title="${template.title}"
104 data-plugins='${JSON.stringify(selectedPlugins)}'
105 data-json-path="${jsonPath}"
106 data-template-main-image="${templateMainImage}"
107 data-template-mobile-image="${templateMobileImage}"
108 data-template-responsive-image="${templateResponsiveImage}"
109 data-content-path="${contentPath}"
110 data-text-domain="${textDomain}"
111 data-template-css="${templateCss}"
112 data-template-js="${templateJs}">
113 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="15" height="15"><path d="M135.2 17.7C140.4 7.1 150.9 0 162.7 0h186.7c11.8 0 22.3 7.1 27.5 17.7L416 64h80c17.7 0 32 14.3 32 32s-14.3 32-32 32h-16v304c0 44.2-35.8 80-80 80H160c-44.2 0-80-35.8-80-80V128H64c-17.7 0-32-14.3-32-32s14.3-32 32-32h80l23.2-46.3zM160 128v304h192V128H160z"/></svg>
114 Uninstall
115 </button>
116 `;
117 } else if (fleximp_template_ajax_object.isElementorActive === '1') {
118 let isDisabled = fleximpCurrentTextDomain != textDomain && fleximpCurrentTextDomain != '' ? 'disabled title="first uninstall imported template"' : '';
119 buttonHTML = `
120 <button
121 class="btn flex-unique-import-button flex-template-buttons import-btn"
122 ${isDisabled}
123 data-template="${templateSlug}"
124 data-title="${template.title}"
125 data-plugins='${JSON.stringify(selectedPlugins)}'
126 data-json-path="${jsonPath}"
127 data-template-main-image="${templateMainImage}"
128 data-template-mobile-image="${templateMobileImage}"
129 data-template-responsive-image="${templateResponsiveImage}"
130 data-content-path="${contentPath}"
131 data-text-domain="${textDomain}"
132 data-template-css="${templateCss}"
133 data-template-js="${templateJs}">
134 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M128 64c0-35.3 28.7-64 64-64L352 0l0 128c0 17.7 14.3 32 32 32l128 0 0 288c0 35.3-28.7 64-64 64l-256 0c-35.3 0-64-28.7-64-64l0-112 174.1 0-39 39c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l80-80c9.4-9.4 9.4-24.6 0-33.9l-80-80c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l39 39L128 288l0-224zm0 224l0 48L24 336c-13.3 0-24-10.7-24-24s10.7-24 24-24l104 0zM512 128l-128 0L384 0 512 128z"/></svg>
135 Import
136 </button>
137 `;
138 } else {
139 // Elementor is NOT active, show disabled message
140 buttonHTML = `
141 <button class="btn flex-template-buttons btn-disabled" disabled title="Please install and activate Elementor to import templates.">
142 Elementor Required
143 </button>
144 `;
145 }
146 }
147
148 // end
149 const templateHTML = `
150 <div class="template-item grid-item" style="position: relative;">
151 <div class="flex-imp-temp-inner-box"><img src="${templateMainImage}" alt="${template.title}" style=""></div>
152
153 ${isPremium ? `
154 <div class="premium-badge" style="
155 position: absolute;
156 top: 10px;
157 left: 10px;
158 background-color: rgba(0, 0, 0, 0.6);
159 color: #fff;
160 padding: 4px 8px;
161 font-size: 12px;
162 border-radius: 4px;
163 display: flex;
164 align-items: center;
165 gap: 5px;">
166 <svg xmlns="http://www.w3.org/2000/svg" height="14" width="12" viewBox="0 0 448 512" fill="currentColor">
167 <path d="..."/>
168 </svg> Premium
169 </div>` : ''
170 }
171 <div class="fleximp-temp-buttons widgets-btn">
172 <div class="buttons widgets-btn">
173 <div class="btn-title">
174 <p class="template-title">${template.title}</p>
175 </div>
176 <div class="d-flex flex-gap-div">
177 <a href="${demoUrl}" target="_blank" class="btn flex-template-buttons">
178 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"> <path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM144 256a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm144-64c0 35.3-28.7 64-64 64c-7.1 0-13.9-1.2-20.3-3.3c-5.5-1.8-11.9 1.6-11.7 7.4c.3 6.9 1.3 13.8 3.2 20.7c13.7 51.2 66.4 81.6 117.6 67.9s81.6-66.4 67.9-117.6c-11.1-41.5-47.8-69.4-88.6-71.1c-5.8-.2-9.2 6.1-7.4 11.7c2.1 6.4 3.3 13.2 3.3 20.3z"></path> </svg>Demo</a>
179 </a>
180 ${buttonHTML}
181 </div>
182 </div>
183 </div>
184 </div>
185 `;
186
187 templatesListContainer.innerHTML += templateHTML;
188 });
189
190
191
192 }
193
194 // Display Categories
195 function displayCategories(categories) {
196 const categoriesListContainer = document.querySelector('#categories-list ul');
197 categoriesListContainer.innerHTML = '';
198 categories.forEach(category => {
199 const categoryHTML = `<li>${category.name}</li>`;
200 categoriesListContainer.innerHTML += categoryHTML;
201 });
202 }
203
204 // for loader
205 function updateProgress(percent, message) {
206 const progressBar = document.getElementById('import-progress-bar');
207 const progressText = document.getElementById('import-progress-text');
208 if (progressBar && progressText) {
209 progressBar.style.width = percent + '%';
210 progressText.textContent = `${message} (${percent}%)`;
211 }
212 }
213 //end
214
215 document.addEventListener('click', function (event) {
216 if (event.target.classList.contains('flex-unique-import-button')) {
217
218 const templateTitle = event.target.getAttribute('data-title');
219 const templateMobileImage = event.target.getAttribute('data-template-mobile-image');
220
221
222 const textDomain = event.target.getAttribute('data-text-domain');
223 const jsonPath = event.target.getAttribute('data-json-path');
224 const contentPath = event.target.getAttribute('data-content-path');
225 const templateCss = event.target.getAttribute('data-template-css');
226 const templateJs = event.target.getAttribute('data-template-js');
227 const plugins = event.target.getAttribute('data-plugins');
228 const templateResponsiveImage = event.target.getAttribute('data-template-responsive-image');
229
230 // Check if modal elements exist
231 const modal = document.getElementById('import-modal');
232 const modalTitle = document.getElementById('modal-template-title');
233 // For Step 2
234 const modalMobileTitle = document.getElementById('modal-template-mobile-title'); // Mobile title in Step 2
235 const modalMobileImage = document.getElementById('modal-template-mobile-image'); // Mobile image in Step 2
236 //new one
237 const modalTemplateImage = document.getElementById('modal-template-responsive-image'); // last one img
238 if (modal && modalTitle && modalMobileTitle && modalMobileImage && modalTemplateImage) {
239 // Set Step 1 Data
240 modalTitle.textContent = `${templateTitle}`;
241 // Set Step 2 Data (Mobile Image and Title)
242 modalMobileTitle.textContent = `${templateTitle}`; // Set title
243 modalMobileImage.src = templateMobileImage; // Set mobile img
244 //new
245 modalTemplateImage.src = templateResponsiveImage;
246 modal.style.display = 'block';
247 } else {
248 console.error('Modal or modal title/image element is missing in the DOM.');
249 }
250 // Now set up confirm import button click
251 const confirmBtn = document.getElementById('flex-confirm-import');
252 if (confirmBtn) {
253 // Remove existing listener if needed, or use once:true
254 confirmBtn.addEventListener('click', function () {
255 const data = {
256 textDomain: textDomain,
257 jsonPath: jsonPath,
258 contentPath: contentPath,
259 templateCss: templateCss,
260 templateJs: templateJs,
261 plugins: plugins,
262 templateResponsiveImage: templateResponsiveImage,
263 };
264
265 sessionStorage.setItem('fleximp_import_data', JSON.stringify(data));
266
267 if (!textDomain) {
268 alert('Text domain not found.');
269 return;
270 }
271
272 // // Save text domain
273 fetch(fleximp_ajax_object.ajax_url, {
274 method: 'POST',
275 headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
276 body: new URLSearchParams({
277 action: 'fleximp_set_text_domain',
278 text_domain: textDomain,
279 })
280 })
281 .then(res => res.json())
282 .then(response => {
283 if (response.success) {
284 sessionStorage.setItem('fleximp_auto_continue', '1');
285 location.reload();
286 } else {
287 alert('Failed to update text domain.');
288 }
289 });
290 }, { once: true });
291 }
292 }
293 });
294
295 fetchCategories();
296 fetchTemplates();
297
298 // for uninstall
299 jQuery(document).on('click', '.uninstall-btn', function () {
300 const button = jQuery(this);
301 const templateSlug = button.data('template');
302 const plugins = button.data('plugins');
303 const textDomain = button.data('text-domain');
304 if (!confirm('Are you sure you want to uninstall this template and remove all related data?')) {
305 return;
306 }
307
308 jQuery.ajax({
309 url: ajaxurl,
310 type: 'POST',
311 data: {
312 action: 'fleximp_uninstall_template',
313 template_slug: templateSlug,
314 plugins: plugins,
315 text_domain: textDomain,
316 },
317 success: function (response) {
318 if (response.success) {
319 alert(response.data.message);
320 location.reload();
321 } else {
322 alert('Error: ' + response.data.message);
323 }
324 },
325 });
326 });
327 });
328
329
330 window.addEventListener('DOMContentLoaded', function () {
331
332 if (sessionStorage.getItem('fleximp_auto_continue') === '1') {
333 const templatesTab = document.querySelector('.nav-link[href="#templates"]');
334 if (templatesTab) templatesTab.classList.add('active');
335 const templatesPane = document.querySelector('#templates');
336 if (templatesPane) templatesPane.classList.add('active', 'show');
337 const templatesTab1 = document.querySelector('.nav-link[href="#dashboard"]');
338 if (templatesTab1) templatesTab1.classList.remove('active');
339 const templatesPane1 = document.querySelector('#dashboard');
340 if (templatesPane1) templatesPane1.classList.remove('active', 'show');
341
342 sessionStorage.removeItem('fleximp_auto_continue');
343 const importData = sessionStorage.getItem('fleximp_import_data');
344 if (!importData) return;
345
346 const {
347 textDomain,
348 jsonPath,
349 contentPath,
350 templateCss,
351 templateJs,
352 plugins,
353 templateResponsiveImage
354 } = JSON.parse(importData);
355
356 const modalTemplateImage = document.getElementById('modal-template-responsive-image');
357 modalTemplateImage.src = templateResponsiveImage;
358
359 const flexgetattributebutton = document.createElement('button');
360 flexgetattributebutton.classList.add('flex-unique-import-button');
361 flexgetattributebutton.setAttribute('data-text-domain', textDomain);
362 flexgetattributebutton.setAttribute('data-json-path', jsonPath);
363 flexgetattributebutton.setAttribute('data-content-path', contentPath);
364 flexgetattributebutton.setAttribute('data-template-css', templateCss);
365 flexgetattributebutton.setAttribute('data-template-js', templateJs);
366 flexgetattributebutton.setAttribute('data-plugins', plugins);
367
368 document.body.appendChild(flexgetattributebutton);
369 runImportProcess(); // continue import
370 }
371 });
372
373 function updateProgress(percent, message) {
374 const progressBar = document.getElementById('import-progress-bar');
375 const progressText = document.getElementById('import-progress-text');
376 if (progressBar && progressText) {
377 progressBar.style.width = percent + '%';
378 progressText.textContent = `${message} (${percent}%)`;
379 }
380 }
381
382 async function runImportProcess() {
383 document.getElementById('step-confirm-import').style.display = 'none';
384 document.getElementById('step-plugins').style.display = 'block';
385 document.getElementById('import-modal').style.display = 'block';
386
387 const pluginLoader = document.getElementById('plugin-loader');
388 const contentLoader = document.getElementById('content-loader');
389 if (pluginLoader) pluginLoader.style.display = 'inline-block';
390 if (contentLoader) contentLoader.style.display = 'none';
391
392 const importBtn = document.querySelector('.flex-unique-import-button');
393 const selectedPlugins = JSON.parse(importBtn.getAttribute('data-plugins'));
394 const jsonPath = importBtn.getAttribute('data-json-path');
395 const contentPath = importBtn.getAttribute('data-content-path');
396 const textDomain = importBtn.getAttribute('data-text-domain');
397 const templateCss = importBtn.getAttribute('data-template-css');
398 const templateJs = importBtn.getAttribute('data-template-js');
399
400 const installPlugin = (plugin) => {
401 return new Promise((resolve) => {
402 jQuery.ajax({
403 url: fleximp_ajax_object.ajax_url,
404 method: 'POST',
405 data: {
406 action: 'fleximp_checked_install_plugin',
407 plugin_slug: plugin.text_domain,
408 plugin_name: plugin.name,
409 plugin_main_file: plugin.main_file
410 },
411 success: function () {
412 console.log(`Plugin ${plugin.name} installed successfully.`);
413 updateProgress(33, `Installed plugin: ${plugin.name}`);
414 },
415 error: function (xhr, status, error) {
416 console.error(`Error installing plugin ${plugin.name}: ${error}`);
417 },
418 complete: function () {
419 resolve();
420 }
421 });
422 });
423 };
424
425 const selectedPluginsObj = Object.values(selectedPlugins);
426
427 // Install plugins one by one
428 for (let i = 0; i < selectedPluginsObj.length; i++) {
429 await installPlugin(selectedPluginsObj[i]);
430 }
431
432 if (pluginLoader) pluginLoader.classList.add('loader-success');
433
434 const innerPagesLoader = document.getElementById('inner-pages-loader');
435 if (innerPagesLoader) innerPagesLoader.style.display = 'inline-block';
436
437 // Step 2: Import Inner Pages
438 await new Promise((resolve) => {
439 jQuery.ajax({
440 url: fleximp_ajax_object.ajax_url,
441 method: 'POST',
442 data: {
443 action: 'fleximp_import_inner_pages_data',
444 nonce: fleximp_ajax_object.nonce,
445 content_path: contentPath,
446 text_domain: textDomain,
447 template_css: templateCss,
448 template_js: templateJs
449 },
450 success: function () {
451 console.log('Inner pages data imported successfully.');
452 if (innerPagesLoader) innerPagesLoader.classList.add('loader-success');
453 updateProgress(75, 'Importing inner pages success');
454 },
455 error: function (xhr, status, error) {
456 console.error(`Error importing inner pages data: ${error}`);
457 if (innerPagesLoader) innerPagesLoader.classList.add('loader-error');
458 },
459 complete: resolve
460 });
461 });
462
463 // Step 3: Import Demo Content
464 if (contentLoader) contentLoader.style.display = 'inline-block';
465 contentLoader.classList.add('loader-active');
466
467 await new Promise((resolve) => {
468 jQuery.ajax({
469 url: fleximp_ajax_object.ajax_url,
470 method: 'POST',
471 data: {
472 action: 'fleximp_import_demo_content',
473 text_domain: textDomain,
474 json_path: jsonPath
475 },
476 success: function () {
477 console.log('Content imported successfully.');
478 updateProgress(100, 'Import success');
479 },
480 error: function (xhr, status, error) {
481 console.error(`Error importing content: ${error}`);
482 },
483 complete: resolve
484 });
485 });
486
487 if (contentLoader) {
488 contentLoader.classList.remove('loader-active');
489 contentLoader.classList.add('loader-success');
490 }
491
492 const continueButton = document.getElementById('flex-continue-install');
493 if (continueButton) continueButton.style.display = 'inline-block';
494
495 document.getElementById('step-plugins').style.display = 'none';
496 document.getElementById('step-done').style.display = 'block';
497
498 setTimeout(() => location.reload(), 8000);
499 }
500