Compare commits

..

2 Commits

Author SHA1 Message Date
Lukáš Kucharczyk 2e5e77b4e5
replace navbar
Django CI/CD / test (push) Successful in 1m12s Details
Django CI/CD / build-and-push (push) Has been skipped Details
2024-08-09 13:14:18 +02:00
Lukáš Kucharczyk e79cf5de7a
fix non-working views 2024-08-09 13:12:47 +02:00
4 changed files with 287 additions and 107 deletions

View File

@ -1246,6 +1246,18 @@ input:checked + .toggle-bg {
} }
} }
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
.visible { .visible {
visibility: visible; visibility: visible;
} }
@ -1334,6 +1346,10 @@ input:checked + .toggle-bg {
z-index: 50; z-index: 50;
} }
.z-0 {
z-index: 0;
}
.mx-2 { .mx-2 {
margin-left: 0.5rem; margin-left: 0.5rem;
margin-right: 0.5rem; margin-right: 0.5rem;
@ -1398,6 +1414,10 @@ input:checked + .toggle-bg {
margin-top: 1rem; margin-top: 1rem;
} }
.ms-2\.5 {
margin-inline-start: 0.625rem;
}
.block { .block {
display: block; display: block;
} }
@ -1467,6 +1487,14 @@ input:checked + .toggle-bg {
height: 2.25rem; height: 2.25rem;
} }
.h-10 {
height: 2.5rem;
}
.h-2\.5 {
height: 0.625rem;
}
.min-h-screen { .min-h-screen {
min-height: 100vh; min-height: 100vh;
} }
@ -1507,6 +1535,18 @@ input:checked + .toggle-bg {
width: 100%; width: 100%;
} }
.w-10 {
width: 2.5rem;
}
.w-2\.5 {
width: 0.625rem;
}
.w-44 {
width: 11rem;
}
.max-w-80 { .max-w-80 {
max-width: 20rem; max-width: 20rem;
} }
@ -1527,6 +1567,10 @@ input:checked + .toggle-bg {
max-width: 20rem; max-width: 20rem;
} }
.max-w-screen-xl {
max-width: 1280px;
}
.flex-1 { .flex-1 {
flex: 1 1 0%; flex: 1 1 0%;
} }
@ -1673,6 +1717,23 @@ input:checked + .toggle-bg {
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
} }
.space-x-3 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(0.75rem * var(--tw-space-x-reverse));
margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
}
.divide-y > :not([hidden]) ~ :not([hidden]) {
--tw-divide-y-reverse: 0;
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
}
.divide-gray-100 > :not([hidden]) ~ :not([hidden]) {
--tw-divide-opacity: 1;
border-color: rgb(243 244 246 / var(--tw-divide-opacity));
}
.self-center { .self-center {
align-self: center; align-self: center;
} }
@ -1719,6 +1780,10 @@ input:checked + .toggle-bg {
border-radius: 0.125rem; border-radius: 0.125rem;
} }
.rounded {
border-radius: 0.25rem;
}
.rounded-e-lg { .rounded-e-lg {
border-start-end-radius: 0.5rem; border-start-end-radius: 0.5rem;
border-end-end-radius: 0.5rem; border-end-end-radius: 0.5rem;
@ -1851,6 +1916,10 @@ input:checked + .toggle-bg {
padding: 1rem; padding: 1rem;
} }
.p-2 {
padding: 0.5rem;
}
.px-2 { .px-2 {
padding-left: 0.5rem; padding-left: 0.5rem;
padding-right: 0.5rem; padding-right: 0.5rem;
@ -2679,6 +2748,11 @@ textarea:disabled:is(.dark *) {
outline-color: #AC94FA; outline-color: #AC94FA;
} }
.dark\:divide-gray-600:is(.dark *) > :not([hidden]) ~ :not([hidden]) {
--tw-divide-opacity: 1;
border-color: rgb(75 85 99 / var(--tw-divide-opacity));
}
.dark\:border-blue-500:is(.dark *) { .dark\:border-blue-500:is(.dark *) {
--tw-border-opacity: 1; --tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity)); border-color: rgb(63 131 248 / var(--tw-border-opacity));
@ -2871,6 +2945,11 @@ textarea:disabled:is(.dark *) {
--tw-ring-color: rgb(14 159 110 / var(--tw-ring-opacity)); --tw-ring-color: rgb(14 159 110 / var(--tw-ring-opacity));
} }
.dark\:focus\:ring-gray-600:focus:is(.dark *) {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(75 85 99 / var(--tw-ring-opacity));
}
@media (min-width: 640px) { @media (min-width: 640px) {
.sm\:inline { .sm\:inline {
display: inline; display: inline;
@ -2927,6 +3006,10 @@ textarea:disabled:is(.dark *) {
margin-bottom: 0px; margin-bottom: 0px;
} }
.md\:mt-0 {
margin-top: 0px;
}
.md\:block { .md\:block {
display: block; display: block;
} }
@ -2935,6 +3018,10 @@ textarea:disabled:is(.dark *) {
display: inline; display: inline;
} }
.md\:hidden {
display: none;
}
.md\:w-auto { .md\:w-auto {
width: auto; width: auto;
} }
@ -2947,6 +3034,29 @@ textarea:disabled:is(.dark *) {
flex-direction: row; flex-direction: row;
} }
.md\:space-x-8 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(2rem * var(--tw-space-x-reverse));
margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse)));
}
.md\:border-0 {
border-width: 0px;
}
.md\:bg-transparent {
background-color: transparent;
}
.md\:bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.md\:p-0 {
padding: 0px;
}
.md\:px-6 { .md\:px-6 {
padding-left: 1.5rem; padding-left: 1.5rem;
padding-right: 1.5rem; padding-right: 1.5rem;
@ -2956,6 +3066,43 @@ textarea:disabled:is(.dark *) {
padding-top: 0.5rem; padding-top: 0.5rem;
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
} }
.md\:text-blue-700 {
--tw-text-opacity: 1;
color: rgb(26 86 219 / var(--tw-text-opacity));
}
.md\:hover\:bg-transparent:hover {
background-color: transparent;
}
.md\:hover\:text-blue-700:hover {
--tw-text-opacity: 1;
color: rgb(26 86 219 / var(--tw-text-opacity));
}
.md\:dark\:bg-gray-900:is(.dark *) {
--tw-bg-opacity: 1;
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
}
.md\:dark\:bg-transparent:is(.dark *) {
background-color: transparent;
}
.md\:dark\:text-blue-500:is(.dark *) {
--tw-text-opacity: 1;
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.md\:dark\:hover\:bg-transparent:hover:is(.dark *) {
background-color: transparent;
}
.md\:dark\:hover\:text-blue-500:hover:is(.dark *) {
--tw-text-opacity: 1;
color: rgb(63 131 248 / var(--tw-text-opacity));
}
} }
@media (min-width: 1024px) { @media (min-width: 1024px) {

View File

@ -33,110 +33,7 @@
width="24" width="24"
alt="loading indicator" /> alt="loading indicator" />
<div class="flex flex-col min-h-screen"> <div class="flex flex-col min-h-screen">
<nav class="dark:bg-gray-900 border-gray-200 h-24 flex items-center"> {% include "navbar.html" %}
<div class="container flex flex-wrap items-center justify-between mx-auto">
<a href="{% url 'list_sessions_recent' %}" class="flex items-center">
<span class="text-4xl">
<img src="{% static 'icons/schedule.png' %}"
height="48"
width="48"
alt="Timetracker Logo"
class="mr-4" />
</span>
<span class="self-center text-xl font-semibold whitespace-nowrap text-white">Timetracker</span>
</a>
<div class="w-full md:block md:w-auto">
<ul class="flex flex-col md:flex-row p-4 mt-4 dark:text-white">
<button id="theme-toggle"
type="button"
class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5">
<svg id="theme-toggle-dark-icon"
class="hidden w-5 h-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path>
</svg>
<svg id="theme-toggle-light-icon"
class="hidden w-5 h-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" fill-rule="evenodd" clip-rule="evenodd">
</path>
</svg>
</button>
<li class="relative group">
{% if user.is_authenticated %}
<a class="block py-2 pl-3 pr-4 hover:underline"
href="{% url 'add_game' %}">New</a>
<ul class="absolute hidden text-gray-700 pt-1 group-hover:block w-auto whitespace-nowrap">
{% if purchase_available %}
<li>
<a class="bg-gray-200 hover:bg-gray-400 py-2 px-4 block whitespace-no-wrap"
href="{% url 'add_device' %}">Device</a>
</li>
{% endif %}
<li>
<a class="bg-gray-200 hover:bg-gray-400 py-2 px-4 block whitespace-no-wrap"
href="{% url 'add_game' %}">Game</a>
</li>
{% if game_available and platform_available %}
<li>
<a class="bg-gray-200 hover:bg-gray-400 py-2 px-4 block whitespace-no-wrap"
href="{% url 'add_edition' %}">Edition</a>
</li>
{% endif %}
<li>
<a class="bg-gray-200 hover:bg-gray-400 py-2 px-4 block whitespace-no-wrap"
href="{% url 'add_platform' %}">Platform</a>
</li>
{% if edition_available %}
<li>
<a class="bg-gray-200 hover:bg-gray-400 py-2 px-4 block whitespace-no-wrap"
href="{% url 'add_purchase' %}">Purchase</a>
</li>
{% endif %}
{% if purchase_available %}
<li>
<a class="bg-gray-200 hover:bg-gray-400 py-2 px-4 block whitespace-no-wrap"
href="{% url 'add_session' %}">Session</a>
</li>
{% endif %}
</ul>
</li>
{% if session_count > 0 %}
<li class="relative group">
<a class="block py-2 pl-3 pr-4 hover:underline"
href="{% url 'stats_by_year' 0 %}">Stats</a>
<ul class="absolute hidden text-gray-700 pt-1 group-hover:block">
<li>
<a class="bg-gray-200 hover:bg-gray-400 py-2 px-4 block whitespace-no-wrap"
href="{% url 'stats_by_year' 0 %}">Overall</a>
</li>
{% for year in stats_dropdown_year_range %}
<li>
<a class="bg-gray-200 hover:bg-gray-400 py-2 px-4 block whitespace-no-wrap"
href="{% url 'stats_by_year' year %}">{{ year }}</a>
</li>
{% endfor %}
</ul>
</li>
<li>
<a class="block py-2 pl-3 pr-4 hover:underline"
href="{% url 'list_sessions' %}">All
Sessions</a>
</li>
<li>
<a class="block py-2 pl-3 pr-4 hover:underline"
href="{% url 'logout' %}">Log Out</a>
</li>
{% endif %}
{% endif %}
</ul>
</div>
</div>
</nav>
<div class="flex flex-1 flex-col dark:bg-gray-800 pt-8"> <div class="flex flex-1 flex-col dark:bg-gray-800 pt-8">
{% block content %} {% block content %}
No content here. No content here.

136
games/templates/navbar.html Normal file
View File

@ -0,0 +1,136 @@
{% load static %}
<nav class="bg-white border-gray-200 dark:bg-gray-900 dark:border-gray-700">
<div class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-4">
<a href="{% url 'index' %}"
class="flex items-center space-x-3 rtl:space-x-reverse">
<img src="{% static 'icons/schedule.png' %}"
height="48"
width="48"
alt="Timetracker Logo"
class="mr-4" />
<span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white">Timetracker</span>
</a>
<button data-collapse-toggle="navbar-dropdown"
type="button"
class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"
aria-controls="navbar-dropdown"
aria-expanded="false">
<span class="sr-only">Open main menu</span>
<svg class="w-5 h-5"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 17 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h15M1 7h15M1 13h15" />
</svg>
</button>
<div class="hidden w-full md:block md:w-auto" id="navbar-dropdown">
<ul class="flex flex-col font-medium p-4 md:p-0 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:space-x-8 rtl:space-x-reverse md:flex-row md:mt-0 md:border-0 md:bg-white dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700">
<li>
<a href="#"
class="block py-2 px-3 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 md:dark:text-blue-500 dark:bg-blue-600 md:dark:bg-transparent"
aria-current="page">Home</a>
</li>
<li>
<button id="dropdownNavbarNewLink"
data-dropdown-toggle="dropdownNavbarNew"
class="flex items-center justify-between w-full py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 md:w-auto dark:text-white md:dark:hover:text-blue-500 dark:focus:text-white dark:border-gray-700 dark:hover:bg-gray-700 md:dark:hover:bg-transparent">
New
<svg class="w-2.5 h-2.5 ms-2.5"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 10 6">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4" />
</svg>
</button>
<!-- Dropdown menu -->
<div id="dropdownNavbarNew"
class="z-10 hidden font-normal bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700 dark:divide-gray-600">
<ul class="py-2 text-sm text-gray-700 dark:text-gray-400"
aria-labelledby="dropdownLargeButton">
<li>
<a href="{% url 'add_device' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Device</a>
</li>
<li>
<a href="{% url 'add_game' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Game</a>
</li>
<li>
<a href="{% url 'add_edition' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Edition</a>
</li>
<li>
<a href="{% url 'add_platform' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Platform</a>
</li>
<li>
<a href="{% url 'add_purchase' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Purchase</a>
</li>
<li>
<a href="{% url 'add_session' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Session</a>
</li>
</ul>
</div>
</li>
<li>
<button id="dropdownNavbarManageLink"
data-dropdown-toggle="dropdownNavbarManage"
class="flex items-center justify-between w-full py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 md:w-auto dark:text-white md:dark:hover:text-blue-500 dark:focus:text-white dark:border-gray-700 dark:hover:bg-gray-700 md:dark:hover:bg-transparent">
Manage
<svg class="w-2.5 h-2.5 ms-2.5"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 10 6">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4" />
</svg>
</button>
<!-- Dropdown menu -->
<div id="dropdownNavbarManage"
class="z-10 hidden font-normal bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700 dark:divide-gray-600">
<ul class="py-2 text-sm text-gray-700 dark:text-gray-400"
aria-labelledby="dropdownLargeButton">
<li>
<a href="{% url 'add_device' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Devices</a>
</li>
<li>
<a href="{% url 'add_game' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Games</a>
</li>
<li>
<a href="{% url 'add_edition' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Editions</a>
</li>
<li>
<a href="{% url 'add_platform' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Platforms</a>
</li>
<li>
<a href="{% url 'list_purchases' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Purchases</a>
</li>
<li>
<a href="{% url 'add_session' %}"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Sessions</a>
</li>
</ul>
</div>
</li>
<li>
<a href="{% url 'stats_by_year' 0 %}"
class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">Stats</a>
</li>
<li>
<a href="{% url 'logout' %}"
class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">Log
out</a>
</li>
</ul>
</div>
</div>
</nav>

View File

@ -48,7 +48,7 @@ def stats_dropdown_year_range(request: HttpRequest) -> dict[str, range]:
@login_required @login_required
def add_session(request: HttpRequest, purchase_id: int) -> HttpResponse: def add_session(request: HttpRequest, purchase_id: int = 0) -> HttpResponse:
context = {} context = {}
initial: dict[str, Any] = {"timestamp_start": timezone.now()} initial: dict[str, Any] = {"timestamp_start": timezone.now()}
@ -831,7 +831,7 @@ def delete_purchase(request: HttpRequest, purchase_id: int) -> HttpResponse:
@login_required @login_required
def add_purchase(request: HttpRequest, edition_id: int) -> HttpResponse: def add_purchase(request: HttpRequest, edition_id: int = 0) -> HttpResponse:
context: dict[str, Any] = {} context: dict[str, Any] = {}
initial = {"date_purchased": timezone.now()} initial = {"date_purchased": timezone.now()}
@ -886,7 +886,7 @@ def add_game(request: HttpRequest) -> HttpResponse:
@login_required @login_required
def add_edition(request: HttpRequest, game_id: int) -> HttpResponse: def add_edition(request: HttpRequest, game_id: int = 0) -> HttpResponse:
context: dict[str, Any] = {} context: dict[str, Any] = {}
if request.method == "POST": if request.method == "POST":
form = EditionForm(request.POST or None) form = EditionForm(request.POST or None)