move to /admimn

This commit is contained in:
Philipp Hofer 2025-04-08 20:18:50 +02:00
parent d69f2ee13e
commit bacce1c55a
9 changed files with 150 additions and 139 deletions

View File

@ -9,8 +9,8 @@ station_new: "Neue Station"
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_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_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"
teams: "Teams"

44
src/admin/mod.rs Normal file
View File

@ -0,0 +1,44 @@
use crate::page;
use axum::{routing::get, Router};
use maud::{html, Markup};
use sqlx::SqlitePool;
use std::sync::Arc;
use tower_sessions::Session;
pub(crate) mod route;
pub(crate) mod station;
pub(crate) mod team;
async fn index(session: Session) -> Markup {
let content = html! {
h1 { (t!("app_name")) }
nav {
ul {
li {
a role="button" href="/admin/station" {
(t!("stations"))
}
}
li {
a role="button" href="/admin/route" {
(t!("routes"))
}
}
li {
a role="button" href="/admin/team" {
(t!("teams"))
}
}
}
}
};
page(content, session, false).await
}
pub(super) fn routes() -> Router<Arc<SqlitePool>> {
Router::new()
.route("/", get(index))
.nest("/station", station::routes())
.nest("/route", route::routes())
.nest("/team", team::routes())
}

View File

@ -1,4 +1,4 @@
use crate::{station::Station, team::Team};
use crate::admin::{station::Station, team::Team};
use axum::Router;
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, Row, SqlitePool};

View File

