diff --git a/src/lib/components/CreateStepList.svelte b/src/lib/components/CreateStepList.svelte
index 54a18c8..dad87ed 100644
--- a/src/lib/components/CreateStepList.svelte
+++ b/src/lib/components/CreateStepList.svelte
@@ -12,6 +12,7 @@ import { do_on_key } from '$lib/components/do_on_key.js'
const step_placeholder = "Kartoffeln schälen..."
export let instructions
+export let add_info
let new_step = {
name: "",
@@ -32,6 +33,12 @@ function get_sublist_index(sublist_name, list){
return -1
}
export function remove_list(list_index){
+ if(instructions[list_index].steps.length > 1){
+ const response = confirm("Bist du dir sicher, dass du diese Liste löschen möchtest? Alle Zubereitungsschritte der Liste werden hiermit auch gelöscht.");
+ if(!response){
+ return
+ }
+ }
instructions.splice(list_index, 1);
instructions = instructions //tells svelte to update dom
}
@@ -117,9 +124,23 @@ input::placeholder{
all:unset;
}
-
+li > div{
+ display:flex;
+ flex-direction: row;
+ justify-items: space-between;
+ align-items:center;
+}
+li > div > div:first-child{
+ flex-grow: 1;
+ cursor: pointer;
+}
+li > div > div:last-child{
+ display: flex;
+ flex-direction: row;
+}
input.heading{
all: unset;
+ box-sizing: border-box;
background-color: var(--nord0);
padding: 1rem;
padding-inline: 2rem;
@@ -139,7 +160,7 @@ input.heading:focus-visible
.heading_wrapper{
position: relative;
- width: 300px;
+ width: min(300px, 95dvw);
margin-inline: auto;
transition: 200ms;
}
@@ -152,15 +173,20 @@ input.heading:focus-visible
.heading_wrapper button{
position: absolute;
bottom: -1.5rem;
- right: -5rem;
+ right: -1.5rem;
}
.adder{
margin-inline: auto;
position: relative;
margin-block: 3rem;
- width: 50ch;
+ width: 90%;
border-radius: 20px;
transition: 200ms;
+ background-color: var(--blue);
+ padding: 1.5rem 2rem;
+}
+dialog .adder{
+ width: 400px;
}
.shadow{
box-shadow: 0 0 1em 0.2em rgba(0,0,0,0.3);
@@ -202,17 +228,18 @@ input.heading:focus-visible
font-family: sans-serif;
width: 100%;
font-size: 1.2rem;
- padding: 2rem;
- padding-top: 2.5rem;
border-radius: 20px;
- background-color: var(--blue);
- color: #bbb;
- transition: 200ms;
+ border: 2px solid var(--nord4);
+ border-radius: 30px;
+ padding: 0.5em 1em;
+ color: var(--nord4);
+ transition: 100ms;
}
.add_step p:hover,
.add_step p:focus-visible
{
color: white;
+ scale: 1.02 1.02;
}
dialog{
@@ -239,6 +266,21 @@ dialog h2{
drop-shadow(0 0 1em black)
;
}
+@media screen and (max-width: 500px){
+ dialog h2{
+ margin-top: 2rem;
+ }
+ dialog .adder{
+ width: 85%;
+ padding-inline: 0.5em;
+ }
+ dialog .adder .category{
+ width: 70%;
+ }
+ dialog .adder input::placeholder{
+ font-size: 1.2rem;
+ }
+}
dialog[open]{
animation: show 200ms ease forwards;
}
@@ -250,10 +292,122 @@ dialog[open]{
backdrop-filter: blur(10px);
}
}
+ol li::marker{
+ font-weight: bold;
+ color: var(--blue);
+ font-size: 1.2rem;
+}
+.instructions{
+ flex-basis: 0;
+ flex-grow: 2;
+ background-color: var(--nord5);
+ padding-block: 1rem;
+ padding-inline: 2rem;
+}
+.instructions ol{
+ padding-left: 1em;
+}
+.instructions li{
+ margin-block: 0.5em;
+ font-size: 1.1rem;
+}
+
+.additional_info{
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1em;
+}
+.additional_info > *{
+ flex-grow: 0;
+ overflow: hidden;
+ padding: 1em;
+ background-color: #FAFAFE;
+ box-shadow: 0.3em 0.3em 1em 0.2em rgba(0,0,0,0.3);
+ /*max-width: 30%*/
+}
+.additional_info > div > *:not(h4){
+ line-height: 2em;
+}
+h4{
+ line-height: 1em;
+ margin-block: 0;
+}
+.button_subtle{
+ padding: 0em;
+ animation: unset;
+ margin: 0.2em 0.1em;
+ background-color: transparent;
+ box-shadow: unset;
+ display:inline;
+}
+.button_subtle:hover{
+ scale: 1.2 1.2;
+}
+h3{
+ display:flex;
+ gap: 1rem;
+}
+.additional_info input{
+ all:unset;
+ display: inline;
+ width: 10ch;
+ border-radius: 1000px;
+ border: 2px solid grey;
+ padding: 0em 0.5em;
+}
+.additional_info input::placeholder{
+ color: grey;
+}
+.additional_info p[contenteditable]{
+ display: inline;
+ padding: 0.25em 1em;
+ border: 2px solid grey;
+ border-radius: 1000px;
+}
+.additional_info div:has(p[contenteditable]){
+ transition: 200ms;
+ display: inline;
+}
+.additional_info div:has(p[contenteditable]):hover,
+.additional_info div:has(p[contenteditable]):focus-within
+{
+ transform: scale(1.1, 1.1);
+}
+@media screen and (max-width: 500px){
+ dialog h2{
+ margin-top: 2rem;
+ }
+ dialog .heading_wrapper{
+ width: 80%;
+ }
+}
+
diff --git a/src/lib/js/season_store.js b/src/lib/js/season_store.js
new file mode 100644
index 0000000..e8ab5b8
--- /dev/null
+++ b/src/lib/js/season_store.js
@@ -0,0 +1,3 @@
+import { writable } from 'svelte/store';
+
+export const season = writable([]);
diff --git a/src/models/Recipe.ts b/src/models/Recipe.ts
index 660f632..06f52fc 100644
--- a/src/models/Recipe.ts
+++ b/src/models/Recipe.ts
@@ -16,16 +16,17 @@ const RecipeSchema = new mongoose.Schema(
description: {type: String, required: true},
tags : [String],
season : [Number],
- baking: { temperature: String,
- length: String,
- mode: String,
+ baking: { temperature: {type:String, default: ""},
+ length: {type:String, default: ""},
+ mode: {type:String, default: ""},
},
- preparation : String,
- fermentation: {bulk: String,
- final: String,
+ preparation : {type:String, default: ""},
+ fermentation: { bulk: {type:String, default: ""},
+ final: {type:String, default: ""},
+
},
- portions : String,
- total_time : String,
+ portions :{type:String, default: ""},
+ total_time : {type:String, default: ""},
ingredients : [ { name: {type: String, default: ""},
list: [{name: {type: String, default: ""},
unit: String,
@@ -34,6 +35,7 @@ const RecipeSchema = new mongoose.Schema(
}],
instructions : [{name: {type: String, default: ""},
steps: [String]}],
+ preamble : String,
addendum : String,
},
);
diff --git a/src/routes/rezepte/+layout.svelte b/src/routes/+layout.svelte
similarity index 83%
rename from src/routes/rezepte/+layout.svelte
rename to src/routes/+layout.svelte
index c6883ab..f3d6ccd 100644
--- a/src/routes/rezepte/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -4,10 +4,12 @@ import "$lib/components/nordtheme.css"
diff --git a/src/routes/.jukit/.jukit_info.json b/src/routes/.jukit/.jukit_info.json
new file mode 100644
index 0000000..92c7342
--- /dev/null
+++ b/src/routes/.jukit/.jukit_info.json
@@ -0,0 +1 @@
+{"terminal": "nvimterm"}
\ No newline at end of file
diff --git a/src/routes/api/add/+server.ts b/src/routes/api/add/+server.ts
index 8f0389b..9eec68e 100644
--- a/src/routes/api/add/+server.ts
+++ b/src/routes/api/add/+server.ts
@@ -16,7 +16,7 @@ export const POST: RequestHandler = async ({request}) => {
await dbConnect();
await Recipe.create(recipe_json);
await dbDisconnect();
- return {status: 400} //TODO: cleanup error throwing
+ return {status: 200} //TODO: cleanup error throwing
}
else{
console.log("PASSWORD INCORRECT")
diff --git a/src/routes/api/delete/+server.ts b/src/routes/api/delete/+server.ts
new file mode 100644
index 0000000..fb4c407
--- /dev/null
+++ b/src/routes/api/delete/+server.ts
@@ -0,0 +1,23 @@
+import type { RequestHandler } from '@sveltejs/kit';
+import { Recipe } from '../../../models/Recipe';
+import { dbConnect, dbDisconnect } from '../../../utils/db';
+import type {RecipeModelType} from '../../../types/types';
+import { BEARER_TOKEN } from '$env/static/private'
+// header: use for bearer token for now
+// recipe json in body
+export const POST: RequestHandler = async ({request}) => {
+ let message = await request.json()
+ const short_name = message.old_short_name
+ const bearer_token = message.headers.bearer
+ if(bearer_token === BEARER_TOKEN){
+ console.log("PASSWORD CORRECT")
+ await dbConnect();
+ await Recipe.findOneAndDelete({short_name: short_name});
+ await dbDisconnect();
+ return {status: 400} //TODO: cleanup error throwing
+ }
+ else{
+ console.log("PASSWORD INCORRECT")
+ return {status: 403}
+ }
+};
diff --git a/src/routes/api/edit/+server.ts b/src/routes/api/edit/+server.ts
index c06b814..75de2d4 100644
--- a/src/routes/api/edit/+server.ts
+++ b/src/routes/api/edit/+server.ts
@@ -3,6 +3,7 @@ import { Recipe } from '../../../models/Recipe';
import { dbConnect, dbDisconnect } from '../../../utils/db';
import type {RecipeModelType} from '../../../types/types';
import { BEARER_TOKEN } from '$env/static/private'
+import { error } from '@sveltejs/kit';
// header: use for bearer token for now
// recipe json in body
export const POST: RequestHandler = async ({request}) => {
@@ -10,16 +11,15 @@ export const POST: RequestHandler = async ({request}) => {
let message = await request.json()
const recipe_json = message.recipe
const bearer_token = message.headers.bearer
- console.log("RECIPE:", recipe_json)
- console.log("BEARER:", bearer_token)
if(bearer_token === BEARER_TOKEN){
await dbConnect();
await Recipe.findOneAndUpdate({short_name: message.old_short_name }, recipe_json);
await dbDisconnect();
- return {status: 400} //TODO: cleanup error throwing
+ const res = new Response(JSON.stringify({ message: "Updated Recipe successfully"}), { status: 200 })
+ return res
}
else{
- console.log("PASSWORD INCORRECT")
- return {status: 403}
+ console.log("INCORRECT PASSWORD")
+ throw error(403, "Password incorrect")
}
};
diff --git a/src/routes/api/items/icon/+server.ts b/src/routes/api/items/icon/+server.ts
new file mode 100644
index 0000000..8a8ecbc
--- /dev/null
+++ b/src/routes/api/items/icon/+server.ts
@@ -0,0 +1,13 @@
+import { json, type RequestHandler } from '@sveltejs/kit';
+import { Recipe } from '../../../../models/Recipe';
+import { dbConnect, dbDisconnect } from '../../../../utils/db';
+import type {BriefRecipeType} from '../../../../types/types';
+
+export const GET: RequestHandler = async ({params}) => {
+ await dbConnect();
+ let icons = (await Recipe.distinct('icon').lean());
+ await dbDisconnect();
+
+ icons = JSON.parse(JSON.stringify(icons));
+ return json(icons);
+};
diff --git a/src/routes/api/items/icon/[icon]/+server.ts b/src/routes/api/items/icon/[icon]/+server.ts
new file mode 100644
index 0000000..60be55d
--- /dev/null
+++ b/src/routes/api/items/icon/[icon]/+server.ts
@@ -0,0 +1,13 @@
+import { json, type RequestHandler } from '@sveltejs/kit';
+import { Recipe } from '../../../../../models/Recipe';
+import { dbConnect, dbDisconnect } from '../../../../../utils/db';
+import type {BriefRecipeType} from '../../../../../types/types';
+
+export const GET: RequestHandler = async ({params}) => {
+ await dbConnect();
+ let recipes = (await Recipe.find({tags: params.icon}, 'name short_name images tags category icon description season').lean()) as BriefRecipeType[];
+ await dbDisconnect();
+
+ recipes = JSON.parse(JSON.stringify(recipes));
+ return json(recipes);
+};
diff --git a/src/routes/api/seed/+server.ts b/src/routes/api/seed/+server.ts
index dda6d3e..720f139 100644
--- a/src/routes/api/seed/+server.ts
+++ b/src/routes/api/seed/+server.ts
@@ -16,10 +16,12 @@ const test_json = [
caption: "",
}],
description: "Alles was das Bauernherz erfreuen lässt in einer Mahlzeit.",
- tags: ["Schweiz", "Käse", "Speck", "Nudeln", "Apfelmuß", "Kartoffeln"],
- season: [6,7,8,9,10,11,12,1],
+ preamble: "Dieser Schweizer Klassiker ist wohl das beste Essen nach einem langen Tag von Skifahren. Die Beilage aus Apfelmus ist ein Muss.",
+ tags: ["Schweiz", "Käse", "Speck", "Nudeln", "Apfelmuß", "Kartoffeln", "Fleisch"],
+ season: [10,11,12,1],
portions: "4 Hauptspeisen",
- total_time: "30 Minuten",
+ preparation: "10 min",
+ total_time: "30 min",
ingredients: [ {
name: "",
list: [
diff --git a/src/routes/api/seed/json/aelplermagronen.js b/src/routes/api/seed/json/aelplermagronen.js
new file mode 100644
index 0000000..39bdac8
--- /dev/null
+++ b/src/routes/api/seed/json/aelplermagronen.js
@@ -0,0 +1,77 @@
+const obj =
+{
+ short_name: "aelplermagronen",
+ name : "Älplermagronen",
+ category: "Hauptspeise",
+ icon: "🍂",
+ datecreated: 20230619,
+ datemodified: 20230619,
+ images: [{
+ mediapath: "aelplermagronen.webp",
+ alt: "Älplermagronen serviert mit Apfelmuß",
+ caption: "",
+ }],
+ description: "Alles was das Bauernherz erfreuen lässt in einer Mahlzeit.",
+ tags: ["Schweiz", "Käse", "Speck", "Nudeln", "Apfelmuß", "Kartoffeln"],
+ season: [6,7,8,9,10,11,12,1],
+ portions: "4 Hauptspeisen",
+ total_time: "30 Minuten",
+ ingredients: [ {
+ name: "",
+ list: [
+ { name: "Speckwürfel",
+ unit: "g",
+ amount: "150"
+ },
+ {
+ name: "mittelgroße Zwiebeln",
+ unit: "",
+ amount: "3",
+ },
+ {
+ name: "Kartoffeln, festkochend",
+ unit: "g",
+ amount: "400",
+ },
+ {
+ name: "Milch",
+ unit: "L",
+ amount: "1-2",
+ },
+ {
+ name: "Maccaroni",
+ unit: "g",
+ amount: "400",
+ },
+ {
+ name: "Appenzeller",
+ unit: "g",
+ amount: "150",
+ },
+ {
+ name: "
Apfelmuß",
+ unit: "",
+ amount: "",
+ },
+
+ ]},
+ ],
+ instructions: [
+ {name: "",
+ steps: [
+ "In einem großen Topf oder tiefer Pfanne Speckwürfel anbraten.",
+ "Zwiebel in Halbringe schneiden und im gleichen Topf schwitzen lassen.",
+ "Kartoffeln schälen und in ~1 cm
3 schneiden.",
+ "Wenn Ziwebeln genügend gekocht sind die Kartoffeln hinzufügen und Milch hinzufügen, sodass alles bedeckt ist. Ca. 10 Minuten kochen lassen.",
+ "Ca. 1 L Milch hinzugeben. Für den nächsten Schritt wollen wir die Maccaroni hinzufügen. Damit diese nicht zu breiig werden geben wir erst die Milch zu und lassen sie aufkochen.",
+ "Wenn die der Topf wieder kocht jetzt die Maccaroni hinzugeben.",
+ "Den Käse zerreiben oder in kleine Würfel schneiden.",
+ "Ein bis zwei Minuten bevor die Nudeln durchgekocht sind den Käse hinzugeben und schmelzen lassen.",
+ "Mit Salz und Muskat würzen.",
+ "Den Topf ein bisschen zu früh vom Herd nehmen und ein bisschen auskühlen lassen.",
+ "Mit
Apfelmuß oder Apfelkompott servieren."
+ ]
+ }
+ ],
+ addendum: "
Man kann das Gericht noch dekanter machen indem man zu Teilen Rahm an Stelle von Milch verwendet. Zudem kann man das ganze auch noch in eine Auflaufform geben und im Ofen eine Kruste anbacken
",
+}
diff --git a/src/routes/api/seed/json/template.js b/src/routes/api/seed/json/template.js
new file mode 100644
index 0000000..0eb137d
--- /dev/null
+++ b/src/routes/api/seed/json/template.js
@@ -0,0 +1,50 @@
+const obj =
+{
+ short_name: "<++>",
+ name : "<++>",
+ category: "<++>",
+ icon: "<++>",
+ datecreated: 20230619,
+ datemodified: 20230619,
+ images: [{
+ mediapath: "<++>.webp",
+ alt: "<++>",
+ caption: "<++>",
+ }],
+ description: "<++>",
+ tags: [<++>],
+ season: [<++>],
+ baking: {
+ temperature: "<++>",
+ length: "<++>",
+ mode: "<++>",
+ },
+ preparation: "<++>",
+ fermentation: {
+ bulk: "<++>",
+ final: "<++>"
+ },
+ portions: "<++>",
+ total_time: "<++>",
+ ingredients: [ {
+ name: "<++>",
+ list: [
+ { name: "<++>",
+ unit: "<++>",
+ amount: <++>,
+ },
+ {
+ name: "<++>",
+ unit: "<++>",
+ amount: <++>,
+ },
+ ]},
+ ],
+ instructions: [
+ {name: "<++>",
+ steps: [
+ "<++>",
+ "<++>"
+ ]
+ }
+ ]}
diff --git a/src/routes/rezepte/+page.svelte b/src/routes/rezepte/+page.svelte
index 5226dd8..5aaf776 100644
--- a/src/routes/rezepte/+page.svelte
+++ b/src/routes/rezepte/+page.svelte
@@ -8,7 +8,6 @@
export let data: PageData;
export let current_month = new Date().getMonth() + 1
-
Rezepte
In Saison
diff --git a/src/routes/rezepte/[name]/+page.svelte b/src/routes/rezepte/[name]/+page.svelte
index 2f9a1df..e899af8 100644
--- a/src/routes/rezepte/[name]/+page.svelte
+++ b/src/routes/rezepte/[name]/+page.svelte
@@ -6,19 +6,42 @@
import "$lib/components/nordtheme.css"
import MultiImgWrapper from './MultiImgWrapper.svelte'
import EditButton from '$lib/components/EditButton.svelte';
+ import InstructionsPage from '$lib/components/InstructionsPage.svelte';
+ import IngredientsPage from '$lib/components/IngredientsPage.svelte';
export let data: PageData;
+ let hero_img_src = "/images/" + data.images[0].mediapath
export let months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
function season_intervals() {
let interval_arr = []
- let start = 0
- for(var i = 0; i < data.season.length - 1; i++)
- {
- if(Math.abs(data.season[i] - data.season[i + 1])%11 > 1){
- interval_arr.push([data.season[start], data.season[i]])
- start=i+1
+
+
+ let start_i = 0
+ for(var i = 12; i > 0; i--){
+ if(data.season.includes(i)){
+ start_i = data.season.indexOf(i);
+ }
+ else{
+ break
}
}
- interval_arr.push([data.season[start], data.season[data.season.length -1]])
+
+ var start = data.season[start_i]
+ var end_i
+ const len = data.season.length
+ for(var i = 0; i < len -1; i++){
+ if(data.season.includes((start + i) %12 + 1)){
+ end_i = (start_i + i + 1) % len
+ }
+ else{
+ interval_arr.push([start, data.season[end_i]])
+ start = data.season[(start + i + 1) % len]
+ }
+
+ }
+ if(interval_arr.length == 0){
+ interval_arr.push([start, data.season[end_i]])
+ }
+
return interval_arr
}
export let season_iv = season_intervals();
@@ -29,20 +52,16 @@ font-family: sans-serif;
}
h1{
text-align: center;
- padding: 0.5em 2em;
+ padding-block: 0.5em;
border-radius: 10000px;
margin:0;
font-size: 3rem;
}
-.wrapper{
- margin-inline: auto;
- max-width: 700px;
- padding-inline: 2rem;
-}
.tags{
margin-block: 1rem;
display: flex;
flex-direction: row;
+ align-items: center;
flex-wrap: wrap;
gap: 1em;
}
@@ -64,12 +83,109 @@ h1{
background-color: var(--orange);
box-shadow: 0.1em 0.1em 0.2em 0.2em rgba(0,0,0,0.3);
}
+
+.wrapper{
+ display: flex;
+ flex-direction: row;
+ max-width: 1000px;
+ justify-content: center;
+ margin-inline: auto;
+}
+
+@media screen and (max-width: 700px){
+ .wrapper{
+ flex-direction:column;
+ }
+}
+
+.title_container{
+ max-width: 1000px;
+ display: flex;
+ flex-direction: column;
+ margin-inline: auto;
+}
+.title{
+ position: relative;
+ width: min(800px, 80vw);
+ margin-inline: auto;
+ transform: translateY(-4rem);
+ background-color: var(--nord6);
+ padding: 1rem 2rem;
+}
+.title_container .img{
+ width: 100%;
+ height: 700px;
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+.icon{
+ position: absolute;
+ top: -1em;
+ right: -0.75em;
+ text-decoration: unset;
+ background-color: #FAFAFE;
+ padding: 0.5em;
+ font-size: 1.5rem;
+ border-radius: 100000px;
+ transition: 100ms;
+ box-shadow: 0em 0em 1em 0.5em rgba(0,0,0,0.5);
+}
+.icon:hover,
+.icon:focus-visible{
+ scale: 1.2 1.2;
+ animation: shake 0.5s ease forwards;
+}
+
+h4{
+ margin-block: 0;
+}
+.addendum{
+ max-width: 800px;
+ margin-inline: auto;
+ padding-inline: 2rem;
+}
+@media screen and (max-width: 800px){
+ .title{
+ width: 100%;
+ }
+ .icon{
+ right: 1rem;
+ }
+}
+@keyframes shake{
+ 0%{
+ transform: rotate(0)
+ scale(1,1);
+ }
+ 25%{
+ box-shadow: 0em 0em 1em 0.2em rgba(0, 0, 0, 0.6);
+ transform: rotate(var(--angle))
+ scale(1.2,1.2)
+ ;
+ }
+ 50%{
+
+ box-shadow: 0em 0em 1em 0.2em rgba(0, 0, 0, 0.6);
+ transform: rotate(calc(-1* var(--angle)))
+ scale(1.2,1.2);
+ }
+ 74%{
+
+ box-shadow: 0em 0em 1em 0.2em rgba(0, 0, 0, 0.6);
+ transform: rotate(var(--angle))
+ scale(1.2, 1.2);
+ }
+ 100%{
+ transform: rotate(0)
+ scale(1.2,1.2);
+ }
+ }
+
-
-
{data.name}
-
1} class=double>
+
+
+
+
+
+
{data.icon}
+
{data.name}
+{#if data.preamble}
+
{data.preamble}
+{/if}
+
Stichwörter:
+
+
-{#if data.preparation}
-Vorbereitung: {data.preparation}
-{/if}
-
-
-{#if data.fermentation}
- {#if data.fermentation.bulk}
- Stockgare: {data.fermentation.bulk}
- {/if}
-
- {#if data.fermentation.final}
- Stückgare: {data.fermentation.final}
- {/if}
-{/if}
-
-{#if data.baking}
-Backen: {data.baking.length} bei {data.baking.temperature} °C {data.baking.mode}
-{/if}
-
-{#if data.total_time}
-Gesamtzeit: {data.total_time}
-{/if}
-
-
-{#if data.ingredients}
-Zutaten
-{#each data.ingredients as list}
-{#if list.name}
- {list.name}
-{/if}
-
- {#each list.list as item}
- - {item.amount} {item.unit} {@html item.name}
- {/each}
-
-{/each}
-{/if}
-
-
-{#if data.instructions}
-Zubereitung
-{#each data.instructions as list}
-{#if list.name}
- {list.name}
-{/if}
-
- {#each list.steps as step}
- - {@html step}
- {/each}
-
-{/each}
-{/if}
+
+
+
+
+
{#if data.addendum}
{@html data.addendum}
{/if}
diff --git a/src/routes/rezepte/add/+page.svelte b/src/routes/rezepte/add/+page.svelte
index 73d66fe..67b5b3a 100644
--- a/src/routes/rezepte/add/+page.svelte
+++ b/src/routes/rezepte/add/+page.svelte
@@ -1,39 +1,92 @@
-
Rezept hinzufügen
+
Rezept erstellen
-
+
Kurzname (für URL):
+
-
+
+
+
Eine etwas längere Beschreibung:
+
+
+
Saison:
+
+
+
+
-
Zutaten
-
-
Zubereitung
-
-
-
+
+
+
+
+
+
Neues Rezept hinzufügen:
+
+
+
diff --git a/src/routes/rezepte/edit/[name]/+page.svelte b/src/routes/rezepte/edit/[name]/+page.svelte
index 26af762..c1dba06 100644
--- a/src/routes/rezepte/edit/[name]/+page.svelte
+++ b/src/routes/rezepte/edit/[name]/+page.svelte
@@ -1,5 +1,21 @@
-
Rezept hinzufügen
+
Rezept editieren
-
-
-
+
+
Kurzname (für URL):
-
Zutaten
-
-
Zubereitung
-
+
+
+
+
Eine etwas längere Beschreibung:
+
+
+
Saison:
+
+
+
+
+
+
+
+
+
+
+
+
Editiertes Rezept abspeichern:
-
+
+
+
+
+
Rezept löschen:
+
+
+
diff --git a/src/types/types.ts b/src/types/types.ts
index 6e10107..17110ac 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -38,6 +38,7 @@ export type RecipeModelType = {
name?: string;
steps: [string]
}]
+ preamble?: String
addendum?: string
};