diff --git a/src/admin/station/web.rs b/src/admin/station/web.rs index 3f6a17a..c8254c1 100644 --- a/src/admin/station/web.rs +++ b/src/admin/station/web.rs @@ -1,5 +1,5 @@ use crate::{ - admin::station::Station, + admin::{station::Station, team::Team}, er, err, models::rating::{Rating, TeamsAtStationLocation}, partials::page, @@ -14,7 +14,7 @@ use axum::{ use maud::{html, Markup}; use serde::Deserialize; use sqlx::SqlitePool; -use std::sync::Arc; +use std::{collections::HashMap, sync::Arc}; use tower_sessions::Session; #[derive(Deserialize)] @@ -233,6 +233,13 @@ async fn view( } } } + a href=(format!("/admin/station/{}/quick", station.id)){ + button { + "Bewertungen für Station " + (station.name) + " eingeben" + } + } @@ -427,6 +434,145 @@ async fn update_amount_people_reset( Redirect::to(&format!("/admin/station/{id}")) } +async fn quick( + State(db): State>, + session: Session, + axum::extract::Path(id): axum::extract::Path, +) -> Result { + let Some(station) = Station::find_by_id(&db, id).await else { + err!( + session, + "Station mit ID {id} konnte nicht geöffnet werden, da sie nicht existiert" + ); + + return Err(Redirect::to("/admin/station")); + }; + + let teams = station.teams(&db).await; + + // maybe switch to maud-display impl of team + let content = html! { + h1 { + a href=(format!("/admin/station/{}", station.id)) { "↩️" } + "Bewertungen Station " (station.name) + } + form action=(format!("/admin/station/{}/quick", station.id)) method="post" { + table { + thead { + tr { + th { "Team" } + th { "Punkte" } + } + } + tbody { + @for team in &teams { + tr { + td { + a href=(format!("/admin/team/{}", team.id)) { + (team.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=(team.id); + } + } + + } + } + } + } + input type="submit" value="Speichern"; + } + }; + Ok(page(content, session, true).await) +} + +#[derive(Deserialize, Debug)] +struct QuickUpdate { + #[serde(flatten)] + fields: HashMap, +} +async fn quick_post( + State(db): State>, + session: Session, + axum::extract::Path(id): axum::extract::Path, + Form(form): Form, +) -> impl IntoResponse { + let Some(station) = Station::find_by_id(&db, id).await else { + err!( + session, + "Station mit ID {id} konnte nicht bearbeitet werden, da sie nicht existiert" + ); + + return Redirect::to("/admin/station"); + }; + + let mut ret = String::new(); + let mut amount_succ = 0; + + for (team_id, points) in form.fields.iter() { + let Ok(team_id) = team_id.parse::() else { + ret.push_str(&format!( + "Skipped team_id={team_id} because this id can't be parsed as i64" + )); + continue; + }; + let Ok(points) = points.parse::() else { + ret.push_str(&format!( + "Skipped team_id={team_id} because points {} can't be parsed as i64", + points + )); + continue; + }; + let Some(team) = Team::find_by_id(&db, team_id).await else { + ret.push_str(&format!( + "Skipped team_id={team_id} because this team does not exist" + )); + continue; + }; + if Rating::find_by_team_and_station(&db, &team, &station) + .await + .is_some() + { + ret.push_str(&format!( + "Skipped rating for team {} because this team already has a rating for station {}", + team.name, station.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/station/{id}/quick")) +} + #[derive(Deserialize)] struct UpdateLocationForm { lat: f64, @@ -566,6 +712,8 @@ pub(super) fn routes() -> Router { .route("/", post(create)) .route("/{id}", get(view)) .route("/{id}/delete", get(delete)) + .route("/{id}/quick", get(quick)) + .route("/{id}/quick", post(quick_post)) .route("/{id}/name", post(update_name)) .route("/{id}/notes", post(update_notes)) .route("/{id}/amount-people", post(update_amount_people)) diff --git a/src/admin/team/web.rs b/src/admin/team/web.rs index 87d04fc..b96782e 100644 --- a/src/admin/team/web.rs +++ b/src/admin/team/web.rs @@ -134,7 +134,7 @@ async fn quick( } } td { - @if let Some(rating) = Rating::find_by_team_and_station(&db, &team, &station).await { + @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" { @@ -743,8 +743,8 @@ pub(super) fn routes() -> Router { .route("/lost", get(lost)) .route("/{id}", get(view)) .route("/{id}/delete", get(delete)) - .route("/{id}/quick", post(quick_post)) .route("/{id}/quick", get(quick)) + .route("/{id}/quick", post(quick_post)) .route("/{id}/name", post(update_name)) .route("/{id}/notes", post(update_notes)) .route("/{id}/amount-people", post(update_amount_people))