Compare commits

...

5 Commits

Author SHA1 Message Date
3272833b2d Merge pull request 'update-ergo' (#773) from update-ergo into staging
Some checks failed
CI/CD Pipeline / deploy-staging (push) Blocked by required conditions
CI/CD Pipeline / deploy-main (push) Blocked by required conditions
CI/CD Pipeline / test (push) Has been cancelled
Reviewed-on: #773
2024-10-19 22:04:18 +02:00
f71c83dc3f lint
Some checks failed
CI/CD Pipeline / deploy-staging (push) Blocked by required conditions
CI/CD Pipeline / deploy-main (push) Blocked by required conditions
CI/CD Pipeline / test (push) Has been cancelled
2024-10-19 22:03:50 +02:00
b9344a42a0 inform people of participation; require updating personal data before joining
Some checks failed
CI/CD Pipeline / deploy-staging (push) Blocked by required conditions
CI/CD Pipeline / deploy-main (push) Blocked by required conditions
CI/CD Pipeline / test (push) Has been cancelled
2024-10-19 22:02:44 +02:00
4d4c680e59 Merge pull request 'compress uploads for faster deplyments' (#772) from faster-deploy into main
All checks were successful
CI/CD Pipeline / test (push) Successful in 11m24s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Successful in 6m27s
Reviewed-on: #772
2024-10-14 14:32:59 +02:00
935f0dd1dd Merge pull request 'merged :-)' (#770) from merged into main
Some checks failed
CI/CD Pipeline / deploy-staging (push) Blocked by required conditions
CI/CD Pipeline / deploy-main (push) Blocked by required conditions
CI/CD Pipeline / test (push) Has been cancelled
Reviewed-on: #770
2024-10-14 14:22:07 +02:00
7 changed files with 359 additions and 241 deletions

View File

@ -678,18 +678,8 @@ WHERE family_id IS NULL;
} }
pub async fn ergo(db: &SqlitePool) -> Vec<Self> { pub async fn ergo(db: &SqlitePool) -> Vec<Self> {
sqlx::query_as!( let ergo = Role::find_by_name(db, "ergo").await.unwrap();
Self, Self::all_with_role(db, &ergo).await
"
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()
} }
pub async fn cox(db: &SqlitePool) -> Vec<Self> { pub async fn cox(db: &SqlitePool) -> Vec<Self> {
@ -723,6 +713,19 @@ ORDER BY last_access DESC
.is_ok() .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> { pub async fn update(&self, db: &SqlitePool, data: UserEditForm<'_>) -> Result<(), String> {
let mut db = db.begin().await.map_err(|e| e.to_string())?; let mut db = db.begin().await.map_err(|e| e.to_string())?;

View File

@ -1,6 +1,6 @@
use std::env; use std::env;
use chrono::Utc; use chrono::{Datelike, Utc};
use rocket::{ use rocket::{
form::Form, form::Form,
fs::TempFile, fs::TempFile,
@ -17,8 +17,7 @@ use sqlx::SqlitePool;
use tera::Context; use tera::Context;
use crate::model::{ use crate::model::{
log::Log, log::Log, notification::Notification, role::Role, user::{AdminUser, User, UserWithDetails}
user::{AdminUser, User, UserWithDetails},
}; };
#[derive(Serialize)] #[derive(Serialize)]
@ -50,7 +49,7 @@ async fn send(db: &State<SqlitePool>, _user: AdminUser) -> Template {
.unwrap(); .unwrap();
Template::render( Template::render(
"ergo.final", "ergo/final",
context!(loggedin_user: &UserWithDetails::from_user(_user.user, db).await, thirty, dozen), context!(loggedin_user: &UserWithDetails::from_user(_user.user, db).await, thirty, dozen),
) )
} }
@ -98,6 +97,19 @@ async fn update(
#[get("/")] #[get("/")]
async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_>>) -> Template { async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_>>) -> 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 users = User::ergo(db).await;
let thirty = sqlx::query_as!( let thirty = sqlx::query_as!(
@ -116,16 +128,56 @@ async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_
.await .await
.unwrap(); .unwrap();
let mut context = Context::new();
if let Some(msg) = flash {
context.insert("flash", &msg.into_inner());
}
context.insert("loggedin_user", &UserWithDetails::from_user(user, db).await);
context.insert("users", &users); context.insert("users", &users);
context.insert("thirty", &thirty); context.insert("thirty", &thirty);
context.insert("dozen", &dozen); context.insert("dozen", &dozen);
Template::render("ergo", context.into_json()) Template::render("ergo/index", context.into_json())
}
#[derive(FromForm, Debug)]
pub struct UserAdd {
birthyear: i32,
weight: i64,
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 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)] #[derive(FromForm, Debug)]
@ -173,6 +225,9 @@ async fn new_thirty(
) )
.await; .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") Flash::success(Redirect::to("/ergo"), "Erfolgreich eingetragen")
} }
@ -214,11 +269,14 @@ async fn new_dozen(
) )
.await; .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") Flash::success(Redirect::to("/ergo"), "Erfolgreich eingetragen")
} }
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![index, new_thirty, new_dozen, send, reset, update] routes![index, new_thirty, new_dozen, send, reset, update, new_user]
} }
#[cfg(test)] #[cfg(test)]

