refactor(wishlist): horizontale Actions + Einkaufswagen-Button
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 2m15s

This commit is contained in:
hsiegeln
2026-04-21 23:38:26 +02:00
parent 0e6d2c93a6
commit 7fa1079125

View File

@@ -1,8 +1,9 @@
<script lang="ts">
import { onMount } from 'svelte';
import { Utensils, Trash2, CookingPot } from 'lucide-svelte';
import { Utensils, Trash2, CookingPot, ShoppingCart } from 'lucide-svelte';
import { profileStore, requireProfile } from '$lib/client/profile.svelte';
import { wishlistStore } from '$lib/client/wishlist.svelte';
import { shoppingCartStore } from '$lib/client/shopping-cart.svelte';
import { confirmAction } from '$lib/client/confirm.svelte';
import { requireOnline } from '$lib/client/require-online';
import type { WishlistEntry, SortKey } from '$lib/server/wishlist/repository';
@@ -70,9 +71,19 @@
void wishlistStore.refresh();
}
async function toggleCart(entry: WishlistEntry) {
if (!requireOnline('Die Einkaufsliste')) return;
if (shoppingCartStore.isInCart(entry.recipe_id)) {
await shoppingCartStore.removeRecipe(entry.recipe_id);
} else {
await shoppingCartStore.addRecipe(entry.recipe_id);
}
}
onMount(() => {
void load();
void wishlistStore.refresh();
void shoppingCartStore.refresh();
});
function resolveImage(p: string | null): string | null {
@@ -125,16 +136,13 @@
{#if e.wanted_by_names}
<span class="wanted-by">{e.wanted_by_names}</span>
{/if}
{#if e.source_domain}
<span class="src">· {e.source_domain}</span>
{/if}
{#if e.avg_stars !== null}
<span>· ★ {e.avg_stars.toFixed(1)}</span>
{/if}
</div>
</div>
</a>
<div class="actions">
<div class="actions-top">
<button
class="like"
class:active={e.on_my_wishlist}
@@ -146,6 +154,16 @@
<span class="count">{e.wanted_by_count}</span>
{/if}
</button>
<button
class="cart"
class:active={shoppingCartStore.isInCart(e.recipe_id)}
aria-label={shoppingCartStore.isInCart(e.recipe_id)
? 'Aus Einkaufswagen entfernen'
: 'In den Einkaufswagen'}
onclick={() => toggleCart(e)}
>
<ShoppingCart size={18} strokeWidth={2} />
</button>
<button
class="del"
aria-label="Für alle entfernen"
@@ -227,6 +245,7 @@
gap: 0.75rem;
}
.card {
position: relative;
display: flex;
align-items: stretch;
background: white;
@@ -255,7 +274,7 @@
}
.text {
flex: 1;
padding: 0.7rem 0.75rem;
padding: 0.7rem 170px 0.7rem 0.75rem;
min-width: 0;
display: flex;
flex-direction: column;
@@ -278,18 +297,19 @@
color: #2b6a3d;
font-weight: 500;
}
.actions {
.actions-top {
position: absolute;
top: 0.5rem;
right: 0.5rem;
display: flex;
flex-direction: column;
gap: 0.4rem;
align-items: stretch;
justify-content: center;
padding: 0.5rem 0.6rem 0.5rem 0;
z-index: 1;
}
.like,
.cart,
.del {
min-width: 48px;
min-height: 40px;
min-width: 44px;
min-height: 44px;
border-radius: 10px;
border: 1px solid #e4eae7;
background: white;
@@ -297,8 +317,8 @@
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.3rem;
font-size: 1.05rem;
gap: 0.25rem;
font-size: 1rem;
color: #444;
}
.like.active {
@@ -306,6 +326,11 @@
background: #eaf4ed;
border-color: #b7d6c2;
}
.cart.active {
color: #2b6a3d;
background: #eaf4ed;
border-color: #b7d6c2;
}
.del:hover {
color: #c53030;
border-color: #f1b4b4;