fyliu's picture
Add flight booking flow with payment validation
d6f7eeb
import type { AutocompleteResult, BookingRequest, BookingResponse, CalendarResponse, SearchRequest, SearchResponse } from './types';
const BASE_URL = '/api';
async function fetchJson<T>(url: string, init?: RequestInit): Promise<T> {
const res = await fetch(url, init);
if (!res.ok) {
const text = await res.text();
throw new Error(`API error ${res.status}: ${text}`);
}
return res.json();
}
export async function searchAirports(query: string): Promise<AutocompleteResult[]> {
if (!query || query.length < 1) return [];
return fetchJson<AutocompleteResult[]>(
`${BASE_URL}/airports/autocomplete?q=${encodeURIComponent(query)}`
);
}
export async function searchFlights(req: SearchRequest): Promise<SearchResponse> {
return fetchJson<SearchResponse>(`${BASE_URL}/search`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(req),
});
}
export async function bookFlight(req: BookingRequest): Promise<BookingResponse> {
const res = await fetch(`${BASE_URL}/booking`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(req),
});
if (!res.ok) {
const data = await res.json().catch(() => null);
throw new Error(data?.detail || `Booking failed (${res.status})`);
}
return res.json();
}
export async function getCalendar(
origin: string,
destination: string,
year: number,
month: number,
cabinClass: string = 'economy'
): Promise<CalendarResponse> {
return fetchJson<CalendarResponse>(
`${BASE_URL}/calendar?origin=${origin}&destination=${destination}&year=${year}&month=${month}&cabin_class=${cabinClass}`
);
}