move to /admimn
This commit is contained in:
parent
d69f2ee13e
commit
bacce1c55a
@ -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
44
src/admin/mod.rs
Normal 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())
|
||||
}
|
@ -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};
|
@ -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 → "))
|
||||
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>> {
|
@ -1,4 +1,4 @@
|
||||
use crate::route::Route;
|
||||
use crate::admin::route::Route;
|
||||
use axum::Router;
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::{Deserialize, Serialize};
|
@ -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"));
|
@ -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};
|
@ -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 → "))
|
||||
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;
|
39
src/lib.rs
39
src/lib.rs
@ -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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user