Fix critical blockers in passenger count selector feature

CRITICAL ISSUE #1: Callback Signature Mismatch
- Updated handleRouteSearch callback to include passengers parameter
- Added passengers to params encoding in navigation state
- Updated OnlineBoardFilterProps to include passengers in initialSearchParams

CRITICAL ISSUE #2: Missing Validation on initialPassengers
- Added validatePassengerCounts function to validate and sanitize passenger counts
- Ensures all values are in valid range (0-9) and total doesn't exceed 9
- Updated state initialization to use validated passenger counts
- Removed unnecessary type assertion from handleSearch callback

Changes:
- online-board-filter.tsx: Updated callback signature and params encoding
- route-filter.tsx: Added passenger validation function and updated state init
This commit is contained in:
gnezim
2026-04-06 08:32:14 +03:00
parent 32cc851f72
commit ec0c67db91
2 changed files with 26 additions and 6 deletions
@@ -14,6 +14,7 @@ interface OnlineBoardFilterProps {
returnDate?: string | Date returnDate?: string | Date
flightNumber?: string flightNumber?: string
tripType?: string tripType?: string
passengers?: { adults: number, children: number, infants: number }
} }
} }
@@ -28,7 +29,7 @@ export const OnlineBoardFilter: React.FC<OnlineBoardFilterProps> = ({ initialSea
navigate(`/onlineboard/flight/${params}`) navigate(`/onlineboard/flight/${params}`)
} }
const handleRouteSearch = (departure: string, arrival: string, date: Date, returnDate?: Date | null, tripType?: string) => { const handleRouteSearch = (departure: string, arrival: string, date: Date, returnDate?: Date | null, tripType?: string, passengers?: { adults: number, children: number, infants: number }) => {
// Navigate to route search results // Navigate to route search results
const params = btoa(JSON.stringify({ const params = btoa(JSON.stringify({
departure, departure,
@@ -36,6 +37,7 @@ export const OnlineBoardFilter: React.FC<OnlineBoardFilterProps> = ({ initialSea
date: date.toISOString(), date: date.toISOString(),
...(returnDate && { returnDate: returnDate.toISOString() }), ...(returnDate && { returnDate: returnDate.toISOString() }),
...(tripType && { tripType }), ...(tripType && { tripType }),
...(passengers && { passengers }),
})) }))
navigate(`/onlineboard/route/${params}`) navigate(`/onlineboard/route/${params}`)
} }
@@ -63,6 +65,7 @@ export const OnlineBoardFilter: React.FC<OnlineBoardFilterProps> = ({ initialSea
initialDate={initialSearchParams?.date} initialDate={initialSearchParams?.date}
initialReturnDate={initialSearchParams?.returnDate} initialReturnDate={initialSearchParams?.returnDate}
initialTripType={initialSearchParams?.tripType} initialTripType={initialSearchParams?.tripType}
initialPassengers={initialSearchParams?.passengers}
/> />
</AccordionTab> </AccordionTab>
</Accordion> </Accordion>
@@ -23,6 +23,23 @@ export interface RouteFilterProps {
} }
// Validation service // Validation service
const validatePassengerCounts = (passengers?: PassengerCounts): PassengerCounts => {
if (!passengers) return { adults: 1, children: 0, infants: 0 }
const safe = {
adults: Math.max(0, Math.min(9, Math.floor(passengers.adults || 0))),
children: Math.max(0, Math.min(9, Math.floor(passengers.children || 0))),
infants: Math.max(0, Math.min(9, Math.floor(passengers.infants || 0))),
}
// Ensure total doesn't exceed 9
const total = safe.adults + safe.children + safe.infants
if (total > 9) {
return { adults: Math.min(9, safe.adults), children: 0, infants: 0 }
}
return safe
}
const validateCityCode = (code: string | undefined): boolean => { const validateCityCode = (code: string | undefined): boolean => {
if (!code) return false if (!code) return false
return /^[A-Z]{3}$/.test(code.toUpperCase()) return /^[A-Z]{3}$/.test(code.toUpperCase())
@@ -63,6 +80,7 @@ export const RouteFilter: React.FC<RouteFilterProps> = ({
initialPassengers initialPassengers
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const validated = validatePassengerCounts(initialPassengers)
const [departure, setDeparture] = useState<City | null>(getCityByCode(initialDeparture)) const [departure, setDeparture] = useState<City | null>(getCityByCode(initialDeparture))
const [arrival, setArrival] = useState<City | null>(getCityByCode(initialArrival)) const [arrival, setArrival] = useState<City | null>(getCityByCode(initialArrival))
const [date, setDate] = useState<Date | null>( const [date, setDate] = useState<Date | null>(
@@ -80,9 +98,9 @@ export const RouteFilter: React.FC<RouteFilterProps> = ({
) )
const [startTime, setStartTime] = useState('00:00') const [startTime, setStartTime] = useState('00:00')
const [endTime, setEndTime] = useState('23:59') const [endTime, setEndTime] = useState('23:59')
const [adults, setAdults] = useState(initialPassengers?.adults || 1) const [adults, setAdults] = useState(validated.adults)
const [children, setChildren] = useState(initialPassengers?.children || 0) const [children, setChildren] = useState(validated.children)
const [infants, setInfants] = useState(initialPassengers?.infants || 0) const [infants, setInfants] = useState(validated.infants)
const [showPassengerDropdown, setShowPassengerDropdown] = useState(false) const [showPassengerDropdown, setShowPassengerDropdown] = useState(false)
const totalPassengers = adults + children + infants const totalPassengers = adults + children + infants
@@ -102,8 +120,7 @@ export const RouteFilter: React.FC<RouteFilterProps> = ({
const handleSearch = useCallback(() => { const handleSearch = useCallback(() => {
if (validateRouteParams(departure, arrival, date) && onSearch) { if (validateRouteParams(departure, arrival, date) && onSearch) {
// Pass all search parameters including return date for round trips and passenger counts // Pass all search parameters including return date for round trips and passenger counts
const handler = onSearch as (departure: string, arrival: string, date: Date, returnDate?: Date | null, tripType?: string, passengers?: PassengerCounts) => void onSearch(departure!.code, arrival!.code, date!, returnDate, tripType, { adults, children, infants })
handler(departure!.code, arrival!.code, date!, returnDate, tripType, { adults, children, infants })
} }
}, [departure, arrival, date, returnDate, tripType, adults, children, infants, onSearch]) }, [departure, arrival, date, returnDate, tripType, adults, children, infants, onSearch])