diff --git a/frontend/main.ts b/frontend/main.ts index ab42d06..fb951e0 100644 --- a/frontend/main.ts +++ b/frontend/main.ts @@ -8,6 +8,8 @@ export interface choiceMap { let choiceObjects: choiceMap = {}; document.addEventListener('DOMContentLoaded', function() { + changeTheme(); + initcolorTheme(); initSearch(); initSidebar(); initToggle(); @@ -20,6 +22,75 @@ document.addEventListener('DOMContentLoaded', function() { setCurrentdate(document.querySelector('#departure')); }); +function changeTheme() { + let toggleBtn = document.querySelector('#theme-toggle-js'); + + if(toggleBtn) { + toggleBtn.addEventListener('click', function() { + if(toggleBtn.dataset.theme === 'light') { + setTheme('dark', true); + } else { + setTheme('light', true); + } + }); + } +} + +/*** +* init javascript +* 1) detect native color scheme or use set theme in local storage +* 2) detect view (desktop or responsive) if on mobile device with touch screen +* 3) set base font size to 112.5% -> 18px +*/ +function initcolorTheme() { + colorThemeWatcher(); + let theme = localStorage.getItem('theme'); + if (theme == null || theme === 'auto') { + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + setTheme('dark', false); + } else { + setTheme('light', false); + } + } else { + setTheme(theme) + } +} + +/*** +* Listener operating system native color configuration +*/ +function colorThemeWatcher() { + try { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { + setTheme(e.matches ? 'dark' : 'light'); + }); + } catch { + console.warn('color theme watcher not supported'); + } +} + +/** +* Define color scheme, colors without losing the base font size configuration +* and add data-theme to html tag +* @param theme +*/ +function setTheme(theme: string, setLocalStorage = true) { + let toggleBtn = document.querySelector('#theme-toggle-js'); + + if(toggleBtn) { + if (setLocalStorage) { + localStorage.setItem('theme', theme); + } + toggleBtn.setAttribute('data-theme', theme); + + if (document.documentElement.classList.contains('dark') && theme === 'light') { + document.documentElement.classList.remove('dark'); + } else if(theme === 'dark'){ + document.documentElement.classList.add('dark'); + } + } +} + function setCurrentdate(input: HTMLInputElement) { if(input) { const now = new Date(); diff --git a/frontend/scss/app.scss b/frontend/scss/app.scss index 46606c2..b4bb35b 100644 --- a/frontend/scss/app.scss +++ b/frontend/scss/app.scss @@ -10,3 +10,4 @@ @import 'components/alert'; @import 'components/status'; @import 'components/chart'; +@import 'components/search'; diff --git a/frontend/scss/components/_btns.scss b/frontend/scss/components/_btns.scss index 6856169..4fca153 100644 --- a/frontend/scss/components/_btns.scss +++ b/frontend/scss/components/_btns.scss @@ -6,11 +6,11 @@ } &-dark { - @apply bg-primary-900 hover:bg-primary-950 focus-visible:outline-primary-950; + @apply bg-primary-900 hover:bg-primary-950 dark:bg-primary-950 dark:hover:bg-primary-700 focus-visible:outline-primary-950; } &-gray { - @apply bg-gray-400 hover:bg-gray-500 focus-visible:outline-primary-500; + @apply bg-gray-400 hover:bg-gray-500 dark:bg-primary-600 focus-visible:outline-primary-500; } &-attention { diff --git a/frontend/scss/components/_headlines.scss b/frontend/scss/components/_headlines.scss index 723d436..cd4fa44 100644 --- a/frontend/scss/components/_headlines.scss +++ b/frontend/scss/components/_headlines.scss @@ -1,7 +1,7 @@ .h1 { - @apply text-center text-3xl uppercase tracking-wide font-bold text-primary-900; + @apply text-center text-3xl uppercase tracking-wide font-bold text-primary-900 dark:text-white; } .h2 { - @apply font-bold uppercase tracking-wide text-center rounded-t-md text-primary-950 bg-gray-200 bg-opacity-80 text-lg px-3 py-3; + @apply font-bold uppercase tracking-wide text-center rounded-t-md text-primary-950 dark:text-white bg-gray-200 dark:bg-primary-950 bg-opacity-80 text-lg px-3 py-3; } \ No newline at end of file diff --git a/frontend/scss/components/_input.scss b/frontend/scss/components/_input.scss index 33489c2..8665c7c 100644 --- a/frontend/scss/components/_input.scss +++ b/frontend/scss/components/_input.scss @@ -1,5 +1,5 @@ .input { - @apply relative block w-full border-0 py-1.5 px-2 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6; + @apply relative block w-full bg-white dark:bg-black border-0 py-1.5 px-2 text-gray-900 dark:text-white ring-1 ring-inset ring-gray-300 dark:ring-black placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6; } select { @@ -7,7 +7,7 @@ select { background-repeat: no-repeat; background-position: right .75rem center; background-size: 16px 12px; - background-color: white; + @apply bg-white dark:bg-black; -webkit-appearance: none; appearance: none; } @@ -32,7 +32,7 @@ select { } .choices.is-disabled .choices__inner, .choices.is-disabled .choices__input { - background-color: #eaeaea; + @apply bg-white dark:bg-black; cursor: not-allowed; -webkit-user-select: none; user-select: none; @@ -52,8 +52,7 @@ select { display: block; width: 100%; padding: 10px; - @apply border-0 ring-1 ring-inset ring-gray-300; - background-color: #fff; + @apply bg-white dark:bg-black border-0 ring-1 ring-inset ring-gray-300 dark:ring-primary-600; margin: 0; } .choices[data-type*=select-one] .choices__button { @@ -93,7 +92,7 @@ select { pointer-events: none; } .choices[data-type*=select-one].is-open::after { - @apply border-0 ring-1 ring-inset ring-gray-300; + @apply border-0 ring-1 ring-inset ring-gray-300 dark:ring-primary-600; margin-top: -7.5px; } .choices[data-type*=select-one][dir=rtl]::after { @@ -135,10 +134,10 @@ select { } .choices__inner { - @apply input rounded-md bg-white; + @apply input rounded-md bg-white dark:bg-black; } .is-focused .choices__inner, .is-open .choices__inner { - @apply border-0 ring-1 ring-inset ring-gray-300; + @apply border-0 ring-1 ring-inset ring-gray-300 dark:ring-primary-600; } .is-open .choices__inner { border-radius: 0; @@ -190,7 +189,7 @@ select { @apply bg-primary-900; } .is-disabled .choices__list--multiple .choices__item { - @apply bg-gray-600; + @apply bg-gray-600 dark:bg-primary-900; } .choices__list--dropdown, .choices__list[aria-expanded] { @@ -198,8 +197,7 @@ select { z-index: 1; position: absolute; width: 100%; - background-color: #fff; - @apply border; + @apply border bg-white dark:bg-black dark:text-white; top: 100%; margin-top: -1px; border-bottom-left-radius: 2.5px; @@ -212,7 +210,7 @@ select { visibility: visible; } .is-open .choices__list--dropdown, .is-open .choices__list[aria-expanded] { - @apply border-0 ring-1 ring-inset ring-gray-300; + @apply border-0 ring-1 ring-inset ring-gray-300 dark:ring-primary-600; } .is-flipped .choices__list--dropdown, .is-flipped .choices__list[aria-expanded] { top: auto; @@ -260,7 +258,7 @@ select { } } .choices__list--dropdown .choices__item--selectable.is-highlighted, .choices__list[aria-expanded] .choices__item--selectable.is-highlighted { - @apply bg-gray-100; + @apply bg-gray-100 dark:bg-primary-950; } .choices__list--dropdown .choices__item--selectable.is-highlighted::after, .choices__list[aria-expanded] .choices__item--selectable.is-highlighted::after { opacity: 0.5; @@ -309,6 +307,8 @@ select { border: 0; border-radius: 0; max-width: 100%; + + @apply bg-transparent; } .choices__input:focus { outline: 0; diff --git a/frontend/scss/components/_links.scss b/frontend/scss/components/_links.scss index fcb67b1..21d9ab7 100644 --- a/frontend/scss/components/_links.scss +++ b/frontend/scss/components/_links.scss @@ -1,6 +1,6 @@ .link { &-primary { - @apply text-primary-600 hover:text-primary-900 underline; + @apply text-primary-600 dark:text-primary-200 hover:text-primary-900 hover:dark:text-primary-300 underline; } &-dark { diff --git a/frontend/scss/components/_search.scss b/frontend/scss/components/_search.scss new file mode 100644 index 0000000..a621e04 --- /dev/null +++ b/frontend/scss/components/_search.scss @@ -0,0 +1,13 @@ +.search { + &-bar { + @apply w-full relative block rounded-md border-0 py-1.5 px-2 bg-white dark:bg-black text-gray-900 dark:text-white ring-1 ring-inset ring-gray-300 dark:ring-black placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6 mb-2 md:mb-0; + } + + &-wrapper { + @apply bg-gray-200 dark:bg-primary-600 p-3 mt-4 rounded-t-md; + } + + &-result { + @apply bg-gray-200 dark:bg-primary-600 text-primary-950 dark:text-white pb-3 px-3 text-right; + } +} diff --git a/frontend/scss/components/_sidebar.scss b/frontend/scss/components/_sidebar.scss index a9c12f3..619753f 100644 --- a/frontend/scss/components/_sidebar.scss +++ b/frontend/scss/components/_sidebar.scss @@ -3,14 +3,12 @@ position: fixed; overflow-y: scroll; top: 0; - background: white; z-index: 2000; width: 0; max-width: 0; box-shadow: 0 1rem 3rem rgba(0,0,0,.175); &.open { - background-color: rgba(255, 255, 255, 100%); display: block; height: 100vh; right: 0; diff --git a/frontend/tailwind.config.cjs b/frontend/tailwind.config.cjs index 6f9bcd6..c17b852 100644 --- a/frontend/tailwind.config.cjs +++ b/frontend/tailwind.config.cjs @@ -40,5 +40,7 @@ export default { }, }, plugins: [], + important: true, + darkMode: 'class', } diff --git a/templates/admin/user/index.html.tera b/templates/admin/user/index.html.tera index 5fbb47b..5e748ac 100644 --- a/templates/admin/user/index.html.tera +++ b/templates/admin/user/index.html.tera @@ -30,26 +30,29 @@ -
+
- +
-
-
+
+
{% for user in users %}
-
-
+ +
-
{{ user.name }} +
{{ user.name }} {% if user.last_access %} (last access: {{ user.last_access | date }}) {% endif %} + {% if user.pw %} + Passwort zurücksetzen + {% endif %}
-
+
{{ macros::checkbox(label='Scheckbuch', name='is_guest', id=loop.index , checked=user.is_guest) }} {{ macros::checkbox(label='Steuerberechtigter', name='is_cox', id=loop.index , checked=user.is_cox) }} {{ macros::checkbox(label='Technical', name='is_tech', id=loop.index , checked=user.is_tech) }} @@ -58,16 +61,13 @@ {{ macros::input(label='Weight (kg)', name='weight', id=loop.index, type="text", value=user.weight) }} {{ macros::input(label='Sex', name='sex', id=loop.index, type="text", value=user.sex) }}
- {% if user.pw %} - Passwort zurücksetzen - {% endif %}
- diff --git a/templates/base.html.tera b/templates/base.html.tera index e7ae735..1dff697 100644 --- a/templates/base.html.tera +++ b/templates/base.html.tera @@ -9,7 +9,7 @@ Ruderassistent - ASKÖ Ruderverein Donau Linz - + {% if loggedin_user %} {{ macros::header(loggedin_user=loggedin_user) }} {% endif %} diff --git a/templates/boatdamages.html.tera b/templates/boatdamages.html.tera index 0bfadbd..49e2d2f 100644 --- a/templates/boatdamages.html.tera +++ b/templates/boatdamages.html.tera @@ -38,24 +38,24 @@
-
+
- +
-
+
{% for boatdamage in boatdamages | sort(attribute="verified") %} -
+
- {{ boatdamage.created_at | date(format='%d.%m.%Y') }} ({{ boatdamage.boat.name }}){% if boatdamage.boat.damage %}(Boot gesperrt){% endif %} + {{ boatdamage.created_at | date(format='%d.%m.%Y') }} ({{ boatdamage.boat.name }}){% if boatdamage.boat.damage %}(Boot gesperrt){% endif %}
{{ boatdamage.desc }}
- + Schaden eingetragen von {{ boatdamage.user_created.name }} am/um {{ boatdamage.created_at | date(format='%d.%m.%Y (%H:%M)') }} {% if boatdamage.fixed_at %} - Repariert von {{ boatdamage.user_fixed.name }} am/um {{ boatdamage.fixed_at | date(format='%d.%m.%Y (%H:%M)') }} + Repariert von {{ boatdamage.user_fixed.name }} am/um {{ boatdamage.fixed_at | date(format='%d.%m.%Y (%H:%M)') }} {% else %} {% if loggedin_user.is_cox %}
@@ -70,7 +70,7 @@ {% endif %} {% if boatdamage.verified_at %} - Verifziert von {{ boatdamage.user_verified.name }} am/um {{ boatdamage.verified_at | date(format='%d.%m.%Y (%H:%M)') }} + Verifziert von {{ boatdamage.user_verified.name }} am/um {{ boatdamage.verified_at | date(format='%d.%m.%Y (%H:%M)') }} {% else %} {% if loggedin_user.is_tech and boatdamage.fixed_at %} diff --git a/templates/dynamics/sidebar.html.tera b/templates/dynamics/sidebar.html.tera index 59c7041..2f9e7f3 100644 --- a/templates/dynamics/sidebar.html.tera +++ b/templates/dynamics/sidebar.html.tera @@ -1,4 +1,4 @@ -