more external string, continue #12
This commit is contained in:
parent
5c72e88a40
commit
1628bdc252
@ -34,6 +34,8 @@ info_crewless_station: "Wenn das eine unbemannte Station ist, wähle hier 0 Pers
|
|||||||
# # # # ## ## # # # # # # # ## # #
|
# # # # ## ## # # # # # # # ## # #
|
||||||
# ###### ###### # # ###### # # # #### # # ####
|
# ###### ###### # # ###### # # # #### # # ####
|
||||||
#
|
#
|
||||||
|
rating: "Bewertung"
|
||||||
|
ratings: "Bewertungen"
|
||||||
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."
|
||||||
@ -114,9 +116,26 @@ confirm_station_cancel_team_finished: "Bist du sicher, dass das Team noch nicht
|
|||||||
#
|
#
|
||||||
station: "Station"
|
station: "Station"
|
||||||
stations: "Stationen"
|
stations: "Stationen"
|
||||||
|
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."
|
||||||
|
login_link: "Login-Link"
|
||||||
|
station_name_edit: "Routennamen bearbeiten"
|
||||||
go_to_stations: "Zu den Stationen"
|
go_to_stations: "Zu den Stationen"
|
||||||
crewless_station: "Station ohne Stationsbetreuer"
|
crewless_station: "Station ohne Stationsbetreuer"
|
||||||
|
amount_crew: "Anzahl Stationsbetreuer"
|
||||||
|
last_access_crew: "Letzter Zugriff eines Stationsbetreuers"
|
||||||
|
not_loggedin_yet: "Noch nicht eingeloggt :-("
|
||||||
|
not_sure_about_amount_crew: "Ich weiß noch nicht wv. Personen benötigt werden."
|
||||||
station_create: "Station erstellen"
|
station_create: "Station erstellen"
|
||||||
|
arrived: "Angekommen"
|
||||||
|
started: "Begonnen"
|
||||||
|
left: "Gegangen"
|
||||||
|
delete_location: "Standort löschen"
|
||||||
|
save_new_location: "Neuen Standort speichern"
|
||||||
|
confirm_delete_location: "Bist du sicher, dass du den Standort der Station löschen willst?"
|
||||||
|
click_on_map_for_new_location: "Um einen neuen Standort zu wählen, auf einen Punkt in der Karte klicken"
|
||||||
|
click_on_map_for_location: "Um einen Standort zu wählen, auf einen Punkt in der Karte klicken"
|
||||||
|
enter_ratings_for_station: "Bewertungen für Station %{station} eingeben"
|
||||||
no_stations_yet: "Es gibt noch keine Stationen."
|
no_stations_yet: "Es gibt noch keine Stationen."
|
||||||
stations_expl_without_first_word: "sind festgelegte Orte mit spezifischen Aufgaben."
|
stations_expl_without_first_word: "sind festgelegte Orte mit spezifischen Aufgaben."
|
||||||
station_warning_not_assigned_route: "Noch keiner Route zugeordnet" # should be short -> tooltip
|
station_warning_not_assigned_route: "Noch keiner Route zugeordnet" # should be short -> tooltip
|
||||||
@ -127,11 +146,26 @@ station_name: "Stationsname"
|
|||||||
station_create_succ: "Station %{name} erfolgreich erstellt"
|
station_create_succ: "Station %{name} erfolgreich erstellt"
|
||||||
station_create_err_duplicate_name: "Station %{name} konnte _NICHT_ erstellt werden, da es bereits eine Station mit diesem Namen gibt (%{err})!"
|
station_create_err_duplicate_name: "Station %{name} konnte _NICHT_ erstellt werden, da es bereits eine Station mit diesem Namen gibt (%{err})!"
|
||||||
station_delete_succ: "Station %{name} erfolgreich gelöscht"
|
station_delete_succ: "Station %{name} erfolgreich gelöscht"
|
||||||
|
station_open_err_nonexisting: "Station mit ID %{id} konnte nicht geöffnet werden, da sie nicht existiert"
|
||||||
|
station_edit_err_nonexisting: "Station mit ID %{id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
||||||
station_delete_err_nonexisting: "Station mit ID %{id} konnte nicht gelöscht werden, da sie nicht existiert"
|
station_delete_err_nonexisting: "Station mit ID %{id} konnte nicht gelöscht werden, da sie nicht existiert"
|
||||||
station_delete_err_already_used: "Station %{name} konnte nicht gelöscht werden, da sie bereits verwendet wird (%{err})"
|
station_delete_err_already_used: "Station %{name} konnte nicht gelöscht werden, da sie bereits verwendet wird (%{err})"
|
||||||
station_has_not_rated_team_yet: "Station hat Team noch nicht bewertet" # should be short -> tooltip
|
station_has_not_rated_team_yet: "Station hat Team noch nicht bewertet" # should be short -> tooltip
|
||||||
station_move_up: "%{name} nach vor reihen" # should be short -> tooltip
|
station_move_up: "%{name} nach vor reihen" # should be short -> tooltip
|
||||||
generate_station_pdf: "Stations PDF generieren"
|
generate_station_pdf: "Stations PDF generieren"
|
||||||
|
station_new_name: "Station %{old} heißt ab sofort %{new}."
|
||||||
|
station_new_notes: "Notizen für die Station %{station} erfolgreich bearbeitet"
|
||||||
|
station_new_crew_amount: "Anzahl an Betreuer für die Station %{station} erfolgreich bearbeitet"
|
||||||
|
already_entered: "Schon eingetragen"
|
||||||
|
team_currently_at_station: "Team gerade bei der Station"
|
||||||
|
error_rating_team_already_rated: "Konnte team %{team} nicht bewerten, da das Team bereits von der Station %{station} bewertet wurde."
|
||||||
|
funny_you_entered_no_rating: "Du hast keine Bewertungen eingegeben... Spaßvogel!"
|
||||||
|
entered_n_ratings: "Erfolgreich %{amount} Bewertung(en) eingetragen"
|
||||||
|
location_changed: "Standort für die Station %{station} wurde erfolgreich geändert"
|
||||||
|
location_deleted: "Standort für die Station %{station} wurde erfolgreich gelöscht"
|
||||||
|
progress: "Fortschritt"
|
||||||
|
station_team_progress: "%{arrived}/%{total} (davon %{waiting} wartend + %{active} aktiv)"
|
||||||
|
station_ready: "Station bereit!"
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -172,6 +206,7 @@ highscore: "Highscore"
|
|||||||
# # # # # # # # # ##
|
# # # # # # # # # ##
|
||||||
# # # ##### # # # # #
|
# # # ##### # # # # #
|
||||||
#
|
#
|
||||||
|
admin: "Admin"
|
||||||
admins: "Admins"
|
admins: "Admins"
|
||||||
cant_update_pw_if_already_existing: "Kann kein neues Passwort setzen, weil es bereits eins gibt..."
|
cant_update_pw_if_already_existing: "Kann kein neues Passwort setzen, weil es bereits eins gibt..."
|
||||||
cant_update_pw_if_already_existing_for_user: "Kann kein neues Passwort für %{user} setzen, weil es bereits eins gibt..."
|
cant_update_pw_if_already_existing_for_user: "Kann kein neues Passwort für %{user} setzen, weil es bereits eins gibt..."
|
||||||
@ -179,6 +214,18 @@ cant_update_pw_with_wrong_code: "Falscher Code zum Setzen eines neuen Passworts
|
|||||||
new_pw_for_user: "Neues Passwort für %{user} setzen"
|
new_pw_for_user: "Neues Passwort für %{user} setzen"
|
||||||
pw_set: "Passwort erfolgreich gesetzt"
|
pw_set: "Passwort erfolgreich gesetzt"
|
||||||
cant_delete_last_admin: "Du kannst den letzten Admin nicht löschen"
|
cant_delete_last_admin: "Du kannst den letzten Admin nicht löschen"
|
||||||
|
user_created: "User %{name} erfolgreich erstellt"
|
||||||
|
user_deleted: "User %{name} erfolgreich gelöscht"
|
||||||
|
user_delete_error_already_in_use: "User %{name} kann nicht gelöscht werden, da er/sie bereits verwendet wird. (%{err})"
|
||||||
|
user_create_error: "User %{name} konnte nicht erstellt werden: %{err}"
|
||||||
|
nonexisting_user: "User mit ID %{id} existiert nicht."
|
||||||
|
edit_username: "Username bearbeiten"
|
||||||
|
new_admin_link: "Passwort vergessen: Neuen Loginlink generieren"
|
||||||
|
confirm_new_admin_link: "Bist du sicher, dass du einen neuen Passwort-Link generieren willst? Mit dem alten Passwort kann man sich dann nicht mehr einloggen."
|
||||||
|
new_user_name: "Admin %{old} heißt ab sofort %{new}"
|
||||||
|
succ_new_admin_link: "Neuer Loginlink für User %{user} wurde generiert"
|
||||||
|
new_admin: "Neuer Admin"
|
||||||
|
confirm_admin_delete: "Bist du sicher, dass der User gelöscht werden soll? Das kann _NICHT_ mehr rückgängig gemacht werden."
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
admin::{station::Station, team::Team},
|
admin::{station::Station, team::Team},
|
||||||
er, err,
|
er,
|
||||||
models::rating::{Rating, TeamsAtStationLocation},
|
models::rating::{Rating, TeamsAtStationLocation},
|
||||||
partials::page,
|
partials::page,
|
||||||
suc, succ, AppState,
|
suc, AppState,
|
||||||
};
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::State,
|
extract::State,
|
||||||
@ -74,10 +74,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(station) = Station::find_by_id(&db, id).await else {
|
let Some(station) = Station::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("station_open_err_nonexisting", id = id));
|
||||||
session,
|
|
||||||
"Station mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Err(Redirect::to("/admin/station"));
|
return Err(Redirect::to("/admin/station"));
|
||||||
};
|
};
|
||||||
@ -88,14 +85,16 @@ async fn view(
|
|||||||
let content = html! {
|
let content = html! {
|
||||||
h1 {
|
h1 {
|
||||||
a href="/admin/station" { "↩️" }
|
a href="/admin/station" { "↩️" }
|
||||||
"Station " (station.name)
|
(t!("station"))
|
||||||
|
" "
|
||||||
|
(station.name)
|
||||||
}
|
}
|
||||||
article {
|
article {
|
||||||
details {
|
details {
|
||||||
summary { "Stationsname bearbeiten ✏️" }
|
summary { (t!("station_name_edit"))" ✏️" }
|
||||||
form action=(format!("/admin/station/{}/name", station.id)) method="post" {
|
form action=(format!("/admin/station/{}/name", station.id)) method="post" {
|
||||||
input type="text" name="name" value=(station.name) required;
|
input type="text" name="name" value=(station.name) required;
|
||||||
input type="submit" value="Speichern";
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -103,7 +102,7 @@ async fn view(
|
|||||||
table {
|
table {
|
||||||
tbody {
|
tbody {
|
||||||
tr {
|
tr {
|
||||||
th scope="row" { "Notizen" };
|
th scope="row" { (t!("notes")) };
|
||||||
td {
|
td {
|
||||||
@match station.notes {
|
@match station.notes {
|
||||||
Some(ref notes) => {
|
Some(ref notes) => {
|
||||||
@ -112,7 +111,7 @@ async fn view(
|
|||||||
summary { "✏️" }
|
summary { "✏️" }
|
||||||
form action=(format!("/admin/station/{}/notes", station.id)) method="post" {
|
form action=(format!("/admin/station/{}/notes", station.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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -120,7 +119,7 @@ async fn view(
|
|||||||
summary { "Neue Notiz hinzufügen" }
|
summary { "Neue Notiz hinzufügen" }
|
||||||
form action=(format!("/admin/station/{}/notes", station.id)) method="post" {
|
form action=(format!("/admin/station/{}/notes", station.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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,20 +128,20 @@ async fn view(
|
|||||||
@if !station.crewless() {
|
@if !station.crewless() {
|
||||||
tr {
|
tr {
|
||||||
th scope="row" {
|
th scope="row" {
|
||||||
"Stations-Link"
|
(t!("station_link"))
|
||||||
article class="warning" {
|
article class="warning" {
|
||||||
(format!("Diesen Link nur Betreuern der Station {} geben! Mit diesem Link erhält man die Berechtigung, Teams zu bewerten.", station.name))
|
(t!("station_url_info", station=station.name))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
td {
|
td {
|
||||||
a href=(format!("/s/{}/{}", station.id, station.pw)) {
|
a href=(format!("/s/{}/{}", station.id, station.pw)) {
|
||||||
"Login-Link"
|
(t!("login_link"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tr {
|
tr {
|
||||||
th scope="row" { "Anzahl Stationsbetreuer"
|
th scope="row" { (t!("amount_crew"))
|
||||||
article class="warning" {
|
article class="warning" {
|
||||||
(t!("info_crewless_station"))
|
(t!("info_crewless_station"))
|
||||||
}
|
}
|
||||||
@ -156,11 +155,11 @@ async fn view(
|
|||||||
summary { "✏️" }
|
summary { "✏️" }
|
||||||
form action=(format!("/admin/station/{}/amount-people", station.id)) method="post" {
|
form action=(format!("/admin/station/{}/amount-people", station.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"));
|
||||||
}
|
}
|
||||||
button class="error" {
|
button class="error" {
|
||||||
a href=(format!("/admin/station/{}/amount-people-reset", station.id)) {
|
a href=(format!("/admin/station/{}/amount-people-reset", station.id)) {
|
||||||
em data-tooltip="Ich weiß noch nicht wv. Personen benötigt werden." {
|
em data-tooltip=(t!("not_sure_about_amount_crew")) {
|
||||||
"?"
|
"?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,11 +169,11 @@ async fn view(
|
|||||||
}
|
}
|
||||||
@if !station.crewless() {
|
@if !station.crewless() {
|
||||||
tr {
|
tr {
|
||||||
th scope="row" { "Letzter Zugriff eines Stationsbetreuers" };
|
th scope="row" { (t!("last_access_crew")) };
|
||||||
td {
|
td {
|
||||||
@match station.local_last_login() {
|
@match station.local_last_login() {
|
||||||
Some(last_login) => (last_login),
|
Some(last_login) => (last_login),
|
||||||
None => "noch nicht eingeloggt :-(",
|
None => (t!("not_loggedin_yet")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,26 +182,26 @@ async fn view(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@if !ratings.is_empty() {
|
@if !ratings.is_empty() {
|
||||||
h2 { "Bewertungen" }
|
h2 { (t!("ratings")) }
|
||||||
div class="overflow-auto" {
|
div class="overflow-auto" {
|
||||||
table {
|
table {
|
||||||
thead {
|
thead {
|
||||||
tr {
|
tr {
|
||||||
th { "Team" }
|
th { (t!("team")) }
|
||||||
th { "Punkte" }
|
th { (t!("points")) }
|
||||||
th { "Notizen" }
|
th { (t!("notes")) }
|
||||||
th {
|
th {
|
||||||
em data-placement="bottom" data-tooltip="Angekommen" {
|
em data-placement="bottom" data-tooltip=(t!("arrived")) {
|
||||||
"👋"
|
"👋"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
th {
|
th {
|
||||||
em data-placement="bottom" data-tooltip="Begonnen" {
|
em data-placement="bottom" data-tooltip=(t!("started")) {
|
||||||
"🎬"
|
"🎬"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
th {
|
th {
|
||||||
em data-placement="bottom" data-tooltip="Gegangen" {
|
em data-placement="bottom" data-tooltip=(t!("left")) {
|
||||||
"🚶♂️"
|
"🚶♂️"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,9 +243,7 @@ async fn view(
|
|||||||
}
|
}
|
||||||
a href=(format!("/admin/station/{}/quick", station.id)){
|
a href=(format!("/admin/station/{}/quick", station.id)){
|
||||||
button {
|
button {
|
||||||
"Bewertungen für Station "
|
(t!("enter_ratings_for_station", station=station.name))
|
||||||
(station.name)
|
|
||||||
" eingeben"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,23 +251,23 @@ async fn view(
|
|||||||
|
|
||||||
@if let (Some(_), Some(_)) = (station.lat, station.lng) {
|
@if let (Some(_), Some(_)) = (station.lat, station.lng) {
|
||||||
article {
|
article {
|
||||||
"Um einen neuen Standort zu wählen, auf einen Punkt in der Karte klicken"
|
(t!("click_on_map_for_new_location"))
|
||||||
}
|
}
|
||||||
} @else{
|
} @else{
|
||||||
article {
|
article {
|
||||||
"Um einen Standort zu wählen, auf einen Punkt in der Karte klicken"
|
(t!("click_on_map_for_location"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@if station.lat.is_some() && station.lng.is_some() {
|
@if station.lat.is_some() && station.lng.is_some() {
|
||||||
a href=(format!("/admin/station/{}/location-clear", station.id))
|
a href=(format!("/admin/station/{}/location-clear", station.id))
|
||||||
onclick="return confirm('Bist du sicher, dass du den Standort der Station löschen willst?');"{
|
onclick=(format!("return confirm('{}');", t!("confirm_delete_location"))){
|
||||||
"Standort löschen"
|
(t!("delete_location"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
form action=(format!("/admin/station/{}/location", station.id)) method="post" {
|
form action=(format!("/admin/station/{}/location", station.id)) method="post" {
|
||||||
input type="hidden" name="lat" id="lat";
|
input type="hidden" name="lat" id="lat";
|
||||||
input type="hidden" name="lng" id="lng";
|
input type="hidden" name="lng" id="lng";
|
||||||
input type="submit" value="Neuen Standort speichern" style="display: None;" id="location-submit";
|
input type="submit" value=(t!("save_new_location")) style="display: None;" id="location-submit";
|
||||||
}
|
}
|
||||||
div id="map" style="height: 500px" {}
|
div id="map" style="height: 500px" {}
|
||||||
script {
|
script {
|
||||||
@ -338,21 +335,15 @@ async fn update_name(
|
|||||||
Form(form): Form<UpdateNameForm>,
|
Form(form): Form<UpdateNameForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(station) = Station::find_by_id(&db, id).await else {
|
let Some(station) = Station::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("station_edit_err_nonexisting", id = id));
|
||||||
session,
|
|
||||||
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/station");
|
return Redirect::to("/admin/station");
|
||||||
};
|
};
|
||||||
|
|
||||||
station.update_name(&db, &form.name).await;
|
station.update_name(&db, &form.name).await;
|
||||||
|
|
||||||
succ!(
|
suc!(
|
||||||
session,
|
session,
|
||||||
"Station '{}' heißt ab sofort '{}'.",
|
t!("station_new_name", old = station.name, new = form.name)
|
||||||
station.name,
|
|
||||||
form.name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/station/{id}"))
|
Redirect::to(&format!("/admin/station/{id}"))
|
||||||
@ -369,21 +360,13 @@ async fn update_notes(
|
|||||||
Form(form): Form<UpdateNotesForm>,
|
Form(form): Form<UpdateNotesForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(station) = Station::find_by_id(&db, id).await else {
|
let Some(station) = Station::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("station_edit_err_nonexisting", id = id));
|
||||||
session,
|
|
||||||
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/station");
|
return Redirect::to("/admin/station");
|
||||||
};
|
};
|
||||||
|
|
||||||
station.update_notes(&db, &form.notes).await;
|
station.update_notes(&db, &form.notes).await;
|
||||||
|
|
||||||
succ!(
|
suc!(session, t!("station_new_notes", station = station.name));
|
||||||
session,
|
|
||||||
"Notizen für die Station '{}' wurden erfolgreich bearbeitet!",
|
|
||||||
station.name
|
|
||||||
);
|
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/station/{id}"))
|
Redirect::to(&format!("/admin/station/{id}"))
|
||||||
}
|
}
|
||||||
@ -399,20 +382,15 @@ async fn update_amount_people(
|
|||||||
Form(form): Form<UpdateAmountPeopleForm>,
|
Form(form): Form<UpdateAmountPeopleForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(station) = Station::find_by_id(&db, id).await else {
|
let Some(station) = Station::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("station_edit_err_nonexisting", id = id));
|
||||||
session,
|
|
||||||
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/station");
|
return Redirect::to("/admin/station");
|
||||||
};
|
};
|
||||||
|
|
||||||
station.update_amount_people(&db, form.amount_people).await;
|
station.update_amount_people(&db, form.amount_people).await;
|
||||||
|
|
||||||
succ!(
|
suc!(
|
||||||
session,
|
session,
|
||||||
"Anzahl an Betreuer für die Station '{}' wurden erfolgreich bearbeitet!",
|
t!("station_new_crew_amount", station = station.name)
|
||||||
station.name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/station/{id}"))
|
Redirect::to(&format!("/admin/station/{id}"))
|
||||||
@ -424,20 +402,15 @@ 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(station) = Station::find_by_id(&db, id).await else {
|
let Some(station) = Station::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("station_edit_err_nonexisting", id = id));
|
||||||
session,
|
|
||||||
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/station");
|
return Redirect::to("/admin/station");
|
||||||
};
|
};
|
||||||
|
|
||||||
station.update_amount_people_reset(&db).await;
|
station.update_amount_people_reset(&db).await;
|
||||||
|
|
||||||
succ!(
|
suc!(
|
||||||
session,
|
session,
|
||||||
"Anzahl an Betreuer für die Station '{}' wurden erfolgreich bearbeitet!",
|
t!("station_new_crew_amount", station = station.name)
|
||||||
station.name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/station/{id}"))
|
Redirect::to(&format!("/admin/station/{id}"))
|
||||||
@ -449,11 +422,7 @@ async fn quick(
|
|||||||
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(station) = Station::find_by_id(&db, id).await else {
|
let Some(station) = Station::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("station_edit_err_nonexisting", id = id));
|
||||||
session,
|
|
||||||
"Station mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Err(Redirect::to("/admin/station"));
|
return Err(Redirect::to("/admin/station"));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -463,14 +432,16 @@ async fn quick(
|
|||||||
let content = html! {
|
let content = html! {
|
||||||
h1 {
|
h1 {
|
||||||
a href=(format!("/admin/station/{}", station.id)) { "↩️" }
|
a href=(format!("/admin/station/{}", station.id)) { "↩️" }
|
||||||
"Bewertungen Station " (station.name)
|
(t!("ratings"))
|
||||||
|
" "
|
||||||
|
(station.name)
|
||||||
}
|
}
|
||||||
form action=(format!("/admin/station/{}/quick", station.id)) method="post" {
|
form action=(format!("/admin/station/{}/quick", station.id)) method="post" {
|
||||||
table {
|
table {
|
||||||
thead {
|
thead {
|
||||||
tr {
|
tr {
|
||||||
th { "Team" }
|
th { (t!("team")) }
|
||||||
th { "Punkte" }
|
th { (t!("points")) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tbody {
|
tbody {
|
||||||
@ -485,11 +456,11 @@ async fn quick(
|
|||||||
@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 {
|
||||||
@ -501,7 +472,7 @@ async fn quick(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input type="submit" value="Speichern";
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(page(content, session, true).await)
|
Ok(page(content, session, true).await)
|
||||||
@ -519,11 +490,7 @@ async fn quick_post(
|
|||||||
Form(form): Form<QuickUpdate>,
|
Form(form): Form<QuickUpdate>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(station) = Station::find_by_id(&db, id).await else {
|
let Some(station) = Station::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("station_edit_err_nonexisting", id = id));
|
||||||
session,
|
|
||||||
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/station");
|
return Redirect::to("/admin/station");
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -554,10 +521,13 @@ async fn quick_post(
|
|||||||
.await
|
.await
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
ret.push_str(&format!(
|
let msg: String = t!(
|
||||||
"Skipped rating for team {} because this team already has a rating for station {}",
|
"error_rating_team_already_rated",
|
||||||
team.name, station.name
|
team = team.name,
|
||||||
));
|
station = station.name
|
||||||
|
)
|
||||||
|
.into();
|
||||||
|
ret.push_str(&msg);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,12 +541,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/station/{id}/quick"))
|
Redirect::to(&format!("/admin/station/{id}/quick"))
|
||||||
@ -594,21 +561,13 @@ async fn update_location(
|
|||||||
Form(form): Form<UpdateLocationForm>,
|
Form(form): Form<UpdateLocationForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(station) = Station::find_by_id(&db, id).await else {
|
let Some(station) = Station::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("station_edit_err_nonexisting", id = id));
|
||||||
session,
|
|
||||||
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/station");
|
return Redirect::to("/admin/station");
|
||||||
};
|
};
|
||||||
|
|
||||||
station.update_location(&db, form.lat, form.lng).await;
|
station.update_location(&db, form.lat, form.lng).await;
|
||||||
|
|
||||||
succ!(
|
suc!(session, t!("location_changed", station = station.name));
|
||||||
session,
|
|
||||||
"Standort für die Station '{}' wurden erfolgreich bearbeitet!",
|
|
||||||
station.name
|
|
||||||
);
|
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/station/{id}"))
|
Redirect::to(&format!("/admin/station/{id}"))
|
||||||
}
|
}
|
||||||
@ -619,21 +578,13 @@ async fn update_location_clear(
|
|||||||
axum::extract::Path(id): axum::extract::Path<i64>,
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(station) = Station::find_by_id(&db, id).await else {
|
let Some(station) = Station::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("station_edit_err_nonexisting", id = id));
|
||||||
session,
|
|
||||||
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/station");
|
return Redirect::to("/admin/station");
|
||||||
};
|
};
|
||||||
|
|
||||||
station.update_location_clear(&db).await;
|
station.update_location_clear(&db).await;
|
||||||
|
|
||||||
succ!(
|
suc!(session, t!("location_changed", station = station.name));
|
||||||
session,
|
|
||||||
"Standort für die Station '{}' wurden erfolgreich gelöscht!",
|
|
||||||
station.name
|
|
||||||
);
|
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/station/{id}"))
|
Redirect::to(&format!("/admin/station/{id}"))
|
||||||
}
|
}
|
||||||
@ -656,8 +607,8 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
table {
|
table {
|
||||||
thead {
|
thead {
|
||||||
tr {
|
tr {
|
||||||
th { "Station" }
|
th { (t!("station")) }
|
||||||
th { "Fortschritt" }
|
th { (t!("progress")) }
|
||||||
th { "" }
|
th { "" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -667,7 +618,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
tr {
|
tr {
|
||||||
td {
|
td {
|
||||||
@if station.ready {
|
@if station.ready {
|
||||||
em data-tooltip="Station bereit!" {
|
em data-tooltip=(t!("station_ready")) {
|
||||||
small { "🟢 " }
|
small { "🟢 " }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -682,13 +633,13 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
(station.name)
|
(station.name)
|
||||||
}
|
}
|
||||||
@if station.crewless() {
|
@if station.crewless() {
|
||||||
em data-tooltip="Station ohne Stationsbetreuer" {
|
em data-tooltip=(t!("crewless_station")) {
|
||||||
small { "🤖" }
|
small { "🤖" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
td {
|
td {
|
||||||
em data-tooltip=(format!("{}/{} Teams (davon {} wartend + {} aktiv)", status.total_teams-status.not_yet_here.len() as i64, status.total_teams, status.waiting.len(), status.doing.len())) {
|
em data-tooltip=(t!("station_team_progress", arrived=status.total_teams-status.not_yet_here.len() as i64, total=status.total_teams, waiting= status.waiting.len(), active=status.doing.len() )) {
|
||||||
progress value=(status.total_teams-status.not_yet_here.len() as i64) max=(status.total_teams) {}
|
progress value=(status.total_teams-status.not_yet_here.len() as i64) max=(status.total_teams) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use crate::{AppState, auth::User, err, partials::page, succ};
|
use crate::{auth::User, er, partials::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, html};
|
use maud::{html, Markup};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -23,15 +23,11 @@ async fn create(
|
|||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let id = match User::create(&db, &form.name).await {
|
let id = match User::create(&db, &form.name).await {
|
||||||
Ok(id) => {
|
Ok(id) => {
|
||||||
succ!(session, "User '{}' erfolgreich erstellt!", form.name);
|
suc!(session, t!("user_created", name = form.name));
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
err!(
|
er!(session, t!("user_create_err", err = e));
|
||||||
session,
|
|
||||||
"User '{}' konnte _NICHT_ erstellt werden: {e:?}",
|
|
||||||
e
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/user");
|
return Redirect::to("/admin/user");
|
||||||
}
|
}
|
||||||
@ -46,20 +42,20 @@ 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(user) = User::find_by_id(&db, id).await else {
|
let Some(user) = User::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_user", id = id));
|
||||||
session,
|
|
||||||
"User mit ID {id} konnte nicht gelöscht werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/user");
|
return Redirect::to("/admin/user");
|
||||||
};
|
};
|
||||||
|
|
||||||
match user.delete(&db).await {
|
match user.delete(&db).await {
|
||||||
Ok(()) => succ!(session, "User '{}' erfolgreich gelöscht!", user.name),
|
Ok(()) => suc!(session, t!("user_deleted", user = user.name)),
|
||||||
Err(e) => err!(
|
Err(e) => er!(
|
||||||
session,
|
session,
|
||||||
"User '{}' kann nicht gelöscht werden, da er/sie bereits verwendet wird. ({e})",
|
t!(
|
||||||
user.name
|
"user_delete_error_already_in_use",
|
||||||
|
user = user.name,
|
||||||
|
err = e
|
||||||
|
)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,11 +68,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(user) = User::find_by_id(&db, id).await else {
|
let Some(user) = User::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_user", id = id));
|
||||||
session,
|
|
||||||
"User mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Err(Redirect::to("/admin/user"));
|
return Err(Redirect::to("/admin/user"));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -84,14 +76,19 @@ async fn view(
|
|||||||
let content = html! {
|
let content = html! {
|
||||||
h1 {
|
h1 {
|
||||||
a href="/admin/user" { "↩️" }
|
a href="/admin/user" { "↩️" }
|
||||||
"User " (user.name)
|
(t!("admin"))
|
||||||
|
" "
|
||||||
|
(user.name)
|
||||||
}
|
}
|
||||||
article {
|
article {
|
||||||
details {
|
details {
|
||||||
summary { "Name bearbeiten ✏️" }
|
summary {
|
||||||
|
(t!("edit_username"))
|
||||||
|
" ✏️"
|
||||||
|
}
|
||||||
form action=(format!("/admin/user/{}/name", user.id)) method="post" {
|
form action=(format!("/admin/user/{}/name", user.id)) method="post" {
|
||||||
input type="text" name="name" value=(user.name) required;
|
input type="text" name="name" value=(user.name) required;
|
||||||
input type="submit" value="Speichern";
|
input type="submit" value=(t!("save"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -99,22 +96,22 @@ async fn view(
|
|||||||
table {
|
table {
|
||||||
tbody {
|
tbody {
|
||||||
tr {
|
tr {
|
||||||
th scope="row" { "Name" };
|
th scope="row" { (t!("name")) };
|
||||||
td {
|
td {
|
||||||
(user.name)
|
(user.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tr {
|
tr {
|
||||||
th scope="row" { "Passwort" };
|
th scope="row" { (t!("pw")) };
|
||||||
td {
|
td {
|
||||||
@if let Some(code) = user.require_new_password_code {
|
@if let Some(code) = user.require_new_password_code {
|
||||||
a href=(format!("/user/{}/set-pw/{}", user.id, code)){
|
a href=(format!("/user/{}/set-pw/{}", user.id, code)){
|
||||||
"Login-Link"
|
(t!("login_link"))
|
||||||
}
|
}
|
||||||
} @else {
|
} @else {
|
||||||
a href=(format!("/admin/user/{}/new-pw", user.id))
|
a href=(format!("/admin/user/{}/new-pw", user.id))
|
||||||
onclick="return confirm('Bist du sicher, dass du einen neuen Passwort-Link generieren willst? Mit dem alten Passwort kann man sich dann nicht mehr einloggen.');" {
|
onclick=(format!("return confirm('{}');", t!("confirm_new_admin_link"))) {
|
||||||
"Passwort vergessen: neuen Loginlink generieren"
|
(t!("new_admin_link"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,21 +133,15 @@ async fn update_name(
|
|||||||
Form(form): Form<UpdateNameForm>,
|
Form(form): Form<UpdateNameForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(user) = User::find_by_id(&db, id).await else {
|
let Some(user) = User::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_user", id = id));
|
||||||
session,
|
|
||||||
"User mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/user");
|
return Redirect::to("/admin/user");
|
||||||
};
|
};
|
||||||
|
|
||||||
user.update_name(&db, &form.name).await;
|
user.update_name(&db, &form.name).await;
|
||||||
|
|
||||||
succ!(
|
suc!(
|
||||||
session,
|
session,
|
||||||
"User '{}' heißt ab sofort '{}'.",
|
t!("new_user_name", old = user.name, new = form.name)
|
||||||
user.name,
|
|
||||||
form.name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/user/{id}"))
|
Redirect::to(&format!("/admin/user/{id}"))
|
||||||
@ -162,21 +153,13 @@ async fn new_pw(
|
|||||||
axum::extract::Path(id): axum::extract::Path<i64>,
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let Some(user) = User::find_by_id(&db, id).await else {
|
let Some(user) = User::find_by_id(&db, id).await else {
|
||||||
err!(
|
er!(session, t!("nonexisting_user", id = id));
|
||||||
session,
|
|
||||||
"User mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
|
||||||
);
|
|
||||||
|
|
||||||
return Redirect::to("/admin/user");
|
return Redirect::to("/admin/user");
|
||||||
};
|
};
|
||||||
|
|
||||||
user.new_pw(&db).await;
|
user.new_pw(&db).await;
|
||||||
|
|
||||||
succ!(
|
suc!(session, t!("succ_new_admin_link", user = user.name));
|
||||||
session,
|
|
||||||
"Neuer Loginlink für User '{}' wurde generiert.",
|
|
||||||
user.name
|
|
||||||
);
|
|
||||||
|
|
||||||
Redirect::to(&format!("/admin/user/{id}"))
|
Redirect::to(&format!("/admin/user/{id}"))
|
||||||
}
|
}
|
||||||
@ -187,10 +170,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" { "↩️" }
|
||||||
"User"
|
(t!("admins"))
|
||||||
}
|
}
|
||||||
article {
|
article {
|
||||||
em { "Admins " }
|
em { "Admins" }
|
||||||
"sind Menschen, die "
|
"sind Menschen, die "
|
||||||
a href="/admin/station" { "Stationen" }
|
a href="/admin/station" { "Stationen" }
|
||||||
", "
|
", "
|
||||||
@ -202,11 +185,11 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
"."
|
"."
|
||||||
}
|
}
|
||||||
article {
|
article {
|
||||||
h2 { "Neuer User" }
|
h2 { (t!("new_admin")) }
|
||||||
form action="/admin/user" method="post" {
|
form action="/admin/user" method="post" {
|
||||||
fieldset role="group" {
|
fieldset role="group" {
|
||||||
input type="text" name="name" placeholder="Name" required;
|
input type="text" name="name" placeholder=(t!("name")) required;
|
||||||
input type="submit" value="Neuer User";
|
input type="submit" value=(t!("new_admin"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,7 +200,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
(user.name)
|
(user.name)
|
||||||
}
|
}
|
||||||
a href=(format!("/admin/user/{}/delete", user.id))
|
a href=(format!("/admin/user/{}/delete", user.id))
|
||||||
onclick="return confirm('Bist du sicher, dass der User gelöscht werden soll? Das kann _NICHT_ mehr rückgängig gemacht werden.');" {
|
onclick=(format!("return confirm('{}');", t!("confirm_admin_delete"))) {
|
||||||
"🗑️"
|
"🗑️"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user