restructure for equatorprice
This commit is contained in:
		| @@ -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; | ||||
|   | ||||
							
								
								
									
										58
									
								
								src/model/personal/equatorprice.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/model/personal/equatorprice.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -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, | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										21
									
								
								src/model/personal/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/model/personal/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -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), | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										62
									
								
								src/model/personal/rowingbadge.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/model/personal/rowingbadge.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -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<Self, Self::Error> { | ||||
|         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, | ||||
|     } | ||||
| } | ||||
| @@ -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<Self, Self::Error> { | ||||
|             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, | ||||
|   | ||||
| @@ -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<SqlitePool>, user: User, flash: Option<FlashMessage<'_ | ||||
|         context.insert("last_trips", &last_trips); | ||||
|     } | ||||
|  | ||||
|     context.insert("achievements", &Achievements::for_user(db, &user).await); | ||||
|     context.insert("notifications", &Notification::for_user(db, &user).await); | ||||
|     context.insert("loggedin_user", &UserWithDetails::from_user(user, db).await); | ||||
|     context.insert("costs_scheckbuch", &SCHECKBUCH); | ||||
|   | ||||
| @@ -74,6 +74,32 @@ | ||||
|                 </div> | ||||
|             {% 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 %} | ||||
|                 <div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5" | ||||
|                      role="alert"> | ||||
|                     <h2 class="h2">Persönliches</h2> | ||||
|                     <div class="mx-2 divide-y divide-gray-200 dark:divide-primary-600"> | ||||
|                         <div class="py-3"> | ||||
|                             <h3 class="font-bold text-xl mb-3">Äquatorpreis</h3> | ||||
|                             {% set price = achievements.equatorprice %} | ||||
|                             {% if price.level == "DONE" %} | ||||
|                                 Gratuliere, du hast alles erreicht, was es beim Äquatorpreis zu erreichen gibt. | ||||
|                             {% else %} | ||||
|                                 <label for="equatorprice" class="label">{{ price.level }}</label> | ||||
|                                 <progress id="equatorprice" | ||||
|                                           class="w-full block my-3" | ||||
|                                           value="{{ price.rowed_km }}" | ||||
|                                           max="{{ price.required_km }}"></progress> | ||||
|                                 <details> | ||||
|                                     <summary>Details</summary> | ||||
|                                     Du bist insgesamt {{ price.rowed_km }} km gerudert. Um den Äquatorpreis in {{ price.level }} zu erhalten, benötigst du noch {{ price.missing_km }} um die notwendigen {{ price.required_km }} km zu erreichen. | ||||
|                                 </details> | ||||
|                             {% endif %} | ||||
|                         </div> | ||||
|                         <div class="py-1"> | ||||
|                             <h3>Fahrtenabzeichen</h3> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5" | ||||
|                      role="alert"> | ||||
|                     <h2 class="h2">Aktives Vereinsmitglied</h2> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user