Files
workout/templates/partials/exercise_history.html
T

125 lines
7.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% if offset == 0 %}
<div id="exercise-history-container"
class="w-full bg-gray-50 p-4 border-t border-gray-200 shadow-inner overflow-x-auto">
<div class="flex items-center justify-between sm:justify-center relative mb-1">
<div class="flex flex-col sm:flex-row items-center justify-center w-full gap-x-2">
<h4 class="text-lg font-semibold text-blue-400">{{ title }}</h4>
<div hx-get="{{ url_for('workout.get_topset_achievements', person_id=person_id, workout_id=latest_workout_id, topset_id=latest_topset_id) }}"
hx-trigger="load" hx-target="this" hx-swap="innerHTML" class="flex items-center">
</div>
</div>
<div class="absolute left-0 z-10">
<button
class="inline-flex justify-center p-1 text-gray-500 rounded cursor-pointer hover:text-gray-900 hover:bg-gray-100"
title="Show Progress Graph"
hx-get="{{ url_for('get_exercise_progress_for_user', person_id=person_id, exercise_id=exercise_id, epoch='All', forecast='true' if forecast_enabled else 'false', forecast_weeks=forecast_weeks, forecast_reps=forecast_target_reps) }}"
hx-target="#exercise-history-container" hx-swap="outerHTML">
<svg class="w-5 h-5 border border-gray-300 rounded p-0.5" fill="none" stroke="currentColor"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"></path>
</svg>
<span class="sr-only">Show Progress Graph</span>
</button>
</div>
</div>
{% if best_fit_formula %}
<h2 class="text-xs font-semibold text-blue-200 mb-4 text-center">
{{ best_fit_formula.kg_per_week }} kg/week, {{ best_fit_formula.kg_per_month }} kg/month
</h2>
{% else %}
<div class="mb-4"></div>
{% endif %}
{% if forecast_enabled and forecast.available %}
<div class="mb-4 rounded-lg border border-emerald-100 bg-emerald-50/70 p-3 text-left">
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2">
<div>
<div class="text-xs font-semibold uppercase tracking-wide text-emerald-800">Projected rep-to-weight map</div>
<div class="text-sm text-gray-700">In {{ forecast.horizon_weeks }} weeks · projected E1RM {{ forecast.projected_value }}kg</div>
</div>
<div class="text-xs text-gray-500 sm:text-right">
Based on {{ forecast.observed_rep_min }}–{{ forecast.observed_rep_max }} reps in view<br>
expanded by ±{{ forecast.rep_buffer }} reps
</div>
</div>
<div class="mt-3 overflow-x-auto rounded border border-emerald-100 bg-white">
<table class="w-full text-left text-xs text-gray-600">
<thead class="bg-gray-50 text-gray-500">
<tr>
<th class="px-3 py-2 font-medium">Reps</th>
<th class="px-3 py-2 font-medium">Est. load</th>
<th class="px-3 py-2 font-medium">Model range</th>
<th class="px-3 py-2 font-medium text-right">Proj. E1RM</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
{% for top_set in forecast.top_sets %}
<tr class="cursor-pointer {% if forecast.selected_reps == top_set.repetitions %}bg-emerald-50 text-emerald-800 font-semibold{% else %}hover:bg-gray-50{% endif %}"
title="View {{ top_set.repetitions }} reps on the graph"
hx-get="{{ url_for('get_exercise_progress_for_user', person_id=person_id, exercise_id=exercise_id, epoch='All', forecast='true', forecast_weeks=forecast_weeks, forecast_reps=top_set.repetitions) }}"
hx-target="#exercise-history-container" hx-swap="outerHTML">
<td class="px-3 py-2">{{ top_set.repetitions }}</td>
<td class="px-3 py-2">{{ top_set.weight_display }}kg</td>
<td class="px-3 py-2">{{ top_set.lower_weight_display }}–{{ top_set.upper_weight_display }}kg</td>
<td class="px-3 py-2 text-right">{{ top_set.e1rm_display }}kg</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="mt-2 text-[11px] text-gray-400">Click a row to return to the graph with that rep target selected. Loads rounded to {{ forecast.target_weight_increment_display }}kg increments.</div>
</div>
{% endif %}
<table class="w-full text-left text-sm text-gray-500">
<thead class="text-xs text-gray-700 uppercase bg-gray-100">
<tr>
<th scope="col" class="px-3 py-2">Date</th>
<th scope="col" class="px-3 py-2">Set & Achievements</th>
</tr>
</thead>
<tbody>
{% endif %}
{% for topset in topsets %}
<tr class="border-b bg-white">
<td class="px-3 py-2 text-sm text-gray-900 whitespace-nowrap">
{{ topset.start_date | strftime }}
</td>
<td class="px-3 py-2 text-sm text-gray-900">
<div class="flex flex-wrap items-center gap-x-2 gap-y-1">
<span class="whitespace-nowrap">{{ topset.repetitions }} x {{ topset.weight }}kg</span>
<div hx-get="{{ url_for('workout.get_topset_achievements', person_id=person_id, workout_id=topset.workout_id, topset_id=topset.topset_id) }}"
hx-trigger="load" hx-target="this" hx-swap="innerHTML"
class="flex flex-wrap items-center gap-1">
<!-- Badges load here -->
</div>
</div>
</td>
</tr>
{% endfor %}
{% if topsets|length == limit %}
<tr id="history-load-more-{{ source_topset_id }}-{{ offset + limit }}">
<td colspan="2" class="px-3 py-3 text-center">
<button
class="text-sm text-blue-600 hover:underline font-medium px-4 py-2 border border-blue-600 rounded"
hx-get="{{ url_for('workout.get_exercise_history', person_id=person_id, exercise_id=exercise_id, limit=limit, offset=offset + limit, source_topset_id=source_topset_id, forecast='true' if forecast_enabled else 'false', forecast_weeks=forecast_weeks, forecast_reps=forecast_target_reps) }}"
hx-target="#history-load-more-{{ source_topset_id }}-{{ offset + limit }}" hx-swap="outerHTML">
Load More
</button>
</td>
</tr>
{% elif topsets|length == 0 and offset == 0 %}
<tr>
<td colspan="2" class="px-3 py-4 text-center text-gray-500">
No history found.
</td>
</tr>
{% endif %}
{% if offset == 0 %}
</tbody>
</table>
</div>
{% endif %}