# Phase 2C — API Client Functions + React Hooks

> **Parent plan:** `2026-04-14-phase-2-online-board-master.md` (sub-plan 2C)

## Goal

Wrap the three Online Board REST endpoints in typed, pure API functions and thin React hooks. API functions are dependency-injected with `ApiClient`; hooks use `useApiClient()` from context.

## Prerequisites

- Phase 1 `ApiClient` (`src/shared/api/client.ts`) and `useApiClient` (`src/shared/api/provider.tsx`) exist.
- Phase 2A types (`src/features/online-board/types.ts`) exist: `ISimpleFlight`, `IBoardResponse`, `IDaysResponse`, `IParsedFlightId`, `FlightRequestType`.
- Phase 2B URL serializer (`src/features/online-board/url.ts`) exists.

## Deliverables

| File | Purpose |
|---|---|
| `src/features/online-board/api.ts` | Pure API functions: `searchFlights`, `getFlightDetails`, `getCalendarDays` |
| `src/features/online-board/api.test.ts` | TDD tests for API functions (mock fetch, verify URL construction + response mapping) |
| `src/features/online-board/hooks/useOnlineBoard.ts` | React hook for search pages |
| `src/features/online-board/hooks/useFlightDetails.ts` | React hook for details page |
| `src/features/online-board/hooks/useCalendarDays.ts` | React hook for calendar availability |
| `src/features/online-board/index.ts` | Updated barrel exports |

## Tasks

### T1: Define API function param types and write `api.ts`

**File:** `src/features/online-board/api.ts`

Three pure functions, each taking `ApiClient` as first param:

1. `searchFlights(client, params)` — builds `GET /{locale}/board?...` with optional query params: `flightNumber`, `dateFrom`, `dateTo`, `departure`, `arrival`, `timeFrom`, `timeTo`. Returns `IBoardResponse`.

2. `getFlightDetails(client, params)` — builds `GET /{locale}/onlineboard/details?flights={carrier}{number}&dates={date}`. Returns `IBoardResponse`.

3. `getCalendarDays(client, params)` — builds `GET /v1/days/{date}/31/{searchType}/{searchParams}/board/`. Returns parsed `string[]` from `IDaysResponse.days`.

**Key design decisions:**
- Functions are PURE — no context, no hooks, no side effects.
- Use `ApiClient.get<T>(path, query)` for query-param endpoints.
- For calendar endpoint, build the path string directly (it's path-based, not query-based).
- Map `IDaysResponse.days` (a single string) to `string[]` by splitting on comma.

### T2: Write TDD tests for `api.ts`

**File:** `src/features/online-board/api.test.ts`

Test cases:
- `searchFlights`: correct URL + query params for flight-number search, route search, departure-only, arrival-only; response deserialization
- `getFlightDetails`: correct URL + query params; response deserialization
- `getCalendarDays`: correct path construction for flight type, route type, departure type, arrival type; response mapping from comma-separated string to array
- Error cases: 404 throws `ApiHttpError`, timeout throws `ApiTimeoutError`

Mock strategy: create `ApiClient` with a mock `fetchImpl` that captures the request URL and returns canned responses.

### T3: Write `useOnlineBoard` hook

**File:** `src/features/online-board/hooks/useOnlineBoard.ts`

- Gets `ApiClient` via `useApiClient()`
- `useState` for flights, loading, error
- `useEffect` calls `searchFlights` on param change
- Returns `{ flights, loading, error, refresh }`

### T4: Write `useFlightDetails` hook

**File:** `src/features/online-board/hooks/useFlightDetails.ts`

- Gets `ApiClient` via `useApiClient()`
- `useState` for flight, loading, error
- `useEffect` calls `getFlightDetails` on param change
- Returns `{ flight, loading, error }`

### T5: Write `useCalendarDays` hook

**File:** `src/features/online-board/hooks/useCalendarDays.ts`

- Gets `ApiClient` via `useApiClient()`
- `useState` for days, loading
- `useEffect` calls `getCalendarDays` on param change
- Returns `{ days, loading }`

### T6: Update barrel exports in `index.ts`

Add API functions and hooks to the public barrel.

### T7: Verify — `pnpm typecheck && pnpm lint && pnpm test`

## Exit gate

- All API function tests pass (URL construction, response mapping, error handling).
- `pnpm typecheck` green — zero `any` types.
- `pnpm lint` green.
- Hooks compile and export correctly.
