Commit Graph

39 Commits

Author SHA1 Message Date
gnezim 51f997e642 Match Angular layout in flights-map filter sidebar
- Add the 'Найдите свой маршрут' heading (uses the existing
  FLIGHTS-MAP.ROUTE key, previously unused).
- Reorder the fields to Angular's order: cities → info → toggles →
  date (date was previously stuck in the middle).
- Replace the three native checkboxes with styled pill toggles +
  sliding knobs — matches p-inputswitch used in the Angular filter.
- Add 'ДД.ММ.ГГГГ' placeholder to the date input so the empty state
  reads the same as Angular.
2026-04-18 10:26:24 +03:00
gnezim cd4864c82e Translate remaining route-level English strings
- Flights-map empty/error states: 'Failed to load routes. Please try
  again.' and 'No directions found.' now use existing translation keys
  (BOARD.LOAD-FAILED + FLIGHTS-MAP.NO_DIRECTIONS_INFO).
- Flights-map feature-flag fallback '404 - Page Not Found / This
  feature is currently unavailable.' reduced to the translated
  PAGE404.HEADER string.
- Suspense fallbacks on /onlineboard, /schedule, /flights-map and
  /popular route pages now render the new SHARED.LOADING ('Загрузка…')
  instead of hardcoded 'Loading...'.
2026-04-18 00:45:00 +03:00
gnezim 79fcf2bdc1 Fix onlineboard empty results and flights-map polyline zoom hazard
Online board: the /board endpoint treats dateFrom/dateTo as a half-open
interval, so sending the same date for both yielded zero rows on routes
that obviously have flights (e.g. SVO-LED). Mirror Angular's
OnlineBoardApiService.getFlightsByRoute and use dateTo = date + 1 day.

Flights map: two stacked problems made arcs disappear on zoom.
 - syncPolylines gated endpoints on map.hasLayer(marker); when
   syncVisibility removed a zoom-tier layer, its arc went with it.
 - The zoomend and toggle effects both called syncPolylines, which
   captured a stale closure from the first render (polylines = []) and
   wiped the layer. Polyline coords are geographic — Leaflet rescales
   them on zoom — so the rebuild was never necessary.
Arcs now render once per polylines prop change and stay put through
zoom and filter toggles.
2026-04-17 22:48:18 +03:00
gnezim 18ab969e1c Keep flights-map arcs visible when zoom tier layers are removed
syncPolylines filtered endpoints by map.hasLayer(marker), which drops
polylines whose endpoint's zoom-tier layer was just removed by
syncVisibility. Result: in spider mode, arcs to small/distant cities
vanished when the user zoomed out.

Arc coordinates are fixed by the city's lat/lng; render them as long as
the markers exist in the index. User-level filtering (domestic /
international) already happens upstream in filterRoutes, so the
hasLayer gate was both incorrect and redundant.
2026-04-17 22:40:46 +03:00
gnezim 5551cb1821 Fix flights-map date format and dev proxy empty-body status parsing
Upstream /destinations and /days endpoints expect yyyy-MM-DD (dashed),
matching Angular's ApiFormatterService.formatDateOnly output. React was
sending the internal compact yyyyMMdd, triggering silent 400s.

Also fix dev-server.mjs status-code parsing: empty-body curl responses
start with the appended "\n%{http_code}" separator at index 0, so
`lastNewline > 0` mis-treated the status as body and defaulted to 200,
hiding real upstream 4xx/5xx responses. Changed to `>= 0`.
2026-04-17 22:25:48 +03:00
gnezim c8d0caa9cf Fix five console-level issues surfaced by live-deploy Playwright audit
1. FlightsMap tiles didn't render: MapCanvas inline height:100% resolved
   to 0 against min-height parents. Hand sizing to consumer CSS so
   .flights-map-start__map height:500px wins.

