Fix: Kategorie-/Bewertungs-Dropdown im Shop-Filter kaputt + horizontaler Scrollbalken

Beim Einbau der Kundenbewertungen in den Shop-Filter (voriger Commit) landete
ein "import" mitten in einem define:vars-Skript, das aber gar keine Module
unterstützt. Dadurch brach das komplette Filter-Skript auf allen 4 Sprachen
mit einem SyntaxError ab, sobald es geladen wurde – Kategorie-Dropdown,
Mindestbewertung-Dropdown und Sortierung reagierten dadurch gar nicht mehr
auf Klicks. Die lokal gespeicherten Kundenbewertungen werden jetzt in einem
eigenen, echten Modul-Skript direkt danach eingerechnet.

Zusätzlich: horizontaler Scrollbalken im Dropdown-Menü entfernt (nur noch
vertikal scrollbar), wie gewünscht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
qcigano
2026-08-03 04:26:30 +02:00
co-authored by Claude Sonnet 5
parent 6f10e41386
commit cc3e84bd98
5 changed files with 62 additions and 17 deletions
+15 -4
View File
@@ -119,8 +119,6 @@ const t = useTranslations(lang);
</Layout> </Layout>
<script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}> <script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}>
import { lokaleBewertungenFuer } from "../../../scripts/reviews";
const grid = document.getElementById("product-grid"); const grid = document.getElementById("product-grid");
const slots = Array.from(grid.querySelectorAll(".product-slot")); const slots = Array.from(grid.querySelectorAll(".product-slot"));
const kategorieSel = document.getElementById("f-kategorie"); const kategorieSel = document.getElementById("f-kategorie");
@@ -239,6 +237,20 @@ const t = useTranslations(lang);
const preset = params.get("kategorie"); const preset = params.get("kategorie");
if (preset) dropdowns.forEach((d) => d.select(preset)); if (preset) dropdowns.forEach((d) => d.select(preset));
// Rezensionen, die auf DIESEM Gerät lokal gespeichert wurden (siehe scripts/reviews.ts),
// werden in einem eigenen (Modul-)Skript direkt im Anschluss eingerechnet — dieses Skript
// hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten).
window.__shopApply = apply;
apply();
</script>
<script>
import { lokaleBewertungenFuer } from "../../../scripts/reviews";
// Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in
// data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der
// Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren.
const slots = Array.from(document.querySelectorAll(".product-slot"));
slots.forEach((slot) => { slots.forEach((slot) => {
const slug = slot.dataset.slug; const slug = slot.dataset.slug;
if (!slug) return; if (!slug) return;
@@ -249,6 +261,5 @@ const t = useTranslations(lang);
const summe = basisSchnitt * basisAnzahl + lokale.reduce((s, r) => s + r.bewertung, 0); const summe = basisSchnitt * basisAnzahl + lokale.reduce((s, r) => s + r.bewertung, 0);
slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length)); slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length));
}); });
(window as any).__shopApply?.();
apply();
</script> </script>
+15 -4
View File
@@ -119,8 +119,6 @@ const t = useTranslations(lang);
</Layout> </Layout>
<script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}> <script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}>
import { lokaleBewertungenFuer } from "../../../scripts/reviews";
const grid = document.getElementById("product-grid"); const grid = document.getElementById("product-grid");
const slots = Array.from(grid.querySelectorAll(".product-slot")); const slots = Array.from(grid.querySelectorAll(".product-slot"));
const kategorieSel = document.getElementById("f-kategorie"); const kategorieSel = document.getElementById("f-kategorie");
@@ -239,6 +237,20 @@ const t = useTranslations(lang);
const preset = params.get("kategorie"); const preset = params.get("kategorie");
if (preset) dropdowns.forEach((d) => d.select(preset)); if (preset) dropdowns.forEach((d) => d.select(preset));
// Rezensionen, die auf DIESEM Gerät lokal gespeichert wurden (siehe scripts/reviews.ts),
// werden in einem eigenen (Modul-)Skript direkt im Anschluss eingerechnet — dieses Skript
// hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten).
window.__shopApply = apply;
apply();
</script>
<script>
import { lokaleBewertungenFuer } from "../../../scripts/reviews";
// Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in
// data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der
// Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren.
const slots = Array.from(document.querySelectorAll(".product-slot"));
slots.forEach((slot) => { slots.forEach((slot) => {
const slug = slot.dataset.slug; const slug = slot.dataset.slug;
if (!slug) return; if (!slug) return;
@@ -249,6 +261,5 @@ const t = useTranslations(lang);
const summe = basisSchnitt * basisAnzahl + lokale.reduce((s, r) => s + r.bewertung, 0); const summe = basisSchnitt * basisAnzahl + lokale.reduce((s, r) => s + r.bewertung, 0);
slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length)); slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length));
}); });
(window as any).__shopApply?.();
apply();
</script> </script>
+15 -4
View File
@@ -119,8 +119,6 @@ const t = useTranslations(lang);
</Layout> </Layout>
<script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}> <script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}>
import { lokaleBewertungenFuer } from "../../../scripts/reviews";
const grid = document.getElementById("product-grid"); const grid = document.getElementById("product-grid");
const slots = Array.from(grid.querySelectorAll(".product-slot")); const slots = Array.from(grid.querySelectorAll(".product-slot"));
const kategorieSel = document.getElementById("f-kategorie"); const kategorieSel = document.getElementById("f-kategorie");
@@ -239,6 +237,20 @@ const t = useTranslations(lang);
const preset = params.get("kategorie"); const preset = params.get("kategorie");
if (preset) dropdowns.forEach((d) => d.select(preset)); if (preset) dropdowns.forEach((d) => d.select(preset));
// Rezensionen, die auf DIESEM Gerät lokal gespeichert wurden (siehe scripts/reviews.ts),
// werden in einem eigenen (Modul-)Skript direkt im Anschluss eingerechnet — dieses Skript
// hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten).
window.__shopApply = apply;
apply();
</script>
<script>
import { lokaleBewertungenFuer } from "../../../scripts/reviews";
// Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in
// data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der
// Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren.
const slots = Array.from(document.querySelectorAll(".product-slot"));
slots.forEach((slot) => { slots.forEach((slot) => {
const slug = slot.dataset.slug; const slug = slot.dataset.slug;
if (!slug) return; if (!slug) return;
@@ -249,6 +261,5 @@ const t = useTranslations(lang);
const summe = basisSchnitt * basisAnzahl + lokale.reduce((s, r) => s + r.bewertung, 0); const summe = basisSchnitt * basisAnzahl + lokale.reduce((s, r) => s + r.bewertung, 0);
slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length)); slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length));
}); });
(window as any).__shopApply?.();
apply();
</script> </script>
+13 -5
View File
@@ -128,8 +128,6 @@ const t = useTranslations(lang);
</Layout> </Layout>
<script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}> <script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}>
import { lokaleBewertungenFuer } from "../../scripts/reviews";
const grid = document.getElementById("product-grid"); const grid = document.getElementById("product-grid");
const slots = Array.from(grid.querySelectorAll(".product-slot")); const slots = Array.from(grid.querySelectorAll(".product-slot"));
const kategorieSel = document.getElementById("f-kategorie"); const kategorieSel = document.getElementById("f-kategorie");
@@ -248,9 +246,20 @@ const t = useTranslations(lang);
const preset = params.get("kategorie"); const preset = params.get("kategorie");
if (preset) dropdowns.forEach((d) => d.select(preset)); if (preset) dropdowns.forEach((d) => d.select(preset));
// Rezensionen, die auf DIESEM Gerät lokal gespeichert wurden (siehe scripts/reviews.ts),
// werden in einem eigenen (Modul-)Skript direkt im Anschluss eingerechnet — dieses Skript
// hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten).
window.__shopApply = apply;
apply();
</script>
<script>
import { lokaleBewertungenFuer } from "../../scripts/reviews";
// Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in // Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in
// data-bewertung einrechnen, BEVOR zum ersten Mal gefiltert/sortiert wird — sonst würden der // data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der
// Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren. // Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren.
const slots = Array.from(document.querySelectorAll(".product-slot"));
slots.forEach((slot) => { slots.forEach((slot) => {
const slug = slot.dataset.slug; const slug = slot.dataset.slug;
if (!slug) return; if (!slug) return;
@@ -261,6 +270,5 @@ const t = useTranslations(lang);
const summe = basisSchnitt * basisAnzahl + lokale.reduce((s, r) => s + r.bewertung, 0); const summe = basisSchnitt * basisAnzahl + lokale.reduce((s, r) => s + r.bewertung, 0);
slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length)); slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length));
}); });
(window as any).__shopApply?.();
apply();
</script> </script>
+4
View File
@@ -956,6 +956,8 @@ a:focus-visible, button:focus-visible {
right: 0; right: 0;
max-height: min(60vh, 420px); max-height: min(60vh, 420px);
overflow-y: auto; overflow-y: auto;
overflow-x: hidden;
box-sizing: border-box;
background: var(--c-anthracite-light); background: var(--c-anthracite-light);
border: 1px solid rgba(244, 241, 247, 0.12); border: 1px solid rgba(244, 241, 247, 0.12);
border-radius: var(--radius-m); border-radius: var(--radius-m);
@@ -980,6 +982,7 @@ a:focus-visible, button:focus-visible {
.cat-filter-option { .cat-filter-option {
display: block; display: block;
width: 100%; width: 100%;
box-sizing: border-box;
text-align: left; text-align: left;
background: none; background: none;
border: none; border: none;
@@ -989,6 +992,7 @@ a:focus-visible, button:focus-visible {
font-size: 0.9rem; font-size: 0.9rem;
cursor: pointer; cursor: pointer;
transition: background 0.15s var(--ease); transition: background 0.15s var(--ease);
overflow-wrap: break-word;
} }
.cat-filter-option:hover { background: color-mix(in srgb, var(--c-accent) 14%, transparent); } .cat-filter-option:hover { background: color-mix(in srgb, var(--c-accent) 14%, transparent); }
.cat-filter-option[aria-selected="true"] { background: color-mix(in srgb, var(--c-accent) 20%, transparent); font-weight: 700; } .cat-filter-option[aria-selected="true"] { background: color-mix(in srgb, var(--c-accent) 20%, transparent); font-weight: 700; }