Files
workout/templates/program_view.html
Peter Stockings dd82f461be feat: Add workout program management
- Create database tables: workout_program, program_session, person_program_assignment.
- Add Flask blueprint `routes/programs.py` with routes for creating, listing, viewing, and deleting programs.
- Implement program creation form (`templates/program_create.html`):
    - Allows defining program name, description, and multiple sessions.
    - Each session includes a name and dynamically added exercise selections.
    - Uses `tail.select` for searchable exercise dropdowns.
    - JavaScript handles dynamic addition/removal of sessions and exercises.
- Implement backend logic for program creation:
    - Parses form data including multiple exercises per session.
    - Automatically finds or creates non-person-specific tags based on selected exercises for each session.
    - Saves program and session data, linking sessions to appropriate tags.
- Implement program list view (`templates/program_list.html`):
    - Displays existing programs.
    - Includes HTMX-enabled delete button for each program.
    - Links program names to the view page using HTMX for dynamic loading.
- Implement program detail view (`templates/program_view.html`):
    - Displays program name, description, and sessions.
    - Parses session tag filters to retrieve and display associated exercises.
- Update changelog with details of the new feature.
2025-04-24 20:17:30 +10:00

82 lines
3.8 KiB
HTML

{% extends "base.html" %}
{% block title %}{{ program.name }} - Program Details{% endblock %}
{% block content %}
<div class="container mx-auto px-4 py-8 max-w-4xl">
{# Back Link #}
<div class="mb-4">
<a href="{{ url_for('programs.list_programs') }}" hx-get="{{ url_for('programs.list_programs') }}"
hx-target="#container" hx-push-url="true" hx-swap="innerHTML"
class="text-indigo-600 hover:text-indigo-800 text-sm">
&larr; Back to Programs List
</a>
</div>
{# Program Header #}
<div class="bg-white shadow overflow-hidden sm:rounded-lg mb-8">
<div class="px-4 py-5 sm:px-6">
<h1 class="text-2xl leading-6 font-bold text-gray-900">
{{ program.name }}
</h1>
{% if program.description %}
<p class="mt-1 max-w-2xl text-sm text-gray-500">
{{ program.description }}
</p>
{% endif %}
{# Add Edit/Assign buttons here later #}
</div>
</div>
{# Sessions Section #}
<h2 class="text-xl font-semibold mb-4 text-gray-700">Sessions</h2>
<div class="space-y-6">
{% if sessions %}
{% for session in sessions %}
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
<div class="px-4 py-4 sm:px-6 bg-gray-50 border-b border-gray-200">
<h3 class="text-lg leading-6 font-medium text-gray-900">
Day {{ session.session_order }}{% if session.session_name %}: {{ session.session_name }}{% endif %}
</h3>
<p class="mt-1 text-sm text-gray-500">Tag: {{ session.tag_name }} (ID: {{ session.tag_id }})</p>
</div>
<div class="border-t border-gray-200 px-4 py-5 sm:p-0">
<dl class="sm:divide-y sm:divide-gray-200">
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">
Exercises
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{% if session.exercises %}
<ul role="list" class="border border-gray-200 rounded-md divide-y divide-gray-200">
{% for exercise in session.exercises %}
<li class="pl-3 pr-4 py-3 flex items-center justify-between text-sm">
<div class="w-0 flex-1 flex items-center">
<!-- Heroicon name: solid/paper-clip -->
{# Could add an icon here #}
<span class="ml-2 flex-1 w-0 truncate">
{{ exercise.name }} (ID: {{ exercise.exercise_id }})
</span>
</div>
{# Add links/actions per exercise later if needed #}
</li>
{% endfor %}
</ul>
{% else %}
<p class="text-gray-500 italic">No exercises found for this session's tag filter.</p>
{% endif %}
</dd>
</div>
{# Add more session details here if needed #}
</dl>
</div>
</div>
{% endfor %}
{% else %}
<p class="text-gray-500 italic">This program currently has no sessions defined.</p>
{% endif %}
</div>
</div>
{% endblock %}