1/** 2 * Pick Cards - "Order again" / "Popular" strip 3 * New file: assets/js/pick-cards.js 4 * 5 * A pick card never adds to the cart itself. It finds the matching main menu 6 * card (data-target-id = product id, or the parent id for a variation child) 7 * and hands it to ProductModal, so options and variations are chosen again 8 * through the normal modal and prices come from the same server-validated path. 9 */ 10 11const PickCards = { 12 13 target(card) { 14 if (!card || !card.dataset) return null; 15 const id = card.dataset.targetId; 16 const main = id 17 ? document.querySelector(`#productsContainer .menu-product-card[data-product-id="${id}"]`) 18 : null; 19 // Variation children have no matching main card (parents carry no id) - the 20 // pick card carries its own data-product, so ProductModal can work off it directly 21 return main || (card.dataset.product ? card : null); 22 }, 23 24 // Free strip card: locked -> tell them what unlocks it, claimed -> nothing, 25 // unlocked -> OffersManager decides between direct add and the modal 26 openFree(card) { 27 if (!card) return; 28 if (card.classList.contains('locked')) { 29 if (typeof Cart !== 'undefined' && card.dataset.unlockSub) Cart.showNotification(card.dataset.unlockSub, 'info'); 30 return; 31 } 32 if (card.classList.contains('claimed')) return; 33 if (typeof OffersManager !== 'undefined') { 34 OffersManager.addFreeItem(parseInt(card.dataset.productId, 10), card.dataset.offerId); 35 } 36 }, 37 38 open(card) { 39 const target = this.target(card); 40 if (!target) return; 41 if (typeof ProductModal === 'undefined') return; 42 ProductModal.open(target); 43 }, 44 45 add(card) { 46 const target = this.target(card); 47 if (!target || typeof ProductModal === 'undefined') return; 48 49 ProductModal.quickAdd(target); 50 51 // Only flash our own button for a direct add; modal opens otherwise 52 let isSimple = false; 53 try { 54 const data = JSON.parse(target.dataset.product || '{}'); 55 isSimple = target.dataset.hasVariations !== '1' && !(data.options && data.options.length); 56 } catch (e) { /* ignore */ } 57 58 if (isSimple) { 59 const btn = card.querySelector('.menu-product-card__quick-add'); 60 if (btn) { 61 btn.classList.add('added'); 62 setTimeout(() => btn.classList.remove('added'), 1500); 63 } 64 } 65 } 66};
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.