Merge branch 'staging' into 'main'
Staging See merge request PhilippHofer/rot!40
This commit is contained in:
commit
9087fa9453
@ -28,6 +28,7 @@ pub struct BoatDamageWithDetails {
|
||||
user_fixed: Option<User>,
|
||||
user_verified: Option<User>,
|
||||
boat: Boat,
|
||||
verified: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -102,6 +103,7 @@ ORDER BY created_at DESC
|
||||
.await
|
||||
.unwrap(),
|
||||
user_fixed,
|
||||
verified: user_verified.is_some(),
|
||||
user_verified,
|
||||
boat_damage,
|
||||
});
|
||||
|
@ -33,7 +33,7 @@ WHERE id in (SELECT rower_id FROM rower WHERE logbook_id=?)
|
||||
//TODO: Check if rower is allowed to row
|
||||
|
||||
sqlx::query!(
|
||||
"INSERT INTO rower(logbook_id, rower_id) VALUES (?,?)",
|
||||
"INSERT INTO rower(logbook_id, rower_id) VALUES (?,?);",
|
||||
logbook_id,
|
||||
rower_id
|
||||
)
|
||||
|
@ -43,7 +43,7 @@ async fn delete(db: &State<SqlitePool>, _admin: AdminUser, boat: i32) -> Flash<R
|
||||
boat.delete(db).await;
|
||||
Flash::success(
|
||||
Redirect::to("/admin/boat"),
|
||||
format!("Sucessfully deleted boat {}", boat.name),
|
||||
format!("Boot {} gelöscht", boat.name),
|
||||
)
|
||||
}
|
||||
None => Flash::error(Redirect::to("/admin/boat"), "Boat does not exist"),
|
||||
@ -63,7 +63,7 @@ async fn update(
|
||||
};
|
||||
|
||||
match boat.update(db, data.into_inner()).await {
|
||||
Ok(_) => Flash::success(Redirect::to("/admin/boat"), "Successfully updated boat"),
|
||||
Ok(_) => Flash::success(Redirect::to("/admin/boat"), "Boot bearbeitet"),
|
||||
Err(e) => Flash::error(Redirect::to("/admin/boat"), e),
|
||||
}
|
||||
}
|
||||
@ -75,7 +75,7 @@ async fn create(
|
||||
_admin: AdminUser,
|
||||
) -> Flash<Redirect> {
|
||||
match Boat::create(db, data.into_inner()).await {
|
||||
Ok(_) => Flash::success(Redirect::to("/admin/boat"), "Successfully created boat"),
|
||||
Ok(_) => Flash::success(Redirect::to("/admin/boat"), "Boot hinzugefügt"),
|
||||
Err(e) => Flash::error(Redirect::to("/admin/boat"), e),
|
||||
}
|
||||
}
|
||||
@ -153,7 +153,7 @@ mod test {
|
||||
.get("_flash")
|
||||
.expect("Expected flash cookie");
|
||||
|
||||
assert_eq!(flash_cookie.value(), "7:successSuccessfully updated boat");
|
||||
assert_eq!(flash_cookie.value(), "7:successBoot bearbeitet");
|
||||
|
||||
let boat = Boat::find_by_id(&db, 1).await.unwrap();
|
||||
assert_eq!(boat.name, "Haichiii");
|
||||
@ -267,7 +267,7 @@ mod test {
|
||||
.get("_flash")
|
||||
.expect("Expected flash cookie");
|
||||
|
||||
assert_eq!(flash_cookie.value(), "7:successSuccessfully created boat");
|
||||
assert_eq!(flash_cookie.value(), "7:successBoot hinzugefügt");
|
||||
|
||||
Boat::find_by_name(&db, "completely-new-boat".into())
|
||||
.await
|
||||
|
@ -36,7 +36,7 @@ async fn create(
|
||||
|
||||
PlannedEvent::create(db, data.name, data.planned_amount_cox, trip_details).await;
|
||||
|
||||
Flash::success(Redirect::to("/"), "Successfully planned the event")
|
||||
Flash::success(Redirect::to("/"), "Event hinzugefügt")
|
||||
}
|
||||
|
||||
//TODO: add constraints (e.g. planned_amount_cox > 0)
|
||||
@ -79,7 +79,7 @@ async fn delete(db: &State<SqlitePool>, id: i64, _admin: AdminUser) -> Flash<Red
|
||||
match PlannedEvent::find_by_id(db, id).await {
|
||||
Some(planned_event) => {
|
||||
planned_event.delete(db).await;
|
||||
Flash::success(Redirect::to("/"), "Successfully deleted the event")
|
||||
Flash::success(Redirect::to("/"), "Event gelöscht")
|
||||
}
|
||||
None => Flash::error(Redirect::to("/"), "PlannedEvent does not exist"),
|
||||
}
|
||||
@ -127,10 +127,7 @@ mod test {
|
||||
.get("_flash")
|
||||
.expect("Expected flash cookie");
|
||||
|
||||
assert_eq!(
|
||||
flash_cookie.value(),
|
||||
"7:successSuccessfully deleted the event"
|
||||
);
|
||||
assert_eq!(flash_cookie.value(), "7:successEvent gelöscht");
|
||||
|
||||
let event = PlannedEvent::find_by_id(&db, 1).await;
|
||||
assert_eq!(event, None);
|
||||
@ -265,10 +262,7 @@ mod test {
|
||||
.get("_flash")
|
||||
.expect("Expected flash cookie");
|
||||
|
||||
assert_eq!(
|
||||
flash_cookie.value(),
|
||||
"7:successSuccessfully planned the event"
|
||||
);
|
||||
assert_eq!(flash_cookie.value(), "7:successEvent hinzugefügt");
|
||||
|
||||
let event = PlannedEvent::find_by_id(&db, 2).await.unwrap();
|
||||
assert_eq!(event.name, "my-cool-new-event");
|
||||
|
@ -35,7 +35,7 @@ async fn resetpw(db: &State<SqlitePool>, _admin: AdminUser, user: i32) -> Flash<
|
||||
user.reset_pw(db).await;
|
||||
Flash::success(
|
||||
Redirect::to("/admin/user"),
|
||||
format!("Successfully reset pw of {}", user.name),
|
||||
format!("Passwort von {} zurückgesetzt", user.name),
|
||||
)
|
||||
}
|
||||
None => Flash::error(Redirect::to("/admin/user"), "User does not exist"),
|
||||
@ -50,7 +50,7 @@ async fn delete(db: &State<SqlitePool>, _admin: AdminUser, user: i32) -> Flash<R
|
||||
user.delete(db).await;
|
||||
Flash::success(
|
||||
Redirect::to("/admin/user"),
|
||||
format!("Sucessfully deleted user {}", user.name),
|
||||
format!("Benutzer {} gelöscht", user.name),
|
||||
)
|
||||
}
|
||||
None => Flash::error(Redirect::to("/admin/user"), "User does not exist"),
|
||||
|
@ -11,7 +11,6 @@ use rocket::{
|
||||
FromForm, Request, Route, State,
|
||||
};
|
||||
use rocket_dyn_templates::{context, tera, Template};
|
||||
use serde_json::json;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
use crate::model::{
|
||||
|
@ -26,7 +26,7 @@ async fn index_kiosk(
|
||||
) -> Template {
|
||||
let boatdamages = BoatDamage::all(db).await;
|
||||
let boats = Boat::all(db).await;
|
||||
let coxes = User::cox(db).await;
|
||||
let user = User::all(db).await;
|
||||
|
||||
let mut context = Context::new();
|
||||
if let Some(msg) = flash {
|
||||
@ -35,7 +35,8 @@ async fn index_kiosk(
|
||||
|
||||
context.insert("boatdamages", &boatdamages);
|
||||
context.insert("boats", &boats);
|
||||
context.insert("coxes", &coxes);
|
||||
context.insert("user", &user);
|
||||
context.insert("show_kiosk_header", &true);
|
||||
|
||||
Template::render("boatdamages", context.into_json())
|
||||
}
|
||||
@ -132,7 +133,7 @@ async fn fixed<'r>(
|
||||
user_id_fixed: coxuser.id as i32,
|
||||
};
|
||||
match boatdamage.fixed(db, boatdamage_fixed).await {
|
||||
Ok(_) => Flash::success(Redirect::to("/boatdamage"), "Successfully fixed the boat."),
|
||||
Ok(_) => Flash::success(Redirect::to("/boatdamage"), "Bootsschaden behoben."),
|
||||
Err(e) => Flash::error(Redirect::to("/boatdamage"), format!("Error: {e}")),
|
||||
}
|
||||
}
|
||||
@ -157,7 +158,7 @@ async fn verified<'r>(
|
||||
match boatdamage.verified(db, boatdamage_verified).await {
|
||||
Ok(_) => Flash::success(
|
||||
Redirect::to("/boatdamage"),
|
||||
"Successfully verified the boat.",
|
||||
"Bootsschaden verifiziert",
|
||||
),
|
||||
Err(e) => Flash::error(Redirect::to("/boatdamage"), format!("Error: {e}")),
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ async fn show(db: &State<SqlitePool>, user: User) -> Template {
|
||||
async fn show_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie) -> Template {
|
||||
let logs = Logbook::completed(db).await;
|
||||
|
||||
Template::render("log.completed", context!(logs))
|
||||
Template::render("log.completed", context!(logs, show_kiosk_header: true))
|
||||
}
|
||||
|
||||
#[get("/kiosk/ekrv2019/<loc>")]
|
||||
@ -148,6 +148,7 @@ async fn kiosk(
|
||||
context.insert("logtypes", &logtypes);
|
||||
context.insert("on_water", &on_water);
|
||||
context.insert("distances", &distances);
|
||||
context.insert("show_kiosk_header", &true);
|
||||
|
||||
Template::render("kiosk", context.into_json())
|
||||
}
|
||||
@ -207,11 +208,11 @@ async fn home_logbook(
|
||||
};
|
||||
|
||||
match logbook.home(db, user, data.into_inner()).await {
|
||||
Ok(_) => Flash::success(Redirect::to("/log"), "Successfully updated log"),
|
||||
Ok(_) => Flash::success(Redirect::to("/log"), "Ausfahrt korrekt eingetragen"),
|
||||
Err(LogbookUpdateError::TooManyRowers(expected, actual)) => Flash::error(Redirect::to("/log"), format!("Zu viele Ruderer (Boot fasst maximal {expected}, es wurden jedoch {actual} Ruderer ausgewählt)")),
|
||||
Err(_) => Flash::error(
|
||||
Redirect::to("/log"),
|
||||
format!("Logbook with ID {} could not be updated!", logbook_id),
|
||||
format!("Eintrag {} konnte nicht abgesendet werden!", logbook_id),
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -245,14 +246,43 @@ async fn home(
|
||||
home_logbook(db, data, logbook_id, &user).await
|
||||
}
|
||||
|
||||
#[get("/<logbook_id>/delete")]
|
||||
#[get("/<logbook_id>/delete", rank = 2)]
|
||||
async fn delete(db: &State<SqlitePool>, logbook_id: i32, user: User) -> Flash<Redirect> {
|
||||
let logbook = Logbook::find_by_id(db, logbook_id).await;
|
||||
if let Some(logbook) = logbook {
|
||||
match logbook.delete(db, &user).await {
|
||||
Ok(_) => Flash::success(
|
||||
Redirect::to("/log"),
|
||||
format!("Logbook with ID {} successfully deleted!", logbook_id),
|
||||
format!("Eintrag {} gelöscht!", logbook_id),
|
||||
),
|
||||
Err(LogbookDeleteError::NotYourEntry) => Flash::error(
|
||||
Redirect::to("/log"),
|
||||
"Du hast nicht die Berechtigung, den Eintrag zu löschen!",
|
||||
),
|
||||
}
|
||||
} else {
|
||||
Flash::error(
|
||||
Redirect::to("/log"),
|
||||
format!("Logbook with ID {} could not be found!", logbook_id),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/<logbook_id>/delete")]
|
||||
async fn delete_kiosk(
|
||||
db: &State<SqlitePool>,
|
||||
logbook_id: i32,
|
||||
_kiosk: KioskCookie,
|
||||
) -> Flash<Redirect> {
|
||||
let logbook = Logbook::find_by_id(db, logbook_id).await;
|
||||
if let Some(logbook) = logbook {
|
||||
let cox = User::find_by_id(db, logbook.shipmaster as i32)
|
||||
.await
|
||||
.unwrap();
|
||||
match logbook.delete(db, &cox).await {
|
||||
Ok(_) => Flash::success(
|
||||
Redirect::to("/log"),
|
||||
format!("Eintrag {} gelöscht!", logbook_id),
|
||||
),
|
||||
Err(LogbookDeleteError::NotYourEntry) => Flash::error(
|
||||
Redirect::to("/log"),
|
||||
@ -278,7 +308,8 @@ pub fn routes() -> Vec<Route> {
|
||||
new_kiosk,
|
||||
show,
|
||||
show_kiosk,
|
||||
delete
|
||||
delete,
|
||||
delete_kiosk
|
||||
]
|
||||
}
|
||||
|
||||
@ -471,7 +502,10 @@ mod test {
|
||||
.get("_flash")
|
||||
.expect("Expected flash cookie");
|
||||
|
||||
assert_eq!(flash_cookie.value(), "7:successSuccessfully updated log");
|
||||
assert_eq!(
|
||||
flash_cookie.value(),
|
||||
"7:successAusfahrt korrekt eingetragen"
|
||||
);
|
||||
}
|
||||
|
||||
//Kiosk mode
|
||||
@ -606,7 +640,10 @@ mod test {
|
||||
.get("_flash")
|
||||
.expect("Expected flash cookie");
|
||||
|
||||
assert_eq!(flash_cookie.value(), "7:successSuccessfully updated log");
|
||||
assert_eq!(
|
||||
flash_cookie.value(),
|
||||
"7:successAusfahrt korrekt eingetragen"
|
||||
);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
@ -796,7 +833,7 @@ mod test {
|
||||
|
||||
assert_eq!(
|
||||
flash_cookie.value(),
|
||||
"5:errorLogbook with ID 1 could not be updated!"
|
||||
"5:errorEintrag 1 konnte nicht abgesendet werden!"
|
||||
);
|
||||
}
|
||||
|
||||
@ -843,7 +880,10 @@ mod test {
|
||||
.get("_flash")
|
||||
.expect("Expected flash cookie");
|
||||
|
||||
assert_eq!(flash_cookie.value(), "7:successSuccessfully updated log");
|
||||
assert_eq!(
|
||||
flash_cookie.value(),
|
||||
"7:successAusfahrt korrekt eingetragen"
|
||||
);
|
||||
}
|
||||
|
||||
async fn cant_start_trip(
|
||||
|
@ -26,7 +26,7 @@ async fn index_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie) -> Template {
|
||||
let stat = Stat::get_rowed_km(db).await;
|
||||
let kiosk = true;
|
||||
|
||||
Template::render("stat", context!(stat, kiosk))
|
||||
Template::render("stat", context!(stat, kiosk, show_kiosk_header: true))
|
||||
}
|
||||
|
||||
pub fn routes() -> Vec<Route> {
|
||||
|
@ -12,9 +12,24 @@
|
||||
<body class="bg-gray-100">
|
||||
{% if loggedin_user %}
|
||||
{{ macros::header(loggedin_user=loggedin_user) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if show_kiosk_header %}
|
||||
<header class="bg-primary-900 text-white flex justify-between px-4 py-3 w-full z-10 ">
|
||||
<div>
|
||||
<a href="/">
|
||||
Hü
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/log" class="px-2">Ausfahrt eintragen</a>
|
||||
<a href="/log/show" class="px-2">Logbuch</a>
|
||||
<a href="/stat" class="px-2">Statistik</a>
|
||||
<a href="/boatdamage" class="px-2">Bootsschaden</a>
|
||||
</div>
|
||||
</header>
|
||||
{% endif %}
|
||||
|
||||
<div class="flex min-h-screen {%if not loggedin_user %} items-center {% else %} items-start {% endif %} justify-center px-4 py-12 sm:px-6 lg:px-8"> {% block content %}{% endblock content %}
|
||||
<div class="flex min-h-screen {%if not loggedin_user and not show_kiosk_header %} items-center {% else %} items-start {% endif %} justify-center px-4 py-12 sm:px-6 lg:px-8"> {% block content %}{% endblock content %}
|
||||
</div>
|
||||
|
||||
{% if loggedin_user %}
|
||||
|
@ -27,7 +27,7 @@
|
||||
<form action="/boatdamage" method="post" class="grid gap-3">
|
||||
{{ log::boat_select(only_ones=false, id='boat') }}
|
||||
{% if not loggedin_user %}
|
||||
{{ macros::select(label='Gemeldet von', data=coxes, name='user_id') }}
|
||||
{{ macros::select(label='Gemeldet von', data=user, name='user_id') }}
|
||||
{% endif %}
|
||||
{{ macros::input(label='Beschreibung des Schadens', name='desc', type='text', required=true, wrapper_class='col-span-4') }}
|
||||
<div class="col-span-4">
|
||||
@ -45,9 +45,9 @@
|
||||
|
||||
<div id="filter-result-js" class="bg-gray-200 text-primary-950 pb-3 px-3 text-right"></div>
|
||||
|
||||
{% for boatdamage in boatdamages %}
|
||||
{% for boatdamage in boatdamages | sort(attribute="verified") %}
|
||||
<div data-filterable="true" data-filter="{{ boatdamage.boat.name }} {{ boatdamage.user_created.name }}" class="w-full border-t bg-white p-3 {% if boatdamage.verified_at %} opacity-50 {% endif %}">
|
||||
<div>
|
||||
<div class="w-full">
|
||||
<strong>{{ boatdamage.created_at | date(format='%d.%m.%Y') }} <span class="font-normal text-gray-600">({{ boatdamage.boat.name }})</span></strong>{% if boatdamage.boat.damage %}<small class="block text-gray-600">(Boot gesperrt)</small>{% endif %}
|
||||
<div>{{ boatdamage.desc }}</div>
|
||||
<small class="block text-gray-600">
|
||||
@ -58,12 +58,12 @@
|
||||
<small class="block text-gray-600">Repariert von {{ boatdamage.user_fixed.name }} am/um {{ boatdamage.fixed_at | date(format='%d.%m.%Y (%H:%M)') }}</small>
|
||||
{% else %}
|
||||
{% if loggedin_user.is_cox %}
|
||||
<form action="/boatdamage/{{ boatdamage.id }}/fixed" method="post" class="mt-3">
|
||||
<input type="text" name="desc" value="{{ boatdamage.desc }}" />
|
||||
<form action="/boatdamage/{{ boatdamage.id }}/fixed" method="post" class="flex justify-between mt-3">
|
||||
<input type="text" name="desc" value="{{ boatdamage.desc }}" class="grow input rounded-s" />
|
||||
{% if loggedin_user.is_tech %}
|
||||
<input type="submit" class="btn btn-primary" value="Repariert und verifiziert" />
|
||||
<input type="submit" class="btn btn-primary" style="border-top-left-radius: 0; border-bottom-left-radius: 0;" value="Repariert und verifiziert" />
|
||||
{% else %}
|
||||
<input type="submit" class="btn btn-primary" value="Repariert" />
|
||||
<input type="submit" class="btn btn-primary" style="border-top-left-radius: 0; border-bottom-left-radius: 0;" value="Repariert" />
|
||||
{% endif %}
|
||||
</form>
|
||||
{% endif %}
|
||||
@ -73,9 +73,9 @@
|
||||
<small class="block text-gray-600">Verifziert von {{ boatdamage.user_verified.name }} am/um {{ boatdamage.verified_at | date(format='%d.%m.%Y (%H:%M)') }}</small>
|
||||
{% else %}
|
||||
{% if loggedin_user.is_tech and boatdamage.fixed_at %}
|
||||
<form action="/boatdamage/{{ boatdamage.id }}/verified" method="post" class="mt-3">
|
||||
<input type="text" name="desc" value="{{ boatdamage.desc }}" />
|
||||
<input type="submit" class="btn btn-dark" value="Verifiziert" />
|
||||
<form action="/boatdamage/{{ boatdamage.id }}/verified" method="post" class="flex justify-between mt-3">
|
||||
<input type="text" name="desc" value="{{ boatdamage.desc }}" class="grow input rounded-s"/>
|
||||
<input type="submit" class="btn btn-dark" style="border-top-left-radius: 0; border-bottom-left-radius: 0;" value="Verifiziert" />
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
@ -162,25 +162,31 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="log{{ log.id }}">
|
||||
{% if log.destination %}
|
||||
{{ log.destination }}
|
||||
{% endif %}
|
||||
{% if log.destination %}
|
||||
{{ log.destination }}
|
||||
{% endif %}
|
||||
|
||||
{% for user in users %}
|
||||
{% if user.id == log.shipmaster %}
|
||||
<p>
|
||||
<strong>{{ user.name }}</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for user in users %}
|
||||
{% if user.id == log.shipmaster %}
|
||||
<p>
|
||||
<strong>{{ user.name }}</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for rower in log.rowers %}
|
||||
<p>{{ rower.name }}</p>
|
||||
{% endfor %}
|
||||
|
||||
{% if allowed_to_close and state == "on_water" %}
|
||||
<a href="/log/{{ log.id }}/delete" onclick="return confirm('Willst du diesen Eintrag wirklich löschen? Die Daten gehen verloren :O');">LÖSCHEN</a>
|
||||
|
||||
{% set amount_rowers = log.rowers | length %}
|
||||
{% set amount_guests = log.boat.amount_seats - amount_rowers -1 %}
|
||||
{% if amount_guests > 0 %}
|
||||
Gäste (ohne Account): {{ amount_guests }}
|
||||
{% endif %}
|
||||
|
||||
{% if allowed_to_close and state == "on_water" %}
|
||||
<a href="/log/{{ log.id }}/delete" class="btn btn-alert w-full absolute bottom-0 left-0" style="border-radius: 0;" onclick="return confirm('Willst du diesen Eintrag wirklich löschen? Die Daten gehen verloren');">Löschen</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -235,8 +241,7 @@
|
||||
{{ rower.name }}{% if not loop.last or amount_guests > 0 %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% if amount_guests > 0 %}
|
||||
{{ amount_guests }}
|
||||
Gäste (ohne Account)
|
||||
Gäste (ohne Account): {{ amount_guests }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -9,7 +9,9 @@
|
||||
<h1 class="h1">Logbuch</h1>
|
||||
|
||||
{% if flash %}
|
||||
{{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }}
|
||||
<div class="pt-3 max-w-lg m-auto">
|
||||
{{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="w-full grid md:grid-cols-5 gap-3 mt-5">
|
||||
|
Loading…
Reference in New Issue
Block a user