Merge branch 'boat-stats' into 'staging'
add boat stats Fixes #50 Closes #50 See merge request PhilippHofer/rot!58
This commit is contained in:
		@@ -9,7 +9,28 @@ pub struct Stat {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Stat {
 | 
			
		||||
    pub async fn get_rowed_km(db: &SqlitePool) -> Vec<Stat> {
 | 
			
		||||
    pub async fn boats(db: &SqlitePool) -> Vec<Stat> {
 | 
			
		||||
        //TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server)
 | 
			
		||||
        sqlx::query(
 | 
			
		||||
            "
 | 
			
		||||
SELECT (SELECT name FROM boat WHERE id=logbook.boat_id) as name, CAST(SUM(distance_in_km) AS INTEGER) AS rowed_km
 | 
			
		||||
FROM logbook
 | 
			
		||||
GROUP BY boat_id 
 | 
			
		||||
ORDER BY rowed_km DESC;
 | 
			
		||||
",
 | 
			
		||||
        )
 | 
			
		||||
        .fetch_all(db)
 | 
			
		||||
        .await
 | 
			
		||||
        .unwrap()
 | 
			
		||||
        .into_iter()
 | 
			
		||||
        .map(|row| Stat {
 | 
			
		||||
            name: row.get("name"),
 | 
			
		||||
            rowed_km: row.get("rowed_km"),
 | 
			
		||||
        })
 | 
			
		||||
        .collect()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn people(db: &SqlitePool) -> Vec<Stat> {
 | 
			
		||||
        //TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server)
 | 
			
		||||
        sqlx::query(
 | 
			
		||||
            "
 | 
			
		||||
 
 | 
			
		||||
@@ -9,28 +9,50 @@ use crate::model::{
 | 
			
		||||
 | 
			
		||||
use super::log::KioskCookie;
 | 
			
		||||
 | 
			
		||||
#[get("/boats", rank = 2)]
 | 
			
		||||
async fn index_boat(db: &State<SqlitePool>, user: NonGuestUser) -> Template {
 | 
			
		||||
    let stat = Stat::boats(db).await;
 | 
			
		||||
    let kiosk = false;
 | 
			
		||||
 | 
			
		||||
    Template::render(
 | 
			
		||||
        "stat.boats",
 | 
			
		||||
        context!(loggedin_user: &user.user, stat, kiosk),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[get("/boats")]
 | 
			
		||||
async fn index_boat_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie) -> Template {
 | 
			
		||||
    let stat = Stat::boats(db).await;
 | 
			
		||||
    let kiosk = true;
 | 
			
		||||
 | 
			
		||||
    Template::render("stat.boats", context!(stat, kiosk, show_kiosk_header: true))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[get("/", rank = 2)]
 | 
			
		||||
async fn index(db: &State<SqlitePool>, user: NonGuestUser) -> Template {
 | 
			
		||||
    let stat = Stat::get_rowed_km(db).await;
 | 
			
		||||
    let stat = Stat::people(db).await;
 | 
			
		||||
    let personal = stat::get_personal(db, &user.user).await;
 | 
			
		||||
    let kiosk = false;
 | 
			
		||||
 | 
			
		||||
    Template::render(
 | 
			
		||||
        "stat",
 | 
			
		||||
        "stat.people",
 | 
			
		||||
        context!(loggedin_user: &user.user, stat, personal, kiosk),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[get("/")]
 | 
			
		||||
async fn index_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie) -> Template {
 | 
			
		||||
    let stat = Stat::get_rowed_km(db).await;
 | 
			
		||||
    let stat = Stat::people(db).await;
 | 
			
		||||
    let kiosk = true;
 | 
			
		||||
 | 
			
		||||
    Template::render("stat", context!(stat, kiosk, show_kiosk_header: true))
 | 
			
		||||
    Template::render(
 | 
			
		||||
        "stat.people",
 | 
			
		||||
        context!(stat, kiosk, show_kiosk_header: true),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn routes() -> Vec<Route> {
 | 
			
		||||
    routes![index, index_kiosk]
 | 
			
		||||
    routes![index, index_kiosk, index_boat, index_boat_kiosk]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,10 @@
 | 
			
		||||
                Logbuch
 | 
			
		||||
              </a>
 | 
			
		||||
              <a href="/stat" class="block w-100 py-2 hover:text-primary-600 border-t">
 | 
			
		||||
                Statistik
 | 
			
		||||
                Personen-Statistik
 | 
			
		||||
              </a>
 | 
			
		||||
              <a href="/stat/boats" class="block w-100 py-2 hover:text-primary-600 border-t">
 | 
			
		||||
                Boots-Statistik
 | 
			
		||||
              </a>
 | 
			
		||||
	      {% if loggedin_user.is_admin %}
 | 
			
		||||
              	<a href="/admin/boat" class="block w-100 py-2 hover:text-primary-600 border-t">
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								templates/stat.boats.html.tera
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								templates/stat.boats.html.tera
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
{% import "includes/macros" as macros %}
 | 
			
		||||
 | 
			
		||||
{% extends "base" %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
	<div class="max-w-screen-lg w-full">
 | 
			
		||||
		<h1 class="h1">Boots-Statistik</h1>
 | 
			
		||||
		<div class="bg-gray-200 p-3 mt-4 rounded-t-md">
 | 
			
		||||
			<label for="name" class="sr-only">Suche</label>
 | 
			
		||||
			<input type="search" name="name" id="filter-js" class="w-full relative block rounded-md border-0 py-1.5 px-2 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6 mb-2 md:mb-0" placeholder="Suchen nach Bootsnamen...">
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<div id="filter-result-js" class="bg-gray-200 text-primary-950 pb-3 px-3 text-right"></div>
 | 
			
		||||
 | 
			
		||||
		<div class="border-r border-l">
 | 
			
		||||
			{% set_global km = 0 %}
 | 
			
		||||
			{% set_global index = 1 %}
 | 
			
		||||
			{% for s in stat %}
 | 
			
		||||
				<div class="border-t {% if loop.last %} border-b {% endif %} bg-white flex justify-between items-center px-3 py-1" data-filterable="true" data-filter="{{ s.name }}">
 | 
			
		||||
					<span class="text-sm text-gray-600 w-10">
 | 
			
		||||
						{% if km != s.rowed_km %}
 | 
			
		||||
							{{loop.index}}
 | 
			
		||||
							{% set_global index = loop.index %}
 | 
			
		||||
						{% else %}
 | 
			
		||||
							{{ index }}
 | 
			
		||||
						{% endif %}
 | 
			
		||||
					</span>
 | 
			
		||||
					<span class="grow">{{s.name}}</span>
 | 
			
		||||
					<span>{{s.rowed_km}}
 | 
			
		||||
						km</span>
 | 
			
		||||
 | 
			
		||||
					{% set_global km = s.rowed_km %}
 | 
			
		||||
				</div>
 | 
			
		||||
			{% endfor %}
 | 
			
		||||
		</div>
 | 
			
		||||
		<div id="container" class="w-full"></div>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<script src="/public/logbook.js"></script>
 | 
			
		||||
{% endblock content%}
 | 
			
		||||
		Reference in New Issue
	
	Block a user