@ -1,5 +1,5 @@
use super::Route;
use crate::{err, page, station::Station, succ};
use crate::{admin::station::Station, err, page, succ};
use axum::{
extract::State,
response::{IntoResponse, Redirect},
@ -17,15 +17,15 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
let content = html! {
h1 {
a href="/" { "↩️" }
a href="/admin/" { "↩️" }
"Routen"
}
article {
em { "Routen " }
"definieren welche "
a href="/station" { "Stationen" }
a href="/admin/station" { "Stationen" }
" von den "
a href="/team" { "Teams" }
a href="/admin/team" { "Teams" }
" in welcher Reihenfolge abgeklappert werden sollen. Wenn es verschiedene Kategorien (zB Kinder- und Erwachsenenwertung) gibt, kannst du auch mehrere Routen mit (teils) überlappenden Stationen erstellen."
}
ol {
@ -36,10 +36,10 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
"⚠️"
}
}
a href=(format!("/route/{}", route.id)){
a href=(format!("/admin/route/{}", route.id)){
(route.name)
}
a href=(format!("/route/{}/delete", route.id))
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.');" {
"🗑️"
}
@ -52,7 +52,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
}
}
h2 { "Neue Route" }
form action="/route" method="post" {
form action="/admin/route" method="post" {
fieldset role="team" {
input type="text" name="name" placeholder="Routenname" required;
input type="submit" value="Neue Route";
@ -81,7 +81,7 @@ async fn create(
),
}
Redirect::to("/route")
Redirect::to("/admin/route")
}
async fn delete(
@ -95,7 +95,7 @@ async fn delete(
"Route mit ID {id} konnte nicht gelöscht werden, da sie nicht existiert"
);
return Redirect::to("/route");
return Redirect::to("/admin/route");
};
match route.delete(&db).await {
@ -107,7 +107,7 @@ async fn delete(
),
}
Redirect::to("/route")
Redirect::to("/admin/route")
}
async fn view(
@ -121,7 +121,7 @@ async fn view(
"Route mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
return Err(Redirect::to("/route"));
return Err(Redirect::to("/admin/route"));
};
let cur_stations = route.stations(&db).await;
@ -131,13 +131,13 @@ async fn view(
let content = html! {
h1 {
a href="/route" { "↩️" }
a href="/admin/route" { "↩️" }
"Route " (route.name)
}
article {
details {
summary { "Routenname bearbeiten ✏️" }
form action=(format!("/route/{}/name", route.id)) method="post" {
form action=(format!("/admin/route/{}/name", route.id)) method="post" {
input type="text" name="name" value=(route.name) required;
input type="submit" value="Speichern";
}
@ -148,7 +148,7 @@ async fn view(
@if stations_not_in_route.is_empty() {
article class="error" {
(PreEscaped("Bevor du einer Route Stationen zuweisen kannst, musst du die Stationen erstellen &rarr; "))
a role="button" href="/station" {
a role="button" href="/admin/station" {
"Station erstellen"
}
}
@ -163,13 +163,13 @@ async fn view(
li {
(station.name)
@if idx > 0 {
a href=(format!("/route/{}/move-station-higher/{}", route.id, station.id)){
a href=(format!("/admin/route/{}/move-station-higher/{}", route.id, station.id)){
em data-tooltip=(format!("{} nach vor reihen", station.name)) {
"⬆️"
}
}
}
a href=(format!("/route/{}/delete-station/{}", route.id, station.id))
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?');" {
"🗑️"
}
@ -178,7 +178,7 @@ async fn view(
}
}
@if !stations_not_in_route.is_empty(){
form action=(format!("/route/{}/add-station", route.id)) method="post" {
form action=(format!("/admin/route/{}/add-station", route.id)) method="post" {
select name="station" aria-label="Hinzuzufügende Station auswählen" required {
@for station in &stations_not_in_route {
option value=(station.id) {
@ -193,7 +193,7 @@ async fn view(
@if teams.is_empty() {
article {
"Noch keine Team ist dieser Route zugeteilt."
a role="button" href="/team" {
a role="button" href="/admin/team" {
"Zu den Teams"
}
@ -202,7 +202,7 @@ async fn view(
ol {
@for team in &teams {
li {
a href=(format!("/team/{}", team.id)) {
a href=(format!("/admin/team/{}", team.id)) {
(team.name)
}
}
@ -230,7 +230,7 @@ async fn update_name(
"Route mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
return Redirect::to("/route");
return Redirect::to("/admin/route");
};
route.update_name(&db, &form.name).await;
@ -242,7 +242,7 @@ async fn update_name(
form.name
);
Redirect::to(&format!("/route/{id}"))
Redirect::to(&format!("/admin/route/{id}"))
}
#[derive(Deserialize)]
@ -261,7 +261,7 @@ async fn add_station(
"Route mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
return Redirect::to("/route");
return Redirect::to("/admin/route");
};
let Some(station) = Station::find_by_id(&db, form.station).await else {
err!(
@ -269,7 +269,7 @@ async fn add_station(
"Station mit ID {id} konnte nicht hinzugefügt werden, da sie nicht existiert"
);
return Redirect::to(&format!("/route/{id}"));
return Redirect::to(&format!("/admin/route/{id}"));
};
match route.add_station(&db, &station).await {
@ -287,7 +287,7 @@ async fn add_station(
),
}
Redirect::to(&format!("/route/{id}"))
Redirect::to(&format!("/admin/route/{id}"))
}
async fn delete_station(
@ -301,7 +301,7 @@ async fn delete_station(
"Konnte keine Station von Route mit ID {route_id} entfernen, da diese Route nicht existiert."
);
return Redirect::to("/route");
return Redirect::to("/admin/route");
};
let Some(station) = Station::find_by_id(&db, station_id).await else {
err!(
@ -310,7 +310,7 @@ async fn delete_station(
route.name
);
return Redirect::to(&format!("/route/{route_id}"));
return Redirect::to(&format!("/admin/route/{route_id}"));
};
if route.delete_station(&db, &station).await {
@ -329,7 +329,7 @@ async fn delete_station(
);
}
Redirect::to(&format!("/route/{route_id}"))
Redirect::to(&format!("/admin/route/{route_id}"))
}
async fn move_station_higher(
@ -343,7 +343,7 @@ async fn move_station_higher(
"Konnte keine Station von Route mit ID {route_id} verschieben, da diese Route nicht existiert."
);
return Redirect::to("/route");
return Redirect::to("/admin/route");
};
let Some(station) = Station::find_by_id(&db, station_id).await else {
err!(
@ -352,7 +352,7 @@ async fn move_station_higher(
route.name
);
return Redirect::to(&format!("/route/{route_id}"));
return Redirect::to(&format!("/admin/route/{route_id}"));
};
if route.move_station_higher(&db, &station).await {
@ -371,7 +371,7 @@ async fn move_station_higher(
);
}
Redirect::to(&format!("/route/{route_id}"))
Redirect::to(&format!("/admin/route/{route_id}"))
}
pub(super) fn routes() -> Router<Arc<SqlitePool>> {

View File

@ -1,4 +1,4 @@
use crate::route::Route;
use crate::admin::route::Route;
use axum::Router;
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
use crate::{er, err, partials::page, station::Station, suc, succ};
use crate::{admin::station::Station, er, err, partials::page, suc, succ};
use axum::{
extract::State,
response::{IntoResponse, Redirect},
@ -33,7 +33,7 @@ async fn create(
),
}
Redirect::to("/station")
Redirect::to("/admin/station")
}
async fn delete(
@ -44,7 +44,7 @@ async fn delete(
let Some(station) = Station::find_by_id(&db, id).await else {
er!(session, t!("station_delete_err_nonexisting", id = id));
return Redirect::to("/station");
return Redirect::to("/admin/station");
};
match station.delete(&db).await {
@ -59,7 +59,7 @@ async fn delete(
),
}
Redirect::to("/station")
Redirect::to("/admin/station")
}
async fn view(
@ -73,19 +73,19 @@ async fn view(
"Station mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
return Err(Redirect::to("/station"));
return Err(Redirect::to("/admin/station"));
};
// maybe switch to maud-display impl of station
let content = html! {
h1 {
a href="/station" { "↩️" }
a href="/admin/station" { "↩️" }
"Station " (station.name)
}
article {
details {
summary { "Stationsname bearbeiten ✏️" }
form action=(format!("/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="submit" value="Speichern";
}
@ -102,7 +102,7 @@ async fn view(
(notes)
details {
summary { "✏️" }
form action=(format!("/station/{}/notes", station.id)) method="post" {
form action=(format!("/admin/station/{}/notes", station.id)) method="post" {
textarea name="notes" required rows="10" { (notes) };
input type="submit" value="Speichern";
}
@ -110,7 +110,7 @@ async fn view(
},
None => details {
summary { "Neue Notiz hinzufügen" }
form action=(format!("/station/{}/notes", station.id)) method="post" {
form action=(format!("/admin/station/{}/notes", station.id)) method="post" {
textarea name="notes" required rows="10" {};
input type="submit" value="Speichern";
}
@ -136,12 +136,12 @@ async fn view(
}
details {
summary { "✏️" }
form action=(format!("/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="submit" value="Speichern";
}
button class="error" {
a href=(format!("/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." {
"?"
}
@ -173,12 +173,12 @@ async fn view(
}
}
@if station.lat.is_some() && station.lng.is_some() {
a href=(format!("/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?');"{
"Standort löschen"
}
}
form action=(format!("/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="lng" id="lng";
input type="submit" value="Neuen Standort speichern" style="display: None;" id="location-submit";
@ -254,7 +254,7 @@ async fn update_name(
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/station");
return Redirect::to("/admin/station");
};
station.update_name(&db, &form.name).await;
@ -266,7 +266,7 @@ async fn update_name(
form.name
);
Redirect::to(&format!("/station/{id}"))
Redirect::to(&format!("/admin/station/{id}"))
}
#[derive(Deserialize)]
@ -285,7 +285,7 @@ async fn update_notes(
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/station");
return Redirect::to("/admin/station");
};
station.update_notes(&db, &form.notes).await;
@ -296,7 +296,7 @@ async fn update_notes(
station.name
);
Redirect::to(&format!("/station/{id}"))
Redirect::to(&format!("/admin/station/{id}"))
}
#[derive(Deserialize)]
@ -315,7 +315,7 @@ async fn update_amount_people(
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/station");
return Redirect::to("/admin/station");
};
station.update_amount_people(&db, form.amount_people).await;
@ -326,7 +326,7 @@ async fn update_amount_people(
station.name
);
Redirect::to(&format!("/station/{id}"))
Redirect::to(&format!("/admin/station/{id}"))
}
async fn update_amount_people_reset(
@ -340,7 +340,7 @@ async fn update_amount_people_reset(
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/station");
return Redirect::to("/admin/station");
};
station.update_amount_people_reset(&db).await;
@ -351,7 +351,7 @@ async fn update_amount_people_reset(
station.name
);
Redirect::to(&format!("/station/{id}"))
Redirect::to(&format!("/admin/station/{id}"))
}
#[derive(Deserialize)]
@ -371,7 +371,7 @@ async fn update_location(
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/station");
return Redirect::to("/admin/station");
};
station.update_location(&db, form.lat, form.lng).await;
@ -382,7 +382,7 @@ async fn update_location(
station.name
);
Redirect::to(&format!("/station/{id}"))
Redirect::to(&format!("/admin/station/{id}"))
}
async fn update_location_clear(
@ -396,7 +396,7 @@ async fn update_location_clear(
"Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/station");
return Redirect::to("/admin/station");
};
station.update_location_clear(&db).await;
@ -407,7 +407,7 @@ async fn update_location_clear(
station.name
);
Redirect::to(&format!("/station/{id}"))
Redirect::to(&format!("/admin/station/{id}"))
}
async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
@ -415,7 +415,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
let content = html! {
h1 {
a href="/" { "↩️" }
a href="/admin/" { "↩️" }
(t!("stations"))
}
article {
@ -433,10 +433,10 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
"⚠️"
}
}
a href=(format!("/station/{}", station.id)){
a href=(format!("/admin/station/{}", station.id)){
(station.name)
}
a href=(format!("/station/{}/delete", station.id))
a href=(format!("/admin/station/{}/delete", station.id))
onclick=(format!("return confirm('{}');", t!("station_confirm_deletion"))) {
"🗑️"
}
@ -449,7 +449,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
}
}
h2 { (t!("station_new")) }
form action="/station" method="post" {
form action="/admin/station" method="post" {
fieldset role="team" {
input type="text" name="name" placeholder=(t!("station_name")) required;
input type="submit" value=(t!("station_new"));

View File

@ -1,4 +1,4 @@
use crate::{route::Route, station::Station};
use crate::admin::{route::Route, station::Station};
use axum::Router;
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, SqlitePool};

View File

@ -1,5 +1,5 @@
use super::{CreateError, Team};
use crate::{err, partials::page, pl, route::Route, station::Station, succ};
use crate::{admin::route::Route, admin::station::Station, err, partials::page, pl, succ};
use axum::{
extract::State,
response::{IntoResponse, Redirect},
@ -31,7 +31,7 @@ async fn create(
form.route_id
);
return Redirect::to("/team");
return Redirect::to("/admin/team");
};
match Team::create(&db, &form.name, &route).await {
@ -49,7 +49,7 @@ async fn create(
),
}
Redirect::to("/team")
Redirect::to("/admin/team")
}
async fn delete(
@ -63,7 +63,7 @@ async fn delete(
"Team mit ID {id} konnte nicht gelöscht werden, da sie nicht existiert"
);
return Redirect::to("/team");
return Redirect::to("/admin/team");
};
match team.delete(&db).await {
@ -75,7 +75,7 @@ async fn delete(
),
}
Redirect::to("/team")
Redirect::to("/admin/team")
}
async fn view(
@ -89,7 +89,7 @@ async fn view(
"Team mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
);
return Err(Redirect::to("/team"));
return Err(Redirect::to("/admin/team"));
};
let first_station = team.first_station(&db).await;
let routes = Route::all(&db).await;
@ -99,13 +99,13 @@ async fn view(
// maybe switch to maud-display impl of team
let content = html! {
h1 {
a href="/team" { "↩️" }
a href="/admin/team" { "↩️" }
"Team " (team.name)
}
article {
details {
summary { "Teamnamen bearbeiten ✏️" }
form action=(format!("/team/{}/name", team.id)) method="post" {
form action=(format!("/admin/team/{}/name", team.id)) method="post" {
input type="text" name="name" value=(team.name) required;
input type="submit" value="Speichern";
}
@ -122,7 +122,7 @@ async fn view(
(notes)
details {
summary { "✏️" }
form action=(format!("/team/{}/notes", team.id)) method="post" {
form action=(format!("/admin/team/{}/notes", team.id)) method="post" {
textarea name="notes" required rows="10" { (notes) };
input type="submit" value="Speichern";
}
@ -130,7 +130,7 @@ async fn view(
},
None => details {
summary { "Neue Notiz hinzufügen" }
form action=(format!("/team/{}/notes", team.id)) method="post" {
form action=(format!("/admin/team/{}/notes", team.id)) method="post" {
textarea name="notes" required rows="10" {};
input type="submit" value="Speichern";
}
@ -147,11 +147,11 @@ async fn view(
}
details {
summary { "✏️" }
form action=(format!("/team/{}/amount-people", team.id)) method="post" {
form action=(format!("/admin/team/{}/amount-people", team.id)) method="post" {
input type="number" name="amount_people" min="0" max="10";
input type="submit" value="Speichern";
}
a href=(format!("/team/{}/amount-people-reset", team.id)) {
a href=(format!("/admin/team/{}/amount-people-reset", team.id)) {
button class="error" {
em data-tooltip="Ich weiß noch nicht wv. Personen dieses Team beherbergt." {
"?"
@ -164,13 +164,13 @@ async fn view(
tr {
th scope="row" { "Route" };
td {
a href=(format!("/route/{}", &team.route(&db).await.id)) {
a href=(format!("/admin/route/{}", &team.route(&db).await.id)) {
(&team.route(&db).await.name)
}
@if routes.len() > 1 {
details {
summary { "✏️" }
form action=(format!("/team/{}/update-route", team.id)) method="post" {
form action=(format!("/admin/team/{}/update-route", team.id)) method="post" {
select name="route_id" aria-label="Route auswählen" required {
@for route in &routes {
@if route.id != team.route(&db).await.id {
@ -194,13 +194,13 @@ async fn view(
}
};
td {
a href=(format!("/station/{}", first_station.id)) {
a href=(format!("/admin/station/{}", first_station.id)) {
(first_station.name)
}
@if stations.len() > 1 {
details {
summary { "✏️" }
form action=(format!("/team/{}/update-first-station", team.id)) method="post" {
form action=(format!("/admin/team/{}/update-first-station", team.id)) method="post" {
select name="first_station_id" aria-label="Station auswählen" required {
@for station in &stations {
@if station.id != first_station.id {
@ -243,7 +243,7 @@ async fn update_name(
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/team");
return Redirect::to("/admin/team");
};
team.update_name(&db, &form.name).await;
@ -255,7 +255,7 @@ async fn update_name(
form.name
);
Redirect::to(&format!("/team/{id}"))
Redirect::to(&format!("/admin/team/{id}"))
}
#[derive(Deserialize)]
@ -274,7 +274,7 @@ async fn update_notes(
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/team");
return Redirect::to("/admin/team");
};
team.update_notes(&db, &form.notes).await;
@ -285,7 +285,7 @@ async fn update_notes(
team.name
);
Redirect::to(&format!("/team/{id}"))
Redirect::to(&format!("/admin/team/{id}"))
}
#[derive(Deserialize)]
@ -304,7 +304,7 @@ async fn update_amount_people(
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/team");
return Redirect::to("/admin/team");
};
team.update_amount_people(&db, form.amount_people).await;
@ -315,7 +315,7 @@ async fn update_amount_people(
team.name
);
Redirect::to(&format!("/team/{id}"))
Redirect::to(&format!("/admin/team/{id}"))
}
#[derive(Deserialize)]
@ -335,7 +335,7 @@ async fn update_route(
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/team");
return Redirect::to("/admin/team");
};
let Some(route) = Route::find_by_id(&db, form.route_id).await else {
@ -345,7 +345,7 @@ async fn update_route(
form.route_id
);
return Redirect::to(&format!("/team/{id}"));
return Redirect::to(&format!("/admin/team/{id}"));
};
match team.update_route(&db, &route).await {
@ -365,7 +365,7 @@ async fn update_route(
),
}
Redirect::to(&format!("/team/{id}"))
Redirect::to(&format!("/admin/team/{id}"))
}
#[derive(Deserialize)]
@ -384,7 +384,7 @@ async fn update_first_station(
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/team");
return Redirect::to("/admin/team");
};
let Some(station) = Station::find_by_id(&db, form.first_station_id).await else {
@ -395,7 +395,7 @@ async fn update_first_station(
team.id
);
return Redirect::to(&format!("/team/{id}"));
return Redirect::to(&format!("/admin/team/{id}"));
};
if !station.is_in_route(&db, &team.route(&db).await).await {
@ -408,7 +408,7 @@ async fn update_first_station(
team.name
);
return Redirect::to(&format!("/team/{id}"));
return Redirect::to(&format!("/admin/team/{id}"));
}
team.update_first_station(&db, &station).await;
@ -420,7 +420,7 @@ async fn update_first_station(
station.name
);
Redirect::to(&format!("/team/{id}"))
Redirect::to(&format!("/admin/team/{id}"))
}
async fn update_amount_people_reset(
@ -434,7 +434,7 @@ async fn update_amount_people_reset(
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
);
return Redirect::to("/team");
return Redirect::to("/admin/team");
};
team.update_amount_people_reset(&db).await;
@ -445,7 +445,7 @@ async fn update_amount_people_reset(
team.name
);
Redirect::to(&format!("/team/{id}"))
Redirect::to(&format!("/admin/team/{id}"))
}
async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
@ -454,24 +454,24 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
let content = html! {
h1 {
a href="/" { "↩️" }
a href="/admin/" { "↩️" }
"Teams"
}
article {
em { "Teams " }
"sind eine Menge an Personen, die verschiedene "
a href="/station" { "Stationen" }
a href="/admin/station" { "Stationen" }
" ablaufen. Welche Stationen, entscheidet sich je nachdem, welcher "
a href="/route" { "Route" }
a href="/admin/route" { "Route" }
" sie zugewiesen sind."
}
ol {
@for team in &teams{
li {
a href=(format!("/team/{}", team.id)){
a href=(format!("/admin/team/{}", team.id)){
(team.name)
}
a href=(format!("/team/{}/delete", team.id))
a href=(format!("/admin/team/{}/delete", team.id))
onclick="return confirm('Bist du sicher, dass das Team gelöscht werden soll? Das kann _NICHT_ mehr rückgängig gemacht werden.');" {
"🗑️"
}
@ -490,12 +490,12 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
@if routes.is_empty() {
article class="error" {
(PreEscaped("Bevor du ein Team erstellen kannst, musst du zumindest eine Route erstellen, die das Team gehen kann &rarr; "))
a role="button" href="/route" {
a role="button" href="/admin/route" {
"Team erstellen"
}
}
} @else {
form action="/team" method="post" {
form action="/admin/team" method="post" {
@if routes.len() == 1 {
fieldset role="team" {
input type="text" name="name" placeholder="Teamnamen" required;

View File

@ -4,18 +4,14 @@ extern crate rust_i18n;
i18n!("locales", fallback = "de-AT");
use axum::{body::Body, response::Response, routing::get, Router};
use maud::{html, Markup};
use partials::page;
use rust_i18n::t;
use sqlx::SqlitePool;
use std::sync::Arc;
use tokio::net::TcpListener;
use tower_sessions::{MemoryStore, Session, SessionManagerLayer};
use tower_sessions::{MemoryStore, SessionManagerLayer};
pub(crate) mod admin;
mod partials;
pub(crate) mod route;
pub(crate) mod station;
pub(crate) mod team;
pub(crate) fn pl(amount: usize, single: &str, append: &str) -> String {
if amount == 1 {
@ -104,42 +100,13 @@ async fn serve_marker_png() -> Response<Body> {
.unwrap()
}
async fn index(session: Session) -> Markup {
let content = html! {
h1 { (t!("app_name")) }
nav {
ul {
li {
a role="button" href="/station" {
(t!("stations"))
}
}
li {
a role="button" href="/route" {
(t!("routes"))
}
}
li {
a role="button" href="/team" {
(t!("teams"))
}
}
}
}
};
page(content, session, false).await
}
/// Starts the main application.
pub async fn start(listener: TcpListener, db: SqlitePool) {
let session_store = MemoryStore::default();
let session_layer = SessionManagerLayer::new(session_store);
let app = Router::new()
.route("/", get(index))
.nest("/station", station::routes())
.nest("/route", route::routes())
.nest("/team", team::routes())
.nest("/admin", admin::routes())
.route("/pico.css", get(serve_pico_css))
.route("/style.css", get(serve_my_css))
.route("/leaflet.css", get(serve_leaflet_css))