Updated the OpenAPI specification to format the 'tags' property as an array on multiple endpoints, ensuring consistent styling across the documentation. Additionally, simplified JSX return statements in the BookingsPage and AdminEventBookingsTab components for improved readability.
164 lines
4.4 KiB
TypeScript
164 lines
4.4 KiB
TypeScript
'use client'
|
|
|
|
import type { PaginationListColumnType } from '@/types'
|
|
import PaginatedList from '@/components/PaginatedList'
|
|
import StatusChip from '@/components/ui/StatusChip'
|
|
import PageNavbar from '@/components/layouts/PageNavbar'
|
|
import AdminTableViewButton from '@/components/ui/AdminTableViewButton'
|
|
import { APP_ROUTES } from '@/constants/routes'
|
|
import { formatPersonName, coerceToString } from '@/helpers'
|
|
import { formatIranianMobile, formatPersianDate } from '@/lib/formatters'
|
|
import { BOOKING_STATUS_FILTER_ITEMS, getBookingStatus } from '@/constants/status'
|
|
import { API_ROUTES } from '@/services/config'
|
|
|
|
interface BookingUser {
|
|
id: string
|
|
mobile: string
|
|
firstName: string | null
|
|
lastName: string | null
|
|
}
|
|
|
|
interface BookingEvent {
|
|
id: string
|
|
title: string
|
|
startsAt: string
|
|
status: string
|
|
organizerId: string
|
|
}
|
|
|
|
const columns: PaginationListColumnType[] = [
|
|
{
|
|
field: 'bookingCode',
|
|
label: 'کد رزرو',
|
|
filterable: false,
|
|
sortable: false,
|
|
type: 'text',
|
|
},
|
|
{
|
|
field: 'userId',
|
|
label: 'مهمان',
|
|
filterable: true,
|
|
sortable: false,
|
|
type: 'text',
|
|
},
|
|
{
|
|
field: 'eventId',
|
|
label: 'رویداد',
|
|
filterable: true,
|
|
sortable: false,
|
|
type: 'text',
|
|
},
|
|
{
|
|
field: 'status',
|
|
label: 'وضعیت',
|
|
filterable: true,
|
|
sortable: true,
|
|
type: 'select',
|
|
filterItems: BOOKING_STATUS_FILTER_ITEMS,
|
|
},
|
|
{
|
|
field: 'cancellationReason',
|
|
label: 'دلیل لغو',
|
|
filterable: false,
|
|
sortable: false,
|
|
type: 'text',
|
|
},
|
|
{
|
|
field: 'checkedInAt',
|
|
label: 'چکاین',
|
|
filterable: false,
|
|
sortable: false,
|
|
type: 'date',
|
|
},
|
|
{
|
|
field: 'createdAt',
|
|
label: 'تاریخ ثبت',
|
|
filterable: false,
|
|
sortable: true,
|
|
type: 'date',
|
|
},
|
|
{
|
|
field: 'actions',
|
|
label: 'عملیات',
|
|
},
|
|
]
|
|
|
|
// Platform-wide, read-only admin bookings list. No write actions here by
|
|
// design — cancel/check-in/refund stay on their existing flows; the view
|
|
// button jumps to the guest's user-detail page (رزروها tab).
|
|
const BookingsPage = () => {
|
|
return (
|
|
<section className="h-full w-full text-right">
|
|
<PageNavbar pageTitle="رزروها" />
|
|
<div className="admin-page-container">
|
|
<PaginatedList
|
|
columns={columns}
|
|
url={API_ROUTES.BOOKINGS.ADMIN_LIST}
|
|
>
|
|
{{
|
|
userId: (row) => {
|
|
const user = row.user as BookingUser | undefined
|
|
|
|
if (!user) return '—'
|
|
|
|
const name = formatPersonName(user.firstName ?? undefined, user.lastName ?? undefined)
|
|
|
|
return (
|
|
<div className="flex flex-col gap-1">
|
|
<span>{name}</span>
|
|
<span
|
|
className="text-xs text-tertiary-300"
|
|
dir="ltr"
|
|
>
|
|
{formatIranianMobile(user.mobile)}
|
|
</span>
|
|
</div>
|
|
)
|
|
},
|
|
eventId: (row) => {
|
|
const event = row.event as BookingEvent | undefined
|
|
|
|
return event?.title ?? '—'
|
|
},
|
|
status: (_row, cellValue) => {
|
|
const { label, chipColor } = getBookingStatus(coerceToString(cellValue))
|
|
|
|
return (
|
|
<StatusChip
|
|
chipColor={chipColor}
|
|
label={label}
|
|
/>
|
|
)
|
|
},
|
|
cancellationReason: (row, cellValue) => {
|
|
const reason = coerceToString(cellValue).trim()
|
|
const isCancelledLike = row.status === 'cancelled' || row.status === 'refunded'
|
|
|
|
if (!isCancelledLike || !reason) return '—'
|
|
|
|
return <span className="max-w-[220px] whitespace-pre-wrap break-words text-xs text-secondary-20">{reason}</span>
|
|
},
|
|
checkedInAt: (_row, cellValue) => formatPersianDate(cellValue),
|
|
createdAt: (_row, cellValue) => formatPersianDate(cellValue),
|
|
actions: (row) => {
|
|
const user = row.user as BookingUser | undefined
|
|
|
|
if (!user) return '—'
|
|
|
|
return (
|
|
<AdminTableViewButton
|
|
label="مشاهده کاربر"
|
|
mode="navigate"
|
|
to={APP_ROUTES.USER_DETAIL(user.id)}
|
|
/>
|
|
)
|
|
},
|
|
}}
|
|
</PaginatedList>
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|
|
|
|
export default BookingsPage
|