diff --git a/src/model/mod.rs b/src/model/mod.rs index 1af7c21..46446db 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -25,6 +25,7 @@ pub mod logbook; pub mod logtype; pub mod mail; pub mod notification; +pub mod personal; pub mod role; pub mod rower; pub mod stat; diff --git a/src/model/personal/equatorprice.rs b/src/model/personal/equatorprice.rs new file mode 100644 index 0000000..ef67ce5 --- /dev/null +++ b/src/model/personal/equatorprice.rs @@ -0,0 +1,58 @@ +use serde::Serialize; + +#[derive(Serialize)] +enum Level { + BRONZE, + SILVER, + GOLD, + DIAMOND, + DONE, +} + +impl Level { + fn required_km(&self) -> i32 { + match self { + Level::BRONZE => 40000, + Level::SILVER => 80000, + Level::GOLD => 100000, + Level::DIAMOND => 200000, + Level::DONE => 0, + } + } + + fn next_level(km: i32) -> Self { + if km < Level::BRONZE.required_km() { + Level::BRONZE + } else if km < Level::SILVER.required_km() { + Level::SILVER + } else if km < Level::GOLD.required_km() { + Level::GOLD + } else if km < Level::DIAMOND.required_km() { + Level::BRONZE + } else { + Level::DONE + } + } +} + +#[derive(Serialize)] +pub(crate) struct Next { + level: Level, + missing_km: i32, + required_km: i32, + rowed_km: i32, +} + +impl Next { + pub(crate) fn rowed_km(km: i32) -> Self { + let level = Level::next_level(km); + let required_km = level.required_km(); + let missing_km = required_km - km; + Self { + level, + missing_km, + required_km, + rowed_km: km, + } + } +} diff --git a/src/model/personal/mod.rs b/src/model/personal/mod.rs new file mode 100644 index 0000000..a1dd59c --- /dev/null +++ b/src/model/personal/mod.rs @@ -0,0 +1,21 @@ +use serde::Serialize; +use sqlx::SqlitePool; + +use super::{stat::Stat, user::User}; + +pub(crate) mod equatorprice; +pub(crate) mod rowingbadge; + +#[derive(Serialize)] +pub(crate) struct Achievements { + equatorprice: equatorprice::Next, +} + +impl Achievements { + pub(crate) async fn for_user(db: &SqlitePool, user: &User) -> Self { + let rowed_km = Stat::person(db, None, user).await.rowed_km; + Self { + equatorprice: equatorprice::Next::rowed_km(rowed_km), + } + } +} diff --git a/src/model/personal/rowingbadge.rs b/src/model/personal/rowingbadge.rs new file mode 100644 index 0000000..006d7e9 --- /dev/null +++ b/src/model/personal/rowingbadge.rs @@ -0,0 +1,62 @@ +use chrono::{Datelike, Local, NaiveDate}; + +use crate::model::user::User; + +enum AgeBracket { + Till14, + From14Till18, + From19Till30, + From31Till60, + From61Till75, + From76, +} + +impl TryFrom<&User> for AgeBracket { + type Error = String; + + fn try_from(value: &User) -> Result { + if let Some(birthdate) = value.birthdate.clone() { + let today = Local::now().date_naive(); + let birthdate = NaiveDate::parse_from_str(&birthdate, "%Y-%m-%d").unwrap(); + + let age = today.year() - birthdate.year(); + if age <= 14 { + Ok(AgeBracket::Till14) + } else if age <= 18 { + Ok(AgeBracket::From14Till18) + } else if age <= 30 { + Ok(AgeBracket::From19Till30) + } else if age <= 60 { + Ok(AgeBracket::From31Till60) + } else if age <= 75 { + Ok(AgeBracket::From61Till75) + } else { + Ok(AgeBracket::From76) + } + } else { + Err("User has no birthdate".to_string()) + } + } +} + +fn cat(value: &AgeBracket) -> &str { + match value { + AgeBracket::Till14 => "Schülerinnen und Schüler bis 14 Jahre", + AgeBracket::From14Till18 => "Juniorinnen und Junioren, Para-Ruderer bis 18 Jahre", + AgeBracket::From19Till30 => "Frauen und Männer, Para-Ruderer bis 30 Jahre", + AgeBracket::From31Till60 => "Frauen und Männer, Para-Ruderer von 31 bis 60 Jahre", + AgeBracket::From61Till75 => "Frauen und Männer, Para-Ruderer von 61 bis 75 Jahre", + AgeBracket::From76 => "Frauen und Männer, Para-Ruderer ab 76 Jahre", + } +} + +fn dist_in_km(value: &AgeBracket) -> u32 { + match value { + AgeBracket::Till14 => 500, + AgeBracket::From14Till18 => 1000, + AgeBracket::From19Till30 => 1200, + AgeBracket::From31Till60 => 1000, + AgeBracket::From61Till75 => 800, + AgeBracket::From76 => 600, + } +} diff --git a/src/model/user.rs b/src/model/user.rs index e56e611..d5f8a41 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -24,71 +24,6 @@ use crate::{ SCHECKBUCH, STUDENT_OR_PUPIL, UNTERSTUETZEND, }; -mod aequatorpreis { - use chrono::{Datelike, Local, NaiveDate}; - - use super::User; - - enum AgeBracket { - Till14, - From14Till18, - From19Till30, - From31Till60, - From61Till75, - From76, - } - - impl TryFrom<&User> for AgeBracket { - type Error = String; - - fn try_from(value: &User) -> Result { - if let Some(birthdate) = value.birthdate.clone() { - let today = Local::now().date_naive(); - let birthdate = NaiveDate::parse_from_str(&birthdate, "%Y-%m-%d").unwrap(); - - let age = today.year() - birthdate.year(); - if age <= 14 { - Ok(AgeBracket::Till14) - } else if age <= 18 { - Ok(AgeBracket::From14Till18) - } else if age <= 30 { - Ok(AgeBracket::From19Till30) - } else if age <= 60 { - Ok(AgeBracket::From31Till60) - } else if age <= 75 { - Ok(AgeBracket::From61Till75) - } else { - Ok(AgeBracket::From76) - } - } else { - Err("User has no birthdate".to_string()) - } - } - } - - fn cat(value: &AgeBracket) -> &str { - match value { - AgeBracket::Till14 => "Schülerinnen und Schüler bis 14 Jahre", - AgeBracket::From14Till18 => "Juniorinnen und Junioren, Para-Ruderer bis 18 Jahre", - AgeBracket::From19Till30 => "Frauen und Männer, Para-Ruderer bis 30 Jahre", - AgeBracket::From31Till60 => "Frauen und Männer, Para-Ruderer von 31 bis 60 Jahre", - AgeBracket::From61Till75 => "Frauen und Männer, Para-Ruderer von 61 bis 75 Jahre", - AgeBracket::From76 => "Frauen und Männer, Para-Ruderer ab 76 Jahre", - } - } - - fn dist_in_km(value: &AgeBracket) -> u32 { - match value { - AgeBracket::Till14 => 500, - AgeBracket::From14Till18 => 1000, - AgeBracket::From19Till30 => 1200, - AgeBracket::From31Till60 => 1000, - AgeBracket::From61Till75 => 800, - AgeBracket::From76 => 600, - } - } -} - #[derive(FromRow, Serialize, Deserialize, Clone, Debug, Eq, Hash, PartialEq)] pub struct User { pub id: i64, diff --git a/src/tera/mod.rs b/src/tera/mod.rs index 7bcc1ba..e49e053 100644 --- a/src/tera/mod.rs +++ b/src/tera/mod.rs @@ -24,6 +24,7 @@ use crate::{ model::{ logbook::Logbook, notification::Notification, + personal::Achievements, role::Role, user::{User, UserWithDetails}, }, @@ -62,6 +63,7 @@ async fn index(db: &State, user: User, flash: Option {% endif %} {% if "Donau Linz" in loggedin_user.roles and "Unterstützend" not in loggedin_user.roles and "Förderndes Mitglied" not in loggedin_user.roles %} +