commit cf1c226944f076c6d2f882da335bb37f4cc98dca Author: ella Date: Fri Apr 17 17:24:20 2026 +0200 update zutatenliste diff --git a/index.html b/index.html new file mode 100644 index 0000000..6c5a0cb --- /dev/null +++ b/index.html @@ -0,0 +1,68 @@ + + + + + + Kartoffelsalat-Rechner + + + + +
+
+ + +
+
+ +
+
+
+

Rezept für "":

+
    + +
+ + +
+
+
+ + diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..dea96ec --- /dev/null +++ b/js/main.js @@ -0,0 +1,125 @@ +import Alpine from "https://unpkg.com/alpinejs@3.15.4/dist/module.esm.js"; +window.Alpine = Alpine; +Alpine.data("daten", () => ({ + zutaten: [ + { gruppe: "Grundzutaten" }, + { name: "Kartoffeln", einheit: "g", faktor: 200 }, + { name: "Nudeln", einheit: "g", faktor: 50 }, + { name: "Salatgurke", einheit: "x", faktor: 0.5, runde: 10 }, + { name: "Saure Gurke", einheit: "x", faktor: 2 }, + { name: "Mayonnaise", einheit: "g", faktor: 20 }, + { name: "Senf", einheit: " EL", faktor: 1.4 }, + { name: "Ketchup", einheit: " EL", faktor: 1.4 }, + { name: "Saure Sahne", einheit: "ml", faktor: 100 }, + { gruppe: "Früchte" }, + { name: "Birne", einheit: "x", faktor: 1 }, + { name: "Apfel", einheit: "x", faktor: 1 }, + { name: "Rote Beete", einheit: " Knolle/n", faktor: 1 }, + { name: "Mandarine", einheit: "x", faktor: 1 }, + { name: "Ananas", einheit: "g", faktor: 50 }, + { name: "Mango", einheit: "g", faktor: 50 }, + { gruppe: "Fleischanteil" }, + { name: "Fleischwurst", einheit: "g", faktor: 200 }, + { name: "Hackfleisch", einheit: "g", faktor: 250 }, + { name: "Bratwurst", einheit: "x", faktor: 1 }, + { name: "Hering", einheit: "g", faktor: 150 }, + { name: "Thunfisch", einheit: "g", faktor: 100 }, + { name: "Lachs", einheit: "g", faktor: 100 }, + { name: "Mehlwürmer" }, + { gruppe: "Milchprodukte" }, + { name: "Käse", einheit: "g", faktor: 100 }, + { name: "Sahne", einheit: "ml", faktor: 100 }, + { gruppe: "Special Gewürze" }, + { name: "Knoblauch", einheit: " Zehe/n", faktor: 1 }, + { name: "Chili", einheit: " Scoville", faktor: 10_000}, + { gruppe: "Sonstiges" }, + { name: "Champignons", einheit: "g", faktor: 100 }, + { name: "Eier", einheit: "", faktor: 1 }, + { name: "Zwiebeln", einheit: "g", faktor: 100 }, + { name: "Tomaten stückig", einheit: "g", faktor: 200 }, + { name: "Meeresfrüchte" }, + { name: "Rucola", einheit: "g", faktor: 150 }, + { name: "Erbsen", einheit: "g", faktor: 100 }, + { name: "Spargel", einheit: " Stange/n", faktor: 1 }, + { name: "Oliven", einheit: "g", faktor: 50 }, + { name: "Kopfsalat", einheit: " Blätter", faktor: 1 }, + ], + filter: "", + init() { + this.zutaten.forEach((z, index) => { + if (z.name) { + z.menge = 0; + z.id = index; + } + }); + }, + reset() { + this.filter = ""; + for (let index = 0; index < this.zutaten.length; index++) { + const zutat = this.zutaten[index]; + if (zutat.menge && zutat.menge > 0) { + zutat.menge = 0; + } + } + }, + get zutaten_filter() { + if (this.filter.length == 0) { + return this.zutaten; + } + let filtered = this.zutaten.filter((z) => { + return ( + z.gruppe || + (z.name && z.name.toLowerCase().includes(this.filter.toLowerCase())) + ); + }); + return filtered; + }, + menge(delta, id) { + let zutat = this.zutaten.find((z) => z.id == id); + zutat.menge = Math.max(0, Math.min(zutat.menge + delta, 10)); + }, + get rezept() { + let ausgabe = []; + for (let i = 0; i < this.zutaten.length; i++) { + const zutat = this.zutaten[i]; + if (zutat.menge > 0 && zutat.einheit) { + let faktor = zutat.faktor ?? 1; + let runde = zutat.runde ?? 1; + ausgabe.push( + `${Math.round(zutat.menge * faktor * runde) / runde}${zutat.einheit} ${zutat.name}`, + ); + } + } + return ausgabe; + }, + get rezeptname() { + let zutaten = this.zutaten.reduce( + (a, v) => ({ ...a, [v.name]: v.menge }), + {}, + ); + let gesamt = Object.values(zutaten).reduce((a, b) => { + if (b) { + return a + b; + } else { + return a; + } + }, 0); + if (zutaten["Salatgurke"] >= 5 && zutaten["Senf"] >= 6 && gesamt < 15) { + return "Senfgurken"; + } else if ( + zutaten["Hackfleisch"] >= 2 && + zutaten["Nudeln"] >= 3 && + zutaten["Tomaten stückig"] >= 2 + ) { + return "Spaghetti Bolognese"; + } else if ( + zutaten["Ketchup"] >= 3 && + zutaten["Mayonnaise"] >= 3 && + zutaten["Kartoffeln"] >= 1 + ) { + return "Pommes Rot-Weiß"; + } + return "Kartoffelsalat"; + }, +})); +Alpine.start(); diff --git a/style.css b/style.css new file mode 100644 index 0000000..461f658 --- /dev/null +++ b/style.css @@ -0,0 +1,115 @@ +body { + font-family: sans-serif; + margin: 0; +} +.window { + display: flex; + flex-wrap: wrap; + gap: 2rem; + margin: 1rem; + margin-top: 0; + @media (max-width: 650px) { + flex-direction: column; + } + .recipe { + min-width: 15rem; + flex-grow: 1; + position: sticky; + position: -webkit-sticky; + align-self: flex-start; + background: white; + top: 6rem; + .title { + text-align: center; + } + } + .actionbar { + width: 100%; + display: flex; + gap: 1rem; + flex-wrap: wrap; + align-items: center; + position: sticky; + top: 0; + background: white; + padding: 1rem; + border-bottom: 1pt lightgray solid; + @media print { + display: none; + } + } +} +.title { + margin: 0; + font-size: 1.3em; +} +.grid { + width: min(100%, 806px); + display: grid; + gap: 0.5rem; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + + .grid-element { + min-height: 1rem; + & > .zutat { + border-radius: 0.5rem; + padding: 1rem 0.5rem; + box-shadow: 3px 3px 2px 0px rgba(0, 0, 0, 0.2); + border: 1pt solid silver; + border-bottom: none; + border-right: none; + } + + .flexbox { + margin-top: 0.5rem; + display: flex; + justify-content: space-between; + color: #666; + .bold { + color: black; + font-weight: bold; + } + } + } + @media print { + display: none; + } +} +.grid-element:has(.heading) { + grid-column: -1/1; + border-bottom: 1pt solid hsl(0, 0%, 80%); +} + +button { + border-radius: 0.5rem; + cursor: pointer; + background-color: transparent; + outline: 2pt solid rgba(0, 0, 0, 0.2); + border: 1pt solid silver; + font-size: 1.2em; + font-weight: bold; + &.plus, + &.minus { + width: 2rem; + height: 2rem; + } + &.plus { + outline-color: oklch(66.442% 0.22551 142.585 / 0.3); + } + &.minus { + outline-color: oklch(66.442% 0.22551 41.6 / 0.3); + } +} +button:focus, +button:hover { + transition: 200ms background-color ease; + outline-offset: -1pt; + background-color: rgba(0, 0, 0, 0.025); +} + +.search { + border-radius: 0.5rem; + max-width: 300px; + padding: .2rem; + /* border: 1pt solid silver; */ +} \ No newline at end of file