2. FlightsMap /map/api/tile/{z}/{x}/{y}.jpeg requests fell through to
   Modern.js SSR (HTML body). Dev proxy now forwards /map/* to the
   test env via curl with image headers and binary-safe piping.

3. PopularRequestsPanel duplicate React key (Route-SVO-LED appears
   twice in upstream). Suffix the key with the visible index.

4. OnlineBoardDetailsPage /onlineboard/details 400. Upstream expects
   an ISO datetime (yyyy-MM-DDTHH:mm:ss), matching Angular's
   ApiFormatterService.formatDate. Append T00:00:00.

5. Browser-level SignalR CORS errors on every details page: the
   default SIGNALR_HUB_URL pointed at an unreachable placeholder.
   Default to empty + skip the connection in useLiveFlights when
   blank. Also configureLogging(LogLevel.None) so SignalR stops
   writing its own negotiation failures to console. Live updates
   re-enable by setting SIGNALR_HUB_URL on a deployment.
2026-04-17 21:55:44 +03:00
gnezim b54746c74c Fix flights-map tile URL to Angular parity /map/api/tile/{z}/{x}/{y}.jpeg
The tile URL was built as `${env.API_BASE_URL}/tiles/{z}/{x}/{y}.png`,
which has three problems on a real deployment:

1. Wrong path segment: the backend serves tiles under /map/api/tile/
   (singular), not /tiles/.
2. Wrong extension: the backend emits .jpeg, not .png.
3. Wrong base: API_BASE_URL may be empty or point at the JSON API host.
   Tiles are served by a dedicated upstream behind the same reverse
   proxy that fronts the React SSR, so they must be same-origin and
   relative (matches Angular environment.mapApiUrl).

With this fix, the map renders its base tiles on the deployed site
instead of issuing doomed requests and showing a blank canvas behind
the markers. The Leaflet marker layer was already rendering; only the
tile layer was missing.
2026-04-17 18:40:52 +03:00
gnezim 373f049e90 Use CityAutocomplete for FlightsMapFilter with geolocate on departure 2026-04-17 15:13:20 +03:00
gnezim c4ae1ef7aa Invoke useGeolocationDefault on FlightsMapStartPage mount 2026-04-17 12:22:29 +03:00
gnezim 0c65755553 Test FlightsMapFilter Calendar min/max/disabledDates + snap effect 2026-04-17 12:21:13 +03:00
gnezim 78b3e86418 Wire availableDays into FlightsMapFilter Calendar with snap-to-nearest 2026-04-17 12:20:37 +03:00
gnezim 73a3d03469 Add useGeolocationDefault hook for flights-map departure pre-fill 2026-04-17 12:17:11 +03:00
gnezim ef04c19e13 Add calendarRange helpers for flights-map date picker window and snapping 2026-04-17 12:16:22 +03:00
gnezim f4b96b8248 Test FlightsMapStartPage filterRoutes + popups + auto-fallback wiring 2026-04-17 11:06:16 +03:00
gnezim 4e92e79a99 Wire filterRoutes, auto-fallback, and buy-ticket popups into Flights Map
routesToPolylines + intermediateCityIds now normalize airport codes to city
codes via the dictionaries so API responses resolve correctly. The page adds
effectiveConnections state + two effects for Angular-parity fallback
(retry connections=1 on empty direct-route result, then flip the UI toggle),
a filterRoutes memo feeding polylines and intermediateIds, and a popups memo
rendering departure + arrival buy-ticket popups in route mode only.
2026-04-17 11:00:40 +03:00
gnezim 77272423c1 Add buildBuyTicketUrl + escapeHtml helpers for popup content 2026-04-17 10:52:32 +03:00
gnezim 40f170f87a Add filterRoutes pure helper with airport-code normalization 2026-04-17 10:52:27 +03:00
gnezim 76e9270f5e Test FlightsMapStartPage polyline + intermediateIds wiring 2026-04-17 10:14:06 +03:00
gnezim 4e103d8073 Drive polylines and intermediateIds from useFlightsMapSearch routes 2026-04-17 10:12:15 +03:00
gnezim a9ed92466f Draw routes as city-code polylines and force-open intermediate tooltips
- routesToPolylines + intermediateCityIds pure helpers with unit coverage.
- IMapPolyline reshaped from points to cityIds for Angular-parity drawing.
- MapCanvas resolves coords via markerIndex, filters invisible cities on
  every zoom/toggle change, and runs a second tooltip pass that keeps
  intermediate-city tooltips open regardless of zoom/highlight rules.
2026-04-17 10:08:44 +03:00
gnezim a9b47036b5 Test FlightsMapStartPage marker construction from dictionaries 2026-04-17 08:46:43 +03:00
gnezim 1f24ee7159 Populate FlightsMapStartPage markers from dictionaries with zoom tiers 2026-04-17 08:44:40 +03:00
gnezim 725a048315 Add categorized rendering to MapCanvas: zoom-tier layers, highlight layer, tooltip rules 2026-04-17 08:41:42 +03:00
gnezim 54f9282a99 Extend IMapMarker with zoomLevel, countryType, highlighted fields 2026-04-17 08:35:27 +03:00
gnezim a61457bc90 Port Angular CityCategoryService to feature-local cityCategory module 2026-04-17 08:35:01 +03:00
gnezim 9a7fcba6ff Test FlightsMapStartPage dictionaries loading/error wiring 2026-04-17 03:21:39 +03:00
gnezim cfc6e12dc9 Wire useDictionaries into FlightsMapStartPage loading/error states 2026-04-17 03:20:01 +03:00
gnezim bb0353bb40 Match Schedule and Flights Map pages to Angular pixel-for-pixel
CI / ci (push) Failing after 37s
Deploy / build-and-deploy (push) Failing after 6s
Schedule: add SearchHistory below filter, time selector fields (timeFrom/timeTo)
for outbound and return flights, breadcrumbs, and bottom description section.

Flights Map: add FILTER_INFO message in filter panel, disabled states on
toggles when no departure/arrival selected (matching Angular logic), breadcrumbs,
and replace plain "Loading..." text with animated spinner matching Angular
loader-sheet component.
2026-04-16 01:09:04 +03:00
gnezim 5fc67f81bd Wire city autocomplete to dictionary API
CI / ci (push) Failing after 37s
Deploy / build-and-deploy (push) Failing after 6s
useCitySearch hook loads cities from /api/dictionary/1/cities on first
use, then searches in-memory by name prefix and code -- matching the
Angular CitiesSearchService behavior. Wired into OnlineBoardFilter,
ScheduleStartPage, and FlightsMapFilter AutoComplete components.
2026-04-15 21:32:39 +03:00
gnezim f61e050e8c Configure dev proxy to flights.test.aeroflot.ru and fix API endpoint paths
API functions now build the full localized path matching the Angular
EndpointService pattern (/api/flights/{version}/{locale}/{endpoint}).
The dev proxy forwards /api and /flights to the test backend.
2026-04-15 21:32:28 +03:00
gnezim cbd47afd77 Wire flights-map feature flag through PageTabs and fix map component issues
PageTabs now reads the FEATURE_FLIGHTS_MAP flag directly via useFeatureFlag
instead of relying on a prop default, matching the Angular page-tabs pattern.
FlightsMapFilter uses PrimeReact AutoComplete and Calendar instead of plain
HTML inputs, with i18n labels. MapCanvas init effect uses refs to avoid
React exhaustive-deps warnings. Root layout imports leaflet CSS and
PrimeReact theme globally. Env schema accepts NODE_ENV "test" for vitest.
2026-04-15 20:38:39 +03:00
gnezim dee10544e0 Polish Flights Map page with PageLayout, tabs, and filter styling
CI / ci (push) Failing after 38s
Deploy / build-and-deploy (push) Failing after 6s
Flights Map now uses PageLayout with PageTabs (flights-map tab active),
filter in content-left column, and map in a .frame section. Added SCSS
for filter panel and map wrapper matching Angular structure.
2026-04-15 19:35:02 +03:00
gnezim 5839692e52 Fix lint and typecheck issues in flights-map feature
Add explicit undefined to optional properties for exactOptionalPropertyTypes
compatibility. Remove unused import. Fix non-null assertions with proper
null guards. Remove invalid eslint-disable comment.
2026-04-15 09:51:23 +03:00
gnezim a60494366f Update flights-map barrel and MF expose from stub to real
Populate the feature barrel with all 4A-4D exports. Replace the
FlightsMap MF expose stub with lazy-loaded FlightsMapStartPage,
gated by the flightsMap feature flag.
2026-04-15 09:43:54 +03:00
gnezim 0f5d7915be Add flights-map SEO builder and JSON-LD WebPage schema
Phase 4D: buildFlightsMapSeo generates meta tags, canonical, hreflang, OG
and Twitter Card props. buildFlightsMapJsonLd produces a schema.org WebPage
object for structured data. 10 tests cover both builders.
2026-04-15 09:43:24 +03:00
gnezim a2cf781b02 Add flights-map route page, start page container, and filter
Phase 4C: FlightsMapStartPage manages filter state and drives search/calendar
hooks. FlightsMapFilter provides departure/arrival/connections/domestic/
international controls. Route page gates on flightsMap feature flag, rendering
404 when disabled.
2026-04-15 09:42:31 +03:00
gnezim dc030aceea Add Leaflet map wrapper and ClientOnly SSR-safe component
Phase 4B: MapCanvas.tsx is the sole Leaflet consumer in the codebase.
Renders markers (blue/orange), polylines (solid/dashed) with great-circle
arcs, popups and tooltips. Accepts all data as props (stateless).
ClientOnly.tsx provides SSR safety by deferring render until mount.
2026-04-15 09:41:11 +03:00
gnezim aa61049229 Add flights-map types, API functions, hooks, and feature flag
Phase 4A: Define IFlightRoute, IMapMarker, IMapPolyline types; implement
searchDestinations and getFlightsMapCalendar API functions with 11 tests;
add useFlightsMapSearch, useFlightsMapCalendar hooks; add FEATURE_FLIGHTS_MAP
env var for feature flag gating.
2026-04-15 09:40:19 +03:00
gnezim 0b9ea74617 Seed frozen public barrels for 4 features + UI adapter 2026-04-14 22:07:26 +03:00