Replace CSS grid with Bootstrap table on conference list page
- Proper <table> with colgroup widths, table-sm table-hover align-middle - Month-divider rows (MARCH 2026, APRIL 2026, …) break up long lists - Date ranges collapsed to a single column (e.g. "25–28 Mar 2026") - Row highlight (conf-going) for conferences marked going=true - Topic and date columns styled text-muted small to reduce visual noise - Trip links replaced with 🧳 emoji: shows just the emoji when the trip title matches the conference name (the common case), otherwise appends the trip title (e.g. "🧳 Budapest" for FOSDEM); full title always in tooltip Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
20f1e31119
commit
ef517c98ff
1 changed files with 109 additions and 43 deletions
|
|
@ -1,22 +1,11 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% from "macros.html" import trip_link, conference_row with context %}
|
||||
{% from "macros.html" import trip_link with context %}
|
||||
|
||||
{% block title %}Conferences - Edward Betts{% endblock %}
|
||||
|
||||
{% block style %}
|
||||
{% set column_count = 9 %}
|
||||
<style>
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat({{ column_count }}, auto);
|
||||
gap: 10px;
|
||||
justify-content: start;
|
||||
}
|
||||
.heading {
|
||||
grid-column: 1 / {{ column_count + 1 }};
|
||||
}
|
||||
|
||||
/* Timeline */
|
||||
.conf-timeline {
|
||||
position: relative;
|
||||
|
|
@ -67,6 +56,22 @@
|
|||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Conference table */
|
||||
.conf-month-row td {
|
||||
background: #e9ecef !important;
|
||||
font-weight: 600;
|
||||
font-size: 0.8em;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: #495057;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.3rem;
|
||||
border-bottom: none;
|
||||
}
|
||||
.conf-going {
|
||||
--bs-table-bg: rgba(25, 135, 84, 0.07);
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
|
|
@ -74,7 +79,6 @@
|
|||
|
||||
{% macro render_timeline(timeline) %}
|
||||
{% if timeline %}
|
||||
{% set bar_h = 26 %}
|
||||
{% set row_h = 32 %}
|
||||
{% set header_h = 22 %}
|
||||
{% set total_h = timeline.lane_count * row_h + header_h %}
|
||||
|
|
@ -82,28 +86,22 @@
|
|||
<h3>Next 90 days</h3>
|
||||
<div class="conf-timeline" style="height: {{ total_h }}px;">
|
||||
|
||||
{# Month markers #}
|
||||
{% for m in timeline.months %}
|
||||
<div class="conf-tl-month" style="left: {{ m.left_pct }}%;">
|
||||
<span class="conf-tl-month-label">{{ m.label }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{# Today marker (always at left: 0) #}
|
||||
<div class="conf-tl-today" style="left: 0;"></div>
|
||||
|
||||
{# Conference bars #}
|
||||
{% for conf in timeline.confs %}
|
||||
{% set color = tl_colors[conf.lane % tl_colors | length] %}
|
||||
{% set top_px = conf.lane * row_h + header_h %}
|
||||
<div class="conf-tl-bar"
|
||||
style="left: {{ conf.left_pct }}%; width: {{ conf.width_pct }}%; top: {{ top_px }}px; background: {{ color }};"
|
||||
title="{{ conf.label }}">
|
||||
{% if conf.url %}
|
||||
<a href="{{ conf.url }}">{{ conf.name }}</a>
|
||||
{% else %}
|
||||
<span>{{ conf.name }}</span>
|
||||
{% endif %}
|
||||
{% if conf.url %}<a href="{{ conf.url }}">{{ conf.name }}</a>
|
||||
{% else %}<span>{{ conf.name }}</span>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
|
|
@ -112,25 +110,95 @@
|
|||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro section(heading, item_list, badge) %}
|
||||
{% if item_list %}
|
||||
<div class="heading">
|
||||
|
||||
<h2>{{ heading }}</h2>
|
||||
|
||||
<p>
|
||||
{% set item_count = item_list|length %}
|
||||
{% if item_count == 1 %}{{ item_count }} conference{% else %}{{ item_count }} conferences{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{% macro conf_table(heading, item_list, badge) %}
|
||||
{% if item_list %}
|
||||
{% set count = item_list | length %}
|
||||
<h2>{{ heading }} <small class="text-muted fs-6 fw-normal">{{ count }} conference{{ "" if count == 1 else "s" }}</small></h2>
|
||||
<table class="table table-sm table-hover align-middle mb-4">
|
||||
<colgroup>
|
||||
<col style="width: 9rem">
|
||||
<col>
|
||||
<col style="width: 18rem">
|
||||
<col style="width: 14rem">
|
||||
<col style="width: 7rem">
|
||||
<col style="width: 10rem">
|
||||
</colgroup>
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Dates</th>
|
||||
<th>Conference</th>
|
||||
<th>Topic</th>
|
||||
<th>Location</th>
|
||||
<th>CFP ends</th>
|
||||
<th>Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% set ns = namespace(prev_month="") %}
|
||||
{% for item in item_list %}
|
||||
{{ conference_row(item, badge) }}
|
||||
<div class="grid-item">
|
||||
{% if item.linked_trip %} trip: {{ trip_link(item.linked_trip) }} {% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% set month_label = item.start_date.strftime("%B %Y") %}
|
||||
{% if month_label != ns.prev_month %}
|
||||
{% set ns.prev_month = month_label %}
|
||||
<tr class="conf-month-row">
|
||||
<td colspan="6">{{ month_label }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr{% if item.going %} class="conf-going"{% endif %}>
|
||||
<td class="text-nowrap text-muted small">
|
||||
{%- if item.start_date == item.end_date -%}
|
||||
{{ item.start_date.strftime("%-d %b %Y") }}
|
||||
{%- elif item.start_date.year == item.end_date.year and item.start_date.month == item.end_date.month -%}
|
||||
{{ item.start_date.strftime("%-d") }}–{{ item.end_date.strftime("%-d %b %Y") }}
|
||||
{%- else -%}
|
||||
{{ item.start_date.strftime("%-d %b") }}–{{ item.end_date.strftime("%-d %b %Y") }}
|
||||
{%- endif -%}
|
||||
</td>
|
||||
<td>
|
||||
{% if item.url %}<a href="{{ item.url }}">{{ item.name }}</a>
|
||||
{% else %}{{ item.name }}{% endif %}
|
||||
{% if item.going and not (item.accommodation_booked or item.travel_booked) %}
|
||||
<span class="badge text-bg-primary ms-1">{{ badge }}</span>
|
||||
{% endif %}
|
||||
{% if item.accommodation_booked %}
|
||||
<span class="badge text-bg-success ms-1">accommodation</span>
|
||||
{% endif %}
|
||||
{% if item.transport_booked %}
|
||||
<span class="badge text-bg-success ms-1">transport</span>
|
||||
{% endif %}
|
||||
{% if item.linked_trip %}
|
||||
{% set trip = item.linked_trip %}
|
||||
<a href="{{ url_for('trip_page', start=trip.start.isoformat()) }}"
|
||||
class="text-muted ms-1 text-decoration-none"
|
||||
title="Trip: {{ trip.title }}">
|
||||
🧳{% if trip.title != item.name %} {{ trip.title }}{% endif %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-muted small">{{ item.topic }}</td>
|
||||
<td class="text-nowrap">
|
||||
{% set country = get_country(item.country) if item.country else None %}
|
||||
{% if country %}{{ country.flag }} {{ item.location }}
|
||||
{% elif item.online %}💻 Online
|
||||
{% else %}{{ item.location }}{% endif %}
|
||||
</td>
|
||||
<td class="text-nowrap text-muted small">
|
||||
{% if item.cfp_end %}{{ item.cfp_end.strftime("%-d %b %Y") }}{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if item.price and item.currency %}
|
||||
<span class="badge bg-info text-nowrap">{{ "{:,d}".format(item.price | int) }} {{ item.currency }}</span>
|
||||
{% if item.currency != "GBP" and item.currency in fx_rate %}
|
||||
<span class="badge bg-info text-nowrap">{{ "{:,.0f}".format(item.price / fx_rate[item.currency]) }} GBP</span>
|
||||
{% endif %}
|
||||
{% elif item.free %}
|
||||
<span class="badge bg-success text-nowrap">free</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block content %}
|
||||
|
|
@ -140,11 +208,9 @@
|
|||
|
||||
{{ render_timeline(timeline) }}
|
||||
|
||||
<div class="grid-container">
|
||||
{{ section("Current", current, "attending") }}
|
||||
{{ section("Future", future, "going") }}
|
||||
{{ section("Past", past|reverse|list, "went") }}
|
||||
</div>
|
||||
{{ conf_table("Current", current, "attending") }}
|
||||
{{ conf_table("Future", future, "going") }}
|
||||
{{ conf_table("Past", past|reverse|list, "went") }}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue