PageSourceSearch

https://www.myavis.gr/themes/custom/avis2024/dist/js/configurator/configuratorSlider.16.1.js

js myavis.gr collected 2026-10-01 14:18:10 UTC 22,165 bytes, 553 lines download raw bytes

1import {get} from "../api/get.16.1.js";
2import {post} from "../api/post.16.1.js";
3import {getCars} from "../api/getCars.16.1.js";
4import {updateTextForDropDowns} from "../leasing-list/leasing-list.16.1.js";
5import {updateQueryStringOnFilter, getLangCode} from "../filters/filters.16.1.js";
6import {getBrandTileData} from "../utils/templates.16.1.js";
7import {makeActive, removeActive} from "../utils/utility.16.1.js";
8
9let brandList = [];
10let brandDetail = [];
11let brandModels = [];
12let markers = "";
13let markersDefault = "";
14let privateCars = [];
15
16//let carCont = $(".manufacturer-details");
17
18//const manufacturerSection = $("#manufacture-list-container");
19//const mobileManufacturerSection = $("#mobile-manufacture-list-container");
20//const configuratorListContainer = $("#configurator-list-container");
21
22(async function () {
23	brandList = await get("manufactures");
24	sessionStorage.setItem("manufacturerBrand", JSON.stringify(brandList));
25})();
26
27// Refactored RK
28export const configuratorBrands = async () => {
29	//Clear any preselected value onLoad of this page. OR we can improve it to read it from preselected vaue
30	// sessionStorage.removeItem("selectedCarBrand");
31	// sessionStorage.removeItem("selectedVehicleType");
32	//const brandListDefault = await get("manufactures");
33
34	// const brandListDefault = JSON.parse(sessionStorage.getItem("manufacturerBrand"));
35	// const selectedCarBrandLS = sessionStorage.getItem("selectedCarBrand");
36	// const carToSelect = brandListDefault.find((item) => item.brandName === JSON.parse(selectedCarBrandLS)?.carName);
37
38	try {
39		// Attempt to retrieve the brand list from sessionStorage
40		let brandListDefault = JSON.parse(sessionStorage.getItem("manufacturerBrand"));
41
42		// If not found in sessionStorage, fetch it from the server or source
43		if (!brandListDefault) {
44			brandListDefault = await get("manufactures"); // Assuming get() fetches the data
45			sessionStorage.setItem("manufacturerBrand", JSON.stringify(brandListDefault));
46		}
47
48		// Proceed only if brandListDefault is a valid array
49		if (!Array.isArray(brandListDefault) || brandListDefault.length === 0) {
50			console.error("Brand list is empty or not available.");
51			return;
52		}
53
54		const selectedCarBrandLS = sessionStorage.getItem("selectedCarBrand");
55		const carToSelect = brandListDefault.find((item) => item.brandName === JSON.parse(selectedCarBrandLS)?.carName);
56
57		const $selectedFilterSectionImg = $(".selected-filter-section img");
58		// console.log("Brand logo selection:" + selectedCarBrandLS);
59		let brandSelectedLS = selectedCarBrandLS ? JSON.parse(selectedCarBrandLS) : null;
60		if (carToSelect && brandSelectedLS && Object.keys(brandSelectedLS).length) {
61			$selectedFilterSectionImg.attr({
62				src: carToSelect?.src,
63				alt: carToSelect?.brandName,
64				"data-tid": carToSelect?.id,
65				"data-order": carToSelect?.order,
66			});
67		} else {
68			$selectedFilterSectionImg.attr({
69				src: brandListDefault[0]["src"],
70				alt: brandListDefault[0]["brandName"],
71				"data-tid": brandListDefault[0]["id"],
72				"data-order": brandListDefault[0]["order"],
73			});
74		}
75	}catch (error) {
76		console.error("An error occurred while configuring brands:", error);
77	}
78};
79
80// car filteration based on vehicle Type RK
81export const getCarsByType = (carTypes) => {
82	return brandList.filter((el) => {
83		return carTypes.some((f) => {
84			return f?.name?.toLowerCase() === el?.brandName?.toLowerCase();
85		});
86	});
87};
88
89// replace the whole configuratorSlider function with this
90export const configuratorSlider = async () => {
91  const $configuratorTitle = $("#configurator-slider-container .configurator-title");
92  const $container = $("#configurator-slider-container");
93
94  // vehicle type (private/commercial)
95  const optionType =
96    sessionStorage.getItem("selectedVehicleType") ||
97    $('input[name="inlineRadioOptions"]:checked').val() ||
98    "private";
99
100  const selectedCarBrandLS = JSON.parse(sessionStorage.getItem("selectedCarBrand"));
101
102  // 1) Make sure we REALLY have manufacturerBrand (avoid race with top IIFE)
103  let brandListDefault = JSON.parse(sessionStorage.getItem("manufacturerBrand"));
104
105  if (!Array.isArray(brandListDefault) || !brandListDefault.length) {
106    brandListDefault = await get("manufactures");
107    sessionStorage.setItem("manufacturerBrand", JSON.stringify(brandListDefault));
108  }
109
110  if (!Array.isArray(brandListDefault) || !brandListDefault.length) {
111    console.warn("No manufacturers available");
112    return;
113  }
114
115  // 2) Decide from which brand to start (selectedCarBrand if exists, else first)
116  let startIndex = 0;
117
118  if (selectedCarBrandLS?.carName) {
119    const idx = brandListDefault.findIndex(
120      (b) =>
121        String(b.brandName).toLowerCase() ===
122        String(selectedCarBrandLS.carName).toLowerCase()
123    );
124    if (idx !== -1) {
125      startIndex = idx;
126    }
127  }
128
129  // helper to call /models for a brand
130  const fetchModelsForBrand = async (brand) => {
131    const payload = {
132      manufacturers: [{ id: String(brand.id), name: brand.brandName }],
133      type: optionType,
134    };
135    return post("models", payload);
136  };
137
138  // 3) Try brands in order until we find one with models (skip ABARTH if [] is returned)
139  let chosenBrand = null;
140  let models = [];
141
142  for (let i = 0; i < brandListDefault.length; i++) {
143    const brand = brandListDefault[(startIndex + i) % brandListDefault.length];
144    const resp = await fetchModelsForBrand(brand);
145    const arr = resp?.[0] || [];
146
147    if (arr.length) {
148      chosenBrand = brand;
149      models = arr;
150      break;
151    }
152  }
153
154  if (!chosenBrand) {
155    console.warn("No models found for any brand for type:", optionType);
156    return;
157  }
158
159  // 4) Sync sessionStorage + selected logo with the brand that actually has models
160  sessionStorage.setItem(
161    "selectedCarBrand",
162    JSON.stringify({ carId: String(chosenBrand.id), carName: chosenBrand.brandName })
163  );
164
165  const $selectedFilterSectionImg = $(".selected-filter-section img");
166  $selectedFilterSectionImg.attr({
167    src: chosenBrand.src,
168    alt: chosenBrand.brandName,
169    "data-tid": chosenBrand.id,
170    "data-order": chosenBrand.order,
171  });
172
173  // 5) Build slider with the models of the first "valid" brand
174  $container.find(".swiper-wrapper").remove();
175
176  const sliderWrapper = document.createElement("div");
177  $(sliderWrapper).addClass("swiper-wrapper");
178
179  models.forEach((response) => {
180    const cardTemplate = getSliderContent(
181      response["manufacturer_name"],
182      response["modelKey"],
183      response["name"]
184    );
185    $(sliderWrapper).append(cardTemplate);
186
187    $configuratorTitle
188      .html(response["name"])
189      .attr({
190        "data-make": response["manufacturer_name"],
191        "data-modelfamily": response["modelKey"],
192      });
193  });
194
195  $container.append(sliderWrapper);
196  initializeConfiguratorSlider();
197};
198
199
200
201
202// const getCardMobileManufacturer = (data, leasingData) => {
203//   let html = "";
204//   let carSrc = data["carImage"].replace(/&amp;/g, "&");
205//   html += `<div class="swiper-slide col-12 h-100 ">
206//               <div class="card px-3 py-4">
207//                 <div class="card-body px-0 pt-0 pb-3 d-flex flex-column align-items-center justify-content-center topDealsClick"
208//                 data-node-id="${data["Id"]}" data-url="${data["url"]}" id="clickCardMobileManufacture-${data["Id"]}">
209//                   <div>
210//                     <h6>${data["brandName"]}</h6>
211//                     <div class="text-body-regular text-avis-faded-grey">${data["subtitle"]}</div>
212//                   </div>
213//                   <img src="${carSrc}" class="image-fluid" alt="${data["brandName"]}" loading="lazy">
214//                   <div>
215//                     <div class="d-flex">
216//                       <h5 style="line-height: 17px;">${data["offerPrice"]}€</h5>
217//                       <h6>/`+Drupal.t("month")+`</h6>
218//                     </div>
219//                     <div class="text-disclaimer text-avis-faded-grey">`+Drupal.t('VAT')+` 24% ${data["offerPriceWithTax"]}€</div>
220//                   </div>
221//                 </div>`;
222//   const items = leasingData;
223//   html += `<div class="card-footer pt-3 car-info-action">
224//               <div class="d-flex d-lg-none align-items-center flex-wrap gap-2">`;
225//   if (Array.isArray(items)) {
226//     items.forEach((item) => {
227//       if (item[0]) {
228//         html += `<button type="button" data-type="${
229//           item[0].name ? item[0].name : ""
230//         }"
231//                   data-desc="${item[0].description__value}"
232//                   data-icon="${
233//                     item[0].field_leasing_icon ? item[0].field_leasing_icon : ""
234//                   }"
235//                   class="info-btn easy-leasing-modal border-0 rounded-pill p-2 text-bg-avis-powder-grey d-flex align-items-center justify-content-center">
236//                   <img src="${
237//                     item[0].field_leasing_icon
238//                       ? item[0].field_leasing_icon
239//                       : "#"
240//                   }" class="d-inline" alt="${
241//           item[0].name ? item[0].name : "img"
242//         }" />
243//                 </button>`;
244//       }
245//     });
246//   }
247//   html += ` <button type="button" data-bs-toggle="modal" data-bs-target="#leasingInfoModal" data-type="info-circle-modal"
248//                 class="info-btn info-circle-modal bg-transparent rounded-pill p-2 d-flex align-items-center justify-content-center">
249//                 <img src='/themes/custom/avis2024/images/svg/infocircle.svg' class="d-inline" alt="info-icon" />
250//               </button></div></div></div></div>`;
251//   return html;
252// };
253
254// const getCardManufacturer = (data, leasingData) => {
255//   let src = data["carImage"].replace(/&amp;/g, "&");
256//   let html = "";
257//   html += `<div class="product-list-view col-12 col-sm-12 col-md-12 col-lg-4">
258//               <div class="card h-100  manufacturer-list-card border-0">
259//                 <div class="card-body p-0 topDealsClick" data-node-id="${data["Id"]}" data-url="${data["url"]}" id="clickCardManufacturer-${data["Id"]}">
260//                   <img src='${src}' alt='${data["brandName"]}' class="img-responsive">
261//                   <div class="d-flex justify-content-between py-3">
262//                     <div class="d-flex flex-column car-title-col col-md-8">
263//                       <h5>${data["brandName"]}</h5>
264//                       <div>${data["subtitle"]}</div>
265//                     </div>
266//                     <div class="d-flex flex-column col-md-4">
267//                       <span><b>${data["offerPrice"]}€</b> /`+Drupal.t("month")+`</span>
268//                       <span>VAT 24% ${data["offerPriceWithTax"]}€</span>
269//                     </div>
270//                   </div>
271//                 </div>`;
272//   const items = leasingData;
273//   html += `<div class="card-footer p-0 bg-transparent d-flex flex-column gap-3">
274//               <div class="d-flex align-items-center justify-content-center flex-wrap py-3 gap-2">`;
275//   if (Array.isArray(items) && items.length > 0) {
276//     items.forEach((item) => {
277//       if (item[0]) {
278//         html += `<a role='button' tabindex="0" class="footer-btn-popover" data-bs-trigger="click"
279//                   data-bs-toggle="popover"
280//                   data-type="${item[0].name ? item[0].name : ""}"
281//                   data-desc="${
282//                     item[0].description__value ? item[0].description__value : ""
283//                   }"
284//                   data-icon="${
285//                     item[0].field_leasing_icon ? item[0].field_leasing_icon : ""
286//                   }">
287//                     <span class="badge">
288//                       <img src="${
289//                         item[0].field_leasing_icon
290//                           ? item[0].field_leasing_icon
291//                           : "#"
292//                       }" class="d-inline pe-2" alt="" />
293//                           ${item[0].name ? item[0].name : ""}
294//                     </span>
295//                 </a>`;
296//       }
297//     });
298//   }
299//   html += `</div></div></div></div>`;
300//   return html;
301// };
302
303export const handleSelectedCarBrand = async () => {
304	const selectBrandImg = $(".brand-item.selected .brand-image");
305	const brand = selectBrandImg.attr("alt");
306	const $selectedFilterSectionImg = $(".selected-filter-section img");
307	const $vehicleOptionSelected = $('input[name="inlineRadioOptions"]:checked').val();
308
309	// Setting the value of current vehicle option if not selected
310	if (sessionStorage.getItem("selectedVehicleType") === null) {
311		sessionStorage.setItem("selectedVehicleType", $vehicleOptionSelected);
312	}
313
314	$selectedFilterSectionImg.attr({
315		src: selectBrandImg.attr("src"),
316		alt: selectBrandImg.attr("alt"),
317		"data-tid": selectBrandImg.attr("data-tid"),
318		"data-order": selectBrandImg.attr("data-order"),
319	});
320
321	//brand-container
322	const manufactureId = $selectedFilterSectionImg.attr("data-order");
323	const manufactureName = $selectedFilterSectionImg.attr("alt");
324	if (manufactureId && manufactureName) {
325		sessionStorage.setItem("selectedCarBrand", JSON.stringify({carId: manufactureId, carName: manufactureName}));
326	}
327	markers = {
328		manufacturers: [{id: manufactureId, name: manufactureName}],
329		type: $vehicleOptionSelected,
330	};
331
332	markersDefault = {
333		manufacturers: [{id: 1, name: "ABARTH"}],
334		type: $vehicleOptionSelected,
335	};
336	if (window.location.pathname.indexOf("top-deals") < 0) {
337		if (brand != null) {
338			brandModels = await post("models", markers);
339		} else {
340			brandModels = await post("models", markersDefault);
341		}
342		const sliderWrapperContainer = $("#configurator-slider-container .swiper-wrapper");
343		if (sliderWrapperContainer.length) {
344			sliderWrapperContainer.empty();
345			$("#configurator-slider-container .configurator-title").empty();
346			brandModels[0].forEach((response) => {
347				$("#configurator-slider-container .configurator-title").html(response["name"]);
348				$("#configurator-slider-container .configurator-title").attr("data-modelfamily", response["modelKey"]);
349				$("#configurator-slider-container .configurator-title").attr("data-make", response["manufacturer_name"]);
350
351				const cardTemplate = getSliderContent(response["manufacturer_name"], response["modelKey"], response["name"]);
352				$(sliderWrapperContainer).append(cardTemplate);
353			});
354		}
355	}
356	$("#brandModalConfigurator").modal("hide");
357	if (typeof configuratorNavSlider !== 'undefined' && configuratorNavSlider.update) {
358		configuratorNavSlider.update();
359	}
360};
361
362let configuratorNavSlider;
363
364// Slider configuration
365const initializeConfiguratorSlider = () => {
366  configuratorNavSlider = new Swiper("#configurator-slider-container", {
367    loop: true,
368    centeredSlides: true,
369    slidesPerView: 2.3,
370    speed: 750,
371    breakpoints: {
372      0:   { slidesPerView: 1 },
373      992: { slidesPerView: 2.2 },
374      1400:{ slidesPerView: 2.3 },
375    },
376    navigation: {
377      nextEl: ".swiper-button-prev",
378      prevEl: ".swiper-button-next",
379    },
380    on: {
381      afterInit: function (swiper) {
382        const $currentSlideTitle = $("#configurator-slider-container .configurator-title");
383        const slides = swiper.slides;
384
385        if (!slides || !slides.length) {
386          $currentSlideTitle.empty();
387          return;
388        }
389
390        const slide = slides[swiper.activeIndex];
391        if (!slide || !slide.dataset) {
392          $currentSlideTitle.empty();
393          return;
394        }
395
396        $currentSlideTitle
397          .empty()
398          .text(slide.dataset.modelname)
399          .attr({
400            "data-make": slide.dataset.make,
401            "data-modelfamily": slide.dataset.modelfamily,
402          });
403      },
404
405      slideChange: function (swiper) {
406        $("#configureNow").attr("disabled", true);
407        const $currentSlideTitle = $("#configurator-slider-container .configurator-title");
408        $currentSlideTitle.empty();
409
410        const slides = swiper.slides;
411        if (!slides || !slides.length) {
412          return;
413        }
414
415        const slide = slides[swiper.activeIndex];
416        if (!slide || !slide.dataset) {
417          return;
418        }
419
420        $currentSlideTitle
421          .text(slide.dataset.modelname)
422          .attr({
423            "data-make": slide.dataset.make,
424            "data-modelfamily": slide.dataset.modelfamily,
425          });
426
427        $("#configureNow").attr("disabled", false);
428      },
429    },
430  });
431};
432
433
434const getSliderContent = (manufacturer, modelKey, modelName) => {
435	//let url = `https://cdn.imagin.studio/getImage?customer=avis-gr&amp;make=${manufacturer}&amp;modelFamily=${modelKey}&amp;modelYear=2024&amp;width=357&amp;aspectRatio=16:10&amp;angle=05&amp;zoomtype=fullscreen&groundPlaneAdjustment=-0.10`;
436	let url = `https://cdn.imagin.studio/getImage?customer=avis-gr&amp;make=${manufacturer}&amp;modelFamily=${modelKey}&amp;width=357&amp;aspectRatio=16:10&amp;angle=05&amp;zoomtype=fullscreen&groundPlaneAdjustment=-0.10`;
437	let result = url.replace(/&amp;/g, "&");
438	return `<div class="swiper-slide" data-make="${manufacturer}" data-modelfamily="${modelKey}" id="${modelName}" data-modelname="${modelName}">
439            <div class="d-flex flex-column align-items-center justify-content-center slider-content">
440              <img src="${result}" class="img-fluid" alt="${modelName}" />
441              <h4 class="title">${modelName}</h4>
442            </div>
443          </div>`;
444};
445
446$("#configureNow").click(async (e) => {
447	e.preventDefault();
448	const lang = getLangCode() || "";
449	const make = $("#configurator-slider-container .configurator-title").attr("data-make");
450	const modelfamily = $("#configurator-slider-container .configurator-title").attr("data-modelfamily");
451	const orderId = $(".selected-filter-section img").attr("data-order");
452	const makeTitle = $("#configurator-slider-container .configurator-title").text();
453	let optionType = sessionStorage.getItem("selectedVehicleType") || $('input[name="inlineRadioOptions"]:checked').val();
454	var configMakers = {
455		manufacturers: [{id: orderId, name: make}],
456		models: [{manufacturer_name: make, modelKey: modelfamily, name: makeTitle}],
457		bluetooth: false,
458		fuelType: [],
459		parkingSensors: false,
460		transmission: false,
461		sunroof: false,
462		priceMin: 80,
463		priceMax: 4500,
464		vehicleType: optionType,
465	};
466	window.location.href = lang + "/configurator-list?searchargs=" + JSON.stringify(configMakers);
467});
468
469// Triggering brand selection modal
470$("#brand-filter-button").click(async () => {
471	let currentSelectTab = "private";
472	const vehicalType = sessionStorage.getItem("selectedVehicleType");
473	if (vehicalType === "private" || vehicalType === "commercial") {
474		currentSelectTab = vehicalType;
475	}
476	$("input[name='inlineRadioOptions']")
477		.filter('[value="' + currentSelectTab + '"]')
478		.attr("checked", true);
479	const carData = await getCars("manufacturers/" + currentSelectTab, "");
480	const filteredBrands = getCarsByType(carData?.[0]);
481	renderAvailableCars(filteredBrands);
482	$("#" + currentSelectTab).prop("checked", true);
483	const selectedCarBrandLS = JSON.parse(sessionStorage.getItem("selectedCarBrand")); // Parse JSON
484	let brandSelected = false;
485	// Try selecting based on sessionStorage
486	if (selectedCarBrandLS && selectedCarBrandLS.carName) {
487	 // Normalize the stored brand name to lowercase
488	 const storedBrandName = selectedCarBrandLS.carName.toLowerCase();
489	 const $targetBrand = $('.brand-container .brand-item[data-brandname="' + storedBrandName + '"]');
490	 if ($targetBrand.length) {
491	   $targetBrand.addClass("selected");
492	   brandSelected = true;
493	 }
494   }
495	// If no brand selected from storage or storage brand not found, select the first one
496	if (!brandSelected) {
497		$(".brand-container > div:first-of-type").find(".brand-item").addClass("selected");
498	}
499	// Ensure save button is always enabled
500	$("#filter-brand-save-button").removeAttr("disabled");
501});
502
503const renderAvailableCars = (filteredBrands) => {
504	$("#brandModalConfigurator").modal("show");
505	const modalBody = $("#brandModalConfigurator .modal-body");
506	const cardListRow = document.createElement("div");
507	$(cardListRow).addClass("brand-container row g-3 scrollbar-style-large");
508	filteredBrands?.forEach((data) => {
509		const brandCard = getBrandTileData(data);
510		$(cardListRow).append(brandCard);
511	});
512	modalBody.html(cardListRow);
513	// $(".brand-container .brand-item").removeClass('selected');
514	// $('.brand-container > div:first-of-type').find(".brand-item").removeClass('selected');
515	const currentSelectedBrand = JSON.parse(sessionStorage.getItem("selectedCarBrand"));
516	currentSelectedBrand && $('.brand-container .brand-item[data-brandname="' + currentSelectedBrand.carName + '"]').addClass("selected");
517};  
518
519export const updateBrandSelection = (event) => {
520	if (!$(event.currentTarget).parents().hasClass("filter-brand-container")) {
521		removeActive();
522		makeActive(event.currentTarget);
523	} else {
524		if ($(event.currentTarget).hasClass("selected")) {
525			$(event.currentTarget).removeClass("selected");
526		} else {
527			// Ensure only one is selected
528			$('.brand-container .brand-item').removeClass('selected');
529			makeActive(event.currentTarget);
530		}
531		// If after deselecting, nothing is selected, re-select the first one
532		if ($('.brand-container .brand-item.selected').length === 0 && $('.brand-container .brand-item').length > 0) {
533			$(".brand-container > div:first-of-type").find(".brand-item").addClass("selected");
534		}
535		// Ensure save button is always enabled
536		$("#filter-brand-save-button").removeAttr("disabled");
537
538	}
539};
540
541$("input[name='inlineRadioOptions']").change(async function () {
542	var currentCarType = $(this).val();
543	let typeCars = [];
544	typeCars = await getCars("manufacturers/" + currentCarType, "");
545	const filteredCarsBrands = getCarsByType(typeCars?.[0]);
546	renderAvailableCars(filteredCarsBrands); // renderAvailableCars now handles selecting the first if needed
547	sessionStorage.setItem("selectedVehicleType", currentCarType);
548	// Double-check selection after render (might be redundant but safe)
549	if ($('.brand-container .brand-item.selected').length === 0 && $('.brand-container .brand-item').length > 0) {
550		$(".brand-container > div:first-of-type").find(".brand-item").addClass("selected");
551	}
552	$("#filter-brand-save-button").removeAttr("disabled"); // Ensure button enabled after type change
553});

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.