149 lines
5.8 KiB
Rust
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"))
|
|
}
|