6 Commits

Author SHA1 Message Date
241aa9dc13 Add manage page
All checks were successful
Django CI/CD / test (push) Successful in 1m16s
Django CI/CD / build-and-push (push) Has been skipped
2024-07-11 14:05:25 +02:00
4670568acb Add .DS_Store to .gitignore
All checks were successful
Django CI/CD / test (push) Successful in 1m4s
Django CI/CD / build-and-push (push) Successful in 1m34s
2024-01-15 22:09:29 +01:00
4b75a1dea9 Increase session count on game overview when starting a new session
All checks were successful
Django CI/CD / test (push) Successful in 50s
Django CI/CD / build-and-push (push) Successful in 1m32s
2024-01-15 21:41:25 +01:00
e2b7ff2e15 Remove cruft
All checks were successful
Django CI/CD / test (push) Successful in 53s
Django CI/CD / build-and-push (push) Successful in 1m30s
2024-01-15 19:17:27 +01:00
b94aa49fc3 Fix title not being displayed on the Recent sessions page 2024-01-15 19:17:24 +01:00
73a92e5636 Mark refunded purchases red
All checks were successful
Django CI/CD / test (push) Successful in 1m3s
Django CI/CD / build-and-push (push) Successful in 1m36s
2024-01-15 11:19:18 +01:00
6 changed files with 119 additions and 100 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ package-lock.json
db.sqlite3 db.sqlite3
/static/ /static/
dist/ dist/
.DS_Store

View File

@ -1,3 +1,12 @@
## Unreleased
## Improved
* mark refunded purchases red on game overview
* increase session count on game overview when starting a new session
## Fixed
* Fix title not being displayed on the Recent sessions page
## 1.5.2 / 2024-01-14 21:27+01:00 ## 1.5.2 / 2024-01-14 21:27+01:00
## Improved ## Improved

View File

