// Biere — Karussell, Filter, Geschmacksprofil
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"show_grain": true
} /*EDITMODE-END*/;
const Profile = ({ profile, animated = true }) => {
const rows = [
{ k: "malz", l: "Malz" },
{ k: "hopfen", l: "Hopfen" },
{ k: "bitter", l: "Bittere" },
{ k: "sauer", l: "Säure" },
{ k: "koerper", l: "Körper" }];
return (
{rows.map((r) =>
{r.l}
{Math.round((profile[r.k] || 0) * 100)}
)}
);
};
const Carousel = ({ beers }) => {
const [idx, setIdx] = React.useState(0);
const [dir, setDir] = React.useState(1);
const [animKey, setAnimKey] = React.useState(0);
React.useEffect(() => {setIdx(0);}, [beers.length]);
const go = (d) => {
setDir(d);
setIdx((i) => (i + d + beers.length) % beers.length);
setAnimKey((k) => k + 1);
};
if (!beers.length) {
return Keine Biere in dieser Kategorie.
;
}
const b = beers[idx];
return (
{String(idx + 1).padStart(2, "0")} / {String(beers.length).padStart(2, "0")}
{b.style} · Charge {b.batch}
{b.name}
{b.tagline}
{b.description}
{b.abv}%Vol.
{b.ibu}IBU
33clFlasche
passt zu
{b.pairs.join(" · ")}
);
};
const BeerCard = ({ beer }) => {
const [hover, setHover] = React.useState(false);
return (
setHover(true)}
onMouseLeave={() => setHover(false)}
style={{ textDecoration: "none", scrollMarginTop: 100 }}>
{beer.style} · {beer.abv}% Vol. · {beer.ibu} IBU
{beer.name}
{beer.tagline}
);
};
const App = () => {
const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
const [filter, setFilter] = React.useState("alle");
const [beers, setBeers] = React.useState(window.BEERS);
React.useEffect(() => {
if (window.beersReady) window.beersReady.then(setBeers);
}, []);
const filtered = filter === "alle" ? beers : beers.filter((b) => b.styleClass === filter);
const styles = [
{ id: "alle", label: "Alle Sorten" },
{ id: "ipa", label: "IPA" },
{ id: "stout", label: "Stout" },
{ id: "sauer", label: "Sauerbier" }];
return (
Sortiment · Aktuelle Chargen
diverse Biere,
diverse Stimmungen.
Was gerade fertig ist, was reift, und was du jetzt bestellen kannst.
Klein gebraut — meist sind 80 bis 120 Flaschen pro Charge.
Filter
{styles.map((s) =>
)}
{filtered.length} {filtered.length === 1 ? "Bier" : "Biere"}
{filtered.length} angezeigt
{filtered.map((b) => )}
setTweak("show_grain", v)} />
);
};
ReactDOM.createRoot(document.getElementById("app")).render();