2023-06-22 20:26:48 +02:00
< script lang = 'ts' >
import Pen from '$lib/assets/icons/Pen.svelte'
import Cross from '$lib/assets/icons/Cross.svelte'
import Plus from '$lib/assets/icons/Plus.svelte'
import Check from '$lib/assets/icons/Check.svelte'
import '$lib/components/nordtheme.css'
2023-06-23 17:23:14 +02:00
import "$lib/css/action_button.css"
import { do_on_key } from '$lib/components/do_on_key.js'
2023-06-22 20:26:48 +02:00
const step_placeholder = "Kartoffeln schälen..."
2023-06-23 17:23:14 +02:00
export let instructions
2023-06-24 15:31:10 +02:00
export let add_info
2023-06-22 20:26:48 +02:00
let new_step = {
name: "",
2023-06-23 17:23:14 +02:00
step: step_placeholder
2023-06-22 20:26:48 +02:00
}
let edit_heading = {
name:"",
list_index: "",
}
function get_sublist_index(sublist_name, list){
for(var i =0; i < list.length ; i ++) {
if(list[i].name == sublist_name){
return i
}
}
return -1
}
export function remove_list(list_index){
2023-06-24 15:31:10 +02:00
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
}
}
2023-06-22 20:26:48 +02:00
instructions.splice(list_index, 1);
instructions = instructions //tells svelte to update dom
}
export function add_new_step(){
2023-06-23 17:23:14 +02:00
if(new_step.step == step_placeholder){
return
}
2023-06-22 20:26:48 +02:00
let list_index = get_sublist_index(new_step.name, instructions)
if(list_index == -1){
instructions.push({
name: new_step.name,
steps: [ new_step.step ],
})
list_index = instructions.length - 1
}
else{
instructions[list_index].steps.push(new_step.step)
}
const el = document.querySelector("#step")
el.innerHTML = step_placeholder
instructions = instructions //tells svelte to update dom
}
export function remove_step(list_index, step_index){
instructions[list_index].steps.splice(step_index, 1)
instructions = instructions //tells svelte to update dom
}
let edit_step = {
name: "",
step: "",
list_index: 0,
step_index: 0,
}
export function show_modal_edit_step(list_index, step_index){
edit_step = {
step: instructions[list_index].steps[step_index],
name: instructions[list_index].name,
}
edit_step.list_index = list_index
edit_step.step_index = step_index
const modal_el = document.querySelector("#edit_step_modal");
modal_el.showModal();
}
export function edit_step_and_close_modal(){
instructions[edit_step.list_index].steps[edit_step.step_index] = edit_step.step
const modal_el = document.querySelector("#edit_step_modal");
modal_el.close();
}
export function show_modal_edit_subheading_step(list_index){
edit_heading.name = instructions[list_index].name
edit_heading.list_index = list_index
const el = document.querySelector('#edit_subheading_steps_modal')
el.showModal()
}
export function edit_subheading_steps_and_close_modal(){
instructions[edit_heading.list_index].name = edit_heading.name
const modal_el = document.querySelector("#edit_subheading_steps_modal");
modal_el.close();
}
export function clear_step(){
const el = document.querySelector("#step")
if(el.innerHTML == step_placeholder){
el.innerHTML = ""
}
}
export function add_placeholder(){
const el = document.querySelector("#step")
if(el.innerHTML == ""){
2023-06-23 17:23:14 +02:00
el.innerHTML = step_placeholder
2023-06-22 20:26:48 +02:00
}
}
< / script >
< style >
input::placeholder{
all:unset;
}
2023-06-24 15:31:10 +02:00
li > div{
display:flex;
flex-direction: row;
justify-items: space-between;
align-items:center;
2023-06-25 10:17:12 +02:00
user-select: none;
2023-06-24 15:31:10 +02:00
}
li > div > div:first-child{
flex-grow: 1;
cursor: pointer;
}
li > div > div:last-child{
display: flex;
flex-direction: row;
}
2023-06-23 17:23:14 +02:00
input.heading{
2023-06-24 15:31:10 +02:00
box-sizing: border-box;
2023-06-23 17:23:14 +02:00
background-color: var(--nord0);
padding: 1rem;
padding-inline: 2rem;
font-size: 1.5rem;
width: 100%;
border-radius: 1000px;
color: white;
justify-content: center;
align-items: center;
transition: 200ms;
}
input.heading:hover,
input.heading:focus-visible
{
background-color: var(--nord1);
}
.heading_wrapper{
position: relative;
2023-06-24 15:31:10 +02:00
width: min(300px, 95dvw);
2023-06-23 17:23:14 +02:00
margin-inline: auto;
transition: 200ms;
}
.heading_wrapper:hover,
.heading_wrapper:focus-visible
{
transform:scale(1.1,1.1);
}
.heading_wrapper button{
position: absolute;
bottom: -1.5rem;
2023-06-24 15:31:10 +02:00
right: -1.5rem;
2023-06-23 17:23:14 +02:00
}
2023-06-22 20:26:48 +02:00
.adder{
margin-inline: auto;
position: relative;
margin-block: 3rem;
2023-06-24 15:31:10 +02:00
width: 90%;
2023-06-22 20:26:48 +02:00
border-radius: 20px;
transition: 200ms;
2023-06-24 15:31:10 +02:00
background-color: var(--blue);
padding: 1.5rem 2rem;
}
dialog .adder{
width: 400px;
2023-06-22 20:26:48 +02:00
}
.shadow{
box-shadow: 0 0 1em 0.2em rgba(0,0,0,0.3);
}
.adder button{
position: absolute;
right: -1.5rem;
bottom: -1.5rem;
}
.category{
position: absolute;
2023-06-25 10:17:12 +02:00
border: none;
2023-06-22 20:26:48 +02:00
--font_size: 1.5rem;
top: -1em;
left: -1em;
font-family: sans-serif;
font-size: 1.5rem;
background-color: var(--nord0);
color: var(--nord4);
border-radius: 1000000px;
width: 23ch;
padding: 0.5em 1em;
transition: 100ms;
box-shadow: 0.5em 0.5em 1em 0.4em rgba(0,0,0,0.3);
}
2023-06-23 17:23:14 +02:00
.category:hover,
.category:focus-visible
{
2023-06-22 20:26:48 +02:00
background-color: var(--nord1);
transform: scale(1.05,1.05);
}
2023-06-23 17:23:14 +02:00
.adder:hover,
.adder:focus-within
{
2023-06-22 20:26:48 +02:00
transform: scale(1.1, 1.1);
}
.add_step p{
font-family: sans-serif;
width: 100%;
font-size: 1.2rem;
border-radius: 20px;
2023-06-24 15:31:10 +02:00
border: 2px solid var(--nord4);
border-radius: 30px;
padding: 0.5em 1em;
color: var(--nord4);
transition: 100ms;
2023-06-22 20:26:48 +02:00
}
.add_step p:hover,
.add_step p:focus-visible
{
color: white;
2023-06-24 15:31:10 +02:00
scale: 1.02 1.02;
2023-06-22 20:26:48 +02:00
}
dialog{
box-sizing: content-box;
width: 100%;
height: 100%;
2023-06-23 17:23:14 +02:00
background-color: rgba(255,255,255, 0.001);
2023-06-22 20:26:48 +02:00
border: unset;
margin: 0;
2023-06-23 17:23:14 +02:00
transition: 200ms;
2023-06-22 20:26:48 +02:00
}
dialog .adder{
margin-top: 5rem;
}
dialog h2{
font-size: 3rem;
font-family: sans-serif;
color: white;
text-align: center;
2023-06-23 17:23:14 +02:00
margin-top: 30vh;
margin-top: 30dvh;
filter: drop-shadow(0 0 0.4em black)
drop-shadow(0 0 1em black)
;
2023-06-22 20:26:48 +02:00
}
2023-06-25 10:17:12 +02:00
dialog .adder input::placeholder{
font-size: 1.2rem;
}
2023-06-24 15:31:10 +02:00
@media screen and (max-width: 500px){
dialog h2{
margin-top: 2rem;
}
dialog .adder{
width: 85%;
padding-inline: 0.5em;
}
dialog .adder .category{
width: 70%;
}
}
2023-07-13 15:25:42 +02:00
dialog[open]::backdrop{
2023-06-23 17:23:14 +02:00
animation: show 200ms ease forwards;
}
@keyframes show{
from {
backdrop-filter: blur(0px);
2023-06-22 20:26:48 +02:00
}
2023-06-23 17:23:14 +02:00
to {
backdrop-filter: blur(10px);
2023-06-22 20:26:48 +02:00
}
2023-06-23 17:23:14 +02:00
}
2023-06-24 15:31:10 +02:00
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;
2023-06-25 10:17:12 +02:00
cursor: pointer;
user-select: none;
2023-06-24 15:31:10 +02:00
}
.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%;
}
}
2023-06-22 20:26:48 +02:00
< / style >
2023-06-24 15:31:10 +02:00
< div class = instructions >
< div class = additional_info >
< div > < h4 > Vorbereitung:< / h4 >
< p contenteditable type = "text" bind:innerText = { add_info . preparation } > </p >
< / div >
2023-06-22 20:26:48 +02:00
2023-06-24 15:31:10 +02:00
< 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 >
2023-06-27 19:01:06 +02:00
< div > < h4 > Kochen:< / h4 >
< p contenteditable type = "text" bind:innerText = { add_info . cooking } > </p >
< / div >
2023-06-24 15:31:10 +02:00
< div > < h4 > Auf dem Teller:< / h4 >
2023-06-25 14:49:52 +02:00
< p contenteditable type = "text" bind:innerText = { add_info . total_time } > </p >
< / div >
2023-06-24 15:31:10 +02:00
< / div >
< h2 > Zubereitung< / h2 >
2023-06-22 20:26:48 +02:00
{ #each instructions as list , list_index }
2023-07-03 00:09:00 +02:00
<!-- svelte - ignore a11y - click - events - have - key - events -->
2023-06-25 10:17:12 +02:00
< h3 on:click = {() => show_modal_edit_subheading_step ( list_index )} >
2023-06-22 20:26:48 +02:00
{ #if list . name }
{ list . name }
{ : else }
Leer
{ /if }
2023-06-24 15:31:10 +02:00
< 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 >
2023-06-22 20:26:48 +02:00
< / button >
2023-06-24 15:31:10 +02:00
< / div >
2023-06-22 20:26:48 +02:00
< / h3 >
< ol >
{ #each list . steps as step , step_index }
2023-07-03 00:09:00 +02:00
<!-- svelte - ignore a11y - click - events - have - key - events -->
2023-06-24 15:31:10 +02:00
< 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 >
2023-06-22 20:26:48 +02:00
< / button >
2023-06-24 15:31:10 +02:00
< button class = "action_button button_subtle" on:click = " {() => remove_step ( list_index , step_index )} " >
< Cross fill = var(--nord1) > < / Cross >
2023-06-22 20:26:48 +02:00
< / button >
2023-06-24 15:31:10 +02:00
< / div > < / div >
2023-06-22 20:26:48 +02:00
< / li >
{ /each }
< / ol >
{ /each }
2023-06-24 15:31:10 +02:00
< / div >
2023-06-22 20:26:48 +02:00
< div class = 'adder shadow' >
2023-07-03 00:09:00 +02:00
< input class = category type = "text" bind:value = { new_step . name } placeholder="Kategorie ( optional )" on:keydown = {( event ) => do_on_key ( event , 'Enter' , false , add_new_step )} >
2023-06-22 20:26:48 +02:00
< div class = add_step >
2023-07-03 00:09:00 +02:00
< p id = step contenteditable on:focus = ' { clear_step } ' on:blur = { add_placeholder } bind:innerText= { new_step . step } on:keydown = {( event ) => do_on_key ( event , 'Enter' , true , add_new_step )} > </p >
2023-06-23 17:23:14 +02:00
< button on:click = {() => add_new_step ()} class=action_button >
2023-06-22 20:26:48 +02:00
< Plus fill = white style = "height: 2rem; width: 2rem" > < / Plus >
< / button >
< / div >
< / div >
< dialog id = edit_step_modal >
< h2 > Schritt verändern< / h2 >
< div class = adder >
2023-07-03 00:09:00 +02:00
< input class = category type = "text" bind:value = { edit_step . name } placeholder="Unterkategorie ( optional )" on:keydown = {( event ) => do_on_key ( event , 'Enter' , false , edit_step_and_close_modal )} >
2023-06-22 20:26:48 +02:00
< div class = add_step >
2023-07-03 00:09:00 +02:00
< p id = step contenteditable bind:innerText = { edit_step . step } on:keydown= {( event ) => do_on_key ( event , 'Enter' , true , edit_step_and_close_modal )} ></ p >
2023-06-23 17:23:14 +02:00
< button class = action_button on:click = " {() => edit_step_and_close_modal ()} " >
2023-06-22 20:26:48 +02:00
< Check fill = white style = "height: 2rem; width: 2rem" > < / Check >
< / button >
< / div >
< / dialog >
< dialog id = edit_subheading_steps_modal >
2023-06-23 17:23:14 +02:00
< h2 > Kategorie umbenennen< / h2 >
< div class = heading_wrapper >
2023-07-03 00:09:00 +02:00
< input class = "heading" type = "text" bind:value = { edit_heading . name } on:keydown= {( event ) => do_on_key ( event , 'Enter' , false , edit_subheading_steps_and_close_modal )} >
2023-06-23 17:23:14 +02:00
< button on:click = { edit_subheading_steps_and_close_modal } class=action_button >
< Check fill = white style = "height: 2rem; width: 2rem" > < / Check >
< / button >
< / div >
2023-06-22 20:26:48 +02:00
< / dialog >