//zewnętrzna funkcja do formatowania cen function _formatPrice(obj) { return format_price(obj.price, { mask: app_shop.vars.currency_format, currency: obj.currency, //.replace(/\s+/g, ''), currency_space: app_shop.vars.currency_space, currency_before_price: app_shop.vars.currency_before_value }) } function projectorEndStartCallback() { //powiadomienie o dostepnosci zmiana roziaru $("#avability_product_size strong").text(projectorObj.currentSizeObj.description); //przypisanie raty cena_raty = projectorObj.currentSizeObj.price.value * projectorObj.configObj.valueOfNumberInput; if (client_login) { $('').attr('title', txt_toltip_2a.replace('[xxx]', client_points)).appendTo('#projector_price_points'); } else { $('').attr('title', txt_toltip_2).appendTo('#projector_price_points'); } $('').attr('title', txt_toltip_3).appendTo('#projector_points_recive_points'); if (projectorObj.txt['size_select_functionality'] && projectorObj.txt['size_select_functionality'] != '0') { app_shop.fn.fashionAvailability(); } app_shop.fn.tommorowAvailability(); if (product_data.sizes && (product_data.sizes.uniw || product_data.sizes.onesize)) { $('#projector_sizes_cont').hide(); } if (projectorObj.currentSizeObj.phone_price != 'true' && projectorObj.currentSizeObj.bundle_price && projectorObj.currentSizeObj.bundle_price.amount_diff_gross > 0) { $('#projector_price_yousave_bundle').show().html('' + projectorObj.txt['oszczedzasz'] + '' + projectorObj.currentSizeObj.bundle_price.percent_diff + '' + projectorObj.txt['taniej']); } else if (projectorObj.currentSizeObj.phone_price != 'true' && yousaveTmp) { $('#projector_price_yousave').show().html('' + projectorObj.txt['oszczedzasz'] + '' + yousave_percentTmp + '' + projectorObj.txt['taniej']); } else { $('#projector_price_yousave').hide(); $('#projector_price_yousave_bundle').hide(); } if (projectorObj.currentSizeObj.product_type === "product_bundle") { if (projectorObj.currentSizeObj.availability.status == 'disable') { $('#projector_tell_availability').find('input').attr('disabled', false); $('body').removeClass('alertek-disabled'); $.getJSON('/ajax/projector.php?action=get_product_observed', { 'product': $('#projector_product_hidden').val(), 'size': $('#projector_size_hidden').val(), 'email': $('#projector_tell_availability [name="email"]').val() }, function (data) { if (data.status == 'error') { message = txt_62619_blad_pobrania; Alertek.show_alert(message); return false; } if (!data.sms_active) { $('#sms_active_checkbox,#sms_active_group').remove(); } if (data.client && data.client.phone) { $('#sms_active_checkbox input').prop('checked', true); $('#sms_active_checkbox,#sms_active_group').show() $('#sms_active_group [name="phone"]').val(data.client.phone); } }) } else { $('#projector_tell_availability').find('input').attr('disabled', true); $('body').addClass('alertek-disabled'); } } // Aktualizacja rabatu ilościowego const {price} = projectorObj.currentSizeObj; if (typeof price !== 'undefined' && $('#projector_rebateNumber').length) { const {rebateNumber} = price; if ($('.rebate_number__item').length > 1) { $('.rebate_number__item').each(function(index) { $(this).find('.rebate_number__price').text(rebateNumber.items[index].price_formatted) }); } else { $('.rebate_number__price').text(rebateNumber.nextprice_formatted); } } const {amount} = projectorObj.currentSizeObj; $('.projector_delivery_info_container, #projector_status_description_wrapper, #projector_status_description_wrapper_shipping').removeClass('hidden'); if(typeof(amount) != "undefined" && amount < 4 && amount != -1){ $('#projector_status_description_wrapper, #projector_product_status_wrapper, #projector_status_description_wrapper_shipping').addClass('--less'); switch (amount){ case 0: $('.projector_delivery_info_container').addClass('hidden'); $('#projector_status_description_wrapper_shipping').addClass('hidden'); break; case 1: $('#projector_status_description').html(projectorObj.txt['zostala'] + " " + "" + projectorObj.txt['sztuka1'] + " " + "" + projectorObj.txt['wRozmiarze']).addClass('only_one'); break; case 2: $('#projector_status_description').html(projectorObj.txt['zostaly'] + " " + "" + projectorObj.txt['sztuka2'] + "" + " " + projectorObj.txt['wRozmiarze']).addClass('only_one'); break; case 3: $('#projector_status_description').html(projectorObj.txt['zostaly'] + " " + "" + projectorObj.txt['sztuka2'] + "" + " " + projectorObj.txt['wRozmiarze']).addClass('only_one'); break; } }else{ $('#projector_status_description_wrapper, #projector_product_status_wrapper, #projector_status_description_wrapper_shipping').removeClass('--less'); } if(projectorObj.currentSizeObj.type == "uniw"){ $('#projector_status_description_wrapper').addClass('hidden'); } } function projectorEndInitFunctionCallback() { app_shop.fn.init_multi_vers(); //inicializacja toltipow simple_tooltip("span.show_tip", "n59581_tooltip"); if (product_data.base_price && product_data.base_price.promotiontilldate) { $('#projector_prices_wrapper').after('
'); app_shop.vars.countDown = new CountdownTimer($('#CDT'), new Date(product_data.base_price.promotiontilldate + 'T23:59:59+01:00')); app_shop.vars.countDown.countDown(); } const selectedSizeFromURL = [...document.querySelectorAll('.select_button')].some(el=> el.className.includes('active')); if($('#projector_sizes_cont .select_button').length>1 && !selectedSizeFromURL){ $('#projector_sizes_cont .select_button').first().click(); } } var pr_goToOpinion = function () { $('#opinions_58676').click(); $('html,body').animate({ scrollTop: $('#component_projector_opinions').offset().top - 120 }, 'fast'); } app_shop.run(function () { var versionSub = $('#projector_form div.product_section.versions div.product_section_sub'); versionSub.find('.select_button').length > 8 ? versionSub.addClass('versions_scroll') : versionSub.removeClass('versions_scroll'); }, 1, '#projector_form', true); $(document).on('click', '.mobile_toggle .mobile_text', function(e){ e.preventDefault(); $(this).parent().toggleClass('active'); }) $(document).on('click', '.question_section .mobile_text', function(){ $('.askforproduct').dialog({ wrappContent: true, }); return false; }); $(document).on('click', '.opinion_section .btn', function(){ $('.opinions_add_form').dialog({ wrappContent: true, }); return false; }); var projectorv3_disable_ajax = "1"; projectorObj = new projectorClass(); projectorObj.txt['sztuka1'] = "Została już tylko 1 sztuka w tym rozmiarze!" projectorObj.txt['sztuka2'] = "Zostały już tylko 2 sztuki w tym rozmiarze!" projectorObj.txt['sztuka3'] = "Zostały już tylko 3 sztuki w tym rozmiarze!" projectorObj.txt['zostala'] = projectorObj.txt['zostaly'] = projectorObj.txt['sztuka1'] = projectorObj.txt['sztuka2'] = projectorObj.txt['sztuka3'] = projectorObj.txt['wRozmiarze'] = projectorObj.txt['additional_texts'] = "" projectorObj.txt['za'] = " " + + " " projectorObj.txt['taniej'] = "% od pierwszej ceny" projectorObj.txt['oszczedzasz'] = + " " projectorObj.txt['wzestawie'] = "), " + + ". " projectorObj.txt['niedostepny'] = projectorObj.txt['tylkotel'] = + "." projectorObj.txt['tylko_punkty'] = + "." projectorObj.txt['za_malo_punktow'] = projectorObj.txt['gratis'] = projectorObj.txt['niemastanu'] = projectorObj.txt['status_24'] = projectorObj.txt['status_natychmiast'] = projectorObj.txt['day'] = " " + + " " projectorObj.txt['days'] = " " + + " " projectorObj.txt['hour'] = " " + + "." projectorObj.txt['hours'] = " " + + ". " projectorObj.txt['min'] = " min " projectorObj.txt['mins'] = " min. " projectorObj.txt['proc'] = "%" projectorObj.txt['wybrany_rozmiar'] = + ":" projectorObj.txt['wysylka'] = "" projectorObj.txt['wysylka_za'] = + " " projectorObj.txt['dostepny'] = "" projectorObj.txt['dostepny_za'] = + " " projectorObj.txt['pkt'] = " " + + "." projectorObj.txt['status_amount_full'] = projectorObj.txt['status_amount_null'] = projectorObj.txt['forpointsonly'] = + "." projectorObj.txt['disable_desc'] = + "." projectorObj.txt['choiceSize'] = projectorObj.txt['maksymalnie'] = projectorObj.txt['minimalnie'] = + " " projectorObj.txt['brak_magazyn'] = projectorObj.txt['koszt_od'] = + " " projectorObj.txt['wysylka_total_begin'] = "
(" + + " " projectorObj.txt['wysylka_total_end'] = ")" projectorObj.txt['nawias_end'] = "). " projectorObj.txt['gratis_produkt'] = projectorObj.txt['virtual_inbasket'] = projectorObj.txt['infinity'] = "" projectorObj.txt['ilosc_mm'] = "" + + " " + "%" + + "." projectorObj.txt['ilosc_mo'] = "" + + " " + "%" + + " " + + "." projectorObj.txt['ilosc_mo_inf'] = + "." projectorObj.txt['size_select_functionality'] = "0" projectorObj.txt['sizes_projector_functionality'] = "1" projectorObj.txt['size_select_label'] = projectorObj.txt['size_select_tell_availability'] = projectorObj.txt['size_select_last_unit'] = projectorObj.txt['size_select_few_last_units'] = var Projector_txt_maksymalnie = + ": " var Projector_txt_minimalnie = projectorObj.txt['minimalnie']; var Projector_txt_brak_magazyn = var Projector_txt_produkt_niedostepny = var Projector_txt_podajilosc = var Projector_txt_zalogujsie = var Projector_txt_closedialog = "" var txt_raty_button1 = var txt_raty_button2 = + " " var txt_62619_cms_table = var txt_toltip_1 = + "." var txt_toltip_2 = + "." var txt_toltip_2a = + "." var txt_toltip_3 = + "." var txt_toltip_4 = "" var prepaid = var dvp = var day_txt = " " + + " " var days_txt = " " + + " " var hour_txt = " " + + ". " var hours_txt = " " + + ". " var min_txt = " min." var txt_24h = var txt_do_24h = var delivery_txt = + " " var delivery_txt2 = + " " var delivery_txt3 = + " " var gratis_txt = app_shop.txt.txt_74629_1 = + ": " app_shop.txt.txt_74629_2 = + "." app_shop.txt.txt_74629_3 = app_shop.txt.txt_74629_4 = + " " app_shop.txt.txt_74629_5 = + " " app_shop.txt.txt_74629_6 = + " " app_shop.txt.txt_74629_7 = + "." var txt_shipping_8 = var txt_shipping_9 = + " " var txt_shipping_10 = + " " var txt_shipping_11 = + " " var txt_shipping_12 = + " " var txt_shipping_13 = + " " var txt_shipping_14 = + " " var txt_shipping_15 = + " " var txt_shipping_16 = app_shop.txt.txt_74629_8 = projectorObj.options['friendly_shipping_format'] = [txt_shipping_8, txt_shipping_9, txt_shipping_10, txt_shipping_11, txt_shipping_12, txt_shipping_13, txt_shipping_14, txt_shipping_15]; app_shop.txt.txt_74629_9 = ; app_shop.txt.txt_74629_10 = ; app_shop.txt.txt_74629_11 = ; app_shop.txt.txt_74629_12 = ; app_shop.txt.txt_74629_13 = ""; app_shop.txt.txt_74629_14 = ; app_shop.txt.txt_74629_15 = ; app_shop.txt.txt_74629_16 = + " "; app_shop.txt.txt_74629_17 = + " "; app_shop.txt.txt_74629_18 = ; app_shop.txt.txt_74629_19 = + " "; app_shop.txt.txt_74629_16467 = ; var txt_62619_nieprawidlowy_email = + "." var txt_62619_przekroczono_liczbe = + "." var txt_62619_podczas_dodawania = var txt_62619_produkt_dodany = + "." var txt_62619_blad_pobrania = + "." var txt_62619_bledny_email = + " " var txt_62619_wpisz_telefon = + ". " var fashionGallery_new = ""; // Countdown timer function CountdownTimer(elm, tl) { this.initialize.apply(this, arguments); } CountdownTimer.prototype = { initialize: function (elm, tl) { this.elem = elm; this.tl = tl; this.tid = ''; }, newData: function (tl) { this.tl = tl; }, countDown: function () { var timer = ''; var today = new Date(); var day = Math.floor((this.tl - today) / (24 * 60 * 60 * 1000)); var hour = Math.floor(((this.tl - today) % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000)); var min = Math.floor(((this.tl - today) % (24 * 60 * 60 * 1000)) / (60 * 1000)) % 60; var sec = Math.floor(((this.tl - today) % (24 * 60 * 60 * 1000)) / 1000) % 60 % 60; var me = this; if ((this.tl - today) > 0) { timer += '
'; if (this.addZero(day) > 0) timer += '
' + app_shop.txt.txt_74629_3 + '
' + this.addZero(day) + '
'; timer += '
' + app_shop.txt.txt_74629_4 + '
' + this.addZero(hour) + '
'; timer += '
' + app_shop.txt.txt_74629_5 + '
' + this.addZero(min) + '
' + app_shop.txt.txt_74629_6 + '
' + this.addZero(sec) + '
'; this.elem.html(timer); this.tid = setTimeout(function () { me.countDown(); }, 1000); } else { clearTimeout(this.tid); this.elem.remove(); return; } }, addZero: function (num) { return ('0' + num).slice(-2); } } class StationaryPanel { constructor() { this.panel = document.querySelector('.stationary__panel'); this.overlay = document.querySelector('.stationary__panel_overlay'); this.search = this.panel.querySelector('.stationary__panel_input'); this.searchWrapper = this.panel.querySelector('.stationary__panel_search'); this.body = document.querySelector('body'); this.template = document.querySelector('#stationary__panel_item_template'); this.geocoder = null; // Placeholder for geocoder if needed later this.clientLocation = null; this.clientCoords = null; this.apiKey = 'gykxSsgNvghUsI0VSMXgPTZ00C2UQYN1KE3yJMrFGCrtUd2jXuFMfhnqzlDnsvzSlNCQBae08Vku0qDKC61HLGYRlaxvqm6V6IMyfv6dZxzlW2HIPA8i7XlcLj9Hkdtr'; this.navigatorGeolocationUsed = false; this.nearMeLiteral = 'Blisko mnie'; this.pickupPointsData = []; this.productSizes = null; this.searchRadius = 100; this.lastSearchValue = null; this.fakeDataSizeS = [ { 'warehouse': 'ANDRESPOL', "city": "Andrespol", "street": "Rokicińska 130", "postalCode": "95-020", 'quantity': 1, }, { "warehouse": "BRZEZINY", "city": "Brzeziny", "street": "Stefana Okrzei 14", "postalCode": "95-060", "quantity": 1 }, { "warehouse": "GŁOWNO", "city": "Głowno", "street": "Sikoorskiego 59 C", "postalCode": "95-015", "quantity": 1 } ]; this.fakeDataSizeM = [ { "warehouse": "ANDRESPOL", "city": "Andrespol", "street": "Rokicińska 130", "postalCode": "95-020", "quantity": 1 }, { "warehouse": "BOLESŁAWIE", "city": "Bolesławiec", "street": "Asnyka 6/10", "postalCode": "59-700", "quantity": 1 }, { "warehouse": "BRZEZINY", "city": "Brzeziny", "street": "Stefana Okrzei 14", "postalCode": "95-060", "quantity": 1 }, { "warehouse": "BYDGOSZCZ2", "city": "Bydgoszcz", "street": "Fordońska 141 lok. 26", "postalCode": "85-739", "quantity": 1 }, { "warehouse": "CHOJNICE", "city": "Chojnice", "street": "Kościuszki 7", "postalCode": "89-600", "quantity": 1 }, { "warehouse": "CHOJNICE2", "city": "Chojnice", "street": "Reymonta 10", "postalCode": "89-600", "quantity": 1 }, { "warehouse": "GŁOWNO", "city": "Głowno", "street": "Sikorskiego 59 C", "postalCode": "95-015", "quantity": 1 }, { "warehouse": "JAWOR", "city": "Jawor", "street": "Rynek 27", "postalCode": "59-400", "quantity": 1 }, { "warehouse": "KOZIENICE", "city": "Kozienice", "street": "Batalionów Chłopskich 18", "postalCode": "26-900", "quantity": 1 }, { "warehouse": "KUTNO1", "city": "Kutno", "street": "Królewska31", "postalCode": "99-300", "quantity": 1 }, { "warehouse": "LWÓWEK ŚL", "city": "Lwówek Śląski", "street": "Orzeszkowej 45", "postalCode": "59-600", "quantity": 1 }, { "warehouse": "ŁASK1", "city": "Łask", "street": "Kościelna 5", "postalCode": "98-100", "quantity": 1 }, { "warehouse": "ŁÓDŹ2", "city": "Łódź", "street": "Piłsudskiego 94", "postalCode": "92-202", "quantity": 1 }, { "warehouse": "PIEKARY", "city": "Piekary Śląskie", "street": "1-go Maja 35", "postalCode": "41-940", "quantity": 1 }, { "warehouse": "PIŁA2", "city": "Piła", "street": "1 Maja 5", "postalCode": "64-920", "quantity": 1 }, { "warehouse": "RAWA MAZ2", "city": "Rawa Mazowiecka", "street": "Konstytucji 3-go Maja 2", "postalCode": "96-200", "quantity": 1 }, { "warehouse": "RAWICZ1", "city": "Rawicz", "street": "17 styczeń 9/11", "postalCode": "63-900", "quantity": 1 }, { "warehouse": "SKIERNIE 1", "city": "Skierniewice", "street": "Senatorska 3", "postalCode": "96-100", "quantity": 1 }, { "warehouse": "TARNOBRZEG", "city": "Tarnobrzeg", "street": "Sienkiewicza 3", "postalCode": "39-400", "quantity": 1 }, { "warehouse": "TRZCIANKA", "city": "Trzcianka", "street": "ul. Oś. XXV-lecia 14", "postalCode": "64-980", "quantity": 1 }, { "warehouse": "WIELUŃ1", "city": "Wieluń", "street": "Warszawska 13", "postalCode": "98-300", "quantity": 1 }, { "warehouse": "WYRZYSK", "city": "Wyrzysk", "street": "UL. Staszica 5", "postalCode": "89-300", "quantity": 1 }, { "warehouse": "ZŁOTORYJA", "city": "Złotoryja", "street": "Rynek 8", "postalCode": "59-500", "quantity": 1 }, { "warehouse": "ŻYRARDÓW1", "city": "Żyrardów", "street": "Mały Rynek 7/11", "postalCode": "96-300", "quantity": 1 } ] } // calculate distance between 2 points haversineDistance(mk1, mk2) { const R = 6371.0710; // Radius of the Earth in kilometers const rlat1 = mk1.lat.toFixed(5) * (Math.PI/180); // Convert degrees to radians const rlat2 = mk2.lat.toFixed(5) * (Math.PI/180); // Convert degrees to radians const difflat = rlat2-rlat1; // Radian difference (latitudes) const difflon = (mk2.lng.toFixed(5) - mk1.lng.toFixed(5)) * (Math.PI/180); // Radian difference (longitudes) const d = 2 * R * Math.asin(Math.sqrt(Math.sin(difflat/2)*Math.sin(difflat/2)+Math.cos(rlat1)*Math.cos(rlat2)*Math.sin(difflon/2)*Math.sin(difflon/2))); return d; } async initGeocoder() { const { Geocoder } = await google.maps.importLibrary("geocoding"); this.geocoder = new google.maps.Geocoder(); } showPanel() { this.panel.classList.add('--open'); this.overlay.style.display = 'block'; this.body.classList.add('--no-scroll'); } closePanel() { this.panel.classList.remove('--open'); this.overlay.style.display = 'none'; this.body.classList.remove('--no-scroll'); } updatePanelMessage(messageType = 'emptyLocation') { const distanceMsgElement = document.querySelector('.stationary__panel_list_message_item[data-message-type="distance"]'); const notAvailableMsgElement = document.querySelector('.stationary__panel_list_message_item[data-message-type="notAvailable"]'); const emptyLocationMsgElement = document.querySelector('.stationary__panel_list_message_item[data-message-type="emptyLocation"]'); const noStoresMsgElement = document.querySelector('.stationary__panel_list_message_item[data-message-type="noStores"]'); // const msgWrapper = document.querySelector('.stationary__panel_list_message'); distanceMsgElement.textContent = distanceMsgElement.textContent.replace('%d', this.searchRadius); if (messageType) this.panel.dataset.messageType = messageType; else delete this.panel.dataset.messageType; } searchInputKeyupEvent() { const clearButton = this.panel.querySelector('.icon_wrapper.--close'); const value = this.search.value; this.navigatorGeolocationUsed = false; if (value.length > 0) { clearButton.style.display = 'block'; } else { clearButton.style.display = 'none'; } } clearSearchInput() { return this.search.value = ''; } async searchEvent(searchValue = this.search.value.trim()) { if (this.lastSearchValue !== null && this.lastSearchValue.trim() === this.search.value.trim()) return false; this.searchWrapper.classList.add('--loading'); this.lastSearchValue = this.search.value.trim(); // await this.localizeAddress(this.search.value.trim()); await this.localizeAddress(searchValue); await this.getPickupPointsData(); this.getPickupPointsDistance(); this.appendData(); this.updatePickupPointsDisplay(); this.searchWrapper.classList.remove('--loading'); this.search.classList.remove('--focused'); } async searchInputSearchEvent() { const address = this.search.value; await this.localizeAddress(address); this.findNearPickupPoints(); } async findNearPickupPoints() { // } // wylicza dystans między pickupPoint, a adresem klienta getPickupPointsDistance() { this.pickupPointsData.forEach((pickupPoint) => { const idx = this.pickupPointsData.findIndex( d => d.warehouse === pickupPoint.warehouse ); const distance = this.haversineDistance(this.clientCoords, pickupPoint.coords); this.pickupPointsData[idx].distance = distance; }); } // fetchujemy dane i wrzucamy do zbiorczego arraya z danymi // dopisujemy size'y do obiektów // dopisujemy koordynaty do obiektów async getPickupPointsData() { if (this.pickupPointsData !== null && Array.isArray(this.pickupPointsData) && this.pickupPointsData.length > 0) return true; const sizes = this.productSizes; const allPromises = sizes.map(async (size) => { // tutaj będzie fetch, size podajemy jako jeden z parametrów // funkcja fetch to osobna funkcja // await response -> dla debuga używamy this.fakeDataSizeS i this.fakeDataSizeM const myHeaders = new Headers(); myHeaders.append("x-api-key", "gykxSsgNvghUsI0VSMXgPTZ00C2UQYN1KE3yJMrFGCrtUd2jXuFMfhnqzlDnsvzSlNCQBae08Vku0qDKC61HLGYRlaxvqm6V6IMyfv6dZxzlW2HIPA8i7XlcLj9Hkdtr"); const requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow', }; let response = null; const code = document.querySelector('.stationary__panel').dataset.code; // const currentSize = projectorObj.currentSizeObj.name; let url = `https://api2.moodo.pl:4547/api/salony/zasoby?kodTowaru=${code}; ${size}`; try { const res = await fetch(url, requestOptions); if (!res.ok) { // HTTP status not in the 200-299 range throw new Error(`HTTP error! status: ${res.status}`); } response = await res.json(); } catch (error) { // Handles both network errors and HTTP errors thrown above console.error('Error fetching data:', error); // Optionally rethrow or handle the error accordingly } // DEBUG // Response to jest strzał po jeden rozmiar, dopisujemy sizes do każdego obiektu // const response = size === 'S' ? this.fakeDataSizeS : this.fakeDataSizeM; const pickupPromises = response.map(async (pickupPoint) => { // dopisujemy size do obiektu z responsa pickupPoint.sizes = [size]; // dopisujemy koordynaty const pickupPointLocation = await this.getCoordinates(`${pickupPoint.postalCode} ${pickupPoint.city}, ${pickupPoint.street}`); pickupPoint.coords = {lat: pickupPointLocation.location.geometry.location.lat(), lng: pickupPointLocation.location.geometry.location.lng()} // dodajemy response do obiektu zbiorczego // Szukamy indeksu magazynu w data const idx = this.pickupPointsData.findIndex( d => d.warehouse === pickupPoint.warehouse ); if (idx !== -1) { // Jeśli magazyn istnieje, dopisujemy size if (this.pickupPointsData[idx].sizes) this.pickupPointsData[idx].sizes.push(size); else this.pickupPointsData[idx].sizes = [size]; } else { // Jeśli nie istnieje, dodajemy cały obiekt z responsa this.pickupPointsData.push(pickupPoint); } }); // Poczekaj na wszystkie promisy dla danego rozmiaru await Promise.all(pickupPromises); }); // Poczekaj na wykonanie wszystkich rozmiarów await Promise.all(allPromises); } async localizeAddress(address) { // bez sensu jest ten IF, trza go wyjebać if (this.navigatorGeolocationUsed !== true || this.clientCoords === null) { // tutaj wyszukujemy coords klienta const clientLocation = await this.getCoordinates(address); this.clientLocation = clientLocation; this.clientCoords = {lat: clientLocation.location.geometry.location.lat(), lng: clientLocation.location.geometry.location.lng()} return clientLocation } } async localizeMe() { const errorMsg = { 1: 'Dostęp do lokalizacji został zablokowany na tym urządzeniu.', 2: 'Nie można określić lokalizacji.', } if (navigator.geolocation) { return new Promise((resolve) => { navigator.geolocation.getCurrentPosition( (position) => { resolve(position); }, (error) => { resolve(errorMsg[error.code] || errorMsg[2]); } ); }); } else { return errorMsg[2]; } } async getCoordinates(address) { if (!address) return false; const isLatLng = /^-?\d+(?:\.\d+)?\s*,\s*-?\d+(?:\.\d+)?$/.test(address); const params = new URLSearchParams(); if (isLatLng) { const [lat, lng] = address.split(',').map(v => parseFloat(v.trim())); params.set('lat', lat); params.set('lng', lng); } else { params.set('q', address); } const t0 = (typeof performance !== 'undefined' && performance.now) ? performance.now() : Date.now(); let res, data; try { res = await fetch('https://serwer1852487.home.pl/Geo/?' + params.toString(), { method: 'GET', headers: { 'Accept': 'application/json' }, }); const t1 = (typeof performance !== 'undefined' && performance.now) ? performance.now() : Date.now(); if (!res.ok) throw new Error('Geocode API failed: ' + res.status); data = await res.json(); if (!data || typeof data.lat !== 'number' || typeof data.lng !== 'number') { throw new Error('Invalid geocode response'); } // OK – adapter const src = data.source || (data.from_cache ? 'cache' : 'google'); const stale = data.stale ? ' (stale)' : ''; const ms = Math.round(t1 - t0); return { location: { geometry: { location: { lat: () => data.lat, lng: () => data.lng, } } }, formatted_address: data.formatted_address || '', place_id: data.place_id || '', from_cache: !!data.from_cache, source: src, stale: !!data.stale, }; } catch (err) { // === fragment logiki ze starego kodu === const list = this.panel?.querySelector('.stationary__panel_list ul'); if (list) list.innerHTML = ""; this.searchWrapper?.classList.remove("--loading"); this.updatePanelMessage("noStores"); this.search?.classList.remove("--focused"); // zwracamy „pusty adapter”, żeby reszta kodu się nie wywaliła return { location: { geometry: { location: { lat: () => null, lng: () => null, } } }, formatted_address: '', place_id: '', from_cache: false, source: 'error', stale: false, }; } } async attachEvents() { document.addEventListener('click', async (e) => { // button ZNAJDŹ W SALONIE if (e.target.closest('.projector_stationary__wrapper button')) { e.preventDefault(); this.showPanel(); this.updatePanelMessage(); return; } // button X if (e.target.closest('.stationary__panel_close')) { e.preventDefault(); this.closePanel(); return; } // klik poza panel if (this.panel.classList.contains('--open') && !e.target.closest('.stationary__panel')) { this.closePanel(); return; } // klik w X w wyszukiwarce if (e.target.closest('.icon_wrapper.--close')) { e.preventDefault(); this.clearSearchInput(); this.searchInputKeyupEvent(); return; } // focus na wrapper wyszukiwarki if (e.target.closest('.stationary__panel_search')) { this.search.classList.add('--focused'); } else { this.search.classList.remove('--focused'); } // klik w SZUKAJ BLISKO MNIE if (e.target.closest('.stationary__panel_search_localize:not(.--blocked)')) { const localizeMeResponse = await this.localizeMe(); // console.log('localizeMeResponse: ', localizeMeResponse) // DEBUG // console.log('app_shop.vars.test: ', app_shop.vars.test) // this.clientCoords = { // lat: app_shop.vars.test.lat, // lng: app_shop.vars.test.lng // } // this.search.value = this.nearMeLiteral; // await this.searchEvent(`${this.clientCoords.lat}, ${this.clientCoords.lng}`); // return; // DEBUG END if (typeof localizeMeResponse === 'string') { // error e.target.closest('.stationary__panel_search_localize').querySelector('span:not(.icon_wrapper)').textContent = localizeMeResponse; e.target.closest('.stationary__panel_search_localize').classList.add('--blocked'); } else { // success console.log('localizeMeResponse.coords: ', localizeMeResponse.coords) this.clientCoords = { lat: localizeMeResponse.coords.latitude, lng: localizeMeResponse.coords.longitude } this.search.value = this.nearMeLiteral; await this.searchEvent(`${this.clientCoords.lat}, ${this.clientCoords.lng}`); // this.search.dataset.lat = this.clientCoords.lat; // this.search.dataset.lon = this.clientCoords.lon; // this.navigatorGeolocationUsed = true; } } // searchButton if (e.target.closest('.stationary__panel_search_btn')) { return await this.searchEvent(); } }); this.search.addEventListener('keyup', async (e) => { if (e.key === 'Enter') { e.preventDefault(); return await this.searchEvent(); } return this.searchInputKeyupEvent(); }); } appendData(data = this.pickupPointsData) { const list = this.panel.querySelector('.stationary__panel_list ul'); list.innerHTML = ''; // Clear previous results if (!data || data.length === 0) { this.updatePanelMessage('notAvailable'); return false; } data.sort((a, b) => a.distance - b.distance).forEach(item => { const clone = this.template.content.cloneNode(true); const itemElement = clone.querySelector('.stationary__panel_item'); // itemElement.dataset.id = item.warehouse; itemElement.dataset.distance = item.distance.toFixed(1); itemElement.dataset.sizes = item.sizes.toString().replaceAll(',', ', '); const sizesOrder = ['XS', 'S', 'M', 'L', 'XL', 'XXL', 'XXXL', 'XXXXL'] itemElement.querySelector('.stationary__panel_item_name').textContent = `${item.city} - ${item.street}`; itemElement.querySelector('.stationary__panel_item_sizes').textContent = item.sizes.sort((a, b) => sizesOrder.indexOf(a) - sizesOrder.indexOf(b)).toString().replaceAll(',', ', '); itemElement.querySelector('.stationary__panel_item_distance').textContent = `${item.distance.toFixed(1)} KM`; list.appendChild(clone); }); } // pokazujemy tylko w radiusie updatePickupPointsDisplay() { const itemsList = this.panel.querySelectorAll('.stationary__panel_list .stationary__panel_item'); const itemsListLength = itemsList.length; let hiddenCounter = 0; itemsList.forEach((item) => { const distance = parseFloat(item.dataset.distance); if (distance > this.searchRadius) { item.classList.add('--hidden'); hiddenCounter++; } else { item.classList.remove('--hidden'); } }); if (hiddenCounter === itemsListLength) this.updatePanelMessage('distance'); else this.updatePanelMessage(null); return; } getProductSizes() { // debug // return this.productSizes = ['S', 'M']; return this.productSizes = this.panel.dataset.sizes.split(','); } async init() { this.getProductSizes(); this.attachEvents(); await this.initGeocoder(); } } app_shop.run(function () { app_shop.fn.stationaryPanel = new StationaryPanel(); app_shop.fn.stationaryPanel.init(); }, 'all', '.projector_stationary__wrapper');