File size: 1,671 Bytes
d6f7eeb
2e50ccd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d6f7eeb
 
 
 
 
 
 
 
 
 
 
 
 
2e50ccd
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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}`
  );
}