feat: add recap page
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
|
||||
{% block title %}Osiris — Recap{% endblock %}
|
||||
|
||||
{% block extrastyle %}
|
||||
{{ block.super }}
|
||||
<style>
|
||||
/* Mobile-first, same shell as the Today page. */
|
||||
#content { padding: 12px; max-width: 640px; margin: 0 auto; }
|
||||
.osiris-card {
|
||||
background: var(--body-bg);
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.osiris-recap { width: 100%; border-collapse: collapse; }
|
||||
.osiris-recap td, .osiris-recap th {
|
||||
padding: 10px 4px;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
text-align: left;
|
||||
}
|
||||
.osiris-recap tr:last-child td { border-bottom: none; }
|
||||
.osiris-recap .status { text-align: center; width: 4em; }
|
||||
.osiris-recap .bpm { text-align: right; width: 5em; }
|
||||
.osiris-recap .incomplete { color: var(--error-fg, #ba2121); font-weight: 600; }
|
||||
.osiris-recap a { font-weight: 600; }
|
||||
.osiris-note-entry { padding: 10px 0; border-bottom: 1px solid var(--hairline-color); }
|
||||
.osiris-note-entry:last-child { border-bottom: none; }
|
||||
.osiris-note-entry p { margin: 4px 0 0; white-space: pre-line; }
|
||||
.dose-detail { color: var(--body-quiet-color); font-size: 0.85rem; }
|
||||
.osiris-stats { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 12px; }
|
||||
.osiris-stats div { font-size: 0.85rem; color: var(--body-quiet-color); }
|
||||
.osiris-stats strong { display: block; font-size: 1.15rem; color: var(--body-fg); }
|
||||
.osiris-chart { width: 100%; height: auto; overflow: visible; }
|
||||
.osiris-empty { color: var(--body-quiet-color); font-style: italic; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="osiris-card">
|
||||
<h2 style="margin-top:0">Doses — last 14 days</h2>
|
||||
<table class="osiris-recap">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Day</th>
|
||||
<th class="status">Given</th>
|
||||
<th class="bpm">Pulse</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in recap_days %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url 'tracker:today' %}?date={{ row.date|date:'Y-m-d' }}">{{ row.date|date:"D j M" }}</a>
|
||||
{% if forloop.first %}<span class="dose-detail">today</span>{% endif %}
|
||||
</td>
|
||||
<td class="status">
|
||||
{% if row.complete %}
|
||||
✅
|
||||
{% else %}
|
||||
<span class="incomplete">{{ row.taken }}/{{ row.expected }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="bpm">{% if row.bpm %}{{ row.bpm }}{% else %}<span class="dose-detail">—</span>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="dose-detail" style="margin-bottom:0">
|
||||
✅ means every active dose was ticked off that day; otherwise the count given
|
||||
out of expected. Tap a day to fill it in.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="osiris-card">
|
||||
<h2 style="margin-top:0">Pulse — last 90 days</h2>
|
||||
{% if chart %}
|
||||
<svg class="osiris-chart" viewBox="0 0 {{ chart.width }} {{ chart.height }}" role="img"
|
||||
aria-label="Pulse from {{ chart.first_date }} to {{ chart.last_date }}">
|
||||
<line x1="24" y1="24" x2="{{ chart.width|add:'-24' }}" y2="24"
|
||||
stroke="currentColor" stroke-width="0.5" opacity="0.2"/>
|
||||
<line x1="24" y1="{{ chart.height|add:'-24' }}" x2="{{ chart.width|add:'-24' }}"
|
||||
y2="{{ chart.height|add:'-24' }}" stroke="currentColor" stroke-width="0.5" opacity="0.2"/>
|
||||
<polyline points="{{ chart.polyline }}" fill="none" stroke="#79aec8" stroke-width="2"
|
||||
stroke-linejoin="round" stroke-linecap="round" vector-effect="non-scaling-stroke"/>
|
||||
{% for point in chart.points %}
|
||||
<circle cx="{{ point.x }}" cy="{{ point.y }}" r="2" fill="#417690">
|
||||
<title>{{ point.reading.date }} — {{ point.reading.bpm }} bpm</title>
|
||||
</circle>
|
||||
{% endfor %}
|
||||
<text x="2" y="27" font-size="8" fill="currentColor" opacity="0.6">{{ chart.high }}</text>
|
||||
<text x="2" y="{{ chart.height|add:'-21' }}" font-size="8" fill="currentColor" opacity="0.6">{{ chart.low }}</text>
|
||||
</svg>
|
||||
<div class="osiris-stats">
|
||||
<div>Average<strong>{{ chart.average }} bpm</strong></div>
|
||||
<div>Range<strong>{{ chart.low }}–{{ chart.high }}</strong></div>
|
||||
<div>Readings<strong>{{ reading_count }}</strong></div>
|
||||
<div>
|
||||
Trend
|
||||
<strong>
|
||||
{% if chart.trend > 0 %}↑ +{{ chart.trend }}{% elif chart.trend < 0 %}↓ {{ chart.trend }}{% else %}→ steady{% endif %}
|
||||
{% if chart.trend %}<span style="font-size:0.75rem">bpm/day</span>{% endif %}
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="osiris-empty">Record the pulse on at least two days to see the graph.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="osiris-card">
|
||||
<h2 style="margin-top:0">Daily notes</h2>
|
||||
{% for note in daily_notes %}
|
||||
<div class="osiris-note-entry">
|
||||
<a href="{% url 'tracker:today' %}?date={{ note.date|date:'Y-m-d' }}" class="dose-detail">
|
||||
{{ note.date|date:"l j F" }}
|
||||
</a>
|
||||
<p>{{ note.body }}</p>
|
||||
</div>
|
||||
{% empty %}
|
||||
<p class="osiris-empty">No notes yet — write one on the Today page.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<p style="text-align:center"><a href="{% url 'tracker:today' %}">← Back to today</a></p>
|
||||
{% endblock %}
|
||||
@@ -54,10 +54,6 @@
|
||||
border: none; border-radius: 10px; cursor: pointer;
|
||||
background: var(--button-bg); color: var(--button-fg);
|
||||
}
|
||||
.osiris-stats { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 12px; }
|
||||
.osiris-stats div { font-size: 0.85rem; color: var(--body-quiet-color); }
|
||||
.osiris-stats strong { display: block; font-size: 1.15rem; color: var(--body-fg); }
|
||||
.osiris-chart { width: 100%; height: auto; overflow: visible; }
|
||||
.osiris-empty { color: var(--body-quiet-color); font-style: italic; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
@@ -134,43 +130,7 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="osiris-card" style="margin-top:16px">
|
||||
<h2 style="margin-top:0">Pulse — last 90 days</h2>
|
||||
{% if chart %}
|
||||
<svg class="osiris-chart" viewBox="0 0 {{ chart.width }} {{ chart.height }}" role="img"
|
||||
aria-label="Pulse from {{ chart.first_date }} to {{ chart.last_date }}">
|
||||
<line x1="24" y1="24" x2="{{ chart.width|add:'-24' }}" y2="24"
|
||||
stroke="currentColor" stroke-width="0.5" opacity="0.2"/>
|
||||
<line x1="24" y1="{{ chart.height|add:'-24' }}" x2="{{ chart.width|add:'-24' }}"
|
||||
y2="{{ chart.height|add:'-24' }}" stroke="currentColor" stroke-width="0.5" opacity="0.2"/>
|
||||
<polyline points="{{ chart.polyline }}" fill="none" stroke="#79aec8" stroke-width="2"
|
||||
stroke-linejoin="round" stroke-linecap="round" vector-effect="non-scaling-stroke"/>
|
||||
{% for point in chart.points %}
|
||||
<circle cx="{{ point.x }}" cy="{{ point.y }}" r="2" fill="#417690">
|
||||
<title>{{ point.reading.date }} — {{ point.reading.bpm }} bpm</title>
|
||||
</circle>
|
||||
{% endfor %}
|
||||
<text x="2" y="27" font-size="8" fill="currentColor" opacity="0.6">{{ chart.high }}</text>
|
||||
<text x="2" y="{{ chart.height|add:'-21' }}" font-size="8" fill="currentColor" opacity="0.6">{{ chart.low }}</text>
|
||||
</svg>
|
||||
<div class="osiris-stats">
|
||||
<div>Average<strong>{{ chart.average }} bpm</strong></div>
|
||||
<div>Range<strong>{{ chart.low }}–{{ chart.high }}</strong></div>
|
||||
<div>Readings<strong>{{ reading_count }}</strong></div>
|
||||
<div>
|
||||
Trend
|
||||
<strong>
|
||||
{% if chart.trend > 0 %}↑ +{{ chart.trend }}{% elif chart.trend < 0 %}↓ {{ chart.trend }}{% else %}→ steady{% endif %}
|
||||
{% if chart.trend %}<span style="font-size:0.75rem">bpm/day</span>{% endif %}
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="osiris-empty">Record the pulse on at least two days to see the graph.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="osiris-card" id="reminders">
|
||||
<div class="osiris-card" id="reminders" style="margin-top:16px">
|
||||
<h2 style="margin-top:0">Reminders</h2>
|
||||
<p class="dose-detail" id="reminder-status">Checking…</p>
|
||||
<div style="display:flex; gap:8px; flex-wrap:wrap">
|
||||
@@ -200,7 +160,10 @@
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<p style="text-align:center"><a href="{% url 'admin:index' %}">Manage medication & history →</a></p>
|
||||
<p style="text-align:center">
|
||||
<a href="{% url 'tracker:recap' %}">Recap: doses, pulse & notes →</a><br>
|
||||
<a href="{% url 'admin:index' %}">Manage medication & history →</a>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
|
||||
Reference in New Issue
Block a user