forked from Ruderverein-Donau-Linz/rowt
nicer explanations
This commit is contained in:
parent
a5a5b1ec25
commit
64ca9826ea
@ -250,12 +250,20 @@ ORDER BY last_access DESC
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub async fn create(db: &SqlitePool, name: &str) -> bool {
|
||||
pub async fn create(db: &SqlitePool, name: &str) {
|
||||
let name = name.trim();
|
||||
sqlx::query!("INSERT INTO USER(name) VALUES (?)", name)
|
||||
if sqlx::query!("INSERT INTO USER(name) VALUES (?)", name)
|
||||
.execute(db)
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sqlx::query!("UPDATE user SET deleted = false where name = ?", name)
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub async fn update(&self, db: &SqlitePool, data: UserEditForm) -> Result<(), String> {
|
||||
|
@ -4,25 +4,13 @@ use rocket_dyn_templates::{context, Template};
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
use super::notification;
|
||||
use crate::{
|
||||
model::{log::Log, role::Role, user::AdminUser},
|
||||
tera::Config,
|
||||
};
|
||||
use crate::model::{log::Log, role::Role, user::AdminUser};
|
||||
|
||||
pub mod event;
|
||||
pub mod user;
|
||||
|
||||
#[get("/rss?<key>")]
|
||||
async fn rss(db: &State<SqlitePool>, key: &str, config: &State<Config>) -> String {
|
||||
if key.eq(&config.rss_key) {
|
||||
Log::generate_feed(db).await
|
||||
} else {
|
||||
"Not allowed".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/rss", rank = 2)]
|
||||
async fn show_rss(db: &State<SqlitePool>, _admin: AdminUser) -> String {
|
||||
#[get("/log")]
|
||||
async fn log(db: &State<SqlitePool>, _admin: AdminUser) -> String {
|
||||
Log::show(db).await
|
||||
}
|
||||
|
||||
@ -75,6 +63,6 @@ pub fn routes() -> Vec<Route> {
|
||||
ret.append(&mut user::routes());
|
||||
ret.append(&mut notification::routes());
|
||||
ret.append(&mut event::routes());
|
||||
ret.append(&mut routes![rss, show_rss, show_list, list]);
|
||||
ret.append(&mut routes![log, show_list, list]);
|
||||
ret
|
||||
}
|
||||
|
@ -176,22 +176,18 @@ async fn create(
|
||||
data: Form<UserAddForm<'_>>,
|
||||
admin: ManageUserUser,
|
||||
) -> Flash<Redirect> {
|
||||
if User::create(db, data.name).await {
|
||||
User::create(db, data.name).await;
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("{} created new user: {data:?}", admin.user.name),
|
||||
)
|
||||
.await;
|
||||
|
||||
Flash::success(
|
||||
Redirect::to("/admin/user"),
|
||||
"Mitglied erfolgreich angelegt!",
|
||||
)
|
||||
} else {
|
||||
Flash::error(
|
||||
Redirect::to("/admin/user"),
|
||||
format!("Mitlgied {} gibt/gab es bereits", data.name),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn routes() -> Vec<Route> {
|
||||
|
@ -80,7 +80,18 @@
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-3">
|
||||
{% for role in roles %}
|
||||
{% if not role.cluster %}
|
||||
{% if role.name == "admin" %}
|
||||
{{ macros::checkbox(label=role.name, name="roles[" ~ role.id ~ "]", id=loop.index , checked=role.name in user.roles, disabled=allowed_to_edit == false, help="Admins können Mitglieder (auf dieser Seite) verwalten") }}
|
||||
{% elif role.name == "scheckbuch" %}
|
||||
{{ macros::checkbox(label=role.name, name="roles[" ~ role.id ~ "]", id=loop.index , checked=role.name in user.roles, disabled=allowed_to_edit == false, help="Anfänger sehen nur Ausfahrten/Events, die explizit für sie ausgeschrieben wurden") }}
|
||||
{% elif role.name == "cox" %}
|
||||
{{ macros::checkbox(label=role.name, name="roles[" ~ role.id ~ "]", id=loop.index , checked=role.name in user.roles, disabled=allowed_to_edit == false, help="Steuerpersonen können selbstständig Ausfahrten ausschreiben und sich bei Events zum steuern anmelden") }}
|
||||
{% elif role.name == "manage_events" %}
|
||||
{{ macros::checkbox(label=role.name, name="roles[" ~ role.id ~ "]", id=loop.index , checked=role.name in user.roles, disabled=allowed_to_edit == false, help="Eventmanager können Events ausschreiben und bearbeiten") }}
|
||||
{% else %}
|
||||
{{ macros::checkbox(label=role.name, name="roles[" ~ role.id ~ "]", id=loop.index , checked=role.name in user.roles, disabled=allowed_to_edit == false) }}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<hr class="sm:col-span-2 lg:col-span-4 my-3" />
|
||||
|
@ -7,17 +7,17 @@
|
||||
role="alert">
|
||||
<h2 class="h2">Allgemein</h2>
|
||||
<div class="p-3">
|
||||
Die Website wird vom ASKÖ Ruderverein Donau Linz betrieben.
|
||||
Die Website wird von ruad.at betrieben.
|
||||
<br />
|
||||
<strong>Postanschrift:</strong>
|
||||
<br />
|
||||
ASKÖ Ruderverein Donau Linz
|
||||
Philipp Hofer
|
||||
<br />
|
||||
Heilhamerweg 2
|
||||
Rubinweg 8
|
||||
<br />
|
||||
4040 Linz
|
||||
4225 Luftenberg
|
||||
<br />
|
||||
ZVR: 363903285
|
||||
Mail: philipp@hofer.link
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -55,39 +55,11 @@
|
||||
<li>
|
||||
<strong>Letzter Zugriff:</strong> {{ loggedin_user.last_access }}
|
||||
</li>
|
||||
<li>
|
||||
<strong>Mitglied seit:</strong> {{ loggedin_user.member_since_date }}
|
||||
</li>
|
||||
<li>
|
||||
<strong>Geburtsdatum:</strong> {{ loggedin_user.birthdate }}
|
||||
</li>
|
||||
<li>
|
||||
<strong>Mail:</strong> {{ loggedin_user.mail }}
|
||||
</li>
|
||||
{% if loggedin_user.nickname %}
|
||||
<li>
|
||||
<strong>Spitzname:</strong> {{ loggedin_user.nickname }}
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<strong>Telefonnummer:</strong> {{ loggedin_user.phone }}
|
||||
</li>
|
||||
<li>
|
||||
<strong>Adresse:</strong> {{ loggedin_user.address }}
|
||||
</li>
|
||||
<li>(Beitrittserklärung)</li>
|
||||
{% if loggedin_user.family_id %}
|
||||
<li>Verbindung zu Familienmitglied (gespeichert um Familientarif anstatt Vollmitglied zu haben)</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<strong>Rollen:</strong> {{ loggedin_user.roles }} (werden für verschiedene Funktionen im Ruderassistenten verwendet)
|
||||
</li>
|
||||
<li>Anmeldungen zu Ausfahrten</li>
|
||||
<li>Anmeldungen zu Events (zB Fetzenfahrt, Anrudern, USI-Rudern, ...)</li>
|
||||
<li>Logbucheinträge</li>
|
||||
<li>Selber eingetragene Bootsschäden, solange sie nicht > 1 Monat verifiziert und repariert wurden</li>
|
||||
<li>Selber eingetragene Bootsreservierung</li>
|
||||
<li>Boote, sofern es welche im Privatbesitz gibt</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -103,7 +75,7 @@
|
||||
Die <strong>Wetterdaten</strong> werden von <a class="underline" href="https://openweathermap.org">OpenWeather</a> bereitgestellt.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Wasserstandsvorhersagen:</strong> Die Vorhersagen werden stündlich vom <a class="underline" href="https://hydro.ooe.gv.at">Hydrographischen Dienstes Oberösterreich</a> geladen und zwischengespeichert, der höchste Tages-Mittelwert wird gemeinsam mit der Schwankungsbreite bei den geplanten Ausfahrten angezeigt. Es handelt sich hierbei um ungeprüfte Rohdaten. Rohdatenfehler können durch betriebliche Störungen an den Messgeräten, Fernübertragungseinrichtungen u. dgl. entstehen. Die Vorhersagen sind daher mit Unsicherheiten behaftet! Mit der Länge des Vorhersagezeitraumeszeitraumes werden diese Unsicherheiten größer! Es wird keine Gewähr für die Vollständigkeit, Richtigkeit und Genauigkeit der dargestellten Daten übernommen. Gewährleistungs- und Haftungsansprüche werden ausdrücklich ausgeschlossen (sowohl vom Hydrographischen Dienstes Oberösterreich als auch vom ASKÖ Ruderverein Donau Linz).
|
||||
<strong>Wasserstandsvorhersagen:</strong> Die Vorhersagen werden stündlich vom <a class="underline" href="https://hydro.ooe.gv.at">Hydrographischen Dienstes Oberösterreich</a> geladen und zwischengespeichert, der höchste Tages-Mittelwert wird gemeinsam mit der Schwankungsbreite bei den geplanten Ausfahrten angezeigt. Es handelt sich hierbei um ungeprüfte Rohdaten. Rohdatenfehler können durch betriebliche Störungen an den Messgeräten, Fernübertragungseinrichtungen u. dgl. entstehen. Die Vorhersagen sind daher mit Unsicherheiten behaftet! Mit der Länge des Vorhersagezeitraumeszeitraumes werden diese Unsicherheiten größer! Es wird keine Gewähr für die Vollständigkeit, Richtigkeit und Genauigkeit der dargestellten Daten übernommen. Gewährleistungs- und Haftungsansprüche werden ausdrücklich ausgeschlossen (sowohl vom Hydrographischen Dienstes Oberösterreich als auch von ruad.at).
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -3,8 +3,7 @@
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<div>
|
||||
<span class="text-[#ff0000]">♥</span>
|
||||
Erstellt vom ASKÖ Ruderverein Donau Linz <a class="underline"
|
||||
onclick="alert('Wir suchen kreative und motivierte Köpfe, die diesen Ruderassistenten mitgestalten möchten. Das Backend ist in Rust (Rocket), das Frontend in TypeScript und Teraform, wobei wir mit dem Gedanken spielen, zu Svelte(Kit) zu wechseln.\n\nWenn du Lust hast, deine Skills in ein Projekt zu stecken, das Wellen schlagen wird, dann komm an Bord! Wir sind offen für frische Ideen, haben jedoch auch selber noch genügend; langweilig wird uns bestimmt nicht.\n\nWirf den Anker bei uns ausi und melde dich bei Marie oder Philipp oder it@rudernlinz.at – für eine Zukunft ohne optische Kenterung in Form von hässlichen Alerts ;)');">... und dir?</a>
|
||||
Erstellt von <a class="underline" href="https://ruad.at" target="_blank">ruad.at</a>
|
||||
</div>
|
||||
<div>
|
||||
<button id="theme-toggle-js"
|
||||
|
@ -73,10 +73,13 @@ function setChoiceByLabel(choicesInstance, label) {
|
||||
<div class="max-w-screen-xl w-full flex justify-between items-center">
|
||||
<div class="w-1/3 truncate">
|
||||
<a href="/">
|
||||
Hü
|
||||
Ahoi
|
||||
{{ loggedin_user.name }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="w-1/3 text-xl"
|
||||
onclick="document.getElementById('call-for-action').showModal()">💡</div>
|
||||
|
||||
<div class="flex items-center">
|
||||
{% if loggedin_user.amount_unread_notifications > 0 %}
|
||||
<a href="/#notification"
|
||||
@ -110,6 +113,8 @@ function setChoiceByLabel(choicesInstance, label) {
|
||||
{% if "admin" in loggedin_user.roles %}
|
||||
<a href="/admin/user"
|
||||
class="block w-100 py-2 hover:text-primary-600 border-t">Mitgliederverwaltung</a>
|
||||
<a href="/admin/log"
|
||||
class="block w-100 py-2 hover:text-primary-600 border-t">Log</a>
|
||||
{% endif %}
|
||||
<a href="/auth/logout"
|
||||
class="block w-100 py-2 hover:text-primary-600 border-t">Ausloggen
|
||||
@ -133,6 +138,78 @@ function setChoiceByLabel(choicesInstance, label) {
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<dialog id="call-for-action"
|
||||
class="max-w-screen-sm dark:bg-primary-600 dark:text-white rounded-md"
|
||||
onclick="document.getElementById('call-for-action').close()">
|
||||
<div onclick="event.stopPropagation();" class="p-3">
|
||||
<button type="button"
|
||||
onclick="document.getElementById('call-for-action').close()"
|
||||
title="Schließen"
|
||||
class="sidebar-close border-0 bg-primary-100 focus:bg-primary-50 text-black flex items-center justify-center transform rotate-45 absolute right-0 mr-3">
|
||||
<svg class="inline h-5 w-5"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16">
|
||||
<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="mt-8">
|
||||
<p class="p-2">
|
||||
Willkommen in der Testversion von ruad.at!
|
||||
Hier wird nochmal <s>alles</s> vieles erklärt.
|
||||
Wenn du Fragen/Wünsche/... hast, kannst du dich gerne jederzeit unter <a href="mailto:philipp@hofer.link">philipp@hofer.link</a> melden.
|
||||
</p>
|
||||
<details class="p-2">
|
||||
<summary>Rollen: Admin, Steuerperson, Anfänger + Eventmanager</summary>
|
||||
<p>
|
||||
Aktuell gibt es <b>4 Rollen</b>, die jedes Mitglied haben kann:
|
||||
<ol class="list-decimal p-5">
|
||||
<li><emph>Admin:</emph> dürfen Mitglieder verwalten (siehe Menüeintrag rechts oben → <q>Mitgliederverwaltung</q></li>
|
||||
<li><emph>Steuerperson:</emph> können selbstständig <q>Ausfahrten</q> ausschreiben/bearbeiten, und sich zum steuern bei <q>Events</q> melden</li>
|
||||
<li><emph>Anfänger:</emph> sehen nur Ausfahrten und Events, die explizit für Anfänger ausgeschrieben wurden</li>
|
||||
<li><emph>Eventmanager:</emph> können <q>Events</q> ausschreiben/bearbeiten</li>
|
||||
</ol>
|
||||
</p>
|
||||
</details>
|
||||
<details class="p-2">
|
||||
<summary>Rudertrips: Ausfahrten + Events</summary>
|
||||
<p class="mt-3">
|
||||
Es gibt 2 Arten von Rudertrips, die ausgeschrieben werden können:
|
||||
<ol class="list-decimal p-5">
|
||||
<li>Ausfahrten: Können jederzeit von Steuerpersonen ausgeschrieben/bearbeitet werden</li>
|
||||
<li>Events: für Veranstaltungen, wo nicht nur Rudererinnen gesucht werden, sondern auch Steuerpersonen (zB Anrudern, Abrudern, Sternfahrten, Wanderfahrten, ...)</li>
|
||||
</ol>
|
||||
</p>
|
||||
</details>
|
||||
<details class="p-2">
|
||||
<summary>Bearbeiten</summary>
|
||||
<p class="mt-3">
|
||||
Details, wie zB Anmerkungen können jederzeit geändert werden.
|
||||
Wichtige Infos, auf die sich Rudernde verlassen (zB Startzeit und Ausfahrtstyp) können nicht mehr geändert werden.
|
||||
Wenn sich die Startzeit ändert, kann man die Ausfahrt/Event absagen und stattdessen einen neuen Trip ausschreiben.
|
||||
</p>
|
||||
</details>
|
||||
<details class="p-2">
|
||||
<summary>Absagen/Löschen</summary>
|
||||
<p class="mt-3">
|
||||
Ausfahrten und Events können gelöscht werden, solange keine Ruderer angemeldet sind.
|
||||
Sobald jemand angemeldet ist, kann die Ausfahrt/Event nicht mehr gelöscht werden, dafür <q>abgesagt</q> werden.
|
||||
In diesem Fall bekommen alle die sich angemeldet haben eine Nachricht.
|
||||
Sobald alle die Nachricht gelesen haben, wird der Trip automatisch gelöscht.
|
||||
</p>
|
||||
</details>
|
||||
<details class="p-2">
|
||||
<summary>Wieviele Tage sehe ich?</summary>
|
||||
<p class="mt-3">
|
||||
Rudernde sehen alle Trips 10 Tage im voraus + zusätzlich alle, wo <q>Immer Anzeigen</q> ausgewählt wurde.
|
||||
Steuerpersonen sehen das ganze Jahr (um im Vorhinein Ausfahrten ausschreiben zu können). Ab Dezember sehen sie auch das volle kommende Jahr.
|
||||
</p>
|
||||
</details>
|
||||
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<div class="h-8"></div>
|
||||
{% endmacro header %}
|
||||
{% macro input(label, name, type, required=false, class='rounded-md', value='', min='', hide_label=false, id='', autofocus=false, wrapper_class='', pattern='', readonly=false, accept='') %}
|
||||
@ -169,7 +246,7 @@ function setChoiceByLabel(choicesInstance, label) {
|
||||
{{name}}
|
||||
{%- endif -%}
|
||||
{% endmacro fancy_role_name %}
|
||||
{% macro checkbox(label, name, id='', checked=false, class='', disabled=false, readonly=false) %}
|
||||
{% macro checkbox(label, name, id='', checked=false, class='', disabled=false, readonly=false, help=false) %}
|
||||
<label for="{{ name }}{{ id }}"
|
||||
class="flex items-center cursor-pointer text-black dark:text-white hover:text-gray-900 dark:hover:text-gray-100 {{ class }}">
|
||||
<input type="checkbox"
|
||||
@ -180,6 +257,33 @@ function setChoiceByLabel(choicesInstance, label) {
|
||||
{% if readonly %}readonly="readonly"{% endif %}
|
||||
class="h-4 w-4 accent-primary-600 dark:accent-primary-200 mr-2" />
|
||||
{{ self::fancy_role_name(name=label) }}
|
||||
{% if help %}
|
||||
<span class=""
|
||||
onclick="this.nextElementSibling.showModal()">❓</span>
|
||||
|
||||
<dialog
|
||||
class="max-w-screen-sm dark:bg-primary-600 dark:text-white rounded-md"
|
||||
onclick="this.close()">
|
||||
<div onclick="event.stopPropagation();" class="p-3">
|
||||
<button type="button"
|
||||
onclick="this.parentNode.parentNode.close()"
|
||||
title="Schließen"
|
||||
class="sidebar-close border-0 bg-primary-100 focus:bg-primary-50 text-black flex items-center justify-center transform rotate-45 absolute right-0 mr-3">
|
||||
<svg class="inline h-5 w-5"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16">
|
||||
<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="mt-8">
|
||||
<p>
|
||||
{{help}}
|
||||
</p>
|
||||
</div>
|
||||
</dialog>
|
||||
{% endif %}
|
||||
</label>
|
||||
{% endmacro checkbox %}
|
||||
{% macro select(label, data, name='trip_type', default='', id='', selected_id='', display='', extras='', class='', wrapper_class='', required=false, show_seats=false, new_last_entry='', nonSelectableDefault=false, only_ergo=false) %}
|
||||
|
@ -169,8 +169,8 @@
|
||||
{{ macros::input(label='Titel', name='name', type='input', value=event.name) }}
|
||||
{{ macros::input(label='Anzahl Ruderer', name='max_people', type='number', required=true, value=event.max_people, min='1') }}
|
||||
{{ macros::input(label='Anzahl Steuerleute', name='planned_amount_cox', type='number', value=event.planned_amount_cox, required=true, min='0') }}
|
||||
{{ macros::checkbox(label='Immer anzeigen', name='always_show', id=event.id,checked=event.always_show) }}
|
||||
{{ macros::checkbox(label='Gesperrt', name='is_locked', id=event.id,checked=event.is_locked) }}
|
||||
{{ macros::checkbox(label='Immer anzeigen', name='always_show', id=event.id,checked=event.always_show, help="Grundsätzlich sehen Rudernde Ausfahrten 10 Tage im vorhinein. Wenn du diese Option aktivierst, ist diese Ausfahrt sofort allen ersichtlich.") }}
|
||||
{{ macros::checkbox(label='Gesperrt', name='is_locked', id=event.id,checked=event.is_locked, help="Wenn diese Option aktiviert ist, kann sich keiner mehr an- und abmelden. Sinnvoll, wenn zB bereits die Bootseinteilung vorgenommen wurde") }}
|
||||
{{ macros::select(label='Typ', name='trip_type', data=trip_types, default='Reguläre Ausfahrt', selected_id=event.trip_type_id) }}
|
||||
{{ macros::input(label='Anmerkungen', name='notes', type='input', value=event.notes) }}
|
||||
<input value="Speichern" class="btn btn-primary" type="submit" />
|
||||
@ -301,7 +301,7 @@
|
||||
<form action="/cox/trip/{{ trip.id }}" method="post" class="grid gap-3">
|
||||
{{ macros::input(label='Anzahl Ruderer', name='max_people', type='number', required=true, value=trip.max_people, min=trip.rower | length) }}
|
||||
{{ macros::input(label='Anmerkungen', name='notes', type='input', value=trip.notes) }}
|
||||
{{ macros::checkbox(label='Gesperrt', name='is_locked', id=trip.id,checked=trip.is_locked) }}
|
||||
{{ macros::checkbox(label='Gesperrt', name='is_locked', id=trip.id,checked=trip.is_locked, help="Wenn diese Option aktiviert ist, kann sich keiner mehr an- und abmelden. Sinnvoll, wenn zB bereits die Bootseinteilung vorgenommen wurde") }}
|
||||
{% if loggedin_user.allowed_to_steer %}
|
||||
{{ macros::select(label='Typ', name='trip_type', data=trip_types, default='Reguläre Ausfahrt', selected_id=trip.trip_type_id, only_ergo=not loggedin_user.allowed_to_steer) }}
|
||||
{% else %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user