feat: add Doris Barbell v1 scaffold
This commit is contained in:
69
home/doris-barbell/app/templates/base.html
Normal file
69
home/doris-barbell/app/templates/base.html
Normal file
@@ -0,0 +1,69 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ title or 'Doris Barbell' }}</title>
|
||||
<link rel="stylesheet" href="/static/app.css?v=4">
|
||||
</head>
|
||||
<body class="doris-hot-fuzz app-barbell">
|
||||
<div class="incident-tape" aria-hidden="true"></div>
|
||||
<header class="page-header casefile-header app-casefile app-casefile-barbell">
|
||||
<div class="film-grain" aria-hidden="true"></div>
|
||||
<div class="cinematic-glow" aria-hidden="true"></div>
|
||||
<div class="brand-row">
|
||||
<div class="nav-brand">
|
||||
<span class="nav-kicker">N.W.A. Case File</span>
|
||||
<strong>Doris Constabulary</strong>
|
||||
</div>
|
||||
<nav class="nav-links" aria-label="Doris Barbell navigation">
|
||||
<a class="nav-link" href="http://10.5.1.16:8787/">Dashboard</a>
|
||||
<a class="nav-link" href="http://10.5.1.16:8092/">Kitchen</a>
|
||||
<a class="nav-link" href="https://schoolhouse.paccoco.com">Schoolhouse</a>
|
||||
<a class="nav-link" href="/">Barbell</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="casefile-title-row">
|
||||
<div>
|
||||
<p class="eyebrow">Station training desk</p>
|
||||
<div class="casefile-stamp barbell-evidence-tag">Training Dossier</div>
|
||||
<h1>Doris Barbell</h1>
|
||||
<p class="lede">Reps, weight, BMI, and body metrics now look like a proper performance dossier instead of generic gym CRUD.</p>
|
||||
<div class="brand-badges" aria-label="Theme badges">
|
||||
<span class="pill badge-hotfuzz">For the Greater Good</span>
|
||||
<span class="pill">Evidence locker: reps</span>
|
||||
<span class="pill">Case type: Training Dossier</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hot-fuzz-art" aria-hidden="true">
|
||||
<svg viewBox="0 0 320 220" class="poster-illustration" role="presentation">
|
||||
<defs>
|
||||
<linearGradient id="barbell-sunset" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#f2c14e"></stop>
|
||||
<stop offset="50%" stop-color="#d53600"></stop>
|
||||
<stop offset="100%" stop-color="#910f3f"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="8" y="8" width="304" height="204" rx="24" class="poster-frame"></rect>
|
||||
<circle cx="228" cy="72" r="58" class="poster-halo"></circle>
|
||||
<path d="M18 170 L112 100 L134 124 L40 198 Z" class="poster-tape tape-left"></path>
|
||||
<path d="M202 82 L302 32 L314 60 L214 112 Z" class="poster-tape tape-right"></path>
|
||||
<path d="M112 180 C110 150 116 126 132 110 C140 100 148 94 154 90 C160 94 168 100 176 110 C192 126 198 150 196 180 Z" class="constable-silhouette lead"></path>
|
||||
<path d="M174 184 C172 154 178 132 194 118 C202 110 210 104 218 100 C226 104 234 110 242 118 C258 132 264 154 262 184 Z" class="constable-silhouette partner"></path>
|
||||
<circle cx="84" cy="60" r="28" class="swan-stamp"></circle>
|
||||
<path d="M76 64 C80 54 91 48 101 53 C93 52 88 57 89 63 C90 69 101 68 103 76 C94 78 83 76 78 69 L71 76 L66 71 L74 64 Z" class="swan-mark"></path>
|
||||
<rect x="122" y="110" width="86" height="8" rx="4" class="barbell-bar"></rect>
|
||||
<circle cx="120" cy="114" r="16" class="plate-outer"></circle>
|
||||
<circle cx="120" cy="114" r="8" class="plate-inner"></circle>
|
||||
<circle cx="210" cy="114" r="16" class="plate-outer"></circle>
|
||||
<circle cx="210" cy="114" r="8" class="plate-inner"></circle>
|
||||
<text x="160" y="204" class="poster-callout">TRAINING DOSSIER</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="page-shell">
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
290
home/doris-barbell/app/templates/dashboard.html
Normal file
290
home/doris-barbell/app/templates/dashboard.html
Normal file
@@ -0,0 +1,290 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<section class="grid cols-2 evidence-board dossier-grid">
|
||||
<article class="card evidence-card">
|
||||
<div class="case-legend">
|
||||
<span class="section-label">Training floor board</span>
|
||||
<span class="pill">Training Dossier</span>
|
||||
</div>
|
||||
<h2>Current body metrics</h2>
|
||||
<div class="grid dossier-grid">
|
||||
{% for user in summary.users %}
|
||||
<section class="evidence-slab">
|
||||
<h3>{{ user.display_name }} {% if user.is_stub %}<span class="badge">stub</span>{% endif %}</h3>
|
||||
<p class="metric-value">{{ user.current_weight_lbs if user.current_weight_lbs is not none else '—' }}{% if user.current_weight_lbs is not none %} lb{% endif %}</p>
|
||||
<p class="muted">BMI: {{ '%.1f'|format(user.current_bmi) if user.current_bmi is not none else 'Not set yet' }}</p>
|
||||
<p class="muted">System: {{ user.measurement_system }}</p>
|
||||
{% if user.latest_measurements %}
|
||||
<p class="muted">
|
||||
Waist {{ user.latest_measurements.waist_inches or '—' }} in ·
|
||||
Hips {{ user.latest_measurements.hip_inches or '—' }} in ·
|
||||
Chest {{ user.latest_measurements.chest_inches or '—' }} in ·
|
||||
Neck {{ user.latest_measurements.neck_inches or '—' }} in
|
||||
</p>
|
||||
{% else %}
|
||||
<p class="muted">No body measurements logged yet.</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="card evidence-card">
|
||||
<div class="case-legend">
|
||||
<span class="section-label">Case priorities</span>
|
||||
<span class="pill">Operator notes</span>
|
||||
</div>
|
||||
<h2>V1 focus</h2>
|
||||
<ul class="list case-list">
|
||||
<li>Structured workout logging with routines and exercises.</li>
|
||||
<li>Body-weight, BMI, waist/hip/chest/neck history in imperial units.</li>
|
||||
<li>Recent workouts, volume trends, and simple PR tracking.</li>
|
||||
</ul>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="grid cols-2 dossier-grid">
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">Intake docket</span><span class="pill">Weight log</span></div>
|
||||
<h2>Log weight</h2>
|
||||
<form class="stack-form intake-docket" method="post" action="/log/weight">
|
||||
<label>User
|
||||
<select name="user_id">
|
||||
{% for user in summary.users %}
|
||||
<option value="{{ user.id }}" {% if user.id == 'john' %}selected{% endif %}>{{ user.display_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>Recorded at
|
||||
<input type="datetime-local" name="recorded_at" required>
|
||||
</label>
|
||||
<div class="grid cols-2 compact-grid">
|
||||
<label>Weight (lb)
|
||||
<input type="number" name="weight_lbs" min="0" step="0.1" required>
|
||||
</label>
|
||||
<label>Body fat %
|
||||
<input type="number" name="body_fat_percent" min="0" max="100" step="0.1">
|
||||
</label>
|
||||
</div>
|
||||
<label>Notes
|
||||
<textarea name="notes" rows="2" placeholder="Morning weigh-in, post-workout, etc."></textarea>
|
||||
</label>
|
||||
<button type="submit">Save weight entry</button>
|
||||
</form>
|
||||
</article>
|
||||
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">Intake docket</span><span class="pill">Measurements</span></div>
|
||||
<h2>Log body measurements</h2>
|
||||
<form class="stack-form intake-docket" method="post" action="/log/measurements">
|
||||
<input type="hidden" name="user_id" value="john">
|
||||
<label>Recorded at
|
||||
<input type="datetime-local" name="recorded_at" required>
|
||||
</label>
|
||||
<div class="grid cols-2 compact-grid">
|
||||
<label>Waist (in)
|
||||
<input type="number" name="waist_inches" min="0" step="0.1">
|
||||
</label>
|
||||
<label>Hips (in)
|
||||
<input type="number" name="hip_inches" min="0" step="0.1">
|
||||
</label>
|
||||
<label>Chest (in)
|
||||
<input type="number" name="chest_inches" min="0" step="0.1">
|
||||
</label>
|
||||
<label>Neck (in)
|
||||
<input type="number" name="neck_inches" min="0" step="0.1">
|
||||
</label>
|
||||
</div>
|
||||
<label>Notes
|
||||
<textarea name="notes" rows="2" placeholder="Flexed, relaxed, baseline, etc."></textarea>
|
||||
</label>
|
||||
<button type="submit">Save measurement entry</button>
|
||||
</form>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="grid cols-2 dossier-grid">
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">Exercise library</span><span class="pill">Template intake</span></div>
|
||||
<h2>Add exercise template</h2>
|
||||
<form class="stack-form intake-docket" method="post" action="/templates">
|
||||
<label>Name
|
||||
<input type="text" name="name" placeholder="Bench Press" required>
|
||||
</label>
|
||||
<div class="grid cols-2 compact-grid">
|
||||
<label>Primary muscle
|
||||
<input type="text" name="primary_muscle" placeholder="Chest">
|
||||
</label>
|
||||
<label>Equipment
|
||||
<input type="text" name="equipment" placeholder="Barbell">
|
||||
</label>
|
||||
</div>
|
||||
<label>Notes
|
||||
<textarea name="notes" rows="3" placeholder="Technique cue, setup reminder, variation notes."></textarea>
|
||||
</label>
|
||||
<button type="submit">Add template</button>
|
||||
</form>
|
||||
</article>
|
||||
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">Routine intake</span><span class="pill">Draft split</span></div>
|
||||
<h2>Build routine draft</h2>
|
||||
<form class="stack-form intake-docket" method="post" action="/routines">
|
||||
<input type="hidden" name="user_id" value="john">
|
||||
<label>Routine name
|
||||
<input type="text" name="name" placeholder="Push Day Draft" required>
|
||||
</label>
|
||||
<label>Exercise lines
|
||||
<textarea name="exercise_lines" rows="6" placeholder="Bench Press|4|6-8 Incline Dumbbell Press|3|8-10 Triceps Pushdown|3|12-15" required></textarea>
|
||||
</label>
|
||||
<p class="hint">Format: exercise | target sets | target reps | optional notes</p>
|
||||
<label>Notes
|
||||
<textarea name="notes" rows="2" placeholder="Temporary until the real split gets entered."></textarea>
|
||||
</label>
|
||||
<button type="submit">Save routine draft</button>
|
||||
</form>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="grid cols-2 dossier-grid">
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">Workout report</span><span class="pill">Quick log</span></div>
|
||||
<h2>Quick log workout</h2>
|
||||
<form class="stack-form intake-docket" method="post" action="/workouts/quick-log">
|
||||
<input type="hidden" name="user_id" value="john">
|
||||
<label>Workout name
|
||||
<input type="text" name="routine_name" placeholder="Push Day" required>
|
||||
</label>
|
||||
<label>Performed at
|
||||
<input type="datetime-local" name="performed_at" required>
|
||||
</label>
|
||||
<label>Exercise lines
|
||||
<textarea name="exercise_lines" rows="6" placeholder="Bench Press|8@135, 8@145 Incline Dumbbell Press|10@50, 8@55|Last set close to failure" required></textarea>
|
||||
</label>
|
||||
<p class="hint">Format: exercise | reps@weight, reps@weight | optional notes</p>
|
||||
<label>Notes
|
||||
<textarea name="notes" rows="2" placeholder="Energy, pain, wins, misses."></textarea>
|
||||
</label>
|
||||
<button type="submit">Save workout</button>
|
||||
</form>
|
||||
</article>
|
||||
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">Library snapshot</span><span class="pill">Scaffold</span></div>
|
||||
<h2>Template and routine scaffold</h2>
|
||||
<p class="muted">You can start building the library now, even before the real split lands tomorrow.</p>
|
||||
<ul class="list case-list">
|
||||
<li>Exercise templates: {{ summary.counts.exercise_templates }}</li>
|
||||
<li>Routines: {{ summary.counts.routines }}</li>
|
||||
</ul>
|
||||
{% if summary.exercise_templates %}
|
||||
<p><strong>Templates</strong></p>
|
||||
<ul class="list">
|
||||
{% for template in summary.exercise_templates %}
|
||||
<li>{{ template.name }}{% if template.equipment %} · {{ template.equipment }}{% endif %}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if summary.routines %}
|
||||
<p><strong>Routines</strong></p>
|
||||
<ul class="list">
|
||||
{% for routine in summary.routines %}
|
||||
<li>{{ routine.name }} · {{ routine.exercises|length }} exercises</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="grid cols-2 dossier-grid">
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">Recent logs</span><span class="pill">Session reports</span></div>
|
||||
<h2>Recent workouts</h2>
|
||||
{% if john_workout_history %}
|
||||
<ul class="list">
|
||||
{% for workout in john_workout_history %}
|
||||
<li>
|
||||
<strong>{{ workout.routine_name }}</strong>
|
||||
<p class="muted">{{ workout.performed_at }} · {{ workout.set_count }} sets · {{ workout.total_volume_lbs }} lb volume</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class="muted">No workouts logged yet.</p>
|
||||
{% endif %}
|
||||
</article>
|
||||
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">History snapshot</span><span class="pill">John file</span></div>
|
||||
<h2>John history snapshot</h2>
|
||||
<div class="history-block">
|
||||
<h3>Recent weights</h3>
|
||||
{% if john_weight_history %}
|
||||
<ul class="list">
|
||||
{% for entry in john_weight_history %}
|
||||
<li>{{ entry.recorded_at }} · {{ entry.weight_lbs }} lb{% if entry.bmi is not none %} · BMI {{ '%.1f'|format(entry.bmi) }}{% endif %}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class="muted">No weight entries yet.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="history-block">
|
||||
<h3>Recent measurements</h3>
|
||||
{% if john_measurement_history %}
|
||||
<ul class="list">
|
||||
{% for entry in john_measurement_history %}
|
||||
<li>{{ entry.recorded_at }} · Waist {{ entry.waist_inches or '—' }} · Chest {{ entry.chest_inches or '—' }} · Hips {{ entry.hip_inches or '—' }} · Neck {{ entry.neck_inches or '—' }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class="muted">No measurement entries yet.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="grid cols-2 dossier-grid">
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">Current counts</span><span class="pill">Inventory</span></div>
|
||||
<h2>Current counts</h2>
|
||||
<ul class="list case-list">
|
||||
<li>Workout sessions: {{ summary.counts.workout_sessions }}</li>
|
||||
<li>Weight entries: {{ summary.counts.weight_entries }}</li>
|
||||
<li>Measurement entries: {{ summary.counts.measurement_entries }}</li>
|
||||
<li>Exercise templates: {{ summary.counts.exercise_templates }}</li>
|
||||
<li>Routines: {{ summary.counts.routines }}</li>
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">Exercise bests</span><span class="pill">PR board</span></div>
|
||||
<h2>Exercise bests</h2>
|
||||
{% if john_progression %}
|
||||
<ul class="list">
|
||||
{% for entry in john_progression %}
|
||||
<li>
|
||||
<strong>{{ entry.exercise_name }}</strong>
|
||||
<p class="muted">{{ entry.sessions }} sessions · max {{ entry.max_weight_lbs }} lb · est 1RM {{ entry.best_set_estimated_1rm }} lb</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class="muted">No exercise progression data yet.</p>
|
||||
{% endif %}
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="grid cols-2 dossier-grid">
|
||||
<article class="card evidence-board">
|
||||
<div class="case-legend"><span class="section-label">Next likely build</span><span class="pill">Open casework</span></div>
|
||||
<h2>Next likely build</h2>
|
||||
<ul class="list case-list">
|
||||
<li>Replace placeholder routines with John’s real day-by-day program tomorrow.</li>
|
||||
<li>Routine-specific workout entry flow driven directly from the saved split.</li>
|
||||
<li>Exercise progression and PR views.</li>
|
||||
</ul>
|
||||
</article>
|
||||
</section>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user