Files
WeightTracker/app/templates/dashboard.html
2026-02-23 08:32:18 +11:00

172 lines
6.5 KiB
HTML

{% extends "base.html" %}
{% block title %}Dashboard — WeightTracker{% endblock %}
{% block content %}
<div class="page-header">
<h1>Hey, {{ user.display_name or user.username }}! 👋</h1>
<p>Here's your progress at a glance.</p>
</div>
<!-- Stats Cards -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-label">Current Weight</div>
<div class="stat-value">{{ '%.1f' % (latest.weight_kg | float) if latest else '—' }} <span
style="font-size: 0.9rem; font-weight: 400; color: var(--text-muted);">kg</span></div>
</div>
<div class="stat-card">
<div class="stat-label">Weight Change</div>
<div class="stat-value">
{% if weight_change is not none %}
{{ '%+.1f' % weight_change }} <span
style="font-size: 0.9rem; font-weight: 400; color: var(--text-muted);">kg</span>
{% else %}
{% endif %}
</div>
{% if weight_change_pct is not none %}
<div class="stat-change {{ 'positive' if weight_change < 0 else 'negative' }}">
{{ '%+.1f' % weight_change_pct }}% from start
</div>
{% endif %}
</div>
<div class="stat-card">
<div class="stat-label">Current BMI</div>
<div class="stat-value">{{ '%.1f' % (latest.bmi | float) if latest and latest.bmi else '—' }}</div>
</div>
<div class="stat-card">
<div class="stat-label">Check-ins</div>
<div class="stat-value">{{ stats.total_checkins if stats else 0 }}</div>
</div>
</div>
<!-- Charts -->
<div class="charts-grid">
<div class="card">
<div class="card-header">
<h2>📈 Weight Over Time</h2>
</div>
<div class="chart-container">
<canvas id="weightChart"></canvas>
</div>
</div>
<div class="card">
<div class="card-header">
<h2>📊 Weekly Change</h2>
</div>
<div class="chart-container">
<canvas id="weeklyChart"></canvas>
</div>
</div>
</div>
<div class="grid-3">
<!-- Recent Check-ins -->
<div class="card">
<div class="card-header">
<h2>🕐 Recent Check-ins</h2>
<a href="{{ url_for('checkin.index') }}" class="btn btn-ghost btn-sm">View All</a>
</div>
{% if recent_checkins %}
<div>
{% for c in recent_checkins %}
<div class="activity-item">
<div style="flex: 1;">
<div style="font-weight: 600; font-size: 1.1rem;">{{ '%.1f' % (c.weight_kg | float) }} kg</div>
<div class="activity-detail">
{% if c.bmi %}BMI {{ '%.1f' % (c.bmi | float) }} · {% endif %}
{{ c.checked_in_at | sydney }}
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<div class="empty-state-icon">📝</div>
<h3>No check-ins yet</h3>
<p>Log your first weigh-in to start tracking!</p>
<a href="{{ url_for('checkin.index') }}" class="btn btn-primary btn-sm">Check In Now</a>
</div>
{% endif %}
</div>
<!-- Activity Feed & Milestones -->
<div>
{% if milestones %}
<div class="card" style="margin-bottom: 1rem;">
<div class="card-header">
<h2>🏅 Milestones</h2>
</div>
<div class="milestones-grid">
{% for m in milestones %}
<span class="milestone-badge {{ 'gold' if 'lost' in m.milestone_key else '' }}">
{% if m.milestone_key == 'first_checkin' %}✅ First Check-in
{% elif m.milestone_key == '5_checkins' %}🔥 5 Check-ins
{% elif m.milestone_key == '10_checkins' %}💪 10 Check-ins
{% elif m.milestone_key == '25_checkins' %}🎯 25 Check-ins
{% elif m.milestone_key == 'lost_1kg' %}⭐ 1kg Lost
{% elif m.milestone_key == 'lost_2kg' %}⭐ 2kg Lost
{% elif m.milestone_key == 'lost_5kg' %}🌟 5kg Lost
{% elif m.milestone_key == 'lost_10kg' %}💎 10kg Lost
{% elif m.milestone_key == 'lost_15kg' %}👑 15kg Lost
{% elif m.milestone_key == 'lost_20kg' %}🏆 20kg Lost
{% else %}{{ m.milestone_key }}
{% endif %}
</span>
{% endfor %}
</div>
</div>
{% endif %}
<div class="card">
<div class="card-header">
<h2>🔔 Activity Feed</h2>
</div>
{% if activity %}
<div>
{% for a in activity %}
<div class="activity-item">
<div class="activity-avatar">{{ (a.display_name or a.username)[:1] | upper }}</div>
<div class="activity-content">
<div class="activity-name">{{ a.display_name or a.username }}</div>
<div class="activity-detail">Logged {{ '%.1f' % (a.weight_kg | float) }} kg · {{
a.checked_in_at | sydney('%d %b, %H:%M') }}</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<div class="empty-state-icon">📢</div>
<p>No activity yet. Be the first to check in!</p>
</div>
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/charts.js') }}"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
fetch('/api/chart-data/{{ user.id }}')
.then(r => r.json())
.then(data => {
if (data.labels.length > 0) {
createWeightChart('weightChart', data.labels, data.weights);
}
});
fetch('/api/weekly-change/{{ user.id }}')
.then(r => r.json())
.then(data => {
if (data.labels.length > 0) {
createWeeklyChangeChart('weeklyChart', data.labels, data.changes);
}
});
});
</script>
{% endblock %}