From ac1f86cac3644bc93537e5d64597355766e29fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Kucharczyk?= Date: Sun, 1 Oct 2023 21:28:02 +0200 Subject: [PATCH] Add game overview page Fixes #8 --- CHANGELOG.md | 1 + games/static/base.css | 137 +++++++++++++++++++++++++++++ games/static/icons/wikidata.png | Bin 0 -> 504 bytes games/templates/list_sessions.html | 6 +- games/templates/view_game.html | 41 +++++++++ games/urls.py | 2 +- games/views.py | 14 +++ 7 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 games/static/icons/wikidata.png create mode 100644 games/templates/view_game.html diff --git a/CHANGELOG.md b/CHANGELOG.md index 38b64fe..ba9a2ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * Improve session list (https://git.kucharczyk.xyz/lukas/timetracker/issues/53) * Change fonts to IBM Plex * Only use local WOFF2 font files +* Add game overview page (https://git.kucharczyk.xyz/lukas/timetracker/issues/8) ## 1.0.3 / 2023-02-20 17:16+01:00 diff --git a/games/static/base.css b/games/static/base.css index e53d77e..35ca3fc 100644 --- a/games/static/base.css +++ b/games/static/base.css @@ -781,6 +781,21 @@ select { margin-bottom: 1rem; } +.mx-2 { + margin-left: 0.5rem; + margin-right: 0.5rem; +} + +.my-1 { + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} + .mb-4 { margin-bottom: 1rem; } @@ -793,6 +808,30 @@ select { margin-top: 1rem; } +.mt-1 { + margin-top: 0.25rem; +} + +.mt-2 { + margin-top: 0.5rem; +} + +.mb-2 { + margin-bottom: 0.5rem; +} + +.mb-1 { + margin-bottom: 0.25rem; +} + +.ml-1 { + margin-left: 0.25rem; +} + +.ml-2 { + margin-left: 0.5rem; +} + .block { display: block; } @@ -809,6 +848,10 @@ select { display: table; } +.list-item { + display: list-item; +} + .hidden { display: none; } @@ -829,6 +872,10 @@ select { width: 100%; } +.w-5 { + width: 1.25rem; +} + .max-w-screen-lg { max-width: 1024px; } @@ -837,6 +884,18 @@ select { max-width: 20rem; } +.max-w-lg { + max-width: 32rem; +} + +.max-w-3xl { + max-width: 48rem; +} + +.max-w-sm { + max-width: 24rem; +} + @keyframes spin { to { transform: rotate(360deg); @@ -847,6 +906,10 @@ select { animation: spin 1s linear infinite; } +.list-disc { + list-style-type: disc; +} + .flex-col { flex-direction: column; } @@ -890,6 +953,21 @@ select { border-color: rgb(229 231 235 / var(--tw-border-opacity)); } +.border-red-300 { + --tw-border-opacity: 1; + border-color: rgb(252 165 165 / var(--tw-border-opacity)); +} + +.border-red-500 { + --tw-border-opacity: 1; + border-color: rgb(239 68 68 / var(--tw-border-opacity)); +} + +.border-slate-500 { + --tw-border-opacity: 1; + border-color: rgb(100 116 139 / var(--tw-border-opacity)); +} + .bg-green-600 { --tw-bg-opacity: 1; background-color: rgb(22 163 74 / var(--tw-bg-opacity)); @@ -900,6 +978,11 @@ select { background-color: rgb(255 255 255 / var(--tw-bg-opacity)); } +.bg-slate-400 { + --tw-bg-opacity: 1; + background-color: rgb(148 163 184 / var(--tw-bg-opacity)); +} + .p-4 { padding: 1rem; } @@ -998,6 +1081,11 @@ select { line-height: 1.75rem; } +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; +} + .font-semibold { font-weight: 600; } @@ -1029,6 +1117,27 @@ select { color: rgb(253 224 71 / var(--tw-text-opacity)); } +.text-gray-600 { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); +} + +.underline { + text-decoration-line: underline; +} + +.decoration-red-500 { + text-decoration-color: #ef4444; +} + +.decoration-slate-400 { + text-decoration-color: #94a3b8; +} + +.decoration-slate-500 { + text-decoration-color: #64748b; +} + .shadow-md { --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); @@ -1295,6 +1404,14 @@ th label { } @media (min-width: 640px) { + .sm\:ml-2 { + margin-left: 0.5rem; + } + + .sm\:inline { + display: inline; + } + .sm\:table-cell { display: table-cell; } @@ -1303,10 +1420,26 @@ th label { max-width: 28rem; } + .sm\:max-w-lg { + max-width: 32rem; + } + + .sm\:max-w-xl { + max-width: 36rem; + } + .sm\:px-4 { padding-left: 1rem; padding-right: 1rem; } + + .sm\:pl-2 { + padding-left: 0.5rem; + } + + .sm\:decoration-2 { + text-decoration-thickness: 2px; + } } @media (min-width: 768px) { @@ -1345,4 +1478,8 @@ th label { .lg\:max-w-lg { max-width: 32rem; } + + .lg\:max-w-3xl { + max-width: 48rem; + } } diff --git a/games/static/icons/wikidata.png b/games/static/icons/wikidata.png new file mode 100644 index 0000000000000000000000000000000000000000..69eb55e8705c1d4f04b7ce3433037f95634e1d32 GIT binary patch literal 504 zcmVv-{5yr@N=i8t`%0d+>u8I@Kj@z53=#G%MIBu>6t zCTWs?H@n#e91e%W;jkDl0u2y@QV>rWvjaQ=HQ;HoQ@~aOI)~A*2I$qhLA6^?0JPS- zt&{6E$C3UvYcuo!Mtwo7NK_5DpR$Jv&9Gmr@e&7WLnU#(eue@GkU~1~@k5-6jDf-A z%qax>QDd`cuit6;rF)g53$K(Z{ehqvK1}TkVsUtRv|TheR3g6^a3%uqfWC=G$e%;N zmWcvpdLYa!FG6T9d$TENZ*BoO+SDv0u$-9!qHzpZ>j4EMQMrIOGKk;DDc{Z`v{KyK zwjQCuS(b%_tpcj&nf0ypK&9}+ypy+1u5V2c(6c@U7P^gZPW7?{)E2US*>d_11-#|= zfwuJs)ys@a_4i8A6?4lLaB$VwGey8KGBk~rtuQ@nN(q_2PE2|r{KZXdQVdAjgIL%s z;Dzi3&(3l>|0A>40}*TjNeDxu1yp|C;K$0i4)Uku*FMsFmY%Ev)cn`cJigFL>1uS~ u|7@W9juxKiO0qT9D#;Ls!{Kl^{sW(CdUOm8gMiKe0000 - {{ data.purchase.edition }} + + {{ data.purchase.edition }} + {{ data.timestamp_start | date:"d/m/Y H:i" }} diff --git a/games/templates/view_game.html b/games/templates/view_game.html new file mode 100644 index 0000000..2667a93 --- /dev/null +++ b/games/templates/view_game.html @@ -0,0 +1,41 @@ +{% extends "base.html" %} + +{% block title %}{{ title }}{% endblock title %} + +{% load static %} + +{% block content %} +
+

