Tidy results table layout and centralise connection defaults
- Redesign results table from 8 columns to 4 (National Rail, Transfer, Eurostar, Total), making GWR and Eurostar legs consistent with each other - Move CET label next to Paris arrival time; show duration · train number on one line below - Move "Too early" label into the National Rail column for unreachable rows - Remove horizontal scrollbar (drop card-scroll / overflow-x: auto) - Add DEFAULT_MIN_CONNECTION / DEFAULT_MAX_CONNECTION to config/default.py (70 / 150 min); remove all hardcoded fallback values from app.py and templates - Redirect to clean URL when both connection params equal their defaults; omit params from all generated links when at default values Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6ab4534051
commit
8433252cae
5 changed files with 109 additions and 87 deletions
|
|
@ -192,7 +192,6 @@
|
|||
|
||||
/* Card helpers */
|
||||
.card > h2:first-child { margin-top: 0; }
|
||||
.card-scroll { overflow-x: auto; }
|
||||
|
||||
/* Form groups */
|
||||
.form-group { margin-bottom: 1.2rem; }
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
</label>
|
||||
<select id="min_connection" name="min_connection" class="form-control">
|
||||
{% for mins in valid_min_connections %}
|
||||
<option value="{{ mins }}" {% if mins == 70 %}selected{% endif %}>{{ mins }} min</option>
|
||||
<option value="{{ mins }}" {% if mins == default_min_connection %}selected{% endif %}>{{ mins }} min</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
</label>
|
||||
<select id="max_connection" name="max_connection" class="form-control">
|
||||
{% for mins in valid_max_connections %}
|
||||
<option value="{{ mins }}" {% if mins == 150 %}selected{% endif %}>{{ mins }} min</option>
|
||||
<option value="{{ mins }}" {% if mins == default_max_connection %}selected{% endif %}>{{ mins }} min</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@
|
|||
{{ departure_station_name }} → {{ destination }}
|
||||
</h2>
|
||||
<div class="date-nav">
|
||||
<a href="{{ url_for('results', station_crs=station_crs, slug=slug, travel_date=prev_date, min_connection=min_connection, max_connection=max_connection) }}"
|
||||
<a href="{{ url_for('results', station_crs=station_crs, slug=slug, travel_date=prev_date, min_connection=url_min_connection, max_connection=url_max_connection) }}"
|
||||
class="btn-nav">← Prev</a>
|
||||
<strong>{{ travel_date_display }}</strong>
|
||||
<a href="{{ url_for('results', station_crs=station_crs, slug=slug, travel_date=next_date, min_connection=min_connection, max_connection=max_connection) }}"
|
||||
<a href="{{ url_for('results', station_crs=station_crs, slug=slug, travel_date=next_date, min_connection=url_min_connection, max_connection=url_max_connection) }}"
|
||||
class="btn-nav">Next →</a>
|
||||
</div>
|
||||
<div class="switcher-section">
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
{% else %}
|
||||
<a
|
||||
class="chip-link"
|
||||
href="{{ url_for('results', station_crs=station_crs, slug=destination_slug, travel_date=travel_date, min_connection=min_connection, max_connection=max_connection) }}"
|
||||
href="{{ url_for('results', station_crs=station_crs, slug=destination_slug, travel_date=travel_date, min_connection=url_min_connection, max_connection=url_max_connection) }}"
|
||||
>{{ destination_name }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
@ -64,9 +64,13 @@
|
|||
</div>
|
||||
<script>
|
||||
function applyConnectionFilter() {
|
||||
var min = document.getElementById('min_conn_select').value;
|
||||
var max = document.getElementById('max_conn_select').value;
|
||||
window.location = '{{ url_for('results', station_crs=station_crs, slug=slug, travel_date=travel_date) }}?min_connection=' + min + '&max_connection=' + max;
|
||||
var min = parseInt(document.getElementById('min_conn_select').value);
|
||||
var max = parseInt(document.getElementById('max_conn_select').value);
|
||||
var base = '{{ url_for('results', station_crs=station_crs, slug=slug, travel_date=travel_date) }}';
|
||||
var params = [];
|
||||
if (min !== {{ default_min_connection }}) params.push('min_connection=' + min);
|
||||
if (max !== {{ default_max_connection }}) params.push('max_connection=' + max);
|
||||
window.location = params.length ? base + '?' + params.join('&') : base;
|
||||
}
|
||||
</script>
|
||||
<p class="card-meta">
|
||||
|
|
@ -90,17 +94,13 @@
|
|||
</div>
|
||||
|
||||
{% if trips or unreachable_morning_services %}
|
||||
<div class="card card-scroll">
|
||||
<div class="card">
|
||||
<table class="results-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="nowrap">{{ departure_station_name }}</th>
|
||||
<th class="nowrap">Paddington</th>
|
||||
<th class="nowrap">GWR Fare</th>
|
||||
<th class="nowrap">National Rail</th>
|
||||
<th class="col-transfer nowrap">Transfer</th>
|
||||
<th class="nowrap">Depart STP</th>
|
||||
<th>{{ destination }}</th>
|
||||
<th class="nowrap">ES Std</th>
|
||||
<th class="nowrap">Eurostar</th>
|
||||
<th class="nowrap">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
@ -128,51 +128,50 @@
|
|||
{% endif %}
|
||||
<tr class="{{ row_class }}">
|
||||
{% if row.row_type == 'trip' %}
|
||||
<td class="font-bold">
|
||||
{{ row.depart_bristol }}
|
||||
{% if row.headcode %}<br><span class="text-xs font-normal text-muted">{{ row.headcode }}</span>{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ row.arrive_paddington }}
|
||||
<span class="font-bold nowrap">{{ row.depart_bristol }} → {{ row.arrive_paddington }}</span>
|
||||
<span class="text-sm text-muted nowrap">({{ row.gwr_duration }})</span>
|
||||
{% if row.arrive_platform %}<br><span class="text-xs text-muted">Plat {{ row.arrive_platform }}</span>{% endif %}
|
||||
</td>
|
||||
<td class="nowrap">
|
||||
{% if row.headcode or row.arrive_platform %}
|
||||
<br><span class="text-xs text-muted">
|
||||
{%- if row.headcode %}{{ row.headcode }}{% endif %}
|
||||
{%- if row.headcode and row.arrive_platform %} · {% endif %}
|
||||
{%- if row.arrive_platform %}Plat {{ row.arrive_platform }}{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if row.ticket_price is not none %}
|
||||
£{{ "%.2f"|format(row.ticket_price) }}
|
||||
<br><span class="text-xs text-muted">{{ row.ticket_name }}</span>
|
||||
<br><span class="text-sm font-bold">£{{ "%.2f"|format(row.ticket_price) }}</span>
|
||||
<span class="text-xs text-muted">{{ row.ticket_name }}</span>
|
||||
{% else %}
|
||||
<span class="text-muted">–</span>
|
||||
<br><span class="text-sm text-muted">–</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="col-transfer nowrap" style="color:#4a5568">
|
||||
{{ row.connection_duration }}{% if row.connection_minutes < 80 %} <span title="Tight connection">⚠️</span>{% endif %}
|
||||
<td class="col-transfer" style="color:#4a5568">
|
||||
<span class="nowrap">{{ row.connection_duration }}{% if row.connection_minutes < 80 %} <span title="Tight connection">⚠️</span>{% endif %}</span>
|
||||
{% if row.circle_services %}
|
||||
{% set c = row.circle_services[0] %}
|
||||
<br><span class="text-xs text-muted">Circle {{ c.depart }} → KX {{ c.arrive_kx }}</span>
|
||||
<br><span class="text-xs text-muted nowrap">Circle {{ c.depart }} → KX {{ c.arrive_kx }}</span>
|
||||
{% if row.circle_services | length > 1 %}
|
||||
{% set c2 = row.circle_services[1] %}
|
||||
<br><span class="text-xs text-muted" style="opacity:0.7">next {{ c2.depart }} → KX {{ c2.arrive_kx }}</span>
|
||||
<br><span class="text-xs text-muted nowrap" style="opacity:0.7">next {{ c2.depart }} → KX {{ c2.arrive_kx }}</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="font-bold">
|
||||
{{ row.depart_st_pancras }}
|
||||
{% if row.train_number %}<br><span class="text-xs font-normal text-muted">{% for part in row.train_number.split(' + ') %}<span class="nowrap">{{ part }}</span>{% if not loop.last %} + {% endif %}{% endfor %}</span>{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ row.arrive_destination }}
|
||||
<span class="font-normal text-muted" style="font-size:0.85em">(CET)</span>
|
||||
{% if row.eurostar_duration %}<br><span class="text-sm text-muted nowrap">({{ row.eurostar_duration }})</span>{% endif %}
|
||||
</td>
|
||||
<td class="nowrap">
|
||||
<span class="font-bold nowrap">{{ row.depart_st_pancras }} → {{ row.arrive_destination }} <span class="font-normal text-muted" style="font-size:0.85em">(CET)</span></span>
|
||||
{% if row.eurostar_duration or row.train_number %}
|
||||
<br><span class="text-xs text-muted">
|
||||
{%- if row.eurostar_duration %}<span class="nowrap">({{ row.eurostar_duration }})</span>{% endif %}
|
||||
{%- if row.eurostar_duration and row.train_number %} · {% endif %}
|
||||
{%- if row.train_number %}{% for part in row.train_number.split(' + ') %}<span class="nowrap">{{ part }}</span>{% if not loop.last %} + {% endif %}{% endfor %}{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if row.eurostar_price is not none %}
|
||||
£{{ "%.2f"|format(row.eurostar_price) }}
|
||||
<br><span class="text-sm font-bold">£{{ "%.2f"|format(row.eurostar_price) }}</span>
|
||||
{% if row.eurostar_seats is not none %}
|
||||
<br><span class="text-xs text-muted">{{ row.eurostar_seats }} at this price</span>
|
||||
<span class="text-xs text-muted">{{ row.eurostar_seats }} at this price</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="text-muted">–</span>
|
||||
<br><span class="text-sm text-muted">–</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="font-bold nowrap">
|
||||
|
|
@ -188,32 +187,29 @@
|
|||
{% endif %}
|
||||
</td>
|
||||
{% else %}
|
||||
<td class="font-bold">—</td>
|
||||
<td>—</td>
|
||||
<td>—</td>
|
||||
<td class="col-transfer">—</td>
|
||||
<td class="font-bold">
|
||||
{{ row.depart_st_pancras }}
|
||||
{% if row.train_number %}<br><span class="text-xs font-normal text-dimmed">{% for part in row.train_number.split(' + ') %}<span class="nowrap">{{ part }}</span>{% if not loop.last %} + {% endif %}{% endfor %}</span>{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ row.arrive_destination }}
|
||||
<span class="font-normal text-dimmed" style="font-size:0.85em">(CET)</span>
|
||||
{% if row.eurostar_duration %}<br><span class="text-sm text-dimmed nowrap">({{ row.eurostar_duration }})</span>{% endif %}
|
||||
<span class="text-dimmed text-sm" title="Too early to reach from {{ departure_station_name }}">Too early</span>
|
||||
</td>
|
||||
<td class="nowrap">
|
||||
<td class="col-transfer text-dimmed">—</td>
|
||||
<td>
|
||||
<span class="font-bold nowrap text-dimmed">{{ row.depart_st_pancras }} → {{ row.arrive_destination }} <span class="font-normal" style="font-size:0.85em">(CET)</span></span>
|
||||
{% if row.eurostar_duration or row.train_number %}
|
||||
<br><span class="text-xs text-dimmed">
|
||||
{%- if row.eurostar_duration %}<span class="nowrap">({{ row.eurostar_duration }})</span>{% endif %}
|
||||
{%- if row.eurostar_duration and row.train_number %} · {% endif %}
|
||||
{%- if row.train_number %}{% for part in row.train_number.split(' + ') %}<span class="nowrap">{{ part }}</span>{% if not loop.last %} + {% endif %}{% endfor %}{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if row.eurostar_price is not none %}
|
||||
<span class="text-dimmed">£{{ "%.2f"|format(row.eurostar_price) }}</span>
|
||||
<br><span class="text-sm text-dimmed">£{{ "%.2f"|format(row.eurostar_price) }}</span>
|
||||
{% if row.eurostar_seats is not none %}
|
||||
<br><span class="text-xs text-dimmed">{{ row.eurostar_seats }} at this price</span>
|
||||
<span class="text-xs text-dimmed">{{ row.eurostar_seats }} at this price</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="text-dimmed">–</span>
|
||||
<br><span class="text-sm text-dimmed">–</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="font-bold">
|
||||
<span title="Too early to reach from {{ departure_station_name }}" class="text-dimmed nowrap">Too early</span>
|
||||
</td>
|
||||
<td class="text-dimmed">—</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue