Does not work: uploading images

Adding/Editing/Deleting works
SeasonsSelect works
Nice recipe layout
This commit is contained in:
2023-06-24 15:31:10 +02:00
parent 3d0d3f41e2
commit 9392ff6ada
25 changed files with 1150 additions and 209 deletions

View File

@ -19,7 +19,11 @@ background-color: var(--red);
display: grid;
justify-content: center;
align-content: center;
}
@media screen and (max-width: 500px) {
.container{
margin: 1rem;
}
}
:global(.icon_svg){
width: 2rem;

View File

@ -215,12 +215,19 @@ input::placeholder{
color:var(--nord0);
}
.card .description{
box-sizing:border-box;
border: 2px solid var(--nord5);
border-radius: 30px;
padding-inline: 1em;
padding-block: 0.5em;
margin-inline: 1em;
margin-top: 0;
color: var(--nord4);
width: calc(300px - 2em); /*??*/
}
.card .description:hover{
color: var(--nord0);
border: 2px solid var(--nord0);
}
.card .tags{
display: flex;
@ -354,7 +361,7 @@ input::placeholder{
<input class=category placeholder=Kategorie... bind:value={card_data.category}/>
<div>
<input class=name placeholder=Name... bind:value={card_data.name}/>
<input class=description placeholder=Kurzbeschreibung... bind:value={card_data.description}/>
<p contenteditable class=description placeholder=Kurzbeschreibung... bind:innerText={card_data.description}></p>
</div>
<div class=tags>
{#each card_data.tags as tag}

View File

@ -10,6 +10,7 @@ import "$lib/css/action_button.css"
import { do_on_key } from '$lib/components/do_on_key.js'
export let ingredients
export let portions
let new_ingredient = {
amount: "",
@ -107,7 +108,6 @@ export function show_keys(event){
</script>
<style>
input::placeholder{
all:unset;
}
@ -117,6 +117,7 @@ input{
input.heading{
all: unset;
box-sizing: border-box;
background-color: var(--nord0);
padding: 1rem;
padding-inline: 2rem;
@ -146,13 +147,14 @@ input.heading:hover{
.heading_wrapper button{
position: absolute;
bottom: -1.5rem;
right: -5rem;
right: -2rem;
}
.adder{
box-sizing: border-box;
margin-inline: auto;
position: relative;
margin-block: 3rem;
width: 400px;
width: 90%;
border-radius: 20px;
transition: 200ms;
}
@ -269,32 +271,11 @@ dialog h2{
drop-shadow(0 0 1em black)
;
}
ul{
width: fit-content;
margin-inline: auto;
}
li{
font-size: 1.2rem;
max-width: 1000px;
align-items: center;
}
.li_wrapper{
display: flex;
justify-content: space-between;
}
.mod_icons{
display: flex;
flex-direction: row;
margin-left: 2rem;
}
li:nth-child(2n){
background-color: var(--nord4);
}
li:nth-child(2n+1){
background-color: var(--nord6);
}
.button_subtle{
padding: 0em;
animation: unset;
@ -306,16 +287,64 @@ li:nth-child(2n+1){
scale: 1.2 1.2;
}
h3{
margin-inline: auto;
width: fit-content;
display: flex;
flex-direction: row;
max-width: 1000px;
justify-content: space-between;
}
.ingredients_grid{
box-sizing: border-box;
display: grid;
font-size: 1.1em;
grid-template-columns: 2fr 3fr 1fr;
grid-template-rows: auto;
grid-auto-flow: row;
align-items: center;
row-gap: 0.5em;
column-gap: 0.5em;
}
.ingredients_grid > *{
cursor: pointer;
}
.ingredients_grid>*:nth-child(3n+1){
min-width: 5ch;
}
.list_wrapper{
padding-inline: 2em;
padding-block: 1em;
}
.list_wrapper p[contenteditable]{
border: 2px solid grey;
border-radius: 1000px;
padding: 0.25em 1em;
background-color: white;
transition: 200ms;
}
.list_wrapper p[contenteditable]:hover,
.list_wrapper p[contenteditable]:focus-within{
scale: 1.05 1.05;
}
@media screen and (max-width: 500px){
dialog h2{
margin-top: 2rem;
}
dialog .heading_wrapper{
width: 80%;
}
.ingredients_grid .mod_icons{
margin-left: 0;
}
}
</style>
<div class=list_wrapper>
<h4>Portionen:</h4>
<p contenteditable type="text" bind:innerText={portions}></p>
<h2>Zutaten</h2>
{#each ingredients as list, list_index}
<h3>
<div>
@ -326,26 +355,23 @@ h3{
{/if}
</div>
<div class=mod_icons>
<button class="action_button button_subtle" on:click="{() => show_modal_edit_subheading_ingredient(list_index)}">
<button class="action_button button_subtle" on:click="{() => show_modal_edit_subheading_ingredient(list_index)}">
<Pen fill=var(--nord1)></Pen> </button>
<button class="action_button button_subtle" on:click="{() => remove_list(list_index)}">
<Cross fill=var(--nord1)></Cross>
</button>
<Cross fill=var(--nord1)></Cross></button>
</div>
</h3>
<ul>
<div class=ingredients_grid>
{#each list.list as ingredient, ingredient_index}
<li><div class=li_wrapper><div>{ingredient.amount} {ingredient.unit} {ingredient.name}</div>
<div on:click={() => show_modal_edit_ingredient(list_index, ingredient_index)} >{ingredient.amount} {ingredient.unit}</div>
<div on:click={() => show_modal_edit_ingredient(list_index, ingredient_index)} >{ingredient.name}</div>
<div class=mod_icons><button class="action_button button_subtle" on:click={() => show_modal_edit_ingredient(list_index, ingredient_index)}>
<Pen fill=var(--nord1) height=1em width=1em></Pen>
</button>
<button class="action_button button_subtle" on:click="{() => remove_ingredient(list_index, ingredient_index)}">
<Cross fill=var(--nord1) height=1em width=1em></Cross>
</button></div></div>
</li>
<Pen fill=var(--nord1) height=1em width=1em></Pen></button>
<button class="action_button button_subtle" on:click="{() => remove_ingredient(list_index, ingredient_index)}"><Cross fill=var(--nord1) height=1em width=1em></Cross></button></div>
{/each}
</ul>
</div>
{/each}
</div>
<div class="adder shadow">
<input class=category type="text" bind:value={new_ingredient.sublist} placeholder="Kategorie (optional)" on:keypress={(event) => do_on_key(event, 'Enter', false, add_new_ingredient)}>
@ -358,7 +384,6 @@ h3{
</button>
</div>
</div>
<dialog id=edit_ingredient_modal>
<h2>Zutat verändern</h2>
<div class=adder>

View File

@ -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%;
}
}
</style>
<div class=instructions>
<div class=additional_info>
<div><h4>Vorbereitung:</h4>
<p contenteditable type="text" bind:innerText={add_info.preparation}></p>
</div>
<div><h4>Stockgare:</h4>
<p contenteditable type="text" bind:innerText={add_info.fermentation.bulk}></p>
</div>
<div><h4>Stückgare:</h4>
<p contenteditable type="text" bind:innerText={add_info.fermentation.final}></p>
</div>
<div><h4>Backen:</h4>
<div><p type="text" bind:innerText={add_info.baking.length} contenteditable placeholder="40 min..."></p></div> bei <div><p type="text" bind:innerText={add_info.baking.temperature} contenteditable placeholder=200...></p></div> °C <div><p type="text" bind:innerText={add_info.baking.mode} contenteditable placeholder="Ober-/Unterhitze..."></p></div></div>
<div><h4>Auf dem Teller:</h4>
<div><p contenteditable type="text" bind:innerText={add_info.total_time}></p></div>
</div>
</div>
<h2>Zubereitung</h2>
{#each instructions as list, list_index}
<h3>
{#if list.name}
@ -261,31 +415,34 @@ dialog[open]{
{:else}
Leer
{/if}
<button class=edit on:click="{() => show_modal_edit_subheading_step(list_index)}">
<Pen></Pen> </button>
<button class=remove on:click="{() => remove_list(list_index)}">
<Cross></Cross>
<div>
<button class="action_button button_subtle" on:click="{() => show_modal_edit_subheading_step(list_index)}">
<Pen fill=var(--nord1)></Pen> </button>
<button class="action_button button_subtle" on:click="{() => remove_list(list_index)}">
<Cross fill=var(--nord1)></Cross>
</button>
</div>
</h3>
<ol>
{#each list.steps as step, step_index}
<li>{step}
<button class=edit on:click={() => show_modal_edit_step(list_index, step_index)}>
<Pen></Pen>
<li><div><div on:click={() => show_modal_edit_step(list_index, step_index)}>{step}</div>
<div><button class="action_button button_subtle" on:click={() => show_modal_edit_step(list_index, step_index)}>
<Pen fill=var(--nord1)></Pen>
</button>
<button class=remove on:click="{() => remove_step(list_index, step_index)}">
<Cross></Cross>
<button class="action_button button_subtle" on:click="{() => remove_step(list_index, step_index)}">
<Cross fill=var(--nord1)></Cross>
</button>
</div></div>
</li>
{/each}
</ol>
{/each}
</div>
<div class='adder shadow'>
<input class=category type="text" bind:value={new_step.name} placeholder="Kategorie (optional)"on:keypress={(event) => do_on_key(event, 'Enter', false , add_new_step)} >
<div class=add_step>
<p id=step contenteditable on:focus='{clear_step}' on:blur={add_placeholder} bind:innerHTML={new_step.step} on:keypress={(event) => do_on_key(event, 'Enter', true , add_new_step)}></p>
<p id=step contenteditable on:focus='{clear_step}' on:blur={add_placeholder} bind:innerText={new_step.step} on:keypress={(event) => do_on_key(event, 'Enter', true , add_new_step)}></p>
<button on:click={() => add_new_step()} class=action_button>
<Plus fill=white style="height: 2rem; width: 2rem"></Plus>
</button>

View File

@ -0,0 +1,45 @@
<script>
export let data
</script>
<style>
*{
font-family: sans-serif;
}
.ingredients{
flex-basis: 0;
flex-grow: 1;
padding-block: 1rem;
padding-inline: 2rem;
}
.ingredients_grid{
display: grid;
font-size: 1.1rem;
grid-template-columns: 1fr 3fr;
grid-template-rows: auto;
grid-auto-flow: row;
row-gap: 0.5em;
column-gap: 0.5em;
}
h4{
margin-block: 0;
}
</style>
{#if data.ingredients}
<div class=ingredients>
{#if data.portions}
<h4>Portionen:</h4>
{data.portions}
{/if}
<h2>Zutaten</h2>
{#each data.ingredients as list}
{#if list.name}
<h3>{list.name}</h3>
{/if}
<div class=ingredients_grid>
{#each list.list as item}
<div class=amount>{item.amount} {item.unit}</div><div class=name>{@html item.name}</div>
{/each}
</div>
{/each}
</div>
{/if}

View File

@ -0,0 +1,90 @@
<script>
export let data
</script>
<style>
*{
font-family: sans-serif;
}
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;
padding: 1em;
background-color: #FAFAFE;
box-shadow: 0.3em 0.3em 1em 0.2em rgba(0,0,0,0.3);
max-width: 30%
}
@media screen and (max-width: 500px){
.additional_info > *{
max-width: 60%;
}
}
h4{
margin-block: 0;
}
</style>
<div class=instructions>
<div class=additional_info>
{#if data.preparation}
<div><h4>Vorbereitung:</h4>{data.preparation}</div>
{/if}
{#if data.fermentation}
{#if data.fermentation.bulk}
<div><h4>Stockgare:</h4>{data.fermentation.bulk}</div>
{/if}
{#if data.fermentation.final}
<div><h4>Stückgare:</h4> {data.fermentation.final}</div>
{/if}
{/if}
{#if data.baking.temperature}
<div><h4>Backen:</h4> {data.baking.length} bei {data.baking.temperature} °C {data.baking.mode}</div>
{/if}
{#if data.total_time}
<div><h4>Auf dem Teller:</h4>{data.total_time}</div>
{/if}
</div>
{#if data.instructions}
<h2>Zubereitung</h2>
{#each data.instructions as list}
{#if list.name}
<h3>{list.name}</h3>
{/if}
<ol>
{#each list.steps as step}
<li>{@html step}</li>
{/each}
</ol>
{/each}
{/if}
</div>

View File

@ -5,7 +5,6 @@
onMount(() => {
const recipes = document.querySelectorAll(".search_me");
console.log("######", recipes)
const search = document.getElementById("search");
const clearSearch = document.getElementById("clear-search");

View File

@ -1,9 +1,16 @@
<script lang=ts>
import "$lib/components/nordtheme.css"
import { season } from '$lib/js/season_store.js'
import {onMount} from "svelte";
let months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
export let season : Number[]
let season_local
season.subscribe((s) => {
season_local = s
});
export function set_season(){
let temp = []
@ -13,18 +20,18 @@ export function set_season(){
temp.push(i+1)
}
}
season = temp
season.update((s) => temp)
}
function write_season(season){
const el = document.getElementById("labels");
for(var i = 0; i < season.length; i++){
el.children[i].children[0].children[0].checked = true
el.children[season[i]-1].children[0].children[0].checked = true
}
}
onMount(() => {
write_season(season)
write_season(season_local)
});
</script>
@ -75,6 +82,3 @@ input[type=checkbox]::after
</div>
{/each}
</div>
<button on:click={() => console.log("season", season)}> PRINT SEASON FROM SEASON_SELECT</button>