141 lines
2.8 KiB
Svelte
141 lines
2.8 KiB
Svelte
|
|
<script lang="ts">
|
||
|
|
import { onMount } from 'svelte';
|
||
|
|
|
||
|
|
let { data } = $props();
|
||
|
|
|
||
|
|
function formatQty(q: number | null): string {
|
||
|
|
if (q === null) return '';
|
||
|
|
if (Number.isInteger(q)) return String(q);
|
||
|
|
return q.toLocaleString('de-DE', { maximumFractionDigits: 2 });
|
||
|
|
}
|
||
|
|
|
||
|
|
onMount(() => {
|
||
|
|
setTimeout(() => window.print(), 250);
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<article class="print">
|
||
|
|
<header>
|
||
|
|
<h1>{data.recipe.title}</h1>
|
||
|
|
<p class="meta">
|
||
|
|
{data.servings} {data.recipe.servings_unit ?? 'Portionen'}
|
||
|
|
{#if data.recipe.prep_time_min}· Vorb. {data.recipe.prep_time_min} min{/if}
|
||
|
|
{#if data.recipe.cook_time_min}· Kochen {data.recipe.cook_time_min} min{/if}
|
||
|
|
{#if data.recipe.source_url}
|
||
|
|
· Quelle: {data.recipe.source_domain}
|
||
|
|
{/if}
|
||
|
|
</p>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
{#if data.recipe.image_path}
|
||
|
|
<img src={`/images/${data.recipe.image_path}`} alt="" />
|
||
|
|
{/if}
|
||
|
|
|
||
|
|
<section>
|
||
|
|
<h2>Zutaten</h2>
|
||
|
|
<ul class="ingredients">
|
||
|
|
{#each data.ingredients as ing, i (i)}
|
||
|
|
<li>
|
||
|
|
<span class="qty">
|
||
|
|
{formatQty(ing.quantity)}{#if ing.unit}{' '}{ing.unit}{/if}
|
||
|
|
</span>
|
||
|
|
<span class="name">
|
||
|
|
{ing.name}{#if ing.note}{' '}<em>({ing.note})</em>{/if}
|
||
|
|
</span>
|
||
|
|
</li>
|
||
|
|
{/each}
|
||
|
|
</ul>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section>
|
||
|
|
<h2>Zubereitung</h2>
|
||
|
|
<ol class="steps">
|
||
|
|
{#each data.recipe.steps as step (step.position)}
|
||
|
|
<li>{step.text}</li>
|
||
|
|
{/each}
|
||
|
|
</ol>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
{#if data.recipe.source_url}
|
||
|
|
<footer>
|
||
|
|
<p>Quelle: <a href={data.recipe.source_url}>{data.recipe.source_url}</a></p>
|
||
|
|
</footer>
|
||
|
|
{/if}
|
||
|
|
</article>
|
||
|
|
|
||
|
|
<style>
|
||
|
|
:global(body) {
|
||
|
|
background: white !important;
|
||
|
|
}
|
||
|
|
:global(header.bar),
|
||
|
|
:global(nav.tabs) {
|
||
|
|
display: none !important;
|
||
|
|
}
|
||
|
|
.print {
|
||
|
|
font-family: Georgia, 'Liberation Serif', serif;
|
||
|
|
color: #111;
|
||
|
|
max-width: 190mm;
|
||
|
|
margin: 0 auto;
|
||
|
|
padding: 1rem;
|
||
|
|
}
|
||
|
|
h1 {
|
||
|
|
font-size: 2rem;
|
||
|
|
margin: 0 0 0.4rem;
|
||
|
|
}
|
||
|
|
.meta {
|
||
|
|
color: #555;
|
||
|
|
margin: 0 0 1rem;
|
||
|
|
font-size: 0.95rem;
|
||
|
|
}
|
||
|
|
img {
|
||
|
|
max-width: 50%;
|
||
|
|
float: right;
|
||
|
|
margin: 0 0 1rem 1rem;
|
||
|
|
border-radius: 6px;
|
||
|
|
}
|
||
|
|
h2 {
|
||
|
|
font-size: 1.15rem;
|
||
|
|
border-bottom: 1px solid #bbb;
|
||
|
|
padding-bottom: 0.25rem;
|
||
|
|
margin-top: 1.5rem;
|
||
|
|
}
|
||
|
|
.ingredients {
|
||
|
|
list-style: none;
|
||
|
|
padding: 0;
|
||
|
|
margin: 0;
|
||
|
|
columns: 2;
|
||
|
|
column-gap: 1.5rem;
|
||
|
|
}
|
||
|
|
.ingredients li {
|
||
|
|
break-inside: avoid;
|
||
|
|
padding: 0.25rem 0;
|
||
|
|
font-size: 0.95rem;
|
||
|
|
}
|
||
|
|
.qty {
|
||
|
|
display: inline-block;
|
||
|
|
min-width: 5rem;
|
||
|
|
font-weight: 600;
|
||
|
|
}
|
||
|
|
.steps {
|
||
|
|
padding-left: 1.25rem;
|
||
|
|
}
|
||
|
|
.steps li {
|
||
|
|
margin-bottom: 0.6rem;
|
||
|
|
line-height: 1.4;
|
||
|
|
}
|
||
|
|
footer {
|
||
|
|
margin-top: 2rem;
|
||
|
|
color: #666;
|
||
|
|
font-size: 0.85rem;
|
||
|
|
text-align: center;
|
||
|
|
}
|
||
|
|
@media print {
|
||
|
|
@page {
|
||
|
|
margin: 15mm;
|
||
|
|
}
|
||
|
|
.print {
|
||
|
|
padding: 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|