PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.86
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.86
51.1.86 51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 All 40 releases
← All changes | includes/admin/js/templates.js +365 -48 51.1.38 → 51.1.86 View file →
@@ -125,9 +125,9 @@
125 125 .then(response => {
126 126 if (!response.ok) {
127 127 // The server returned a 4xx or 5xx, read the text and throw an error
128 128 return response.text().then(html => {
129 - console.error('Server error:\n' + html);
129 + // console.error('Server error:\n' + html);
130 130 throw new Error('Server error (not JSON).');
131 131 });
132 132 }
133 133 // If ok, parse JSON
@@ -134,9 +134,9 @@
134 134 return response.json();
135 135 })
136 136 .then(data => {
137 137 if (!data.success) {
138 - console.error('API error:', data);
138 + // console.error('API error:', data);
139 139 }
140 140 if (data.success) {
141 141 $('#template-installing-popup').fadeIn();
142 142 doImport(data);
@@ -144,9 +144,9 @@
144 144 $('#premium-promo-popup').fadeIn();
145 145 }
146 146 })
147 147 .catch(error => {
148 - console.error('Fetch error:', error);
148 + // console.error('Fetch error:', error);
149 149 alert('Connection error: ' + error);
150 150 });
151 151 });
152 152
@@ -176,9 +176,10 @@
176 176 fetch(kingAddonsData.ajaxUrl, {
177 177 method: 'POST',
178 178 body: new URLSearchParams({
179 179 action: 'import_elementor_page_with_images',
180 - data: JSON.stringify(initial_data),
180 + nonce: kingAddonsData.nonce,
181 + data: JSON.stringify(initial_data)
181 182 })
182 183 })
183 184 .then(response => {
184 185 if (!response.ok) {
@@ -183,9 +184,9 @@
183 184 .then(response => {
184 185 if (!response.ok) {
185 186 // The server returned a 4xx or 5xx, read the text and throw an error
186 187 return response.text().then(html => {
187 - console.error('Server error:\n' + html);
188 + // console.error('Server error:\n' + html);
188 189 throw new Error('Server error:\n' + html);
189 190 });
190 191 }
191 192 // If ok, parse JSON
@@ -212,8 +213,9 @@
212 213 fetch(kingAddonsData.ajaxUrl, {
213 214 method: 'POST',
214 215 body: new URLSearchParams({
215 216 action: 'process_import_images',
217 + nonce: kingAddonsData.nonce
216 218 })
217 219 })
218 220 .then(response => {
219 221 if (!response.ok) {
@@ -218,9 +220,9 @@
218 220 .then(response => {
219 221 if (!response.ok) {
220 222 // The server returned a 4xx or 5xx, read the text and throw an error
221 223 return response.text().then(html => {
222 - console.error('Server error:\n' + html);
224 + // console.error('Server error:\n' + html);
223 225 throw new Error('Server error:\n' + html);
224 226 });
225 227 }
226 228 // If ok, parse JSON
@@ -255,9 +257,9 @@
255 257 goToPage.fadeIn();
256 258 $('#close-installing-popup').fadeIn();
257 259 }
258 260 } else {
259 - console.error('Process image issue:', data);
261 + // console.error('Process image issue:', data);
260 262 // Skip image
261 263 if (data.data && data.data.retry) {
262 264 processNextImage();
263 265 }
@@ -263,9 +265,9 @@
263 265 }
264 266 }
265 267 })
266 268 .catch(error => {
267 - console.error('Catch Error:', error);
269 + // console.error('Catch Error:', error);
268 270 if (currentRetry < maxRetries) {
269 271 currentRetry++;
270 272 retryTimeout *= 2;
271 273 setTimeout(attemptProcessImage, retryTimeout);
@@ -273,9 +275,9 @@
273 275 let imageUrlElement = document.querySelector('li[data-url="unknown"]');
274 276 if (imageUrlElement) {
275 277 imageUrlElement.innerHTML += ' - SKIPPED';
276 278 }
277 - console.error('Error:', error);
279 + // console.error('Error:', error);
278 280 document.getElementById('final_response').innerText = 'Error: ' + error.message;
279 281 currentRetry = 0;
280 282 retryTimeout = 1000;
281 283 processNextImage();
@@ -330,9 +332,9 @@
330 332 alert('Error: ' + response.data);
331 333 }
332 334 },
333 335 error: function (xhr, status, error) {
334 - console.error('AJAX Error: ', status, error);
336 + // console.error('AJAX Error: ', status, error);
335 337 }
336 338 });
337 339 }
338 340
@@ -397,10 +399,96 @@
397 399 // Load sections on first visit to sections tab
398 400 if (tabId === 'sections' && !window.sectionsLoaded) {
399 401 loadSections();
400 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 + }
401 413 });
402 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 +
403 491 // ===== SECTIONS FUNCTIONALITY =====
404 492
405 493 window.sectionsLoaded = false;
406 494 window.sectionsData = null;
@@ -408,9 +496,9 @@
408 496 window.sectionsFilters = {};
409 497
410 498 function loadSections(page = 1) {
411 499 if (!window.kingAddonsData || !window.kingAddonsData.ajaxUrl) {
412 - console.error('King Addons data not available');
500 + // console.error('King Addons data not available');
413 501 return;
414 502 }
415 503
416 504 var searchQuery = $('#sections-search').val() || '';
@@ -455,9 +543,9 @@
455 543 `);
456 544 }
457 545 },
458 546 error: function(xhr, status, error) {
459 - console.error('AJAX Error loading sections:', status, error);
547 + // console.error('AJAX Error loading sections:', status, error);
460 548 $('.sections-grid').html(`
461 549 <div class="sections-loading">
462 550 Failed to load sections. Please try again.
463 551 </div>
@@ -489,26 +577,26 @@
489 577 data-section-plan="${section.plan}"
490 578 data-category="${section.category || ''}"
491 579 data-tags="${(section.tags || []).join(',')}"
492 580 data-section-type="${section.section_type || ''}">
493 - <img class="kng-addons-section-thumbnail" loading="lazy"
494 - src="${screenshotUrl}"
495 - alt="${section.title}"
496 - onerror="this.src='data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjE4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImciIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNmOGY5ZmEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlNWU3ZWIiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2cpIi8+PGNpcmNsZSBjeD0iMTUwIiBjeT0iNzAiIHI9IjE2IiBmaWxsPSIjOWNhM2FmIiBvcGFjaXR5PSIwLjQiLz48cmVjdCB4PSIxMzQiIHk9Ijg2IiB3aWR0aD0iMzIiIGhlaWdodD0iNCIgZmlsbD0iIzljYTNhZiIgb3BhY2l0eT0iMC40IiByeD0iMiIvPjxyZWN0IHg9IjEyNiIgeT0iOTQiIHdpZHRoPSI0OCIgaGVpZ2h0PSI0IiBmaWxsPSIjOWNhM2FmIiBvcGFjaXR5PSIwLjMiIHJ4PSIyIi8+PHRleHQgeD0iNTAlIiB5PSIxMjAiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsIHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTIiIGZpbGw9IiM2Yjc1ODQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIG9wYWNpdHk9IjAuNyI+U2VjdGlvbiBQcmV2aWV3PC90ZXh0Pjwvc3ZnPg=='">
497 - <div class="section-content">
498 - <h3>${section.title}</h3>
499 - <div class="section-plan section-plan-${section.plan}">${section.plan}</div>
500 - </div>
501 - <div class="section-overlay">
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=='">
502 586 <div class="section-actions">
503 - <button class="section-import-btn" data-section-key="${section.section_key}" data-section-plan="${section.plan}">
504 - Import Section
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
505 589 </button>
506 - <a href="https://sections.kingaddons.com/${section.section_key}" class="section-preview-btn" target="_blank">
507 - Live Preview
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
508 592 </a>
509 593 </div>
594 + ${section.plan === 'premium' ? '<span class="section-badge-pro">PRO</span>' : ''}
510 595 </div>
596 + <div class="section-info">
597 + <h4>${section.title}</h4>
598 + </div>
511 599 </div>
512 600 `;
513 601 });
514 602
@@ -685,47 +773,87 @@
685 773 loadSections(page);
686 774 }
687 775 });
688 776
689 - // Section import button handler
690 - $(document).on('click', '.section-import-btn', function(e) {
777 + // Section Import Popup Logic
778 + let pendingSectionImport = null;
779 +
780 + // Open Import Popup
781 + $(document).on('click', '.import-section-btn', function(e) {
691 782 e.preventDefault();
692 - e.stopPropagation(); // Prevent triggering parent click
783 + e.stopPropagation();
693 784
694 - var sectionKey = $(this).data('section-key');
695 - var sectionPlan = $(this).data('section-plan');
785 + let sectionKey = $(this).data('section-key');
786 + let sectionPlan = $(this).data('section-plan');
787 + let sectionTitle = $(this).closest('.section-item').find('h4').text();
696 788
697 - // Check if this is a premium section and user doesn't have premium
698 - var planActive = $('#install-template').attr('data-plan-active');
699 -
789 + // Check premium
790 + let planActive = $('#install-template').attr('data-plan-active');
700 791 if (sectionPlan === 'premium' && planActive !== 'premium') {
701 - // Show premium promo popup
702 792 $('#templates-catalog').addClass('kng-whole-overlay');
703 793 $('#premium-promo-popup').fadeIn();
704 794 return;
705 795 }
706 -
707 - // For free sections or premium sections with premium license, trigger import
708 - if (confirm('Import this section?\n\nSection: ' + sectionKey + '\nPlan: ' + sectionPlan + '\n\nNote: This will be added to your current page in Elementor.')) {
709 - importSection(sectionKey, sectionPlan);
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();
710 836 }
711 837 });
712 838
713 - // Section preview button handler (handled by href, but we can add tracking here)
714 - $(document).on('click', '.section-preview-btn', function(e) {
715 - e.stopPropagation(); // Prevent triggering parent click
716 - // The link will open in new tab automatically due to target="_blank"
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 + }
717 844 });
718 845
719 846 // Section item click handler - now only for general clicks (not on buttons)
720 847 $(document).on('click', '.section-item', function(e) {
721 848 // Don't trigger if clicking on buttons or overlay
722 - if ($(e.target).closest('.section-overlay, .section-import-btn, .section-preview-btn').length) {
849 + if ($(e.target).closest('.section-overlay, .import-section-btn, .live-preview-btn').length) {
723 850 return;
724 851 }
725 852
726 853 var sectionKey = $(this).data('section-key');
727 854 var sectionPlan = $(this).data('section-plan');
855 + var sectionTitle = $(this).find('h4').text();
728 856
729 857 // Check if this is a premium section and user doesn't have premium
730 858 var planActive = $('#install-template').attr('data-plan-active');
731 859
@@ -735,12 +863,19 @@
735 863 $('#premium-promo-popup').fadeIn();
736 864 return;
737 865 }
738 866
739 - // For free sections or premium sections with premium license, trigger import
740 - if (confirm('Import this section?\n\nSection: ' + sectionKey + '\nPlan: ' + sectionPlan + '\n\nNote: This will be added to your current page in Elementor.')) {
741 - importSection(sectionKey, sectionPlan);
742 - }
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 + });
743 878 });
744 879
745 880 // Function to import section from main catalog
746 881 function importSection(sectionKey, sectionPlan) {
@@ -807,8 +942,9 @@
807 942 url: window.kingAddonsData.ajaxUrl,
808 943 type: 'POST',
809 944 data: {
810 945 action: 'import_elementor_page_with_images',
946 + nonce: window.kingAddonsData.nonce,
811 947 data: JSON.stringify(importData)
812 948 },
813 949 success: function(result) {
814 950 if (result.success) {
@@ -849,9 +985,190 @@
849 985 $('#sections-count').text(response.data.pagination.total_sections);
850 986 }
851 987 },
852 988 error: function(xhr, status, error) {
853 - console.log('Failed to load sections count:', error);
989 + // console.log('Failed to load sections count:', error);
854 990 }
855 991 });
856 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 + });
857 1173 });
1174 +