| 1 |
(function ($) { |
| 2 |
if (!$('.bdt-setup-wizard').length) { |
| 3 |
return; |
| 4 |
} |
| 5 |
|
| 6 |
$(document).ready(function () { |
| 7 |
const wizard = { |
| 8 |
currentStep: 0, |
| 9 |
steps: document.querySelectorAll('.bdt-wizard-step'), |
| 10 |
nextButtons: document.querySelectorAll('.bdt-wizard-next'), |
| 11 |
prevButtons: document.querySelectorAll('.bdt-wizard-prev'), |
| 12 |
progressItems: document.querySelectorAll('.bdt-wizard-progress-item'), |
| 13 |
progressBar: document.getElementById('plugin-install-progress'), |
| 14 |
categorySelect: document.getElementById('category-select'), |
| 15 |
searchInput: document.querySelector('.widget-search'), |
| 16 |
activateAllButton: document.querySelector('.bulk-action.activate'), |
| 17 |
deactivateAllButton: document.querySelector('.bulk-action.deactivate'), |
| 18 |
saveButton: document.getElementById('save-and-continue'), |
| 19 |
widgetList: document.querySelector('.widget-list'), |
| 20 |
installButton: document.getElementById('upk-install-plugins-btn'), |
| 21 |
filterButtons: document.querySelectorAll('.filter-button'), |
| 22 |
|
| 23 |
init: function () { |
| 24 |
this.setupStepAttributes(); |
| 25 |
this.showStep(this.currentStep); |
| 26 |
this.updateProgress(this.currentStep); |
| 27 |
this.bindEvents(); |
| 28 |
this.initAnimations(); |
| 29 |
}, |
| 30 |
|
| 31 |
setupStepAttributes: function() { |
| 32 |
const stepNames = ['welcome', 'features', 'integration', 'finish']; |
| 33 |
this.steps.forEach((step, index) => { |
| 34 |
if (!step.hasAttribute('data-step') && index < stepNames.length) { |
| 35 |
step.setAttribute('data-step', stepNames[index]); |
| 36 |
} |
| 37 |
}); |
| 38 |
}, |
| 39 |
|
| 40 |
initAnimations: function() { |
| 41 |
const currentStep = this.steps[this.currentStep]; |
| 42 |
if (currentStep) { |
| 43 |
setTimeout(() => { |
| 44 |
currentStep.classList.add('active'); |
| 45 |
currentStep.style.display = 'block'; // Ensure display is set to block |
| 46 |
}, 100); |
| 47 |
} |
| 48 |
}, |
| 49 |
|
| 50 |
bindEvents: function () { |
| 51 |
const self = this; |
| 52 |
|
| 53 |
this.progressItems.forEach((item, index) => { |
| 54 |
item.addEventListener('click', () => { |
| 55 |
const stepName = item.getAttribute('data-step'); |
| 56 |
if (index <= this.getCompletedStepIndex()) { |
| 57 |
this.goToStep(index); |
| 58 |
} |
| 59 |
}); |
| 60 |
}); |
| 61 |
|
| 62 |
$(document).on('click', '.bdt-wizard-next', function(e) { |
| 63 |
e.preventDefault(); |
| 64 |
const targetStep = $(this).data('step'); |
| 65 |
|
| 66 |
// No loader or timeout - immediate transition |
| 67 |
if (targetStep) { |
| 68 |
for (let i = 0; i < self.steps.length; i++) { |
| 69 |
if ($(self.steps[i]).data('step') === targetStep) { |
| 70 |
self.goToStep(i); |
| 71 |
return; |
| 72 |
} |
| 73 |
} |
| 74 |
|
| 75 |
const stepIndex = self.getStepIndexByName(targetStep); |
| 76 |
if (stepIndex !== -1) { |
| 77 |
self.goToStep(stepIndex); |
| 78 |
return; |
| 79 |
} |
| 80 |
} |
| 81 |
|
| 82 |
self.goToStep(self.currentStep + 1); |
| 83 |
}); |
| 84 |
|
| 85 |
this.prevButtons.forEach(button => { |
| 86 |
button.addEventListener('click', () => { |
| 87 |
// No loader or timeout - immediate transition |
| 88 |
const targetStep = button.getAttribute('data-step'); |
| 89 |
if (targetStep) { |
| 90 |
const stepIndex = this.getStepIndexByName(targetStep); |
| 91 |
if (stepIndex !== -1) { |
| 92 |
this.goToStep(stepIndex); |
| 93 |
} |
| 94 |
} else if (this.currentStep > 0) { |
| 95 |
this.goToStep(this.currentStep - 1); |
| 96 |
} |
| 97 |
}); |
| 98 |
}); |
| 99 |
|
| 100 |
if (this.filterButtons) { |
| 101 |
this.filterButtons.forEach(button => { |
| 102 |
button.addEventListener('click', () => { |
| 103 |
this.filterButtons.forEach(btn => btn.classList.remove('active')); |
| 104 |
button.classList.add('active'); |
| 105 |
this.filterItemsByType(button.dataset.filter); |
| 106 |
}); |
| 107 |
}); |
| 108 |
} |
| 109 |
|
| 110 |
if (this.categorySelect) { |
| 111 |
this.categorySelect.addEventListener('change', this.filterWidgets.bind(this)); |
| 112 |
} |
| 113 |
|
| 114 |
if (this.searchInput) { |
| 115 |
this.searchInput.addEventListener('input', this.searchWidgets.bind(this)); |
| 116 |
} |
| 117 |
|
| 118 |
if (this.activateAllButton) { |
| 119 |
this.activateAllButton.addEventListener('click', this.activateAllWidgets.bind(this)); |
| 120 |
} |
| 121 |
if (this.deactivateAllButton) { |
| 122 |
this.deactivateAllButton.addEventListener('click', this.deactivateAllWidgets.bind(this)); |
| 123 |
} |
| 124 |
|
| 125 |
this.saveSettingsSubmit(); |
| 126 |
this.installPlugins(); |
| 127 |
this.onChangedPluginSliderCheckbox(); |
| 128 |
|
| 129 |
const featureItems = document.querySelectorAll('.bdt-feature-item'); |
| 130 |
featureItems.forEach(item => { |
| 131 |
item.addEventListener('mouseenter', () => { |
| 132 |
item.style.transform = 'translateY(-8px)'; |
| 133 |
}); |
| 134 |
item.addEventListener('mouseleave', () => { |
| 135 |
item.style.transform = 'translateY(-3px)'; |
| 136 |
}); |
| 137 |
}); |
| 138 |
}, |
| 139 |
|
| 140 |
getStepIndexByName: function(stepName) { |
| 141 |
for (let i = 0; i < this.steps.length; i++) { |
| 142 |
if (this.steps[i].getAttribute('data-step') === stepName) { |
| 143 |
return i; |
| 144 |
} |
| 145 |
} |
| 146 |
|
| 147 |
const stepMap = { |
| 148 |
'welcome': 0, |
| 149 |
'features': 1, |
| 150 |
'integration': 2, |
| 151 |
'finish': 3 |
| 152 |
}; |
| 153 |
|
| 154 |
return stepName in stepMap ? stepMap[stepName] : -1; |
| 155 |
}, |
| 156 |
|
| 157 |
getCompletedStepIndex: function() { |
| 158 |
return this.currentStep; |
| 159 |
}, |
| 160 |
|
| 161 |
goToStep: function(stepIndex) { |
| 162 |
if (stepIndex >= 0 && stepIndex < this.steps.length) { |
| 163 |
this.currentStep = stepIndex; |
| 164 |
this.showStep(this.currentStep); |
| 165 |
this.updateProgress(this.currentStep); |
| 166 |
} |
| 167 |
}, |
| 168 |
|
| 169 |
pluginSliderCheckbox: function(selector){ |
| 170 |
const pluginSlugs = []; |
| 171 |
const data = $(selector).serialize(); |
| 172 |
data.split('&').forEach(item => { |
| 173 |
const [key, value] = item.split('='); |
| 174 |
if (key.startsWith('plugins') && value === 'on') { |
| 175 |
const slug = decodeURIComponent(key.split('%5B%5D')[1]); |
| 176 |
if (slug) { |
| 177 |
pluginSlugs.push(slug); |
| 178 |
} |
| 179 |
} |
| 180 |
}); |
| 181 |
|
| 182 |
if(pluginSlugs.length){ |
| 183 |
$("#upk-install-plugins-btn").removeClass('d-none').addClass('pulse-animation'); |
| 184 |
}else{ |
| 185 |
$("#upk-install-plugins-btn").addClass('d-none').removeClass('pulse-animation'); |
| 186 |
} |
| 187 |
}, |
| 188 |
|
| 189 |
onChangedPluginSliderCheckbox: function(){ |
| 190 |
const vm = this; |
| 191 |
$('#upk-install-plugins').on('change', '.plugin-slider-checkbox', function (e) { |
| 192 |
vm.pluginSliderCheckbox('#upk-install-plugins .plugin-slider-checkbox'); |
| 193 |
|
| 194 |
const pluginItem = $(this).closest('.plugin-item'); |
| 195 |
pluginItem.addClass('item-highlight'); |
| 196 |
setTimeout(() => { |
| 197 |
pluginItem.removeClass('item-highlight'); |
| 198 |
}, 600); |
| 199 |
}); |
| 200 |
}, |
| 201 |
|
| 202 |
showStep: function (step) { |
| 203 |
// Hide all steps first |
| 204 |
this.steps.forEach((stepElement) => { |
| 205 |
stepElement.classList.remove('active'); |
| 206 |
stepElement.style.display = 'none'; // Ensure inactive steps are completely hidden |
| 207 |
}); |
| 208 |
|
| 209 |
// Immediately show the current step without delay |
| 210 |
const currentStep = this.steps[step]; |
| 211 |
if (currentStep) { |
| 212 |
currentStep.classList.add('active'); |
| 213 |
currentStep.style.display = 'block'; // Make sure active step is visible |
| 214 |
} |
| 215 |
|
| 216 |
this.pluginSliderCheckbox('#upk-install-plugins .plugin-slider-checkbox'); |
| 217 |
}, |
| 218 |
|
| 219 |
filterItemsByType: function(type) { |
| 220 |
const items = document.querySelectorAll('.feature-item, .plugin-item'); |
| 221 |
|
| 222 |
items.forEach(item => { |
| 223 |
if (type === 'all' || item.dataset.type === type) { |
| 224 |
item.style.display = 'flex'; |
| 225 |
setTimeout(() => { |
| 226 |
item.style.opacity = '1'; |
| 227 |
item.style.transform = 'translateY(0)'; |
| 228 |
}, 50); |
| 229 |
} else { |
| 230 |
item.style.opacity = '0'; |
| 231 |
item.style.transform = 'translateY(10px)'; |
| 232 |
setTimeout(() => { |
| 233 |
item.style.display = 'none'; |
| 234 |
}, 300); |
| 235 |
} |
| 236 |
}); |
| 237 |
}, |
| 238 |
|
| 239 |
filterWidgets: function () { |
| 240 |
const selectedCategory = this.categorySelect.value; |
| 241 |
const widgets = this.widgetList.querySelectorAll('li'); |
| 242 |
|
| 243 |
widgets.forEach(widget => { |
| 244 |
const types = widget.dataset.type.split(/\s+/); |
| 245 |
if (selectedCategory === 'all' || types.includes(selectedCategory)) { |
| 246 |
widget.style.display = 'block'; |
| 247 |
setTimeout(() => { |
| 248 |
widget.style.opacity = '1'; |
| 249 |
widget.style.transform = 'translateY(0)'; |
| 250 |
}, 50); |
| 251 |
} else { |
| 252 |
widget.style.opacity = '0'; |
| 253 |
widget.style.transform = 'translateY(10px)'; |
| 254 |
setTimeout(() => { |
| 255 |
widget.style.display = 'none'; |
| 256 |
}, 300); |
| 257 |
} |
| 258 |
}); |
| 259 |
}, |
| 260 |
|
| 261 |
updateProgress: function (step) { |
| 262 |
this.progressItems.forEach((item, index) => { |
| 263 |
if (index < step) { |
| 264 |
item.classList.remove('active'); |
| 265 |
item.classList.add('completed'); |
| 266 |
} else if (index === step) { |
| 267 |
item.classList.add('active'); |
| 268 |
item.classList.remove('completed'); |
| 269 |
} else { |
| 270 |
item.classList.remove('active', 'completed'); |
| 271 |
} |
| 272 |
}); |
| 273 |
}, |
| 274 |
|
| 275 |
searchWidgets: function () { |
| 276 |
const searchTerm = this.searchInput.value.toLowerCase(); |
| 277 |
const widgets = this.widgetList.querySelectorAll('li'); |
| 278 |
|
| 279 |
widgets.forEach(widget => { |
| 280 |
if (widget.dataset.label.toLowerCase().includes(searchTerm)) { |
| 281 |
widget.style.display = 'block'; |
| 282 |
setTimeout(() => { |
| 283 |
widget.style.opacity = '1'; |
| 284 |
}, 50); |
| 285 |
} else { |
| 286 |
widget.style.opacity = '0'; |
| 287 |
setTimeout(() => { |
| 288 |
widget.style.display = 'none'; |
| 289 |
}, 300); |
| 290 |
} |
| 291 |
}); |
| 292 |
}, |
| 293 |
|
| 294 |
activateAllWidgets: function (event) { |
| 295 |
event.preventDefault(); |
| 296 |
const checkboxes = this.widgetList.querySelectorAll('input[type="checkbox"]'); |
| 297 |
|
| 298 |
this.activateAllButton.classList.add('button-pulse'); |
| 299 |
setTimeout(() => { |
| 300 |
this.activateAllButton.classList.remove('button-pulse'); |
| 301 |
}, 500); |
| 302 |
|
| 303 |
checkboxes.forEach(checkbox => { |
| 304 |
checkbox.checked = true; |
| 305 |
const widgetItem = checkbox.closest('li'); |
| 306 |
widgetItem.classList.add('item-highlight'); |
| 307 |
setTimeout(() => { |
| 308 |
widgetItem.classList.remove('item-highlight'); |
| 309 |
}, 600); |
| 310 |
}); |
| 311 |
}, |
| 312 |
|
| 313 |
deactivateAllWidgets: function (event) { |
| 314 |
event.preventDefault(); |
| 315 |
const checkboxes = this.widgetList.querySelectorAll('input[type="checkbox"]'); |
| 316 |
|
| 317 |
this.deactivateAllButton.classList.add('button-pulse'); |
| 318 |
setTimeout(() => { |
| 319 |
this.deactivateAllButton.classList.remove('button-pulse'); |
| 320 |
}, 500); |
| 321 |
|
| 322 |
checkboxes.forEach(checkbox => { |
| 323 |
checkbox.checked = false; |
| 324 |
const widgetItem = checkbox.closest('li'); |
| 325 |
widgetItem.classList.add('item-highlight'); |
| 326 |
setTimeout(() => { |
| 327 |
widgetItem.classList.remove('item-highlight'); |
| 328 |
}, 600); |
| 329 |
}); |
| 330 |
}, |
| 331 |
|
| 332 |
saveSettingsSubmit: function () { |
| 333 |
const vm = this; |
| 334 |
$('#upk_setup_wizard_modules').submit(function (e) { |
| 335 |
e.preventDefault(); |
| 336 |
var data = $(this).serialize(); |
| 337 |
|
| 338 |
// Get the button and store original text |
| 339 |
const saveBtn = $(this).find('#save-and-continue'); |
| 340 |
const originalText = saveBtn.html().trim(); |
| 341 |
|
| 342 |
// Show loading state |
| 343 |
saveBtn.prop('disabled', true) |
| 344 |
.html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Saving...'); |
| 345 |
|
| 346 |
$.ajax({ |
| 347 |
url: BDT_SetupWizard.ajax_url, |
| 348 |
type: 'POST', |
| 349 |
data: data, |
| 350 |
success: function (response) { |
| 351 |
if (response.success) { |
| 352 |
saveBtn.html('<i class="dashicons dashicons-yes-alt"></i> Saved!'); |
| 353 |
setTimeout(() => { |
| 354 |
vm.goToStep(vm.currentStep + 1); |
| 355 |
// Reset button state |
| 356 |
saveBtn.prop('disabled', false).html(originalText); |
| 357 |
}, 1000); |
| 358 |
} else { |
| 359 |
saveBtn.html('<i class="dashicons dashicons-no"></i> Failed'); |
| 360 |
setTimeout(() => { |
| 361 |
saveBtn.prop('disabled', false).html(originalText); |
| 362 |
}, 1000); |
| 363 |
alert('Failed to save settings'); |
| 364 |
} |
| 365 |
}, |
| 366 |
error: function (error) { |
| 367 |
saveBtn.html('<i class="dashicons dashicons-no"></i> Error'); |
| 368 |
setTimeout(() => { |
| 369 |
saveBtn.prop('disabled', false).html(originalText); |
| 370 |
}, 1000); |
| 371 |
console.error('Error:', error); |
| 372 |
} |
| 373 |
}); |
| 374 |
}); |
| 375 |
}, |
| 376 |
|
| 377 |
installPlugins: function () { |
| 378 |
const vm = this; |
| 379 |
$('#upk-install-plugins').submit(function (e) { |
| 380 |
e.preventDefault(); |
| 381 |
|
| 382 |
vm.installButton.disabled = true; |
| 383 |
vm.installButton.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Installing...'; |
| 384 |
|
| 385 |
const pluginSlugs = []; |
| 386 |
const data = $(this).serialize(); |
| 387 |
data.split('&').forEach(item => { |
| 388 |
const [key, value] = item.split('='); |
| 389 |
if (key.startsWith('plugins') && value === 'on') { |
| 390 |
const slug = decodeURIComponent(key.split('%5B%5D')[1]); |
| 391 |
if (slug) { |
| 392 |
pluginSlugs.push(slug); |
| 393 |
} |
| 394 |
} |
| 395 |
}); |
| 396 |
|
| 397 |
let installedPlugins = 0; |
| 398 |
const totalPluginsSlug = pluginSlugs.length; |
| 399 |
|
| 400 |
let progressContainer = document.querySelector('.install-progress-container'); |
| 401 |
if (!progressContainer) { |
| 402 |
progressContainer = document.createElement('div'); |
| 403 |
progressContainer.className = 'install-progress-container'; |
| 404 |
progressContainer.innerHTML = ` |
| 405 |
<div class="progress-bar-wrapper"> |
| 406 |
<div id="plugin-install-progress" class="progress-bar" style="width: 0%">0%</div> |
| 407 |
</div> |
| 408 |
<div class="install-status">Preparing to install plugins...</div> |
| 409 |
`; |
| 410 |
vm.installButton.parentNode.appendChild(progressContainer); |
| 411 |
} |
| 412 |
|
| 413 |
const progressBar = document.getElementById('plugin-install-progress'); |
| 414 |
const statusText = document.querySelector('.install-status'); |
| 415 |
|
| 416 |
const updateProgressBar = () => { |
| 417 |
const progress = (installedPlugins / totalPluginsSlug) * 100; |
| 418 |
progressBar.style.width = `${progress}%`; |
| 419 |
progressBar.textContent = `${Math.round(progress)}%`; |
| 420 |
statusText.textContent = `Installing plugin ${installedPlugins} of ${totalPluginsSlug}...`; |
| 421 |
}; |
| 422 |
|
| 423 |
const installNextPlugin = () => { |
| 424 |
if (installedPlugins < totalPluginsSlug) { |
| 425 |
const slug = pluginSlugs[installedPlugins]; |
| 426 |
const pluginName = slug.split('/')[0].split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '); |
| 427 |
|
| 428 |
statusText.textContent = `Installing ${pluginName}...`; |
| 429 |
|
| 430 |
jQuery.ajax({ |
| 431 |
url: BDT_SetupWizard.ajax_url, |
| 432 |
method: 'POST', |
| 433 |
data: { |
| 434 |
action: 'setup_wizard_install_plugins', |
| 435 |
nonce: BDT_SetupWizard.nonce, |
| 436 |
plugins: [slug] |
| 437 |
}, |
| 438 |
success: (response) => { |
| 439 |
if (response.success) { |
| 440 |
installedPlugins++; |
| 441 |
updateProgressBar(); |
| 442 |
|
| 443 |
statusText.innerHTML += ` <span class="success-indicator"><i class="dashicons dashicons-yes-alt"></i></span>`; |
| 444 |
|
| 445 |
const pluginItem = document.querySelector(`[data-slug="${slug}"]`); |
| 446 |
if (pluginItem) { |
| 447 |
pluginItem.classList.add('plugin-installed'); |
| 448 |
} |
| 449 |
|
| 450 |
setTimeout(() => { |
| 451 |
installNextPlugin(); |
| 452 |
}, 500); |
| 453 |
} else { |
| 454 |
statusText.innerHTML += ` <span class="error-indicator"><i class="dashicons dashicons-no"></i> Failed</span>`; |
| 455 |
installedPlugins++; |
| 456 |
updateProgressBar(); |
| 457 |
setTimeout(() => { |
| 458 |
installNextPlugin(); |
| 459 |
}, 500); |
| 460 |
} |
| 461 |
}, |
| 462 |
error: (error) => { |
| 463 |
statusText.innerHTML += ` <span class="error-indicator"><i class="dashicons dashicons-no"></i> Error</span>`; |
| 464 |
installedPlugins++; |
| 465 |
updateProgressBar(); |
| 466 |
setTimeout(() => { |
| 467 |
installNextPlugin(); |
| 468 |
}, 500); |
| 469 |
} |
| 470 |
}); |
| 471 |
} else { |
| 472 |
statusText.textContent = 'All plugins installed successfully!'; |
| 473 |
statusText.innerHTML += ' <span class="success-indicator"><i class="dashicons dashicons-yes-alt"></i></span>'; |
| 474 |
|
| 475 |
setTimeout(() => { |
| 476 |
vm.installButton.disabled = false; |
| 477 |
vm.installButton.innerHTML = 'Installation Complete'; |
| 478 |
vm.goToStep(vm.currentStep + 1); |
| 479 |
}, 1500); |
| 480 |
} |
| 481 |
}; |
| 482 |
|
| 483 |
installNextPlugin(); |
| 484 |
}); |
| 485 |
} |
| 486 |
}; |
| 487 |
|
| 488 |
wizard.init(); |
| 489 |
}); |
| 490 |
|
| 491 |
// Handle template import button clicks |
| 492 |
$('body').on('click', '.upk-setup-wizard .template-import', function (e) { |
| 493 |
e.preventDefault(); |
| 494 |
e.stopPropagation(); |
| 495 |
|
| 496 |
const $button = $(this); |
| 497 |
const $templateCard = $button.closest('.choose-template'); |
| 498 |
const importUrl = $templateCard.data('import-url'); |
| 499 |
const templateName = $templateCard.find('.template-title').text(); |
| 500 |
|
| 501 |
if (!importUrl) { |
| 502 |
alert('Import URL not found'); |
| 503 |
return; |
| 504 |
} |
| 505 |
|
| 506 |
// Prevent multiple clicks |
| 507 |
if ($button.prop('disabled')) { |
| 508 |
return; |
| 509 |
} |
| 510 |
|
| 511 |
// Update button state |
| 512 |
const originalButtonHtml = $button.html(); |
| 513 |
$button.prop('disabled', true) |
| 514 |
.html('<i class="dashicons dashicons-update"></i> Importing...'); |
| 515 |
|
| 516 |
$templateCard.addClass('template-importing'); |
| 517 |
$templateCard.find('.template-title').html(`<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Importing ${templateName}...`); |
| 518 |
|
| 519 |
// Determine import type based on template card classes |
| 520 |
const isZipTemplate = $templateCard.hasClass('bdt-upk-import-temp-zip'); |
| 521 |
const isJsonTemplate = $templateCard.hasClass('bdt-upk-import-temp-json'); |
| 522 |
|
| 523 |
if (isJsonTemplate) { |
| 524 |
// Handle JSON template import |
| 525 |
$.ajax({ |
| 526 |
url: BDT_SetupWizard.ajax_url, |
| 527 |
type: 'POST', |
| 528 |
data: { |
| 529 |
action: 'import_elementor_template', |
| 530 |
nonce: BDT_SetupWizard.nonce, |
| 531 |
import_url: importUrl |
| 532 |
}, |
| 533 |
success: function(response) { |
| 534 |
if (response.success) { |
| 535 |
$button.removeClass('template-importing') |
| 536 |
.addClass('template-imported') |
| 537 |
.html('<i class="dashicons dashicons-yes-alt"></i> Imported'); |
| 538 |
$templateCard.removeClass('template-importing').addClass('template-imported'); |
| 539 |
$templateCard.find('.template-title').html(`<i class="dashicons dashicons-yes-alt"></i> ${templateName} Imported`); |
| 540 |
} else { |
| 541 |
$button.removeClass('template-importing') |
| 542 |
.addClass('template-import-failed') |
| 543 |
.html('<i class="dashicons dashicons-no"></i> Failed'); |
| 544 |
$templateCard.removeClass('template-importing').addClass('template-import-failed'); |
| 545 |
$templateCard.find('.template-title').html(`<i class="dashicons dashicons-no"></i> Import Failed`); |
| 546 |
|
| 547 |
// Reset button after 3 seconds |
| 548 |
setTimeout(() => { |
| 549 |
$button.prop('disabled', false) |
| 550 |
.removeClass('template-import-failed') |
| 551 |
.html(originalButtonHtml); |
| 552 |
}, 3000); |
| 553 |
} |
| 554 |
}, |
| 555 |
error: function() { |
| 556 |
$button.removeClass('template-importing') |
| 557 |
.addClass('template-import-failed') |
| 558 |
.html('<i class="dashicons dashicons-no"></i> Failed'); |
| 559 |
$templateCard.removeClass('template-importing').addClass('template-import-failed'); |
| 560 |
$templateCard.find('.template-title').html(`<i class="dashicons dashicons-no"></i> Import Failed`); |
| 561 |
|
| 562 |
// Reset button after 3 seconds |
| 563 |
setTimeout(() => { |
| 564 |
$button.prop('disabled', false) |
| 565 |
.removeClass('template-import-failed') |
| 566 |
.html(originalButtonHtml); |
| 567 |
}, 3000); |
| 568 |
} |
| 569 |
}); |
| 570 |
} else if (isZipTemplate) { |
| 571 |
// Handle ZIP template import |
| 572 |
$.ajax({ |
| 573 |
url: BDT_SetupWizard.ajax_url, |
| 574 |
type: 'POST', |
| 575 |
data: { |
| 576 |
action: 'import_upk_elementor_bundle_template', |
| 577 |
nonce: BDT_SetupWizard.nonce, |
| 578 |
import_url: importUrl |
| 579 |
}, |
| 580 |
success: async function(response) { |
| 581 |
if (response.success) { |
| 582 |
const sessionId = response.data.session; |
| 583 |
const runners = response?.data?.runners; |
| 584 |
let error = ''; |
| 585 |
|
| 586 |
for (const runner of runners) { |
| 587 |
const success = await importRunner(sessionId, runner); |
| 588 |
if (!success) { |
| 589 |
error = `❌ Failed to import: ${runner}`; |
| 590 |
break; |
| 591 |
} |
| 592 |
} |
| 593 |
|
| 594 |
if (error) { |
| 595 |
$button.removeClass('template-importing') |
| 596 |
.addClass('template-import-failed') |
| 597 |
.html('<i class="dashicons dashicons-no"></i> Failed'); |
| 598 |
$templateCard.removeClass('template-importing').addClass('template-import-failed'); |
| 599 |
$templateCard.find('.template-title').html(`<i class="dashicons dashicons-no"></i> ${error}`); |
| 600 |
alert(error); |
| 601 |
|
| 602 |
// Reset button after 3 seconds |
| 603 |
setTimeout(() => { |
| 604 |
$button.prop('disabled', false) |
| 605 |
.removeClass('template-import-failed') |
| 606 |
.html(originalButtonHtml); |
| 607 |
}, 3000); |
| 608 |
return; |
| 609 |
} |
| 610 |
|
| 611 |
$button.removeClass('template-importing') |
| 612 |
.addClass('template-imported') |
| 613 |
.html('<i class="dashicons dashicons-yes-alt"></i> Imported'); |
| 614 |
$templateCard.removeClass('template-importing').addClass('template-imported'); |
| 615 |
$templateCard.find('.template-title').html(`<i class="dashicons dashicons-yes-alt"></i> ${templateName} Imported`); |
| 616 |
} else { |
| 617 |
$button.removeClass('template-importing') |
| 618 |
.addClass('template-import-failed') |
| 619 |
.html('<i class="dashicons dashicons-no"></i> Failed'); |
| 620 |
$templateCard.removeClass('template-importing').addClass('template-import-failed'); |
| 621 |
const missingPlugins = response?.data?.plugins; |
| 622 |
if (missingPlugins) { |
| 623 |
let pluginArr = []; |
| 624 |
for (const plugin of missingPlugins) { |
| 625 |
pluginArr.push(plugin.name); |
| 626 |
} |
| 627 |
$templateCard.find('.template-title').html(`<i class="dashicons dashicons-no"></i> ${"plugins are required to import: " + pluginArr.join(', ')}`); |
| 628 |
} else { |
| 629 |
$templateCard.find('.template-title').html(`<i class="dashicons dashicons-no"></i> ${response.data.message}`); |
| 630 |
} |
| 631 |
|
| 632 |
// Reset button after 3 seconds |
| 633 |
setTimeout(() => { |
| 634 |
$button.prop('disabled', false) |
| 635 |
.removeClass('template-import-failed') |
| 636 |
.html(originalButtonHtml); |
| 637 |
}, 3000); |
| 638 |
} |
| 639 |
}, |
| 640 |
error: function() { |
| 641 |
$button.removeClass('template-importing') |
| 642 |
.addClass('template-import-failed') |
| 643 |
.html('<i class="dashicons dashicons-no"></i> Failed'); |
| 644 |
$templateCard.removeClass('template-importing').addClass('template-import-failed'); |
| 645 |
$templateCard.find('.template-title').html(`<i class="dashicons dashicons-no"></i> Import Failed`); |
| 646 |
|
| 647 |
// Reset button after 3 seconds |
| 648 |
setTimeout(() => { |
| 649 |
$button.prop('disabled', false) |
| 650 |
.removeClass('template-import-failed') |
| 651 |
.html(originalButtonHtml); |
| 652 |
}, 3000); |
| 653 |
} |
| 654 |
}); |
| 655 |
} else { |
| 656 |
// Unsupported template type |
| 657 |
alert('Unsupported template format'); |
| 658 |
$button.prop('disabled', false).html(originalButtonHtml); |
| 659 |
$templateCard.removeClass('template-importing'); |
| 660 |
} |
| 661 |
}); |
| 662 |
|
| 663 |
async function importRunner(sessionId, runner) { |
| 664 |
try { |
| 665 |
const response = await new Promise((resolve, reject) => { |
| 666 |
$.ajax({ |
| 667 |
url: BDT_SetupWizard.ajax_url, type: 'POST', data: { |
| 668 |
action: 'import_upk_elementor_bundle_runner_template', |
| 669 |
nonce: BDT_SetupWizard.nonce, |
| 670 |
sessionId: sessionId, |
| 671 |
runner: runner, |
| 672 |
}, success: resolve, error: reject |
| 673 |
}) |
| 674 |
}); |
| 675 |
|
| 676 |
return response.success; |
| 677 |
} catch (error) { |
| 678 |
console.error('AJAX Error:', error); |
| 679 |
return false; |
| 680 |
} |
| 681 |
} |
| 682 |
|
| 683 |
})(jQuery); |
| 684 |
|
| 685 |
document.addEventListener('DOMContentLoaded', function() { |
| 686 |
const style = document.createElement('style'); |
| 687 |
style.textContent = ` |
| 688 |
.bdt-wizard-step { |
| 689 |
transition: opacity 0.3s ease, transform 0.3s ease; |
| 690 |
display: none; /* Hide all steps by default */ |
| 691 |
} |
| 692 |
|
| 693 |
.bdt-wizard-step.active { |
| 694 |
display: block; /* Show only active step */ |
| 695 |
opacity: 1; |
| 696 |
transform: translateY(0); |
| 697 |
} |
| 698 |
|
| 699 |
.item-highlight { |
| 700 |
transition: all 0.3s ease; |
| 701 |
box-shadow: 0 0 0 2px var(--upk-primary); |
| 702 |
transform: translateY(-3px); |
| 703 |
} |
| 704 |
|
| 705 |
.button-pulse { |
| 706 |
animation: buttonPulse 0.5s ease; |
| 707 |
} |
| 708 |
|
| 709 |
.pulse-animation { |
| 710 |
animation: pulse 1.5s infinite; |
| 711 |
} |
| 712 |
|
| 713 |
/* Spinner for plugin installation and template importing */ |
| 714 |
.spinner { |
| 715 |
display: inline-block; |
| 716 |
width: 16px; |
| 717 |
height: 16px; |
| 718 |
border: 2px solid rgba(255,255,255,0.3); |
| 719 |
border-radius: 50%; |
| 720 |
border-top-color: #fff; |
| 721 |
animation: spin 1s linear infinite; |
| 722 |
margin-right: 8px; |
| 723 |
} |
| 724 |
|
| 725 |
/* Plugin installation progress styles */ |
| 726 |
.install-progress-container { |
| 727 |
margin-top: 20px; |
| 728 |
padding: 15px; |
| 729 |
background: var(--upk-gray-light); |
| 730 |
border-radius: var(--upk-border-radius); |
| 731 |
} |
| 732 |
|
| 733 |
.progress-bar-wrapper { |
| 734 |
height: 8px; |
| 735 |
background: var(--upk-gray-medium); |
| 736 |
border-radius: 4px; |
| 737 |
overflow: hidden; |
| 738 |
margin-bottom: 10px; |
| 739 |
} |
| 740 |
|
| 741 |
.progress-bar { |
| 742 |
height: 100%; |
| 743 |
background: var(--upk-primary); |
| 744 |
border-radius: 4px; |
| 745 |
transition: width 0.3s ease; |
| 746 |
color: transparent; |
| 747 |
font-size: 0; |
| 748 |
} |
| 749 |
|
| 750 |
.install-status { |
| 751 |
font-size: 14px; |
| 752 |
color: var(--upk-text-light); |
| 753 |
} |
| 754 |
|
| 755 |
.success-indicator { |
| 756 |
color: var(--upk-success); |
| 757 |
} |
| 758 |
|
| 759 |
.error-indicator { |
| 760 |
color: var(--upk-danger); |
| 761 |
} |
| 762 |
|
| 763 |
.plugin-installed { |
| 764 |
border-color: var(--upk-success) !important; |
| 765 |
} |
| 766 |
|
| 767 |
/* Template import states */ |
| 768 |
.template-importing { |
| 769 |
opacity: 0.7; |
| 770 |
pointer-events: none; |
| 771 |
} |
| 772 |
|
| 773 |
.template-imported { |
| 774 |
border-color: var(--upk-success) !important; |
| 775 |
} |
| 776 |
|
| 777 |
.template-import-failed { |
| 778 |
border-color: var(--upk-danger) !important; |
| 779 |
} |
| 780 |
|
| 781 |
/* Template import button states */ |
| 782 |
.template-import:disabled { |
| 783 |
cursor: not-allowed; |
| 784 |
} |
| 785 |
|
| 786 |
.template-import.template-imported { |
| 787 |
background-color: #28a745; |
| 788 |
border-color: #28a745; |
| 789 |
color: white; |
| 790 |
} |
| 791 |
|
| 792 |
.template-import.template-import-failed { |
| 793 |
background-color: #dc3545; |
| 794 |
border-color: #dc3545; |
| 795 |
color: white; |
| 796 |
} |
| 797 |
|
| 798 |
/* Animations */ |
| 799 |
@keyframes buttonPulse { |
| 800 |
0%, 100% { transform: scale(1); } |
| 801 |
50% { transform: scale(1.05); } |
| 802 |
} |
| 803 |
|
| 804 |
@keyframes pulse { |
| 805 |
0% { box-shadow: 0 0 0 0 rgba(108, 92, 231, 0.4); } |
| 806 |
70% { box-shadow: 0 0 0 10px rgba(108, 92, 231, 0); } |
| 807 |
100% { box-shadow: 0 0 0 0 rgba(108, 92, 231, 0); } |
| 808 |
} |
| 809 |
|
| 810 |
@keyframes spin { |
| 811 |
0% { transform: rotate(0deg); } |
| 812 |
100% { transform: rotate(360deg); } |
| 813 |
} |
| 814 |
`; |
| 815 |
document.head.appendChild(style); |
| 816 |
}); |
| 817 |
|