diff --git a/src/model/user.rs b/src/model/user.rs index 24127a9..6e4691e 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -678,18 +678,8 @@ WHERE family_id IS NULL; } pub async fn ergo(db: &SqlitePool) -> Vec { - sqlx::query_as!( - Self, - " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token -FROM user -WHERE deleted = 0 AND dob != '' and weight != '' and sex != '' -ORDER BY name - " - ) - .fetch_all(db) - .await - .unwrap() + let ergo = Role::find_by_name(db, "ergo").await.unwrap(); + Self::all_with_role(db, &ergo).await } pub async fn cox(db: &SqlitePool) -> Vec { @@ -723,6 +713,19 @@ ORDER BY last_access DESC .is_ok() } + pub async fn update_ergo(&self, db: &SqlitePool, dob: i32, weight: i64, sex: &str) { + sqlx::query!( + "UPDATE user SET dob = ?, weight = ?, sex = ? where id = ?", + dob, + weight, + sex, + self.id + ) + .execute(db) + .await + .unwrap(); //Okay, because we can only create a User of a valid id + } + pub async fn update(&self, db: &SqlitePool, data: UserEditForm<'_>) -> Result<(), String> { let mut db = db.begin().await.map_err(|e| e.to_string())?; diff --git a/src/tera/ergo.rs b/src/tera/ergo.rs index 493ae64..1c3e334 100644 --- a/src/tera/ergo.rs +++ b/src/tera/ergo.rs @@ -1,6 +1,6 @@ use std::env; -use chrono::Utc; +use chrono::{Datelike, Utc}; use rocket::{ form::Form, fs::TempFile, @@ -17,8 +17,7 @@ use sqlx::SqlitePool; use tera::Context; use crate::model::{ - log::Log, - user::{AdminUser, User, UserWithDetails}, + log::Log, notification::Notification, role::Role, user::{AdminUser, User, UserWithDetails} }; #[derive(Serialize)] @@ -50,7 +49,7 @@ async fn send(db: &State, _user: AdminUser) -> Template { .unwrap(); Template::render( - "ergo.final", + "ergo/final", context!(loggedin_user: &UserWithDetails::from_user(_user.user, db).await, thirty, dozen), ) } @@ -98,6 +97,19 @@ async fn update( #[get("/")] async fn index(db: &State, user: User, flash: Option>) -> Template { + let mut context = Context::new(); + if let Some(msg) = flash { + context.insert("flash", &msg.into_inner()); + } + context.insert("loggedin_user", &UserWithDetails::from_user(user.clone(), db).await); + + if !user.has_role(db, "ergo").await { + return Template::render( + "ergo/missing-data", + context.into_json() + ); + } + let users = User::ergo(db).await; let thirty = sqlx::query_as!( @@ -116,16 +128,56 @@ async fn index(db: &State, user: User, flash: Option, + data: Form, + user: User, +) -> Flash { + if user.has_role(db, "ergo").await { + return + Flash::error(Redirect::to("/ergo"), "Du hast deine Daten schon eingegeben. Wenn du sie updaten willst, melde dich bitte bei it@rudernlinz.at"); + } + + // check data + if data.birthyear <1900 || data.birthyear > chrono::Utc::now().year() - 5 { + return + Flash::error(Redirect::to("/ergo"), "Bitte überprüfe dein Geburtsjahr..."); + } + if data.weight < 20 || data.weight > 200 { + return + Flash::error(Redirect::to("/ergo"), "Bitte überprüfe dein Gewicht..."); + } + if &data.sex != "f" && &data.sex != "m"{ + return + Flash::error(Redirect::to("/ergo"), "Bitte überprüfe dein Geschlecht..."); + } + + // set data + user.update_ergo(db, data.birthyear, data.weight, &data.sex).await; + + // inform all other `ergo` users + let ergo = Role::find_by_name(db, "ergo").await.unwrap(); + Notification::create_for_role(db, &ergo, &format!("{} nimmt heuer an der Ergochallenge teil 💪", user.name), "Ergo-Challenge", None, None).await; + + // add to `ergo` group + user.add_role(db,&ergo).await.unwrap(); + + Flash::success(Redirect::to("/ergo"), "Du hast deine Daten erfolgreich eingegeben. Viel Spaß beim Schwitzen :-)") } #[derive(FromForm, Debug)] @@ -173,6 +225,9 @@ async fn new_thirty( ) .await; + let ergo = Role::find_by_name(db, "ergo").await.unwrap(); + Notification::create_for_role(db, &ergo, &format!("{} ist gerade die Dirty Thirty Challenge gefahren 🥵", user.name), "Ergo-Challenge", Some("/ergo"), None).await; + Flash::success(Redirect::to("/ergo"), "Erfolgreich eingetragen") } @@ -214,11 +269,14 @@ async fn new_dozen( ) .await; + let ergo = Role::find_by_name(db, "ergo").await.unwrap(); + Notification::create_for_role(db, &ergo, &format!("{} ist gerade die Dirty Dozen Challenge gefahren 🥵", user.name), "Ergo-Challenge", Some("/ergo"), None).await; + Flash::success(Redirect::to("/ergo"), "Erfolgreich eingetragen") } pub fn routes() -> Vec { - routes![index, new_thirty, new_dozen, send, reset, update] + routes![index, new_thirty, new_dozen, send, reset, update, new_user] } #[cfg(test)] diff --git a/staging-diff.sql b/staging-diff.sql index e4387f2..6fb21fc 100644 --- a/staging-diff.sql +++ b/staging-diff.sql @@ -3,35 +3,3 @@ INSERT INTO user(name) VALUES('Marie'); INSERT INTO "user_role" (user_id, role_id) VALUES((SELECT id from user where name = 'Marie'),(SELECT id FROM role where name = 'Donau Linz')); INSERT INTO user(name) VALUES('Philipp'); INSERT INTO "user_role" (user_id, role_id) VALUES((SELECT id from user where name = 'Philipp'),(SELECT id FROM role where name = 'Donau Linz')); - -ALTER TABLE "role" ADD COLUMN "cluster" text; -CREATE TRIGGER IF NOT EXISTS prevent_multiple_roles_same_cluster -BEFORE INSERT ON user_role -BEGIN - SELECT CASE - WHEN EXISTS ( - SELECT 1 - FROM user_role ur - JOIN role r1 ON ur.role_id = r1.id - JOIN role r2 ON r1."cluster" = r2."cluster" - WHERE ur.user_id = NEW.user_id - AND r2.id = NEW.role_id - AND r1.id != NEW.role_id - ) - THEN RAISE(ABORT, 'User already has a role in this cluster') - END; -END; - - -UPDATE role SET 'cluster'='skill' WHERE id=2; -UPDATE role SET 'cluster'='membership_type' WHERE id=3; -UPDATE role SET 'cluster'='skill' WHERE id=5; -UPDATE role SET 'cluster'='skill' WHERE id=6; -UPDATE role SET 'cluster'='membership_type' WHERE id=7; -UPDATE role SET 'cluster'='financial' WHERE id=8; -UPDATE role SET 'cluster'='membership_type' WHERE id=9; -UPDATE role SET 'cluster'='membership_type' WHERE id=14; -UPDATE role SET 'cluster'='financial' WHERE id=17; -UPDATE role SET 'cluster'='financial' WHERE id=18; -UPDATE role SET 'cluster'='membership_type' WHERE id=20; -UPDATE role SET 'cluster'='membership_type' WHERE id=22; diff --git a/templates/ergo.html.tera b/templates/ergo.html.tera deleted file mode 100644 index dff7d8a..0000000 --- a/templates/ergo.html.tera +++ /dev/null @@ -1,205 +0,0 @@ -{% import "includes/macros" as macros %} -{% extends "base" %} -{% block content %} -
-

Ergo Challenges

-
- -
-

- Neuer Eintrag -

-
- Dirty Thirty -
-
-
- - -
- {{ macros::input(label="Distanz [m]", name="result", required=true, type="number", class="input rounded-md") }} -
- - -
-
- -
-
-
-
-
- Dirty Dozen -
-
-
- - -
- {{ macros::input(label="Zeit [hh:mm:ss.s] oder Distanz [m]", name="result", required=true, type="text", class="input rounded-md", pattern="(?:\d+:\d{2}:\d{2}\.\d+|\d{1,2}:\d{2}\.\d+|\d+(\.\d+)?)") }} -
- - -
-
- -
-
-
-
-
-
-

Aktuelle Woche

-
- - Dirty Thirty ({{ thirty | length }}) - -
-
    - {% for stat in thirty %} -
  1. - {{ stat.name }}: {{ stat.result }} -
  2. - {% endfor %} -
-
-
-
- - Dirty Dozen ({{ dozen | length }}) - -
-
    - {% for stat in dozen %} -
  1. - {{ stat.name }}: {{ stat.result }} -
  2. - {% endfor %} -
-
-
-
- {% if "admin" in loggedin_user.roles %} -
-

Update

-
- - Dirty Thirty ({{ thirty | length }}) - -
-
    - {% for stat in thirty %} -
  1. -
    - {{ stat.name }}: - - -
    -
  2. - {% endfor %} -
-
-
-
- - Dirty Dozen ({{ dozen | length }}) - -
-
    - {% for stat in dozen %} -
  1. -
    - {{ stat.name }}: - - -
    -
  2. - {% endfor %} -
-
-
-
-
- {% endif %} -
- -{% endblock content %} diff --git a/templates/ergo.final.html.tera b/templates/ergo/final.html.tera similarity index 100% rename from templates/ergo.final.html.tera rename to templates/ergo/final.html.tera diff --git a/templates/ergo/index.html.tera b/templates/ergo/index.html.tera new file mode 100644 index 0000000..3ead2fc --- /dev/null +++ b/templates/ergo/index.html.tera @@ -0,0 +1,231 @@ +{% import "includes/macros" as macros %} +{% extends "base" %} +{% block content %} +
+

Ergo Challenges

+
+ +
+

+ Neuer Eintrag +

+
+ Dirty Thirty +
+
+
+ + +
+ {{ macros::input(label="Distanz [m]", name="result", required=true, type="number", class="input rounded-md") }} +
+ + +
+
+ +
+
+
+
+
+ Dirty Dozen +
+
+
+ + +
+ {{ macros::input(label="Zeit [hh:mm:ss.s] oder Distanz [m]", name="result", required=true, type="text", class="input rounded-md", pattern="(?:\d+:\d{2}:\d{2}\.\d+|\d{1,2}:\d{2}\.\d+|\d+(\.\d+)?)") }} +
+ + +
+
+ +
+
+
+
+
+
+

Aktuelle Woche

+
+ + Dirty Thirty ({{ thirty | length }}) + +
+
    + {% for stat in thirty %} +
  1. + {{ stat.name }}: {{ stat.result }} +
  2. + {% endfor %} +
+
+
+
+ + Dirty Dozen ({{ dozen | length }}) + +
+
    + {% for stat in dozen %} +
  1. + {{ stat.name }}: {{ stat.result }} +
  2. + {% endfor %} +
+
+
+
+ {% if "admin" in loggedin_user.roles %} +
+

Update

+
+ + Dirty Thirty ({{ thirty | length }}) + +
+
    + {% for stat in thirty %} +
  1. +
    + {{ stat.name }}: + + +
    +
  2. + {% endfor %} +
+
+
+
+ + Dirty Dozen ({{ dozen | length }}) + +
+
    + {% for stat in dozen %} +
  1. +
    + {{ stat.name }}: + + +
    +
  2. + {% endfor %} +
+
+
+
+
+ {% endif %} +
+ + {% endblock content %} diff --git a/templates/ergo/missing-data.html.tera b/templates/ergo/missing-data.html.tera new file mode 100644 index 0000000..2340237 --- /dev/null +++ b/templates/ergo/missing-data.html.tera @@ -0,0 +1,33 @@ +{% import "includes/macros" as macros %} +{% import "includes/forms/boat" as boat %} +{% extends "base" %} +{% block content %} +
+

Ergo-Challenge

+
+ +
+
+{% endblock content %} diff --git a/templates/index.html.tera b/templates/index.html.tera index 890ff4f..698dcc9 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -303,6 +303,17 @@ {% endif %} + {% if "schnupper-betreuer" in loggedin_user.roles %} {% endif %} - {% if loggedin_user.weight and loggedin_user.sex and loggedin_user.dob %} - - {% endif %}