site-panzai/components/CartSummary.vue
2026-11-13 13:57:04 +01:00

60 lines
3.4 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
// Panier latéral (desktop) sur la page Menu
const { lines, count, subtotal, setQty, mode, bump } = useCart()
const { settings } = useShop()
const fee = computed(() => mode.value === 'livraison' && count.value && subtotal.value < (settings.value?.freeFrom ?? 3500) ? (settings.value?.deliveryFee ?? 250) : 0)
const popping = ref(false)
watch(bump, () => { popping.value = false; requestAnimationFrame(() => { popping.value = true }) })
</script>
<template>
<aside class="cs card" :class="{ pop: popping }" aria-labelledby="cs-h">
<div class="row" style="justify-content: space-between">
<h2 id="cs-h" style="font-size: 20px; font-weight: 800; color: #fff">Ton panier</h2>
<span class="small muted">{{ count }} article(s)</span>
</div>
<p v-if="!lines.length" class="empty muted">Ton panier est vide.<br>Le Crousty t'attend 🔥</p>
<ul v-else class="lines">
<li v-for="l in lines" :key="l.key">
<img v-if="l.img" :src="l.img" alt="" class="thumb">
<span v-else class="thumb ph" />
<div class="grow">
<p class="strong" style="font-size: 15px">{{ l.name }} {{ l.size }}</p>
<p class="small muted">{{ [l.meat, l.sauce, ...l.extrasLabel].filter(Boolean).join(' · ') }}</p>
<div class="row" style="justify-content: space-between; margin-top: 6px">
<div class="qty mini">
<button type="button" :aria-label="`Retirer un ${l.name}`" @click="setQty(l.key, l.qty - 1)">−</button>
<span>{{ l.qty }}</span>
<button type="button" :aria-label="`Ajouter un ${l.name}`" @click="setQty(l.key, l.qty + 1)">+</button>
</div>
<strong class="price">{{ eur(l.unit * l.qty) }}</strong>
</div>
</div>
</li>
</ul>
<dl class="tot">
<dt>Sous-total</dt><dd>{{ eur(subtotal) }}</dd>
<dt>{{ mode === 'livraison' ? 'Livraison' : 'Retrait sur place' }}</dt><dd>{{ mode === 'livraison' ? eur(fee) : 'Gratuit' }}</dd>
<dt>Frais de service</dt><dd style="color: var(--leaf)">0,00 €</dd>
<dt class="big">Total</dt><dd class="big price">{{ eur(subtotal + fee) }}</dd>
</dl>
<NuxtLink v-if="lines.length" to="/panier" class="btn btn-primary btn-lg btn-block">Commander — {{ eur(subtotal + fee) }}</NuxtLink>
<p class="small muted" style="text-align: center">Commande directe : zéro commission d'appli, 100 % pour le resto 🌴</p>
</aside>
</template>
<style scoped>
.cs { padding: 22px; display: flex; flex-direction: column; gap: 14px; border: 1px solid rgba(243,227,195,.08); box-shadow: 0 30px 60px rgba(0,0,0,.35); }
.cs.pop { animation: none; }
.empty { padding: 20px 0; text-align: center; }
.lines { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; max-height: 420px; overflow-y: auto; }
.lines li { display: flex; gap: 10px; padding: 10px; border-radius: 16px; background: var(--bg); }
.thumb { width: 54px; height: 54px; object-fit: contain; flex: none; }
.thumb.ph { border-radius: 12px; background: var(--surface-2); }
.qty.mini button { width: 30px; height: 30px; font-size: 16px; }
.tot { margin: 0; padding-top: 12px; border-top: 1px solid var(--line); display: grid; grid-template-columns: 1fr auto; gap: 8px; font-size: 14px; }
.tot dt { opacity: .75; }
.tot dd { margin: 0; font-weight: 700; text-align: right; }
.tot .big { font-size: 20px; font-weight: 800; opacity: 1; color: #fff; }
.tot dd.big { color: var(--orange-1); }
</style>