# Phase 4 -- Flights Map (Master Plan)

## Goal

Port the Angular `flights-map` feature (single `/flights-map` route) to the React/ModernJS codebase as a Module Federation remote component. The map uses Leaflet for interactive marker/polyline rendering and is behind the `flightsMap` feature flag.

## Angular analysis summary

- **Route:** `/flights-map` (start page with embedded Leaflet map)
- **Feature flag:** `flightsMap` (env-based)
- **APIs:** `destinations/v1` (search routes by departure/arrival), `days/.../flights-map/v1` (calendar availability)
- **Leaflet map:** markers (blue default, blue-small zoom-dependent, orange selected), polylines (solid direct, dashed connecting), popups, tooltips, zoom-aware layer visibility
- **Components:** start page container, map body (sole Leaflet consumer), filter panel, meta tags, loader/empty overlays
- **No SignalR** -- data is static, fetched on filter change
- **SEO:** meta tags only in Angular; design spec requires JSON-LD `WebPage` schema

## Sub-plans

### 4A -- Types + API + Hooks

**Files:** `src/features/flights-map/types.ts`, `api.ts`, `api.test.ts`, `hooks/useFlightsMapSearch.ts`, `hooks/useFlightsMapCalendar.ts`

- Define `IFlightRoute`, `IMapMarker`, `IMapPolyline`, `FlightsMapSearchParams`, `FlightsMapCalendarParams`
- Define `IDestinationsResponse`, `IFlightsMapDaysResponse`
- API: `searchDestinations(client, params)` -> `GET destinations/1`, `getFlightsMapCalendar(client, params)` -> `GET days/{date}/200/{route}/flights-map/v1`
- Hooks: `useFlightsMapSearch(params)`, `useFlightsMapCalendar(params)`
- Feature flag: `useFeatureFlag("flightsMap")` via env config
- TDD: ~10 tests for API functions

### 4B -- Leaflet Map Wrapper

**File:** `src/features/flights-map/components/MapCanvas.tsx`

- **Only file that imports `leaflet`** (design spec constraint)
- Wrapped in `React.lazy()` + `<ClientOnly>` (SSR-safe)
- Accepts `markers`, `polylines`, `onMarkerClick` etc. as props -- does not own state
- Renders markers (blue/orange icons), polylines (solid/dashed), popups, tooltips
- Great-circle arc calculation for polyline rendering
- Install `leaflet` + `@types/leaflet`
- No TDD (Leaflet requires real DOM)

### 4C -- Route Pages + Feature Components

**Files:**
- `src/routes/[lang]/flights-map/page.tsx` -- route page with SEO + feature flag guard
- `src/features/flights-map/components/FlightsMapStartPage.tsx` -- container (filter + map + loading/empty states)
- `src/features/flights-map/components/FlightsMapFilter.tsx` -- search filter (departure, arrival, connections, domestic/international toggles, date picker)
- `src/features/flights-map/components/ClientOnly.tsx` -- SSR-safe wrapper

### 4D -- SEO + JSON-LD + Parity

**Files:**
- `src/features/flights-map/seo.ts` -- `buildFlightsMapSeo(t, locale, canonicalOrigin)`
- `src/features/flights-map/json-ld.ts` -- JSON-LD `WebPage` schema builder
- `src/features/flights-map/seo.test.ts` -- ~5 integration tests
- Update barrel `src/features/flights-map/index.ts`
- Update `src/mf/expose/FlightsMap.tsx` from stub to real

## Dependency graph

```
4A (types/api/hooks) --> 4B (map canvas, needs types)
                     --> 4C (pages/components, needs hooks)
4A + 4B + 4C --------> 4D (SEO + barrel + MF expose update)
```

## Verification

```bash
pnpm typecheck && pnpm lint && pnpm test && pnpm build:standalone
```

## Constraints

- Do NOT touch `ClientApp/`, ASP.NET, `wwwroot/`
- No `Co-Authored-By` lines in commits
- ~8-12 commits total
