diff --git a/src/pages/ch/produkt/[slug].astro b/src/pages/ch/produkt/[slug].astro
index dec077e..f344147 100644
--- a/src/pages/ch/produkt/[slug].astro
+++ b/src/pages/ch/produkt/[slug].astro
@@ -1,7 +1,8 @@
---
import Layout from "../../../layouts/Layout.astro";
import ProductCard from "../../../components/ProductCard.astro";
-import { products, getProduct, productsByCategory } from "../../../data/products";
+import HeartRating from "../../../components/HeartRating.astro";
+import { products, getProduct, productsByCategory, durchschnittsbewertung, anzahlBewertungen } from "../../../data/products";
import { getCategory } from "../../../data/categories";
import type { Locale } from "../../../i18n/config";
import { useTranslations } from "../../../i18n/ui";
@@ -27,6 +28,8 @@ const finalPrice = effektiverPreis(product);
const discountBadge = rabattLabel(product);
const showOldAsPreis = !product.preisAlt && hatAktivenRabatt(product);
const mengenrabatt = product.rabatt?.mengenrabatt ?? [];
+const bewertungSchnitt = durchschnittsbewertung(product);
+const bewertungAnzahl = anzahlBewertungen(product);
const felder: [string, string | undefined][] = [
[t.product.articleNo, product.artikelnummer],
@@ -71,6 +74,11 @@ const felder: [string, string | undefined][] = [
{product.bestand === 0 && {t.badge.ausverkauft}}
{name}
+ {bewertungSchnitt !== null && (
+
+
+
+ )}
{product.preisAlt && {formatPrice(product.preisAlt, lang)}}
{showOldAsPreis && {formatPrice(product.preis, lang)}}
@@ -123,6 +131,33 @@ const felder: [string, string | undefined][] = [
+
+
+
{t.product.reviewsTitle}
+ {bewertungSchnitt !== null ? (
+ <>
+
+
+
+
+ {product.bewertungen!.map((r) => (
+
+
+ {r.name}
+
+ {r.datum && {r.datum}}
+
+ {r.text &&
{r.text[lang]}
}
+
+ ))}
+
+ >
+ ) : (
+
{t.product.noReviews}
+ )}
+
+
+
{empfehlungen.length > 0 && (
diff --git a/src/pages/ch/shop/index.astro b/src/pages/ch/shop/index.astro
index 8eb3969..d67c124 100644
--- a/src/pages/ch/shop/index.astro
+++ b/src/pages/ch/shop/index.astro
@@ -2,7 +2,7 @@
import Layout from "../../../layouts/Layout.astro";
import ProductCard from "../../../components/ProductCard.astro";
import { categories, subcategoryChipLabel } from "../../../data/categories";
-import { products } from "../../../data/products";
+import { products, durchschnittsbewertung } from "../../../data/products";
import type { Locale } from "../../../i18n/config";
import { useTranslations } from "../../../i18n/ui";
@@ -59,6 +59,16 @@ const t = useTranslations(lang);
+
+
+
+
{t.shop.filterNote}
@@ -68,6 +78,7 @@ const t = useTranslations(lang);
@@ -82,6 +93,7 @@ const t = useTranslations(lang);
data-bestand={p.bestand}
data-neu={p.badges.includes("neu") ? 1 : 0}
data-bestseller={p.badges.includes("bestseller") ? 1 : 0}
+ data-bewertung={durchschnittsbewertung(p) ?? 0}
>
@@ -101,6 +113,7 @@ const t = useTranslations(lang);
const preisRange = document.getElementById("f-preis");
const preisValue = document.getElementById("f-preis-value");
const verfuegbarChk = document.getElementById("f-verfuegbar");
+ const bewertungSel = document.getElementById("f-bewertung");
const sortSel = document.getElementById("sort");
const resultCount = document.getElementById("result-count");
const emptyMsg = document.getElementById("empty-msg");
@@ -114,6 +127,7 @@ const t = useTranslations(lang);
const kat = kategorieSel.value;
const maxPreis = Number(preisRange.value);
const nurVerfuegbar = verfuegbarChk.checked;
+ const minBewertung = Number(bewertungSel.value);
preisValue.textContent = formatPrice(maxPreis);
let visible = 0;
@@ -125,7 +139,8 @@ const t = useTranslations(lang);
: slot.dataset.kategorie === kat;
const matchPreis = Number(slot.dataset.preis) <= maxPreis;
const matchVerfuegbar = !nurVerfuegbar || Number(slot.dataset.bestand) > 0;
- const show = matchKat && matchPreis && matchVerfuegbar;
+ const matchBewertung = Number(slot.dataset.bewertung) >= minBewertung;
+ const show = matchKat && matchPreis && matchVerfuegbar && matchBewertung;
slot.style.display = show ? "" : "none";
if (show) visible++;
});
@@ -138,13 +153,14 @@ const t = useTranslations(lang);
case "preis-auf": return Number(a.dataset.preis) - Number(b.dataset.preis);
case "preis-ab": return Number(b.dataset.preis) - Number(a.dataset.preis);
case "bestseller": return Number(b.dataset.bestseller) - Number(a.dataset.bestseller);
+ case "bewertung": return Number(b.dataset.bewertung) - Number(a.dataset.bewertung);
default: return Number(b.dataset.neu) - Number(a.dataset.neu);
}
});
sorted.forEach((el) => grid.appendChild(el));
}
- [preisRange, verfuegbarChk, sortSel].forEach((el) => el.addEventListener("input", apply));
+ [preisRange, verfuegbarChk, bewertungSel, sortSel].forEach((el) => el.addEventListener("input", apply));
const catFilter = document.getElementById("cat-filter");
const catFilterBtn = document.getElementById("cat-filter-btn");
diff --git a/src/pages/en/index.astro b/src/pages/en/index.astro
index dd371b0..47583e9 100644
--- a/src/pages/en/index.astro
+++ b/src/pages/en/index.astro
@@ -1,15 +1,20 @@
---
import Layout from "../../layouts/Layout.astro";
import ProductCard from "../../components/ProductCard.astro";
+import HeartRating from "../../components/HeartRating.astro";
import { categories } from "../../data/categories";
-import { products } from "../../data/products";
+import { products, alleBewertungen, gesamtDurchschnitt } from "../../data/products";
+import { useTranslations } from "../../i18n/ui";
import type { Locale } from "../../i18n/config";
const lang: Locale = "en";
+const t = useTranslations(lang);
const neuheiten = products.filter((p) => p.badges.includes("neu")).slice(0, 4);
const bestseller = products.filter((p) => p.badges.includes("bestseller")).slice(0, 4);
const sale = products.filter((p) => p.badges.includes("sale") || p.preisAlt).slice(0, 4);
+const topBewertungen = alleBewertungen().slice(0, 3);
+const bewertungSchnittGesamt = gesamtDurchschnitt();
---