Make calendar month view default when viewing a persons workout and display workouts for month view (year view remaining)
This commit is contained in:
25
app.py
25
app.py
@@ -1,4 +1,5 @@
|
||||
from datetime import datetime, date, timedelta
|
||||
import calendar
|
||||
import os
|
||||
from flask import Flask, render_template, redirect, request, url_for
|
||||
import jinja_partials
|
||||
@@ -31,7 +32,7 @@ def get_person_list():
|
||||
return render_template('partials/people_link.html', people=people)
|
||||
|
||||
|
||||
@ app.route("/person/<int:person_id>")
|
||||
@ app.route("/person/<int:person_id>/workout/list", methods=['GET'])
|
||||
@ validate_person
|
||||
def get_person(person_id):
|
||||
person = db.get_person(person_id)
|
||||
@@ -70,15 +71,31 @@ def get_calendar(person_id):
|
||||
'date'), '%Y-%m-%d') or date.today()
|
||||
selected_view = request.args.get('view') or 'month'
|
||||
|
||||
if selected_view == 'all':
|
||||
return redirect(url_for('get_person', person_id=person_id))
|
||||
|
||||
next_date = selected_date + (timedelta(
|
||||
365/12) if selected_view == 'month' else timedelta(365))
|
||||
previous_date = selected_date + (timedelta(
|
||||
-365/12) if selected_view == 'month' else timedelta(-365))
|
||||
|
||||
first_date_of_view = selected_date.replace(
|
||||
day=1) if selected_view == 'month' else selected_date.replace(month=1, day=1)
|
||||
last_date_of_view = first_date_of_view + \
|
||||
(timedelta(365/12) if selected_view == 'month' else timedelta(365))
|
||||
|
||||
start = dict([(6, 0), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)])
|
||||
start_date = first_date_of_view - \
|
||||
timedelta(days=start[first_date_of_view.weekday()])
|
||||
|
||||
end = dict([(6, 6), (0, 5), (1, 4), (2, 3), (3, 2), (4, 1), (5, 0)])
|
||||
end_date = last_date_of_view + \
|
||||
timedelta(days=end[last_date_of_view.weekday()])
|
||||
|
||||
if htmx:
|
||||
return render_template('partials/page/calendar.html',
|
||||
person=person, selected_date=selected_date, selected_view=selected_view, next_date=next_date, previous_date=previous_date)
|
||||
return render_template('calendar.html', person=person, selected_date=selected_date, selected_view=selected_view, next_date=next_date, previous_date=previous_date)
|
||||
person=person, selected_date=selected_date, selected_view=selected_view, next_date=next_date, previous_date=previous_date, start_date=start_date, end_date=end_date)
|
||||
return render_template('calendar.html', person=person, selected_date=selected_date, selected_view=selected_view, next_date=next_date, previous_date=previous_date, start_date=start_date, end_date=end_date)
|
||||
|
||||
|
||||
@ app.route("/person/<int:person_id>/workout", methods=['POST'])
|
||||
@@ -282,7 +299,7 @@ def my_utility_processor():
|
||||
def strftime(date, format="%b %d %Y"):
|
||||
return date.strftime(format)
|
||||
|
||||
return dict(get_list_of_people_and_workout_count=get_list_of_people_and_workout_count, is_selected_page=is_selected_page, get_first_element_from_list_with_matching_attribute=get_first_element_from_list_with_matching_attribute, is_checked=is_checked, strftime=strftime)
|
||||
return dict(get_list_of_people_and_workout_count=get_list_of_people_and_workout_count, is_selected_page=is_selected_page, get_first_element_from_list_with_matching_attribute=get_first_element_from_list_with_matching_attribute, is_checked=is_checked, strftime=strftime, datetime=datetime, timedelta=timedelta)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
|
||||
{{ render_partial('partials/page/calendar.html',
|
||||
person=person, selected_date=selected_date, selected_view=selected_view, next_date=next_date,
|
||||
previous_date=previous_date) }}
|
||||
previous_date=previous_date, start_date=start_date, end_date=end_date) }}
|
||||
|
||||
{% endblock %}
|
||||
@@ -35,6 +35,7 @@
|
||||
hx-vals='{"date": "{{ selected_date }}"}' hx-push-url="true">
|
||||
<option value="month" {% if selected_view=='month' %}selected{% endif %}>Month</option>
|
||||
<option value="year" {% if selected_view=='year' %}selected{% endif %}>Year</option>
|
||||
<option value="all">All</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -74,301 +75,32 @@
|
||||
|
||||
<div class="grid grid-cols-7 overflow-hidden flex-1 pl-2 pr-2 w-full">
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
{% for i in range((end_date-start_date).days + 1) %}
|
||||
{% set date = start_date + timedelta(days=i) %}
|
||||
{% set workout =
|
||||
get_first_element_from_list_with_matching_attribute(person['Workouts'],
|
||||
'StartDate',
|
||||
date) %}
|
||||
<div class="{% if date == datetime.today().date() %}rounded-md border-4 border-green-50{% endif %} border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer {% if selected_date.month != date.month %}bg-gray-100{% endif %}"
|
||||
{% if workout %}
|
||||
hx-get="{{ url_for('get_workout' ,person_id=person['PersonId'], workout_id=workout['WorkoutId']) }}"
|
||||
hx-target="#container" hx-push-url="true" {% endif %}>
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">1</span>
|
||||
<span class="text-gray-500 font-semibold">{{ date.day }}</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full">
|
||||
{% if workout %}
|
||||
{% for topset in workout['TopSets'] %}
|
||||
<button class="flex items-center flex-shrink-0 h-5 px-1 text-xs">
|
||||
<span class="ml-2 font-medium leading-none truncate">Squat</span>
|
||||
<span class="ml-2 font-light leading-none">5x50kg</span>
|
||||
</button>
|
||||
<button class="flex items-center flex-shrink-0 h-5 px-1 text-xs">
|
||||
<span class="ml-2 font-medium leading-none truncate">DB Seal row</span>
|
||||
<span class="ml-2 font-light leading-none">12x20kg</span>
|
||||
<span class="ml-2 font-medium leading-none truncate">{{ topset['ExerciseName'] }}</span>
|
||||
<span class="ml-2 font-light leading-none">{{ topset['Repetitions'] }} x {{ topset['Weight']
|
||||
}}kg</span>
|
||||
</button>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">2</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full">
|
||||
<button class="flex items-center flex-shrink-0 h-5 px-1 text-xs">
|
||||
<span class="ml-2 font-medium leading-none truncate">Squat</span>
|
||||
<span class="ml-2 font-light leading-none">5x50kg</span>
|
||||
</button>
|
||||
<button class="flex items-center flex-shrink-0 h-5 px-1 text-xs">
|
||||
<span class="ml-2 font-medium leading-none truncate">DB Seal row</span>
|
||||
<span class="ml-2 font-light leading-none">12x20kg</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">3</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">4</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">6</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">7</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full">
|
||||
<button class="flex items-center flex-shrink-0 h-5 px-1 text-xs">
|
||||
<span class="ml-2 font-medium leading-none truncate">Squat</span>
|
||||
<span class="ml-2 font-light leading-none">5x50kg</span>
|
||||
</button>
|
||||
<button class="flex items-center flex-shrink-0 h-5 px-1 text-xs">
|
||||
<span class="ml-2 font-medium leading-none truncate">DB Seal row</span>
|
||||
<span class="ml-2 font-light leading-none">12x20kg</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold text-sm">8</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">9</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">10</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">12</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full">
|
||||
<button class="flex items-center flex-shrink-0 h-5 px-1 text-xs">
|
||||
<span class="ml-2 font-medium leading-none truncate">Squat</span>
|
||||
<span class="ml-2 font-light leading-none">5x50kg</span>
|
||||
</button>
|
||||
<button class="flex items-center flex-shrink-0 h-5 px-1 text-xs">
|
||||
<span class="ml-2 font-medium leading-none truncate">DB Seal row</span>
|
||||
<span class="ml-2 font-light leading-none">12x20kg</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">13</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="rounded-md border-4 border-green-50 border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">14</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">15</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold text-sm">16</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">16</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full">
|
||||
<button class="flex items-center flex-shrink-0 h-5 px-1 text-xs">
|
||||
<span class="ml-2 font-medium leading-none truncate">Squat</span>
|
||||
<span class="ml-2 font-light leading-none">5x50kg</span>
|
||||
</button>
|
||||
<button class="flex items-center flex-shrink-0 h-5 px-1 text-xs">
|
||||
<span class="ml-2 font-medium leading-none truncate">DB Seal row</span>
|
||||
<span class="ml-2 font-light leading-none">12x20kg</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">17</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">18</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">19</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">20</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">21</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold text-sm">22</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">23</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">24</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">25</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">26</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">27</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">28</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold text-sm">29</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">30</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">31</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer bg-gray-100 pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">1</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer bg-gray-100 pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">2</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer bg-gray-100 pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">3</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer bg-gray-100 pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold">4</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="border flex flex-col h-40 mx-auto mx-auto overflow-hidden w-full pt-2 pl-2 cursor-pointer bg-gray-100 pt-2 pl-2 cursor-pointer">
|
||||
<div class="top h-5 w-full">
|
||||
<span class="text-gray-500 font-semibold text-sm">5</span>
|
||||
</div>
|
||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% for p in people %}
|
||||
<li>
|
||||
<a hx-get="{{ url_for('get_person' ,person_id=p['PersonId']) }}" hx-push-url="true" hx-target="#container" class="text-base text-gray-900 font-normal rounded-lg hover:bg-gray-100 flex items-center p-2 group cursor-pointer {% if
|
||||
<a hx-get="{{ url_for('get_calendar' ,person_id=p['PersonId']) }}" hx-push-url="true" hx-target="#container" class="text-base text-gray-900 font-normal rounded-lg hover:bg-gray-100 flex items-center p-2 group cursor-pointer {% if
|
||||
p['IsActive']==1 %} bg-gray-200 {% endif %}">
|
||||
<svg class="w-6 h-6 text-gray-500 flex-shrink-0 group-hover:text-gray-900 transition duration-75"
|
||||
fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
Reference in New Issue
Block a user