Reviewed-on: #95
This commit is contained in:
commit
e4da952a62
@ -36,6 +36,36 @@ ORDER BY rowed_km DESC;
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn guest(db: &SqlitePool, year: Option<i32>) -> Stat {
|
||||||
|
let year = match year {
|
||||||
|
Some(year) => year,
|
||||||
|
None => chrono::Utc::now().year(),
|
||||||
|
};
|
||||||
|
//TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server)
|
||||||
|
let rowed_km = sqlx::query(&format!(
|
||||||
|
"
|
||||||
|
SELECT SUM((b.amount_seats - COALESCE(m.member_count, 0)) * l.distance_in_km) as total_guest_km
|
||||||
|
FROM logbook l
|
||||||
|
JOIN boat b ON l.boat_id = b.id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT logbook_id, COUNT(*) as member_count
|
||||||
|
FROM rower
|
||||||
|
GROUP BY logbook_id
|
||||||
|
) m ON l.id = m.logbook_id
|
||||||
|
WHERE l.distance_in_km IS NOT NULL AND l.arrival LIKE '{year}-%' AND b.name != 'Externes Boot';
|
||||||
|
"
|
||||||
|
))
|
||||||
|
.fetch_one(db)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.get::<i64, usize>(0);
|
||||||
|
|
||||||
|
Stat {
|
||||||
|
name: "Gäste".into(),
|
||||||
|
rowed_km: rowed_km as i32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn people(db: &SqlitePool, year: Option<i32>) -> Vec<Stat> {
|
pub async fn people(db: &SqlitePool, year: Option<i32>) -> Vec<Stat> {
|
||||||
let year = match year {
|
let year = match year {
|
||||||
Some(year) => year,
|
Some(year) => year,
|
||||||
|
@ -35,23 +35,25 @@ async fn index_boat_kiosk(
|
|||||||
#[get("/?<year>", rank = 2)]
|
#[get("/?<year>", rank = 2)]
|
||||||
async fn index(db: &State<SqlitePool>, user: NonGuestUser, year: Option<i32>) -> Template {
|
async fn index(db: &State<SqlitePool>, user: NonGuestUser, year: Option<i32>) -> Template {
|
||||||
let stat = Stat::people(db, year).await;
|
let stat = Stat::people(db, year).await;
|
||||||
|
let guest_km = Stat::guest(db, year).await;
|
||||||
let personal = stat::get_personal(db, &user.user).await;
|
let personal = stat::get_personal(db, &user.user).await;
|
||||||
let kiosk = false;
|
let kiosk = false;
|
||||||
|
|
||||||
Template::render(
|
Template::render(
|
||||||
"stat.people",
|
"stat.people",
|
||||||
context!(loggedin_user: &user.user, stat, personal, kiosk),
|
context!(loggedin_user: &user.user, stat, personal, kiosk, guest_km),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/?<year>")]
|
#[get("/?<year>")]
|
||||||
async fn index_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie, year: Option<i32>) -> Template {
|
async fn index_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie, year: Option<i32>) -> Template {
|
||||||
let stat = Stat::people(db, year).await;
|
let stat = Stat::people(db, year).await;
|
||||||
|
let guest_km = Stat::guest(db, year).await;
|
||||||
let kiosk = true;
|
let kiosk = true;
|
||||||
|
|
||||||
Template::render(
|
Template::render(
|
||||||
"stat.people",
|
"stat.people",
|
||||||
context!(stat, kiosk, show_kiosk_header: true),
|
context!(stat, kiosk, show_kiosk_header: true, guest_km),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,37 +5,66 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
|
||||||
<div class="max-w-screen-lg w-full">
|
<div class="max-w-screen-lg w-full">
|
||||||
<h1 class="h1">Statistik <select id="yearSelect" onchange="changeYear()" style="background: transparent; background-image: none; text-decoration: underline;"></select></h1>
|
<h1 class="h1">
|
||||||
<div class="search-wrapper">
|
Statistik
|
||||||
<label for="name" class="sr-only">Suche</label>
|
<select
|
||||||
<input type="search" name="name" id="filter-js" class="search-bar" placeholder="Suchen nach Namen...">
|
id="yearSelect"
|
||||||
|
onchange="changeYear()"
|
||||||
|
style="
|
||||||
|
background: transparent;
|
||||||
|
background-image: none;
|
||||||
|
text-decoration: underline;
|
||||||
|
"
|
||||||
|
></select>
|
||||||
|
</h1>
|
||||||
|
<div class="search-wrapper">
|
||||||
|
<label for="name" class="sr-only">Suche</label>
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
name="name"
|
||||||
|
id="filter-js"
|
||||||
|
class="search-bar"
|
||||||
|
placeholder="Suchen nach Namen..."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="filter-result-js" class="search-result"></div>
|
||||||
|
|
||||||
|
<div class="border-r border-l border-gray-200 dark:border-primary-600">
|
||||||
|
{% set_global km = 0 %} {% set_global index = 1 %} {% for s in stat %}
|
||||||
|
<div
|
||||||
|
class="border-t border-gray-200 dark:border-primary-600 {% if loop.last %} border-b {% endif %} bg-white dark:bg-primary-900 text-black dark:text-white flex justify-between items-center px-3 py-1"
|
||||||
|
data-filterable="true"
|
||||||
|
data-filter="{{ s.name }}"
|
||||||
|
>
|
||||||
|
<span class="text-sm text-gray-600 dark:text-gray-100 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>
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<div
|
||||||
|
class="border-t border-gray-200 dark:border-primary-600 {% if loop.last %} border-b {% endif %} bg-white dark:bg-primary-900 text-black dark:text-white flex justify-between items-center px-3 py-1"
|
||||||
|
data-filterable="true"
|
||||||
|
data-filter="{{ guest_km.name }}"
|
||||||
|
>
|
||||||
|
<span class="text-sm text-gray-600 dark:text-gray-100 w-10">
|
||||||
|
</span>
|
||||||
|
<span class="grow">{{ guest_km.name }}</span>
|
||||||
|
<span>{{ guest_km.rowed_km }} km</span>
|
||||||
|
|
||||||
<div id="filter-result-js" class="search-result"></div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="border-r border-l border-gray-200 dark:border-primary-600">
|
<div id="container" class="w-full"></div>
|
||||||
{% set_global km = 0 %}
|
</div>
|
||||||
{% set_global index = 1 %}
|
|
||||||
{% for s in stat %}
|
|
||||||
<div class="border-t border-gray-200 dark:border-primary-600 {% if loop.last %} border-b {% endif %} bg-white dark:bg-primary-900 text-black dark:text-white flex justify-between items-center px-3 py-1" data-filterable="true" data-filter="{{ s.name }}">
|
|
||||||
<span class="text-sm text-gray-600 dark:text-gray-100 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>
|
<script>
|
||||||
{% if personal %}
|
{% if personal %}
|
||||||
|
Loading…
Reference in New Issue
Block a user