237 lines
13 KiB
HTML
237 lines
13 KiB
HTML
{% extends "_layout.html" %}
|
|
{% block content %}
|
|
<div class="max-w-5xl mx-auto p-4 space-y-6">
|
|
|
|
<!-- Header Section with "Add New Reading" Button -->
|
|
<div class="flex justify-between items-center">
|
|
<h1 class="text-2xl font-bold text-gray-800">Dashboard</h1>
|
|
<a rel="prefetch" href="{{ url_for('main.add_reading') }}"
|
|
class="bg-blue-600 text-white px-4 py-2 rounded shadow hover:bg-blue-700">
|
|
+ Add New Reading
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Weekly Summary -->
|
|
<div class="bg-gradient-to-r from-blue-500 to-blue-700 text-white p-6 rounded-lg shadow-md">
|
|
<h3 class="text-lg font-bold">Weekly Summary</h3>
|
|
<div class="flex justify-between mt-4">
|
|
<div>
|
|
<p class="text-sm font-semibold">Systolic Average</p>
|
|
<p class="text-2xl">{{ systolic_avg }} <span class="text-base">mmHg</span></p>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm font-semibold">Diastolic Average</p>
|
|
<p class="text-2xl">{{ diastolic_avg }} <span class="text-base">mmHg</span></p>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm font-semibold">Heart Rate Average</p>
|
|
<p class="text-2xl">{{ heart_rate_avg }} <span class="text-base">bpm</span></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Progress Badges -->
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-800 mb-2">Progress Badges</h3>
|
|
<div class="flex flex-wrap gap-4">
|
|
{% for badge in badges %}
|
|
<div class="bg-green-100 text-green-800 px-4 py-2 rounded shadow text-sm font-medium">
|
|
{{ badge }}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Graphs -->
|
|
<div x-data="{ open: false }" class="bg-white rounded-lg shadow-md p-4">
|
|
<!-- Header with Toggle Button -->
|
|
<div class="flex justify-between items-center">
|
|
<h2 class="text-lg font-bold text-gray-800">Graphs</h2>
|
|
<button @click="open = !open" class="text-blue-600 hover:underline flex items-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2"
|
|
stroke="currentColor" class="w-4 h-4 mr-2">
|
|
<path x-show="!open" stroke-linecap="round" stroke-linejoin="round" d="M6 9l6 6 6-6" />
|
|
<path x-show="open" x-cloak stroke-linecap="round" stroke-linejoin="round" d="M18 15l-6-6-6 6" />
|
|
</svg>
|
|
<span x-show="!open">Show Graphs</span>
|
|
<span x-show="open" x-cloak>Hide Graphs</span>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Collapsible Graph Section -->
|
|
<div x-show="open" x-transition.duration.300ms class="mt-4 space-y-6">
|
|
<!-- Blood Pressure Graph -->
|
|
<div>
|
|
<h3 class="text-sm font-semibold text-gray-600 mb-2">Blood Pressure (mmHg)</h3>
|
|
<svg viewBox="0 0 600 250" xmlns="http://www.w3.org/2000/svg" class="w-full">
|
|
<!-- Axes -->
|
|
<line x1="50" y1="200" x2="550" y2="200" stroke="black" stroke-width="1" /> <!-- X-axis -->
|
|
<line x1="50" y1="20" x2="50" y2="200" stroke="black" stroke-width="1" /> <!-- Y-axis -->
|
|
|
|
<!-- Y-axis Labels (Blood Pressure Values) -->
|
|
{% for value in range(50, 201, 50) %}
|
|
<text x="40" y="{{ 200 - (value / 200 * 180) }}" font-size="10" text-anchor="end">{{ value }}</text>
|
|
{% endfor %}
|
|
|
|
<!-- X-axis Labels (Timestamps) -->
|
|
{% for i in range(timestamps|length) %}
|
|
<text x="{{ 50 + i * 50 }}" y="215" font-size="10" text-anchor="middle">{{ timestamps[i] }}</text>
|
|
{% endfor %}
|
|
|
|
<!-- Graph Lines -->
|
|
<!-- Systolic Line -->
|
|
<polyline fill="none" stroke="blue" stroke-width="2"
|
|
points="{% for i in range(timestamps|length) %}{{ 50 + i * 50 }},{{ 200 - (systolic[i] / 200 * 180) }} {% endfor %}" />
|
|
|
|
<!-- Diastolic Line -->
|
|
<polyline fill="none" stroke="red" stroke-width="2"
|
|
points="{% for i in range(timestamps|length) %}{{ 50 + i * 50 }},{{ 200 - (diastolic[i] / 200 * 180) }} {% endfor %}" />
|
|
|
|
<!-- Axis Labels -->
|
|
<text x="25" y="110" font-size="12" transform="rotate(-90, 25, 110)" text-anchor="middle">Blood
|
|
Pressure (mmHg)</text>
|
|
<text x="300" y="240" font-size="12" text-anchor="middle">Date</text>
|
|
</svg>
|
|
</div>
|
|
|
|
<!-- Heart Rate Graph -->
|
|
<div>
|
|
<h3 class="text-sm font-semibold text-gray-600 mb-2">Heart Rate (bpm)</h3>
|
|
<svg viewBox="0 0 600 250" xmlns="http://www.w3.org/2000/svg" class="w-full">
|
|
<!-- Axes -->
|
|
<line x1="50" y1="200" x2="550" y2="200" stroke="black" stroke-width="1" /> <!-- X-axis -->
|
|
<line x1="50" y1="20" x2="50" y2="200" stroke="black" stroke-width="1" /> <!-- Y-axis -->
|
|
|
|
<!-- Y-axis Labels (Heart Rate Values) -->
|
|
{% for value in range(50, 201, 50) %}
|
|
<text x="40" y="{{ 200 - (value / 200 * 180) }}" font-size="10" text-anchor="end">{{ value }}</text>
|
|
{% endfor %}
|
|
|
|
<!-- X-axis Labels (Timestamps) -->
|
|
{% for i in range(timestamps|length) %}
|
|
<text x="{{ 50 + i * 50 }}" y="215" font-size="10" text-anchor="middle">{{ timestamps[i] }}</text>
|
|
{% endfor %}
|
|
|
|
<!-- Heart Rate Line -->
|
|
<polyline fill="none" stroke="green" stroke-width="2"
|
|
points="{% for i in range(timestamps|length) %}{{ 50 + i * 50 }},{{ 200 - (heart_rate[i] / 200 * 180) }} {% endfor %}" />
|
|
|
|
<!-- Axis Labels -->
|
|
<text x="25" y="110" font-size="12" transform="rotate(-90, 25, 110)" text-anchor="middle">Heart Rate
|
|
(bpm)</text>
|
|
<text x="300" y="240" font-size="12" text-anchor="middle">Date</text>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div x-data="{ open: {{ 'true' if request.method == 'POST' else 'false' }} }"
|
|
class="p-4 bg-white rounded-lg shadow-md">
|
|
<!-- Collapsible Header -->
|
|
<div class="flex justify-between items-center">
|
|
<h3 class="text-lg font-bold text-gray-800">Filter Readings</h3>
|
|
<button @click="open = !open" class="text-blue-600 hover:underline flex items-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2"
|
|
stroke="currentColor" class="w-4 h-4 mr-2">
|
|
<path x-show="!open" stroke-linecap="round" stroke-linejoin="round" d="M6 9l6 6 6-6" />
|
|
<path x-show="open" x-cloak stroke-linecap="round" stroke-linejoin="round" d="M18 15l-6-6-6 6" />
|
|
</svg>
|
|
<span x-show="!open">Show Filters</span>
|
|
<span x-show="open" x-cloak>Hide Filters</span>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Collapsible Content -->
|
|
<form method="POST" action="{{ url_for('main.dashboard') }}" x-show="open" x-transition.duration.300ms
|
|
class="mt-4">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label for="start_date" class="block text-sm font-medium text-gray-700">Start Date</label>
|
|
<input type="date" name="start_date" id="start_date" value="{{ start_date or '' }}"
|
|
class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
|
</div>
|
|
<div>
|
|
<label for="end_date" class="block text-sm font-medium text-gray-700">End Date</label>
|
|
<input type="date" name="end_date" id="end_date" value="{{ end_date or '' }}"
|
|
class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
|
</div>
|
|
</div>
|
|
<div class="mt-4">
|
|
<button type="submit"
|
|
class="w-full md:w-auto bg-blue-600 text-white px-6 py-3 rounded-lg font-semibold shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
Apply Filters
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Readings Table -->
|
|
<div class="bg-white rounded-lg shadow-md overflow-hidden">
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-left border-collapse">
|
|
<!-- Table Header -->
|
|
<thead class="bg-gray-50 border-b">
|
|
<tr>
|
|
<th class="px-6 py-3 text-sm font-semibold text-gray-700 uppercase">Timestamp</th>
|
|
<th class="px-6 py-3 text-sm font-semibold text-gray-700 uppercase">Blood Pressure (mmHg)</th>
|
|
<th class="px-6 py-3 text-sm font-semibold text-gray-700 uppercase">Heart Rate</th>
|
|
<th class="px-6 py-3 text-sm font-semibold text-gray-700 uppercase text-center">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<!-- Table Body -->
|
|
<tbody>
|
|
{% for reading in readings %}
|
|
<tr class="border-b hover:bg-gray-50">
|
|
<!-- Timestamp -->
|
|
<td class="px-6 py-4 text-sm text-gray-600 whitespace-nowrap">
|
|
{{ reading.timestamp.strftime('%d %b %Y, %I:%M %p') }}
|
|
</td>
|
|
<!-- Blood Pressure -->
|
|
<td class="px-6 py-4 text-sm text-gray-600 whitespace-nowrap">
|
|
{{ reading.systolic }}/{{ reading.diastolic }}
|
|
</td>
|
|
<!-- Heart Rate -->
|
|
<td class="px-6 py-4 text-sm text-gray-600 whitespace-nowrap">
|
|
{{ reading.heart_rate }} bpm
|
|
</td>
|
|
<!-- Actions -->
|
|
<td class="px-6 py-4 text-center">
|
|
<!-- Edit Button -->
|
|
<a rel="prefetch" href="{{ url_for('main.edit_reading', reading_id=reading.id) }}"
|
|
class="inline-flex items-center px-2 py-1 text-sm font-medium text-blue-600 hover:text-blue-800 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor" class="w-3 h-3 mr-1">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" />
|
|
</svg>
|
|
|
|
<span>Edit</span>
|
|
</a>
|
|
|
|
<!-- Delete Button -->
|
|
<a href="{{ url_for('main.confirm_delete', reading_id=reading.id) }}"
|
|
class="flex items-center px-2 py-1 text-sm font-medium text-red-600 hover:text-red-800 focus:outline-none focus:ring-2 focus:ring-red-500">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 mr-1" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
<span>Delete</span>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="4" class="px-6 py-4 text-center text-sm text-gray-500">
|
|
No readings found.
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
{% endblock %} |