chore: seminarhof customer project

This commit is contained in:
e2e
2026-07-11 08:29:46 +02:00
commit 1d847171eb
188 changed files with 20784 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
import { m } from '@/i18n/messages'
import { useLocale, getLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'
import { Box, Button, Card, Flex, Image, Stack, Text, Title } from '@pikku/mantine/core'
import { ImageOff } from 'lucide-react'
type EventCardProps = {
eventName: string
startDate: Date | null
endDate: Date | null
clientName?: string | null
coverImageUrl?: string | null
eventOutline?: string | null
description?: string | null
organiserWebsite?: string | null
}
function formatDateRange(start: Date | null, end: Date | null, lng: string): string {
const locale = lng.startsWith('de') ? 'de-DE' : 'en-GB'
const fmt = new Intl.DateTimeFormat(locale, { day: 'numeric', month: 'long', year: 'numeric' })
// An enquiry may have no dates yet; show whatever we have, or a placeholder.
if (!start && !end) return '—'
if (!start || !end) return fmt.format((start ?? end) as Date)
return start.toISOString().slice(0, 10) === end.toISOString().slice(0, 10)
? fmt.format(start)
: fmt.formatRange(start, end)
}
export function EventCard({
eventName,
startDate,
endDate,
clientName,
coverImageUrl,
eventOutline,
description,
organiserWebsite,
}: EventCardProps) {
useLocale()
return (
<Card withBorder radius="md" p={0} style={{ overflow: 'hidden' }}>
<Flex>
<Box w={{ base: 120, sm: 220 }} style={{ flexShrink: 0 }}>
{coverImageUrl ? (
<Image src={coverImageUrl} alt={eventName} h="100%" w="100%" fit="cover" />
) : (
<Flex h="100%" mih={140} align="center" justify="center" bg="gray.1">
<ImageOff size={28} color="var(--mantine-color-gray-5)" />
</Flex>
)}
</Box>
<Stack gap="xs" p="md" style={{ flexGrow: 1 }}>
<Title order={4}>{asI18n(`${eventName}`)}</Title>
<Text size="sm" fw={500}>
{asI18n(`${formatDateRange(startDate, endDate, getLocale())}`)}
</Text>
{clientName && (
<Text size="sm" c="dimmed">
{asI18n(`${clientName}`)}
</Text>
)}
{(eventOutline || description) && (
<Text size="sm" c="dimmed" lineClamp={3}>
{asI18n(`${eventOutline || description}`)}
</Text>
)}
{organiserWebsite && (
<Button
component="a"
href={organiserWebsite}
target="_blank"
rel="noopener noreferrer"
size="xs"
variant="light"
mt="auto"
w="fit-content"
>
{m.common__pages__events__more_info()}
</Button>
)}
</Stack>
</Flex>
</Card>
)
}