You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

116 lines
3.4 KiB

<script setup lang="ts">
import { cn } from '~/lib/utils'
import type { CartItemWithProduct } from '~/types/cart'
interface Props {
/**
* Cart items for summary calculation
*/
items: CartItemWithProduct[]
/**
* Total amount in EUR
*/
total: number
/**
* Loading state (e.g., during checkout)
*/
loading?: boolean
/**
* Additional CSS classes
*/
class?: string
}
const props = defineProps<Props>()
// Format currency in EUR
const formatCurrency = (amount: number) => {
return new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR',
}).format(amount)
}
// Calculate item count
const itemCount = computed(() => {
return props.items.reduce((sum, item) => sum + item.quantity, 0)
})
// Calculate VAT (7% already included in total)
// Formula: VAT = total * (VAT_rate / (1 + VAT_rate))
const vatAmount = computed(() => {
return props.total * (0.07 / 1.07)
})
// Format values
const formattedSubtotal = computed(() => formatCurrency(props.total))
const formattedVat = computed(() => formatCurrency(vatAmount.value))
const formattedTotal = computed(() => formatCurrency(props.total))
// Item count text (singular/plural)
const itemCountText = computed(() => {
return itemCount.value === 1 ? '1 Artikel' : `${itemCount.value} Artikel`
})
</script>
<template>
<Card :class="cn('sticky top-4', props.class)">
<div class="p-6 space-y-4">
<!-- Header -->
<div>
<h2 class="text-xl font-bold text-white">Zusammenfassung</h2>
<p class="text-sm text-white/60 mt-1">{{ itemCountText }}</p>
</div>
<Separator class="bg-white/20" />
<!-- Price Breakdown -->
<div class="space-y-3">
<!-- Subtotal -->
<div class="flex items-center justify-between text-white/80">
<span class="text-sm">Zwischensumme</span>
<span class="font-medium">{{ formattedSubtotal }}</span>
</div>
<!-- VAT (included) -->
<div class="flex items-center justify-between text-white/60 text-sm">
<span>inkl. MwSt. (7%)</span>
<span>{{ formattedVat }}</span>
</div>
</div>
<Separator class="bg-white/20" />
<!-- Total -->
<div class="flex items-center justify-between">
<span class="text-lg font-bold text-white">Gesamt</span>
<span class="text-2xl font-bold text-experimenta-accent">
{{ formattedTotal }}
</span>
</div>
<!-- Checkout Button -->
<Button
class="w-full bg-gradient-button bg-size-300 bg-left hover:bg-right transition-all duration-300 font-bold text-white shadow-lg hover:shadow-2xl"
size="lg" :disabled="loading || items.length === 0" @click="$emit('checkout')">
<span v-if="!loading">Zur Kasse</span>
<span v-else class="flex items-center gap-2">
<div class="animate-spin rounded-full h-4 w-4 border-2 border-white/20 border-t-white" />
Wird verarbeitet...
</span>
</Button>
<!-- Additional Info -->
<!-- <div class="pt-2 space-y-2 text-xs text-white/60">
<p class="flex items-start gap-2">
<span class="text-experimenta-accent"></span>
<span>Sichere Zahlung mit PayPal</span>
</p>
<p class="flex items-start gap-2">
<span class="text-experimenta-accent"></span>
<span>Versandkostenfrei</span>
</p>
</div> -->
</div>
</Card>
</template>