`;
}
@@ -848,6 +858,7 @@ class IdmHotspot{
if(!this.options.addToBasket) return markup;
const prodTotalAmount = this.getProdTotalAmount(prod);
+ const prodCurrentSizeAmount = this.options.selectSize ? prod.sizes.find(size=>size.amount !== 0).amount : prod.sizes[0].amount;
// link do produktu jak nie jest to zwykły produkt
@@ -860,7 +871,7 @@ class IdmHotspot{
@@ -870,7 +881,7 @@ class IdmHotspot{
value="${prod.unit?.sellBy}"
step="${prod.unit?.sellBy}"
min="${prod.unit?.sellBy}"
- max="${prod.sizes[0].amount === -1 ? 999999 : prod.sizes[0].amount}"
+ max="${prodCurrentSizeAmount === -1 ? 999999 : prodCurrentSizeAmount}"
aria-label="${idmHotspotTextObject["Ilość"]}"
>
@@ -1181,12 +1192,38 @@ class IdmHotspot{
const inputEl = e.target.closest("input[type='radio']");
if(!inputEl) return;
- const newValue = inputEl?.dataset?.value;
+ //1. Zmiana Wybranego inputa
+ const sizeId = inputEl?.dataset?.value;
const hiddenSizeInputEl = e.target.closest("form.add_to_basket")?.querySelector("input[type='hidden'][name='size']");
- if(!hiddenSizeInputEl || !newValue) return inputEl.checked = false;
+ if(!hiddenSizeInputEl || !sizeId) return inputEl.checked = false;
- hiddenSizeInputEl.value = newValue;
+ hiddenSizeInputEl.value = sizeId;
+
+ // 2. Zmiana ceny
+ const productEl = e.target.closest(".product.hotspot__product");
+ const productData = this.searchForProductData(+productEl?.dataset.id)
+ const currSizeData = productData?.sizes.find(size=>size.id === sizeId);
+ if(!currSizeData || !productData) return;
+
+ const priceEl = productEl.querySelector(".product__prices");
+ if(!priceEl) return;
+
+ priceEl.outerHTML = this.markupPrice({prod: productData, sizeId});
+
+ this.setHeightDefault();
+
+ // 3. Zmiana maksymalnej ilości produktu dozwolonego do kupienia dla range
+ if(this.options.addToBasket === "range"){
+ const qtyContainer = productEl.querySelector(".idm-products-banner__qty");
+ const qtyInput = qtyContainer?.querySelector("input.idm-products-banner__qty-input");
+ if(!qtyContainer || !qtyInput) return console.error("Brak elementów qty");
+
+
+ qtyContainer.dataset.max = currSizeData.amount;
+ qtyInput.max = currSizeData.amount;
+ if(qtyInput.value > currSizeData.amount) qtyInput.value = currSizeData.amount - (currSizeData.amount % +qtyInput.step);
+ }
}
/**
@@ -1224,6 +1261,7 @@ class IdmHotspot{
}
cssVariableVersionColumnCount(){
+ if(!this.options?.selectVersion) return false;
this.cssSetVariable("--version-desktop-columns", this.cssVariables?.version?.columnDesktop || 5)
this.cssSetVariable("--version-tablet-columns", this.cssVariables?.version?.columnTablet || 3)
this.cssSetVariable("--version-mobile-columns", this.cssVariables?.version?.columnMobile || 4)
@@ -1290,7 +1328,7 @@ class IdmHotspot{
cssInsertStyleTag(){
this.hotspotEl.insertAdjacentHTML("beforeend", `
`)
}
@@ -1305,7 +1343,7 @@ class IdmHotspot{
// ========================================================
getProdTotalAmount(prod){
- return prod.sizes.reduce((acc, val) => val === -1 || acc === -1 ? -1 : acc + val, 0);
+ return prod.sizes.reduce((acc, val) => val.amount === -1 || acc === -1 ? -1 : acc + val.amount, 0);
}
/**
@@ -1347,22 +1385,38 @@ class IdmHotspot{
if (selectors?.length) selectors.forEach(adjustAllHeights)
}
+ setHeightDefault(){
+ this.setHeight({
+ selectors: [
+ `#${this.id} .product__prices`,
+ `#${this.id} .product__name`,
+ ],
+ container: `#${this.id} .products__wrapper`,
+ });
+ }
+
+
/**
* Przeładowanie pojedynczego produktu
*/
async reloadProduct(prodEl, newProdId){
try{
prodEl.classList.add("--loading");
- const res = await fetch(`/graphql/v1/`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: IDM_PRODUCT_GQL(`productId: ${newProdId}`, this.priceType),
- });
- const data = await res.json();
+ let productData = this.searchForProductData(newProdId);
+
+ if(!productData){
+ const res = await fetch(`/graphql/v1/`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: IDM_PRODUCT_GQL(`productId: ${newProdId}`, this.priceType),
+ });
+ const data = await res.json();
+ productData = data?.data?.product?.product;
+ if(productData) this.productsVersions.push(productData);
+ }
- const productData = data?.data?.product?.product;
if(!productData) throw new Error("Nie udało się pobrać danych o produkcie");
@@ -1374,13 +1428,7 @@ class IdmHotspot{
else prodEl.classList.remove("--phone");
this.initSingleEvent(prodEl);
- this.setHeight({
- selectors: [
- `#${this.id} .product__prices`,
- `#${this.id} .product__name`,
- ],
- container: `#${this.id} .products__wrapper`,
- });
+ this.setHeightDefault();
}catch(err){
Alertek?.Error(idmHotspotTextObject["Błąd przy pobieraniu danych"]);
console.error(err);
@@ -1389,6 +1437,15 @@ class IdmHotspot{
}
}
+
+ searchForProductData(searchedId){
+ let productData;
+
+ productData = this.products.find(prod=>prod.id === +searchedId) || this.productsVersions.find(prod=>prod.id === +searchedId) || null;
+
+ return productData;
+ }
+
// ========================================================
// XML to GraphQL
// ========================================================
@@ -1741,13 +1798,7 @@ class IdmHotspot{
await this.initSwiper();
// IDM setHeight
- this.setHeight({
- selectors: [
- `#${this.id} .product__prices`,
- `#${this.id} .product__name`,
- ],
- container: `#${this.id} .products__wrapper`,
- });
+ this.setHeightDefault();
this.initEvents();
console.log(`Initialized hotspot #${this.id}`);
diff --git a/ramka.txt b/ramka.txt
index daa9041..f1a27ec 100644
--- a/ramka.txt
+++ b/ramka.txt
@@ -2,16 +2,18 @@
bugi selectSize + addToBasket="range"
-- wybór rozmiaru/wersji?? Wykluczenie powtarzających się wersji
+- Wykluczenie powtarzających się wersji
+
wersja max 5 zdjęć i później + może????
+Wyświetlanie filmu na hover?
- zakres cen?????????????
- Wybór kolorystyczny???
- AAAAA - banner na hotspocie
- stary szablon
-- blokowanie dodawania do koszyka jeśli ilość jest maksymalna
-- informacje o producencie albo serri gdzieś nad produktem
+- blokowanie dodawania do koszyka jeśli ilość jest maksymalna(chyba tylko nowy szablon ma app_shop.vars.basket)
+- informacje o producencie albo seri gdzieś nad produktem
- czy zapisywać wszystkie hotspoty do jakiegoś app_shop.fn.idmHotspots = {"#idmMainHotspot1": {}}
- czy jakoś inteligentnie ucinać niepotrzebne query na podstawie wybranych opcji? chyba za dużo roboty i nie ma sensu
@@ -19,13 +21,15 @@ wersja max 5 zdjęć i później + może????
- własne klasy
Stara ramka
-- getProductXML=t
- slick
-cacheowanie ramek do indexedDB
+cacheowanie ramek do indexedD
-awaitowanie idmHotspot
+zapisywanie querySelectorów produktów??
+awaitowanie idmHotspot???(raczej nie przez intersection observer)
-fix cssVariables jak nie ma wesji
-zapisywanie querySelectorów produktów
\ No newline at end of file
+rozmiary i wersje - dropdown
+
+
+Dodawanie do this.products klikniętego produktu na wersje, ale tak żeby nie wczytywał się ponownie, jakaś baza danych wersji??
\ No newline at end of file
diff --git a/style.less b/style.less
index 7cbaf0e..86bdd50 100644
--- a/style.less
+++ b/style.less
@@ -131,6 +131,14 @@
top: -1px;
transition: all 0.3s;
border-radius: 5px;
+ &:after{
+ content: "";
+ position: absolute;
+ opacity: 0;
+ height: calc(100% + 8px);
+ top: -4px;
+ width: 100%;
+ }
}
@@ -400,24 +408,28 @@
gap: 1rem;
padding: 0.3rem;
background: #fff;
+ width: 100%;
input[type="radio"]{
display: none;
}
.product__size_select{
- width: 4.5rem;
+ // width: 4.5rem;
+ width: calc(26% - 1.5rem);
height: 4.5rem;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
border: 1px solid #ccc;
- transition: border 0.2s;
- &:hover{
- border-color: #000;
- }
- &:not(:has(input:checked)){
- cursor: pointer;
+ transition: all 0.2s;
+ white-space: nowrap;
+ border-radius: 8px;
+
+ &:has(input:disabled){
+ opacity: 0.6;
+ cursor: not-allowed!important;
}
+
&:has(input:checked){
box-shadow: 0 0 0 1px #000;
border-color: #000;
@@ -433,6 +445,14 @@
top: calc(100%);
padding-top: 1rem;
}
+ .product__select_sizes .product__size_select{
+ &:hover:not(:has(input:disabled)){
+ border-color: #000;
+ }
+ &:not(:has(input:checked)){
+ cursor: pointer;
+ }
+ }
.product:hover .product__select_sizes{
clip-path: inset(0 0 0 0);
}