Passenger list report filter updates

This commit is contained in:
Stephanos A
2026-07-19 22:52:23 +03:00
parent eb41f4bb5f
commit 8e84fcebd5
2 changed files with 42 additions and 17 deletions

View File

@@ -27,13 +27,17 @@ interface PassengerRow {
passportNumber: string | null;
passportCountry: string | null;
seatLabel: string | null;
seatNumber: string | null;
seatClassName: string | null;
coachNumber: string | null;
coachType: string | null;
nationality: string | null;
origin: string | null;
destination: string | null;
amountPaidMinor: number;
currency: string;
isGroupBooking: boolean;
bookingStatus: string;
}
type Tab = 'occupancy' | 'list';
@@ -44,6 +48,7 @@ export default function PassengersReportPage() {
const [listSearch, setListSearch] = useState('');
const [filterCoach, setFilterCoach] = useState('');
const [filterOrigin, setFilterOrigin] = useState('');
const [filterSeatClass, setFilterSeatClass] = useState('');
const { data: schedulesRaw, isLoading: loadingSchedules } = useQuery<ScheduleOption[]>({
queryKey: ['report-schedules'],
@@ -65,11 +70,13 @@ export default function PassengersReportPage() {
const coachOptions = [...new Set(passengerList.map(p => p.coachNumber).filter(Boolean))].sort() as string[];
const originOptions = [...new Set(passengerList.map(p => p.origin).filter(Boolean))].sort() as string[];
const seatClassOptions = [...new Set(passengerList.map(p => p.seatClassName).filter(Boolean))].sort() as string[];
const filteredList = passengerList
.filter(p => {
if (filterCoach && p.coachNumber !== filterCoach) return false;
if (filterOrigin && p.origin !== filterOrigin) return false;
if (filterSeatClass && p.seatClassName !== filterSeatClass) return false;
if (listSearch.trim()) {
const q = listSearch.toLowerCase();
return (
@@ -126,7 +133,7 @@ export default function PassengersReportPage() {
<select
className="input"
value={scheduleId}
onChange={e => { setScheduleId(e.target.value); setTab('occupancy'); setListSearch(''); setFilterCoach(''); setFilterOrigin(''); }}
onChange={e => { setScheduleId(e.target.value); setTab('occupancy'); setListSearch(''); setFilterCoach(''); setFilterOrigin(''); setFilterSeatClass(''); }}
disabled={loadingSchedules}
>
<option value="">{loadingSchedules ? 'Loading schedules…' : 'Select a schedule…'}</option>
@@ -294,6 +301,14 @@ export default function PassengersReportPage() {
value={listSearch}
onChange={e => setListSearch(e.target.value)}
/>
<select className="input w-40" value={filterSeatClass} onChange={e => setFilterSeatClass(e.target.value)}>
<option value="">All classes</option>
{seatClassOptions.map(c => <option key={c} value={c}>{c}</option>)}
</select>
<select className="input w-36" value={filterOrigin} onChange={e => setFilterOrigin(e.target.value)}>
<option value="">All origins</option>
{originOptions.map(o => <option key={o} value={o}>{o}</option>)}
</select>
{passengerList.length > 0 && (
<ActionButton icon={Download} variant="secondary" onClick={doExportList}>Export CSV</ActionButton>
)}
@@ -314,20 +329,11 @@ export default function PassengersReportPage() {
{filteredList.map((p, i) => (
<tr key={`${p.bookingRef}-${i}`} className="hover:bg-muted/30">
<td className="py-2 pr-4 font-medium">{p.passengerName}</td>
<td className="py-2 pr-4 text-xs">
{p.passportNumber ? (
<>
<span className="text-muted-foreground">{p.passportCountry ?? 'Intl'}</span>
<span className="ml-1 font-mono">{p.passportNumber}</span>
</>
) : (
<span className="text-muted-foreground">{p.idDocumentNumber ?? '—'}</span>
)}
<td className="py-2 pr-4 text-xs whitespace-nowrap">
{[p.nationality, p.passportNumber].filter(Boolean).join(' · ') || '—'}
</td>
<td className="py-2 pr-4 font-mono text-xs">
{p.coachNumber && p.seatLabel
? <>{p.coachNumber} · {p.seatLabel}{p.coachType && <span className="font-sans text-muted-foreground ml-1">({p.coachType})</span>}</>
: (p.coachNumber ?? p.seatLabel ?? '—')}
<td className="py-2 pr-4 font-mono text-xs whitespace-nowrap">
{[p.coachNumber, p.seatNumber ?? p.seatLabel, p.seatClassName].filter(Boolean).join(' · ') || '—'}
</td>
<td className="py-2 pr-4 text-muted-foreground text-xs">
{p.origin && p.destination ? `${p.origin}${p.destination}` : (p.origin ?? p.destination ?? '—')}
@@ -342,7 +348,14 @@ export default function PassengersReportPage() {
)}
</div>
</td>
<td className="py-2 font-mono text-xs">{p.bookingRef}</td>
<td className="py-2 font-mono text-xs">
<div className="flex items-center gap-1.5">
{p.bookingRef}
{p.bookingStatus !== 'CONFIRMED' && p.bookingStatus !== 'BOARDED' && (
<span className="inline-flex items-center rounded px-1.5 py-0.5 text-[10px] font-semibold bg-yellow-100 text-yellow-700 dark:bg-yellow-900/40 dark:text-yellow-300">{p.bookingStatus.replace('_', ' ')}</span>
)}
</div>
</td>
</tr>
))}
{filteredList.length === 0 && (