Refactor calendar (month and year view), switching to vertical slice arch. Also in progress of refactoring of stats so they are retreived after inital page load for performance sake

This commit is contained in:
Peter Stockings
2024-04-11 13:45:38 +10:00
parent 76789a4934
commit 63d997a3f1
7 changed files with 302 additions and 133 deletions

View File

@@ -108,7 +108,8 @@
{% block content %}
{% endblock %}
</div>
{% block stats %}
{% endblock %}
</main>
</div>
@@ -150,6 +151,9 @@
</div>
</template>
{% block add_workout_button %}
{% endblock %}
</body>
</html>

View File

@@ -2,16 +2,17 @@
{% block content %}
<a hx-get="{{ url_for('get_calendar', person_id=person['PersonId']) }}" hx-target="#container"
hx-vals='{"date": "{{ selected_date }}", "view": "{{ selected_view }}"}' hx-trigger="refreshView"
id="refreshViewElement"></a>
<a hx-get="{{ url_for('get_calendar', person_id=person_id) }}" hx-target="#container"
hx-vals='{"date": "{{ date }}", "view": "{{ view }}"}' hx-trigger="refreshView" id="refreshViewElement"
hx-swap="innerHTML swap:0.5s"></a>
<div class="flex flex-grow flex-col bg-white sm:rounded shadow overflow-hidden">
<div class="flex items-center justify-between pt-2 pb-2">
<div class="flex">
<div class="flex ml-1 md:ml-6">
<button hx-get="{{ url_for('get_calendar', person_id=person['PersonId']) }}" hx-target="#container"
hx-vals='{"date": "{{ previous_date }}"}' hx-include="[name='view']" hx-push-url="true">
<button hx-get="{{ url_for('get_calendar', person_id=person_id) }}" hx-target="#container"
hx-vals='{"date": "{{ prev_date }}"}' hx-include="[name='view']" hx-push-url="true"
hx-swap="innerHTML swap:0.5s">
<svg class="w-6 h-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke="currentColor" data-darkreader-inline-stroke=""
style="--darkreader-inline-stroke:currentColor;">
@@ -19,8 +20,9 @@
</path>
</svg>
</button>
<button hx-get="{{ url_for('get_calendar', person_id=person['PersonId']) }}" hx-target="#container"
hx-vals='{"date": "{{ next_date }}"}' hx-include="[name='view']" hx-push-url="true">
<button hx-get="{{ url_for('get_calendar', person_id=person_id) }}" hx-target="#container"
hx-vals='{"date": "{{ next_date }}"}' hx-include="[name='view']" hx-push-url="true"
hx-swap="innerHTML swap:0.5s">
<svg class="w-6 h-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke="currentColor" data-darkreader-inline-stroke=""
style="--darkreader-inline-stroke:currentColor;">
@@ -30,29 +32,29 @@
</button>
</div>
{% if selected_view == 'month' %}
<h2 class="ml-2 text-xl font-bold leading-none">{{ selected_date | strftime('%B, %Y') }}</h2>
{% if view == 'month' %}
<h2 class="ml-2 text-xl font-bold leading-none">{{ date | strftime('%B, %Y') }}</h2>
{% else %}
<h2 class="ml-2 text-xl font-bold leading-none">{{ selected_date | strftime('%Y') }}</h2>
<h2 class="ml-2 text-xl font-bold leading-none">{{ date | strftime('%Y') }}</h2>
{% endif %}
<span
class="bg-blue-100 text-blue-800 text-sm font-medium mr-2 px-2.5 py-0.5 rounded dark:bg-blue-200 dark:text-blue-800 ml-1 sm:ml-5 flex justify-center items-center ">{{
person['PersonName']}}</span>
class="bg-blue-100 text-blue-800 text-sm font-medium mr-2 px-2.5 py-0.5 rounded dark:bg-blue-200 dark:text-blue-800 ml-1 sm:ml-5 flex justify-center items-center ">
{{ person_name }}
</span>
</div>
<div class="mr-4">
<select name="view" hx-get="{{ url_for('get_calendar', person_id=person['PersonId']) }}"
hx-target="#container" hx-vals='{"date": "{{ selected_date }}"}' hx-push-url="true"
_="init js(me) tail.select(me, {}) end">
<option value="month" {% if selected_view=='month' %}selected{% endif %}>Month</option>
<option value="year" {% if selected_view=='year' %}selected{% endif %}>Year</option>
<select name="view" hx-get="{{ url_for('get_calendar', person_id=person_id) }}" hx-target="#container"
hx-vals='{"date": "{{ date }}"}' hx-push-url="true" _="init js(me) tail.select(me, {}) end">
<option value="month" {% if view=='month' %}selected{% endif %}>Month</option>
<option value="year" {% if view=='year' %}selected{% endif %}>Year</option>
<option value="notes">Notes</option>
<option value="all">All</option>
</select>
</div>
</div>
{% if selected_view == 'month' %}
{% if view == 'month' %}
<div class="flex flex-col px-2 py-2 -mb-px">
<div class="grid grid-cols-7 pl-2 pr-2">
@@ -88,57 +90,44 @@
<div class="grid grid-cols-7 overflow-hidden flex-1 pl-2 pr-2 w-full">
{% for i in range((end_date-start_date).days + 1) %}
{% set date = start_date + timedelta(days=i) %}
{% set workout = person['Workouts'] |
get_first_element_from_list_with_matching_attribute(
'StartDate',
date) %}
<div class="{% if date == datetime.today().date() %}rounded-md border-4 border-green-50{% endif %} border flex flex-col h-36 sm:h-40 md:h-30 lg:h-30 mx-auto mx-auto overflow-hidden w-full pt-2 pl-1 cursor-pointer {% if selected_date.month != date.month %}bg-gray-100{% endif %}"
{% if workout %}
hx-get="{{ url_for('get_workout_modal', person_id=person['PersonId'], workout_id=workout['WorkoutId']) }}"
hx-target='body' hx-swap='beforeend' {% endif %}>
{% for day in days %}
<div
class="{% if day.is_today %}rounded-md border-4 border-green-50{% endif %} border flex flex-col h-36 sm:h-40 md:h-30 lg:h-30 mx-auto mx-auto overflow-hidden w-full pt-2 pl-1 cursor-pointer {% if day.is_in_current_month %}bg-gray-100{% endif %}">
<div class="top h-5 w-full">
<span class="text-gray-500 font-semibold">{{ date.day }}</span>
<span class="text-gray-500 font-semibold">{{ day.day }}</span>
</div>
<div class="bottom flex-grow py-1 w-full">
{% if workout['TopSets']|length > 0 %}
{% for topset in workout['TopSets'] %}
{% for workout in day.workouts %}
<div class="bottom flex-grow py-1 w-full"
hx-get="{{ url_for('get_workout_modal', person_id=person_id, workout_id=workout.workout_id) }}"
hx-target='body' hx-swap='beforeend'>
{% for set in workout.sets %}
<button
class="flex flex-col xl:flex-row items-start lg:items-center flex-shrink-0 px-0 sm:px-0.5 md:px-0.5 lg:px-0.5 text-xs">
<span class="ml-0 sm:ml-0.5 md:ml-2 lg:ml-2 font-medium leading-none truncate">{{
topset['ExerciseName'] }}</span>
<span class="ml-0 sm:ml-0.5 md:ml-2 lg:ml-2 font-light leading-none">{{ topset['Repetitions'] }}
x
{{
topset['Weight']
}}kg</span>
set.exercise_name }}</span>
<span class="ml-0 sm:ml-0.5 md:ml-2 lg:ml-2 font-light leading-none">{{ set.repetitions }} x {{
set.weight }}kg</span>
</button>
{% endfor %}
{% endif %}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
{% elif selected_view == 'year'%}
{% elif view == 'year'%}
<div class="flex justify-center px-2 py-2 -mb-px">
<div
class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 gap-4 lg:gap-10 bg-white overflow-hidden">
{% for i in range(12) %}
{% set date = start_date + relativedelta(months=i) %}
{% set first_day_of_month = date.replace(day=1) %}
{% set last_day_of_month = date + relativedelta(day=31) %}
{% set (first_day, last_day) = first_and_last_visible_days_in_month(first_day_of_month, last_day_of_month)
%}
{% for month in months %}
<div>
<div class="bg-grey-lighter font-semibold text-center cursor-pointer"
hx-get="{{ url_for('get_calendar', person_id=person['PersonId']) }}" hx-target="#container"
hx-vals='{"date": "{{ first_day_of_month }}", "view": "month"}' hx-push-url="true"
_="on click go to the top of the body">{{
first_day_of_month | strftime('%B %Y') }}
hx-get="{{ url_for('get_calendar', person_id=person_id) }}" hx-target="#container"
hx-vals='{"date": "{{ month.first_day_of_month }}", "view": "month"}' hx-push-url="true"
_="on click go to the top of the body">
{{ month.first_day_of_month | strftime('%B') }}
</div>
<div>
<div class="grid grid-cols-7 border-b font-semibold">
@@ -152,18 +141,15 @@
</div>
<div class="grid grid-cols-7 overflow-hidden flex-1 pl-2 pr-2 w-full">
{% for i in range((last_day-first_day).days + 1) %}
{% set day_date = first_day + timedelta(days=i) %}
{% set workout = person['Workouts'] | get_first_element_from_list_with_matching_attribute(
'StartDate',
day_date) %}
{% set is_in_month = day_date.month == first_day_of_month.month%}
<div class="{% if day_date == datetime.today().date() and is_in_month %}rounded-md border-4 border-green-50 border{% endif %} py-3 px-4 hover:bg-blue hover:text-white text-center cursor-pointer rounded-md {% if workout and is_in_month %}bg-green-100{% endif %}"
{% if workout %}
hx-get="{{ url_for('get_workout_modal', person_id=person['PersonId'], workout_id=workout['WorkoutId']) }}"
{% for day in month.days %}
<div class="{% if day.is_today and day.is_in_current_month %}rounded-md border-4 border-green-50 border{% endif %} py-3 px-4 hover:bg-blue hover:text-white text-center cursor-pointer rounded-md {% if day.has_workouts and day.is_in_current_month %}bg-green-100{% endif %}"
{% if day.has_workouts %}
hx-get="{{ url_for('get_workout_modal', person_id=person_id, workout_id=day.first_workout_id) }}"
hx-target='body' hx-swap='beforeend' {% endif %}>
{% if is_in_month %}
{{ day_date.day }} {% endif %}</div>
{% if day.is_in_current_month %}
{{ day.day }}
{% endif %}
</div>
{% endfor %}
</div>
</div>
@@ -175,11 +161,20 @@
{% endif %}
</div>
</div>
{{ render_partial('partials/stats.html', stats=person['Stats']) }}
{% endblock %}
{% block stats %}
<div class="hidden" hx-get="{{ url_for('get_stats_for_person', person_id=person_id) }}" hx-trigger="load"
hx-target="this" hx-swap="outerHTML">
</div>
{% endblock %}
{% block add_workout_button %}
<button
class="fixed z-90 bottom-10 right-8 bg-blue-600 w-20 h-20 rounded-full drop-shadow-lg flex justify-center items-center text-white text-4xl hover:bg-blue-700 hover:drop-shadow-2xl hover:animate-bounce duration-300"
hx-post="{{ url_for('create_workout', person_id=person['PersonId']) }}" hx-target='body' hx-swap='beforeend'>
hx-post="{{ url_for('create_workout', person_id=person_id) }}" hx-target='body' hx-swap='beforeend'>
<svg viewBox="0 0 20 20" enable-background="new 0 0 20 20" class="w-6 h-6 inline-block">
<path fill="#FFFFFF" d="M16,10c0,0.553-0.048,1-0.601,1H11v4.399C11,15.951,10.553,16,10,16c-0.553,0-1-0.049-1-0.601V11H4.601
C4.049,11,4,10.553,4,10c0-0.553,0.049-1,0.601-1H9V4.601C9,4.048,9.447,4,10,4c0.553,0,1,0.048,1,0.601V9h4.399