Simplify forecast panel and extend horizon
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% if best_fit_formula %}
|
||||
{% if best_fit_formula and not forecast_enabled %}
|
||||
<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>
|
||||
|
||||
@@ -34,6 +34,7 @@ M{% for value, position in lower_points %}{{ (((position * vb_width) + margin) |
|
||||
|
||||
{% macro forecast_circles(data_points, details, color) %}
|
||||
{% for value, position in data_points %}
|
||||
{% if loop.last %}
|
||||
{% set x = (position * vb_width)+margin %}
|
||||
{% set y = (vb_height - value)+margin %}
|
||||
<circle cx="{{ x | int }}" cy="{{ y | int }}" r="1.6" fill="{{ color }}" stroke="{{ color }}"
|
||||
@@ -43,6 +44,7 @@ M{% for value, position in lower_points %}{{ (((position * vb_width) + margin) |
|
||||
data-e1rm="{{ details[loop.index0].e1rm }}"
|
||||
data-topset="{{ details[loop.index0].top_set }}"
|
||||
data-range="{{ details[loop.index0].range }}"></circle>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
@@ -102,9 +104,9 @@ M{% for value, position in lower_points %}{{ (((position * vb_width) + margin) |
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="text-xs font-semibold text-blue-200 mb-1 text-center">
|
||||
{% if best_fit_formula %}
|
||||
{{ best_fit_formula.kg_per_week }} kg/week, {{ best_fit_formula.kg_per_month }} kg/month
|
||||
{% endif %}
|
||||
{% if best_fit_formula and not forecast_enabled %}
|
||||
{{ best_fit_formula.kg_per_week }} kg/week, {{ best_fit_formula.kg_per_month }} kg/month
|
||||
{% endif %}
|
||||
</h2>
|
||||
<div class="inline-flex rounded-md shadow-sm w-full items-center justify-center mb-1">
|
||||
{% for epoch in epochs %}
|
||||
@@ -127,43 +129,32 @@ M{% for value, position in lower_points %}{{ (((position * vb_width) + margin) |
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if forecast_enabled %}
|
||||
<div class="mx-2 mb-3 rounded-xl border {% if forecast.available %}border-emerald-100 bg-emerald-50/70{% else %}border-amber-100 bg-amber-50/70{% endif %} p-3 text-left">
|
||||
<div class="mx-2 mb-3 rounded-xl border {% if forecast.available %}border-emerald-100 bg-emerald-50/70{% else %}border-amber-100 bg-amber-50/70{% endif %} p-2.5 text-left">
|
||||
{% if forecast.available %}
|
||||
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2">
|
||||
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-1.5">
|
||||
<div>
|
||||
<div class="text-xs font-semibold uppercase tracking-wide text-emerald-800">E1RM projection</div>
|
||||
<div class="text-sm text-gray-700 mt-0.5">{{ forecast.last_value }}kg now <span class="text-gray-400">→</span> <span class="font-bold text-emerald-800">{{ forecast.projected_value }}kg</span> in {{ forecast.horizon_weeks }} weeks</div>
|
||||
<div class="text-xs font-semibold uppercase tracking-wide text-emerald-800">Forecast · {{ forecast.horizon_weeks }} weeks</div>
|
||||
<div class="text-lg font-bold text-gray-800 mt-0.5">{{ forecast.projected_value }}kg <span class="text-xs font-normal text-gray-500">projected E1RM</span></div>
|
||||
</div>
|
||||
<div class="text-left sm:text-right">
|
||||
<div class="text-sm font-semibold {% if forecast.weekly_change >= 0 %}text-emerald-700{% else %}text-rose-700{% endif %}">{% if forecast.weekly_change >= 0 %}+{% endif %}{{ forecast.weekly_change }}kg/week</div>
|
||||
<div class="text-sm font-semibold {% if forecast.projected_change >= 0 %}text-emerald-700{% else %}text-rose-700{% endif %}">{% if forecast.projected_change >= 0 %}+{% endif %}{{ forecast.projected_change }}kg total</div>
|
||||
<div class="text-xs text-gray-500">{{ forecast.confidence }} confidence · {{ forecast.observed_points }} sessions</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if forecast.selected_top_set %}
|
||||
<div class="mt-3 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 rounded-lg border border-emerald-100 bg-white/80 px-3 py-2.5">
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div>
|
||||
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500">Projected top set</div>
|
||||
<div class="text-lg font-bold text-gray-800">{{ forecast.selected_top_set.weight_display }}kg × {{ forecast.selected_top_set.repetitions }} reps</div>
|
||||
</div>
|
||||
<div class="text-right text-xs text-gray-500">
|
||||
<div>Model range</div>
|
||||
<div class="font-semibold text-emerald-700">{{ forecast.selected_top_set.lower_weight_display }}–{{ forecast.selected_top_set.upper_weight_display }}kg</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-[11px] text-gray-500 sm:text-right">
|
||||
Full rep-to-weight forecast in the table view.<br>
|
||||
Based on {{ forecast.observed_rep_min }}–{{ forecast.observed_rep_max }} reps in view.
|
||||
</div>
|
||||
<div class="mt-2 flex flex-wrap items-center gap-x-2 gap-y-1 rounded-lg bg-white/80 px-2.5 py-2 text-sm">
|
||||
<span class="text-xs font-semibold uppercase tracking-wide text-gray-500">Top-set guide</span>
|
||||
<span class="font-bold text-gray-800">{{ forecast.selected_top_set.weight_display }}kg × {{ forecast.selected_top_set.repetitions }}</span>
|
||||
<span class="text-xs text-gray-500">at the selected rep target · details in History</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="flex flex-wrap items-center gap-2 mt-3">
|
||||
<div class="flex flex-wrap items-center gap-1.5 mt-2.5">
|
||||
<span class="text-xs text-gray-500 mr-1">Horizon</span>
|
||||
{% for weeks in [4, 8, 12, 26] %}
|
||||
<button class="px-2.5 py-1 rounded-md text-xs font-medium {% if forecast_weeks == weeks %}bg-emerald-700 text-white{% else %}bg-white text-gray-600 border border-emerald-200 hover:bg-emerald-100{% endif %}"
|
||||
{% for weeks, label in forecast_horizons %}
|
||||
<button class="px-2 py-0.5 rounded-md text-xs font-medium {% if forecast_weeks == weeks %}bg-emerald-700 text-white{% else %}bg-white text-gray-600 border border-emerald-200 hover:bg-emerald-100{% endif %}"
|
||||
hx-get="{{ url_for('get_exercise_progress_for_user', person_id=person_id, exercise_id=exercise_id, epoch=selected_epoch, forecast='true', forecast_weeks=weeks, forecast_reps=forecast_target_reps) }}"
|
||||
hx-include="#svg-plot-{{ unique_id }} [name='min_date'], #svg-plot-{{ unique_id }} [name='max_date'], #svg-plot-{{ unique_id }} [name='degree']"
|
||||
hx-target="#svg-plot-{{ unique_id }}" hx-swap="outerHTML">{{ weeks }}w</button>
|
||||
hx-target="#svg-plot-{{ unique_id }}" hx-swap="outerHTML">{{ label }}</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
Reference in New Issue
Block a user