feat: create OnlineBoardSearchPage for search results

This commit is contained in:
gnezim
2026-04-05 21:08:44 +03:00
parent 92ffc2a103
commit 573b99ea1c
3 changed files with 130 additions and 0 deletions
@@ -1 +1,2 @@
export { OnlineBoardStartPage } from './online-board-start-page'
export { OnlineBoardSearchPage } from './online-board-search-page'
@@ -0,0 +1,9 @@
.online-board-search-page {
width: 100%;
}
.online-board-search-page__content {
display: flex;
flex-direction: column;
gap: 16px;
}
@@ -0,0 +1,120 @@
import React, { useState, useEffect } from 'react'
import { useParams } from 'react-router-dom'
import axios from 'axios'
import { PageLayout } from '@app/components/page-layout'
import { PageTabs } from '@app/components/page-tabs'
import { PageLoader } from '@app/components/page-loader'
import { PageEmptyList } from '@app/components/page-empty-list'
import { DayTabs } from '@app/components/day-tabs'
import { OnlineBoardFilter } from '../components/online-board-filter'
import './online-board-search-page.scss'
interface Flight {
id: string
flightNumber: string
status: string
departure: any
arrival: any
aircraft?: string
operator?: string
}
export const OnlineBoardSearchPage: React.FC = () => {
const { params: encodedParams } = useParams<{ params: string }>()
const [selectedDate, setSelectedDate] = useState(new Date())
const [flights, setFlights] = useState<Flight[]>([])
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const [searchParams, setSearchParams] = useState<any>(null)
useEffect(() => {
if (!encodedParams) return
try {
const decoded = JSON.parse(atob(encodedParams))
setSearchParams(decoded)
} catch (err) {
console.error('Failed to decode params:', err)
setError('Invalid search parameters')
}
}, [encodedParams])
useEffect(() => {
if (!searchParams) return
const fetchFlights = async () => {
try {
setLoading(true)
setError(null)
// Build API request based on search type
let endpoint = '/api/flights'
const queryParams: Record<string, any> = {
date: selectedDate.toISOString().split('T')[0],
}
if (searchParams.flightNumber) {
queryParams.flightNumber = searchParams.flightNumber
}
if (searchParams.departure) {
queryParams.departure = searchParams.departure
}
if (searchParams.arrival) {
queryParams.arrival = searchParams.arrival
}
if (searchParams.startTime) {
queryParams.startTime = searchParams.startTime
}
if (searchParams.endTime) {
queryParams.endTime = searchParams.endTime
}
const response = await axios.get(endpoint, { params: queryParams })
setFlights(response.data?.flights || [])
} catch (err) {
console.error('Flight search failed:', err)
setError('Failed to load flights')
setFlights([])
} finally {
setLoading(false)
}
}
fetchFlights()
}, [searchParams, selectedDate])
if (error) {
return (
<div className="online-board-search-page" data-testid="online-board-search-page">
<PageTabs />
<PageEmptyList message={error} />
</div>
)
}
return (
<div className="online-board-search-page" data-testid="online-board-search-page">
<PageTabs />
<PageLoader isLoading={loading} />
<PageLayout
contentLeft={<OnlineBoardFilter />}
stickyContent={
<DayTabs
selectedDate={selectedDate}
onDateSelect={setSelectedDate}
/>
}
>
<div className="online-board-search-page__content">
{flights.length === 0 && !loading ? (
<PageEmptyList message="No flights found matching your criteria" />
) : (
<div data-testid="board-search-result">Flights: {flights.length}</div>
)}
</div>
</PageLayout>
</div>
)
}