{{ game.name }} (#{{ game.pk }})

+

{{ total_playtime }} ({{ first_session.timestamp_end | date:"M Y"}} — {{ first_session.timestamp_end | date:"M Y"}})

+
+

Editions

+
    + {% for edition in editions %} +
  • + {{ edition.name }} ({{ edition.platform }}, {{ edition.year_released }}) + {% if edition.wikidata %} + + {% endif %} +
  • + {% endfor %} +
+

Purchases

+
    + {% for purchase in purchases %} +
  • {{ purchase.platform }} ({{ purchase.get_ownership_type_display }}, {{ purchase.date_purchased | date:"Y" }}, {{ purchase.price }} {{ purchase.price_currency}})
  • + {% endfor %} +
+

Sessions

+
    + {% for session in sessions %} +
  • {{ session.timestamp_end | date:"d/m/Y" }} ({{ session.device.get_type_display | default:"Unknown" }}, {{ session.duration_formatted }})
  • + {% endfor %} +
+ +
+{% endblock content %} diff --git a/games/urls.py b/games/urls.py index 7113b4d..f191962 100644 --- a/games/urls.py +++ b/games/urls.py @@ -31,7 +31,7 @@ urlpatterns = [ path("add-purchase/", views.add_purchase, name="add_purchase"), path("add-edition/", views.add_edition, name="add_edition"), path("edit-edition/", views.edit_edition, name="edit_edition"), - path("edit-game/", views.edit_game, name="edit_game"), + path("game//view", views.view_game, name="view_game"), path("edit-platform/", views.edit_platform, name="edit_platform"), path("add-device/", views.add_device, name="add_device"), path("edit-session/", views.edit_session, name="edit_session"), diff --git a/games/views.py b/games/views.py index 29422a0..6c70d9f 100644 --- a/games/views.py +++ b/games/views.py @@ -91,6 +91,20 @@ def edit_game(request, game_id=None): return render(request, "add.html", context) +def view_game(request, game_id=None): + context = {} + game = Game.objects.get(id=game_id) + context["title"] = "View Game" + context["game"] = game + context["editions"] = Edition.objects.filter(game_id=game_id) + context["purchases"] = Purchase.objects.filter(edition__game_id=game_id) + context["sessions"] = Session.objects.filter(purchase__edition__game_id=game_id) + context["total_playtime"] = context["sessions"].total_duration() + context["last_session"] = context["sessions"].last + context["first_session"] = context["sessions"].first + return render(request, "view_game.html", context) + + def edit_platform(request, platform_id=None): context = {} purchase = Platform.objects.get(id=platform_id)