document.addEventListener('DOMContentLoaded', function() { var cartWidget = document.querySelector('.elementor-widget-woocommerce-menu-cart'); if (!cartWidget) return; cartWidget.classList.remove('elementor-menu-cart--shown'); var container = cartWidget.querySelector('.elementor-menu-cart__container'); var main = cartWidget.querySelector('.elementor-menu-cart__main'); if (container) container.setAttribute('aria-hidden', 'true'); if (main) main.setAttribute('aria-hidden', 'true'); });

Шаурма

  • lrJpavN-NaDRCHf-dxreAFw_original

    Шаурма з креветкою та гуакомоле

    260,00 
    Шаурма у хрусткому лаваші з ніжними креветками, свіжим салатом айсберг, соковитими томатами та кремовим гуакамоле створює яскраве й збалансоване поєднання смаків. Ніжний майо-соус доповнює страву, надаючи їй м’якості та приємної насиченості.
  • kHJkNFC-ICXOkAZ-PCqyxIw_original

    Шаурма з креветкою “Азія”

    175,00 
    Шаурма у хрусткому лаваші з ніжними креветками, свіжим салатом айсберг, хрустким огірком та пікантною морквою по-корейськи створює легке й освіжаюче поєднання смаків. Ніжний майо-соус гармонійно доповнює страву, додаючи їй м’якості та делікатної насиченості.
  • QfzMRTb-liUovJI-IjrNApv_original

    Шаурма з куркою та грибами

    210,00 
    Шаурма з хрусткого лаваша, наповненого соковитою куркою, ніжним міксом сирів, ароматними шампіньйонами та маринованою ріпчастою цибулею, заправлена насиченим сирним соусом, що створює глибокий вершково-грибний смак із приємною тягучістю сиру 350г
  • GPcYBsQ-GkdqeUn-pLlwbWK_original

    Шаурма з куркою та ананасом

    180,00 
    Шаурма з хрусткого лаваша, наповненого соковитою куркою, хрумким салатом айсберг, свіжим болгарським перцем та соковитими шматочками ананаса, заправлена ніжним сирним соусом і класичним айолі, з додаванням халапеньйо, що надає страві яскравої пікантної гостроти та збалансованого смаку 350г
  • GbDjbwn-IFifCvk-VRCrqbI_original (1)

    Шаурма MEGA

    430,00 
    Соковита курка, свіжі овочі, хрустка капуста та фірмовий соус, загорнуті в ароматний лаваш. Насичена, класична, саме така, яку хочеться з’їсти до останнього шматочка. 1000г
  • QHIrphS-LqGkkJL-xGEJtFj_original

    MIX Курка/Яловичина

    185,00 
    Шаурма у хрусткому лаваші поєднує ніжну яловичину та соковиту курку, доповнені свіжою овочевою сальсою та листям салату айсберг. Ароматний часниковий айолі разом із фірмовим соусом Хулі створюють глибокий, насичений смак, що робить кожен шматочок по-справжньому гармонійним 320г
  • SCdGZeF-hFFShwY-CmGSIki_original

    Класична з яловичиною

    180,00 
    Шаурма у хрусткому лаваші поєднує ніжну яловичину, свіжу овочеву сальсу та хрусткий салат айсберг. Дует часникового айолі та фірмового соусу Хулі додає насиченості та легкої пікантності, створюючи витончений, але виразний смаковий акцент 300г
  • EzsJBFz-oDDSizb-AJLcbTb_original

    Шаурма з курочкою беконом та сирним соусом

    260,00 
    Шаурма у хрусткому лаваші з соковитою курочкою та хрустким беконом дарує поєднання м’ясної ніжності та приємної пружності. Свіжі овочі, тягучий сирний соус і фірмовий соус Хулі додають страві глибини та роблять її особливо апетитною 400г
  • WGGnkKl-DzHVBCG-BFqQETL

    Листопада

    158,00 
    Шаурма у хрусткому лаваші з соковитою курочкою, хрустким овочевим міксом та солодкою морквою по-корейськи дарує гармонію свіжості та легкої пікантності. Часниковий айолі додає страві глибини, роблячи її ніжною та водночас насиченою 350г
  • CAJedQv-QBvbVMq-dLXuGhV_original

    Бурум

    180,00 
    Шаурма у хрусткому лаваші створена з ніжної курки, що поєднується з ароматним часниковим айолі та стиглими помідорами. М’який сирний мікс із твердого сиру, сулугуні та моцарели робить смак багатим, делікатним і по-справжньому вершковим 350г
  • HjVgUNF-JSebenH-HUAzKCN_original

    Класична

    135,00 
    Шаурма у хрусткому лаваші поєднує овочеву сальсу, два види капусти та моркву, утворюючи яскраву та соковиту основу. Фірмова курка-гриль і часниковий айолі додають насиченого аромату, роблячи смак виразним і дуже домашнім 350г
