import { Link, createFileRoute, useNavigate } from '@tanstack/react-router' import { useMemo, useState } from 'react' import { m } from '@/i18n/messages' import { bookingStatus } from '@/i18n/i18n-enum.gen' import { useLocale, getLocale } from '@/i18n/config' import { asI18n } from '@pikku/react' import { keepPreviousData } from '@tanstack/react-query' import { Badge, Box, Button, Checkbox, Container, Group, Loader, MultiSelect, Paper, Stack, Table, Text, TextInput, } from '@pikku/mantine/core' import { Search } from 'lucide-react' import { usePikkuQuery } from '@project/functions-sdk/pikku/api.gen' import { StatusPill } from '../components/StatusPill' import { usePageTitle } from '../components/AppLayout' import { BOOKING_STATUS, type BookingStatus } from '../lib/status' import { fmtDateShort } from '../lib/dates' const STATUS_KEYS: BookingStatus[] = [ 'enquiry', 'reserved', 'confirmed', 'ended', 'cancelled', ] function StatusDot({ color }: { color: string }) { return ( ) } function AdminBookingsInner() { useLocale() const navigate = useNavigate() usePageTitle(m.common__pages__admin__bookings__title()) const [years, setYears] = useState([]) const [statusFilter, setStatusFilter] = useState([]) const [search, setSearch] = useState('') const [halfHouseOnly, setHalfHouseOnly] = useState(false) const queryArgs = useMemo( () => ({ venueSlug: 'drawehn', years: years.length ? years.map(Number) : undefined, status: statusFilter.length ? statusFilter : undefined, search: search.trim() || undefined, halfHouseOnly: halfHouseOnly || undefined, }), [years, statusFilter, search, halfHouseOnly], ) const normalizedSearch = search.trim().toLocaleLowerCase(getLocale()) const { data, isLoading, isFetching, error } = usePikkuQuery( 'getAdminBookings', queryArgs, { placeholderData: keepPreviousData }, ) const statusOptions = useMemo( () => STATUS_KEYS.map((s) => ({ value: s, label: bookingStatus[s](), })), [getLocale()], ) if (isLoading && !data) { return {m.common__states__loading()} } if (error && !data) { return {m.common__states__error()} } if (!data) return null const bookings = [...data.bookings].sort((a, b) => { if (!normalizedSearch) return 0 const rank = (value: string | null | undefined) => { const text = value?.toLocaleLowerCase(getLocale()) ?? '' if (text === normalizedSearch) return 0 if (text.startsWith(normalizedSearch)) return 1 if (text.includes(normalizedSearch)) return 2 return 3 } const aRank = Math.min(rank(a.eventName), rank(a.clientName)) const bRank = Math.min(rank(b.eventName), rank(b.clientName)) if (aRank !== bRank) return aRank - bRank return a.eventName.localeCompare(b.eventName, getLocale()) }) return ( } placeholder={m.common__pages__admin__bookings__search_placeholder()} value={search} onChange={(e) => setSearch(e.currentTarget.value)} /> String(y))} value={years} onChange={setYears} /> ( {option.label} )} /> setHalfHouseOnly(e.currentTarget.checked)} styles={{ root: { alignSelf: 'center' } }} /> {m.common__pages__admin__bookings__stats__showing({ count: data.totalCount })} {isFetching && } {bookings.length === 0 ? ( {m.common__pages__admin__bookings__empty()} ) : ( {m.common__pages__admin__bookings__cols__dates()} {m.common__pages__admin__bookings__cols__course()} {m.common__pages__admin__bookings__cols__client()} {m.common__pages__admin__bookings__cols__status()} {m.common__pages__admin__bookings__cols__persons()} {m.common__pages__admin__bookings__cols__half_house()} {m.common__pages__admin__bookings__cols__deposit()} {m.common__pages__admin__bookings__cols__final()} {bookings.map((b) => ( navigate({ to: '/admin/bookings/$bookingId', params: { bookingId: b.bookingId } }) } > {asI18n(`${fmtDateShort(b.startDate, getLocale())}`)} {asI18n(`→ ${fmtDateShort(b.endDate, getLocale())}`)} {asI18n(`${b.eventName}`)} {b.isStammgruppe && ( {asI18n('★')} )} {asI18n(`${b.clientName}`)} {b.participantCount} / {b.expectedPersons ?? '?'} {b.halfHouse ? '½' : ''} {!b.hasDeposit ? {m.common__pages__admin__bookings__deposit__missing()} : {(b.depositPaid ? m.common__pages__admin__bookings__deposit__paid : m.common__pages__admin__bookings__deposit__outstanding)()} } {!b.hasFinal ? {m.common__pages__admin__bookings__deposit__missing()} : {(b.finalPaid ? m.common__pages__admin__bookings__deposit__paid : m.common__pages__admin__bookings__deposit__outstanding)()} } ))}
)}
) } export const Route = createFileRoute('/admin/bookings/')({ component: AdminBookingsInner, })