import { Link, createFileRoute, useNavigate } from '@tanstack/react-router'
import { useMemo, useState } from 'react'
import { m, mKey } from '@/i18n/messages'
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: mKey(`common.pages.bookingStatus.label.${s}` as any),
})),
[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,
})