Merge pull request #29 from iantsch/ui-generic-store

Refactor UI to generic store syntax
This commit is contained in:
Mario Zechner 2023-05-28 20:37:45 +02:00 committed by GitHub
commit 35c3bbbcca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 71 additions and 70 deletions

View File

@ -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();
@ -89,25 +129,16 @@ function removeCart(name) {
}
function itemToStoreLink(item) {
if (item.store == "spar")
return `<a target="_blank" href="https://www.interspar.at/shop/lebensmittel/search/?q=${encodeURIComponent(item.name)}">${item.name}</a>`;
if (item.store == "billa")
return `<a target="_blank" href="https://shop.billa.at/search/results?category=&searchTerm=${encodeURIComponent(item.name)}">${item.name}</a>`;
if (item.store == "hofer")
return `<a target="_blank" href="https://www.roksh.at/hofer/angebot/suche/${encodeURIComponent(item.name)}">${item.name}</a>`;
if (item.store == "dm")
return `<a target="_blank" href="https://www.dm.at/product-p${item.id}.html">${item.name}</a>`;
if (item.store == "lidl")
return `<a target="_blank" href="https://www.lidl.at${item.url}">${item.name}</a>`;
if (item.store == "mpreis")
return `<a target="_blank" href="https://www.mpreis.at/shop/p/${item.id}">${item.name}</a>`;
return item.name;
if (STORE_KEYS.includes(item.store)) {
return `<a target="_blank" class="itemname itemname--${item.store}" rel="noopener noreferrer nofollow" href="${item.url}">${item.name}</a>`
}
return `<span class="itemname itemname--${item.store} itemname--nolink">${item.name}</span>`;
}
function itemToDOM(item) {
let storeDom = dom("td", item.store);
storeDom.setAttribute("data-label", "Kette");
let nameDom = dom("td", `<div class="itemname">${itemToStoreLink(item)}</div>`);
let nameDom = dom("td", `${itemToStoreLink(item)}`);
nameDom.setAttribute("data-label", "Name");
let unitDom = dom("td", item.unit ? item.unit : "");
unitDom.setAttribute("data-label", "Menge");
@ -143,25 +174,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);
@ -171,7 +184,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 [];
@ -205,15 +218,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);
}
@ -227,16 +238,11 @@ function newSearchComponent(parentElement, items, searched, filter, headerModifi
parentElement.innerHTML = `
<input id="search-${id}" class="search" type="text" placeholder="Produkte suchen...">
<a id="querylink-${id}" class="hide">Query link</a>
<div class="filters">
<label><input id="billa-${id}" type="checkbox" checked="true"> Billa</label>
<label><input id="spar-${id}" type="checkbox" checked="true"> Spar</label>
<label><input id="hofer-${id}" type="checkbox" checked="true"> Hofer</label>
<label><input id="dm-${id}" type="checkbox" checked="true"> DM</label>
<label><input id="lidl-${id}" type="checkbox" checked="true"> Lidl</label>
<label><input id="mpreis-${id}" type="checkbox" checked="false"> MPREIS</label>
<div class="filters filters--store">
${STORE_KEYS.map(store => `<label><input id="${store}-${id}" type="checkbox" checked="true">${stores[store].name}</label>`).join(" ")}
</div>
<div class="filters">
<label><input id="eigenmarken-${id}" type="checkbox"> Nur CLEVER / S-BUDGET / MILFINA</label>
<label><input id="budgetBrands-${id}" type="checkbox"> Nur ${BUDGET_BRANDS.map(budgetBrand => budgetBrand.toUpperCase()).join(", ")}</label>
<label><input id="bio-${id}" type="checkbox"> Nur Bio</label>
</div>
<div class="filters">
@ -252,14 +258,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}`);
@ -269,8 +270,8 @@ function newSearchComponent(parentElement, items, searched, filter, headerModifi
let now = performance.now();
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);
@ -320,14 +321,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));

View File

@ -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}`
};
}

View File

@ -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`
};
}

View File

@ -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}`
};
}

View File

@ -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}`
};
}

View File

@ -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}`
};
}

View File

@ -19,7 +19,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}`
};
}