show stations their location; Fixes #17
All checks were successful
CI/CD Pipeline / test (push) Successful in 2m53s
CI/CD Pipeline / deploy (push) Successful in 2m20s

This commit is contained in:
Philipp Hofer 2025-04-11 22:33:10 +02:00
parent e81a994074
commit a601507435
8 changed files with 76 additions and 21 deletions

View File

@ -1,8 +1,8 @@
use super::team::Team;
use crate::{
AppState,
admin::route::Route,
models::rating::{Rating, TeamsAtStationLocation},
AppState,
};
use axum::Router;
use chrono::{DateTime, Local, NaiveDateTime, Utc};
@ -19,8 +19,8 @@ pub(crate) struct Station {
amount_people: Option<i64>,
last_login: Option<NaiveDateTime>, // TODO use proper timestamp (NaiveDateTime?)
pub(crate) pw: String,
lat: Option<f64>,
lng: Option<f64>,
pub(crate) lat: Option<f64>,
pub(crate) lng: Option<f64>,
}
impl Station {
@ -81,7 +81,10 @@ impl Station {
let teams = TeamsAtStationLocation::for_station(db, self).await;
if !teams.not_yet_here.contains(team) {
return Err(format!("Kann Team nicht der Warteschlange hinzufügen, weil das Team {} nicht zu deiner Station kommen soll.", team.name));
return Err(format!(
"Kann Team nicht der Warteschlange hinzufügen, weil das Team {} nicht zu deiner Station kommen soll.",
team.name
));
}
Rating::create(db, self, team).await?;
@ -132,7 +135,10 @@ impl Station {
let waiting_teams: Vec<&Team> = teams.waiting.iter().map(|(team, _)| team).collect();
if !waiting_teams.contains(&team) {
return Err(format!("Kann Team nicht von der Warteschlange gelöscht werden, weil das Team {} nicht in der Warteschlange ist.", team.name));
return Err(format!(
"Kann Team nicht von der Warteschlange gelöscht werden, weil das Team {} nicht in der Warteschlange ist.",
team.name
));
}
Rating::delete(db, self, team).await?;

View File

@ -1,17 +1,18 @@
use crate::{
AppState,
admin::station::Station,
er, err,
models::rating::{Rating, TeamsAtStationLocation},
partials::page,
suc, succ, AppState,
suc, succ,
};
use axum::{
Form, Router,
extract::State,
response::{IntoResponse, Redirect},
routing::{get, post},
Form, Router,
};
use maud::{html, Markup};
use maud::{Markup, html};
use serde::Deserialize;
use sqlx::SqlitePool;
use std::sync::Arc;
@ -506,7 +507,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
}
tbody {
@for station in &stations {
@let status = TeamsAtStationLocation::for_station(&db, &station).await;
@let status = TeamsAtStationLocation::for_station(&db, station).await;
tr {
td {
@if station.routes(&db).await.is_empty() {

View File

@ -1,6 +1,6 @@
use crate::{
admin::{route::Route, station::Station},
AppState,
admin::{route::Route, station::Station},
};
use axum::Router;
use chrono::{DateTime, Local, NaiveDateTime, Utc};

View File

@ -1,17 +1,18 @@
use super::{CreateError, LastContactTeam, Team};
use crate::{
AppState,
admin::{route::Route, station::Station},
err,
partials::page,
pl, succ, AppState,
pl, succ,
};
use axum::{
Form, Router,
extract::State,
response::{IntoResponse, Redirect},
routing::{get, post},
Form, Router,
};
use maud::{html, Markup, PreEscaped};
use maud::{Markup, PreEscaped, html};
use serde::Deserialize;
use sqlx::SqlitePool;
use std::sync::Arc;

View File

@ -17,7 +17,7 @@ macro_rules! testdb {
i18n!("locales", fallback = "de-AT");
use admin::station::Station;
use axum::{body::Body, extract::FromRef, response::Response, routing::get, Router};
use axum::{Router, body::Body, extract::FromRef, response::Response, routing::get};
use partials::page;
use sqlx::SqlitePool;
use std::sync::Arc;

View File

@ -1,4 +1,4 @@
use crate::{admin::team::Team, Station};
use crate::{Station, admin::team::Team};
use chrono::{DateTime, Local, NaiveDateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, SqlitePool};

View File

@ -1,4 +1,4 @@
use maud::{html, Markup, DOCTYPE};
use maud::{DOCTYPE, Markup, html};
use tower_sessions::Session;
pub(crate) async fn page(content: Markup, session: Session, leaflet: bool) -> Markup {

View File

@ -37,6 +37,35 @@ async fn view(
let content = html! {
h1 { (format!("Station {}", station.name)) }
@if let (Some(lat), Some(lng)) = (station.lat, station.lng) {
article {
b { "Hier befindet sich deine Station:" }
div id="map" style="height: 500px" {}
script { (format!("
const map = L.map('map').setView([{lat}, {lng}], 14);
L.tileLayer('https://{{s}}.tile.openstreetmap.org/{{z}}/{{x}}/{{y}}.png', {{
attribution: '© OpenStreetMap contributors'
}}).addTo(map);
const myIcon = L.icon({{
iconUrl: '/marker.png',
iconAnchor: [12, 41]
}});
currentMarker = L.marker([{lat}, {lng}], {{icon: myIcon}}).addTo(map);
map.setView([lat, lng], 14);
"))
}
sub {
a href=(format!("https://www.google.com/maps?q={lat},{lng}")) target="_blank" {
"Google Maps..."
}
}
}
}
article {
"Insgesamt sollten "
(teams.total_teams)
@ -200,7 +229,9 @@ async fn view(
};
partials::page(content, session, false).await
let use_map = station.lat.is_some() && station.lng.is_some();
partials::page(content, session, use_map).await
}
#[derive(Deserialize)]
@ -221,7 +252,11 @@ async fn new_waiting(
return Redirect::to("/s/{id}/{code}");
};
let Some(team) = Team::find_by_id(&db, form.team_id).await else {
err!(session, "Konnte das Team der Warteschlange nicht hinzufügen, weil ein Team mit ID {} nicht existiert", form.team_id);
err!(
session,
"Konnte das Team der Warteschlange nicht hinzufügen, weil ein Team mit ID {} nicht existiert",
form.team_id
);
return Redirect::to("/s/{id}/{code}");
};
@ -247,7 +282,11 @@ async fn remove_waiting(
};
let Some(team) = Team::find_by_id(&db, team_id).await else {
err!(session, "Konnte das Team nicht von der Warteschlange entfernen, weil ein Team mit ID {} nicht existiert", team_id);
err!(
session,
"Konnte das Team nicht von der Warteschlange entfernen, weil ein Team mit ID {} nicht existiert",
team_id
);
return Redirect::to("/s/{id}/{code}");
};
@ -303,7 +342,11 @@ async fn remove_doing(
};
let Some(team) = Team::find_by_id(&db, team_id).await else {
err!(session, "Konnte das Team nicht zur Warteschlange hinzufügen, weil ein Team mit ID {} nicht existiert", team_id);
err!(
session,
"Konnte das Team nicht zur Warteschlange hinzufügen, weil ein Team mit ID {} nicht existiert",
team_id
);
return Redirect::to("/s/{id}/{code}");
};
@ -359,7 +402,11 @@ async fn remove_left(
};
let Some(team) = Team::find_by_id(&db, team_id).await else {
err!(session, "Konnte das Team nicht zur Arbeits-Position hinzufügen, weil ein Team mit ID {} nicht existiert", team_id);
err!(
session,
"Konnte das Team nicht zur Arbeits-Position hinzufügen, weil ein Team mit ID {} nicht existiert",
team_id
);
return Redirect::to("/s/{id}/{code}");
};