{% extends "base.html" %} {% from "_trainings_table.html" import approach_chips %} {% block content %} {% macro num(value) %}{{ '%g'|format(value|round(1)) }}{% endmacro %} {# "+12 кг (+6.5%)" colored by direction; unit is "кг" or "повт." #} {% macro change(value, percent, unit) %} {{ '%+g'|format(value|round(1)) }} {{ unit }}{% if percent is not none %} ({{ '%+.1f'|format(percent) }}%){% endif %} к первой тренировке {% endmacro %} {# Text with a dotted underline and a tooltip explaining it #} {% macro tip(text, hint) %}{{ text }}{% endmacro %} {% macro stat_card(title, value, note, hint) %}
{{ tip(title, hint) }}
{{ value }}
{{ note }}
{% endmacro %} {% set hints = { 'record_e1rm': 'e1RM — расчётный максимум на один повтор по лучшему подходу тренировки (формула Эпли: вес × (1 + повторы / 30)). Рекорд — наибольшее значение за всю историю.', 'last_e1rm': 'e1RM лучшего подхода последней тренировки. Ниже — изменение относительно первой тренировки с этим упражнением.', 'record_volume': 'Тоннаж — суммарная работа за тренировку: сумма вес × повторы по всем подходам с весом. Рекорд — тренировка с наибольшим тоннажем.', 'max_weight': 'Самый тяжёлый вес в одном подходе за всю историю, без учёта повторов.', 'best_reps': 'Наибольшее число повторов в одном подходе за всю историю.', 'last_best_reps': 'Наибольшее число повторов в одном подходе последней тренировки. Ниже — изменение относительно первой тренировки.', 'record_total_reps': 'Наибольшая сумма повторов по всем подходам за одну тренировку.', 'e1rm': 'Расчётный максимум на один повтор по лучшему подходу тренировки (формула Эпли: вес × (1 + повторы / 30)). Подходы без веса не учитываются.', 'volume': 'Тоннаж: сумма вес × повторы по подходам с весом за тренировку.', } %}

История упражнения

{% for item in exercise_names %}{% endfor %}
{% if selected %} {% set rows = progress.rows %}

{{ selected }}

Тренировок: {{ rows|length }}, первая: {{ rows[-1].session.date.strftime('%d.%m.%Y') }}, последняя: {{ rows[0].session.date.strftime('%d.%m.%Y') }}

{% if progress.weighted %} {{ stat_card('Рекорд e1RM', num(progress.best_primary.value) ~ ' кг', progress.best_primary.date.strftime('%d.%m.%Y'), hints.record_e1rm) }} {{ stat_card('Последний e1RM', num(progress.last_primary) ~ ' кг', change(progress.primary_change, progress.primary_change_percent, 'кг') if rows|length > 1 else '', hints.last_e1rm) }} {{ stat_card('Рекорд тоннажа', num(progress.best_secondary.value) ~ ' кг', progress.best_secondary.date.strftime('%d.%m.%Y'), hints.record_volume) }} {{ stat_card('Максимальный вес', num(progress.max_weight) ~ ' кг', '', hints.max_weight) }} {% else %} {{ stat_card('Лучший подход', num(progress.best_primary.value) ~ ' повт.', progress.best_primary.date.strftime('%d.%m.%Y'), hints.best_reps) }} {{ stat_card('Лучший подход в последний раз', num(progress.last_primary) ~ ' повт.', change(progress.primary_change, progress.primary_change_percent, 'повт.') if rows|length > 1 else '', hints.last_best_reps) }} {{ stat_card('Рекорд суммы повторов', num(progress.best_secondary.value), progress.best_secondary.date.strftime('%d.%m.%Y'), hints.record_total_reps) }} {% endif %}

{% if progress.weighted %} e1RM — расчётный максимум на один повтор по формуле Эпли: вес × (1 + повторы / 30), берётся лучший подход тренировки; подходы без веса не учитываются. Тоннаж — сумма вес × повторы по подходам с весом. {% else %} Упражнение выполняется без дополнительного веса, поэтому прогресс считается по повторам. {% endif %}

{% if progress.weighted %} {% else %} {% endif %} {% for row in rows %} {% set item = row.session %} {% set m = row.metrics %} {# data-order: ISO date and plain numbers, so sorting is chronological/numeric #} {% if progress.weighted %} {% else %} {% endif %} {% endfor %}
Дата Тренер Подходы (вес × повторения)Макс. вес {{ tip('e1RM', hints.e1rm) }} {{ tip('Тоннаж', hints.volume) }}Лучший подход Всего повторов
{{ item.date.strftime('%d.%m.%Y') }} {{ item.trainer or '' }} {{ approach_chips(item.approaches) }} {% if item.splitted_weight %} на руку {% endif %} {% if m.max_weight %}{{ num(m.max_weight) }} кг{% else %}—{% endif %} {% if m.e1rm %}{{ num(m.e1rm) }} кг{% else %}—{% endif %} {% if m.volume %}{{ num(m.volume) }} кг{% else %}—{% endif %}{{ m.best_reps }} {{ m.total_reps }}
{% elif query %}
Упражнение «{{ query }}» не найдено. {% if suggestions %}Возможно, вы искали:{% endif %}
{% if suggestions %}
{% for item in suggestions %} {{ item.name }} {{ item.count }} {% endfor %}
{% endif %} {% elif not exercise_names %}
В базе пока нет тренировок. Загрузи их из заметок командой:
docker compose exec fastapi-app python -m app.cli import
{% endif %} {% endblock %} {% block extra_scripts %} {% if chart %}{% endif %} {% endblock %}