@ -1,5 +1,5 @@
/* /*
! tailwindcss v3.4.0 | MIT License | https://tailwindcss.com ! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com
*/ */
/* /*
@ -834,11 +834,6 @@ select {
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
} }
.mx-1 {
margin-left: 0.25rem;
margin-right: 0.25rem;
}
.mb-1 { .mb-1 {
margin-bottom: 0.25rem; margin-bottom: 0.25rem;
} }
@ -895,6 +890,10 @@ select {
display: none; display: none;
} }
.h-3 {
height: 0.75rem;
}
.h-4 { .h-4 {
height: 1rem; height: 1rem;
} }
@ -907,18 +906,6 @@ select {
height: 1.5rem; height: 1.5rem;
} }
.h-8 {
height: 2rem;
}
.h-2 {
height: 0.5rem;
}
.h-3 {
height: 0.75rem;
}
.min-h-screen { .min-h-screen {
min-height: 100vh; min-height: 100vh;
} }
@ -935,10 +922,6 @@ select {
width: 1.75rem; width: 1.75rem;
} }
.w-8 {
width: 2rem;
}
.w-auto { .w-auto {
width: auto; width: auto;
} }
@ -947,14 +930,6 @@ select {
width: 100%; width: 100%;
} }
.w-4 {
width: 1rem;
}
.w-3 {
width: 0.75rem;
}
.max-w-screen-lg { .max-w-screen-lg {
max-width: 1024px; max-width: 1024px;
} }
@ -967,10 +942,6 @@ select {
max-width: 20rem; max-width: 20rem;
} }
.transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
@keyframes spin { @keyframes spin {
to { to {
transform: rotate(360deg); transform: rotate(360deg);
@ -1029,6 +1000,10 @@ select {
border-radius: 0.25rem; border-radius: 0.25rem;
} }
.rounded-full {
border-radius: 9999px;
}
.rounded-lg { .rounded-lg {
border-radius: 0.5rem; border-radius: 0.5rem;
} }
@ -1037,10 +1012,6 @@ select {
border-radius: 0.125rem; border-radius: 0.125rem;
} }
.rounded-full {
border-radius: 9999px;
}
.border-gray-200 { .border-gray-200 {
--tw-border-opacity: 1; --tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity)); border-color: rgb(229 231 235 / var(--tw-border-opacity));
@ -1071,16 +1042,6 @@ select {
background-color: rgb(255 255 255 / var(--tw-bg-opacity)); background-color: rgb(255 255 255 / var(--tw-bg-opacity));
} }
.bg-green-400 {
--tw-bg-opacity: 1;
background-color: rgb(74 222 128 / var(--tw-bg-opacity));
}
.bg-green-500 {
--tw-bg-opacity: 1;
background-color: rgb(34 197 94 / var(--tw-bg-opacity));
}
.p-4 { .p-4 {
padding: 1rem; padding: 1rem;
} }
@ -1105,16 +1066,6 @@ select {
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
} }
.py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
.px-1 {
padding-left: 0.25rem;
padding-right: 0.25rem;
}
.pl-3 { .pl-3 {
padding-left: 0.75rem; padding-left: 0.75rem;
} }
@ -1183,6 +1134,11 @@ select {
color: rgb(55 65 81 / var(--tw-text-opacity)); color: rgb(55 65 81 / var(--tw-text-opacity));
} }
.text-red-600 {
--tw-text-opacity: 1;
color: rgb(220 38 38 / var(--tw-text-opacity));
}
.text-slate-300 { .text-slate-300 {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(203 213 225 / var(--tw-text-opacity)); color: rgb(203 213 225 / var(--tw-text-opacity));
@ -1276,7 +1232,7 @@ a:hover {
transition: all 0.2s ease-out; transition: all 0.2s ease-out;
} }
:is(:where(.dark) form label) { :is(.dark form label) {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity)); color: rgb(148 163 184 / var(--tw-text-opacity));
} }
@ -1286,7 +1242,7 @@ a:hover {
margin-right: auto; margin-right: auto;
} }
:is(:where(.dark) .responsive-table) { :is(.dark .responsive-table) {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity)); color: rgb(255 255 255 / var(--tw-text-opacity));
} }
@ -1317,8 +1273,8 @@ a:hover {
border-left-color: rgb(100 116 139 / var(--tw-border-opacity)); border-left-color: rgb(100 116 139 / var(--tw-border-opacity));
} }
:is(:where(.dark) form input),:is(:where(.dark) :is(.dark form input),:is(.dark
select),:is(:where(.dark) select),:is(.dark
textarea) { textarea) {
border-width: 1px; border-width: 1px;
--tw-border-opacity: 1; --tw-border-opacity: 1;
@ -1329,8 +1285,8 @@ textarea) {
color: rgb(241 245 249 / var(--tw-text-opacity)); color: rgb(241 245 249 / var(--tw-text-opacity));
} }
:is(:where(.dark) form input:disabled),:is(:where(.dark) :is(.dark form input:disabled),:is(.dark
select:disabled),:is(:where(.dark) select:disabled),:is(.dark
textarea:disabled) { textarea:disabled) {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(51 65 85 / var(--tw-bg-opacity)); background-color: rgb(51 65 85 / var(--tw-bg-opacity));
@ -1502,6 +1458,36 @@ th label {
display: block; display: block;
} }
:is(.dark .dark\:bg-gray-800) {
--tw-bg-opacity: 1;
background-color: rgb(31 41 55 / var(--tw-bg-opacity));
}
:is(.dark .dark\:bg-gray-900) {
--tw-bg-opacity: 1;
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
}
:is(.dark .dark\:text-slate-400) {
--tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity));
}
:is(.dark .dark\:text-slate-500) {
--tw-text-opacity: 1;
color: rgb(100 116 139 / var(--tw-text-opacity));
}
:is(.dark .dark\:text-slate-600) {
--tw-text-opacity: 1;
color: rgb(71 85 105 / var(--tw-text-opacity));
}
:is(.dark .dark\:text-white) {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
}
@media (min-width: 640px) { @media (min-width: 640px) {
.sm\:inline { .sm\:inline {
display: inline; display: inline;
@ -1586,33 +1572,3 @@ th label {
max-width: 32rem; max-width: 32rem;
} }
} }
:is(:where(.dark) .dark\:bg-gray-800) {
--tw-bg-opacity: 1;
background-color: rgb(31 41 55 / var(--tw-bg-opacity));
}
:is(:where(.dark) .dark\:bg-gray-900) {
--tw-bg-opacity: 1;
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
}
:is(:where(.dark) .dark\:text-slate-400) {
--tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity));
}
:is(:where(.dark) .dark\:text-slate-500) {
--tw-text-opacity: 1;
color: rgb(100 116 139 / var(--tw-text-opacity));
}
:is(:where(.dark) .dark\:text-slate-600) {
--tw-text-opacity: 1;
color: rgb(71 85 105 / var(--tw-text-opacity));
}
:is(:where(.dark) .dark\:text-white) {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
}

View File

@ -0,0 +1,36 @@
{% extends 'base.html' %}
{% block content %}
<table class="table table-sm table-zebra">
<thead>
<tr class="text-left">
<th></th>
<th>Name</th>
<th>Year</th>
<th>Wikidata ID</th>
<th>Created At</th>
<th>Manage</th>
</tr>
</thead>
<tbody>
{% for game in games %}
<tr>
<th>{{ game.pk }}</th>
<td>{{ game.name }}</td>
<td>{{ game.year_released }}</td>
<td>{{ game.wikidata }}</td>
<td>{{ game.created_at }}</td>
<td>
<div class="join">
<button class="btn btn-primary btn-sm join-item">
Edit
</button>
<button class="btn btn-warning btn-sm join-item">
Delete
</button>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock content %}

View File

@ -36,7 +36,7 @@
</li> </li>
<ul> <ul>
{% for purchase in edition.game_purchases %} {% for purchase in edition.game_purchases %}
<li class="sm:pl-6 flex items-center"> <li class="sm:pl-6 flex items-center {% if purchase.date_refunded %}text-red-600{% endif %}">
{{ purchase.get_ownership_type_display }}, {{ purchase.date_purchased | date:"Y" }} {{ purchase.get_ownership_type_display }}, {{ purchase.date_purchased | date:"Y" }}
{% if purchase.price != 0 %}({{ purchase.price }} {{ purchase.price_currency }}){% endif %} {% if purchase.price != 0 %}({{ purchase.price }} {{ purchase.price_currency }}){% endif %}
{% url 'edit_purchase' purchase.id as edit_url %} {% url 'edit_purchase' purchase.id as edit_url %}
@ -57,13 +57,14 @@
</ul> </ul>
<h1 class="text-3xl mt-4 mb-1 flex gap-2 items-center"> <h1 class="text-3xl mt-4 mb-1 flex gap-2 items-center">
Sessions Sessions
<span class="dark:text-slate-500">({{ session_count }})</span> <span class="dark:text-slate-500" id="session-count">({{ session_count }})</span>
{% url 'view_game_start_session_from_session' latest_session_id as add_session_link %} {% url 'view_game_start_session_from_session' latest_session_id as add_session_link %}
<a <a
class="truncate max-w-xs py-1 px-2 text-xs bg-green-600 hover:bg-green-700 focus:ring-green-500 focus:ring-offset-blue-200 text-white transition ease-in duration-200 text-center font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-sm" class="truncate max-w-xs py-1 px-2 text-xs bg-green-600 hover:bg-green-700 focus:ring-green-500 focus:ring-offset-blue-200 text-white transition ease-in duration-200 text-center font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-sm"
title="Start new session" title="Start new session"
href="{{ add_session_link }}" href="{{ add_session_link }}"
hx-get="{{ add_session_link }}" hx-get="{{ add_session_link }}"
hx-vals="js:{session_count:getSessionCount()}"
hx-target="#session-list" hx-target="#session-list"
hx-swap="afterbegin" hx-swap="afterbegin"
>New</a> >New</a>
@ -83,9 +84,9 @@
class="flex bg-green-600 rounded-full px-2 w-7 h-4 text-white justify-center items-center" class="flex bg-green-600 rounded-full px-2 w-7 h-4 text-white justify-center items-center"
href="{{ end_session_url }}" href="{{ end_session_url }}"
hx-get="{{ end_session_url }}" hx-get="{{ end_session_url }}"
hx-vals='{"partial":"view_game.html#session-info"}'
hx-target="closest li" hx-target="closest li"
hx-swap="outerHTML" hx-swap="outerHTML"
hx-vals="js:{session_count:getSessionCount()}"
hx-indicator="#indicator" hx-indicator="#indicator"
> >
<svg xmlns="http://www.w3.org/2000/svg" fill="#ffffff" class="h-3" x="0px" y="0px" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" fill="#ffffff" class="h-3" x="0px" y="0px" viewBox="0 0 24 24">
@ -96,8 +97,16 @@
{% endif %} {% endif %}
</li> </li>
<li class="sm:pl-4 italic">{{ session.note|linebreaks }}</li> <li class="sm:pl-4 italic">{{ session.note|linebreaks }}</li>
<div class="hidden" hx-swap-oob="innerHTML:#session-count">
({{ session_count }})
</div>
{% endpartialdef %} {% endpartialdef %}
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<script>
function getSessionCount() {
return document.getElementById('session-count').textContent.match("[0-9]+");
}
</script>
{% endblock content %} {% endblock content %}

View File

@ -1,5 +1,6 @@
from datetime import datetime from datetime import datetime
from typing import Any, Callable from typing import Any, Callable
import re
from django.db.models import ( from django.db.models import (
Avg, Avg,
@ -247,7 +248,10 @@ def clone_session_by_id(session_id: int) -> Session:
def new_session_from_existing_session(request, session_id: int, template: str = ""): def new_session_from_existing_session(request, session_id: int, template: str = ""):
session = clone_session_by_id(session_id) session = clone_session_by_id(session_id)
if request.htmx: if request.htmx:
context = {"session": session} context = {
"session": session,
"session_count": int(request.GET.get("session_count", 0)) + 1,
}
return render(request, template, context) return render(request, template, context)
return redirect("list_sessions") return redirect("list_sessions")
@ -258,7 +262,10 @@ def end_session(request, session_id: int, template: str = ""):
session.timestamp_end = timezone.now() session.timestamp_end = timezone.now()
session.save() session.save()
if request.htmx: if request.htmx:
context = {"session": session} context = {
"session": session,
"session_count": request.GET.get("session_count", 0),
}
return render(request, template, context) return render(request, template, context)
return redirect("list_sessions") return redirect("list_sessions")
@ -311,6 +318,7 @@ def list_sessions(
dataset = all_sessions dataset = all_sessions
context = { context = {
**context,
"dataset": dataset, "dataset": dataset,
"dataset_count": dataset.count(), "dataset_count": dataset.count(),
"last": Session.objects.prefetch_related("purchase__platform").latest(), "last": Session.objects.prefetch_related("purchase__platform").latest(),