Compare commits
	
		
			1 Commits
		
	
	
		
			eec485dced
			...
			mb-npm-cho
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					397092bff5 | 
@@ -17,9 +17,6 @@ jobs:
 | 
			
		||||
    - name: Run Test DB Script
 | 
			
		||||
      run: ./test_db.sh
 | 
			
		||||
 | 
			
		||||
    - name: Test
 | 
			
		||||
      run: npm --version
 | 
			
		||||
 | 
			
		||||
    - name: Cache Cargo dependencies
 | 
			
		||||
      uses: Swatinem/rust-cache@v2
 | 
			
		||||
 | 
			
		||||
@@ -28,15 +25,15 @@ jobs:
 | 
			
		||||
        cargo build 
 | 
			
		||||
        cd frontend && npm install && npm run build
 | 
			
		||||
    - name: Frontend tests
 | 
			
		||||
      run: cd frontend  && npx playwright install && npx playwright test --workers 1 --reporter html,line
 | 
			
		||||
    - uses: actions/upload-artifact@v3
 | 
			
		||||
      if: always()
 | 
			
		||||
      with:
 | 
			
		||||
        name: playwright-report
 | 
			
		||||
        path: frontend/playwright-report/
 | 
			
		||||
        retention-days: 30
 | 
			
		||||
      run: cd frontend  && npx playwright install && npx playwright test --workers 1 --reporter line
 | 
			
		||||
    - name: Backend tests
 | 
			
		||||
      run: cargo test --verbose
 | 
			
		||||
    #- uses: actions/upload-artifact@v3
 | 
			
		||||
    #  if: always()
 | 
			
		||||
    #  with:
 | 
			
		||||
    #    name: playwright-report
 | 
			
		||||
    #    path: frontend/playwright-report/
 | 
			
		||||
    #    retention-days: 30
 | 
			
		||||
 | 
			
		||||
  deploy-staging:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 
 | 
			
		||||
