more external string, continue #12
All checks were successful
CI/CD Pipeline / test (push) Successful in 14m52s
CI/CD Pipeline / deploy (push) Successful in 6m32s

This commit is contained in:
Philipp Hofer 2025-04-22 16:13:22 +02:00
parent 5c72e88a40
commit 1628bdc252
3 changed files with 156 additions and 175 deletions

View File

@ -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."
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."
@ -114,9 +116,26 @@ confirm_station_cancel_team_finished: "Bist du sicher, dass das Team noch nicht
#
station: "Station"
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"
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"
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."
stations_expl_without_first_word: "sind festgelegte Orte mit spezifischen Aufgaben."
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_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_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_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_move_up: "%{name} nach vor reihen" # should be short -> tooltip
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"
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..."
@ -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"
pw_set: "Passwort erfolgreich gesetzt"
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."
#

View File

@ -1,9 +1,9 @@
use crate::{
admin::{station::Station, team::Team},
er, err,
er,
models::rating::{Rating, TeamsAtStationLocation},
partials::page,
suc, succ, AppState,
suc, AppState,
};
use axum::{
extract::State,
@ -74,10 +74,7 @@ async fn view(
axum::extract::Path(id): axum::extract::Path<i64>,
) -> Result<Markup, impl IntoResponse> {
let Some(station) = Station::find_by_id(&db, id).await else {
err!(
session,
"Station mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
er!(session, t!("station_open_err_nonexisting", id = id));
return Err(Redirect::to("/admin/station"));
};
@ -88,14 +85,16 @@ async fn view(
let content = html! {
h1 {
a href="/admin/station" { "↩️" }
"Station " (station.name)
(t!("station"))
" "
(station.name)
}
article {
details {
summary { "Stationsname bearbeiten ✏️" }
summary { (t!("station_name_edit"))" ✏️" }
form action=(format!("/admin/station/{}/name", station.id)) method="post" {
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 {
tbody {
tr {
th scope="row" { "Notizen" };
th scope="row" { (t!("notes")) };
td {
@match station.notes {
Some(ref notes) => {
@ -112,7 +111,7 @@ async fn view(
summary { "✏️" }
form action=(format!("/admin/station/{}/notes", station.id)) method="post" {
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" }
form action=(format!("/admin/station/{}/notes", station.id)) method="post" {
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() {
tr {
th scope="row" {
"Stations-Link"
(t!("station_link"))
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 {
a href=(format!("/s/{}/{}", station.id, station.pw)) {
"Login-Link"
(t!("login_link"))
}
}
}
}
tr {
th scope="row" { "Anzahl Stationsbetreuer"
th scope="row" { (t!("amount_crew"))
article class="warning" {
(t!("info_crewless_station"))
}
@ -156,11 +155,11 @@ async fn view(
summary { "✏️" }
form action=(format!("/admin/station/{}/amount-people", station.id)) method="post" {
input type="number" name="amount_people" min="0" max="10";
input type="submit" value="Speichern";
input type="submit" value=(t!("save"));
}
button class="error" {
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() {
tr {
th scope="row" { "Letzter Zugriff eines Stationsbetreuers" };
th scope="row" { (t!("last_access_crew")) };
td {
@match station.local_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() {
h2 { "Bewertungen" }
h2 { (t!("ratings")) }
div class="overflow-auto" {
table {
thead {
tr {
th { "Team" }
th { "Punkte" }
th { "Notizen" }
th { (t!("team")) }
th { (t!("points")) }
th { (t!("notes")) }
th {
em data-placement="bottom" data-tooltip="Angekommen" {
em data-placement="bottom" data-tooltip=(t!("arrived")) {
"👋"
}
}
th {
em data-placement="bottom" data-tooltip="Begonnen" {
em data-placement="bottom" data-tooltip=(t!("started")) {
"🎬"
}
}
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)){
button {
"Bewertungen für Station "
(station.name)
" eingeben"
(t!("enter_ratings_for_station", station=station.name))
}
}
@ -254,23 +251,23 @@ async fn view(
@if let (Some(_), Some(_)) = (station.lat, station.lng) {
article {
"Um einen neuen Standort zu wählen, auf einen Punkt in der Karte klicken"
(t!("click_on_map_for_new_location"))
}
} @else{
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() {
a href=(format!("/admin/station/{}/location-clear", station.id))
onclick="return confirm('Bist du sicher, dass du den Standort der Station löschen willst?');"{
"Standort löschen"
onclick=(format!("return confirm('{}');", t!("confirm_delete_location"))){
(t!("delete_location"))
}
}
form action=(format!("/admin/station/{}/location", station.id)) method="post" {
input type="hidden" name="lat" id="lat";
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" {}
script {
@ -338,21 +335,15 @@ async fn update_name(
Form(form): Form<UpdateNameForm>,
) -> impl IntoResponse {
let Some(station) = Station::find_by_id(&db, id).await else {
err!(
session,
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
er!(session, t!("station_edit_err_nonexisting", id = id));
return Redirect::to("/admin/station");
};
station.update_name(&db, &form.name).await;
succ!(
suc!(
session,
"Station '{}' heißt ab sofort '{}'.",
station.name,
form.name
t!("station_new_name", old = station.name, new = form.name)
);
Redirect::to(&format!("/admin/station/{id}"))
@ -369,21 +360,13 @@ async fn update_notes(
Form(form): Form<UpdateNotesForm>,
) -> impl IntoResponse {
let Some(station) = Station::find_by_id(&db, id).await else {
err!(
session,
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
er!(session, t!("station_edit_err_nonexisting", id = id));
return Redirect::to("/admin/station");
};
station.update_notes(&db, &form.notes).await;
succ!(
session,
"Notizen für die Station '{}' wurden erfolgreich bearbeitet!",
station.name
);
suc!(session, t!("station_new_notes", station = station.name));
Redirect::to(&format!("/admin/station/{id}"))
}
@ -399,20 +382,15 @@ async fn update_amount_people(
Form(form): Form<UpdateAmountPeopleForm>,
) -> impl IntoResponse {
let Some(station) = Station::find_by_id(&db, id).await else {
err!(
session,
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
er!(session, t!("station_edit_err_nonexisting", id = id));
return Redirect::to("/admin/station");
};
station.update_amount_people(&db, form.amount_people).await;
succ!(
suc!(
session,
"Anzahl an Betreuer für die Station '{}' wurden erfolgreich bearbeitet!",
station.name
t!("station_new_crew_amount", station = station.name)
);
Redirect::to(&format!("/admin/station/{id}"))
@ -424,20 +402,15 @@ async fn update_amount_people_reset(
axum::extract::Path(id): axum::extract::Path<i64>,
) -> impl IntoResponse {
let Some(station) = Station::find_by_id(&db, id).await else {
err!(
session,
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
er!(session, t!("station_edit_err_nonexisting", id = id));
return Redirect::to("/admin/station");
};
station.update_amount_people_reset(&db).await;
succ!(
suc!(
session,
"Anzahl an Betreuer für die Station '{}' wurden erfolgreich bearbeitet!",
station.name
t!("station_new_crew_amount", station = station.name)
);
Redirect::to(&format!("/admin/station/{id}"))
@ -449,11 +422,7 @@ async fn quick(
axum::extract::Path(id): axum::extract::Path<i64>,
) -> Result<Markup, impl IntoResponse> {
let Some(station) = Station::find_by_id(&db, id).await else {
err!(
session,
"Station mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
er!(session, t!("station_edit_err_nonexisting", id = id));
return Err(Redirect::to("/admin/station"));
};
@ -463,14 +432,16 @@ async fn quick(
let content = html! {
h1 {
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" {
table {
thead {
tr {
th { "Team" }
th { "Punkte" }
th { (t!("team")) }
th { (t!("points")) }
}
}
tbody {
@ -485,11 +456,11 @@ async fn quick(
@if let Some(rating) = Rating::find_by_team_and_station(&db, team, &station).await {
a href=(format!("/s/{}/{}", station.id, station.pw)){
@if let Some(points) = rating.points {
em data-tooltip="Schon eingetragen" {
em data-tooltip=(t!("already_entered")) {
(points)
}
} @else {
em data-tooltip="Team gerade bei Station" { "?" }
em data-tooltip=(t!("team_currently_at_station")) { "?" }
}
}
} @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)
@ -519,11 +490,7 @@ async fn quick_post(
Form(form): Form<QuickUpdate>,
) -> impl IntoResponse {
let Some(station) = Station::find_by_id(&db, id).await else {
err!(
session,
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
er!(session, t!("station_edit_err_nonexisting", id = id));
return Redirect::to("/admin/station");
};
@ -554,10 +521,13 @@ async fn quick_post(
.await
.is_some()
{
ret.push_str(&format!(
"Skipped rating for team {} because this team already has a rating for station {}",
team.name, station.name
));
let msg: String = t!(
"error_rating_team_already_rated",
team = team.name,
station = station.name
)
.into();
ret.push_str(&msg);
continue;
}
@ -571,12 +541,9 @@ async fn quick_post(
}
if amount_succ == 0 {
succ!(
session,
"Du hast keine Bewertungen eingegeben... Spaßvogel!"
);
suc!(session, t!("funny_you_entered_no_rating"));
} else {
succ!(session, "Erfolgreich {amount_succ} Bewertungen eingetragen");
suc!(session, t!("entered_n_ratings", amount = amount_succ));
}
Redirect::to(&format!("/admin/station/{id}/quick"))
@ -594,21 +561,13 @@ async fn update_location(
Form(form): Form<UpdateLocationForm>,
) -> impl IntoResponse {
let Some(station) = Station::find_by_id(&db, id).await else {
err!(
session,
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
er!(session, t!("station_edit_err_nonexisting", id = id));
return Redirect::to("/admin/station");
};
station.update_location(&db, form.lat, form.lng).await;
succ!(
session,
"Standort für die Station '{}' wurden erfolgreich bearbeitet!",
station.name
);
suc!(session, t!("location_changed", station = station.name));
Redirect::to(&format!("/admin/station/{id}"))
}
@ -619,21 +578,13 @@ async fn update_location_clear(
axum::extract::Path(id): axum::extract::Path<i64>,
) -> impl IntoResponse {
let Some(station) = Station::find_by_id(&db, id).await else {
err!(
session,
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
er!(session, t!("station_edit_err_nonexisting", id = id));
return Redirect::to("/admin/station");
};
station.update_location_clear(&db).await;
succ!(
session,
"Standort für die Station '{}' wurden erfolgreich gelöscht!",
station.name
);
suc!(session, t!("location_changed", station = station.name));
Redirect::to(&format!("/admin/station/{id}"))
}
@ -656,8 +607,8 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
table {
thead {
tr {
th { "Station" }
th { "Fortschritt" }
th { (t!("station")) }
th { (t!("progress")) }
th { "" }
}
}
@ -667,7 +618,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
tr {
td {
@if station.ready {
em data-tooltip="Station bereit!" {
em data-tooltip=(t!("station_ready")) {
small { "🟢 " }
}
}
@ -682,13 +633,13 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
(station.name)
}
@if station.crewless() {
em data-tooltip="Station ohne Stationsbetreuer" {
em data-tooltip=(t!("crewless_station")) {
small { "🤖" }
}
}
}
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) {}
}

View File

@ -1,11 +1,11 @@
use crate::{AppState, auth::User, err, partials::page, succ};
use crate::{auth::User, er, partials::page, suc, AppState};
use axum::{
Form, Router,
extract::State,
response::{IntoResponse, Redirect},
routing::{get, post},
Form, Router,
};
use maud::{Markup, html};
use maud::{html, Markup};
use serde::Deserialize;
use sqlx::SqlitePool;
use std::sync::Arc;
@ -23,15 +23,11 @@ async fn create(
) -> impl IntoResponse {
let id = match User::create(&db, &form.name).await {
Ok(id) => {
succ!(session, "User '{}' erfolgreich erstellt!", form.name);
suc!(session, t!("user_created", name = form.name));
id
}
Err(e) => {
err!(
session,
"User '{}' konnte _NICHT_ erstellt werden: {e:?}",
e
);
er!(session, t!("user_create_err", err = e));
return Redirect::to("/admin/user");
}
@ -46,20 +42,20 @@ async fn delete(
axum::extract::Path(id): axum::extract::Path<i64>,
) -> impl IntoResponse {
let Some(user) = User::find_by_id(&db, id).await else {
err!(
session,
"User mit ID {id} konnte nicht gelöscht werden, da sie nicht existiert"
);
er!(session, t!("nonexisting_user", id = id));
return Redirect::to("/admin/user");
};
match user.delete(&db).await {
Ok(()) => succ!(session, "User '{}' erfolgreich gelöscht!", user.name),
Err(e) => err!(
Ok(()) => suc!(session, t!("user_deleted", user = user.name)),
Err(e) => er!(
session,
"User '{}' kann nicht gelöscht werden, da er/sie bereits verwendet wird. ({e})",
user.name
t!(
"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>,
) -> Result<Markup, impl IntoResponse> {
let Some(user) = User::find_by_id(&db, id).await else {
err!(
session,
"User mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
er!(session, t!("nonexisting_user", id = id));
return Err(Redirect::to("/admin/user"));
};
@ -84,14 +76,19 @@ async fn view(
let content = html! {
h1 {
a href="/admin/user" { "↩️" }
"User " (user.name)
(t!("admin"))
" "
(user.name)
}
article {
details {
summary { "Name bearbeiten ✏️" }
summary {
(t!("edit_username"))
" ✏️"
}
form action=(format!("/admin/user/{}/name", user.id)) method="post" {
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 {
tbody {
tr {
th scope="row" { "Name" };
th scope="row" { (t!("name")) };
td {
(user.name)
}
}
tr {
th scope="row" { "Passwort" };
th scope="row" { (t!("pw")) };
td {
@if let Some(code) = user.require_new_password_code {
a href=(format!("/user/{}/set-pw/{}", user.id, code)){
"Login-Link"
(t!("login_link"))
}
} @else {
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.');" {
"Passwort vergessen: neuen Loginlink generieren"
onclick=(format!("return confirm('{}');", t!("confirm_new_admin_link"))) {
(t!("new_admin_link"))
}
}
}
@ -136,21 +133,15 @@ async fn update_name(
Form(form): Form<UpdateNameForm>,
) -> impl IntoResponse {
let Some(user) = User::find_by_id(&db, id).await else {
err!(
session,
"User mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
er!(session, t!("nonexisting_user", id = id));
return Redirect::to("/admin/user");
};
user.update_name(&db, &form.name).await;
succ!(
suc!(
session,
"User '{}' heißt ab sofort '{}'.",
user.name,
form.name
t!("new_user_name", old = user.name, new = form.name)
);
Redirect::to(&format!("/admin/user/{id}"))
@ -162,21 +153,13 @@ async fn new_pw(
axum::extract::Path(id): axum::extract::Path<i64>,
) -> impl IntoResponse {
let Some(user) = User::find_by_id(&db, id).await else {
err!(
session,
"User mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
er!(session, t!("nonexisting_user", id = id));
return Redirect::to("/admin/user");
};
user.new_pw(&db).await;
succ!(
session,
"Neuer Loginlink für User '{}' wurde generiert.",
user.name
);
suc!(session, t!("succ_new_admin_link", user = user.name));
Redirect::to(&format!("/admin/user/{id}"))
}
@ -187,7 +170,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
let content = html! {
h1 {
a href="/admin" { "↩️" }
"User"
(t!("admins"))
}
article {
em { "Admins" }
@ -202,11 +185,11 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
"."
}
article {
h2 { "Neuer User" }
h2 { (t!("new_admin")) }
form action="/admin/user" method="post" {
fieldset role="group" {
input type="text" name="name" placeholder="Name" required;
input type="submit" value="Neuer User";
input type="text" name="name" placeholder=(t!("name")) required;
input type="submit" value=(t!("new_admin"));
}
}
}
@ -217,7 +200,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
(user.name)
}
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"))) {
"🗑️"
}
}