diff options
author | Daniel Schadt <kingdread@gmx.de> | 2025-04-19 00:45:15 +0200 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2025-04-19 00:45:15 +0200 |
commit | 94c598f00b1c2747419d87d3fa3cf7d6dbb0bf49 (patch) | |
tree | 0519e3d1fdb1ad86afb4676fce46fb68d87fc66b | |
parent | f715a0543460fb5c1cbd40b54c60db3857887220 (diff) | |
download | fietsboek-94c598f00b1c2747419d87d3fa3cf7d6dbb0bf49.tar.gz fietsboek-94c598f00b1c2747419d87d3fa3cf7d6dbb0bf49.tar.bz2 fietsboek-94c598f00b1c2747419d87d3fa3cf7d6dbb0bf49.zip |
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.
-rw-r--r-- | fietsboek/routes.py | 12 | ||||
-rw-r--r-- | fietsboek/templates/layout.jinja2 | 2 | ||||
-rw-r--r-- | fietsboek/templates/profile.jinja2 | 255 | ||||
-rw-r--r-- | fietsboek/templates/profile_calendar.jinja2 | 44 | ||||
-rw-r--r-- | fietsboek/templates/profile_graphs.jinja2 | 16 | ||||
-rw-r--r-- | fietsboek/templates/profile_overview.jinja2 | 188 | ||||
-rw-r--r-- | fietsboek/views/profile.py | 70 |
7 files changed, 324 insertions, 263 deletions
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; <a class="dropdown-item" href="{{ request.route_url('logout') }}">{{ _("page.navbar.logout") }}</a> </li> <li> - <a class="dropdown-item" href="{{ request.route_url('profile', user_id=request.identity.id) }}">{{ _("page.navbar.profile") }}</a> + <a class="dropdown-item" href="{{ request.route_url('profile-overview', user_id=request.identity.id) }}">{{ _("page.navbar.profile") }}</a> </li> <li> <a class="dropdown-item" href="{{ request.route_url('user-data') }}">{{ _("page.navbar.user_data") }}</a> 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) %} - <div class="card mb-3"> - <h5 class="card-header"> - <a href="{{ request.route_url('details', track_id=track.id) }}">{{ track.title | default(track.date, true) }}</a> - {% if track.text_tags() %} - {% for tag in track.tags %}<span class="badge bg-info text-dark">{{ tag.tag }}</span> {% endfor %} - {% endif %} - </h5> - <div class="card-body"> - <table class="table table-hover table-sm browse-summary"> - <tbody> - <tr> - <th scope="row">{{ _("page.details.date") }}</th> - <td>{{ track.date | format_datetime }}</td> - <th scope="row">{{ _("page.details.length") }}</th> - <td>{{ (track.length / 1000) | round(2) | format_decimal }} km</td> - </tr> - <tr> - <th scope="row">{{ _("page.details.start_time") }}</th> - <td>{{ track.start_time | format_datetime }}</td> - <th scope="row">{{ _("page.details.end_time") }}</th> - <td>{{ track.end_time | format_datetime }}</td> - </tr> - <tr> - <th scope="row">{{ _("page.details.uphill") }}</th> - <td>{{ track.uphill | round(2) | format_decimal }} m</td> - <th scope="row">{{ _("page.details.downhill") }}</th> - <td>{{ track.downhill | round(2) | format_decimal }} m</td> - </tr> - <tr> - <th scope="row">{{ _("page.details.moving_time") }}</th> - <td>{{ track.moving_time }}</td> - <th scope="row">{{ _("page.details.stopped_time") }}</th> - <td>{{ track.stopped_time }}</td> - </tr> - <tr> - <th scope="row">{{ _("page.details.max_speed") }}</th> - <td>{{ mps_to_kph(track.max_speed) | round(2) | format_decimal }} km/h</td> - <th scope="row">{{ _("page.details.avg_speed") }}</th> - <td>{{ mps_to_kph(track.avg_speed) | round(2) | format_decimal }} km/h</td> - </tr> - </tbody> - </table> - - <ul> - <li>{{ track.owner.name }}</li> - {% for user in track.tagged_people %} - <li>{{ user.name }}</li> - {% endfor %} - </ul> - </div> - </div> -{% endmacro %} - {% block content %} <div class="container"> <h1>{{ user.name }}</h1> <ul class="nav nav-tabs" id="profileTabbar" role="tablist"> <li class="nav-item" role="presentation"> - <button class="nav-link {% if not tab_focus or tab_focus == 'overview' %}active{% endif %}" id="tabOverviewButton" data-bs-toggle="tab" data-bs-target="#tabOverviewPane" type="button" role="tab" aria-controls="tabOverviewPane" aria-selected="{% if not tab_focus or tab_focus == 'overview' %}true{% else %}false{% endif %}"> + <a class="nav-link {% if profile_index == 0 %}active{% endif %}" aria-selected="{% if profile_index == 0 %}true{% else %}false{% endif %}" href="{{ request.route_url('profile-overview', user_id=user.id) }}"> {{ _("page.profile.tabbar.overview") }} - </button> + </a> </li> <li class="nav-item" role="presentation"> - <button class="nav-link {% if tab_focus == 'graph' %}active{% endif %}" id="tabGraphsButton" data-bs-toggle="tab" data-bs-target="#tabGraphsPane" type="button" role="tab" aria-controls="tabGraphsPane" aria-selected="{% if tab_focus == 'graph' %}true{% else %}false{% endif %}"> + <a class="nav-link {% if profile_index == 1 %}active{% endif %}" aria-selected="{% if profile_index == 1 %}true{% else %}false{% endif %}" href="{{ request.route_url('profile-graphs', user_id=user.id) }}"> {{ _("page.profile.tabbar.graphs") }} - </button> + </a> </li> <li class="nav-item" role="presentation"> - <button class="nav-link {% if tab_focus == 'calendar' %}active{% endif %}" id="tabCalendarButton" data-bs-toggle="tab" data-bs-target="#tabCalendarPane" type="button" role="tab" aria-controls="tabCalendarPane" aria-selected="{% if tab_focus == 'calendar' %}true{% else %}false{% endif %}"> + <a class="nav-link {% if profile_index == 2 %}active{% endif %}" aria-selected="{% if profile_index == 2 %}true{% else %}false{% endif %}" href="{{ request.route_url('profile-calendar', user_id=user.id) }}"> {{ _("page.profile.tabbar.calendar") }} - </button> + </a> </li> </ul> <div class="tab-content"> - <!-- First tab --> - <div class="tab-pane {% if not tab_focus or tab_focus == 'overview' %}show active{% endif %}" id="tabOverviewPane" role="tabpanel" aria-labelledby="tabOverviewButton"> - {% if heatmap_url or tilehunt_url %} - <div id="userMap" style="height: 600px; width: 100%;"></div> - {% endif %} - - <table class="table table-hover table-sm"> - <tr> - <th scope="row">{{ _("page.profile.length") }}</th> - <td id="profileLength">{{ (total.length / 1000) | round(2) | format_decimal }} km</td> - </tr> - <tr> - <th scope="row">{{ _("page.profile.avg_length") }}</th> - <td id="profileAvgLength">{{ (total.avg_length / 1000) | round(2) | format_decimal }} km</td> - </tr> - <tr> - <th scope="row">{{ _("page.profile.uphill") }}</th> - <td id="profileUphill">{{ total.uphill | round(2) | format_decimal }} m</td> - </tr> - <tr> - <th scope="row">{{ _("page.profile.downhill") }}</th> - <td id="profileDownhill">{{ total.downhill | round(2) | format_decimal }} m</td> - </tr> - <tr> - <th scope="row">{{ _("page.profile.moving_time") }}</th> - <td id="profileMovingTime">{{ total.moving_time }}</td> - </tr> - <tr> - <th scope="row">{{ _("page.profile.stopped_time") }}</th> - <td id="profileStoppedTime">{{ total.stopped_time }}</td> - </tr> - <tr> - <th scope="row">{{ _("page.profile.avg_duration") }}</th> - <td id="profileAvgDuration">{{ total.avg_duration }}</td> - </tr> - <tr> - <th scope="row">{{ _("page.profile.max_speed") }}</th> - <td id="profileMaxSpeed">{{ mps_to_kph(total.max_speed) | round(2) | format_decimal }} km/h</td> - </tr> - <tr> - <th scope="row">{{ _("page.profile.avg_speed") }}</th> - <td id="profileAvgSpeed">{{ mps_to_kph(total.avg_speed) | round(2) | format_decimal }} km/h</td> - </tr> - <tr> - <th scope="row">{{ _("page.profile.number_of_tracks") }}</th> - <td id="profileNumberOfTracks">{{ total.count }}</td> - </tr> - </table> - - {% if total.longest_distance_track %} - <h2>{{ _("page.profile.longest_distance_track") }}</h2> - {{ render_track_card(total.longest_distance_track) }} - {% endif %} - - {% if total.shortest_distance_track %} - <h2>{{ _("page.profile.shortest_distance_track") }}</h2> - {{ render_track_card(total.shortest_distance_track) }} - {% endif %} - - {% if total.longest_duration_track %} - <h2>{{ _("page.profile.longest_duration_track") }}</h2> - {{ render_track_card(total.longest_duration_track) }} - {% endif %} - - {% if total.shortest_duration_track %} - <h2>{{ _("page.profile.shortest_duration_track") }}</h2> - {{ render_track_card(total.shortest_duration_track) }} - {% endif %} - </div> - - <!-- Second tab --> - <div class="tab-pane {% if tab_focus == 'graph' %}show active{% endif %}" id="tabGraphsPane" role="tabpanel" aria-labelledby="tabGraphsButton"> - <h2 class="chart-title">{{ _("page.profile.graph.km_per_month") }}</h2> - <div style="position: relative; height: 500px; width: 75%; margin: auto;"><canvas id="graph-month-summary"></canvas></div> - </div> - - <!-- Third tab --> - <div class="tab-pane {% if tab_focus == 'calendar' %}show active{% endif %}" id="tabCalendarPane" role="tabpanel" aria-labelledby="tabCalendarButton"> - <h2 class="calendar-title">{{ calendar_month | format_date("MMMM YYYY") }}</h2> - - <div class="calendar-controls"> - <a href="{{ request.route_url('user-calendar-ym', user_id=user.id, year=calendar_prev.year, month=calendar_prev.month) }}">{{ _("page.profile.calendar.previous") }}</a> - | - <a href="{{ request.route_url('user-calendar-ym', user_id=user.id, year=calendar_next.year, month=calendar_next.month) }}">{{ _("page.profile.calendar.next") }}</a> - </div> - - <table class="profile-calendar"> - <thead> - <tr> - {% for day in range(7) %} - <td>{{ day_name(request, day) }}</td> - {% endfor %} - </tr> - </thead> - {% for row in calendar_rows %} - <tr> - {% for cell in row %} - {% if cell %} - {% set day, style, tracks = cell %} - <td class="calendar-cell {{ style }}"> - <p class="calendar-date">{{ day.day }}</p> - {% if tracks %} - <ul> - {% for track in tracks %} - <li><a href="{{ request.route_url('details', track_id=track.id) }}" title="{{ track.title }}">{{ (track.length / 1000) | round(2) | format_decimal }} km</a></li> - {% endfor %} - </ul> - {% endif %} - </td> - {% else %} - <td class="calendar-cell-empty"></td> - {% endif %} - {% endfor %} - </tr> - {% endfor %} - </table> - </div> + {% block profile_content %} + {% endblock %} </div> - </div> {% endblock %} - -{% block latescripts %} -<script> - (function() { - loadProfileStats(); - - const renderMap = document.getElementById("userMap") !== null; - if (!renderMap) { - return; - } - - const map = L.map("userMap").setView([52.520008, 13.404954], 2); - - baseLayers = {}; - overlayLayers = {}; - - let defaultOverlayLayer = null; - let layer = null; - {% if heatmap_url %} - layer = overlayLayers[{{ _("page.profile.heatmap") | tojson }}] = L.tileLayer({{ heatmap_url | tojson }}, { - maxZoom: 19, - }); - if (defaultOverlayLayer === null) { - defaultOverlayLayer = layer; - } - {% endif %} - {% if tilehunt_url %} - layer = overlayLayers[{{ _("page.profile.tilehunt") | tojson }}] = L.tileLayer({{ tilehunt_url | tojson }}, { - maxZoom: 19, - }); - if (defaultOverlayLayer === null) { - defaultOverlayLayer = layer; - } - {% endif %} - - let defaultLayer = null; - - for (let layer of TILE_LAYERS) { - if (layer.type === "base") { - baseLayers[layer.name] = L.tileLayer(layer.url, { - maxZoom: layer.zoom, - attribution: layer.attribution, - }); - if (defaultLayer === null) { - defaultLayer = baseLayers[layer.name]; - } - } else if (layer.type === "overlay") { - overlayLayers[layer.name] = L.tileLayer(layer.url, { - attribution: layer.attribution, - }); - } - } - - - // Add the default layer via .addTo directly, otherwise it will not be - // selected at the start. - defaultLayer.addTo(map); - if (defaultOverlayLayer != null) { - defaultOverlayLayer.addTo(map); - } - L.control.layers(baseLayers, overlayLayers).addTo(map); - - // Fix leaflet being all weird if it's loaded on a hidden tab - document.querySelector("#tabOverviewButton").addEventListener("shown.bs.tab", event => { - map.invalidateSize(); - }); - })(); -</script> -{% 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 %} +<!-- Third tab --> +<h2 class="calendar-title">{{ calendar_month | format_date("MMMM YYYY") }}</h2> + +<div class="calendar-controls"> + <a href="{{ request.route_url('profile-calendar-ym', user_id=user.id, year=calendar_prev.year, month=calendar_prev.month) }}">{{ _("page.profile.calendar.previous") }}</a> + | + <a href="{{ request.route_url('profile-calendar-ym', user_id=user.id, year=calendar_next.year, month=calendar_next.month) }}">{{ _("page.profile.calendar.next") }}</a> +</div> + +<table class="profile-calendar"> + <thead> + <tr> + {% for day in range(7) %} + <td>{{ day_name(request, day) }}</td> + {% endfor %} + </tr> + </thead> + {% for row in calendar_rows %} + <tr> + {% for cell in row %} + {% if cell %} + {% set day, style, tracks = cell %} + <td class="calendar-cell {{ style }}"> + <p class="calendar-date">{{ day.day }}</p> + {% if tracks %} + <ul> + {% for track in tracks %} + <li><a href="{{ request.route_url('details', track_id=track.id) }}" title="{{ track.title }}">{{ (track.length / 1000) | round(2) | format_decimal }} km</a></li> + {% endfor %} + </ul> + {% endif %} + </td> + {% else %} + <td class="calendar-cell-empty"></td> + {% endif %} + {% endfor %} + </tr> + {% endfor %} +</table> +{% 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 %} +<!-- Second tab --> +<h2 class="chart-title">{{ _("page.profile.graph.km_per_month") }}</h2> +<div style="position: relative; height: 500px; width: 75%; margin: auto;"><canvas id="graph-month-summary"></canvas></div> +{% endblock %} + +{% block latescripts %} +<script> + (function() { + loadProfileStats(); + })(); +</script> +{% 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) %} + <div class="card mb-3"> + <h5 class="card-header"> + <a href="{{ request.route_url('details', track_id=track.id) }}">{{ track.title | default(track.date, true) }}</a> + {% if track.text_tags() %} + {% for tag in track.tags %}<span class="badge bg-info text-dark">{{ tag.tag }}</span> {% endfor %} + {% endif %} + </h5> + <div class="card-body"> + <table class="table table-hover table-sm browse-summary"> + <tbody> + <tr> + <th scope="row">{{ _("page.details.date") }}</th> + <td>{{ track.date | format_datetime }}</td> + <th scope="row">{{ _("page.details.length") }}</th> + <td>{{ (track.length / 1000) | round(2) | format_decimal }} km</td> + </tr> + <tr> + <th scope="row">{{ _("page.details.start_time") }}</th> + <td>{{ track.start_time | format_datetime }}</td> + <th scope="row">{{ _("page.details.end_time") }}</th> + <td>{{ track.end_time | format_datetime }}</td> + </tr> + <tr> + <th scope="row">{{ _("page.details.uphill") }}</th> + <td>{{ track.uphill | round(2) | format_decimal }} m</td> + <th scope="row">{{ _("page.details.downhill") }}</th> + <td>{{ track.downhill | round(2) | format_decimal }} m</td> + </tr> + <tr> + <th scope="row">{{ _("page.details.moving_time") }}</th> + <td>{{ track.moving_time }}</td> + <th scope="row">{{ _("page.details.stopped_time") }}</th> + <td>{{ track.stopped_time }}</td> + </tr> + <tr> + <th scope="row">{{ _("page.details.max_speed") }}</th> + <td>{{ mps_to_kph(track.max_speed) | round(2) | format_decimal }} km/h</td> + <th scope="row">{{ _("page.details.avg_speed") }}</th> + <td>{{ mps_to_kph(track.avg_speed) | round(2) | format_decimal }} km/h</td> + </tr> + </tbody> + </table> + + <ul> + <li>{{ track.owner.name }}</li> + {% for user in track.tagged_people %} + <li>{{ user.name }}</li> + {% endfor %} + </ul> + </div> + </div> +{% endmacro %} + +{% block profile_content %} +<!-- First tab --> +{% if heatmap_url or tilehunt_url %} +<div id="userMap" style="height: 600px; width: 100%;"></div> +{% endif %} + +<table class="table table-hover table-sm"> + <tr> + <th scope="row">{{ _("page.profile.length") }}</th> + <td id="profileLength">{{ (total.length / 1000) | round(2) | format_decimal }} km</td> + </tr> + <tr> + <th scope="row">{{ _("page.profile.avg_length") }}</th> + <td id="profileAvgLength">{{ (total.avg_length / 1000) | round(2) | format_decimal }} km</td> + </tr> + <tr> + <th scope="row">{{ _("page.profile.uphill") }}</th> + <td id="profileUphill">{{ total.uphill | round(2) | format_decimal }} m</td> + </tr> + <tr> + <th scope="row">{{ _("page.profile.downhill") }}</th> + <td id="profileDownhill">{{ total.downhill | round(2) | format_decimal }} m</td> + </tr> + <tr> + <th scope="row">{{ _("page.profile.moving_time") }}</th> + <td id="profileMovingTime">{{ total.moving_time }}</td> + </tr> + <tr> + <th scope="row">{{ _("page.profile.stopped_time") }}</th> + <td id="profileStoppedTime">{{ total.stopped_time }}</td> + </tr> + <tr> + <th scope="row">{{ _("page.profile.avg_duration") }}</th> + <td id="profileAvgDuration">{{ total.avg_duration }}</td> + </tr> + <tr> + <th scope="row">{{ _("page.profile.max_speed") }}</th> + <td id="profileMaxSpeed">{{ mps_to_kph(total.max_speed) | round(2) | format_decimal }} km/h</td> + </tr> + <tr> + <th scope="row">{{ _("page.profile.avg_speed") }}</th> + <td id="profileAvgSpeed">{{ mps_to_kph(total.avg_speed) | round(2) | format_decimal }} km/h</td> + </tr> + <tr> + <th scope="row">{{ _("page.profile.number_of_tracks") }}</th> + <td id="profileNumberOfTracks">{{ total.count }}</td> + </tr> +</table> + +{% if total.longest_distance_track %} +<h2>{{ _("page.profile.longest_distance_track") }}</h2> +{{ render_track_card(total.longest_distance_track) }} +{% endif %} + +{% if total.shortest_distance_track %} +<h2>{{ _("page.profile.shortest_distance_track") }}</h2> +{{ render_track_card(total.shortest_distance_track) }} +{% endif %} + +{% if total.longest_duration_track %} +<h2>{{ _("page.profile.longest_duration_track") }}</h2> +{{ render_track_card(total.longest_duration_track) }} +{% endif %} + +{% if total.shortest_duration_track %} +<h2>{{ _("page.profile.shortest_duration_track") }}</h2> +{{ render_track_card(total.shortest_duration_track) }} +{% endif %} +{% endblock %} + +{% block latescripts %} +<script> + (function() { + const renderMap = document.getElementById("userMap") !== null; + if (!renderMap) { + return; + } + + const map = L.map("userMap").setView([52.520008, 13.404954], 2); + + baseLayers = {}; + overlayLayers = {}; + + let defaultOverlayLayer = null; + let layer = null; + {% if heatmap_url %} + layer = overlayLayers[{{ _("page.profile.heatmap") | tojson }}] = L.tileLayer({{ heatmap_url | tojson }}, { + maxZoom: 19, + }); + if (defaultOverlayLayer === null) { + defaultOverlayLayer = layer; + } + {% endif %} + {% if tilehunt_url %} + layer = overlayLayers[{{ _("page.profile.tilehunt") | tojson }}] = L.tileLayer({{ tilehunt_url | tojson }}, { + maxZoom: 19, + }); + if (defaultOverlayLayer === null) { + defaultOverlayLayer = layer; + } + {% endif %} + + let defaultLayer = null; + + for (let layer of TILE_LAYERS) { + if (layer.type === "base") { + baseLayers[layer.name] = L.tileLayer(layer.url, { + maxZoom: layer.zoom, + attribution: layer.attribution, + }); + if (defaultLayer === null) { + defaultLayer = baseLayers[layer.name]; + } + } else if (layer.type === "overlay") { + overlayLayers[layer.name] = L.tileLayer(layer.url, { + attribution: layer.attribution, + }); + } + } + + + // Add the default layer via .addTo directly, otherwise it will not be + // selected at the start. + defaultLayer.addTo(map); + if (defaultOverlayLayer != null) { + defaultOverlayLayer.addTo(map); + } + L.control.layers(baseLayers, overlayLayers).addTo(map); + })(); +</script> +{% 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", +] |