(function($) { /* ========================= * Конфигурация шагов * ========================= */ const stepConfig = [ { name: 'quantity', condition: () => true, render: renderQuantityStep, collect: collectQuantity }, { name: 'ingredients', condition: r => r.hidden_attributes?.length && !answers.skipIngredients, render: renderIngredientsChoice, collect: collectIngredients }, { name: 'otherCategory', condition: r => r.custom_fields?.offer_other_categories, render: renderOtherCategoriesChoice, collect: collectOtherCategory }, { name: 'otherProduct', condition: (r,a) => a.otherCategory, render: renderOtherProductStep, collect: collectProductSelection }, { name: 'sauceList', condition: (r,a) => r.custom_fields?.offer_other_categories && a.otherCategory !== 21, render: body => renderProductList(() => `/wp-json/custom/v1/products/24`, 'Який соус бажаєте?', body), collect: collectProductSelection }, { name: 'drinkCategory', condition: r => r.custom_fields?.offer_drinks, render: renderDrinkCategoryChoice, collect: collectDrinkCategory }, { name: 'drinkList', condition: (r,a) => a.drinkCategory && a.drinkCategory !== 'none', render: body => renderProductList(() => `/wp-json/custom/v1/products/${answers.drinkCategory}`, 'Який напій бажаєте?', body), collect: collectProductSelection }, { name: 'dessertList', condition: r => r.custom_fields?.offer_donut, render: body => renderProductListWithNone(() => `/wp-json/custom/v1/products/23`, 'Який пончик з’їш сьогодні?', body, 'Далі'), collect: collectProductSelection } ]; /* ========================= * Служебные переменные * ========================= */ let currentStep = 0; let latestResponse = null; let productId = null; const answers = {}; const CART_URL = '/cart/'; let productMeta = { name: '', image: '', link: '#' }; /* ========================= * Утилиты * ========================= */ function escapeHtml(s=''){return String(s).replace(/[&"']/g, m=>({'&':'&','':'>','"':'"',"'":'''}[m]))} function debounce(fn, wait){ let t; return function(...a){ clearTimeout(t); t=setTimeout(()=>fn.apply(this,a), wait); }; } function updateCartItemQty(itemKey, qty){ if (!window.HULI_AJAX || !HULI_AJAX.url || !HULI_AJAX.nonce) { console.error('[Cart] HULI_AJAX не инициализирован (проверь wp_head/wp_enqueue_scripts).'); const d = $.Deferred(); d.reject({ localError: 'HULI_AJAX_MISSING' }); return d.promise(); } qty = parseInt(qty, 10); if (isNaN(qty) || qty < 0) qty = 0; return $.post(HULI_AJAX.url, { action: 'huli_cart_set_qty', nonce: HULI_AJAX.nonce, key: itemKey, qty: qty }); } // «Далі» в футере — обычный переход function setFooterNext(onNext) { const $next = $('#productModalNext'); $next.text('Далі').off('click').on('click', onNext).show(); $('#productModalLink').hide(); } // «Далі» как «Нічого не бажаю» (скип на шагах выбора) function setFooterNextAsNone(onNone, label) { const $next = $('#productModalNext'); $next.text(label || 'Далі').off('click').on('click', onNone).show(); $('#productModalLink').hide(); } // Полностью спрятать футерные кнопки function hideFooterAll() { $('#productModalNext').hide().off('click').text('Далі'); $('#productModalLink').hide(); } // Кнопка «Детальніше» в ТЕЛЕ шага (стили как у «Далі») function makeInlineDetailsBtn(href, label) { const $btn = $(` ${label || 'Детальніше'} `); $btn.attr('href', href || '#'); return $btn; } function formatStoreAmount(amountStr, meta = {}, opts = {}) { if (amountStr == null) return ''; const minor = parseInt(amountStr, 10); if (isNaN(minor)) return ''; const mu = Number(meta.currency_minor_unit ?? 2); // 2 для UAH const decSep = meta.currency_decimal_separator ?? ','; // из API const thouSep = meta.currency_thousand_separator ?? ' '; // из API const prefix = meta.currency_prefix ?? ''; // обычно пусто const suffix = meta.currency_suffix ?? (meta.currency_symbol ? ` ${meta.currency_symbol}` : ''); // " ₴" const fixed = (minor / Math.pow(10, mu)).toFixed(mu); // "55.00" let [intPart, decPart] = fixed.split('.'); // тысячные разряды intPart = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, thouSep); // заменить точку на локальный разделитель let number = mu > 0 ? intPart + (decPart ? decSep + decPart : '') : intPart; // если хочешь скрывать .00 — поставь opts.stripZeros = true if (opts.stripZeros && decPart && /^0+$/.test(decPart)) { number = intPart; } return `${prefix}${number}${suffix}`; } /* ========================= * Рендеры шагов * ========================= */ // Render and collect functions function renderQuantityStep($body, resp, answersObj) { // Определяем, какие метаданные использовать const meta = resp?.selectedMeta || productMeta; const title = meta.name || resp?.product_name || ''; const description = meta.shortDesc || resp?.product_short_description || ''; const price = meta.price ? `
${meta.price} ₴
` : (resp?.product_price ? `
${resp.product_price} ₴
` : ''); // Шапка с картинкой и описанием const headerHtml = `
${meta.image ? `
${escapeHtml(title)}
` : ``}
${title ? `

${escapeHtml(title)}

` : ``} ${description ? `
${description}
` : ``} ${price}
`; // Поле количества const qtyHtml = `
`; // Собираем контент $body.html(headerHtml + qtyHtml); // Кнопки и управление const $ctrl = $('
'); if (resp.hidden_attributes && resp.hidden_attributes.length > 0) { $ctrl.append(` `); $ctrl.find('#qty-change-ingredients').on('click', () => { // Для основного товара if (!resp.selectedMeta) { answers.skipIngredients = false; } else { // Для подтовара answers.otherSkipIngredients = false; } nextStep(); }); } // Кнопка «Детальніше» $ctrl.append(makeInlineDetailsBtn(meta.link || productMeta.link)); $body.append($ctrl); // Кнопка «Далі» в футере setFooterNext(() => { if (!resp.selectedMeta) { // Основной товар answers.skipIngredients = true; } else { // Подтовар answers.otherSkipIngredients = true; } nextStep(); }); } function renderIngredientsChoice($body, resp) { let addHtml = '', removeHtml = ''; (resp.hidden_attributes || []).forEach(attr => { const tpl = `
  • `; if (attr.value === '+') addHtml += tpl; else removeHtml += tpl; }); $body.html(`

    Додати інгредієнти:

      ${addHtml}

    Видалити інгредієнти:

      ${removeHtml}
    `); // «Детальніше» в теле шага $('#ingr-inline-controls').append(makeInlineDetailsBtn(productMeta.link)); // «Далі» — в футере setFooterNext(() => { const data = collectIngredients(); nextStep(data); }); } function fetchCategoryMeta(catId) { return $.get(`/wp-json/custom/v1/products/${catId}`) .then(data => { const name = data.category_name || `Категорія ${catId}`; const image = (data.category_image && data.category_image.trim()) ? data.category_image : (data.products && data.products.length ? data.products[0].image : null); return { id: catId, name, image }; }) .catch(() => ({ id: catId, name: `Категорія ${catId}`, image: null })); } function renderDrinkCategoryChoice($body /*, resp, answers */) { const catIds = [26]; $body.html(`
    Завантажуємо категорії…
    `); Promise.all(catIds.map(fetchCategoryMeta)).then(list => { let html = `

    Оберіть категорію напоїв:

    `; html += list.map(o => `
    ${o.image ? `${o.name}` : `
    (без зображення)
    `}

    ${o.name}

    `).join(''); html += `
    Далі
    `; $body.html(html); $body.find('.drink-cat').on('click', e => nextStep($(e.currentTarget).data('id'))); $body.find('#drink-none').on('click', () => nextStep('none')); // ФУТЕР: «Далі» = «Нічого не бажаю» setFooterNextAsNone(() => nextStep('none'), 'Далі'); }); } function renderOtherCategoriesChoice($body, resp) { let html = '

    Що бажаєте додати?

    '; (resp.custom_fields?.other_categories_array || []).forEach(cat => { html += `
    ${cat.image ? `` : ''}

    ${cat.name}

    `; }); html += `

    Далі

    `; $body.html(html); $body.find('.other-category').on('click', e => nextStep($(e.currentTarget).data('id'))); $body.find('#other-none').on('click', () => nextStep(null)); // ФУТЕР: «Далі» = «Нічого не бажаю» setFooterNextAsNone(() => nextStep(null), 'Далі'); } function renderOtherProductStep($body) { renderProductList( () => `/wp-json/custom/v1/products/${answers.otherCategory}`, 'Оберіть товар:', $body ); // setFooterNextAsNone будет подключен внутри renderProductList } function renderProductListWithNone(urlFn, title, $body, noneLabel = 'Далі') { return renderProductList(urlFn, title, $body, noneLabel); } function renderProductList(urlFn, title, $body, noneLabel = 'Далі') { $.get(urlFn(), data => { let html = `

    ${title}

    `; (data.products || []).forEach((p) => { html += `
    ${p.name}

    ${p.name}

    ${p.price} ₴

    `; }); html += `

    ${noneLabel}

    `; $body.html(html); $body.find('.product-item').on('click', e => { const id = $(e.currentTarget).data('id'); nextStep(id); }); // ФУТЕР: «Далі» = «Нічого не бажаю» (скип) setFooterNextAsNone(() => nextStep('none'), noneLabel); }); } /* ========================= * Сбор данных * ========================= */ function collectQuantity() { answers.quantity = parseInt($('#step-quantity').val(), 10) || 1; return answers.quantity; } function collectIngredients() { const added = [], removed = []; $('.add-ingredient:checked').each((_, el) => added.push(el.value)); $('.remove-ingredient:checked').each((_, el) => removed.push(el.value)); answers.ingredients = { added, removed }; return answers.ingredients; } function collectOtherCategory() { return answers.otherCategory; // заполнится через processNext(prev.name)=answer } function collectProductSelection(id) { return (id === 'none' || id == null) ? null : id; } function collectDrinkCategory(selected) { answers.drinkCategory = selected; // 26 | 'none' return answers.drinkCategory; } /* ========================= * Финализация и корзина * ========================= */ function renderCartSummary() { hideFooterAll(); const $body = $('#productModalBody'); $body.html(`
    Оновлюємо кошик…
    `); $.get('/wp-json/wc/store/cart', data => { const items = (data && data.items) || []; let list = ''; items.forEach(it => { const img = (it.images && it.images[0] && it.images[0].src) || ''; const name = it.name || 'Товар'; const qty = it.quantity || 1; const line = formatStoreAmount(it.totals?.line_total, it.totals, { stripZeros: true }); const key = it.key; // ключ позиции в корзине (нужен для апдейта) list += `
    ${img ? `${name}` : ''}
    ${name}
    ${line}
    `; }); const totalsHtml = data?.totals?.total_price ? `
    Разом: ${formatStoreAmount(data.totals.total_price, data.totals, { stripZeros: true })}
    ` : ''; $body.html(`

    Ваше замовлення

    ${list || '
    Кошик порожній.
    '}
    ${totalsHtml}
    Оформити замовлення
    `); $('#modal-continue-shopping').on('click', () => $('#productModal').modal('hide')); // Делегирование событий для qty const applyChange = debounce(($row, newQty) => { const key = $row.data('key'); const $inputs = $row.find('.qty-input, .qty-minus, .qty-plus').prop('disabled', true); updateCartItemQty(key, newQty) .always(() => $inputs.prop('disabled', false)) .done(() => renderCartSummary()) .fail(() => renderCartSummary()); }, 300); $body.off('click.qtyMinus').on('click.qtyMinus', '.qty-minus', function(){ const $row = $(this).closest('.mini-cart-row'); const $in = $row.find('.qty-input'); const next = Math.max(0, (parseInt($in.val(),10)||0) - 1); $in.val(next); applyChange($row, next); }); $body.off('click.qtyPlus').on('click.qtyPlus', '.qty-plus', function(){ const $row = $(this).closest('.mini-cart-row'); const $in = $row.find('.qty-input'); const next = (parseInt($in.val(),10)||0) + 1; $in.val(next); applyChange($row, next); }); $body.off('input.qtyInput change.qtyInput').on('input.qtyInput change.qtyInput', '.qty-input', function(){ const $row = $(this).closest('.mini-cart-row'); const val = parseInt(this.value, 10); if (!Number.isNaN(val) && val >= 0) applyChange($row, val); }); }).fail(() => { $body.html(`
    Не вдалося завантажити кошик.
    Кошик
    `); $('#modal-continue-shopping').on('click', () => $('#productModal').modal('hide')); }); } function finalizeAddToCart() { hideFooterAll(); const mainData = { product_id: productId, quantity: answers.quantity || 1 }; if (answers.ingredients) { mainData.ingredients_added = answers.ingredients.added || []; mainData.ingredients_removed = answers.ingredients.removed || []; mainData.comment = `Додано інгредієнти: ${(answers.ingredients.added||[]).join(', ')}; Видалено інгредієнти: ${(answers.ingredients.removed||[]).join(', ')}`; } $.post('/?wc-ajax=add_to_cart', mainData) .done(() => { let seq = $.Deferred().resolve(); ['sauceList','drinkList','dessertList'].forEach(key => { if (answers[key]) { seq = seq.then(() => $.post('/?wc-ajax=add_to_cart', { product_id: answers[key], quantity: 1 })); } }); seq.always(() => renderCartSummary()); }) .fail(() => renderCartSummary()); } /* ========================= * Навигация по шагам * ========================= */ function processNext(answer) { if (answer !== undefined) { const prev = stepConfig[currentStep-1]; answers[prev.name] = answer; } while (currentStep = stepConfig.length) return finalizeAddToCart(); const step = stepConfig[currentStep++]; step.render($('#productModalBody'), latestResponse, answers); } function nextStep(arg) { processNext(arg); } function resetProductModal() { $('#productModalBody').empty(); } /* ========================= * Точка входа * ========================= */ $(document).on('click', '#product_listing .item', function(e) { e.preventDefault(); resetProductModal(); productId = $(this).find('[data-product_id]').data('product_id'); // Из карточки товара тянем метаданные const $it = $(this); const $img = $it.find('img').first(); const imgSrc = $img.attr('src') || $img.attr('data-src') || $img.attr('data-lazy') || (($img.attr('srcset') || '').split(',')[0] || '').trim().split(' ')[0]; productMeta = { name: ($it.find('.title, .product-title').first().text() || $it.data('name') || '').trim(), image: imgSrc || $it.data('image') || '', link: $it.find('a').first().attr('href') || '#' }; if (productMeta.name) $('#productModalTitle').text(productMeta.name); $('#productModalLink').attr('href', productMeta.link); $.get(`/wp-json/custom/v1/product-category/${productId}`, resp => { latestResponse = resp; currentStep = 0; Object.keys(answers).forEach(k => delete answers[k]); processNext(); }); $('#productModal').modal('show'); }); })(jQuery);
    x