From a8865804694aefad90f0c192142e2e3e327d8352 Mon Sep 17 00:00:00 2001 From: Christian Tschugg Date: Fri, 26 May 2023 18:12:29 +0200 Subject: [PATCH] Refactor UI to generic store syntax --- site/utils.js | 126 +++++++++++++++++++++++------------------------ stores/billa.js | 3 +- stores/dm.js | 1 + stores/hofer.js | 3 +- stores/lidl.js | 2 +- stores/mpreis.js | 3 +- stores/spar.js | 3 +- 7 files changed, 71 insertions(+), 70 deletions(-) diff --git a/site/utils.js b/site/utils.js index d672e1a..fa9dce0 100644 --- a/site/utils.js +++ b/site/utils.js @@ -1,3 +1,43 @@ +const stores = { + billa: { + name: "Billa", + budgetBrands: ["clever"], + color: "rgb(255 255 225)", + }, + dm: { + name: "DM", + budgetBrands: [], + color: "rgb(255 240 230)", + }, + hofer: { + name: "Hofer", + budgetBrands: ["milfina"], + color: "rgb(230 230 255)", + }, + lidl: { + name: "Lidl", + budgetBrands: ["milbona"], + color: "rgb(255 225 225)", + }, + mpreis: { + name: "MPREIS", + budgetBrands: [], + color: "rgb(255 230 230)", + }, + spar: { + name: "Spar", + budgetBrands: ["s-budget"], + color: "rgb(225 244 225)", + }, +}; + +const STORE_KEYS = Object.keys(stores); +const BUDGET_BRANDS = [].concat( + ...Object + .values(stores) + .map(store => store.budgetBrands) +); + function currentDate() { const currentDate = new Date(); const year = currentDate.getFullYear(); @@ -90,25 +130,16 @@ function removeCart(name) { } function itemToStoreLink(item) { - if (item.store == "spar") - return `${item.name}`; - if (item.store == "billa") - return `${item.name}`; - if (item.store == "hofer") - return `${item.name}`; - if (item.store == "dm") - return `${item.name}`; - if (item.store == "lidl") - return `${item.name}`; - if (item.store == "mpreis") - return `${item.name}`; - return item.name; + if (STORE_KEYS.includes(item.store)) { + return `${item.name}` + } + return `${item.name}`; } function itemToDOM(item) { let storeDom = dom("td", item.store); storeDom.setAttribute("data-label", "Kette"); - let nameDom = dom("td", `
${itemToStoreLink(item)}
`); + let nameDom = dom("td", `${itemToStoreLink(item)}`); nameDom.setAttribute("data-label", "Name"); let unitDom = dom("td", item.unit ? item.unit : ""); unitDom.setAttribute("data-label", "Menge"); @@ -144,25 +175,7 @@ function itemToDOM(item) { }); } let row = dom("tr", ""); - switch (item.store) { - case "billa": - row.style["background"] = "rgb(255 255 225)"; - break; - case "spar": - row.style["background"] = "rgb(225 244 225)"; - break; - case "hofer": - row.style["background"] = "rgb(230 230 255)"; - break; - case "dm": - row.style["background"] = "rgb(255 240 230)"; - break; - case "lidl": - row.style["background"] = "rgb(255 225 225)"; - break; - case "mpreis": - row.style["background"] = "rgb(255 230 230)"; - } + row.style["background"] = stores[item.store]?.color; row.appendChild(storeDom); row.appendChild(nameDom); row.appendChild(unitDom); @@ -172,7 +185,7 @@ function itemToDOM(item) { let componentId = 0; -function searchItems(items, query, billa, spar, hofer, dm, lidl, mpreis, eigenmarken, minPrice, maxPrice, exact, bio) { +function searchItems(items, query, checkedStores, budgetBrands, minPrice, maxPrice, exact, bio) { query = query.trim(); if (query.length < 3) return []; @@ -215,15 +228,13 @@ function searchItems(items, query, billa, spar, hofer, dm, lidl, mpreis, eigenma } if (allFound) { const name = item.name.toLowerCase(); - if (item.store == "billa" && !billa) continue; - if (item.store == "spar" && !spar) continue; - if (item.store == "hofer" && !hofer) continue; - if (item.store == "dm" && !dm) continue; - if (item.store == "lidl" && !lidl) continue; - if (item.store == "mpreis" && !mpreis) continue; + if (checkedStores.length && !checkedStores.includes(item.store)) continue; if (item.price < minPrice) continue; if (item.price > maxPrice) continue; - if (eigenmarken && !(name.indexOf("clever") == 0 || name.indexOf("s-budget") == 0 || name.indexOf("milfina") == 0)) continue; + if ( + budgetBrands && + !BUDGET_BRANDS.some(budgetBrand => name.indexOf(budgetBrand)) + ) continue; if (bio && !item.bio) continue; hits.push(item); } @@ -237,16 +248,11 @@ function newSearchComponent(parentElement, items, searched, filter, headerModifi parentElement.innerHTML = ` Query link -
- - - - - - +
+ ${STORE_KEYS.map(store => ``).join(" ")}
- +
@@ -262,14 +268,9 @@ function newSearchComponent(parentElement, items, searched, filter, headerModifi const queryLink = parentElement.querySelector(`#querylink-${id}`); const exact = parentElement.querySelector(`#exact-${id}`); const table = parentElement.querySelector(`#result-${id}`); - const eigenmarken = parentElement.querySelector(`#eigenmarken-${id}`); + const budgetBrands = parentElement.querySelector(`#budgetBrands-${id}`); const bio = parentElement.querySelector(`#bio-${id}`); - const billa = parentElement.querySelector(`#billa-${id}`); - const spar = parentElement.querySelector(`#spar-${id}`); - const hofer = parentElement.querySelector(`#hofer-${id}`); - const dm = parentElement.querySelector(`#dm-${id}`); - const lidl = parentElement.querySelector(`#lidl-${id}`); - const mpreis = parentElement.querySelector(`#mpreis-${id}`); + const storeCheckboxes = STORE_KEYS.map(store => parentElement.querySelector(`#${store}-${id}`)); const minPrice = parentElement.querySelector(`#minprice-${id}`); const maxPrice = parentElement.querySelector(`#maxprice-${id}`); const numResults = parentElement.querySelector(`#numresults-${id}`); @@ -278,8 +279,8 @@ function newSearchComponent(parentElement, items, searched, filter, headerModifi let hits = []; try { hits = searchItems(items, query, - billa.checked, spar.checked, hofer.checked, dm.checked, lidl.checked, mpreis.checked, - eigenmarken.checked, toNumber(minPrice.value, 0), toNumber(maxPrice.value, 100), exact.checked, bio.checked + STORE_KEYS.filter((store, i) => storeCheckboxes[i].checked), + budgetBrands.checked, toNumber(minPrice.value, 0), toNumber(maxPrice.value, 100), exact.checked, bio.checked ); } catch (e) { console.log("Query: " + query + "\n" + e.message); @@ -325,14 +326,9 @@ function newSearchComponent(parentElement, items, searched, filter, headerModifi } search(searchInput.value); }); - eigenmarken.addEventListener("change", () => search(searchInput.value)); + budgetBrands.addEventListener("change", () => search(searchInput.value)); bio.addEventListener("change", () => search(searchInput.value)); - billa.addEventListener("change", () => search(searchInput.value)); - spar.addEventListener("change", () => search(searchInput.value)); - hofer.addEventListener("change", () => search(searchInput.value)); - dm.addEventListener("change", () => search(searchInput.value)); - lidl.addEventListener("change", () => search(searchInput.value)); - mpreis.addEventListener("change", () => search(searchInput.value)); + storeCheckboxes.map(store => store.addEventListener("change", () => search(searchInput.value))); exact.addEventListener("change", () => search(searchInput.value)); minPrice.addEventListener("change", () => search(searchInput.value)); maxPrice.addEventListener("change", () => search(searchInput.value)); diff --git a/stores/billa.js b/stores/billa.js index 6a3ee15..dbdc3a9 100644 --- a/stores/billa.js +++ b/stores/billa.js @@ -8,7 +8,8 @@ exports.getCanonical = function(item, today) { price: item.data.price.final, priceHistory: [{ date: today, price: item.data.price.final }], unit: item.data.grammagePriceFactor == 1 ? item.data.grammage : "kg", - bio: item.data.attributes && item.data.attributes.includes("s_bio") + bio: item.data.attributes && item.data.attributes.includes("s_bio"), + url: `https://shop.billa.at${item.data.canonicalPath}` }; } diff --git a/stores/dm.js b/stores/dm.js index c563bb4..7d64903 100644 --- a/stores/dm.js +++ b/stores/dm.js @@ -8,6 +8,7 @@ exports.getCanonical = function(item, today) { priceHistory: [{ date: today, price: item.price.value }], unit: `${item.netQuantityContent} ${item.contentUnit}`, ...(item.brandName === "dmBio" || (item.name ? (item.name.startsWith("Bio ") | item.name.startsWith("Bio-")) : false)) && {bio: true}, + url: `https://www.dm.at/product-p${item.gtin}.html` }; } diff --git a/stores/hofer.js b/stores/hofer.js index ca993ea..0d5a3a1 100644 --- a/stores/hofer.js +++ b/stores/hofer.js @@ -7,7 +7,8 @@ exports.getCanonical = function(item, today) { price: item.Price, priceHistory: [{ date: today, price: item.Price }], unit: `${item.Unit} ${item.UnitType}`, - bio: item.IsBio + bio: item.IsBio, + url: `https://www.roksh.at/hofer/produkte/${item.CategorySEOName}/${item.SEOName}` }; } diff --git a/stores/lidl.js b/stores/lidl.js index d1cf98b..df81b01 100644 --- a/stores/lidl.js +++ b/stores/lidl.js @@ -8,7 +8,7 @@ exports.getCanonical = function(item, today) { price: item.price.price, priceHistory: [{ date: today, price: item.price.price }], unit: item.price.basePrice?.text ?? "", - url: item.canonicalUrl + url: `https://www.lidl.at${item.canonicalUrl}` }; } diff --git a/stores/mpreis.js b/stores/mpreis.js index 3f8f4c5..48a031d 100644 --- a/stores/mpreis.js +++ b/stores/mpreis.js @@ -7,7 +7,8 @@ exports.getCanonical = function(item, today) { price: item.prices[0].presentationPrice.effectiveAmount, priceHistory: [{ date: today, price: item.prices[0].presentationPrice.effectiveAmount }], unit: `${item.prices[0].presentationPrice.measurementUnit.quantity} ${item.prices[0].presentationPrice.measurementUnit.unitCode}`, - bio: item.mixins.mpreisAttributes.properties?.includes('BIO') + bio: item.mixins.mpreisAttributes.properties?.includes('BIO'), + url: `https://www.mpreis.at/shop/p/${item.code}` }; } diff --git a/stores/spar.js b/stores/spar.js index 469145a..6ed1611 100644 --- a/stores/spar.js +++ b/stores/spar.js @@ -18,7 +18,8 @@ exports.getCanonical = function(item, today) { price, priceHistory: [{ date: today, price }], unit, - bio: item.masterValues.biolevel === "Bio" + bio: item.masterValues.biolevel === "Bio", + url: `https://www.interspar.at/shop/lebensmittel${item.masterValues.url}` }; }