From 94c598f00b1c2747419d87d3fa3cf7d6dbb0bf49 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Sat, 19 Apr 2025 00:45:15 +0200 Subject: use proper templates for profile tabs I wasn't very happy with the wonkiness that the previous tabs were, especially with the calendar having different URLs *sometimes*. I'm planning to use the same strategy for the admin site soon, so it makes sense to implement it here. --- fietsboek/routes.py | 12 +- fietsboek/templates/layout.jinja2 | 2 +- fietsboek/templates/profile.jinja2 | 255 +--------------------------- fietsboek/templates/profile_calendar.jinja2 | 44 +++++ fietsboek/templates/profile_graphs.jinja2 | 16 ++ fietsboek/templates/profile_overview.jinja2 | 188 ++++++++++++++++++++ fietsboek/views/profile.py | 70 ++++++-- 7 files changed, 324 insertions(+), 263 deletions(-) create mode 100644 fietsboek/templates/profile_calendar.jinja2 create mode 100644 fietsboek/templates/profile_graphs.jinja2 create mode 100644 fietsboek/templates/profile_overview.jinja2 diff --git a/fietsboek/routes.py b/fietsboek/routes.py index 07e73cf..d5caef8 100644 --- a/fietsboek/routes.py +++ b/fietsboek/routes.py @@ -63,9 +63,17 @@ def includeme(config): config.add_route("toggle-favourite", "/me/toggle-favourite") config.add_route("force-logout", "/me/force-logout") - config.add_route("profile", "/user/{user_id}", factory="fietsboek.models.User.factory") config.add_route( - "user-calendar-ym", + "profile-overview", "/user/{user_id}/", factory="fietsboek.models.User.factory" + ) + config.add_route( + "profile-graphs", "/user/{user_id}/graphs", factory="fietsboek.models.User.factory" + ) + config.add_route( + "profile-calendar", "/user/{user_id}/calendar/", factory="fietsboek.models.User.factory" + ) + config.add_route( + "profile-calendar-ym", "/user/{user_id}/calendar/{year}/{month}", factory="fietsboek.models.User.factory", ) diff --git a/fietsboek/templates/layout.jinja2 b/fietsboek/templates/layout.jinja2 index b61c359..c96716d 100644 --- a/fietsboek/templates/layout.jinja2 +++ b/fietsboek/templates/layout.jinja2 @@ -77,7 +77,7 @@ const Legende = false; {{ _("page.navbar.logout") }}
  • - {{ _("page.navbar.profile") }} + {{ _("page.navbar.profile") }}
  • {{ _("page.navbar.user_data") }} diff --git a/fietsboek/templates/profile.jinja2 b/fietsboek/templates/profile.jinja2 index 9b56f04..06386ac 100644 --- a/fietsboek/templates/profile.jinja2 +++ b/fietsboek/templates/profile.jinja2 @@ -1,269 +1,30 @@ {% extends "layout.jinja2" %} -{% macro render_track_card(track) %} -
    -
    - {{ track.title | default(track.date, true) }} - {% if track.text_tags() %} - {% for tag in track.tags %}{{ tag.tag }} {% endfor %} - {% endif %} -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{ _("page.details.date") }}{{ track.date | format_datetime }}{{ _("page.details.length") }}{{ (track.length / 1000) | round(2) | format_decimal }} km
    {{ _("page.details.start_time") }}{{ track.start_time | format_datetime }}{{ _("page.details.end_time") }}{{ track.end_time | format_datetime }}
    {{ _("page.details.uphill") }}{{ track.uphill | round(2) | format_decimal }} m{{ _("page.details.downhill") }}{{ track.downhill | round(2) | format_decimal }} m
    {{ _("page.details.moving_time") }}{{ track.moving_time }}{{ _("page.details.stopped_time") }}{{ track.stopped_time }}
    {{ _("page.details.max_speed") }}{{ mps_to_kph(track.max_speed) | round(2) | format_decimal }} km/h{{ _("page.details.avg_speed") }}{{ mps_to_kph(track.avg_speed) | round(2) | format_decimal }} km/h
    - -
      -
    • {{ track.owner.name }}
    • - {% for user in track.tagged_people %} -
    • {{ user.name }}
    • - {% endfor %} -
    -
    -
    -{% endmacro %} - {% block content %}

    {{ user.name }}

    - -
    - {% if heatmap_url or tilehunt_url %} -
    - {% endif %} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{ _("page.profile.length") }}{{ (total.length / 1000) | round(2) | format_decimal }} km
    {{ _("page.profile.avg_length") }}{{ (total.avg_length / 1000) | round(2) | format_decimal }} km
    {{ _("page.profile.uphill") }}{{ total.uphill | round(2) | format_decimal }} m
    {{ _("page.profile.downhill") }}{{ total.downhill | round(2) | format_decimal }} m
    {{ _("page.profile.moving_time") }}{{ total.moving_time }}
    {{ _("page.profile.stopped_time") }}{{ total.stopped_time }}
    {{ _("page.profile.avg_duration") }}{{ total.avg_duration }}
    {{ _("page.profile.max_speed") }}{{ mps_to_kph(total.max_speed) | round(2) | format_decimal }} km/h
    {{ _("page.profile.avg_speed") }}{{ mps_to_kph(total.avg_speed) | round(2) | format_decimal }} km/h
    {{ _("page.profile.number_of_tracks") }}{{ total.count }}
    - - {% if total.longest_distance_track %} -

    {{ _("page.profile.longest_distance_track") }}

    - {{ render_track_card(total.longest_distance_track) }} - {% endif %} - - {% if total.shortest_distance_track %} -

    {{ _("page.profile.shortest_distance_track") }}

    - {{ render_track_card(total.shortest_distance_track) }} - {% endif %} - - {% if total.longest_duration_track %} -

    {{ _("page.profile.longest_duration_track") }}

    - {{ render_track_card(total.longest_duration_track) }} - {% endif %} - - {% if total.shortest_duration_track %} -

    {{ _("page.profile.shortest_duration_track") }}

    - {{ render_track_card(total.shortest_duration_track) }} - {% endif %} -
    - - -
    -

    {{ _("page.profile.graph.km_per_month") }}

    -
    -
    - - -
    -

    {{ calendar_month | format_date("MMMM YYYY") }}

    - - - - - - - {% for day in range(7) %} - - {% endfor %} - - - {% for row in calendar_rows %} - - {% for cell in row %} - {% if cell %} - {% set day, style, tracks = cell %} - - {% else %} - - {% endif %} - {% endfor %} - - {% endfor %} -
    {{ day_name(request, day) }}
    -

    {{ day.day }}

    - {% if tracks %} - - {% endif %} -
    -
    + {% block profile_content %} + {% endblock %}
    -
    {% endblock %} - -{% block latescripts %} - -{% endblock %} diff --git a/fietsboek/templates/profile_calendar.jinja2 b/fietsboek/templates/profile_calendar.jinja2 new file mode 100644 index 0000000..03a82db --- /dev/null +++ b/fietsboek/templates/profile_calendar.jinja2 @@ -0,0 +1,44 @@ +{% set profile_index = 2 %} +{% extends "profile.jinja2" %} + +{% block profile_content %} + +

    {{ calendar_month | format_date("MMMM YYYY") }}

    + + + + + + + {% for day in range(7) %} + + {% endfor %} + + + {% for row in calendar_rows %} + + {% for cell in row %} + {% if cell %} + {% set day, style, tracks = cell %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} +
    {{ day_name(request, day) }}
    +

    {{ day.day }}

    + {% if tracks %} + + {% endif %} +
    +{% endblock %} diff --git a/fietsboek/templates/profile_graphs.jinja2 b/fietsboek/templates/profile_graphs.jinja2 new file mode 100644 index 0000000..4a9e474 --- /dev/null +++ b/fietsboek/templates/profile_graphs.jinja2 @@ -0,0 +1,16 @@ +{% set profile_index = 1 %} +{% extends "profile.jinja2" %} + +{% block profile_content %} + +

    {{ _("page.profile.graph.km_per_month") }}

    +
    +{% endblock %} + +{% block latescripts %} + +{% endblock %} diff --git a/fietsboek/templates/profile_overview.jinja2 b/fietsboek/templates/profile_overview.jinja2 new file mode 100644 index 0000000..aa2333c --- /dev/null +++ b/fietsboek/templates/profile_overview.jinja2 @@ -0,0 +1,188 @@ +{% set profile_index = 0 %} +{% extends "profile.jinja2" %} + +{% macro render_track_card(track) %} +
    +
    + {{ track.title | default(track.date, true) }} + {% if track.text_tags() %} + {% for tag in track.tags %}{{ tag.tag }} {% endfor %} + {% endif %} +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {{ _("page.details.date") }}{{ track.date | format_datetime }}{{ _("page.details.length") }}{{ (track.length / 1000) | round(2) | format_decimal }} km
    {{ _("page.details.start_time") }}{{ track.start_time | format_datetime }}{{ _("page.details.end_time") }}{{ track.end_time | format_datetime }}
    {{ _("page.details.uphill") }}{{ track.uphill | round(2) | format_decimal }} m{{ _("page.details.downhill") }}{{ track.downhill | round(2) | format_decimal }} m
    {{ _("page.details.moving_time") }}{{ track.moving_time }}{{ _("page.details.stopped_time") }}{{ track.stopped_time }}
    {{ _("page.details.max_speed") }}{{ mps_to_kph(track.max_speed) | round(2) | format_decimal }} km/h{{ _("page.details.avg_speed") }}{{ mps_to_kph(track.avg_speed) | round(2) | format_decimal }} km/h
    + +
      +
    • {{ track.owner.name }}
    • + {% for user in track.tagged_people %} +
    • {{ user.name }}
    • + {% endfor %} +
    +
    +
    +{% endmacro %} + +{% block profile_content %} + +{% if heatmap_url or tilehunt_url %} +
    +{% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {{ _("page.profile.length") }}{{ (total.length / 1000) | round(2) | format_decimal }} km
    {{ _("page.profile.avg_length") }}{{ (total.avg_length / 1000) | round(2) | format_decimal }} km
    {{ _("page.profile.uphill") }}{{ total.uphill | round(2) | format_decimal }} m
    {{ _("page.profile.downhill") }}{{ total.downhill | round(2) | format_decimal }} m
    {{ _("page.profile.moving_time") }}{{ total.moving_time }}
    {{ _("page.profile.stopped_time") }}{{ total.stopped_time }}
    {{ _("page.profile.avg_duration") }}{{ total.avg_duration }}
    {{ _("page.profile.max_speed") }}{{ mps_to_kph(total.max_speed) | round(2) | format_decimal }} km/h
    {{ _("page.profile.avg_speed") }}{{ mps_to_kph(total.avg_speed) | round(2) | format_decimal }} km/h
    {{ _("page.profile.number_of_tracks") }}{{ total.count }}
    + +{% if total.longest_distance_track %} +

    {{ _("page.profile.longest_distance_track") }}

    +{{ render_track_card(total.longest_distance_track) }} +{% endif %} + +{% if total.shortest_distance_track %} +

    {{ _("page.profile.shortest_distance_track") }}

    +{{ render_track_card(total.shortest_distance_track) }} +{% endif %} + +{% if total.longest_duration_track %} +

    {{ _("page.profile.longest_duration_track") }}

    +{{ render_track_card(total.longest_duration_track) }} +{% endif %} + +{% if total.shortest_duration_track %} +

    {{ _("page.profile.shortest_duration_track") }}

    +{{ render_track_card(total.shortest_duration_track) }} +{% endif %} +{% endblock %} + +{% block latescripts %} + +{% endblock %} diff --git a/fietsboek/views/profile.py b/fietsboek/views/profile.py index bf604b5..15bc46c 100644 --- a/fietsboek/views/profile.py +++ b/fietsboek/views/profile.py @@ -83,46 +83,82 @@ def profile_data(request: Request) -> dict: @view_config( - route_name="profile", - renderer="fietsboek:templates/profile.jinja2", + route_name="profile-overview", + renderer="fietsboek:templates/profile_overview.jinja2", request_method="GET", permission="profile.view", ) -def profile(request: Request) -> dict: +def profile_overview(request: Request) -> dict: """Shows the profile page. :param request: The pyramid request. :return: The template parameters. """ data = profile_data(request) - today = datetime.date.today() + return data + + +@view_config( + route_name="profile-graphs", + renderer="fietsboek:templates/profile_graphs.jinja2", + request_method="GET", + permission="profile.view", +) +def profile_graphs(request: Request) -> dict: + """Shows the user's graphs. + + :param request: The pyramid request. + :return: The template parameters. + """ + return { + "user": request.context, + } + + +@view_config( + route_name="profile-calendar", + renderer="fietsboek:templates/profile_calendar.jinja2", + request_method="GET", + permission="profile.view", +) +def profile_calendar(request: Request) -> dict: + """Shows the user's calendar for the current month. + + :param request: The pyramid request. + :return: The template parameters. + """ + date = datetime.date.today() + data = {} + data["user"] = request.context data["calendar_rows"] = calendar_rows( request.dbsession, request.data_manager, request.context, - today.year, - today.month, + date.year, + date.month, ) - data["calendar_month"] = today - data["calendar_prev"], data["calendar_next"] = prev_next_month(today) + data["calendar_month"] = date + data["calendar_prev"], data["calendar_next"] = prev_next_month(date) + data["tab_focus"] = "calendar" data["day_name"] = util.day_name return data @view_config( - route_name="user-calendar-ym", - renderer="fietsboek:templates/profile.jinja2", + route_name="profile-calendar-ym", + renderer="fietsboek:templates/profile_calendar.jinja2", request_method="GET", permission="profile.view", ) -def user_calendar_ym(request: Request) -> dict: +def profile_calendar_ym(request: Request) -> dict: """Shows the user's calendar. :param request: The pyramid request. :return: The template parameters. """ - data = profile_data(request) date = datetime.date(int(request.matchdict["year"]), int(request.matchdict["month"]), 1) + data = {} + data["user"] = request.context data["calendar_rows"] = calendar_rows( request.dbsession, request.data_manager, @@ -309,4 +345,12 @@ def json_summary(request: Request) -> Response: return {y.year: {m.month: m.total_length for m in y} for y in summary} -__all__ = ["EMPTY_TILE", "profile", "user_tile", "user_calendar_ym", "json_summary"] +__all__ = [ + "EMPTY_TILE", + "profile_overview", + "profile_graphs", + "profile_calendar", + "profile_calendar_ym", + "user_tile", + "json_summary", +] -- cgit v1.2.3