Flight Search - Requirements & Frontend Specification¶
Overview¶
Standalone flight search page accessible from Products > Flights in the admin interface. Allows agents to search for flights across supported providers (Google Flights via RapidAPI) without requiring a TripMaker project context.
Files:
- tqweb-adm/flights.html - Page structure
- tqweb-adm/js/modules/flight-search.js - JavaScript ES6 module
Requirements¶
Functional Requirements¶
| ID | Requirement | Status |
|---|---|---|
| FS-01 | Search one-way flights by origin, destination, departure date | Implemented |
| FS-02 | Search round-trip flights with two-step outbound/return selection | Implemented |
| FS-03 | Airport autocomplete with IATA code resolution | Implemented |
| FS-04 | Passenger configuration: adults, children, infants | Implemented |
| FS-05 | Cabin class selection (Economy, Premium Economy, Business, First) | Implemented |
| FS-06 | Currency selection from server-configured quotation currencies | Implemented |
| FS-07 | Paginated search results (10 per page) | Implemented |
| FS-08 | Display flight details: airline, route, times, duration, stops, price | Implemented |
| FS-09 | Handle unavailable pricing gracefully (show "N/A", disable actions) | Implemented |
| FS-10 | "Add to Cart" button (placeholder for future cart integration) | Placeholder |
Non-Functional Requirements¶
- No dependency on TripMaker modules (
tripmaker-common.jsnot imported) - All API calls go through
tlinq()directly fromglobals.js - Authentication required (agent/admin roles)
Architecture¶
flights.html
↓ imports
flight-search.js
↓ calls via tlinq()
┌─────────────────────────────────────┐
│ flight/search (outbound) │
│ flight/search/return (returns) │
│ flight/fetchResults (pagination) │
│ tripmaker/location/search (airports)│
└─────────────────────────────────────┘
API Wrapper¶
FlightSearchAPI object in flight-search.js wraps four endpoints:
| Method | Endpoint | Purpose |
|---|---|---|
search(params) |
flight/search |
Initial flight search |
searchReturn(params) |
flight/search/return |
Return flight search after outbound selection |
fetchResults(searchId, page) |
flight/fetchResults |
Paginated results |
searchAirports(keyword) |
tripmaker/location/search |
Airport autocomplete (purpose=AIRPORT) |
User Interface¶
Search Panel¶
Collapsible card with: - Row 1: Origin airport (autocomplete) | Destination airport (autocomplete) | Departure date | Return date (optional) | Trip type badge (auto-detected) - Row 2: Adults (1-9) | Children (0-9) | Infants (0-4) | Cabin class | Currency
Search Results¶
Table with columns: Airline (logo + code), Route, Departure, Arrival, Duration, Stops, Price, Action.
Action buttons vary by context: - One-way search: "Add to Cart" (green, placeholder) - Round-trip outbound: "Select Outbound" (blue, triggers return search) - Round-trip return: "Add to Cart" (green, placeholder) - Price unavailable: Disabled "N/A" button (muted)
Two-Step Round-Trip Flow¶
- User enters origin, destination, departure + return dates → searches
- Results show outbound flights with "Select Outbound" buttons
- User selects outbound → system searches return flights
- Blue info banner shows selected outbound summary with "Change" link
- Return results show "Add to Cart" buttons
- "Change" link returns to cached outbound results
Price Handling¶
The external API (Google Flights via RapidAPI) may return "price": "unavailable" instead of a numeric value. This is handled at two levels:
- Backend:
GoogleFlightsClientServiceuses lenient GsonTypeAdapterforDouble/Integerthat returnsnullfor non-numeric strings - Frontend:
grandTotalnull → price displays as "N/A" (muted text), action buttons are disabled