allow quick add of teams
This commit is contained in:
parent
6d0bd31f07
commit
7069cc363e
@ -2,6 +2,7 @@ use super::{CreateError, LastContactTeam, Team};
|
|||||||
use crate::{
|
use crate::{
|
||||||
admin::{route::Route, station::Station},
|
admin::{route::Route, station::Station},
|
||||||
err,
|
err,
|
||||||
|
models::rating::Rating,
|
||||||
partials::page,
|
partials::page,
|
||||||
pl, succ, AppState,
|
pl, succ, AppState,
|
||||||
};
|
};
|
||||||
@ -14,7 +15,7 @@ use axum::{
|
|||||||
use maud::{html, Markup, PreEscaped};
|
use maud::{html, Markup, PreEscaped};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
use std::sync::Arc;
|
use std::{collections::HashMap, sync::Arc};
|
||||||
use tower_sessions::Session;
|
use tower_sessions::Session;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@ -94,6 +95,142 @@ async fn delete(
|
|||||||
Redirect::to("/admin/team")
|
Redirect::to("/admin/team")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn quick(
|
||||||
|
State(db): State<Arc<SqlitePool>>,
|
||||||
|
session: Session,
|
||||||
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
|
) -> Result<Markup, impl IntoResponse> {
|
||||||
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
|
err!(
|
||||||
|
session,
|
||||||
|
"Team mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert"
|
||||||
|
);
|
||||||
|
|
||||||
|
return Err(Redirect::to("/admin/team"));
|
||||||
|
};
|
||||||
|
|
||||||
|
let stations = team.route(&db).await.stations(&db).await;
|
||||||
|
|
||||||
|
// maybe switch to maud-display impl of team
|
||||||
|
let content = html! {
|
||||||
|
h1 {
|
||||||
|
a href=(format!("/admin/team/{}", team.id)) { "↩️" }
|
||||||
|
"Bewertungen Team " (team.name)
|
||||||
|
}
|
||||||
|
form action=(format!("/admin/team/{}/quick", team.id)) method="post" {
|
||||||
|
table {
|
||||||
|
thead {
|
||||||
|
tr {
|
||||||
|
th { "Station" }
|
||||||
|
th { "Punkte" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tbody {
|
||||||
|
@for station in &stations {
|
||||||
|
tr {
|
||||||
|
td {
|
||||||
|
a href=(format!("/admin/station/{}", station.id)) {
|
||||||
|
(station.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
@if let Some(rating) = Rating::find_by_team_and_station(&db, &team, &station).await {
|
||||||
|
a href=(format!("/s/{}/{}", station.id, station.pw)){
|
||||||
|
@if let Some(points) = rating.points {
|
||||||
|
em data-tooltip="Schon eingetragen" {
|
||||||
|
(points)
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
em data-tooltip="Team gerade bei Station" { "?" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
input type="number" min="0" max="10" name=(station.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input type="submit" value="Speichern";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(page(content, session, true).await)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct QuickUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
fields: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
async fn quick_post(
|
||||||
|
State(db): State<Arc<SqlitePool>>,
|
||||||
|
session: Session,
|
||||||
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
|
Form(form): Form<QuickUpdate>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let Some(team) = Team::find_by_id(&db, id).await else {
|
||||||
|
err!(
|
||||||
|
session,
|
||||||
|
"Team mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert"
|
||||||
|
);
|
||||||
|
|
||||||
|
return Redirect::to("/admin/team");
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut ret = String::new();
|
||||||
|
let mut amount_succ = 0;
|
||||||
|
|
||||||
|
for (station_id, points) in form.fields.iter() {
|
||||||
|
let Ok(station_id) = station_id.parse::<i64>() else {
|
||||||
|
ret.push_str(&format!(
|
||||||
|
"Skipped stationid={station_id} because this id can't be parsed as i64"
|
||||||
|
));
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Ok(points) = points.parse::<i64>() else {
|
||||||
|
ret.push_str(&format!(
|
||||||
|
"Skipped stationid={station_id} because points {} can't be parsed as i64",
|
||||||
|
points
|
||||||
|
));
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(station) = Station::find_by_id(&db, station_id).await else {
|
||||||
|
ret.push_str(&format!(
|
||||||
|
"Skipped stationid={station_id} because this station does not exist"
|
||||||
|
));
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if Rating::find_by_team_and_station(&db, &team, &station)
|
||||||
|
.await
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
ret.push_str(&format!("Skipped rating for station {} because this station already has a rating for team {}", station.name, team.name));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rating::create_quick(&db, &team, &station, points).await;
|
||||||
|
amount_succ += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ret.is_empty() {
|
||||||
|
// TODO: properly log warnings
|
||||||
|
println!("{ret}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if amount_succ == 0 {
|
||||||
|
succ!(
|
||||||
|
session,
|
||||||
|
"Du hast keine Bewertungen eingegeben... Spaßvogel!"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
succ!(session, "Erfolgreich {amount_succ} Bewertungen eingetragen");
|
||||||
|
}
|
||||||
|
|
||||||
|
Redirect::to(&format!("/admin/team/{id}/quick"))
|
||||||
|
}
|
||||||
|
|
||||||
async fn view(
|
async fn view(
|
||||||
State(db): State<Arc<SqlitePool>>,
|
State(db): State<Arc<SqlitePool>>,
|
||||||
session: Session,
|
session: Session,
|
||||||
@ -239,6 +376,13 @@ async fn view(
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
a href=(format!("/admin/team/{}/quick", team.id)){
|
||||||
|
button {
|
||||||
|
"Stations-Bewertungen für Team "
|
||||||
|
(team.name)
|
||||||
|
" eingeben"
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ok(page(content, session, true).await)
|
Ok(page(content, session, true).await)
|
||||||
}
|
}
|
||||||
@ -599,6 +743,8 @@ pub(super) fn routes() -> Router<AppState> {
|
|||||||
.route("/lost", get(lost))
|
.route("/lost", get(lost))
|
||||||
.route("/{id}", get(view))
|
.route("/{id}", get(view))
|
||||||
.route("/{id}/delete", get(delete))
|
.route("/{id}/delete", get(delete))
|
||||||
|
.route("/{id}/quick", post(quick_post))
|
||||||
|
.route("/{id}/quick", get(quick))
|
||||||
.route("/{id}/name", post(update_name))
|
.route("/{id}/name", post(update_name))
|
||||||
.route("/{id}/notes", post(update_notes))
|
.route("/{id}/notes", post(update_notes))
|
||||||
.route("/{id}/amount-people", post(update_amount_people))
|
.route("/{id}/amount-people", post(update_amount_people))
|
||||||
|
@ -31,6 +31,18 @@ impl Rating {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn create_quick(db: &SqlitePool, team: &Team, station: &Station, points: i64) {
|
||||||
|
sqlx::query!(
|
||||||
|
"INSERT INTO rating(team_id, station_id, points, arrived_at, started_at, left_at) VALUES (?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)",
|
||||||
|
team.id,
|
||||||
|
station.id,
|
||||||
|
points
|
||||||
|
)
|
||||||
|
.execute(db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) async fn team(&self, db: &SqlitePool) -> Team {
|
pub(crate) async fn team(&self, db: &SqlitePool) -> Team {
|
||||||
Team::find_by_id(db, self.team_id)
|
Team::find_by_id(db, self.team_id)
|
||||||
.await
|
.await
|
||||||
|
Loading…
x
Reference in New Issue
Block a user