Three-breakpoint layout (mobile/tablet/desktop) with VarietyScoreCard, WeekStrip, DayMealCard components. Server loads week plan and variety score via API; read-only role behavior derived from benutzer.rolle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
71 lines
2.0 KiB
Svelte
71 lines
2.0 KiB
Svelte
<script lang="ts">
|
|
import { weekDays, formatDayAbbr } from './week';
|
|
|
|
interface Slot {
|
|
id?: string;
|
|
slotDate?: string;
|
|
recipe?: { id?: string; name?: string } | null;
|
|
}
|
|
|
|
let {
|
|
weekStart,
|
|
slots = [],
|
|
selectedDay,
|
|
today,
|
|
onselectDay
|
|
}: {
|
|
weekStart: string;
|
|
slots?: Slot[];
|
|
selectedDay: string;
|
|
today: string;
|
|
onselectDay?: (day: string) => void;
|
|
} = $props();
|
|
|
|
let days = $derived(weekDays(weekStart));
|
|
let slotMap = $derived(
|
|
Object.fromEntries(slots.map((s) => [s.slotDate!, s]))
|
|
);
|
|
|
|
function selectDay(day: string) {
|
|
onselectDay?.(day);
|
|
}
|
|
</script>
|
|
|
|
<div class="grid grid-cols-7 gap-[2px] md:gap-[6px]">
|
|
{#each days as day}
|
|
{@const isSelected = day === selectedDay}
|
|
{@const isTodayDay = day === today}
|
|
{@const hasMeal = !!slotMap[day]?.recipe}
|
|
{@const dateNum = day.slice(-2).replace(/^0/, '')}
|
|
{@const abbr = formatDayAbbr(day, 'narrow')}
|
|
|
|
<button
|
|
type="button"
|
|
data-testid="day-chip-{day}"
|
|
data-selected={isSelected}
|
|
data-today={isTodayDay}
|
|
onclick={() => selectDay(day)}
|
|
class="flex flex-col items-center rounded-[10px] px-1 py-2 transition-colors
|
|
{isTodayDay ? 'border border-[var(--yellow-light)] bg-[var(--yellow-tint)]' : ''}
|
|
{isSelected && !isTodayDay ? 'border border-[var(--green-light)] bg-[var(--green-tint)]' : ''}
|
|
{!isTodayDay && !isSelected ? 'border border-transparent' : ''}"
|
|
>
|
|
<span class="font-[var(--font-sans)] text-[7px] uppercase tracking-wide text-[var(--color-text-muted)] md:text-[10px]">
|
|
{abbr}
|
|
</span>
|
|
<span class="font-[var(--font-sans)] text-[11px] font-medium text-[var(--color-text)] md:text-[14px]">
|
|
{dateNum}
|
|
</span>
|
|
<!-- Dot indicator -->
|
|
<span
|
|
data-testid="dot-{day}"
|
|
data-has-meal={hasMeal}
|
|
class="mt-1 h-[3px] w-[3px] rounded-full
|
|
{hasMeal ? 'bg-[var(--green)]' : ''}
|
|
{!hasMeal && isTodayDay ? 'bg-[var(--yellow-text)]' : ''}
|
|
{!hasMeal && !isTodayDay ? 'bg-[var(--color-border)]' : ''}"
|
|
></span>
|
|
</button>
|
|
{/each}
|
|
</div>
|