mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Passenger list report filter updates
This commit is contained in:
@@ -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 && (
|
||||
|
||||
Reference in New Issue
Block a user