more externalization of strings
All checks were successful
CI/CD Pipeline / test (push) Successful in 5m58s
CI/CD Pipeline / deploy (push) Successful in 3m58s

This commit is contained in:
Philipp Hofer 2025-04-21 11:50:47 +02:00
parent ffbcf04da7
commit cb6f8a258a
3 changed files with 208 additions and 97 deletions

View File

@ -1,5 +1,25 @@
_version: 1
# Ascii: https://www.asciiart.eu/text-to-ascii-art banner
total_points: "Gesamtpunkte"
rank: "Rang"
logout: "Ausloggen"
save: "Speichern"
change_that_below: "Das kannst du hier ändern ⤵️"
add: "Hinzufügen"
#
# #####
# # # ##### ## ##### # #### # #
# # # # # # # # # ## #
# ##### # # # # # # # # # #
# # # ###### # # # # # # #
# # # # # # # # # # # ##
# ##### # # # # # #### # #
#
stations: "Stationen"
station_create: "Station erstellen"
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_confirm_deletion: "Bist du sicher, dass die Station gelöscht werden soll? Das kann _NICHT_ mehr rückgängig gemacht werden."
@ -11,5 +31,85 @@ station_create_err_duplicate_name: "Station %{name} konnte _NICHT_ erstellt werd
station_delete_succ: "Station %{name} erfolgreich gelöscht"
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})"
routes: "Routen"
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
#
# #######
# # ###### ## # #
# # # # # ## ##
# # ##### # # # ## #
# # # ###### # #
# # # # # # #
# # ###### # # # #
#
team: "Team"
teams: "Teams"
go_to_teams: "Zu den Teams"
#
# # #
# # # # #### # # #### #### #### ##### ######
# # # # # # # # # # # # # # # #
# ####### # # ###### #### # # # # # #####
# # # # # ### # # # # # # ##### #
# # # # # # # # # # # # # # # # #
# # # # #### # # #### #### #### # # ######
#
highscore: "Highscore"
#
# #
# # # ##### # # # # #
# # # # # ## ## # ## #
# # # # # # ## # # # # #
# ####### # # # # # # # #
# # # # # # # # # ##
# # # ##### # # # # #
#
admins: "Admins"
#
# ######
# # # #### # # ##### ######
# # # # # # # # #
# ###### # # # # # #####
# # # # # # # # #
# # # # # # # # #
# # # #### #### # ######
#
route: "Route"
routes: "Routen"
route_new: "Neue Route"
route_name: "Routenname"
route_name_edit: "Routennamen bearbeiten"
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."
no_routes: "Es gibt noch keine Routen."
route_create_succ: "Route %{name} erfolgreich erstellt"
route_create_err_duplicate_name: "Route %{name} konnte _NICHT_ erstellt werden, da es bereits eine Route mit diesem Namen gibt (%{err})!"
route_delete_succ: "Route %{name} erfolgreich gelöscht"
route_delete_err_nonexisting: "Route mit ID %{id} konnte nicht gelöscht werden, da sie nicht existiert"
route_delete_err_already_used: "Route %{name} konnte nicht gelöscht werden, da sie bereits verwendet wird (%{err})"
cant_assign_station_to_route_because_no_stations_exist: "Bevor du einer Route Stationen zuweisen kannst, musst du die Stationen erstellen"
route_has_no_stations_yet: "Diese Route hat noch keine Stationen zugewiesen."
confirm_remove_station_from_route: "Bist du sicher, dass die Station von der Route entfernt werden soll?"
select_station_to_add_to_route: "Hinzuzufügende Station auswählen"
teams_with_this_route: "Teams mit dieser Route"
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_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"
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})"
cant_remove_station_from_nonexisting_route: "Konnte keine Station von der Route mit ID %{id} entfernen, da diese Route nicht existiert."
cant_remove_nonexisting_station_from_route: "Konnte Station mit der ID %{id} nicht von der Route %{route} entfernen, da die Station nicht existiert."
station_deleted_from_route: "Station %{station} wurde von der Route %{route} gelöscht"
cant_remove_station_from_route_if_not_included: "Station %{station} kann nicht von der Route %{route} gelöscht werden, da diese nicht auf der Route liegt."
cant_move_nonexisting_station: "Konnte Station mit der ID %{id} nicht in der Route %{route} verschieben, da die Station nicht existiert."
station_succ_moved_in_route: "Station %{station} wurde in der Route %{route} erfolgreich vorgereiht"
cant_move_station_in_route_if_not_included: "Station %{station} kann in der Route %{route} nicht vorgereiht werden, da diese nicht auf der Route liegt."

