The tables were squeezed to fit the screen, and with seven to nine
columns on a 390px phone every heading and every value was truncated to
a few characters - a gravity of "1.0..." and a date of "202..." are
worse than useless, and the beer name was painted over the gravity
reading because the cell was allowed to overflow.
The tables keep their natural width and scroll sideways inside their
card, which is what a table does. The advice is a small button so the
column that matters is narrow, and the headings have a short form for
a phone ("Brewing advice" -> "Advice", "Attenuation" -> "Att.").
The secondary columns - the drop, the legacy ABV and the days - go away
on a phone; the details are still on the run's own page.
A name and a comment get a sensible minimum width and wrap on a word
boundary rather than one word per line.
The desktop is untouched: the same full headings, the same 806px table,
and the pop-out still opens on hover.
214 lines
9.5 KiB
HTML
214 lines
9.5 KiB
HTML
{% extends 'base.html' %}
|
||
|
||
{% block title %}History — Brew Log{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="page__head">
|
||
<div>
|
||
<h1 class="page__title">History</h1>
|
||
<p class="page__sub">How every brew has gone, and what it turned out like.</p>
|
||
</div>
|
||
<div class="btn-row">
|
||
<a class="btn btn--ghost btn--sm" href="{{ url_for('analysis.active') }}">Active beers</a>
|
||
<a class="btn btn--ghost btn--sm" href="{{ url_for('brews.index') }}">Brew process</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid grid--4 mb-lg">
|
||
<div class="stat">
|
||
<div class="stat__label">Total brews</div>
|
||
<div class="stat__value">{{ stats.total_runs }}</div>
|
||
<div class="stat__meta">{{ stats.completed }} finished · {{ stats.active }} active</div>
|
||
</div>
|
||
<div class="stat">
|
||
<div class="stat__label">Average ABV</div>
|
||
<div class="stat__value">{{ '%.2f' % stats.avg_abv }}%</div>
|
||
<div class="stat__meta">
|
||
{% if stats.abv_counted < stats.abv_total %}
|
||
across {{ stats.abv_counted }} of {{ stats.abv_total }} finished brews
|
||
{% else %}
|
||
across finished brews
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
<div class="stat">
|
||
<div class="stat__label">Strongest</div>
|
||
<div class="stat__value">
|
||
{% if stats.best %}{{ '%.2f' % stats.best.abv }}%{% else %}—{% endif %}
|
||
</div>
|
||
<div class="stat__meta">
|
||
{% if stats.best %}{{ stats.best.name }}{% else %}—{% endif %}
|
||
</div>
|
||
</div>
|
||
<div class="stat">
|
||
<div class="stat__label">Lightest</div>
|
||
<div class="stat__value">
|
||
{% if stats.worst %}{{ '%.2f' % stats.worst.abv }}%{% else %}—{% endif %}
|
||
</div>
|
||
<div class="stat__meta">
|
||
{% if stats.worst %}{{ stats.worst.name }}{% else %}—{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid grid--2 mb-lg">
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<h2 class="card__title">Alcohol by brew</h2>
|
||
<span class="card__hint">Standard formula (OG − FG) × 131.25</span>
|
||
</div>
|
||
<div class="card__body">
|
||
<canvas id="abv-chart" height="120"></canvas>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<h2 class="card__title">Brews over time</h2>
|
||
<span class="card__hint">Runs started per month (active runs counted at their first reading)</span>
|
||
</div>
|
||
<div class="card__body">
|
||
<canvas id="months-chart" height="120"></canvas>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
{% if outliers %}
|
||
<section class="card mb-lg">
|
||
<div class="card__head">
|
||
<h2 class="card__title">Readings worth a second look</h2>
|
||
<span class="card__hint">{{ outliers | length }} outside the usual hydrometer range</span>
|
||
</div>
|
||
<div class="card__body card__body--flush">
|
||
<div class="table-wrap">
|
||
<table class="data">
|
||
<thead>
|
||
<tr>
|
||
<th class="col-run">Run</th>
|
||
<th class="col-name">Name</th>
|
||
<th class="col-finished">Date</th>
|
||
<th class="num col-gravity">Reading</th>
|
||
<th class="col-comment" title="Comment"><span class="long">Comment</span><span class="short">Note</span></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for row in outliers %}
|
||
<tr>
|
||
<td class="col-run mono">{{ row.beer_run_id }}</td>
|
||
<td class="col-name">{{ row.name }}</td>
|
||
<td class="col-finished mono nowrap">{{ row.date or '—' }}</td>
|
||
<td class="col-gravity num"><span class="chip chip--warn">{{ row.sg }}</span></td>
|
||
<td class="col-comment comment">{{ row.comment or '—' }}</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
{% endif %}
|
||
|
||
<section class="card mb-lg">
|
||
<div class="card__head">
|
||
<h2 class="card__title">Every brew</h2>
|
||
<span class="card__hint">{{ summaries | length }} runs</span>
|
||
</div>
|
||
<div class="card__body card__body--flush">
|
||
<div class="table-wrap">
|
||
<table class="data">
|
||
<thead>
|
||
<tr>
|
||
<th class="col-run">Run</th>
|
||
<th class="col-name">Name</th>
|
||
<th class="col-finished" title="Status"><span class="long">Status</span><span class="short">Stat</span></th>
|
||
<th class="num col-gravity">OG</th>
|
||
<th class="num col-gravity">FG</th>
|
||
<th class="num col-drop">Drop</th>
|
||
<th class="num col-abv">ABV</th>
|
||
<th class="num col-legacy">Legacy</th>
|
||
<th class="col-finished" title="Finished"><span class="long">Finished</span><span class="short">Done</span></th>
|
||
<th class="col-comment" title="Comment"><span class="long">Comment</span><span class="short">Note</span></th>
|
||
<th class="col-action"></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for run in summaries %}
|
||
<tr>
|
||
<td class="col-run mono">{{ run.beer_run_id }}</td>
|
||
<td class="col-name">{{ run.canonical_name }}</td>
|
||
<td class="col-finished">
|
||
{% if run.active %}
|
||
<span class="chip chip--active">Active</span>
|
||
{% else %}
|
||
<span class="chip chip--done">Finished</span>
|
||
{% endif %}
|
||
</td>
|
||
<td class="col-drop col-gravity num">{{ run.og_points or '—' }}</td>
|
||
<td class="col-gravity num">{{ run.fg_points or '—' }}</td>
|
||
<td class="col-gravity num">{{ run.drop_points if run.drop_points is not none else '—' }}</td>
|
||
<td class="col-abv num">
|
||
{% if run.abv is not none %}<strong>{{ '%.2f' % run.abv }}%</strong>
|
||
{% elif run.projected_abv is not none %}{{ '%.2f' % run.projected_abv }}%*
|
||
{% else %}—{% endif %}
|
||
</td>
|
||
<td class="col-legacy col-abv num muted">{{ run.legacy_abv if run.legacy_abv is not none else '—' }}</td>
|
||
<td class="col-finished mono nowrap">{{ run.final_date or '—' }}</td>
|
||
<td class="col-comment comment">
|
||
{% if run.comments %}{{ run.comments[-1] }}{% else %}<span class="faint">—</span>{% endif %}
|
||
</td>
|
||
<td class="right col-action">
|
||
<a class="btn btn--ghost btn--sm"
|
||
href="{{ url_for('brews.run_detail', run_id=run.beer_run_id) }}">Open</a>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<h2 class="card__title">Standard vs legacy alcohol figures</h2>
|
||
<span class="card__hint">The old app used (max − min) ÷ 7.36 + 0.5, which is not a recognised formula</span>
|
||
</div>
|
||
<div class="card__body card__body--flush">
|
||
<div class="table-wrap">
|
||
<table class="data">
|
||
<thead>
|
||
<tr>
|
||
<th class="col-run">Run</th>
|
||
<th class="col-name">Name</th>
|
||
<th class="num col-abv" title="Standard ABV"><span class="long">Standard ABV</span><span class="short">Std</span></th>
|
||
<th class="num col-legacy col-abv" title="Legacy ABV"><span class="long">Legacy ABV</span><span class="short">Old</span></th>
|
||
<th class="num col-abv" title="Overstated by"><span class="long">Overstated by</span><span class="short">Over</span></th>
|
||
<th class="col-finished" title="Finished"><span class="long">Finished</span><span class="short">Done</span></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for row in abv_rows %}
|
||
<tr>
|
||
<td class="col-run mono">{{ row.beer_run_id }}</td>
|
||
<td class="col-name">{{ row.name }}</td>
|
||
<td class="col-abv num">{{ '%.2f' % row.abv }}%</td>
|
||
<td class="col-abv num muted">{{ '%.2f' % row.legacy_abv }}%</td>
|
||
<td class="col-abv num">
|
||
{% if row.delta > 0 %}
|
||
<span class="chip chip--warn">+{{ '%.2f' % row.delta }}</span>
|
||
{% else %}
|
||
<span class="faint">{{ '%.2f' % row.delta }}</span>
|
||
{% endif %}
|
||
</td>
|
||
<td class="col-finished mono nowrap">{{ row.final_date or '—' }}</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
{% endblock %}
|
||
|
||
|