87 lines
2.7 KiB
TypeScript
87 lines
2.7 KiB
TypeScript
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>
|
|
)
|
|
}
|