PageSourceSearch

https://www.hogbackdistillery.com/wp-content/plugins/hogback-gift-voucher/assets/js/voucher.js?ver=1791510194

js hogbackdistillery.com collected 2026-10-09 01:43:47 UTC 12,422 bytes, 261 lines download raw bytes

1(function(){
2    function getHeaderOffset(){
3        var header = document.querySelector('.elementor-location-header');
4        if (!header) return 0;
5        var height = header.offsetHeight || 0;
6        var extra = 16; // small breathing space below header
7        return height + extra;
8    }
9    var stripeInstance = null;
10
11    function ensureStripe(){
12        if (!stripeInstance && window.Stripe && window.HogbackGV && HogbackGV.publishableKey) {
13            stripeInstance = Stripe(HogbackGV.publishableKey);
14        }
15        return stripeInstance;
16    }
17
18    function selectFlight(element) {
19        document.querySelectorAll('.flight-option').forEach(function(opt){ opt.classList.remove('selected'); });
20        element.classList.add('selected');
21        calculateTotal();
22        // Smooth scroll to Number of Guests with header-based offset
23        var guestsEl = document.getElementById('guests');
24        if (guestsEl) {
25            var rect = guestsEl.getBoundingClientRect();
26            var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
27            var offset = getHeaderOffset();
28            var targetY = rect.top + scrollTop - offset;
29            window.scrollTo({ top: targetY, behavior: 'smooth' });
30            // Also focus for accessibility after scroll
31            setTimeout(function(){ guestsEl.focus(); }, 300);
32        }
33    }
34
35    function getSelectedFlight(){
36        var checked = document.querySelector('input[name="flight"]:checked');
37        if (!checked) return { price: 0, name: '' };
38        var label = checked.closest('.flight-option');
39        var name = label ? (label.querySelector('h3') ? label.querySelector('h3').textContent.trim() : '') : '';
40        var price = parseFloat(checked.value || '0');
41        return { price: price, name: name };
42    }
43
44    function calculateTotal() {
45        var flight = getSelectedFlight();
46        var guestsEl = document.getElementById('guests');
47        var guests = parseInt(guestsEl ? guestsEl.value : '1', 10) || 1;
48        var subtotal = (flight.price || 0) * guests;
49        var serviceFee = 0;
50        var total = subtotal + serviceFee;
51        var fmt = function(n){ return '$' + (n||0).toFixed(2); };
52        var subtotalEl = document.getElementById('subtotal');
53        var serviceFeeEl = document.getElementById('serviceFee');
54        var totalEl = document.getElementById('total');
55        if (subtotalEl) subtotalEl.innerText = fmt(subtotal);
56        if (serviceFeeEl) serviceFeeEl.innerText = fmt(serviceFee);
57        if (totalEl) totalEl.innerText = fmt(total);
58    }
59
60    function getSelectedGiftcardItems(){
61        var items = [];
62        document.querySelectorAll('input[name="gift_amount"]:checked').forEach(function(input){
63            var amount = parseFloat(input.value || '0');
64            if (amount > 0) {
65                items.push({ amount: amount });
66            }
67        });
68        return items;
69    }
70
71    function calculateGiftcardTotal(){
72        var items = getSelectedGiftcardItems();
73        var total = items.reduce(function(sum, item){ return sum + (item.amount || 0); }, 0);
74        var totalEl = document.getElementById('giftcardTotal');
75        if (totalEl) totalEl.innerText = '$' + total.toFixed(2);
76    }
77
78    function bindEvents(){
79        document.querySelectorAll('.flight-option').forEach(function(label){
80            var radio = label.querySelector('input[type="radio"]');
81            if (!radio) return;
82            label.addEventListener('click', function(){
83                if (radio) { radio.checked = true; }
84                selectFlight(label);
85            });
86        });
87        var guests = document.getElementById('guests');
88        if (guests) guests.addEventListener('change', calculateTotal);
89        calculateTotal();
90
91        var form = document.getElementById('voucherForm');
92        if (form) {
93            form.addEventListener('submit', function(e){
94                e.preventDefault();
95                var submitBtn = form.querySelector('.btn-submit');
96                var originalText = submitBtn ? submitBtn.textContent : '';
97                if (submitBtn) {
98                    submitBtn.textContent = 'Processing...';
99                    submitBtn.disabled = true;
100                }
101                var stripe = ensureStripe();
102                if (!stripe) {
103                    alert('Stripe is not initialized. Please set the publishable key.');
104                    if (submitBtn) {
105                        submitBtn.textContent = originalText || 'Pay Now';
106                        submitBtn.disabled = false;
107                    }
108                    return;
109                }
110
111                // Basic client-side validation
112                var email = form.querySelector('#email');
113                var sender = form.querySelector('#senderName');
114                var recipient = form.querySelector('#recipientName');
115                var flight = getSelectedFlight();
116                var age = form.querySelector('#ageConfirm');
117                var guestsEl = document.getElementById('guests');
118                var guests = parseInt(guestsEl ? guestsEl.value : '1', 10) || 1;
119                if (!email.value || !sender.value || !recipient.value || !flight.price || !age.checked) {
120                    alert('Please complete all required fields and confirm age.');
121                    if (submitBtn) {
122                        submitBtn.textContent = originalText || 'Pay Now';
123                        submitBtn.disabled = false;
124                    }
125                    return;
126                }
127
128                var data = new FormData();
129                data.append('action', 'hogback_create_checkout_session');
130                data.append('nonce', (window.HogbackGV && HogbackGV.nonce) ? HogbackGV.nonce : '');
131                data.append('email', email.value);
132                data.append('senderName', sender.value);
133                data.append('recipientName', recipient.value);
134                data.append('message', (form.querySelector('#message') || { value: '' }).value);
135                data.append('guests', String(guests));
136                data.append('flight', String(flight.price));
137                data.append('flightName', flight.name || 'Tasting Flight');
138
139                fetch(HogbackGV.ajaxUrl, { method: 'POST', body: data })
140                    .then(function(resp){ return resp.json(); })
141                    .then(function(json){
142                        if (json && json.success && json.data) {
143                            // Prefer URL redirect if provided
144                            if (json.data.checkoutUrl) {
145                                window.location.href = json.data.checkoutUrl;
146                                return;
147                            }
148                            if (json.data.sessionId) {
149                                stripe.redirectToCheckout({ sessionId: json.data.sessionId });
150                                return;
151                            }
152                        }
153                        var msg = (json && json.data && json.data.message) ? json.data.message : 'Failed to start checkout.';
154                        alert(msg);
155                        if (submitBtn) {
156                            submitBtn.textContent = originalText || 'Pay Now';
157                            submitBtn.disabled = false;
158                        }
159                    })
160                    .catch(function(){
161                        alert('Network error.');
162                        if (submitBtn) {
163                            submitBtn.textContent = originalText || 'Pay Now';
164                            submitBtn.disabled = false;
165                        }
166                    });
167            });
168        }
169
170        var giftForm = document.getElementById('giftCardForm');
171        if (giftForm) {
172            giftForm.querySelectorAll('input[name="gift_amount"]').forEach(function(input){
173                input.addEventListener('change', function(){
174                    var label = input.closest('.giftcard-option');
175                    if (label) {
176                        if (input.checked) {
177                            label.classList.add('selected');
178                        } else {
179                            label.classList.remove('selected');
180                        }
181                    }
182                    calculateGiftcardTotal();
183                });
184            });
185            calculateGiftcardTotal();
186
187            giftForm.addEventListener('submit', function(e){
188                e.preventDefault();
189                var submitBtn = giftForm.querySelector('.btn-submit');
190                var originalText = submitBtn ? submitBtn.textContent : '';
191                if (submitBtn) {
192                    submitBtn.textContent = 'Processing...';
193                    submitBtn.disabled = true;
194                }
195                var stripe = ensureStripe();
196                if (!stripe) {
197                    alert('Stripe is not initialized. Please set the publishable key.');
198                    if (submitBtn) {
199                        submitBtn.textContent = originalText || 'Pay Now';
200                        submitBtn.disabled = false;
201                    }
202                    return;
203                }
204
205                var email = giftForm.querySelector('#gcEmail');
206                var sender = giftForm.querySelector('#gcSenderName');
207                var recipient = giftForm.querySelector('#gcRecipientName');
208                var age = giftForm.querySelector('#gcAgeConfirm');
209                var items = getSelectedGiftcardItems();
210                if (!email.value || !sender.value || !recipient.value || items.length === 0 || !age.checked) {
211                    alert('Please complete all required fields and select at least one amount.');
212                    if (submitBtn) {
213                        submitBtn.textContent = originalText || 'Pay Now';
214                        submitBtn.disabled = false;
215                    }
216                    return;
217                }
218
219                var data = new FormData();
220                data.append('action', 'hogback_create_giftcard_checkout_session');
221                data.append('nonce', (window.HogbackGV && HogbackGV.nonce) ? HogbackGV.nonce : '');
222                data.append('email', email.value);
223                data.append('senderName', sender.value);
224                data.append('recipientName', recipient.value);
225                data.append('message', (giftForm.querySelector('#gcMessage') || { value: '' }).value);
226                data.append('items', JSON.stringify(items));
227                data.append('ageConfirm', age.checked ? '1' : '');
228
229                fetch(HogbackGV.ajaxUrl, { method: 'POST', body: data })
230                    .then(function(resp){ return resp.json(); })
231                    .then(function(json){
232                        if (json && json.success && json.data) {
233                            if (json.data.checkoutUrl) {
234                                window.location.href = json.data.checkoutUrl;
235                                return;
236                            }
237                            if (json.data.sessionId) {
238                                stripe.redirectToCheckout({ sessionId: json.data.sessionId });
239                                return;
240                            }
241                        }
242                        var msg = (json && json.data && json.data.message) ? json.data.message : 'Failed to start checkout.';
243                        alert(msg);
244                        if (submitBtn) {
245                            submitBtn.textContent = originalText || 'Pay Now';
246                            submitBtn.disabled = false;
247                        }
248                    })
249                    .catch(function(){
250                        alert('Network error.');
251                        if (submitBtn) {
252                            submitBtn.textContent = originalText || 'Pay Now';
253                            submitBtn.disabled = false;
254                        }
255                    });
256            });
257        }
258    }
259
260    document.addEventListener('DOMContentLoaded', bindEvents);
261})();

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.