cargagep-v2/frontend/src/components/reservation/ReservationDetails.vue
2026-08-24 13:02:01 +02:00

77 lines
2.7 KiB
Vue

<script setup lang="ts">
/**
* The read-only body of a reservation, shared by the admin card and the two
* dialogs so the three never drift apart.
*/
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import type { Bike, ReservationLike } from '@/utils/types'
type Field = 'period' | 'bikes' | 'telegram' | 'people' | 'linka' | 'reason'
const props = withDefaults(
defineProps<{
reservation: ReservationLike
bikes: Bike[]
/** Fields the caller renders itself — the edit dialog omits what it edits */
omit?: Field[]
}>(),
{ omit: () => [] },
)
function shows(field: Field) {
return !props.omit.includes(field)
}
const { locale } = useI18n()
const bikeNames = computed(() =>
props.reservation.bikes
.map((id) => props.bikes.find((bike) => bike.id === id)?.name ?? `#${id}`)
.join(', '),
)
const formatter = computed(
() =>
new Intl.DateTimeFormat(locale.value === 'fr' ? 'fr-CH' : 'en-GB', {
dateStyle: 'short',
timeStyle: 'short',
}),
)
function format(iso: string) {
return formatter.value.format(new Date(iso))
}
</script>
<template>
<dl class="grid gap-1 text-sm">
<div v-if="shows('period')" class="flex gap-2">
<dt class="text-muted-foreground shrink-0">{{ $t('reservation.details.period') }}</dt>
<dd>{{ format(reservation.start_time) }} → {{ format(reservation.end_time) }}</dd>
</div>
<div v-if="shows('bikes')" class="flex gap-2">
<dt class="text-muted-foreground shrink-0">{{ $t('reservation.details.bikes') }}</dt>
<dd>{{ bikeNames }}</dd>
</div>
<div v-if="shows('telegram') && reservation.telegram" class="flex gap-2">
<dt class="text-muted-foreground shrink-0">{{ $t('reservation.details.telegram') }}</dt>
<dd class="truncate">{{ reservation.telegram }}</dd>
</div>
<div v-if="shows('people') && reservation.users?.length" class="flex gap-2">
<dt class="text-muted-foreground shrink-0">{{ $t('reservation.details.people') }}</dt>
<dd class="min-w-0 break-words">
{{ reservation.users.map((u) => `${u.firstname} ${u.name} <${u.email}>`).join(', ') }}
</dd>
</div>
<div v-if="shows('linka') && reservation.linka_emails?.length" class="flex gap-2">
<dt class="text-muted-foreground shrink-0">{{ $t('reservation.details.linka') }}</dt>
<dd class="min-w-0 break-words">{{ reservation.linka_emails.join(', ') }}</dd>
</div>
<div v-if="shows('reason') && reservation.description" class="flex gap-2">
<dt class="text-muted-foreground shrink-0">{{ $t('reservation.details.reason') }}</dt>
<dd class="min-w-0 break-words italic">{{ reservation.description }}</dd>
</div>
</dl>
</template>