more externalization of strings
This commit is contained in:
parent
ffbcf04da7
commit
cb6f8a258a
@ -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."
|
||||
|
@ -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"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 → "))
|
||||
(t!("cant_assign_station_to_route_because_no_stations_exist"))
|
||||
(PreEscaped(" → "))
|
||||
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
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user