PageSourceSearch

https://www.tccq.com/wp-content/plugins/matrix-bogo-promotions/assets/js/gift-popup.js?ver=1.2.1

js tccq.com collected 2026-09-24 10:46:53 UTC 4,428 bytes, 134 lines download raw bytes

1/**
2 * Matrix BOGO – Gift Popup JS
3 * Manages the gift-selector modal on cart/checkout pages.
4 */
5/* global matrixBogoFrontend */
6(function ($) {
7	'use strict';
8
9	const $popup = $('#matrix-bogo-gift-popup');
10	const $overlay = $popup.find('.matrix-bogo-popup-overlay');
11	const $products = $popup.find('#matrix-bogo-popup-products');
12	const $addBtn = $popup.find('#matrix-bogo-popup-add-btn');
13
14	let currentRuleId = null;
15	let currentNonce = null;
16
17	// ── Open popup if choice gifts exist ────────────────────────────
18
19	function maybeOpenPopup() {
20		if (!$popup.length) return;
21		if (!matrixBogoFrontend.hasChoiceGifts) return;
22
23		// Avoid re-showing if already dismissed this session.
24		if (sessionStorage.getItem('matrix_bogo_popup_dismissed')) return;
25
26		openPopup(matrixBogoFrontend.choiceRuleId, matrixBogoFrontend.nonce);
27	}
28
29	function openPopup(ruleId, nonce) {
30		currentRuleId = ruleId;
31		currentNonce = nonce;
32		loadGiftProducts(ruleId, nonce);
33		$popup.fadeIn(200).attr('aria-hidden', 'false');
34		$('body').addClass('matrix-bogo-popup-open');
35	}
36
37	function closePopup() {
38		$popup.fadeOut(200).attr('aria-hidden', 'true');
39		$('body').removeClass('matrix-bogo-popup-open');
40		sessionStorage.setItem('matrix_bogo_popup_dismissed', '1');
41	}
42
43	// ── Load gift product options ────────────────────────────────────
44
45	function loadGiftProducts(ruleId, nonce) {
46		$products.html('<div class="matrix-bogo-popup-loading"><span class="spinner is-active"></span></div>');
47
48		$.post(matrixBogoFrontend.ajaxUrl, {
49			action: 'matrix_bogo_search_gifts',
50			nonce,
51			rule_id: ruleId,
52		}).done(function (res) {
53			if (!res.success || !res.data.products.length) {
54				$products.html('<p>' + matrixBogoFrontend.i18n.noGifts + '</p>');
55				return;
56			}
57			renderProducts(res.data.products);
58		}).fail(function () {
59			$products.html('<p>' + matrixBogoFrontend.i18n.error + '</p>');
60		});
61	}
62
63	function renderProducts(products) {
64		let html = '<div class="matrix-bogo-gift-products">';
65		products.forEach(function (p) {
66			html += `
67				<div class="matrix-bogo-gift-item">
68					<label>
69						<input type="radio" name="matrix_bogo_popup_choice"
70						       value="${p.id}" data-quantity="1">
71						<img src="${p.thumbnail}" alt="${p.name}" width="80">
72						<span class="matrix-bogo-gift-name">${p.name}</span>
73						<span class="matrix-bogo-gift-free-label">${matrixBogoFrontend.i18n.free}</span>
74					</label>
75				</div>`;
76		});
77		html += '</div>';
78		$products.html(html);
79	}
80
81	// ── Add selected gift ────────────────────────────────────────────
82
83	$addBtn.on('click', function () {
84		const $checked = $products.find('input[type="radio"]:checked');
85		if (!$checked.length) {
86			alert(matrixBogoFrontend.i18n.selectGift);
87			return;
88		}
89
90		const productId = $checked.val();
91		const quantity = $checked.data('quantity') || 1;
92
93		$addBtn.prop('disabled', true);
94
95		$.post(matrixBogoFrontend.ajaxUrl, {
96			action: 'matrix_bogo_apply_gift',
97			nonce: currentNonce,
98			rule_id: currentRuleId,
99			product_id: productId,
100			quantity,
101		}).done(function (res) {
102			if (res.success) {
103				$(document.body).trigger('wc_fragment_refresh');
104				closePopup();
105			} else {
106				alert(res.data.message || matrixBogoFrontend.i18n.error);
107				$addBtn.prop('disabled', false);
108			}
109		});
110	});
111
112	// ── Enable Add button when a product is selected ─────────────────
113
114	$(document).on('change', '#matrix-bogo-popup-products input[type="radio"]', function () {
115		$addBtn.prop('disabled', false);
116	});
117
118	// ── Close handlers ────────────────────────────────────────────── */
119
120	$popup.find('.matrix-bogo-popup-close, .matrix-bogo-popup-skip').on('click', closePopup);
121	$overlay.on('click', closePopup);
122
123	$(document).on('keydown', function (e) {
124		if (e.key === 'Escape') closePopup();
125	});
126
127	// ── Init ─────────────────────────────────────────────────────────
128
129	$(function () {
130		// Small delay so cart fragments have loaded.
131		setTimeout(maybeOpenPopup, 800);
132	});
133
134})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.