View File

@ -30,7 +30,7 @@ async fn highscore(State(db): State<Arc<SqlitePool>>, session: Session) -> Marku
let content = html! {
h1 {
a href="/admin" { "↩️" }
"Highscore"
(t!("highscore"))
}
@for (idx, route) in routes.into_iter().enumerate() {
details open[idx==0] {
@ -40,15 +40,15 @@ async fn highscore(State(db): State<Arc<SqlitePool>>, session: Session) -> Marku
table {
thead {
tr {
td { "Team" }
td { (t!("team")) }
@for station in route.stations(&db).await {
td {
(station)
}
}
td { "Gesamtpunkte" }
td { "Rang" }
td { "Team" }
td { (t!("total_points")) }
td { (t!("rank")) }
td { (t!("team")) }
}
}
tbody {
@ -74,7 +74,7 @@ async fn highscore(State(db): State<Arc<SqlitePool>>, session: Session) -> Marku
({total_points += points;""})
(points)
}@else {
em data-placement="bottom" data-tooltip="Station hat Team noch nicht bewertet" {
em data-placement="bottom" data-tooltip=(t!("station_has_not_rated_team_yet")) {
"?"
}
}
@ -116,7 +116,7 @@ async fn index(session: Session) -> Markup {
}
ul {
a href="/auth/logout" {
"Ausloggen"
(t!("logout"))
}
}
}
@ -139,12 +139,12 @@ async fn index(session: Session) -> Markup {
}
li {
a role="button" href="/admin/highscore" {
"Highscore"
(t!("highscore"))
}
}
li {
a href="/admin/user" {
"Admins"
(t!("admins"))
}
}
}

View File

@ -1,5 +1,5 @@
use super::Route;
use crate::{admin::station::Station, err, page, succ, AppState};
use crate::{admin::station::Station, er, page, suc, AppState};
use axum::{
extract::State,
response::{IntoResponse, Redirect},
@ -32,7 +32,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
@for route in &routes{
li {
@if route.stations(&db).await.is_empty() {
em data-tooltip="Keine Stationen zugeteilt" {
em data-tooltip=(t!("route_has_no_station_assigned")) {
"⚠️"
}
}
@ -40,7 +40,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
(route.name)
}
a href=(format!("/admin/route/{}/delete", route.id))
onclick="return confirm('Bist du sicher, dass die Route gelöscht werden soll? Das kann _NICHT_ mehr rückgängig gemacht werden.');" {
onclick=(format!("return confirm('{}');", t!("route_confirm_deletion"))) {
"🗑️"
}
}
@ -48,14 +48,16 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
}
@if routes.is_empty() {
article class="warning" {
"Es gibt noch keine Routen. Das kannst du hier ändern ⤵️"
(t!("no_routes"))
" "
(t!("change_that_below"))
}
}
h2 { "Neue Route" }
h2 { (t!("route_new")) }
form action="/admin/route" method="post" {
fieldset role="group" {
input type="text" name="name" placeholder="Routenname" required;
input type="submit" value="Neue Route";
input type="text" name="name" placeholder=(t!("route_name")) required;
input type="submit" value=(t!("route_new"));
}
}
};
@ -73,11 +75,10 @@ async fn create(
Form(form): Form<CreateForm>,
) -> impl IntoResponse {
match Route::create(&db, &form.name).await {
Ok(()) => succ!(session, "Route '{}' erfolgreich erstellt!", form.name),
Err(e) => err!(
Ok(()) => suc!(session, t!("route_create_succ", name = form.name)),
Err(e) => er!(
session,
"Route '{}' konnte _NICHT_ erstellt werden, da es bereits eine Route mit diesem Namen gibt ({e})!",
form.name
t!("route_create_err_duplicate_name", name = form.name, err = e)
),
}
@ -90,20 +91,16 @@ async fn delete(
axum::extract::Path(id): axum::extract::Path<i64>,
) -> impl IntoResponse {
let Some(route) = Route::find_by_id(&db, id).await else {
err!(
session,
"Route mit ID {id} konnte nicht gelöscht werden, da sie nicht existiert"
);
er!(session, t!("route_delete_err_nonexisting"));
return Redirect::to("/admin/route");
};
match route.delete(&db).await {
Ok(()) => succ!(session, "Route '{}' erfolgreich gelöscht!", route.name),
Err(e) => err!(
Ok(()) => suc!(session, t!("route_delete_succ")),
Err(e) => er!(
session,
"Route '{}' kann nicht gelöscht werden, da sie bereits verwendet wird. ({e})",
route.name
t!("route_delete_err_already_used", name = route.name, err = e)
),
}
@ -116,10 +113,7 @@ async fn view(
axum::extract::Path(id): axum::extract::Path<i64>,
) -> Result<Markup, impl IntoResponse> {
let Some(route) = Route::find_by_id(&db, id).await else {
err!(
session,
"Route mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
er!(session, t!("route_delete_err_nonexisting"));
return Err(Redirect::to("/admin/route"));
};
@ -132,29 +126,34 @@ async fn view(
let content = html! {
h1 {
a href="/admin/route" { "↩️" }
"Route " (route.name)
(t!("route"))
" "
(route.name)
}
article {
details {
summary { "Routenname bearbeiten ✏️" }
summary { (t!("route_name_edit")) "✏️" }
form action=(format!("/admin/route/{}/name", route.id)) method="post" {
input type="text" name="name" value=(route.name) required;
input type="submit" value="Speichern";
input type="submit" value=(t!("save"));
}
}
}
h2 { "Stationen" }
h2 { (t!("stations")) }
@if cur_stations.is_empty() {
@if stations_not_in_route.is_empty() {
article class="error" {
(PreEscaped("Bevor du einer Route Stationen zuweisen kannst, musst du die Stationen erstellen &rarr; "))
(t!("cant_assign_station_to_route_because_no_stations_exist"))
(PreEscaped(" &rarr; "))
a role="button" href="/admin/station" {
"Station erstellen"
(t!("station_create"))
}
}
} @else {
article class="warning" {
"Diese Route hat noch keine Stationen zugewiesen. Das kannst du hier ändern ⤵️"
(t!("route_has_no_stations_yet"))
" "
(t!("change_that_below"))
}
}
} @else {
@ -164,13 +163,13 @@ async fn view(
(station)
@if idx > 0 {
a href=(format!("/admin/route/{}/move-station-higher/{}", route.id, station.id)){
em data-tooltip=(format!("{} nach vor reihen", station.name)) {
em data-tooltip=(t!("station_move_up", name = station.name)) {
"⬆️"
}
}
}
a href=(format!("/admin/route/{}/delete-station/{}", route.id, station.id))
onclick="return confirm('Bist du sicher, dass die Station von der Route entfernt werden soll?');" {
onclick=(format!("return confirm('{}');", t!("confirm_remove_station_from_route"))) {
"🗑️"
}
}
@ -179,22 +178,22 @@ async fn view(
}
@if !stations_not_in_route.is_empty(){
form action=(format!("/admin/route/{}/add-station", route.id)) method="post" {
select name="station" aria-label="Hinzuzufügende Station auswählen" required {
select name="station" aria-label=(t!("select_station_to_add_to_route")) required {
@for station in &stations_not_in_route {
option value=(station.id) {
(station.name)
}
}
input type="submit" value="Hinzufügen";
input type="submit" value=(t!("add"));
}
}
}
h2 { "Teams mit dieser Route" }
h2 { (t!("teams_with_this_route")) }
@if teams.is_empty() {
article {
"Noch keine Team ist dieser Route zugeteilt."
(t!("no_team_with_this_route"))
a role="button" href="/admin/team" {
"Zu den Teams"
(t!("go_to_teams"))
}
}
@ -225,21 +224,16 @@ async fn update_name(
Form(form): Form<UpdateNameForm>,
) -> impl IntoResponse {
let Some(route) = Route::find_by_id(&db, id).await else {
err!(
session,
"Route mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
er!(session, t!("route_update_err_nonexisting", id = id));
return Redirect::to("/admin/route");
};
route.update_name(&db, &form.name).await;
succ!(
suc!(
session,
"Route '{}' heißt ab sofort {}.",
route.name,
form.name
t!("route_new_name", old = route.name, new = form.name)
);
Redirect::to(&format!("/admin/route/{id}"))
@ -256,34 +250,40 @@ async fn add_station(
Form(form): Form<AddStationForm>,
) -> impl IntoResponse {
let Some(route) = Route::find_by_id(&db, id).await else {
err!(
session,
"Route mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
er!(session, t!("route_update_err_nonexisting", id = id));
return Redirect::to("/admin/route");
};
let Some(station) = Station::find_by_id(&db, form.station).await else {
err!(
er!(
session,
"Station mit ID {id} konnte nicht hinzugefügt werden, da sie nicht existiert"
t!(
"route_cant_add_nonexisting_station",
id = form.station,
route = route.name
)
);
return Redirect::to(&format!("/admin/route/{id}"));
};
match route.add_station(&db, &station).await {
Ok(()) => succ!(
Ok(()) => suc!(
session,
"Station {} wurde der Route {} hinzugefügt",
station.name,
route.name
t!(
"station_added_to_route",
station = station.name,
route = route.name
)
),
Err(e) => err!(
Err(e) => er!(
session,
"Station {} kann nur 1x der Route {} hinzugefügt werden. ({e})",
station.name,
route.name
t!(
"station_can_only_be_added_once_to_route",
station = station.name,
route = route.name,
err = e
)
),
}
@ -296,36 +296,43 @@ async fn delete_station(
axum::extract::Path((route_id, station_id)): axum::extract::Path<(i64, i64)>,
) -> impl IntoResponse {
let Some(route) = Route::find_by_id(&db, route_id).await else {
err!(
er!(
session,
"Konnte keine Station von Route mit ID {route_id} entfernen, da diese Route nicht existiert."
t!("cant_remove_station_from_nonexisting_route", id = route_id)
);
return Redirect::to("/admin/route");
};
let Some(station) = Station::find_by_id(&db, station_id).await else {
err!(
er!(
session,
"Konnte Station mit der ID {station_id} nicht von der Route {} entfernen, da die Station nicht existiert.",
route.name
t!(
"cant_remove_nonexisting_station_from_route",
id = station_id,
route = route.name
)
);
return Redirect::to(&format!("/admin/route/{route_id}"));
};
if route.delete_station(&db, &station).await {
succ!(
suc!(
session,
"Station '{}' wurde von der Route '{}' gelöscht",
station.name,
route.name
t!(
"station_deleted_from_route",
station = station.name,
route = route.name
)
);
} else {
err!(
er!(
session,
"Station '{}' konnte nicht von der Route '{}' gelöscht werden, da diese nicht auf dieser Route liegt",
station.name,
route.name
t!(
"cant_remove_station_from_route_if_not_included",
station = station.name,
route = route.name
)
);
}
@ -338,36 +345,40 @@ async fn move_station_higher(
axum::extract::Path((route_id, station_id)): axum::extract::Path<(i64, i64)>,
) -> impl IntoResponse {
let Some(route) = Route::find_by_id(&db, route_id).await else {
err!(
session,
"Konnte keine Station von Route mit ID {route_id} verschieben, da diese Route nicht existiert."
);
er!(session, t!("route_update_err_nonexisting", id = route_id));
return Redirect::to("/admin/route");
};
let Some(station) = Station::find_by_id(&db, station_id).await else {
err!(
er!(
session,
"Konnte Station mit der ID {station_id} nicht in der Route {} verschieben, da die Station nicht existiert.",
route.name
t!(
"cant_move_nonexisting_station",
id = station_id,
route = route.name
)
);
return Redirect::to(&format!("/admin/route/{route_id}"));
};
if route.move_station_higher(&db, &station).await {
succ!(
suc!(
session,
"Station '{}' wurde in der Route '{}' erfolgreich vorgereiht",
station.name,
route.name
t!(
"station_succ_moved_in_route",
station = station.name,
route = route.name
)
);
} else {
err!(
er!(
session,
"Station '{}' konnte in der Route '{}' nicht vorgereiht werden, da diese nicht auf dieser Route liegt",
station.name,
route.name
t!(
"cant_move_station_in_route_if_not_included",
station = station.name,
route = route.name
)
);
}