more external string, continue #12
This commit is contained in:
parent
1628bdc252
commit
7f354879fe
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -1126,9 +1126,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.15"
|
version = "0.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
@ -1720,9 +1720,9 @@ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
version = "0.2.11"
|
version = "0.2.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
|
checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libredox"
|
name = "libredox"
|
||||||
@ -2134,7 +2134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "1a2a4764cc1f8d961d802af27193c6f4f0124bd0e76e8393cf818e18880f0524"
|
checksum = "1a2a4764cc1f8d961d802af27193c6f4f0124bd0e76e8393cf818e18880f0524"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argon2",
|
"argon2",
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.2.16",
|
||||||
"password-hash",
|
"password-hash",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
@ -2462,7 +2462,7 @@ version = "0.6.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.2.16",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2509,7 +2509,7 @@ version = "0.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
|
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.2.16",
|
||||||
"libredox",
|
"libredox",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
]
|
]
|
||||||
@ -2586,7 +2586,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.2.16",
|
||||||
"libc",
|
"libc",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
@ -2643,8 +2643,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-i18n"
|
name = "rust-i18n"
|
||||||
version = "3.1.4"
|
version = "3.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a2b6307cde881492032919adf26e254981604a6657b339ae23cce8358e9ee203"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"globwalk",
|
"globwalk",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@ -2657,8 +2655,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-i18n-macro"
|
name = "rust-i18n-macro"
|
||||||
version = "3.1.4"
|
version = "3.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1c0dc724669fe2ddbbec5ed9daea8147a9030de87ebb46fdc7bb9315701d9912"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glob",
|
"glob",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@ -2674,8 +2670,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-i18n-support"
|
name = "rust-i18n-support"
|
||||||
version = "3.1.4"
|
version = "3.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b47501de04282525d0192c4b4133f9e3574e1fab3542ddc7bb109ff773dc108b"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"base62",
|
"base62",
|
||||||
|
@ -13,7 +13,8 @@ serde = "1.0"
|
|||||||
sqlx = { version = "0.8", features = ["sqlite", "runtime-tokio-rustls", "macros", "chrono"] }
|
sqlx = { version = "0.8", features = ["sqlite", "runtime-tokio-rustls", "macros", "chrono"] }
|
||||||
tokio = { version = "1.44", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.44", features = ["macros", "rt-multi-thread"] }
|
||||||
tower-sessions = "0.14"
|
tower-sessions = "0.14"
|
||||||
rust-i18n = "3"
|
#rust-i18n = { version = "3", features = [ "log-miss-tr" ] }
|
||||||
|
rust-i18n = { path="/home/ph/rust-i18n" }
|
||||||
thiserror = "2.0"
|
thiserror = "2.0"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
password-auth = "1.0"
|
password-auth = "1.0"
|
||||||
@ -37,3 +38,7 @@ typst-pdf = "0.13"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
axum-test = "17.3"
|
axum-test = "17.3"
|
||||||
|
|
||||||
|
[package.metadata.i18n]
|
||||||
|
available-locales = ["de-AT"]
|
||||||
|
default-locale = "de-AT"
|
||||||
|
@ -24,6 +24,7 @@ run_restarted: "Stationslauf erfolgreich wieder aufgenommen"
|
|||||||
come_home_with_these_groups: "Gruppen mitnehmen"
|
come_home_with_these_groups: "Gruppen mitnehmen"
|
||||||
station_info: "Schön, dass du uns als Stationsbetreuer hilfst."
|
station_info: "Schön, dass du uns als Stationsbetreuer hilfst."
|
||||||
info_crewless_station: "Wenn das eine unbemannte Station ist, wähle hier 0 Personen aus. Dann werden dieser Station keine Startteams zugeteilt und es wird kein PDF generiert."
|
info_crewless_station: "Wenn das eine unbemannte Station ist, wähle hier 0 Personen aus. Dann werden dieser Station keine Startteams zugeteilt und es wird kein PDF generiert."
|
||||||
|
time: "Uhrzeit"
|
||||||
|
|
||||||
#
|
#
|
||||||
# ######
|
# ######
|
||||||
@ -34,15 +35,15 @@ info_crewless_station: "Wenn das eine unbemannte Station ist, wähle hier 0 Pers
|
|||||||
# # # # ## ## # # # # # # # ## # #
|
# # # # ## ## # # # # # # # ## # #
|
||||||
# ###### ###### # # ###### # # # #### # # ####
|
# ###### ###### # # ###### # # # #### # # ####
|
||||||
#
|
#
|
||||||
rating: "Bewertung"
|
|
||||||
ratings: "Bewertungen"
|
ratings: "Bewertungen"
|
||||||
|
rate_crewless_stations: "Unbemannte Stationen bewerten"
|
||||||
invalid_rating_code: "Falscher Quick-Login-Link. Bitte nochmal scannen oder neu eingeben."
|
invalid_rating_code: "Falscher Quick-Login-Link. Bitte nochmal scannen oder neu eingeben."
|
||||||
infos: "Infos"
|
infos: "Infos"
|
||||||
station_has_no_teams_to_take_to_start: "Nachdem es offiziell losgeht kannst du gleich direkt zu deiner Station gehen, du musst keine Teams mitnehmen."
|
station_has_no_teams_to_take_to_start: "Nachdem es offiziell losgeht kannst du gleich direkt zu deiner Station gehen, du musst keine Teams mitnehmen."
|
||||||
station_should_take_one_teams_to_start: "Nachdem es offiziell losgeht, nimm bitte folgendes Team am Anfang zu deiner Station mit:"
|
station_should_take_one_teams_to_start: "Nachdem es offiziell losgeht, nimm bitte folgendes Team am Anfang zu deiner Station mit:"
|
||||||
station_should_take_n_teams_to_start: "Nachdem es offiziell losgeht, nimm bitte folgende %{amount} Teams am Anfang zu deiner Station mit:"
|
station_should_take_n_teams_to_start: "Nachdem es offiziell losgeht, nimm bitte folgende %{amount} Teams am Anfang zu deiner Station mit:"
|
||||||
your_station_is_here: "Deine Station befindet sich hier:"
|
your_station_is_here: "Deine Station befindet sich hier:"
|
||||||
station_ready: "Sobald du bei deiner Station bist und bereit zu starten bist, drücke diesen Button damit wir Bescheid wissen"
|
button_station_ready: "Sobald du bei deiner Station bist und bereit zu starten bist, drücke diesen Button damit wir Bescheid wissen"
|
||||||
station_not_yet_ready: "Bin mit der Station doch noch nicht bereit..."
|
station_not_yet_ready: "Bin mit der Station doch noch nicht bereit..."
|
||||||
one_team_should_come_to_station: "Insgesamt sollte 1 Team zu deiner Station kommen."
|
one_team_should_come_to_station: "Insgesamt sollte 1 Team zu deiner Station kommen."
|
||||||
n_teams_should_come_to_station: "Insgesamt sollten %{amount} Teams zu deiner Station kommen."
|
n_teams_should_come_to_station: "Insgesamt sollten %{amount} Teams zu deiner Station kommen."
|
||||||
@ -116,8 +117,9 @@ confirm_station_cancel_team_finished: "Bist du sicher, dass das Team noch nicht
|
|||||||
#
|
#
|
||||||
station: "Station"
|
station: "Station"
|
||||||
stations: "Stationen"
|
stations: "Stationen"
|
||||||
|
nonexisting_station: "Station mit ID %{id} existiert nicht."
|
||||||
station_url: "Stations-Link"
|
station_url: "Stations-Link"
|
||||||
station_url_info: "Diesen Link nur Betreuern der Station #{station} geben! Mit diesem Link erhält man die Berechtigung, Teams zu bewerten."
|
station_url_info: "Diesen Link nur Betreuern der Station %{station} geben! Mit diesem Link erhält man die Berechtigung, Teams zu bewerten."
|
||||||
login_link: "Login-Link"
|
login_link: "Login-Link"
|
||||||
station_name_edit: "Routennamen bearbeiten"
|
station_name_edit: "Routennamen bearbeiten"
|
||||||
go_to_stations: "Zu den Stationen"
|
go_to_stations: "Zu den Stationen"
|
||||||
@ -166,6 +168,11 @@ location_deleted: "Standort für die Station %{station} wurde erfolgreich gelös
|
|||||||
progress: "Fortschritt"
|
progress: "Fortschritt"
|
||||||
station_team_progress: "%{arrived}/%{total} (davon %{waiting} wartend + %{active} aktiv)"
|
station_team_progress: "%{arrived}/%{total} (davon %{waiting} wartend + %{active} aktiv)"
|
||||||
station_ready: "Station bereit!"
|
station_ready: "Station bereit!"
|
||||||
|
first_station: "Erste Station"
|
||||||
|
first_station_expl: "Die erste Station wird beim Anlegen eines Team automatisch an diejenige Station vergeben, die aktuell am wenigsten Startteams hat. Diese Zuteilung kannst du hier auch manuell verändern."
|
||||||
|
new_team_name: "Team %{old} heißt ab sofort %{new}"
|
||||||
|
notes_edited: "Notizen für das Team %{team} erfolgreich geändert"
|
||||||
|
amount_teammembers_edited: "Anzahl an Mitglieder für das Team %{team} erfolgreich geändert"
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -179,10 +186,39 @@ station_ready: "Station bereit!"
|
|||||||
#
|
#
|
||||||
team: "Team"
|
team: "Team"
|
||||||
teams: "Teams"
|
teams: "Teams"
|
||||||
|
nonexisting_team: "Team mit ID %{id} existiert nicht."
|
||||||
select_team: "Team auswählen"
|
select_team: "Team auswählen"
|
||||||
|
new_team: "Neues Team"
|
||||||
|
edit_teamname: "Teamname bearbeiten"
|
||||||
|
teamname: "Teamname"
|
||||||
go_to_teams: "Zu den Teams"
|
go_to_teams: "Zu den Teams"
|
||||||
not_yet_started: "nocht nicht gestartet"
|
not_yet_started: "nocht nicht gestartet"
|
||||||
not_yet_done: "nocht nicht fertig"
|
not_yet_done: "nocht nicht fertig"
|
||||||
|
team_created: "Team %{team} erstellt"
|
||||||
|
team_deleted: "Team %{team} gelöscht"
|
||||||
|
add_new_note: "Neue Notiz hinzufügen"
|
||||||
|
team_not_created_duplicate_name: "Team %{team} konnte nicht erstellt werden, da es bereits ein Team mit diesem Namen gibt (%{err})"
|
||||||
|
team_not_created_no_station_in_route: "Team %{team} konnte nicht erstellt werden, da in der angegebenen Route %{route} keine Station vorkommt und daher die Startstation nicht festgelegt werden kann."
|
||||||
|
team_not_deleted_already_in_use: "Team %{team} kann nicht gelöscht werden, da es bereits verwendet wird. (%{err})"
|
||||||
|
amount_teammembers: "Anzahl Teammitglieder"
|
||||||
|
not_sure_about_amount_team: "Ich weiß noch nicht wv. Personen dieses Team beherbergt."
|
||||||
|
select_station: "Station auswählen"
|
||||||
|
already_has_1_start_team: "schon 1 Startteam"
|
||||||
|
already_has_n_start_team: "schon %{amount} Startteams"
|
||||||
|
last_station: "Letzte Station"
|
||||||
|
route_edited: "Team %{team} läuft ab sofort die Route %{route}. Auch die erste Station hat sich dadurch auf %{first_station} verändert"
|
||||||
|
team_not_edited_route_has_no_stations: "Team %{team} kann nicht zur Route %{route} zugeteilt werden, da diese Route noch keine Station hat und daher die Startstation nicht festgelegt werden kann."
|
||||||
|
first_station_not_edited_not_on_route: "Konnte Station %{station} nicht als erste Station dem Team %{team} zuteilen, weil dieses Team bei Route %{route} mitläuft und die Station nicht auf dieser Route liegt."
|
||||||
|
last_station_not_edited_not_on_route: "Konnte Station %{station} nicht als letzte Station dem Team %{team} zuteilen, weil dieses Team bei Route %{route} mitläuft und die Station nicht auf dieser Route liegt."
|
||||||
|
changed_first_station: "Erste Station des Teams %{team} ist ab sofort Station %{station}"
|
||||||
|
changed_last_station: "Letzte Station des Teams %{team} ist ab sofort Station %{station}"
|
||||||
|
last_contact_team: "Letzter Stationskontakt der Teams"
|
||||||
|
not_yet_seen: "Noch nicht gesehen"
|
||||||
|
no_teams: "Es gibt noch keine Teams."
|
||||||
|
route_needed_before_creating_teams: "Bevor du ein Team erstellen kannst, musst du zumindest eine Route erstellen, die das Team gehen kann"
|
||||||
|
have_i_lost_groups: "Hab ich eine Gruppe verloren? 😳"
|
||||||
|
confirm_delete_team: "Bist du sicher, dass das Team gelöscht werden soll? Das kann _NICHT_ mehr rückgängig gemacht werden."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -239,8 +275,11 @@ confirm_admin_delete: "Bist du sicher, dass der User gelöscht werden soll? Das
|
|||||||
#
|
#
|
||||||
route: "Route"
|
route: "Route"
|
||||||
routes: "Routen"
|
routes: "Routen"
|
||||||
|
nonexisting_route: "Route mit ID %{id} existiert nicht."
|
||||||
route_new: "Neue Route"
|
route_new: "Neue Route"
|
||||||
route_name: "Routenname"
|
route_name: "Routenname"
|
||||||
|
create_route: "Route erstellen"
|
||||||
|
select_route: "Route auswählen"
|
||||||
route_name_edit: "Routennamen bearbeiten"
|
route_name_edit: "Routennamen bearbeiten"
|
||||||
route_has_no_station_assigned: "Keine Station zugeteilt" # should be short -> tooltip
|
route_has_no_station_assigned: "Keine Station zugeteilt" # should be short -> tooltip
|
||||||
route_confirm_deletion: "Bist du sicher, dass die Route gelöscht werden soll? Das kann _NICHT_ mehr rückgängig gemacht werden."
|
route_confirm_deletion: "Bist du sicher, dass die Route gelöscht werden soll? Das kann _NICHT_ mehr rückgängig gemacht werden."
|
||||||
@ -258,7 +297,7 @@ teams_with_this_route: "Teams mit dieser Route"
|
|||||||
no_team_with_this_route: "Noch kein Team ist dieser Route zugeteilt"
|
no_team_with_this_route: "Noch kein Team ist dieser Route zugeteilt"
|
||||||
route_update_err_nonexisting: "Route mit ID %{id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
route_update_err_nonexisting: "Route mit ID %{id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
||||||
route_new_name: "Route %{old} heißt ab sofort %{new}."
|
route_new_name: "Route %{old} heißt ab sofort %{new}."
|
||||||
route_cant_add_nonexisting_station: "Station mit ID {id} konnte nicht der Route %{route} hinzugefügt werden, da die Station nicht existiert"
|
route_cant_add_nonexisting_station: "Station mit ID %{id} konnte nicht der Route %{route} hinzugefügt werden, da die Station nicht existiert"
|
||||||
station_added_to_route: "Station %{station} wurde erfolgreich der Route %{route} hinzugefügt"
|
station_added_to_route: "Station %{station} wurde erfolgreich der Route %{route} hinzugefügt"
|
||||||
station_can_only_be_added_once_to_route: "Station %{station} kann nur 1x der Route %{route} hinzugefügt werden (%{err})"
|
station_can_only_be_added_once_to_route: "Station %{station} kann nur 1x der Route %{route} hinzugefügt werden (%{err})"
|
||||||
cant_remove_station_from_nonexisting_route: "Konnte keine Station von der Route mit ID %{id} entfernen, da diese Route nicht existiert."
|
cant_remove_station_from_nonexisting_route: "Konnte keine Station von der Route mit ID %{id} entfernen, da diese Route nicht existiert."
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use super::Route;
|
use super::Route;
|
||||||
use crate::{AppState, admin::station::Station, er, page, suc};
|
use crate::{admin::station::Station, er, page, suc, AppState};
|
||||||
use axum::{
|
use axum::{
|
||||||
Form, Router,
|
|
||||||
extract::State,
|
extract::State,
|
||||||
response::{IntoResponse, Redirect},
|
response::{IntoResponse, Redirect},
|
||||||
routing::{get, post},
|
routing::{get, post},
|
||||||
|
Form, Router,
|
||||||
};
|
};
|
||||||
use maud::{Markup, PreEscaped, html};
|
use maud::{html, Markup, PreEscaped};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -91,13 +91,12 @@ async fn delete(
|
|||||||
axum::extract::Path(id): axum::extract::Path<i64>,
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(route) = Route::find_by_id(&db, id).await else {
|
let Some(route) = Route::find_by_id(&db, id).await else {
|
||||||
er!(session, t!("route_delete_err_nonexisting"));
|
er!(session, t!("route_delete_err_nonexisting", id = id));
|
||||||
|
|
||||||
return Redirect::to("/admin/route");
|
return Redirect::to("/admin/route");
|
||||||
};
|
};
|
||||||
|
|
||||||
match route.delete(&db).await {
|
match route.delete(&db).await {
|
||||||
Ok(()) => suc!(session, t!("route_delete_succ")),
|
Ok(()) => suc!(session, t!("route_delete_succ", name = route.name)),
|
||||||
Err(e) => er!(
|
Err(e) => er!(
|
||||||
session,
|
session,
|
||||||
t!("route_delete_err_already_used", name = route.name, err = e)
|
t!("route_delete_err_already_used", name = route.name, err = e)
|
||||||
@ -113,8 +112,7 @@ async fn view(
|
|||||||
axum::extract::Path(id): axum::extract::Path<i64>,
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
) -> Result<Markup, impl IntoResponse> {
|
) -> Result<Markup, impl IntoResponse> {
|
||||||
let Some(route) = Route::find_by_id(&db, id).await else {
|
let Some(route) = Route::find_by_id(&db, id).await else {
|
||||||
er!(session, t!("route_delete_err_nonexisting"));
|
er!(session, t!("route_delete_err_nonexisting", id = id));
|
||||||
|
|
||||||
return Err(Redirect::to("/admin/route"));
|
return Err(Redirect::to("/admin/route"));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ async fn view(
|
|||||||
@if !station.crewless() {
|
@if !station.crewless() {
|
||||||
tr {
|
tr {
|
||||||
th scope="row" {
|
th scope="row" {
|
||||||
(t!("station_link"))
|
(t!("station_url"))
|
||||||
article class="warning" {
|
article class="warning" {
|
||||||
(t!("station_url_info", station=station.name))
|
(t!("station_url_info", station=station.name))
|
||||||
}
|
}
|
||||||
@ -584,7 +584,7 @@ async fn update_location_clear(
|
|||||||
|
|
||||||
station.update_location_clear(&db).await;
|
station.update_location_clear(&db).await;
|
||||||
|
|
||||||
suc!(session, t!("location_changed", station = station.name));
|
suc!(session, t!("location_deleted", station = station.name));
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/station/{id}"))
|
Redirect::to(&format!("/admin/station/{id}"))
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use super::{CreateError, LastContactTeam, Team};
|
use super::{CreateError, LastContactTeam, Team};
|
||||||
use crate::{
|
use crate::{
|
||||||
admin::{route::Route, station::Station},
|
admin::{route::Route, station::Station},
|
||||||
err,
|
er,
|
||||||
models::rating::Rating,
|
models::rating::Rating,
|
||||||
partials::page,
|
partials::page,
|
||||||
pl, succ, AppState,
|
suc, AppState,
|
||||||
};
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::State,
|
extract::State,
|
||||||
@ -30,36 +30,32 @@ async fn create(
|
|||||||
Form(form): Form<CreateForm>,
|
Form(form): Form<CreateForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(route) = Route::find_by_id(&db, form.route_id).await else {
|
let Some(route) = Route::find_by_id(&db, form.route_id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_route", id = form.route_id));
|
||||||
session,
|
|
||||||
"Team mit {} konnte nicht erstellt werden, da keine Route mit ID {} existiert",
|
|
||||||
form.name,
|
|
||||||
form.route_id
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
};
|
};
|
||||||
|
|
||||||
let id = match Team::create(&db, &form.name, &route).await {
|
let id = match Team::create(&db, &form.name, &route).await {
|
||||||
Ok(id) => {
|
Ok(id) => {
|
||||||
succ!(session, "Team '{}' erfolgreich erstellt!", form.name);
|
suc!(session, t!("team_created", team = form.name));
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
Err(CreateError::DuplicateName(e)) => {
|
Err(CreateError::DuplicateName(e)) => {
|
||||||
err!(
|
er!(
|
||||||
session,
|
session,
|
||||||
"Team '{}' konnte _NICHT_ erstellt werden, da es bereits ein Team mit diesem Namen gibt ({e})!",
|
t!("team_not_created_duplicate_name", team = form.name, err = e)
|
||||||
form.name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
}
|
}
|
||||||
Err(CreateError::NoStationForRoute) => {
|
Err(CreateError::NoStationForRoute) => {
|
||||||
err!(
|
er!(
|
||||||
session,
|
session,
|
||||||
"Team '{}' konnte _NICHT_ erstellt werden, da in der angegebenen Route '{}' noch keine Stationen vorkommen",
|
t!(
|
||||||
form.name,
|
"team_not_created_no_station_in_route",
|
||||||
route.name
|
team = form.name,
|
||||||
|
route = route.name
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
@ -75,20 +71,15 @@ async fn delete(
|
|||||||
axum::extract::Path(id): axum::extract::Path<i64>,
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht gelöscht werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
};
|
};
|
||||||
|
|
||||||
match team.delete(&db).await {
|
match team.delete(&db).await {
|
||||||
Ok(()) => succ!(session, "Team '{}' erfolgreich gelöscht!", team.name),
|
Ok(()) => suc!(session, t!("team_deleted", team = team.name)),
|
||||||
Err(e) => err!(
|
Err(e) => er!(
|
||||||
session,
|
session,
|
||||||
"Team '{}' kann nicht gelöscht werden, da sie bereits verwendet wird. ({e})",
|
t!("team_not_deleted_already_in_use", team = team.name, err = e)
|
||||||
team.name
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,15 +90,19 @@ async fn quick(db: Arc<SqlitePool>, team: &Team, stations: Vec<Station>, redirec
|
|||||||
html! {
|
html! {
|
||||||
h1 {
|
h1 {
|
||||||
a href=(format!("/admin/team/{}", team.id)) { "↩️" }
|
a href=(format!("/admin/team/{}", team.id)) { "↩️" }
|
||||||
"Bewertungen Team " (team.name)
|
(t!("ratings"))
|
||||||
|
" "
|
||||||
|
(t!("team"))
|
||||||
|
" "
|
||||||
|
(team.name)
|
||||||
}
|
}
|
||||||
form action=(format!("/admin/team/{}/quick", team.id)) method="post" {
|
form action=(format!("/admin/team/{}/quick", team.id)) method="post" {
|
||||||
input type="hidden" name="redirect" value=(redirect);
|
input type="hidden" name="redirect" value=(redirect);
|
||||||
table {
|
table {
|
||||||
thead {
|
thead {
|
||||||
tr {
|
tr {
|
||||||
th { "Station" }
|
th { (t!("station")) }
|
||||||
th { "Punkte" }
|
th { (t!("points")) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tbody {
|
tbody {
|
||||||
@ -122,11 +117,11 @@ async fn quick(db: Arc<SqlitePool>, team: &Team, stations: Vec<Station>, redirec
|
|||||||
@if let Some(rating) = Rating::find_by_team_and_station(&db, team, station).await {
|
@if let Some(rating) = Rating::find_by_team_and_station(&db, team, station).await {
|
||||||
a href=(format!("/s/{}/{}", station.id, station.pw)){
|
a href=(format!("/s/{}/{}", station.id, station.pw)){
|
||||||
@if let Some(points) = rating.points {
|
@if let Some(points) = rating.points {
|
||||||
em data-tooltip="Schon eingetragen" {
|
em data-tooltip=(t!("already_entered")) {
|
||||||
(points)
|
(points)
|
||||||
}
|
}
|
||||||
} @else {
|
} @else {
|
||||||
em data-tooltip="Team gerade bei Station" { "?" }
|
em data-tooltip=(t!("team_currently_at_station")) { "?" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} @else {
|
} @else {
|
||||||
@ -138,7 +133,7 @@ async fn quick(db: Arc<SqlitePool>, team: &Team, stations: Vec<Station>, redirec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input type="submit" value="Speichern";
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,11 +143,7 @@ async fn quick_crewless(
|
|||||||
axum::extract::Path(id): axum::extract::Path<i64>,
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
) -> Result<Markup, impl IntoResponse> {
|
) -> Result<Markup, impl IntoResponse> {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Err(Redirect::to("/admin/team"));
|
return Err(Redirect::to("/admin/team"));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -169,11 +160,7 @@ async fn quick_all(
|
|||||||
axum::extract::Path(id): axum::extract::Path<i64>,
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
) -> Result<Markup, impl IntoResponse> {
|
) -> Result<Markup, impl IntoResponse> {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Err(Redirect::to("/admin/team"));
|
return Err(Redirect::to("/admin/team"));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -197,11 +184,7 @@ async fn quick_post(
|
|||||||
Form(form): Form<QuickUpdate>,
|
Form(form): Form<QuickUpdate>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -231,7 +214,13 @@ async fn quick_post(
|
|||||||
.await
|
.await
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
ret.push_str(&format!("Skipped rating for station {} because this station already has a rating for team {}", station.name, team.name));
|
let msg: String = t!(
|
||||||
|
"error_rating_team_already_rated",
|
||||||
|
team = team.name,
|
||||||
|
station = station.name
|
||||||
|
)
|
||||||
|
.into();
|
||||||
|
ret.push_str(&msg);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,12 +234,9 @@ async fn quick_post(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if amount_succ == 0 {
|
if amount_succ == 0 {
|
||||||
succ!(
|
suc!(session, t!("funny_you_entered_no_rating"));
|
||||||
session,
|
|
||||||
"Du hast keine Bewertungen eingegeben... Spaßvogel!"
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
succ!(session, "Erfolgreich {amount_succ} Bewertungen eingetragen");
|
suc!(session, t!("entered_n_ratings", amount = amount_succ));
|
||||||
}
|
}
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/team/{id}/quick{}", form.redirect))
|
Redirect::to(&format!("/admin/team/{id}/quick{}", form.redirect))
|
||||||
@ -262,11 +248,7 @@ async fn view(
|
|||||||
axum::extract::Path(id): axum::extract::Path<i64>,
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
) -> Result<Markup, impl IntoResponse> {
|
) -> Result<Markup, impl IntoResponse> {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Err(Redirect::to("/admin/team"));
|
return Err(Redirect::to("/admin/team"));
|
||||||
};
|
};
|
||||||
let first_station = team.first_station(&db).await;
|
let first_station = team.first_station(&db).await;
|
||||||
@ -279,14 +261,19 @@ async fn view(
|
|||||||
let content = html! {
|
let content = html! {
|
||||||
h1 {
|
h1 {
|
||||||
a href="/admin/team" { "↩️" }
|
a href="/admin/team" { "↩️" }
|
||||||
"Team " (team.name)
|
(t!("team"))
|
||||||
|
" "
|
||||||
|
(team.name)
|
||||||
}
|
}
|
||||||
article {
|
article {
|
||||||
details {
|
details {
|
||||||
summary { "Teamnamen bearbeiten ✏️" }
|
summary {
|
||||||
|
(t!("edit_teamname"))
|
||||||
|
" ✏️"
|
||||||
|
}
|
||||||
form action=(format!("/admin/team/{}/name", team.id)) method="post" {
|
form action=(format!("/admin/team/{}/name", team.id)) method="post" {
|
||||||
input type="text" name="name" value=(team.name) required;
|
input type="text" name="name" value=(team.name) required;
|
||||||
input type="submit" value="Speichern";
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -294,7 +281,7 @@ async fn view(
|
|||||||
table {
|
table {
|
||||||
tbody {
|
tbody {
|
||||||
tr {
|
tr {
|
||||||
th scope="row" { "Notizen" };
|
th scope="row" { (t!("notes")) };
|
||||||
td {
|
td {
|
||||||
@match &team.notes {
|
@match &team.notes {
|
||||||
Some(notes) => {
|
Some(notes) => {
|
||||||
@ -303,22 +290,22 @@ async fn view(
|
|||||||
summary { "✏️" }
|
summary { "✏️" }
|
||||||
form action=(format!("/admin/team/{}/notes", team.id)) method="post" {
|
form action=(format!("/admin/team/{}/notes", team.id)) method="post" {
|
||||||
textarea name="notes" required rows="10" { (notes) };
|
textarea name="notes" required rows="10" { (notes) };
|
||||||
input type="submit" value="Speichern";
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => details {
|
None => details {
|
||||||
summary { "Neue Notiz hinzufügen" }
|
summary { (t!("add_new_note")) }
|
||||||
form action=(format!("/admin/team/{}/notes", team.id)) method="post" {
|
form action=(format!("/admin/team/{}/notes", team.id)) method="post" {
|
||||||
textarea name="notes" required rows="10" {};
|
textarea name="notes" required rows="10" {};
|
||||||
input type="submit" value="Speichern";
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tr {
|
tr {
|
||||||
th scope="row" { "Anzahl Teammitglieder" };
|
th scope="row" { (t!("amount_teammembers")) };
|
||||||
td {
|
td {
|
||||||
@match team.amount_people {
|
@match team.amount_people {
|
||||||
Some(amount) => (amount),
|
Some(amount) => (amount),
|
||||||
@ -328,11 +315,11 @@ async fn view(
|
|||||||
summary { "✏️" }
|
summary { "✏️" }
|
||||||
form action=(format!("/admin/team/{}/amount-people", team.id)) method="post" {
|
form action=(format!("/admin/team/{}/amount-people", team.id)) method="post" {
|
||||||
input type="number" name="amount_people" min="0" max="10";
|
input type="number" name="amount_people" min="0" max="10";
|
||||||
input type="submit" value="Speichern";
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
a href=(format!("/admin/team/{}/amount-people-reset", team.id)) {
|
a href=(format!("/admin/team/{}/amount-people-reset", team.id)) {
|
||||||
button class="error" {
|
button class="error" {
|
||||||
em data-tooltip="Ich weiß noch nicht wv. Personen dieses Team beherbergt." {
|
em data-tooltip=(t!("not_sure_about_amount_team")) {
|
||||||
"?"
|
"?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -341,7 +328,7 @@ async fn view(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tr {
|
tr {
|
||||||
th scope="row" { "Route" };
|
th scope="row" { (t!("route")) };
|
||||||
td {
|
td {
|
||||||
a href=(format!("/admin/route/{}", &team.route(&db).await.id)) {
|
a href=(format!("/admin/route/{}", &team.route(&db).await.id)) {
|
||||||
(&team.route(&db).await.name)
|
(&team.route(&db).await.name)
|
||||||
@ -350,7 +337,7 @@ async fn view(
|
|||||||
details {
|
details {
|
||||||
summary { "✏️" }
|
summary { "✏️" }
|
||||||
form action=(format!("/admin/team/{}/update-route", team.id)) method="post" {
|
form action=(format!("/admin/team/{}/update-route", team.id)) method="post" {
|
||||||
select name="route_id" aria-label="Route auswählen" required {
|
select name="route_id" aria-label=(t!("select_route")) required {
|
||||||
@for route in &routes {
|
@for route in &routes {
|
||||||
@if route.id != team.route(&db).await.id {
|
@if route.id != team.route(&db).await.id {
|
||||||
option value=(route.id) {
|
option value=(route.id) {
|
||||||
@ -359,7 +346,7 @@ async fn view(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input type="submit" value="Team speichern";
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,9 +354,9 @@ async fn view(
|
|||||||
}
|
}
|
||||||
tr {
|
tr {
|
||||||
th scope="row" {
|
th scope="row" {
|
||||||
"Erste Station"
|
(t!("first_station"))
|
||||||
article {
|
article {
|
||||||
"Die erste Station wird beim Anlegen eines Team automatisch an diejenige Station vergeben, die aktuell am wenigsten Startteams hat. Diese Zuteilung kannst du hier auch manuell verändern."
|
(t!("first_station_expl"))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
td {
|
td {
|
||||||
@ -380,20 +367,24 @@ async fn view(
|
|||||||
details {
|
details {
|
||||||
summary { "✏️" }
|
summary { "✏️" }
|
||||||
form action=(format!("/admin/team/{}/update-first-station", team.id)) method="post" {
|
form action=(format!("/admin/team/{}/update-first-station", team.id)) method="post" {
|
||||||
select name="first_station_id" aria-label="Station auswählen" required {
|
select name="first_station_id" aria-label=(t!("select_station")) required {
|
||||||
@for station in &stations {
|
@for station in &stations {
|
||||||
@if station.id != first_station.id {
|
@if station.id != first_station.id {
|
||||||
option value=(station.id) {
|
option value=(station.id) {
|
||||||
(station.name)
|
(station.name)
|
||||||
@let amount_start_teams = Team::all_with_first_station(&db, station).await.len();
|
@let amount_start_teams = Team::all_with_first_station(&db, station).await.len();
|
||||||
@if amount_start_teams > 0 {
|
@if amount_start_teams > 0 {
|
||||||
(format!(" (schon {amount_start_teams} {})", pl(amount_start_teams, "Startteam", "s")))
|
@if amount_start_teams == 1 {
|
||||||
|
(t!("already_has_1_start_team"))
|
||||||
|
}@else{
|
||||||
|
(t!("already_has_n_start_team", amount=amount_start_teams))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input type="submit" value="Station speichern";
|
}
|
||||||
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -402,7 +393,7 @@ async fn view(
|
|||||||
@if let Some(last_station) = last_station {
|
@if let Some(last_station) = last_station {
|
||||||
tr {
|
tr {
|
||||||
th scope="row" {
|
th scope="row" {
|
||||||
"Letzte Station"
|
(t!("last_station"))
|
||||||
};
|
};
|
||||||
td {
|
td {
|
||||||
a href=(format!("/admin/station/{}", last_station.id)) {
|
a href=(format!("/admin/station/{}", last_station.id)) {
|
||||||
@ -412,7 +403,7 @@ async fn view(
|
|||||||
details {
|
details {
|
||||||
summary { "✏️" }
|
summary { "✏️" }
|
||||||
form action=(format!("/admin/team/{}/update-last-station", team.id)) method="post" {
|
form action=(format!("/admin/team/{}/update-last-station", team.id)) method="post" {
|
||||||
select name="last_station_id" aria-label="Station auswählen" required {
|
select name="last_station_id" aria-label=(t!("select_station")) required {
|
||||||
@for station in &stations {
|
@for station in &stations {
|
||||||
@if station.id != last_station.id {
|
@if station.id != last_station.id {
|
||||||
option value=(station.id) {
|
option value=(station.id) {
|
||||||
@ -421,7 +412,7 @@ async fn view(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input type="submit" value="Station speichern";
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -433,13 +424,13 @@ async fn view(
|
|||||||
}
|
}
|
||||||
a href=(format!("/admin/team/{}/quick", team.id)){
|
a href=(format!("/admin/team/{}/quick", team.id)){
|
||||||
button {
|
button {
|
||||||
"Bewertungen"
|
(t!("ratings"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hr;
|
hr;
|
||||||
a href=(format!("/admin/team/{}/quick/crewless", team.id)){
|
a href=(format!("/admin/team/{}/quick/crewless", team.id)){
|
||||||
button {
|
button {
|
||||||
"Unbemannte Bewertungen"
|
(t!("rate_crewless_stations"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -457,21 +448,15 @@ async fn update_name(
|
|||||||
Form(form): Form<UpdateNameForm>,
|
Form(form): Form<UpdateNameForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
};
|
};
|
||||||
|
|
||||||
team.update_name(&db, &form.name).await;
|
team.update_name(&db, &form.name).await;
|
||||||
|
|
||||||
succ!(
|
suc!(
|
||||||
session,
|
session,
|
||||||
"Team '{}' heißt ab sofort '{}'.",
|
t!("new_team_name", old = team.name, new = form.name)
|
||||||
team.name,
|
|
||||||
form.name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/team/{id}"))
|
Redirect::to(&format!("/admin/team/{id}"))
|
||||||
@ -488,21 +473,13 @@ async fn update_notes(
|
|||||||
Form(form): Form<UpdateNotesForm>,
|
Form(form): Form<UpdateNotesForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
};
|
};
|
||||||
|
|
||||||
team.update_notes(&db, &form.notes).await;
|
team.update_notes(&db, &form.notes).await;
|
||||||
|
|
||||||
succ!(
|
suc!(session, t!("notes_edited", team = team.name));
|
||||||
session,
|
|
||||||
"Notizen für das Team '{}' wurden erfolgreich bearbeitet!",
|
|
||||||
team.name
|
|
||||||
);
|
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/team/{id}"))
|
Redirect::to(&format!("/admin/team/{id}"))
|
||||||
}
|
}
|
||||||
@ -518,21 +495,13 @@ async fn update_amount_people(
|
|||||||
Form(form): Form<UpdateAmountPeopleForm>,
|
Form(form): Form<UpdateAmountPeopleForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
};
|
};
|
||||||
|
|
||||||
team.update_amount_people(&db, form.amount_people).await;
|
team.update_amount_people(&db, form.amount_people).await;
|
||||||
|
|
||||||
succ!(
|
suc!(session, t!("amount_teammembers_edited", team = team.name));
|
||||||
session,
|
|
||||||
"Anzahl an Mitglieder für das Team '{}' wurden erfolgreich bearbeitet!",
|
|
||||||
team.name
|
|
||||||
);
|
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/team/{id}"))
|
Redirect::to(&format!("/admin/team/{id}"))
|
||||||
}
|
}
|
||||||
@ -549,38 +518,32 @@ async fn update_route(
|
|||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
// TODO: move sanity checks into mod.rs
|
// TODO: move sanity checks into mod.rs
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(route) = Route::find_by_id(&db, form.route_id).await else {
|
let Some(route) = Route::find_by_id(&db, form.route_id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_route", id = form.route_id));
|
||||||
session,
|
|
||||||
"Konnte Team mit ID {id} konnte nicht zur Route mit ID {} bearbeiten, da diese Route nicht existiert.",
|
|
||||||
form.route_id
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to(&format!("/admin/team/{id}"));
|
return Redirect::to(&format!("/admin/team/{id}"));
|
||||||
};
|
};
|
||||||
|
|
||||||
match team.update_route(&db, &route).await {
|
match team.update_route(&db, &route).await {
|
||||||
Ok(new_first_station_name) => succ!(
|
Ok(new_first_station_name) => suc!(
|
||||||
session,
|
session,
|
||||||
"Team '{}' läuft ab sofort die Route '{}'. Auch die erste Station hat sich dadurch auf {} verändert!!",
|
t!(
|
||||||
team.name,
|
"route_edited",
|
||||||
route.name,
|
team = team.name,
|
||||||
new_first_station_name
|
route = route.name,
|
||||||
|
first_station = new_first_station_name
|
||||||
|
)
|
||||||
),
|
),
|
||||||
Err(()) => err!(
|
Err(()) => er!(
|
||||||
session,
|
session,
|
||||||
"Konnte für das Team {} nicht die Route {} auswählen, da Route {} keine Stationen zugeteilt hat.",
|
t!(
|
||||||
team.name,
|
"team_not_edited_route_has_no_stations",
|
||||||
route.name,
|
team = team.name,
|
||||||
route.name
|
route = route.name
|
||||||
|
)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,33 +561,28 @@ async fn update_first_station(
|
|||||||
Form(form): Form<UpdateFirstStationForm>,
|
Form(form): Form<UpdateFirstStationForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(station) = Station::find_by_id(&db, form.first_station_id).await else {
|
let Some(station) = Station::find_by_id(&db, form.first_station_id).await else {
|
||||||
err!(
|
er!(
|
||||||
session,
|
session,
|
||||||
"Konnte die erste Station (ID={}) des Teams mit ID {} nicht bearbeiten, da diese Station nicht existiert.",
|
t!("nonexisting_station", id = form.first_station_id)
|
||||||
form.first_station_id,
|
|
||||||
team.id
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return Redirect::to(&format!("/admin/team/{id}"));
|
return Redirect::to(&format!("/admin/team/{id}"));
|
||||||
};
|
};
|
||||||
|
|
||||||
if !station.is_in_route(&db, &team.route(&db).await).await {
|
if !station.is_in_route(&db, &team.route(&db).await).await {
|
||||||
err!(
|
er!(
|
||||||
session,
|
session,
|
||||||
"Konnte Station {} nicht dem Team {} hinzufügen, weil dieses Team bei Route {} und nicht bei Route {} mitläuft.",
|
t!(
|
||||||
station.name,
|
"first_station_not_edited_not_on_route",
|
||||||
team.name,
|
station = station.name,
|
||||||
team.route(&db).await.name,
|
team = team.name,
|
||||||
team.name
|
route = team.route(&db).await.name
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return Redirect::to(&format!("/admin/team/{id}"));
|
return Redirect::to(&format!("/admin/team/{id}"));
|
||||||
@ -632,11 +590,13 @@ async fn update_first_station(
|
|||||||
|
|
||||||
team.update_first_station(&db, &station).await;
|
team.update_first_station(&db, &station).await;
|
||||||
|
|
||||||
succ!(
|
suc!(
|
||||||
session,
|
session,
|
||||||
"Erste Station des Teams {} ist ab sofort {}",
|
t!(
|
||||||
team.name,
|
"changed_first_station",
|
||||||
station.name
|
team = team.name,
|
||||||
|
station = station.name
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/team/{id}"))
|
Redirect::to(&format!("/admin/team/{id}"))
|
||||||
@ -653,33 +613,27 @@ async fn update_last_station(
|
|||||||
Form(form): Form<UpdateLastStationForm>,
|
Form(form): Form<UpdateLastStationForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(station) = Station::find_by_id(&db, form.last_station_id).await else {
|
let Some(station) = Station::find_by_id(&db, form.last_station_id).await else {
|
||||||
err!(
|
er!(
|
||||||
session,
|
session,
|
||||||
"Konnte die letzte Station (ID={}) des Teams mit ID {} nicht bearbeiten, da diese Station nicht existiert.",
|
t!("nonexisting_station", id = form.last_station_id)
|
||||||
form.last_station_id,
|
|
||||||
team.id
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return Redirect::to(&format!("/admin/team/{id}"));
|
return Redirect::to(&format!("/admin/team/{id}"));
|
||||||
};
|
};
|
||||||
|
|
||||||
if !station.is_in_route(&db, &team.route(&db).await).await {
|
if !station.is_in_route(&db, &team.route(&db).await).await {
|
||||||
err!(
|
er!(
|
||||||
session,
|
session,
|
||||||
"Konnte Station {} nicht dem Team {} hinzufügen, weil dieses Team bei Route {} und nicht bei Route {} mitläuft.",
|
t!(
|
||||||
station.name,
|
"last_station_not_edited_not_on_route",
|
||||||
team.name,
|
station = station.name,
|
||||||
team.route(&db).await.name,
|
team = team.name,
|
||||||
team.name
|
route = team.route(&db).await.name
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return Redirect::to(&format!("/admin/team/{id}"));
|
return Redirect::to(&format!("/admin/team/{id}"));
|
||||||
@ -687,11 +641,13 @@ async fn update_last_station(
|
|||||||
|
|
||||||
team.update_last_station(&db, &station).await;
|
team.update_last_station(&db, &station).await;
|
||||||
|
|
||||||
succ!(
|
suc!(
|
||||||
session,
|
session,
|
||||||
"Letzte Station des Teams {} ist ab sofort {}",
|
t!(
|
||||||
team.name,
|
"changed_last_station",
|
||||||
station.name
|
team = team.name,
|
||||||
|
station = station.name
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/team/{id}"))
|
Redirect::to(&format!("/admin/team/{id}"))
|
||||||
@ -703,21 +659,13 @@ async fn update_amount_people_reset(
|
|||||||
axum::extract::Path(id): axum::extract::Path<i64>,
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(team) = Team::find_by_id(&db, id).await else {
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_team", id = id));
|
||||||
session,
|
|
||||||
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/team");
|
return Redirect::to("/admin/team");
|
||||||
};
|
};
|
||||||
|
|
||||||
team.update_amount_people_reset(&db).await;
|
team.update_amount_people_reset(&db).await;
|
||||||
|
|
||||||
succ!(
|
suc!(session, t!("amount_teammembers_edited", team = team.name));
|
||||||
session,
|
|
||||||
"Anzahl an Mitglieder für das Team '{}' wurden erfolgreich bearbeitet!",
|
|
||||||
team.name
|
|
||||||
);
|
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/team/{id}"))
|
Redirect::to(&format!("/admin/team/{id}"))
|
||||||
}
|
}
|
||||||
@ -728,15 +676,15 @@ async fn lost(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
let content = html! {
|
let content = html! {
|
||||||
h1 {
|
h1 {
|
||||||
a href="/admin/team" { "↩️" }
|
a href="/admin/team" { "↩️" }
|
||||||
"Teams: Letzter Kontakt"
|
(t!("last_contact_team"))
|
||||||
}
|
}
|
||||||
div class="overflow-auto" {
|
div class="overflow-auto" {
|
||||||
table {
|
table {
|
||||||
thead {
|
thead {
|
||||||
tr {
|
tr {
|
||||||
td { "Gruppe" }
|
td { (t!("team")) }
|
||||||
td { "Uhrzeit" }
|
td { (t!("time")) }
|
||||||
td { "Station" }
|
td { (t!("station")) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tbody {
|
tbody {
|
||||||
@ -751,7 +699,7 @@ async fn lost(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
@if let Some(time) = lost.local_last_contact() {
|
@if let Some(time) = lost.local_last_contact() {
|
||||||
(time)
|
(time)
|
||||||
}@else{
|
}@else{
|
||||||
"Noch nicht gesehen"
|
(t!("not_yet_seen"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
td {
|
td {
|
||||||
@ -760,7 +708,7 @@ async fn lost(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
(station.name)
|
(station.name)
|
||||||
}
|
}
|
||||||
}@else{
|
}@else{
|
||||||
"Noch nicht gesehen"
|
(t!("not_yet_seen"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -780,10 +728,10 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
let content = html! {
|
let content = html! {
|
||||||
h1 {
|
h1 {
|
||||||
a href="/admin" { "↩️" }
|
a href="/admin" { "↩️" }
|
||||||
"Teams"
|
(t!("teams"))
|
||||||
}
|
}
|
||||||
article {
|
article {
|
||||||
em { "Teams " }
|
em { (t!("teams")) }
|
||||||
"sind eine Menge an Personen, die verschiedene "
|
"sind eine Menge an Personen, die verschiedene "
|
||||||
a href="/admin/station" { "Stationen" }
|
a href="/admin/station" { "Stationen" }
|
||||||
" ablaufen. Welche Stationen, entscheidet sich je nachdem, welcher "
|
" ablaufen. Welche Stationen, entscheidet sich je nachdem, welcher "
|
||||||
@ -792,46 +740,47 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
}
|
}
|
||||||
@if teams.is_empty() {
|
@if teams.is_empty() {
|
||||||
article class="warning" {
|
article class="warning" {
|
||||||
"Es gibt noch keine Teams. "
|
(t!("no_teams"))
|
||||||
@if !routes.is_empty() {
|
@if !routes.is_empty() {
|
||||||
"Das kannst du hier ändern ⤵️"
|
(t!("change_that_below"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
article {
|
article {
|
||||||
h2 { "Neues Team" }
|
h2 { (t!("new_team")) }
|
||||||
@if routes.is_empty() {
|
@if routes.is_empty() {
|
||||||
article class="error" {
|
article class="error" {
|
||||||
(PreEscaped("Bevor du ein Team erstellen kannst, musst du zumindest eine Route erstellen, die das Team gehen kann → "))
|
(t!("route_needed_before_creating_teams"))
|
||||||
|
(PreEscaped(" → "))
|
||||||
a role="button" href="/admin/route" {
|
a role="button" href="/admin/route" {
|
||||||
"Route erstellen"
|
(t!("create_route"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} @else {
|
} @else {
|
||||||
form action="/admin/team" method="post" {
|
form action="/admin/team" method="post" {
|
||||||
@if routes.len() == 1 {
|
@if routes.len() == 1 {
|
||||||
fieldset role="group" {
|
fieldset role="group" {
|
||||||
input type="text" name="name" placeholder="Teamnamen" required;
|
input type="text" name="name" placeholder=(t!("teamname")) required;
|
||||||
input type="hidden" name="route_id" value=(routes[0].id) ;
|
input type="hidden" name="route_id" value=(routes[0].id) ;
|
||||||
input type="submit" value="Neues Team";
|
input type="submit" value="Neues Team";
|
||||||
}
|
}
|
||||||
} @else {
|
} @else {
|
||||||
input type="text" name="name" placeholder="Teamnamen" required;
|
input type="text" name="name" placeholder=(t!("teamname")) required;
|
||||||
select name="route_id" aria-label="Route auswählen" required {
|
select name="route_id" aria-label=(t!("select_route")) required {
|
||||||
@for route in &routes {
|
@for route in &routes {
|
||||||
option value=(route.id) {
|
option value=(route.id) {
|
||||||
(route.name)
|
(route.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input type="submit" value="Neues Team";
|
input type="submit" value=(t!("new_team"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a href="/admin/team/lost" {
|
a href="/admin/team/lost" {
|
||||||
button class="outline" {
|
button class="outline" {
|
||||||
"Hab ich eine Gruppe verloren? 😳"
|
(t!("have_i_lost_groups"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@for route in &routes {
|
@for route in &routes {
|
||||||
@ -843,7 +792,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
(team.name)
|
(team.name)
|
||||||
}
|
}
|
||||||
a href=(format!("/admin/team/{}/delete", team.id))
|
a href=(format!("/admin/team/{}/delete", team.id))
|
||||||
onclick="return confirm('Bist du sicher, dass das Team gelöscht werden soll? Das kann _NICHT_ mehr rückgängig gemacht werden.');" {
|
onclick=(format!("return confirm('{}');", t!("confirm_delete_team"))) {
|
||||||
"🗑️"
|
"🗑️"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ async fn create(
|
|||||||
id
|
id
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
er!(session, t!("user_create_err", err = e));
|
er!(session, t!("user_create_error", name = form.name, err = e));
|
||||||
|
|
||||||
return Redirect::to("/admin/user");
|
return Redirect::to("/admin/user");
|
||||||
}
|
}
|
||||||
@ -48,12 +48,12 @@ async fn delete(
|
|||||||
};
|
};
|
||||||
|
|
||||||
match user.delete(&db).await {
|
match user.delete(&db).await {
|
||||||
Ok(()) => suc!(session, t!("user_deleted", user = user.name)),
|
Ok(()) => suc!(session, t!("user_deleted", name = user.name)),
|
||||||
Err(e) => er!(
|
Err(e) => er!(
|
||||||
session,
|
session,
|
||||||
t!(
|
t!(
|
||||||
"user_delete_error_already_in_use",
|
"user_delete_error_already_in_use",
|
||||||
user = user.name,
|
name = user.name,
|
||||||
err = e
|
err = e
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
10
src/lib.rs
10
src/lib.rs
@ -48,14 +48,6 @@ pub fn url() -> String {
|
|||||||
env::var("URL").unwrap()
|
env::var("URL").unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn pl(amount: usize, single: &str, append: &str) -> String {
|
|
||||||
if amount == 1 {
|
|
||||||
single.into()
|
|
||||||
} else {
|
|
||||||
format!("{single}{append}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! err {
|
macro_rules! err {
|
||||||
($session:expr, $fmt:expr $(, $arg:expr)*) => {
|
($session:expr, $fmt:expr $(, $arg:expr)*) => {
|
||||||
@ -201,7 +193,7 @@ async fn set_pw(
|
|||||||
if correct_code != code {
|
if correct_code != code {
|
||||||
er!(
|
er!(
|
||||||
session,
|
session,
|
||||||
t!("cant_updaet_pw_with_wrong_code", user = user.name)
|
t!("cant_update_pw_with_wrong_code", user = user.name)
|
||||||
);
|
);
|
||||||
return Err(Redirect::to("/"));
|
return Err(Redirect::to("/"));
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ async fn view(
|
|||||||
@if station.ready {
|
@if station.ready {
|
||||||
(t!("station_not_yet_ready"))
|
(t!("station_not_yet_ready"))
|
||||||
} @else {
|
} @else {
|
||||||
button { (t!("station_ready")) }
|
button { (t!("button_station_ready")) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -512,7 +512,7 @@ async fn team_finished(
|
|||||||
};
|
};
|
||||||
|
|
||||||
match station.team_finished(&db, &team).await {
|
match station.team_finished(&db, &team).await {
|
||||||
Ok(()) => suc!(session, t!("team_added_to_finished")),
|
Ok(()) => suc!(session, t!("team_added_to_finished", team = team.name)),
|
||||||
Err(e) => err!(session, "{e}"),
|
Err(e) => err!(session, "{e}"),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,7 +538,7 @@ async fn remove_left(
|
|||||||
};
|
};
|
||||||
|
|
||||||
match station.remove_team_left(&db, &team).await {
|
match station.remove_team_left(&db, &team).await {
|
||||||
Ok(()) => suc!(session, t!("team_removed_from_finished")),
|
Ok(()) => suc!(session, t!("team_removed_from_finished", team = team.name)),
|
||||||
Err(e) => err!(session, "{e}"),
|
Err(e) => err!(session, "{e}"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user