feat(shopping): add ShoppingHeader.svelte component
Displays title, eyebrow counts (remaining/checked), generation timestamp, and planner-only generate/regenerate button. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
58
frontend/src/lib/shopping/ShoppingHeader.svelte
Normal file
58
frontend/src/lib/shopping/ShoppingHeader.svelte
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { enhance } from '$app/forms';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
totalItems: number;
|
||||||
|
checkedCount: number;
|
||||||
|
generatedAt: string | null;
|
||||||
|
weekPlanId: string | null;
|
||||||
|
isPlanner: boolean;
|
||||||
|
hasShoppingList: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
let { totalItems, checkedCount, generatedAt, weekPlanId, isPlanner, hasShoppingList }: Props = $props();
|
||||||
|
|
||||||
|
let remainingCount = $derived(totalItems - checkedCount);
|
||||||
|
|
||||||
|
let formattedTime = $derived(
|
||||||
|
generatedAt
|
||||||
|
? new Date(generatedAt).toLocaleString('de-DE', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit'
|
||||||
|
})
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header class="flex flex-col gap-1">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<h1 class="font-[var(--font-display)] text-[20px] font-[300] text-[var(--color-text)]">
|
||||||
|
Einkaufsliste
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
{#if isPlanner && weekPlanId}
|
||||||
|
<form method="POST" action="?/generate" use:enhance>
|
||||||
|
<input type="hidden" name="weekPlanId" value={weekPlanId} />
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="rounded-[var(--radius-md)] {hasShoppingList
|
||||||
|
? 'border border-[var(--color-border)] text-[var(--color-text)] hover:bg-[var(--color-surface)]'
|
||||||
|
: 'bg-[var(--green-dark)] text-white'} px-3 py-1.5 text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)]"
|
||||||
|
>
|
||||||
|
{hasShoppingList ? 'Neu generieren' : 'Liste generieren'}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if hasShoppingList}
|
||||||
|
<p class="font-[var(--font-sans)] text-[12px] text-[var(--color-text-muted)]">
|
||||||
|
{remainingCount} Artikel übrig · {checkedCount} abgehakt
|
||||||
|
{#if formattedTime}
|
||||||
|
<span class="ml-1">· erstellt {formattedTime}</span>
|
||||||
|
{/if}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
|
</header>
|
||||||
Reference in New Issue
Block a user