| 1 |
// noinspection DuplicatedCode,JSUnresolvedReference,JSValidateTypes |
| 2 |
|
| 3 |
jQuery(document).ready(function ($) { |
| 4 |
$(document).on('click', '.template-item', function () { |
| 5 |
let templateKey = $(this).data('template-key'); |
| 6 |
let templatePlan = $(this).data('template-plan'); |
| 7 |
let templateBtn = $('#install-template'); |
| 8 |
templateBtn.attr('data-template-key', templateKey); |
| 9 |
templateBtn.attr('data-template-plan', templatePlan); |
| 10 |
let planActive = templateBtn.attr('data-plan-active'); |
| 11 |
|
| 12 |
if (templatePlan === 'premium') { |
| 13 |
if (planActive === 'premium') { |
| 14 |
templateBtn.text('Import Premium Template'); |
| 15 |
} else { |
| 16 |
templateBtn.text('Import Premium Template'); |
| 17 |
} |
| 18 |
} else { |
| 19 |
templateBtn.text('Import Free Template'); |
| 20 |
} |
| 21 |
|
| 22 |
$('#template-preview-iframe').attr('src', 'https://demo.kingaddons.com/' + templateKey); |
| 23 |
$('#template-preview-link').attr('href', 'https://demo.kingaddons.com/' + templateKey); |
| 24 |
$('#template-preview-popup').fadeIn(); |
| 25 |
}); |
| 26 |
|
| 27 |
// Listen for clicks on any button inside .preview-mode-switcher |
| 28 |
$('.preview-mode-switcher button').on('click', function () { |
| 29 |
// Remove the .active class from all buttons |
| 30 |
$('.preview-mode-switcher button').removeClass('active'); |
| 31 |
// Add .active to the clicked button |
| 32 |
$(this).addClass('active'); |
| 33 |
|
| 34 |
// Determine which mode was clicked: desktop, tablet, or mobile |
| 35 |
let mode = $(this).data('mode'); |
| 36 |
|
| 37 |
// Select the preview iframe |
| 38 |
let $iframe = $('#template-preview-iframe'); |
| 39 |
|
| 40 |
// Remove any previous mode classes |
| 41 |
$iframe.removeClass('preview-tablet preview-mobile'); |
| 42 |
|
| 43 |
// If tablet, add .preview-tablet class |
| 44 |
if (mode === 'tablet') { |
| 45 |
$iframe.addClass('preview-tablet'); |
| 46 |
} |
| 47 |
// If mobile, add .preview-mobile class |
| 48 |
else if (mode === 'mobile') { |
| 49 |
$iframe.addClass('preview-mobile'); |
| 50 |
} |
| 51 |
// If desktop, no extra class (width:100% by default). |
| 52 |
}); |
| 53 |
|
| 54 |
$(document).on('click', '#close-popup', function () { |
| 55 |
$('#template-preview-popup').fadeOut(); |
| 56 |
}); |
| 57 |
|
| 58 |
$(document).on('click', '#activate-license-btn', function () { |
| 59 |
$('#templates-catalog').addClass('kng-whole-overlay'); |
| 60 |
$('#license-activating-popup').fadeIn(); |
| 61 |
}); |
| 62 |
|
| 63 |
$(document).on('click', '#close-license-activating-popup', function () { |
| 64 |
$('#templates-catalog').removeClass('kng-whole-overlay'); |
| 65 |
$('#license-activating-popup').fadeOut(); |
| 66 |
}); |
| 67 |
|
| 68 |
$(document).on('click', '#close-premium-promo-popup', function () { |
| 69 |
$('#templates-catalog').removeClass('kng-whole-overlay'); |
| 70 |
$('#premium-promo-popup').fadeOut(); |
| 71 |
}); |
| 72 |
|
| 73 |
$(document).on('click', '#close-installing-popup', function () { |
| 74 |
$('#templates-catalog').removeClass('kng-whole-overlay'); |
| 75 |
$('#template-installing-popup').fadeOut(); |
| 76 |
$('#go-to-imported-page').fadeOut(); |
| 77 |
$('#close-installing-popup').fadeOut(); |
| 78 |
document.getElementById('final_response').innerText = ''; |
| 79 |
document.getElementById('progress').innerText = ''; |
| 80 |
document.getElementById('progress-bar').style.width = '0%'; |
| 81 |
document.getElementById('progress-bar').innerText = '0%'; |
| 82 |
}); |
| 83 |
|
| 84 |
$(document).on('click', '#install-template', function () { |
| 85 |
|
| 86 |
$('#templates-catalog').addClass('kng-whole-overlay'); |
| 87 |
$('#template-preview-popup').fadeOut(); |
| 88 |
|
| 89 |
let templateBtn = $('#install-template'); |
| 90 |
let templateKey = templateBtn.attr('data-template-key'); |
| 91 |
let templatePlan = templateBtn.attr('data-template-plan'); |
| 92 |
let planActive = templateBtn.attr('data-plan-active'); |
| 93 |
|
| 94 |
let api_request_url; |
| 95 |
let installId; |
| 96 |
|
| 97 |
if (planActive === 'premium') { |
| 98 |
if (templatePlan === 'premium') { |
| 99 |
api_request_url = 'https://api.kingaddons.com/get-template.php'; |
| 100 |
installId = window.kingAddons.installId; |
| 101 |
} else { |
| 102 |
api_request_url = 'https://api.kingaddons.com/get-template-free.php'; |
| 103 |
installId = 0; |
| 104 |
} |
| 105 |
} else { |
| 106 |
if (templatePlan === 'free') { |
| 107 |
api_request_url = 'https://api.kingaddons.com/get-template-free.php'; |
| 108 |
installId = 0; |
| 109 |
} else { |
| 110 |
$('#premium-promo-popup').fadeIn(); |
| 111 |
return; |
| 112 |
} |
| 113 |
} |
| 114 |
|
| 115 |
fetch(api_request_url, { |
| 116 |
method: 'POST', |
| 117 |
headers: { |
| 118 |
'Content-Type': 'application/json', |
| 119 |
}, |
| 120 |
body: JSON.stringify({ |
| 121 |
key: templateKey, |
| 122 |
install: installId, |
| 123 |
}), |
| 124 |
}) |
| 125 |
.then(response => { |
| 126 |
if (!response.ok) { |
| 127 |
// The server returned a 4xx or 5xx, read the text and throw an error |
| 128 |
return response.text().then(html => { |
| 129 |
console.error('Server error:\n' + html); |
| 130 |
throw new Error('Server error (not JSON).'); |
| 131 |
}); |
| 132 |
} |
| 133 |
// If ok, parse JSON |
| 134 |
return response.json(); |
| 135 |
}) |
| 136 |
.then(data => { |
| 137 |
if (!data.success) { |
| 138 |
console.error('API error:', data); |
| 139 |
} |
| 140 |
if (data.success) { |
| 141 |
$('#template-installing-popup').fadeIn(); |
| 142 |
doImport(data); |
| 143 |
} else { |
| 144 |
$('#premium-promo-popup').fadeIn(); |
| 145 |
} |
| 146 |
}) |
| 147 |
.catch(error => { |
| 148 |
console.error('Fetch error:', error); |
| 149 |
alert('Connection error: ' + error); |
| 150 |
}); |
| 151 |
}); |
| 152 |
|
| 153 |
function doImport(data) { |
| 154 |
document.getElementById('progress').innerText = 'Starting import...'; |
| 155 |
document.getElementById('image-list').innerHTML = ''; |
| 156 |
document.getElementById('progress').innerText = 'Import initialized.'; |
| 157 |
document.getElementById('progress-bar').style.width = '10%'; |
| 158 |
document.getElementById('progress-bar').innerText = '10%'; |
| 159 |
|
| 160 |
let images = data.landing.images; |
| 161 |
|
| 162 |
if (images && images.length > 0) { |
| 163 |
let imageList = images.map(function (img) { |
| 164 |
return '<li data-id="' + img.id + '" data-url="' + img.url + '">' + img.url + ' (ID: ' + img.id + ')</li>'; |
| 165 |
}).join(''); |
| 166 |
|
| 167 |
document.getElementById('image-list').innerHTML = '<ul>' + imageList + '</ul>'; |
| 168 |
|
| 169 |
startImport(data.landing); |
| 170 |
} else { |
| 171 |
document.getElementById('final_response').innerText = 'No images to import.'; |
| 172 |
} |
| 173 |
} |
| 174 |
|
| 175 |
function startImport(initial_data) { |
| 176 |
fetch(kingAddonsData.ajaxUrl, { |
| 177 |
method: 'POST', |
| 178 |
body: new URLSearchParams({ |
| 179 |
action: 'import_elementor_page_with_images', |
| 180 |
nonce: kingAddonsData.nonce, |
| 181 |
data: JSON.stringify(initial_data) |
| 182 |
}) |
| 183 |
}) |
| 184 |
.then(response => { |
| 185 |
if (!response.ok) { |
| 186 |
// The server returned a 4xx or 5xx, read the text and throw an error |
| 187 |
return response.text().then(html => { |
| 188 |
console.error('Server error:\n' + html); |
| 189 |
throw new Error('Server error:\n' + html); |
| 190 |
}); |
| 191 |
} |
| 192 |
// If ok, parse JSON |
| 193 |
return response.json(); |
| 194 |
}) |
| 195 |
.then(data => { |
| 196 |
if (data.success) { |
| 197 |
processNextImage(); |
| 198 |
} else { |
| 199 |
alert('Error getting template: ' + data.message); |
| 200 |
} |
| 201 |
}) |
| 202 |
.catch(error => { |
| 203 |
alert('Error: ' + error); |
| 204 |
}); |
| 205 |
} |
| 206 |
|
| 207 |
function processNextImage() { |
| 208 |
const maxRetries = 3; |
| 209 |
let currentRetry = 0; |
| 210 |
let retryTimeout = 1000; |
| 211 |
|
| 212 |
function attemptProcessImage() { |
| 213 |
fetch(kingAddonsData.ajaxUrl, { |
| 214 |
method: 'POST', |
| 215 |
body: new URLSearchParams({ |
| 216 |
action: 'process_import_images', |
| 217 |
nonce: kingAddonsData.nonce |
| 218 |
}) |
| 219 |
}) |
| 220 |
.then(response => { |
| 221 |
if (!response.ok) { |
| 222 |
// The server returned a 4xx or 5xx, read the text and throw an error |
| 223 |
return response.text().then(html => { |
| 224 |
console.error('Server error:\n' + html); |
| 225 |
throw new Error('Server error:\n' + html); |
| 226 |
}); |
| 227 |
} |
| 228 |
// If ok, parse JSON |
| 229 |
return response.json(); |
| 230 |
}) |
| 231 |
.then(data => { |
| 232 |
if (data.success) { |
| 233 |
if (data.data.progress !== undefined) { |
| 234 |
|
| 235 |
let progressBar = document.getElementById('progress-bar'); |
| 236 |
let progress = data.data.progress; |
| 237 |
progressBar.style.width = progress + '%'; |
| 238 |
progressBar.innerText = progress + '%'; |
| 239 |
|
| 240 |
document.getElementById('progress').innerText = data.data.message; |
| 241 |
|
| 242 |
let imageUrlElement = document.querySelector('li[data-url="' + data.data.image_url + '"]'); |
| 243 |
if (imageUrlElement) { |
| 244 |
imageUrlElement.innerHTML += ' - done'; |
| 245 |
} |
| 246 |
currentRetry = 0; |
| 247 |
retryTimeout = 1000; |
| 248 |
processNextImage(); |
| 249 |
} else { |
| 250 |
// Both templates and sections from main admin catalog create new pages |
| 251 |
document.getElementById('final_response').innerText = data.data.message; |
| 252 |
document.getElementById('progress').innerText = 'Import completed.'; |
| 253 |
document.getElementById('progress-bar').style.width = '100%'; |
| 254 |
document.getElementById('progress-bar').innerText = '100%'; |
| 255 |
let goToPage = $('#go-to-imported-page'); |
| 256 |
goToPage.attr('href', data.data.page_url); |
| 257 |
goToPage.fadeIn(); |
| 258 |
$('#close-installing-popup').fadeIn(); |
| 259 |
} |
| 260 |
} else { |
| 261 |
console.error('Process image issue:', data); |
| 262 |
// Skip image |
| 263 |
if (data.data && data.data.retry) { |
| 264 |
processNextImage(); |
| 265 |
} |
| 266 |
} |
| 267 |
}) |
| 268 |
.catch(error => { |
| 269 |
console.error('Catch Error:', error); |
| 270 |
if (currentRetry < maxRetries) { |
| 271 |
currentRetry++; |
| 272 |
retryTimeout *= 2; |
| 273 |
setTimeout(attemptProcessImage, retryTimeout); |
| 274 |
} else { |
| 275 |
let imageUrlElement = document.querySelector('li[data-url="unknown"]'); |
| 276 |
if (imageUrlElement) { |
| 277 |
imageUrlElement.innerHTML += ' - SKIPPED'; |
| 278 |
} |
| 279 |
console.error('Error:', error); |
| 280 |
document.getElementById('final_response').innerText = 'Error: ' + error.message; |
| 281 |
currentRetry = 0; |
| 282 |
retryTimeout = 1000; |
| 283 |
processNextImage(); |
| 284 |
} |
| 285 |
}); |
| 286 |
} |
| 287 |
|
| 288 |
attemptProcessImage(); |
| 289 |
} |
| 290 |
|
| 291 |
$(document).on('click', '.pagination a', function (e) { |
| 292 |
e.preventDefault(); |
| 293 |
let page = $(this).attr('href').split('paged=')[1]; |
| 294 |
filterTemplates(page); |
| 295 |
}); |
| 296 |
|
| 297 |
let templateSearch = $('#template-search'); |
| 298 |
let templateCategory = $('#template-category'); |
| 299 |
let templateCollection = $('#template-collection'); |
| 300 |
|
| 301 |
function filterTemplates(page = 1) { |
| 302 |
let searchQuery = templateSearch.val().toLowerCase(); |
| 303 |
let selectedCategory = templateCategory.val(); |
| 304 |
let selectedCollection = templateCollection.val(); |
| 305 |
let selectedTags = []; |
| 306 |
|
| 307 |
$('#template-tags input:checked').each(function () { |
| 308 |
selectedTags.push($(this).val()); |
| 309 |
}); |
| 310 |
|
| 311 |
$.ajax({ |
| 312 |
url: kingAddonsData.ajaxUrl, |
| 313 |
type: 'POST', |
| 314 |
data: { |
| 315 |
action: 'filter_templates', |
| 316 |
s: searchQuery, |
| 317 |
category: selectedCategory, |
| 318 |
collection: selectedCollection, |
| 319 |
tags: selectedTags.join(','), |
| 320 |
paged: page |
| 321 |
}, |
| 322 |
success: function (response) { |
| 323 |
if (response.success) { |
| 324 |
|
| 325 |
// Scroll to top after the new content is loaded with admin bar offset |
| 326 |
const scrollOffset = $('#king-addons-templates-top').offset().top - 32; // Subtract 32px for admin bar |
| 327 |
$('html, body').animate({scrollTop: scrollOffset}, 0); |
| 328 |
|
| 329 |
$('.templates-grid').html(response.data.grid_html); |
| 330 |
$('.pagination').html(response.data.pagination_html); |
| 331 |
} else { |
| 332 |
alert('Error: ' + response.data); |
| 333 |
} |
| 334 |
}, |
| 335 |
error: function (xhr, status, error) { |
| 336 |
console.error('AJAX Error: ', status, error); |
| 337 |
} |
| 338 |
}); |
| 339 |
} |
| 340 |
|
| 341 |
templateSearch.on('keyup', function () { |
| 342 |
templateCategory.val(''); |
| 343 |
templateCollection.val(''); |
| 344 |
$('#template-tags input:checked').prop('checked', false); |
| 345 |
filterTemplates(); |
| 346 |
}); |
| 347 |
|
| 348 |
templateCategory.on('change', function () { |
| 349 |
templateSearch.val(''); |
| 350 |
templateCollection.val(''); |
| 351 |
$('#template-tags input:checked').prop('checked', false); |
| 352 |
filterTemplates(); |
| 353 |
}); |
| 354 |
|
| 355 |
templateCollection.on('change', function () { |
| 356 |
templateSearch.val(''); |
| 357 |
templateCategory.val(''); |
| 358 |
$('#template-tags input:checked').prop('checked', false); |
| 359 |
filterTemplates(); |
| 360 |
}); |
| 361 |
|
| 362 |
$('#template-tags input').on('change', function () { |
| 363 |
templateSearch.val(''); |
| 364 |
templateCategory.val(''); |
| 365 |
templateCollection.val(''); |
| 366 |
if ($(this).is(':checked')) { |
| 367 |
$('#template-tags input').not(this).prop('checked', false); |
| 368 |
} |
| 369 |
filterTemplates(); |
| 370 |
}); |
| 371 |
|
| 372 |
$('#reset-filters').on('click', function () { |
| 373 |
templateSearch.val(''); |
| 374 |
templateCategory.val(''); |
| 375 |
templateCollection.val(''); |
| 376 |
$('#template-tags input:checked').prop('checked', false); |
| 377 |
filterTemplates(); |
| 378 |
}); |
| 379 |
|
| 380 |
// Load sections count on page load |
| 381 |
if ($('#sections-count').length) { |
| 382 |
loadSectionsCount(); |
| 383 |
} |
| 384 |
|
| 385 |
// ===== TABS FUNCTIONALITY ===== |
| 386 |
|
| 387 |
// Tab switching |
| 388 |
$('.king-addons-tab-button').on('click', function() { |
| 389 |
var tabId = $(this).data('tab'); |
| 390 |
|
| 391 |
// Remove active class from all tabs and content |
| 392 |
$('.king-addons-tab-button').removeClass('active'); |
| 393 |
$('.king-addons-tab-content').removeClass('active'); |
| 394 |
|
| 395 |
// Add active class to clicked tab and corresponding content |
| 396 |
$(this).addClass('active'); |
| 397 |
$('#' + tabId + '-catalog').addClass('active'); |
| 398 |
|
| 399 |
// Load sections on first visit to sections tab |
| 400 |
if (tabId === 'sections' && !window.sectionsLoaded) { |
| 401 |
loadSections(); |
| 402 |
} |
| 403 |
|
| 404 |
// Collections: List View only |
| 405 |
if (tabId === 'collections') { |
| 406 |
$('#collection-details-view').hide(); |
| 407 |
$('.collections-toolbar').show(); |
| 408 |
$('.collections-rows-wrapper').show(); |
| 409 |
if (!window.collectionRowsLoaded) { |
| 410 |
loadCollectionRows(1); |
| 411 |
} |
| 412 |
} |
| 413 |
}); |
| 414 |
|
| 415 |
// ===== COLLECTIONS FUNCTIONALITY ===== |
| 416 |
|
| 417 |
function openCollectionDetails(collectionId) { |
| 418 |
if (!collectionId) return; |
| 419 |
|
| 420 |
$('.collections-toolbar').hide(); |
| 421 |
$('.collections-rows-wrapper').hide(); |
| 422 |
$('#collection-details-view').show(); |
| 423 |
$('.collection-details-content').html('<div class="collection-loading">Loading collection...</div>'); |
| 424 |
$('#collection-search').val(''); |
| 425 |
|
| 426 |
$.ajax({ |
| 427 |
url: window.kingAddonsData.ajaxUrl, |
| 428 |
type: 'POST', |
| 429 |
data: { |
| 430 |
action: 'king_addons_get_collection_details', |
| 431 |
nonce: window.kingAddonsData.nonce || '', |
| 432 |
collection_id: collectionId |
| 433 |
}, |
| 434 |
success: function(response) { |
| 435 |
if (response.success) { |
| 436 |
var data = response.data; |
| 437 |
var html = ''; |
| 438 |
|
| 439 |
if (data.templates_count > 0) { |
| 440 |
html += '<div class="collection-section-title"><h3>Templates (' + data.templates_count + ')</h3></div>'; |
| 441 |
html += '<div class="templates-grid collection-templates-grid">' + data.templates_html + '</div>'; |
| 442 |
} |
| 443 |
|
| 444 |
if (data.sections_count > 0) { |
| 445 |
html += '<div class="collection-section-title"><h3>Sections (' + data.sections_count + ')</h3></div>'; |
| 446 |
html += '<div class="sections-grid collection-sections-grid">' + data.sections_html + '</div>'; |
| 447 |
} |
| 448 |
|
| 449 |
if (data.templates_count === 0 && data.sections_count === 0) { |
| 450 |
html = '<div class="collection-empty">No items found in this collection.</div>'; |
| 451 |
} |
| 452 |
|
| 453 |
$('.collection-details-content').html(html); |
| 454 |
} else { |
| 455 |
$('.collection-details-content').html('<div class="collection-error">Error loading collection: ' + (response.data || 'Unknown error') + '</div>'); |
| 456 |
} |
| 457 |
}, |
| 458 |
error: function() { |
| 459 |
$('.collection-details-content').html('<div class="collection-error">Failed to load collection. Please try again.</div>'); |
| 460 |
} |
| 461 |
}); |
| 462 |
} |
| 463 |
|
| 464 |
// (Optional) If legacy grid cards ever exist, keep them working. |
| 465 |
$(document).on('click', '.ka-collection-card', function () { |
| 466 |
openCollectionDetails($(this).data('collection-id') || ''); |
| 467 |
}); |
| 468 |
|
| 469 |
// Back button |
| 470 |
$(document).on('click', '.ka-back-button', function() { |
| 471 |
$('#collection-details-view').hide(); |
| 472 |
$('.collections-toolbar').show(); |
| 473 |
$('.collections-rows-wrapper').fadeIn(); |
| 474 |
}); |
| 475 |
|
| 476 |
// Search in collection |
| 477 |
$(document).on('keyup', '#collection-search', function() { |
| 478 |
var value = $(this).val().toLowerCase(); |
| 479 |
|
| 480 |
// Filter templates |
| 481 |
$('.collection-templates-grid .template-item').filter(function() { |
| 482 |
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1) |
| 483 |
}); |
| 484 |
|
| 485 |
// Filter sections |
| 486 |
$('.collection-sections-grid .section-item').filter(function() { |
| 487 |
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1) |
| 488 |
}); |
| 489 |
}); |
| 490 |
|
| 491 |
// ===== SECTIONS FUNCTIONALITY ===== |
| 492 |
|
| 493 |
window.sectionsLoaded = false; |
| 494 |
window.sectionsData = null; |
| 495 |
window.sectionsPage = 1; |
| 496 |
window.sectionsFilters = {}; |
| 497 |
|
| 498 |
function loadSections(page = 1) { |
| 499 |
if (!window.kingAddonsData || !window.kingAddonsData.ajaxUrl) { |
| 500 |
console.error('King Addons data not available'); |
| 501 |
return; |
| 502 |
} |
| 503 |
|
| 504 |
var searchQuery = $('#sections-search').val() || ''; |
| 505 |
var selectedCategory = $('#sections-category').val() || ''; |
| 506 |
var selectedType = $('#sections-type').val() || ''; |
| 507 |
var selectedPlan = $('#sections-plan').val() || ''; |
| 508 |
|
| 509 |
$('.sections-grid').html(` |
| 510 |
<div class="sections-loading"> |
| 511 |
Loading sections... |
| 512 |
</div> |
| 513 |
`); |
| 514 |
|
| 515 |
$.ajax({ |
| 516 |
url: window.kingAddonsData.ajaxUrl, |
| 517 |
type: 'POST', |
| 518 |
data: { |
| 519 |
action: 'king_addons_get_sections_catalog', |
| 520 |
nonce: window.kingAddonsData.nonce || '', |
| 521 |
search: searchQuery, |
| 522 |
category: selectedCategory, |
| 523 |
section_type: selectedType, |
| 524 |
plan: selectedPlan, |
| 525 |
page: page |
| 526 |
}, |
| 527 |
success: function(response) { |
| 528 |
if (response.success) { |
| 529 |
// Scroll to top after new content is loaded with admin bar offset (same as templates) |
| 530 |
const scrollOffset = $('#king-addons-templates-top').offset().top - 32; // Subtract 32px for admin bar |
| 531 |
$('html, body').animate({scrollTop: scrollOffset}, 0); |
| 532 |
|
| 533 |
window.sectionsData = response.data; |
| 534 |
window.sectionsLoaded = true; |
| 535 |
renderSections(); |
| 536 |
updateSectionsFilters(); |
| 537 |
updateSectionsCount(); |
| 538 |
} else { |
| 539 |
$('.sections-grid').html(` |
| 540 |
<div class="sections-loading"> |
| 541 |
Error loading sections: ${response.data || 'Unknown error'} |
| 542 |
</div> |
| 543 |
`); |
| 544 |
} |
| 545 |
}, |
| 546 |
error: function(xhr, status, error) { |
| 547 |
console.error('AJAX Error loading sections:', status, error); |
| 548 |
$('.sections-grid').html(` |
| 549 |
<div class="sections-loading"> |
| 550 |
Failed to load sections. Please try again. |
| 551 |
</div> |
| 552 |
`); |
| 553 |
} |
| 554 |
}); |
| 555 |
} |
| 556 |
|
| 557 |
function renderSections() { |
| 558 |
if (!window.sectionsData || !window.sectionsData.sections) { |
| 559 |
$('.sections-grid').html(` |
| 560 |
<div class="sections-loading"> |
| 561 |
<p>No sections found. Try adjusting your search or filters to find more sections.</p> |
| 562 |
</div> |
| 563 |
`); |
| 564 |
return; |
| 565 |
} |
| 566 |
|
| 567 |
var sectionsHtml = ''; |
| 568 |
var sections = window.sectionsData.sections; |
| 569 |
|
| 570 |
sections.forEach(function(section) { |
| 571 |
// Use the correct screenshot URL pattern with plan-based paths |
| 572 |
var screenshotUrl = `https://thumbnails.kingaddons.com/sections/${section.plan}/${section.section_key}.png?v=4`; |
| 573 |
|
| 574 |
sectionsHtml += ` |
| 575 |
<div class="section-item" |
| 576 |
data-section-key="${section.section_key}" |
| 577 |
data-section-plan="${section.plan}" |
| 578 |
data-category="${section.category || ''}" |
| 579 |
data-tags="${(section.tags || []).join(',')}" |
| 580 |
data-section-type="${section.section_type || ''}"> |
| 581 |
<div class="section-preview"> |
| 582 |
<img src="${screenshotUrl}" |
| 583 |
alt="${section.title}" |
| 584 |
loading="lazy" |
| 585 |
onerror="this.src='data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjE4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImciIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNmOGY5ZmEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlNWU3ZWIiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2cpIi8+PGNpcmNsZSBjeD0iMTUwIiBjeT0iNzAiIHI9IjE2IiBmaWxsPSIjOWNhM2FmIiBvcGFjaXR5PSIwLjQiLz48cmVjdCB4PSIxMzQiIHk9Ijg2IiB3aWR0aD0iMzIiIGhlaWdodD0iNCIgZmlsbD0iIzljYTNhZiIgb3BhY2l0eT0iMC40IiByeD0iMiIvPjxyZWN0IHg9IjEyNiIgeT0iOTQiIHdpZHRoPSI0OCIgaGVpZ2h0PSI0IiBmaWxsPSIjOWNhM2FmIiBvcGFjaXR5PSIwLjMiIHJ4PSIyIi8+PHRleHQgeD0iNTAlIiB5PSIxMjAiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsIHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTIiIGZpbGw9IiM2Yjc1ODQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIG9wYWNpdHk9IjAuNyI+U2VjdGlvbiBQcmV2aWV3PC90ZXh0Pjwvc3ZnPg=='"> |
| 586 |
<div class="section-actions"> |
| 587 |
<button class="import-section-btn" data-section-key="${section.section_key}" data-section-plan="${section.plan}"> |
| 588 |
<i class="eicon-file-download"></i> Import |
| 589 |
</button> |
| 590 |
<a href="https://sections.kingaddons.com/${section.section_key}" class="live-preview-btn" target="_blank"> |
| 591 |
<i class="eicon-preview-medium"></i> Live Preview |
| 592 |
</a> |
| 593 |
</div> |
| 594 |
${section.plan === 'premium' ? '<span class="section-badge-pro">PRO</span>' : ''} |
| 595 |
</div> |
| 596 |
<div class="section-info"> |
| 597 |
<h4>${section.title}</h4> |
| 598 |
</div> |
| 599 |
</div> |
| 600 |
`; |
| 601 |
}); |
| 602 |
|
| 603 |
$('.sections-grid').html(sectionsHtml); |
| 604 |
|
| 605 |
// Render pagination if available |
| 606 |
if (window.sectionsData.pagination) { |
| 607 |
renderSectionsPagination(); |
| 608 |
} |
| 609 |
} |
| 610 |
|
| 611 |
|
| 612 |
|
| 613 |
function renderSectionsPagination() { |
| 614 |
var pagination = window.sectionsData.pagination; |
| 615 |
var paginationHtml = ''; |
| 616 |
|
| 617 |
if (pagination.total_pages > 1) { |
| 618 |
paginationHtml += '<div class="pagination-inner">'; |
| 619 |
|
| 620 |
var current = pagination.current_page; |
| 621 |
var total = pagination.total_pages; |
| 622 |
var endSize = 3; // Show 3 pages at beginning and end |
| 623 |
var midSize = 2; // Show 2 pages around current |
| 624 |
|
| 625 |
// Previous page |
| 626 |
if (current > 1) { |
| 627 |
paginationHtml += `<a class="page-numbers" href="#" data-page="${current - 1}">← Previous</a>`; |
| 628 |
} |
| 629 |
|
| 630 |
// Smart pagination logic with proper ellipsis |
| 631 |
var pages = []; |
| 632 |
|
| 633 |
// Always show first pages |
| 634 |
for (var i = 1; i <= Math.min(endSize, total); i++) { |
| 635 |
pages.push(i); |
| 636 |
} |
| 637 |
|
| 638 |
// Calculate middle range around current page |
| 639 |
var start = Math.max(current - midSize, 1); |
| 640 |
var end = Math.min(current + midSize, total); |
| 641 |
|
| 642 |
// Add first ellipsis if there's a gap |
| 643 |
if (start > endSize + 1) { |
| 644 |
pages.push('...'); |
| 645 |
} |
| 646 |
|
| 647 |
// Add middle pages around current (avoid duplicates with start/end) |
| 648 |
for (var i = Math.max(start, endSize + 1); i <= Math.min(end, total - endSize); i++) { |
| 649 |
if (pages.indexOf(i) === -1) { |
| 650 |
pages.push(i); |
| 651 |
} |
| 652 |
} |
| 653 |
|
| 654 |
// Add second ellipsis if there's a gap |
| 655 |
if (end < total - endSize) { |
| 656 |
pages.push('...'); |
| 657 |
} |
| 658 |
|
| 659 |
// Always show last pages (avoid duplicates) |
| 660 |
for (var i = Math.max(total - endSize + 1, endSize + 1); i <= total; i++) { |
| 661 |
if (pages.indexOf(i) === -1) { |
| 662 |
pages.push(i); |
| 663 |
} |
| 664 |
} |
| 665 |
|
| 666 |
// Render pages |
| 667 |
pages.forEach(function(page) { |
| 668 |
if (page === '...') { |
| 669 |
paginationHtml += `<span class="page-numbers dots">…</span>`; |
| 670 |
} else if (page === current) { |
| 671 |
paginationHtml += `<span class="page-numbers current">${page}</span>`; |
| 672 |
} else { |
| 673 |
paginationHtml += `<a class="page-numbers" href="#" data-page="${page}">${page}</a>`; |
| 674 |
} |
| 675 |
}); |
| 676 |
|
| 677 |
// Next page |
| 678 |
if (current < total) { |
| 679 |
paginationHtml += `<a class="page-numbers" href="#" data-page="${current + 1}">Next →</a>`; |
| 680 |
} |
| 681 |
|
| 682 |
paginationHtml += '</div>'; |
| 683 |
} |
| 684 |
|
| 685 |
$('.sections-pagination').html(paginationHtml); |
| 686 |
} |
| 687 |
|
| 688 |
function updateSectionsFilters() { |
| 689 |
if (!window.sectionsData) return; |
| 690 |
|
| 691 |
// Update categories dropdown |
| 692 |
var categoriesHtml = '<option value="">All Categories</option>'; |
| 693 |
if (window.sectionsData.categories) { |
| 694 |
window.sectionsData.categories.forEach(function(category) { |
| 695 |
var displayName = category.charAt(0).toUpperCase() + category.slice(1).replace(/-/g, ' '); |
| 696 |
categoriesHtml += `<option value="${category}">${displayName}</option>`; |
| 697 |
}); |
| 698 |
} |
| 699 |
$('#sections-category').html(categoriesHtml); |
| 700 |
|
| 701 |
// Update types dropdown |
| 702 |
var typesHtml = '<option value="">All Types</option>'; |
| 703 |
if (window.sectionsData.section_types) { |
| 704 |
window.sectionsData.section_types.forEach(function(type) { |
| 705 |
var displayName = type.charAt(0).toUpperCase() + type.slice(1).replace(/-/g, ' '); |
| 706 |
typesHtml += `<option value="${type}">${displayName}</option>`; |
| 707 |
}); |
| 708 |
} |
| 709 |
$('#sections-type').html(typesHtml); |
| 710 |
} |
| 711 |
|
| 712 |
function updateSectionsCount() { |
| 713 |
if (window.sectionsData && window.sectionsData.pagination) { |
| 714 |
$('#sections-count').text(window.sectionsData.pagination.total_sections); |
| 715 |
} |
| 716 |
} |
| 717 |
|
| 718 |
// Sections filters event handlers - Same logic as templates |
| 719 |
var sectionsSearch = $('#sections-search'); |
| 720 |
var sectionsCategory = $('#sections-category'); |
| 721 |
var sectionsType = $('#sections-type'); |
| 722 |
var sectionsPlan = $('#sections-plan'); |
| 723 |
|
| 724 |
sectionsSearch.on('keyup', function() { |
| 725 |
// Reset other filters when searching (same as templates) |
| 726 |
sectionsCategory.val(''); |
| 727 |
sectionsType.val(''); |
| 728 |
sectionsPlan.val(''); |
| 729 |
|
| 730 |
clearTimeout(window.sectionsSearchTimeout); |
| 731 |
window.sectionsSearchTimeout = setTimeout(function() { |
| 732 |
loadSections(1); |
| 733 |
}, 500); |
| 734 |
}); |
| 735 |
|
| 736 |
sectionsCategory.on('change', function() { |
| 737 |
// Reset search and other filters (same as templates) |
| 738 |
sectionsSearch.val(''); |
| 739 |
sectionsType.val(''); |
| 740 |
sectionsPlan.val(''); |
| 741 |
loadSections(1); |
| 742 |
}); |
| 743 |
|
| 744 |
sectionsType.on('change', function() { |
| 745 |
// Reset search and other filters (same as templates) |
| 746 |
sectionsSearch.val(''); |
| 747 |
sectionsCategory.val(''); |
| 748 |
sectionsPlan.val(''); |
| 749 |
loadSections(1); |
| 750 |
}); |
| 751 |
|
| 752 |
sectionsPlan.on('change', function() { |
| 753 |
// Reset search and other filters (same as templates) |
| 754 |
sectionsSearch.val(''); |
| 755 |
sectionsCategory.val(''); |
| 756 |
sectionsType.val(''); |
| 757 |
loadSections(1); |
| 758 |
}); |
| 759 |
|
| 760 |
$('#sections-reset-filters').on('click', function() { |
| 761 |
sectionsSearch.val(''); |
| 762 |
sectionsCategory.val(''); |
| 763 |
sectionsType.val(''); |
| 764 |
sectionsPlan.val(''); |
| 765 |
loadSections(1); |
| 766 |
}); |
| 767 |
|
| 768 |
// Sections pagination handler |
| 769 |
$(document).on('click', '.sections-pagination .page-numbers', function(e) { |
| 770 |
e.preventDefault(); |
| 771 |
var page = $(this).data('page'); |
| 772 |
if (page) { |
| 773 |
loadSections(page); |
| 774 |
} |
| 775 |
}); |
| 776 |
|
| 777 |
// Section Import Popup Logic |
| 778 |
let pendingSectionImport = null; |
| 779 |
|
| 780 |
// Open Import Popup |
| 781 |
$(document).on('click', '.import-section-btn', function(e) { |
| 782 |
e.preventDefault(); |
| 783 |
e.stopPropagation(); |
| 784 |
|
| 785 |
let sectionKey = $(this).data('section-key'); |
| 786 |
let sectionPlan = $(this).data('section-plan'); |
| 787 |
let sectionTitle = $(this).closest('.section-item').find('h4').text(); |
| 788 |
|
| 789 |
// Check premium |
| 790 |
let planActive = $('#install-template').attr('data-plan-active'); |
| 791 |
if (sectionPlan === 'premium' && planActive !== 'premium') { |
| 792 |
$('#templates-catalog').addClass('kng-whole-overlay'); |
| 793 |
$('#premium-promo-popup').fadeIn(); |
| 794 |
return; |
| 795 |
} |
| 796 |
|
| 797 |
// Store pending import data |
| 798 |
pendingSectionImport = { |
| 799 |
key: sectionKey, |
| 800 |
plan: sectionPlan |
| 801 |
}; |
| 802 |
|
| 803 |
// Populate and show popup |
| 804 |
$('#popup-section-name').text(sectionTitle); |
| 805 |
$('#popup-section-plan').text(sectionPlan.charAt(0).toUpperCase() + sectionPlan.slice(1)); |
| 806 |
$('#section-import-popup').css('display', 'flex').hide().fadeIn(10, function() { |
| 807 |
$(this).addClass('active'); |
| 808 |
}); |
| 809 |
}); |
| 810 |
|
| 811 |
// Live Preview Button - Stop Propagation |
| 812 |
$(document).on('click', '.live-preview-btn', function(e) { |
| 813 |
e.stopPropagation(); |
| 814 |
}); |
| 815 |
|
| 816 |
// Close Popup |
| 817 |
function closeSectionPopup() { |
| 818 |
$('#section-import-popup').removeClass('active'); |
| 819 |
setTimeout(function() { |
| 820 |
$('#section-import-popup').fadeOut(); |
| 821 |
}, 300); |
| 822 |
pendingSectionImport = null; |
| 823 |
} |
| 824 |
|
| 825 |
$(document).on('click', '#close-section-popup, #cancel-section-import', function(e) { |
| 826 |
e.preventDefault(); |
| 827 |
closeSectionPopup(); |
| 828 |
}); |
| 829 |
|
| 830 |
// Confirm Import |
| 831 |
$(document).on('click', '#confirm-section-import', function(e) { |
| 832 |
e.preventDefault(); |
| 833 |
if (pendingSectionImport) { |
| 834 |
importSection(pendingSectionImport.key, pendingSectionImport.plan); |
| 835 |
closeSectionPopup(); |
| 836 |
} |
| 837 |
}); |
| 838 |
|
| 839 |
// Close on click outside |
| 840 |
$(document).on('click', '#section-import-popup', function(e) { |
| 841 |
if ($(e.target).is('#section-import-popup')) { |
| 842 |
closeSectionPopup(); |
| 843 |
} |
| 844 |
}); |
| 845 |
|
| 846 |
// Section item click handler - now only for general clicks (not on buttons) |
| 847 |
$(document).on('click', '.section-item', function(e) { |
| 848 |
// Don't trigger if clicking on buttons or overlay |
| 849 |
if ($(e.target).closest('.section-overlay, .import-section-btn, .live-preview-btn').length) { |
| 850 |
return; |
| 851 |
} |
| 852 |
|
| 853 |
var sectionKey = $(this).data('section-key'); |
| 854 |
var sectionPlan = $(this).data('section-plan'); |
| 855 |
var sectionTitle = $(this).find('h4').text(); |
| 856 |
|
| 857 |
// Check if this is a premium section and user doesn't have premium |
| 858 |
var planActive = $('#install-template').attr('data-plan-active'); |
| 859 |
|
| 860 |
if (sectionPlan === 'premium' && planActive !== 'premium') { |
| 861 |
// Show premium promo popup |
| 862 |
$('#templates-catalog').addClass('kng-whole-overlay'); |
| 863 |
$('#premium-promo-popup').fadeIn(); |
| 864 |
return; |
| 865 |
} |
| 866 |
|
| 867 |
// Open the custom popup instead of confirm() |
| 868 |
pendingSectionImport = { |
| 869 |
key: sectionKey, |
| 870 |
plan: sectionPlan |
| 871 |
}; |
| 872 |
|
| 873 |
$('#popup-section-name').text(sectionTitle); |
| 874 |
$('#popup-section-plan').text(sectionPlan.charAt(0).toUpperCase() + sectionPlan.slice(1)); |
| 875 |
$('#section-import-popup').css('display', 'flex').hide().fadeIn(10, function() { |
| 876 |
$(this).addClass('active'); |
| 877 |
}); |
| 878 |
}); |
| 879 |
|
| 880 |
// Function to import section from main catalog |
| 881 |
function importSection(sectionKey, sectionPlan) { |
| 882 |
// Show importing popup |
| 883 |
$('#templates-catalog').addClass('kng-whole-overlay'); |
| 884 |
$('#template-installing-popup').fadeIn(); |
| 885 |
|
| 886 |
// Initialize progress |
| 887 |
document.getElementById('progress').innerText = 'Loading section data...'; |
| 888 |
document.getElementById('progress-bar').style.width = '5%'; |
| 889 |
document.getElementById('progress-bar').innerText = '5%'; |
| 890 |
|
| 891 |
// Get section data |
| 892 |
$.ajax({ |
| 893 |
url: window.kingAddonsData.ajaxUrl, |
| 894 |
type: 'POST', |
| 895 |
data: { |
| 896 |
action: 'king_addons_import_section_admin', |
| 897 |
nonce: window.kingAddonsData.nonce, |
| 898 |
section_key: sectionKey, |
| 899 |
section_plan: sectionPlan |
| 900 |
}, |
| 901 |
success: function(response) { |
| 902 |
if (response.success) { |
| 903 |
var sectionData = response.data.section_data; |
| 904 |
var imageCount = sectionData.images ? sectionData.images.length : 0; |
| 905 |
|
| 906 |
document.getElementById('progress').innerText = 'Section loaded! Found ' + imageCount + ' images to process...'; |
| 907 |
document.getElementById('progress-bar').style.width = '25%'; |
| 908 |
document.getElementById('progress-bar').innerText = '25%'; |
| 909 |
|
| 910 |
// Process section import (use existing system) |
| 911 |
processSectionImport(sectionData); |
| 912 |
} else { |
| 913 |
document.getElementById('progress').innerText = 'Error: ' + (response.data || 'Failed to load section'); |
| 914 |
$('#close-installing-popup').fadeIn(); |
| 915 |
} |
| 916 |
}, |
| 917 |
error: function(xhr, status, error) { |
| 918 |
document.getElementById('progress').innerText = 'Network error: ' + error; |
| 919 |
$('#close-installing-popup').fadeIn(); |
| 920 |
} |
| 921 |
}); |
| 922 |
} |
| 923 |
|
| 924 |
// Process section import using existing Templates system |
| 925 |
function processSectionImport(sectionData) { |
| 926 |
document.getElementById('progress').innerText = 'Preparing section import...'; |
| 927 |
document.getElementById('progress-bar').style.width = '45%'; |
| 928 |
document.getElementById('progress-bar').innerText = '45%'; |
| 929 |
|
| 930 |
// Use existing Templates import system |
| 931 |
var importData = { |
| 932 |
content: sectionData.content, |
| 933 |
images: sectionData.images || [], |
| 934 |
title: sectionData.title || 'Imported Section', |
| 935 |
elementor_version: sectionData.elementor_version || '3.0.0', |
| 936 |
existing_page_id: 0, |
| 937 |
create_new_page: true // Create new page for sections from main admin catalog |
| 938 |
}; |
| 939 |
|
| 940 |
// Call Templates import system |
| 941 |
$.ajax({ |
| 942 |
url: window.kingAddonsData.ajaxUrl, |
| 943 |
type: 'POST', |
| 944 |
data: { |
| 945 |
action: 'import_elementor_page_with_images', |
| 946 |
nonce: window.kingAddonsData.nonce, |
| 947 |
data: JSON.stringify(importData) |
| 948 |
}, |
| 949 |
success: function(result) { |
| 950 |
if (result.success) { |
| 951 |
document.getElementById('progress').innerText = 'Section import initialized! Processing images...'; |
| 952 |
document.getElementById('progress-bar').style.width = '65%'; |
| 953 |
document.getElementById('progress-bar').innerText = '65%'; |
| 954 |
|
| 955 |
// Start processing images using existing system |
| 956 |
processNextImage(); |
| 957 |
} else { |
| 958 |
document.getElementById('progress').innerText = 'Error: ' + (result.data || 'Failed to initialize section import'); |
| 959 |
$('#close-installing-popup').fadeIn(); |
| 960 |
} |
| 961 |
}, |
| 962 |
error: function(xhr, status, error) { |
| 963 |
document.getElementById('progress').innerText = 'Import error: ' + error; |
| 964 |
$('#close-installing-popup').fadeIn(); |
| 965 |
} |
| 966 |
}); |
| 967 |
} |
| 968 |
|
| 969 |
// Load sections count for tab |
| 970 |
function loadSectionsCount() { |
| 971 |
$.ajax({ |
| 972 |
url: window.kingAddonsData.ajaxUrl, |
| 973 |
type: 'POST', |
| 974 |
data: { |
| 975 |
action: 'king_addons_get_sections_catalog', |
| 976 |
nonce: window.kingAddonsData.nonce || '', |
| 977 |
search: '', |
| 978 |
category: '', |
| 979 |
section_type: '', |
| 980 |
plan: '', |
| 981 |
page: 1 |
| 982 |
}, |
| 983 |
success: function(response) { |
| 984 |
if (response.success && response.data.pagination) { |
| 985 |
$('#sections-count').text(response.data.pagination.total_sections); |
| 986 |
} |
| 987 |
}, |
| 988 |
error: function(xhr, status, error) { |
| 989 |
console.log('Failed to load sections count:', error); |
| 990 |
} |
| 991 |
}); |
| 992 |
} |
| 993 |
|
| 994 |
// ===== COLLECTIONS (LIST VIEW ONLY) ===== |
| 995 |
|
| 996 |
window.collectionRowsLoaded = false; |
| 997 |
window.collectionRowsData = null; |
| 998 |
window.collectionRowsPage = 1; |
| 999 |
window.collectionRowsSearch = ''; |
| 1000 |
|
| 1001 |
function loadCollectionRows(page = 1) { |
| 1002 |
$('.collections-rows-container').html('<div class="collections-loading">Loading collections...</div>'); |
| 1003 |
window.collectionRowsPage = page; |
| 1004 |
|
| 1005 |
$.ajax({ |
| 1006 |
url: window.kingAddonsData.ajaxUrl, |
| 1007 |
type: 'POST', |
| 1008 |
data: { |
| 1009 |
action: 'king_addons_get_collections_rows', |
| 1010 |
nonce: window.kingAddonsData.nonce || '', |
| 1011 |
page: page, |
| 1012 |
search: window.collectionRowsSearch || '' |
| 1013 |
}, |
| 1014 |
success: function(response) { |
| 1015 |
if (response.success) { |
| 1016 |
window.collectionRowsData = response.data; |
| 1017 |
window.collectionRowsLoaded = true; |
| 1018 |
renderCollectionRows(); |
| 1019 |
} else { |
| 1020 |
$('.collections-rows-container').html('<div class="collections-error">Error loading collections.</div>'); |
| 1021 |
} |
| 1022 |
}, |
| 1023 |
error: function() { |
| 1024 |
$('.collections-rows-container').html('<div class="collections-error">Failed to load collections.</div>'); |
| 1025 |
} |
| 1026 |
}); |
| 1027 |
} |
| 1028 |
|
| 1029 |
function renderCollectionRows() { |
| 1030 |
if (!window.collectionRowsData || !window.collectionRowsData.collections) { |
| 1031 |
$('.collections-rows-container').html('<div class="collections-empty">No collections found.</div>'); |
| 1032 |
return; |
| 1033 |
} |
| 1034 |
|
| 1035 |
var html = ''; |
| 1036 |
var collections = window.collectionRowsData.collections; |
| 1037 |
|
| 1038 |
collections.forEach(function(collection) { |
| 1039 |
if (collection.templates.length === 0) return; // Skip empty collections |
| 1040 |
|
| 1041 |
var templatesCount = collection.templates_count || 0; |
| 1042 |
var sectionsCount = collection.sections_count || 0; |
| 1043 |
|
| 1044 |
html += ` |
| 1045 |
<div class="collection-row"> |
| 1046 |
<div class="collection-row-header"> |
| 1047 |
<div class="collection-row-title-wrap"> |
| 1048 |
<h3 class="collection-row-title">${collection.name}</h3> |
| 1049 |
<div class="collection-row-counts"> |
| 1050 |
<span class="collection-row-count" title="Templates"> |
| 1051 |
<i class="eicon-document-file"></i> ${templatesCount} |
| 1052 |
</span> |
| 1053 |
<span class="collection-row-count" title="Sections"> |
| 1054 |
<i class="eicon-section"></i> ${sectionsCount} |
| 1055 |
</span> |
| 1056 |
</div> |
| 1057 |
</div> |
| 1058 |
<a href="#" class="collection-row-view-all" data-collection-id="${collection.id}"> |
| 1059 |
View All <i class="eicon-arrow-right"></i> |
| 1060 |
</a> |
| 1061 |
</div> |
| 1062 |
<div class="collection-row-scroll-wrap"> |
| 1063 |
<div class="collection-row-scroll"> |
| 1064 |
`; |
| 1065 |
|
| 1066 |
collection.templates.forEach(function(template) { |
| 1067 |
var thumbUrl = `https://thumbnails.kingaddons.com/${template.key}.png?v=4`; |
| 1068 |
html += ` |
| 1069 |
<div class="collection-row-item template-item" |
| 1070 |
data-template-key="${template.key}" |
| 1071 |
data-template-plan="${template.plan}"> |
| 1072 |
<img src="${thumbUrl}" alt="${template.title}" loading="lazy"> |
| 1073 |
<div class="collection-row-item-info"> |
| 1074 |
<h4 class="collection-row-item-title">${template.title}</h4> |
| 1075 |
<div class="collection-row-item-meta"> |
| 1076 |
<span class="template-plan template-plan-${template.plan}">${template.plan}</span> |
| 1077 |
</div> |
| 1078 |
</div> |
| 1079 |
</div> |
| 1080 |
`; |
| 1081 |
}); |
| 1082 |
|
| 1083 |
html += ` |
| 1084 |
</div> |
| 1085 |
</div> |
| 1086 |
</div> |
| 1087 |
`; |
| 1088 |
}); |
| 1089 |
|
| 1090 |
if (!html || html.trim() === '') { |
| 1091 |
$('.collections-rows-container').html('<div class="collection-row-empty">No collections found.</div>'); |
| 1092 |
$('.collections-rows-pagination').html(''); |
| 1093 |
return; |
| 1094 |
} |
| 1095 |
|
| 1096 |
$('.collections-rows-container').html(html); |
| 1097 |
|
| 1098 |
// Render Pagination |
| 1099 |
var pagination = window.collectionRowsData.pagination; |
| 1100 |
var paginationHtml = ''; |
| 1101 |
|
| 1102 |
if (pagination && pagination.pages > 1) { |
| 1103 |
paginationHtml += '<div class="pagination-inner">'; |
| 1104 |
|
| 1105 |
// Previous |
| 1106 |
if (pagination.current > 1) { |
| 1107 |
paginationHtml += `<a class="page-numbers collection-rows-page" href="#" data-page="${pagination.current - 1}"><i class="eicon-chevron-left"></i></a>`; |
| 1108 |
} |
| 1109 |
|
| 1110 |
// Smart Pagination Logic (1 2 3 ... 10) |
| 1111 |
var startPage = Math.max(1, pagination.current - 2); |
| 1112 |
var endPage = Math.min(pagination.pages, pagination.current + 2); |
| 1113 |
|
| 1114 |
if (startPage > 1) { |
| 1115 |
paginationHtml += `<a class="page-numbers collection-rows-page" href="#" data-page="1">1</a>`; |
| 1116 |
if (startPage > 2) { |
| 1117 |
paginationHtml += `<span class="page-numbers dots">...</span>`; |
| 1118 |
} |
| 1119 |
} |
| 1120 |
|
| 1121 |
for (var i = startPage; i <= endPage; i++) { |
| 1122 |
if (i === pagination.current) { |
| 1123 |
paginationHtml += `<span class="page-numbers current">${i}</span>`; |
| 1124 |
} else { |
| 1125 |
paginationHtml += `<a class="page-numbers collection-rows-page" href="#" data-page="${i}">${i}</a>`; |
| 1126 |
} |
| 1127 |
} |
| 1128 |
|
| 1129 |
if (endPage < pagination.pages) { |
| 1130 |
if (endPage < pagination.pages - 1) { |
| 1131 |
paginationHtml += `<span class="page-numbers dots">...</span>`; |
| 1132 |
} |
| 1133 |
paginationHtml += `<a class="page-numbers collection-rows-page" href="#" data-page="${pagination.pages}">${pagination.pages}</a>`; |
| 1134 |
} |
| 1135 |
|
| 1136 |
// Next |
| 1137 |
if (pagination.current < pagination.pages) { |
| 1138 |
paginationHtml += `<a class="page-numbers collection-rows-page" href="#" data-page="${pagination.current + 1}"><i class="eicon-chevron-right"></i></a>`; |
| 1139 |
} |
| 1140 |
|
| 1141 |
paginationHtml += '</div>'; |
| 1142 |
} |
| 1143 |
|
| 1144 |
$('.collections-rows-pagination').html(paginationHtml); |
| 1145 |
|
| 1146 |
// Handle pagination click |
| 1147 |
$('.collection-rows-page').off('click').on('click', function(e) { |
| 1148 |
e.preventDefault(); |
| 1149 |
var page = $(this).data('page'); |
| 1150 |
loadCollectionRows(page); |
| 1151 |
$('html, body').animate({scrollTop: $('#collections-catalog').offset().top - 50}, 500); |
| 1152 |
}); |
| 1153 |
|
| 1154 |
// Handle "View All" click to switch to details view |
| 1155 |
$('.collection-row-view-all').off('click').on('click', function(e) { |
| 1156 |
e.preventDefault(); |
| 1157 |
var collectionId = $(this).data('collection-id'); |
| 1158 |
openCollectionDetails(collectionId); |
| 1159 |
}); |
| 1160 |
} |
| 1161 |
|
| 1162 |
// Collections search (List View) |
| 1163 |
var collectionsSearchTimer = null; |
| 1164 |
$(document).on('input', '#collections-search', function() { |
| 1165 |
var value = $(this).val() || ''; |
| 1166 |
window.collectionRowsSearch = value; |
| 1167 |
clearTimeout(collectionsSearchTimer); |
| 1168 |
collectionsSearchTimer = setTimeout(function() { |
| 1169 |
window.collectionRowsLoaded = false; |
| 1170 |
loadCollectionRows(1); |
| 1171 |
}, 250); |
| 1172 |
}); |
| 1173 |
}); |
| 1174 |
|
| 1175 |
|