@@ -413,7 +413,7 @@ function initNewChoice(select: HTMLInputElement) {
 | 
			
		||||
    steering_person.setAttribute("required", "required");
 | 
			
		||||
  }
 | 
			
		||||
  const choice = new Choices(select, {
 | 
			
		||||
    searchResultLimit: 100,
 | 
			
		||||
    searchResultLimit: -1,
 | 
			
		||||
    searchFields: ["label", "value", "customProperties.searchableText"],
 | 
			
		||||
    removeItemButton: true,
 | 
			
		||||
    loadingText: "Wird geladen...",
 | 
			
		||||
@@ -426,6 +426,7 @@ function initNewChoice(select: HTMLInputElement) {
 | 
			
		||||
      return `Nur ${maxItemCount} Ruderer können hinzugefügt werden`;
 | 
			
		||||
    },
 | 
			
		||||
    callbackOnInit: function () {
 | 
			
		||||
      console.log(this);
 | 
			
		||||
      this._currentState.items.forEach(function (obj) {
 | 
			
		||||
        if (boat_in_ottensheim && obj.customProperties) {
 | 
			
		||||
          if (obj.customProperties.is_racing) {
 | 
			
		||||
 
 | 
			
		||||
@@ -16,12 +16,12 @@
 | 
			
		||||
    "postcss": "^8.4.21",
 | 
			
		||||
    "sass": "^1.60.0",
 | 
			
		||||
    "tailwindcss": "^3.3.1",
 | 
			
		||||
    "typescript": "^5.9.3",
 | 
			
		||||
    "typescript": "^4.9.5",
 | 
			
		||||
    "vite": "^4.2.0",
 | 
			
		||||
    "vite-plugin-static-copy": "^0.13.1"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "choices.js": "^10.2.0",
 | 
			
		||||
    "choices.js": "^11.1.0",
 | 
			
		||||
    "d3": "^7.8.5",
 | 
			
		||||
    "terser": "^5.21.0"
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -1,6 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "rowt",
 | 
			
		||||
  "lockfileVersion": 3,
 | 
			
		||||
  "requires": true,
 | 
			
		||||
  "packages": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -8,7 +8,7 @@ use crate::model::{
 | 
			
		||||
    notification::Notification,
 | 
			
		||||
    role::Role,
 | 
			
		||||
};
 | 
			
		||||
use chrono::{Datelike, Local, NaiveDate};
 | 
			
		||||
use chrono::NaiveDate;
 | 
			
		||||
use rocket::{fs::TempFile, tokio::io::AsyncReadExt};
 | 
			
		||||
use sqlx::SqlitePool;
 | 
			
		||||
 | 
			
		||||
@@ -578,32 +578,4 @@ impl User {
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) async fn has_to_pay_einschreibgebuehr_this_year(&self, db: &SqlitePool) -> bool {
 | 
			
		||||
        if !self.has_role(db, "schnupperant").await {
 | 
			
		||||
            if let Some(member_since_date) = &self.member_since_date {
 | 
			
		||||
                if let Ok(member_since_date) =
 | 
			
		||||
                    NaiveDate::parse_from_str(member_since_date, "%Y-%m-%d")
 | 
			
		||||
                {
 | 
			
		||||
                    if member_since_date.year() == Local::now().year()
 | 
			
		||||
                        && !self.has_role(db, "no-einschreibgebuehr").await
 | 
			
		||||
                    {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        false
 | 
			
		||||
    }
 | 
			
		||||
    pub(crate) fn has_to_pay_only_half(&self) -> bool {
 | 
			
		||||
        if let Some(member_since_date) = &self.member_since_date {
 | 
			
		||||
            if let Ok(member_since_date) = NaiveDate::parse_from_str(member_since_date, "%Y-%m-%d")
 | 
			
		||||
            {
 | 
			
		||||
                let halfprice_startdate =
 | 
			
		||||
                    NaiveDate::from_ymd_opt(Local::now().year(), 7, 1).unwrap();
 | 
			
		||||
                return member_since_date >= halfprice_startdate;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        false
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,10 @@
 | 
			
		||||
use super::User;
 | 
			
		||||
use crate::{
 | 
			
		||||
    model::family::Family, BOAT_STORAGE, DUAL_MEMBERSHIP, EINSCHREIBGEBUEHR, FAMILY_THREE_OR_MORE,
 | 
			
		||||
    FAMILY_TWO, FOERDERND, REGULAR, RENNRUDERBEITRAG, SCHECKBUCH, STUDENT_OR_PUPIL, TRIAL_ROWING,
 | 
			
		||||
    TRIAL_ROWING_REDUCED, UNTERSTUETZEND,
 | 
			
		||||
    BOAT_STORAGE, DUAL_MEMBERSHIP, EINSCHREIBGEBUEHR, FAMILY_THREE_OR_MORE, FAMILY_TWO, FOERDERND,
 | 
			
		||||
    REGULAR, RENNRUDERBEITRAG, SCHECKBUCH, STUDENT_OR_PUPIL, TRIAL_ROWING, TRIAL_ROWING_REDUCED,
 | 
			
		||||
    UNTERSTUETZEND, model::family::Family,
 | 
			
		||||
};
 | 
			
		||||
use chrono::{Datelike, Local, NaiveDate};
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
use sqlx::SqlitePool;
 | 
			
		||||
 | 
			
		||||
@@ -80,52 +81,30 @@ impl User {
 | 
			
		||||
        let mut fee = Fee::new();
 | 
			
		||||
 | 
			
		||||
        if let Some(family) = Family::find_by_opt_id(db, self.family_id).await {
 | 
			
		||||
            let mut einschreibgebuehr = false;
 | 
			
		||||
            let mut half_price = true;
 | 
			
		||||
            for member in family.members(db).await {
 | 
			
		||||
                fee.add_person(&member);
 | 
			
		||||
                if member.has_role(db, "paid").await {
 | 
			
		||||
                    fee.paid();
 | 
			
		||||
                }
 | 
			
		||||
                fee.merge(member.fee_without_families(db, true).await);
 | 
			
		||||
                if member.has_to_pay_einschreibgebuehr_this_year(db).await {
 | 
			
		||||
                    einschreibgebuehr = true;
 | 
			
		||||
                }
 | 
			
		||||
                if !member.has_to_pay_only_half() {
 | 
			
		||||
                    half_price = false;
 | 
			
		||||
                }
 | 
			
		||||
                fee.merge(member.fee_without_families(db).await);
 | 
			
		||||
            }
 | 
			
		||||
            if family.amount_family_members(db).await > 2 {
 | 
			
		||||
                if half_price {
 | 
			
		||||
                    fee.add(
 | 
			
		||||
                        "Familie 3+ Personen (Halbpreis)".into(),
 | 
			
		||||
                        FAMILY_THREE_OR_MORE / 2,
 | 
			
		||||
                    );
 | 
			
		||||
                } else {
 | 
			
		||||
                    fee.add("Familie 3+ Personen".into(), FAMILY_THREE_OR_MORE);
 | 
			
		||||
                }
 | 
			
		||||
                fee.add("Familie 3+ Personen".into(), FAMILY_THREE_OR_MORE);
 | 
			
		||||
            } else {
 | 
			
		||||
                if half_price {
 | 
			
		||||
                    fee.add("Familie 2 Personen (Halbpreis)".into(), FAMILY_TWO / 2);
 | 
			
		||||
                } else {
 | 
			
		||||
                    fee.add("Familie 2 Personen".into(), FAMILY_TWO);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if einschreibgebuehr {
 | 
			
		||||
                fee.add("Einschreibgebühr (Familie)".into(), EINSCHREIBGEBUEHR);
 | 
			
		||||
                fee.add("Familie 2 Personen".into(), FAMILY_TWO);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            fee.add_person(self);
 | 
			
		||||
            if self.has_role(db, "paid").await {
 | 
			
		||||
                fee.paid();
 | 
			
		||||
            }
 | 
			
		||||
            fee.merge(self.fee_without_families(db, false).await);
 | 
			
		||||
            fee.merge(self.fee_without_families(db).await);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Some(fee)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn fee_without_families(&self, db: &SqlitePool, entry_fee_paid_with_family: bool) -> Fee {
 | 
			
		||||
    async fn fee_without_families(&self, db: &SqlitePool) -> Fee {
 | 
			
		||||
        let mut fee = Fee::new();
 | 
			
		||||
 | 
			
		||||
        if !self.has_role(db, "Donau Linz").await
 | 
			
		||||
@@ -146,24 +125,38 @@ impl User {
 | 
			
		||||
 | 
			
		||||
        let amount_boats = self.amount_boats(db).await;
 | 
			
		||||
        if amount_boats > 0 {
 | 
			
		||||
            if self.has_to_pay_only_half() {
 | 
			
		||||
                fee.add(
 | 
			
		||||
                    format!("{}x Bootsplatz (Halbpreis)", amount_boats),
 | 
			
		||||
                    amount_boats * BOAT_STORAGE / 2,
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                fee.add(
 | 
			
		||||
                    format!("{}x Bootsplatz", amount_boats),
 | 
			
		||||
                    amount_boats * BOAT_STORAGE,
 | 
			
		||||
                );
 | 
			
		||||
            fee.add(
 | 
			
		||||
                format!("{}x Bootsplatz", amount_boats),
 | 
			
		||||
                amount_boats * BOAT_STORAGE,
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if !self.has_role(db, "schnupperant").await {
 | 
			
		||||
            if let Some(member_since_date) = &self.member_since_date {
 | 
			
		||||
                if let Ok(member_since_date) =
 | 
			
		||||
                    NaiveDate::parse_from_str(member_since_date, "%Y-%m-%d")
 | 
			
		||||
                {
 | 
			
		||||
                    if member_since_date.year() == Local::now().year()
 | 
			
		||||
                        && !self.has_role(db, "no-einschreibgebuehr").await
 | 
			
		||||
                    {
 | 
			
		||||
                        fee.add("Einschreibgebühr".into(), EINSCHREIBGEBUEHR);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if self.has_to_pay_einschreibgebuehr_this_year(db).await && !entry_fee_paid_with_family {
 | 
			
		||||
            fee.add("Einschreibgebühr".into(), EINSCHREIBGEBUEHR);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let halfprice = self.has_to_pay_only_half();
 | 
			
		||||
        let halfprice = if let Some(member_since_date) = &self.member_since_date {
 | 
			
		||||
            match NaiveDate::parse_from_str(member_since_date, "%Y-%m-%d") {
 | 
			
		||||
                Ok(member_since_date) => {
 | 
			
		||||
                    let halfprice_startdate =
 | 
			
		||||
                        NaiveDate::from_ymd_opt(Local::now().year(), 7, 1).unwrap();
 | 
			
		||||
                    member_since_date >= halfprice_startdate
 | 
			
		||||
                }
 | 
			
		||||
                Err(_) => false,
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            false
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if self.has_role(db, "schnupperant").await {
 | 
			
		||||
            if self.has_role(db, "Student").await || self.has_role(db, "Schüler").await {
 | 
			
		||||
 
 | 
			
		||||
@@ -795,7 +795,6 @@ macro_rules! special_user {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl $name {
 | 
			
		||||
            #[allow(dead_code)]
 | 
			
		||||
            pub fn into_inner(self) -> User {
 | 
			
		||||
                self.user
 | 
			
		||||
            }
 | 
			
		||||
@@ -860,7 +859,6 @@ special_user!(AllowedForPlannedTripsUser, +"Donau Linz", +"scheckbuch", +"Förde
 | 
			
		||||
special_user!(DonauLinzUser, +"Donau Linz", +"Förderndes Mitglied", -"Unterstützend"); // TODO:
 | 
			
		||||
                                                                                       // remove ->
 | 
			
		||||
                                                                                       // RegularUser
 | 
			
		||||
special_user!(ErgoAdminUser, +"ergo-admin", +"admin");
 | 
			
		||||
special_user!(SchnupperBetreuerUser, +"schnupper-betreuer");
 | 
			
		||||
special_user!(VorstandUser, +"admin", +"Vorstand");
 | 
			
		||||
special_user!(EventUser, +"manage_events");
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ use std::env;
 | 
			
		||||
 | 
			
		||||
use chrono::Utc;
 | 
			
		||||
use rocket::{
 | 
			
		||||
    FromForm, Route, State,
 | 
			
		||||
    form::Form,
 | 
			
		||||
    fs::TempFile,
 | 
			
		||||
    get,
 | 
			
		||||
@@ -9,9 +10,9 @@ use rocket::{
 | 
			
		||||
    post,
 | 
			
		||||
    request::FlashMessage,
 | 
			
		||||
    response::{Flash, Redirect},
 | 
			
		||||
    routes, FromForm, Route, State,
 | 
			
		||||
    routes,
 | 
			
		||||
};
 | 
			
		||||
use rocket_dyn_templates::{context, Template};
 | 
			
		||||
use rocket_dyn_templates::{Template, context};
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
use sqlx::SqlitePool;
 | 
			
		||||
use tera::Context;
 | 
			
		||||
@@ -20,7 +21,7 @@ use crate::model::{
 | 
			
		||||
    log::Log,
 | 
			
		||||
    notification::Notification,
 | 
			
		||||
    role::Role,
 | 
			
		||||
    user::{AdminUser, ErgoAdminUser, User, UserWithDetails},
 | 
			
		||||
    user::{AdminUser, User, UserWithDetails},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize)]
 | 
			
		||||
@@ -58,7 +59,7 @@ async fn send(db: &State<SqlitePool>, _user: AdminUser) -> Template {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[get("/reset")]
 | 
			
		||||
async fn reset(db: &State<SqlitePool>, _user: ErgoAdminUser) -> Flash<Redirect> {
 | 
			
		||||
async fn reset(db: &State<SqlitePool>, _user: AdminUser) -> Flash<Redirect> {
 | 
			
		||||
    sqlx::query!("UPDATE user SET dirty_thirty = NULL, dirty_dozen = NULL;")
 | 
			
		||||
        .execute(db.inner())
 | 
			
		||||
        .await
 | 
			
		||||
@@ -73,7 +74,7 @@ async fn reset(db: &State<SqlitePool>, _user: ErgoAdminUser) -> Flash<Redirect>
 | 
			
		||||
#[get("/<challenge>/user/<user_id>/new?<new>")]
 | 
			
		||||
async fn update(
 | 
			
		||||
    db: &State<SqlitePool>,
 | 
			
		||||
    _admin: ErgoAdminUser,
 | 
			
		||||
    _admin: AdminUser,
 | 
			
		||||
    challenge: &str,
 | 
			
		||||
    user_id: i64,
 | 
			
		||||
    new: &str,
 | 
			
		||||
@@ -145,47 +146,47 @@ pub struct UserAdd {
 | 
			
		||||
    sex: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[post("/set-data", data = "<data>")]
 | 
			
		||||
async fn new_user(db: &State<SqlitePool>, data: Form<UserAdd>, user: User) -> Flash<Redirect> {
 | 
			
		||||
    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 info@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 :-)",
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
//#[post("/set-data", data = "<data>")]
 | 
			
		||||
//async fn new_user(db: &State<SqlitePool>, data: Form<UserAdd>, user: User) -> Flash<Redirect> {
 | 
			
		||||
//    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)]
 | 
			
		||||
pub struct ErgoToAdd<'a> {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ use std::{fs::OpenOptions, io::Write};
 | 
			
		||||
 | 
			
		||||
use chrono::{Datelike, Local};
 | 
			
		||||
use rocket::{
 | 
			
		||||
    catch, catchers,
 | 
			
		||||
    Build, Data, FromForm, Request, Rocket, State, catch, catchers,
 | 
			
		||||
    fairing::{AdHoc, Fairing, Info, Kind},
 | 
			
		||||
    form::Form,
 | 
			
		||||
    fs::FileServer,
 | 
			
		||||
@@ -13,7 +13,6 @@ use rocket::{
 | 
			
		||||
    response::{Flash, Redirect},
 | 
			
		||||
    routes,
 | 
			
		||||
    time::{Duration, OffsetDateTime},
 | 
			
		||||
    Build, Data, FromForm, Request, Rocket, State,
 | 
			
		||||
};
 | 
			
		||||
use rocket_dyn_templates::Template;
 | 
			
		||||
use serde::Deserialize;
 | 
			
		||||
@@ -21,6 +20,7 @@ use sqlx::SqlitePool;
 | 
			
		||||
use tera::Context;
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    SCHECKBUCH,
 | 
			
		||||
    model::{
 | 
			
		||||
        logbook::Logbook,
 | 
			
		||||
        notification::Notification,
 | 
			
		||||
@@ -28,7 +28,6 @@ use crate::{
 | 
			
		||||
        role::Role,
 | 
			
		||||
        user::{User, UserWithDetails},
 | 
			
		||||
    },
 | 
			
		||||
    SCHECKBUCH,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub(crate) mod admin;
 | 
			
		||||
@@ -331,11 +330,13 @@ mod test {
 | 
			
		||||
 | 
			
		||||
        assert_eq!(response.status(), Status::Ok);
 | 
			
		||||
 | 
			
		||||
        assert!(response
 | 
			
		||||
            .into_string()
 | 
			
		||||
            .await
 | 
			
		||||
            .unwrap()
 | 
			
		||||
            .contains("Ruderassistent"));
 | 
			
		||||
        assert!(
 | 
			
		||||
            response
 | 
			
		||||
                .into_string()
 | 
			
		||||
                .await
 | 
			
		||||
                .unwrap()
 | 
			
		||||
                .contains("Ruderassistent")
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[sqlx::test]
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,10 @@
 | 
			
		||||
                               class="link-primary">Überblick der Challenges</a>
 | 
			
		||||
                        </li>
 | 
			
		||||
                        <li class="py-1">
 | 
			
		||||
                            Eintragung ist jederzeit möglich, wenn du sie auch an die offizielle Liste schicken willst, kannst du das <a href="https://data.ergochallenge.at/" target="_blank" style="text-decoration: underline">hier</a> machen
 | 
			
		||||
                            Eintragung ist jederzeit möglich, alle Daten die bis Sonntag 23:59 hier hochgeladen wurden, werden gesammelt an die Ister Ergo Challenge geschickt
 | 
			
		||||
                            <li class="py-1">
 | 
			
		||||
                                Montag → gemeinsames Training; bitte um <a href="/planned" class="link-primary">Anmeldung</a>, damit jeder einen Ergo hat
 | 
			
		||||
                            </li>
 | 
			
		||||
                            <li class="py-1">
 | 
			
		||||
                                <a href="https://data.ergochallenge.at"
 | 
			
		||||
                                   target="_blank"
 | 
			
		||||
@@ -191,7 +194,7 @@
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </details>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    {% if "admin" in loggedin_user.roles or "ergo-admin" in loggedin_user.roles %}
 | 
			
		||||
                    {% if "admin" in loggedin_user.roles %}
 | 
			
		||||
                        <div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow grid gap-3">
 | 
			
		||||
                            <h2 class="h2">Update</h2>
 | 
			
		||||
                            <details class="p-2">
 | 
			
		||||
@@ -230,14 +233,6 @@
 | 
			
		||||
                                    </ol>
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </details>
 | 
			
		||||
                              <div class="mt-3 text-right">
 | 
			
		||||
                                <a href="/ergo/reset"
 | 
			
		||||
                                   class="w-28 btn btn-alert"
 | 
			
		||||
                                   onclick="return confirm('Willst du wirklich alle Ergo-Eingaben löschen?');">
 | 
			
		||||
                                    {% include "includes/delete-icon" %}
 | 
			
		||||
                                    Einträge löschen
 | 
			
		||||
                                </a>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                {% endif %}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user