feat: D1 — Shopping list (Issue #30) #43
@@ -27,12 +27,14 @@
|
||||
method="POST"
|
||||
action="?/addItem"
|
||||
use:enhance={() => {
|
||||
return async ({ update }) => {
|
||||
await update();
|
||||
customName = '';
|
||||
quantity = '1';
|
||||
unit = '';
|
||||
expanded = false;
|
||||
return async ({ result, update }) => {
|
||||
if (result.type === 'success') {
|
||||
await update();
|
||||
customName = '';
|
||||
quantity = '1';
|
||||
unit = '';
|
||||
expanded = false;
|
||||
}
|
||||
};
|
||||
}}
|
||||
class="flex flex-col gap-2 rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-surface)] p-3"
|
||||
|
||||
@@ -32,15 +32,17 @@
|
||||
);
|
||||
</script>
|
||||
|
||||
<form method="POST" action="?/check" use:enhance class="group flex items-center gap-3 py-2">
|
||||
<form method="POST" action="?/check" use:enhance={() => async ({ update }) => update({ reset: false })} class="group flex items-center gap-3 py-2">
|
||||
<input type="hidden" name="listId" value={listId} />
|
||||
<input type="hidden" name="itemId" value={itemId} />
|
||||
<input type="hidden" name="isChecked" value={!isChecked} />
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
role="checkbox"
|
||||
aria-checked={isChecked}
|
||||
aria-label="{isChecked ? 'Abhaken rückgängig' : 'Abhaken'}: {name}"
|
||||
class="flex h-5 w-5 flex-shrink-0 items-center justify-center rounded border
|
||||
class="flex h-5 w-5 flex-shrink-0 items-center justify-center rounded border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--green)]
|
||||
{isChecked
|
||||
? 'border-[var(--green)] bg-[var(--green)] text-white'
|
||||
: 'border-[var(--color-border)] bg-[var(--color-surface)] hover:border-[var(--green-light)]'}"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
href="/recipes/{slot.recipe?.id}"
|
||||
class="flex items-center gap-2 rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-3 py-2 hover:border-[var(--green-light)]"
|
||||
>
|
||||
<span class="min-w-[28px] font-[var(--font-sans)] text-[11px] text-[var(--color-text-muted)]">
|
||||
<span class="min-w-[28px] font-[var(--font-sans)] text-[12px] text-[var(--color-text-muted)]">
|
||||
{slot.slotDate ? formatDayAbbr(slot.slotDate, 'short') : ''}
|
||||
</span>
|
||||
<span class="flex-1 truncate font-[var(--font-sans)] text-[13px] font-medium text-[var(--color-text)]">
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
let remainingCount = $derived(totalItems - checkedCount);
|
||||
|
||||
let generating = $state(false);
|
||||
|
||||
let formattedTime = $derived(
|
||||
generatedAt
|
||||
? new Date(generatedAt).toLocaleString('de-DE', {
|
||||
@@ -33,15 +35,22 @@
|
||||
</h1>
|
||||
|
||||
{#if isPlanner && weekPlanId}
|
||||
<form method="POST" action="?/generate" use:enhance>
|
||||
<form method="POST" action="?/generate" use:enhance={() => {
|
||||
generating = true;
|
||||
return async ({ update }) => {
|
||||
await update();
|
||||
generating = false;
|
||||
};
|
||||
}}>
|
||||
<input type="hidden" name="weekPlanId" value={weekPlanId} />
|
||||
<button
|
||||
type="submit"
|
||||
disabled={generating}
|
||||
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)]"
|
||||
: 'bg-[var(--green-dark)] text-white'} px-3 py-1.5 text-[13px] font-medium tracking-[0.04em] font-[var(--font-sans)] disabled:opacity-50"
|
||||
>
|
||||
{hasShoppingList ? 'Neu generieren' : 'Liste generieren'}
|
||||
{generating ? '…' : hasShoppingList ? 'Neu generieren' : 'Liste generieren'}
|
||||
</button>
|
||||
</form>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user