View File

@ -1,205 +0,0 @@
{% import "includes/macros" as macros %}
{% extends "base" %}
{% block content %}
<div class="max-w-screen-lg w-full">
<h1 class="h1">Ergo Challenges</h1>
<div class="grid gap-3">
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
role="alert">
<h2 class="h2">Ergo-Challenge?!</h2>
<div class="text-sm p-3">
<ul class="list-disc ms-2">
<li class="py-1">
<a href="https://rudernlinz.at/termin"
target="_blank"
class="link-primary">Überblick der Challenges</a>
</li>
<li class="py-1">
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">
Dienstag + Donnerstag &rarr; gemeinsames Training; bitte um <a href="/" class="link-primary">Anmeldung</a>, damit jeder einen Ergo hat
</li>
<li class="py-1">
Offizielle Ergebnisse: <a href="https://rudernlinz.at/dt"
target="_blank"
style="text-decoration: underline">Dirty Thirty (rudernlinz.at/dt)</a> / <a href="https://rudernlinz.at/dd"
target="_blank"
style="text-decoration: underline">Dirty Dozen (rudernlinz.at/dd)</a>, bei Fehlern direkt mit <a href="mailto:office@ergochallenge.at"
style="text-decoration: underline">Christian (Ister)</a> Kontakt aufnehmen
</li>
<li class="py-1">
<a href="https://cloud.rudernlinz.at/s/m7mPQdwSWscpaXT"
target="_blank"
class="link-primary">Noch mehr Infos zur Ergo-Challenge findest du hier</a>
</li>
</ul>
</div>
<details class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md p-2">
<summary class="cursor-pointer">Deine Daten</summary>
<div class="pt-3">
<p>
Folgende Daten hat der Ruderassistent von dir. Wenn diese nicht mehr aktuell sind, bitte gewünschte Änderungen an Philipp melden (Tel. nr siehe Signal, oder an <a href="mailto:it@rudernlinz.at"
class="text-primary-600 dark:text-primary-200 hover:text-primary-950 hover:dark:text-primary-300 underline"
target="_blank">it@rudernlinz.at</a>).
<br />
<br />
<ul>
<li>Geburtsdatum: {{ loggedin_user.dob }}</li>
<li>Gewicht: {{ loggedin_user.weight }} kg</li>
<li>Geschlecht: {{ loggedin_user.sex }}</li>
</ul>
</p>
</div>
</details>
</div>
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow grid gap-3">
<h2 class="h2">
Neuer Eintrag
</h1>
<details class="p-2">
<summary class="cursor-pointer">Dirty Thirty</summary>
<div class="mt-3">
<form action="/ergo/thirty"
class="grid gap-3"
method="post"
enctype="multipart/form-data">
<div>
<label for="user-thirty" class="text-sm text-gray-600 dark:text-gray-100">Ergo-Fahrer</label>
<select name="user" id="user-thirty" class="input rounded-md">
<option disabled="disabled">User auswählen</option>
{% for user in users %}
{% if user.id == loggedin_user.id %}
<option value="{{ user.id }}" selected="selected">{{ user.name }}</option>
{% else %}
<option value="{{ user.id }}">{{ user.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
{{ macros::input(label="Distanz [m]", name="result", required=true, type="number", class="input rounded-md") }}
<div>
<label for="file-thirty" class="text-sm text-gray-600 dark:text-gray-100">Ergebnis-Foto vom Ergo-Display</label>
<input type="file"
id="file-thirty"
name="proof"
class="input rounded-md"
accept="image/*">
</div>
<div class="text-end">
<input type="submit" value="Speichern" class="btn btn-primary btn-fw m-auto" />
</div>
</form>
</div>
</details>
<details class="p-2">
<summary class="cursor-pointer">Dirty Dozen</summary>
<div class="mt-3">
<form action="/ergo/dozen"
class="grid gap-3"
method="post"
enctype="multipart/form-data">
<div>
<label for="user-dozen" class="text-sm text-gray-600 dark:text-gray-100">Ergo-Fahrer</label>
<select name="user" id="user-dozen" class="input rounded-md">
<option disabled="disabled">User auswählen</option>
{% for user in users %}
{% if user.id == loggedin_user.id %}
<option value="{{ user.id }}" selected="selected">{{ user.name }}</option>
{% else %}
<option value="{{ user.id }}">{{ user.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
{{ 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+)?)") }}
<div>
<label for="file-dozen" class="text-sm text-gray-600 dark:text-gray-100">Ergebnis-Foto vom Ergo-Display</label>
<input type="file"
id="file-dozen"
name="proof"
class="input rounded-md"
accept="image/*">
</div>
<div class="text-end">
<input type="submit" value="Speichern" class="btn btn-primary btn-fw m-auto" />
</div>
</form>
</div>
</details>
</div>
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow grid gap-3">
<h2 class="h2">Aktuelle Woche</h2>
<details class="p-2">
<summary class="cursor-pointer">
Dirty Thirty <small class="text-gray-600 dark:text-white">({{ thirty | length }})</small>
</summary>
<div class="mt-3">
<ol>
{% for stat in thirty %}
<li>
<strong>{{ stat.name }}:</strong> {{ stat.result }}
</li>
{% endfor %}
</ol>
</div>
</details>
<details class="p-2">
<summary class="cursor-pointer">
Dirty Dozen <small class="text-gray-600 dark:text-white">({{ dozen | length }})</small>
</summary>
<div class="mt-3">
<ol>
{% for stat in dozen %}
<li>
<strong>{{ stat.name }}:</strong> {{ stat.result }}
</li>
{% endfor %}
</ol>
</div>
</details>
</div>
{% 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">
<summary class="cursor-pointer">
Dirty Thirty <small class="text-gray-600 dark:text-white">({{ thirty | length }})</small>
</summary>
<div class="mt-3">
<ol>
{% for stat in thirty %}
<li>
<form action="/ergo/thirty/user/{{ stat.id }}/new" method="get">
{{ stat.name }}:
<input type="text" value="{{ stat.result }}" name="new" style="color: black" />
<input type="submit" />
</form>
</li>
{% endfor %}
</ol>
</div>
</details>
<details class="p-2">
<summary class="cursor-pointer">
Dirty Dozen <small class="text-gray-600 dark:text-white">({{ dozen | length }})</small>
</summary>
<div class="mt-3">
<ol>
{% for stat in dozen %}
<li>
<form action="/ergo/dozen/user/{{ stat.id }}/new" method="get">
{{ stat.name }}:
<input type="text" value="{{ stat.result }}" name="new" style="color: black" />
<input type="submit" />
</form>
</li>
{% endfor %}
</ol>
</div>
</details>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,231 @@
{% import "includes/macros" as macros %}
{% extends "base" %}
{% block content %}
<div class="max-w-screen-lg w-full">
<h1 class="h1">Ergo Challenges</h1>
<div class="grid gap-3">
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
role="alert">
<h2 class="h2">Ergo-Challenge?!</h2>
<div class="text-sm p-3">
<ul class="list-disc ms-2">
<li class="py-1">
<a href="https://rudernlinz.at/termin"
target="_blank"
class="link-primary">Überblick der Challenges</a>
</li>
<li class="py-1">
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 &rarr; gemeinsames Training; bitte um <a href="/" class="link-primary">Anmeldung</a>, damit jeder einen Ergo hat
</li>
<li class="py-1">
Offizielle Ergebnisse: <a href="https://rudernlinz.at/dt"
target="_blank"
style="text-decoration: underline">Dirty Thirty (rudernlinz.at/dt)</a> / <a href="https://rudernlinz.at/dd"
target="_blank"
style="text-decoration: underline">Dirty Dozen (rudernlinz.at/dd)</a>, bei Fehlern direkt mit <a href="mailto:office@ergochallenge.at"
style="text-decoration: underline">Christian (Ister)</a> Kontakt aufnehmen
</li>
</ul>
</div>
<details class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md p-2">
<summary class="cursor-pointer">Noch mehr Infos</summary>
<strong>Um was geht es bei den Ergochallenges?</strong>
<p>
Der Linzer Verein Ister veranstaltet seit einigen Jahren zwei Challenges im Winter, Dirty Thirty (6x im Winter) und Dirty Dozen (12 Wochen lang).
<ul>
<li>Bei Dirty Thirty geht es darum so viele Kilometer wie möglich in 30 Minuten zu fahren.</li>
<li>
Bei Dirty Dozen werden jede Woche neue Ziele ausgeschrieben, gestartet wird mit einem Halbmarathon und es geht runter bis auf 100m.
</li>
</ul>
Ihr könnt gerne bei allen Challenges mitmachen und es ist möglich jederzeit ein- bzw. auszusteigen. Für alle komplett neuen Teilnehmer würde ich allerdings empfehlen die ersten beiden Dirty Dozen Challenges (Halbmarathon und 16 Kilometer) auszulassen und es am Anfang etwas ruhiger anzugehen. Es steht der Spaß und die Festigung der Technik im Vordergrund, nicht Rekorde.
<p>Video Tipps von Marie:</p>
<ul>
<li>
<a href="https://www.youtube.com/watch?v=TJsQPV6LNPI"
target="_blank"
style="text-decoration: underline">Intro</a>
</li>
<li>
<a href="https://www.youtube.com/watch?v=KOacKLOpWkI"
target="_blank"
style="text-decoration: underline">Schlagaufbau</a>
</li>
<li>
<a href="https://www.youtube.com/watch?v=m6VP11EDjcM"
target="_blank"
style="text-decoration: underline">PM5 Monitor</a>
</li>
</ul>
</details>
<details class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md p-2">
<summary class="cursor-pointer">Deine Daten</summary>
<div class="pt-3">
<p>
Folgende Daten hat der Ruderassistent von dir. Wenn diese nicht mehr aktuell sind, bitte gewünschte Änderungen an Philipp melden (Tel. nr siehe Signal, oder an <a href="mailto:it@rudernlinz.at"
class="text-primary-600 dark:text-primary-200 hover:text-primary-950 hover:dark:text-primary-300 underline"
target="_blank">it@rudernlinz.at</a>).
<br />
<br />
<ul>
<li>Geburtsdatum: {{ loggedin_user.dob }}</li>
<li>Gewicht: {{ loggedin_user.weight }} kg</li>
<li>Geschlecht: {{ loggedin_user.sex }}</li>
</ul>
</p>
</div>
</details>
</div>
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow grid gap-3">
<h2 class="h2">
Neuer Eintrag
</h1>
<details class="p-2">
<summary class="cursor-pointer">Dirty Thirty</summary>
<div class="mt-3">
<form action="/ergo/thirty"
class="grid gap-3"
method="post"
enctype="multipart/form-data">
<div>
<label for="user-thirty" class="text-sm text-gray-600 dark:text-gray-100">Ergo-Fahrer</label>
<select name="user" id="user-thirty" class="input rounded-md">
<option disabled="disabled">User auswählen</option>
{% for user in users %}
{% if user.id == loggedin_user.id %}
<option value="{{ user.id }}" selected="selected">{{ user.name }}</option>
{% else %}
<option value="{{ user.id }}">{{ user.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
{{ macros::input(label="Distanz [m]", name="result", required=true, type="number", class="input rounded-md") }}
<div>
<label for="file-thirty" class="text-sm text-gray-600 dark:text-gray-100">Ergebnis-Foto vom Ergo-Display</label>
<input type="file"
id="file-thirty"
name="proof"
class="input rounded-md"
accept="image/*">
</div>
<div class="text-end">
<input type="submit" value="Speichern" class="btn btn-primary btn-fw m-auto" />
</div>
</form>
</div>
</details>
<details class="p-2">
<summary class="cursor-pointer">Dirty Dozen</summary>
<div class="mt-3">
<form action="/ergo/dozen"
class="grid gap-3"
method="post"
enctype="multipart/form-data">
<div>
<label for="user-dozen" class="text-sm text-gray-600 dark:text-gray-100">Ergo-Fahrer</label>
<select name="user" id="user-dozen" class="input rounded-md">
<option disabled="disabled">User auswählen</option>
{% for user in users %}
{% if user.id == loggedin_user.id %}
<option value="{{ user.id }}" selected="selected">{{ user.name }}</option>
{% else %}
<option value="{{ user.id }}">{{ user.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
{{ 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+)?)") }}
<div>
<label for="file-dozen" class="text-sm text-gray-600 dark:text-gray-100">Ergebnis-Foto vom Ergo-Display</label>
<input type="file"
id="file-dozen"
name="proof"
class="input rounded-md"
accept="image/*">
</div>
<div class="text-end">
<input type="submit" value="Speichern" class="btn btn-primary btn-fw m-auto" />
</div>
</form>
</div>
</details>
</div>
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow grid gap-3">
<h2 class="h2">Aktuelle Woche</h2>
<details class="p-2">
<summary class="cursor-pointer">
Dirty Thirty <small class="text-gray-600 dark:text-white">({{ thirty | length }})</small>
</summary>
<div class="mt-3">
<ol>
{% for stat in thirty %}
<li>
<strong>{{ stat.name }}:</strong> {{ stat.result }}
</li>
{% endfor %}
</ol>
</div>
</details>
<details class="p-2">
<summary class="cursor-pointer">
Dirty Dozen <small class="text-gray-600 dark:text-white">({{ dozen | length }})</small>
</summary>
<div class="mt-3">
<ol>
{% for stat in dozen %}
<li>
<strong>{{ stat.name }}:</strong> {{ stat.result }}
</li>
{% endfor %}
</ol>
</div>
</details>
</div>
{% 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">
<summary class="cursor-pointer">
Dirty Thirty <small class="text-gray-600 dark:text-white">({{ thirty | length }})</small>
</summary>
<div class="mt-3">
<ol>
{% for stat in thirty %}
<li>
<form action="/ergo/thirty/user/{{ stat.id }}/new" method="get">
{{ stat.name }}:
<input type="text" value="{{ stat.result }}" name="new" style="color: black" />
<input type="submit" />
</form>
</li>
{% endfor %}
</ol>
</div>
</details>
<details class="p-2">
<summary class="cursor-pointer">
Dirty Dozen <small class="text-gray-600 dark:text-white">({{ dozen | length }})</small>
</summary>
<div class="mt-3">
<ol>
{% for stat in dozen %}
<li>
<form action="/ergo/dozen/user/{{ stat.id }}/new" method="get">
{{ stat.name }}:
<input type="text" value="{{ stat.result }}" name="new" style="color: black" />
<input type="submit" />
</form>
</li>
{% endfor %}
</ol>
</div>
</details>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,33 @@
{% import "includes/macros" as macros %}
{% import "includes/forms/boat" as boat %}
{% extends "base" %}
{% block content %}
<div class="max-w-screen-lg w-full dark:text-white">
<h1 class="h1">Ergo-Challenge</h1>
<div class="grid ">
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
role="alert">
<p class="mb-2">
Schön, dass du heuer bei der Ergo-Challenge mitmachen willst!
Dafür benötigen wir 3 Daten: Geburtsjahr, Gewicht und Geschlecht.
{% if loggedin_user.weight %}Wir haben von dir schon Daten, bitte überprüfe (und aktualisiere) diese kurz:{% endif %}
</p>
<form action="/ergo/set-data" method="post" class="grid gap-3 p-3">
{{ macros::input(label="Geburtsjahr [YYYY]", name="birthyear", required=true, type="number", class="input rounded-md", value=loggedin_user.dob) }}
{{ macros::input(label="Gewicht [kg]", name="weight", required=true, type="number", class="input rounded-md", value=loggedin_user.weight) }}
<select name="sex" id="sex" class="input rounded-md" required>
<option disabled="disabled"
{% if loggedin_user.sex != 'f' and loggedin_user.sex != 'm' %}selected="selected"{% endif %}>
Geschlecht auswählen
</option>
<option value="f"
{% if loggedin_user.sex == 'f' %}selected="selected"{% endif %}>weiblich</option>
<option value="m"
{% if loggedin_user.sex == 'm' %}selected="selected"{% endif %}>männlich</option>
</select>
<input type="submit" class="btn btn-primary" value="Abschicken" />
</form>
</div>
</div>
</div>
{% endblock content %}

View File

@ -303,6 +303,17 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
role="alert">
<h2 class="h2">Ergo</h2>
<div class="p-3">
<ul class="list-none ms-2">
<li class="py-1">
<a href="/ergo" class="block w-100 py-2 hover:text-primary-600">Ergo</a>
</li>
</ul>
</div>
</div>
{% if "schnupper-betreuer" in loggedin_user.roles %} {% if "schnupper-betreuer" in loggedin_user.roles %}
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5" <div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
role="alert"> role="alert">
@ -369,19 +380,6 @@
</ul> </ul>
</div> </div>
{% endif %} {% endif %}
{% if loggedin_user.weight and loggedin_user.sex and loggedin_user.dob %}
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
role="alert">
<h2 class="h2">Ergo</h2>
<div class="p-3">
<ul class="list-none ms-2">
<li class="py-1">
<a href="/ergo" class="block w-100 py-2 hover:text-primary-600">Ergo</a>
</li>
</ul>
</div>
</div>
{% endif %}
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5" <div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
role="alert"> role="alert">
<h2 class="h2">Allgemein</h2> <h2 class="h2">Allgemein</h2>