Philipp Hofer d20993e6aa
All checks were successful
CI/CD Pipeline / test (push) Successful in 4m16s
CI/CD Pipeline / deploy (push) Successful in 2m55s
show rank in highscore view
2025-04-14 15:40:28 +02:00

149 lines
5.8 KiB
Rust

use crate::{auth::Backend, models::rating::Rating, page, AppState};
use axum::{extract::State, routing::get, Router};
use axum_login::login_required;
use maud::{html, Markup};
use route::Route;
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 highscore(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
let routes = Route::all(&db).await;
let content = html! {
h1 {
a href="/admin" { "↩️" }
"Highscore"
}
@for (idx, route) in routes.into_iter().enumerate() {
details open[idx==0] {
summary { (route.name) }
div class="overflow-auto" {
table {
thead {
tr {
td { "Team" }
@for station in route.stations(&db).await {
td {
a href=(format!("/admin/station/{}", station.id)){
(station.name)
}
}
}
td { "Gesamtpunkte" }
td { "Rang" }
td { "Team" }
}
}
tbody {
@let mut rank = 0;
@let mut amount_teams_iterated = 0;
@let mut prev_points = i64::MAX;
@for team in route.teams_ordered_by_points(&db).await {
@let mut total_points = 0;
({ amount_teams_iterated += 1;"" })
tr {
td {
a href=(format!("/admin/team/{}", team.id)) {
(team.name)
}
}
@for station in route.stations(&db).await {
td {
@if let Some(rating) = Rating::find_by_team_and_station(&db, &team, &station).await {
@if let (Some(notes), Some(points)) = (rating.notes, rating.points) {
({total_points += points;""})
em data-placement="bottom" data-tooltip=(notes) { (points) }
}@else if let Some(points) = rating.points {
({total_points += points;""})
(points)
}@else {
em data-placement="bottom" data-tooltip="Station hat Team noch nicht bewertet" {
"?"
}
}
}
}
}
td { (total_points) }
td {
@if total_points < prev_points {
({rank = amount_teams_iterated; ""})
({ prev_points = total_points;"" })
}
(rank)
"."
}
td {
a href=(format!("/admin/team/{}", team.id)) {
(team.name)
}
}
}
}
}
}
}
}
}
};
page(content, session, false).await
}
async fn index(session: Session) -> Markup {
let content = html! {
nav {
ul {
img class="logo" src="/logo-hor.svg" style="max-width: 100%; width: 25em; margin:auto;";
img class="logo-inv" src="/logo-hor-inv.svg" width="max-width: 100%; width: 25em; margin:auto;";
}
ul {
a href="/auth/logout" {
"Ausloggen"
}
}
}
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"))
}
}
li {
a role="button" href="/admin/highscore" {
"Highscore"
}
}
}
}
};
page(content, session, false).await
}
pub(super) fn routes() -> Router<AppState> {
Router::new()
.route("/", get(index))
.route("/highscore", get(highscore))
.nest("/station", station::routes())
.nest("/route", route::routes())
.nest("/team", team::routes())
.layer(login_required!(Backend, login_url = "/auth/login"))
}