114 lines
5.7 KiB
HTML
114 lines
5.7 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('reading.add_reading') }}"
|
|
class="bg-primary-600 text-white px-4 py-2 rounded shadow hover:bg-primary-700">
|
|
+ Add New Reading
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Weekly Summary -->
|
|
<div class="bg-gradient-to-r from-primary-500 to-primary-700 text-white p-6 rounded-xl 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>
|
|
<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>
|
|
|
|
|
|
|
|
|
|
<div class="max-w-5xl mx-auto">
|
|
<!-- Tabs -->
|
|
<div class="flex border-b mb-4 overflow-x-auto" id="dashboard-tabs">
|
|
<button hx-get="{{ url_for('main.dashboard_list') }}" hx-target="#dashboard-content"
|
|
class="tab-btn px-4 py-2 text-sm font-medium border-b-2 whitespace-nowrap {{ 'border-primary-600 text-primary-600' if active_view == 'list' else 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">List
|
|
View</button>
|
|
<button hx-get="{{ url_for('main.dashboard_table') }}" hx-target="#dashboard-content"
|
|
class="tab-btn px-4 py-2 text-sm font-medium border-b-2 whitespace-nowrap {{ 'border-primary-600 text-primary-600' if active_view == 'table' else 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">Table
|
|
View</button>
|
|
<button hx-get="{{ url_for('main.dashboard_weekly') }}" hx-target="#dashboard-content"
|
|
class="tab-btn px-4 py-2 text-sm font-medium border-b-2 whitespace-nowrap {{ 'border-primary-600 text-primary-600' if active_view == 'weekly' else 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">Weekly
|
|
View</button>
|
|
<button hx-get="{{ url_for('main.dashboard_monthly') }}" hx-target="#dashboard-content"
|
|
class="tab-btn px-4 py-2 text-sm font-medium border-b-2 whitespace-nowrap {{ 'border-primary-600 text-primary-600' if active_view == 'monthly' else 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">Monthly
|
|
View</button>
|
|
<button hx-get="{{ url_for('main.dashboard_graph') }}" hx-target="#dashboard-content"
|
|
class="tab-btn px-4 py-2 text-sm font-medium border-b-2 whitespace-nowrap {{ 'border-primary-600 text-primary-600' if active_view == 'graph' else 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">Graph
|
|
View</button>
|
|
</div>
|
|
|
|
<!-- Dashboard Content Target Area for HTMX -->
|
|
<div id="dashboard-content" hx-get="{{ url_for('main.dashboard_list') }}" hx-trigger="load">
|
|
<div class="flex justify-center items-center p-12">
|
|
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary-600"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script>
|
|
// Use event delegation for dashboard interactions to survive DIY Turbo page replacements
|
|
document.addEventListener('click', (e) => {
|
|
// Filter Form Toggle
|
|
const filterBtn = e.target.closest('#filter-btn');
|
|
if (filterBtn) {
|
|
const filterForm = document.getElementById('filter-form');
|
|
const iconClosed = document.getElementById('filter-icon-closed');
|
|
const iconOpen = document.getElementById('filter-icon-open');
|
|
|
|
if (filterForm) {
|
|
const isHidden = filterForm.classList.contains('hidden');
|
|
if (isHidden) {
|
|
filterForm.classList.remove('hidden');
|
|
if (iconClosed) iconClosed.classList.add('hidden');
|
|
if (iconOpen) iconOpen.classList.remove('hidden');
|
|
} else {
|
|
filterForm.classList.add('hidden');
|
|
if (iconClosed) iconClosed.classList.remove('hidden');
|
|
if (iconOpen) iconOpen.classList.add('hidden');
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Tabs
|
|
const tabBtn = e.target.closest('.tab-btn');
|
|
if (tabBtn) {
|
|
const tabBtns = document.querySelectorAll('.tab-btn');
|
|
tabBtns.forEach(b => {
|
|
b.classList.remove('border-primary-600', 'text-primary-600');
|
|
});
|
|
tabBtn.classList.add('border-primary-600', 'text-primary-600');
|
|
// The click will still bubble up and be caught by the Micro-HTMX logic in _layout.html
|
|
return;
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %} |