From ed8a5626a4ea4c4b0639ef5dfe5bf26c828dd6d8 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Tue, 26 May 2026 12:55:23 +0100 Subject: [PATCH] Refine homepage journey form layout --- app.py | 31 +++++++++++++++++++--------- templates/base.html | 27 ++++++++++++++++++++++-- templates/index.html | 49 ++++++++++++++++++++++---------------------- tests/test_app.py | 5 +++-- 4 files changed, 74 insertions(+), 38 deletions(-) diff --git a/app.py b/app.py index ed09bf5..4fc7e34 100644 --- a/app.py +++ b/app.py @@ -32,6 +32,8 @@ from trip_planner import ( find_unreachable_inbound_eurostars, find_unreachable_morning_eurostars, ) +import cache +import circle_line RTT_PADDINGTON_URL = ( "https://www.realtimetrains.co.uk/search/detailed/" @@ -51,9 +53,6 @@ _local = os.path.join(os.path.dirname(__file__), "config", "local.py") if os.path.exists(_local): app.config.from_pyfile(_local) -import cache -import circle_line - cache.CACHE_DIR = app.config["CACHE_DIR"] # type: ignore[attr-defined] circle_line._TXC_XML = app.config["CIRCLE_LINE_XML"] # type: ignore[attr-defined] @@ -72,13 +71,25 @@ def _load_stations() -> list[tuple[str, str]]: STATIONS = _load_stations() STATION_BY_CRS = {crs: name for name, crs in STATIONS} +DESTINATION_OPTIONS = [ + {"slug": "paris", "city": "Paris", "destination": "Paris Gare du Nord"}, + {"slug": "brussels", "city": "Brussels", "destination": "Brussels Midi"}, + {"slug": "lille", "city": "Lille", "destination": "Lille Europe"}, + { + "slug": "amsterdam", + "city": "Amsterdam", + "destination": "Amsterdam Centraal", + }, + { + "slug": "rotterdam", + "city": "Rotterdam", + "destination": "Rotterdam Centraal", + }, + {"slug": "cologne", "city": "Cologne Hbf", "destination": "Cologne Hbf"}, +] + DESTINATIONS = { - "paris": "Paris Gare du Nord", - "brussels": "Brussels Midi", - "lille": "Lille Europe", - "amsterdam": "Amsterdam Centraal", - "rotterdam": "Rotterdam Centraal", - "cologne": "Cologne Hbf", + option["slug"]: option["destination"] for option in DESTINATION_OPTIONS } @@ -88,7 +99,7 @@ def index() -> ResponseReturnValue: default_min, default_max = _get_defaults() return render_template( "index.html", - destinations=DESTINATIONS, + destination_options=DESTINATION_OPTIONS, today=today, stations=STATIONS, default_min_connection=default_min, diff --git a/templates/base.html b/templates/base.html index 242196a..5aeafa9 100644 --- a/templates/base.html +++ b/templates/base.html @@ -95,6 +95,10 @@ gap: 0.75rem; } + .destination-grid--eurostar { + grid-template-columns: repeat(6, minmax(0, 1fr)); + } + .destination-option { position: relative; } @@ -110,7 +114,7 @@ .destination-option label { display: block; min-height: 100%; - padding: 0.95rem 1rem; + padding: 0.8rem 0.85rem; border: 1px solid #cbd5e0; border-radius: 10px; background: linear-gradient(180deg, #ffffff 0%, #f8fbff 100%); @@ -121,7 +125,7 @@ .destination-option label strong { display: block; color: #0f172a; - font-size: 1rem; + font-size: 0.98rem; margin-bottom: 0.2rem; } @@ -184,6 +188,10 @@ @media (max-width: 640px) { .card { padding: 1.25rem; } + .destination-grid--eurostar { + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + } + /* Convert results table to a 2-column card layout per row */ .results-table, .results-table tbody { display: block; } .results-table thead { display: none; } @@ -233,6 +241,21 @@ /* Form groups */ .form-group { margin-bottom: 1.2rem; } .form-group-lg { margin-bottom: 1.5rem; } + .form-row { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 1rem; + margin-bottom: 1.5rem; + } + .form-row .form-group, + .form-row .form-group-lg { + margin-bottom: 0; + } + @media (max-width: 640px) { + .form-row { + grid-template-columns: 1fr; + } + } #return-date-group:has(input:disabled) { cursor: pointer; } /* Buttons */ diff --git a/templates/index.html b/templates/index.html index 898a6e4..20882e8 100644 --- a/templates/index.html +++ b/templates/index.html @@ -99,13 +99,12 @@
Eurostar destination -
- {% for slug, name in destinations.items() %} - {% set city = name.replace(' Gare du Nord','').replace(' Centraal','').replace(' Midi','').replace(' Europe','') %} +
+ {% for destination in destination_options %}
- - +
{% endfor %}
@@ -128,26 +127,28 @@
-
- - -
+
+
+ + +
-
- - +
+ + +
diff --git a/tests/test_app.py b/tests/test_app.py index a7ea82b..9b19b31 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -64,8 +64,9 @@ def test_index_shows_station_dropdown_and_destination_radios() -> None: assert "Departure point" in html assert "Bristol Temple Meads" in html assert 'name="station_crs"' in html - assert html.count('type="radio"') == len(app_module.DESTINATIONS) - assert "destination-rotterdam" in html + assert html.count('name="destination"') == len(app_module.DESTINATIONS) + assert 'id="dest-rotterdam"' in html + assert "Cologne HbfCologne Hbf" in html def test_search_redirects_to_results_with_selected_params() -> None: