diff --git a/README.md b/README.md index 946593f..fb27823 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ ## New large features ### Logbuch - Only layout + tests missing :-) + ### Guest-Scheckbuch - guest_trip - guest_user_id diff --git a/src/tera/log.rs b/src/tera/log.rs index a9df73a..95a0824 100644 --- a/src/tera/log.rs +++ b/src/tera/log.rs @@ -1,9 +1,9 @@ use rocket::{ form::Form, get, post, - request::FlashMessage, + request::{FlashMessage, FromRequest, self}, response::{Flash, Redirect}, - routes, Route, State, + routes, Route, State, Request, http::{CookieJar, Cookie}, time::{OffsetDateTime, Duration}, }; use rocket_dyn_templates::Template; use sqlx::SqlitePool; @@ -16,6 +16,20 @@ use crate::model::{ user::{AdminUser, User}, }; +pub struct KioskCookie(String); + +#[rocket::async_trait] +impl<'r> FromRequest<'r> for KioskCookie { + type Error = std::convert::Infallible; + + async fn from_request(request: &'r Request<'_>) -> request::Outcome { + match request.cookies().get_private("kiosk") { + Some(cookie) => request::Outcome::Success(KioskCookie(cookie.value().to_string())), + None => request::Outcome::Forward(()), + } + } +} + #[get("/")] async fn index( db: &State, @@ -48,7 +62,46 @@ async fn index( Template::render("log", context.into_json()) } -#[post("/", data = "")] + +#[get("/kiosk/ekrv2019")] +fn new_kiosk( + flash: Option>, + cookies: &CookieJar<'_>, +) -> Redirect { + let mut cookie = Cookie::new("kiosk", format!("yes")); + cookie.set_expires(OffsetDateTime::now_utc() + Duration::weeks(12)); + cookies.add_private(cookie); + Redirect::to("/log/kiosk") +} + +#[get("/kiosk")] +async fn kiosk(db: &State, flash: Option>, _kiosk: KioskCookie) -> Template { + let boats = Boat::all(db).await; + let coxes = User::cox(db).await; + let users = User::all(db).await; + let logtypes = LogType::all(db).await; + let distances = Logbook::distances(db).await; + + let on_water = Logbook::on_water(db).await; + let completed = Logbook::completed(db).await; + + let mut context = Context::new(); + if let Some(msg) = flash { + context.insert("flash", &msg.into_inner()); + } + + context.insert("boats", &boats); + context.insert("coxes", &coxes); + context.insert("users", &users); + context.insert("logtypes", &logtypes); + context.insert("on_water", &on_water); + context.insert("completed", &completed); + context.insert("distances", &distances); + + Template::render("kiosk", context.into_json()) +} + +#[post("/", data = "", rank=2)] async fn create( db: &State, data: Form, @@ -68,7 +121,51 @@ async fn create( } } +#[post("/", data = "")] +async fn create_kiosk( + db: &State, + data: Form, +) -> Flash { + match Logbook::create( + db, + data.into_inner() + ) + .await + { + Ok(_) => Flash::success(Redirect::to("/log/kiosk"), "Ausfahrt erfolgreich hinzugefügt"), + Err(LogbookCreateError::BoatAlreadyOnWater) => Flash::error(Redirect::to("/log/kiosk"), format!("Boot schon am Wasser")), + Err(LogbookCreateError::BoatLocked) => Flash::error(Redirect::to("/log/kiosk"), format!("Boot gesperrt")), + Err(LogbookCreateError::BoatNotFound) => Flash::error(Redirect::to("/log/kiosk"), format!("Boot gibt's ned")), + Err(LogbookCreateError::TooManyRowers(expected, actual)) => Flash::error(Redirect::to("/log/kiosk"), format!("Zu viele Ruderer (Boot fasst maximal {expected}, es wurden jedoch {actual} Ruderer ausgewählt)")), + } +} + + #[post("/", data = "")] +async fn home_kiosk( + db: &State, + data: Form, + logbook_id: i32, +) -> Flash { + let logbook = Logbook::find_by_id(db, logbook_id).await; + let Some(logbook) = logbook else { + return Flash::error( + Redirect::to("/admin/log"), + format!("Log with ID {} does not exist!", logbook_id), + ) + }; + + match logbook.home(db, &User::find_by_id(db, logbook.shipmaster as i32).await.unwrap(), data.into_inner()).await { + Ok(_) => Flash::success(Redirect::to("/log"), "Successfully updated log"), + Err(_) => Flash::error( + Redirect::to("/log"), + format!("Logbook with ID {} could not be updated!", logbook_id), + ), + } +} + + +#[post("/", data = "", rank=2)] async fn home( db: &State, data: Form, @@ -93,7 +190,7 @@ async fn home( } pub fn routes() -> Vec { - routes![index, create, home] + routes![index, create, create_kiosk, home, kiosk, home_kiosk, new_kiosk] } #[cfg(test)] diff --git a/templates/includes/forms/log.html.tera b/templates/includes/forms/log.html.tera index bd3c83a..2d5895e 100644 --- a/templates/includes/forms/log.html.tera +++ b/templates/includes/forms/log.html.tera @@ -1,10 +1,10 @@ -{% macro new() %} +{% macro new(only_ones, allow_any_shipmaster, shipmaster) %}
- {% if loggedin_user.is_cox %} - {{ macros::select(data=boats, select_name='boat_id', display=["name", " (","amount_seats", " x)"], extras=["default_shipmaster_only_steering", "amount_seats"]) }} + {% if not only_ones %} + {{ macros::select(data=boats, select_name='boat_id', display=["name", " (","amount_seats", " x)"], extras=["default_shipmaster_only_steering", "amount_seats"]) }} {% else %} {% set ones = boats | filter(attribute="amount_seats", value=1) %} - {{ macros::select(data=ones, select_name='boat_id', display=["name", " (","amount_seats", " x)"], extras=["default_shipmaster_only_steering", "amount_seats"]) }} + {{ macros::select(data=ones, select_name='boat_id', display=["name", " (","amount_seats", " x)"], extras=["default_shipmaster_only_steering", "amount_seats"]) }} {% endif %} - {% if loggedin_user.is_cox %} + {% if allow_any_shipmaster %} {% else %} - + {% endif %} - {% if loggedin_user.is_cox %} + {% if only_ones %} {{ macros::checkbox(label='shipmaster_only_steering', name='shipmaster_only_steering') }} {% endif %} Departure: @@ -57,7 +57,7 @@ {{ macros::input(label="Distanz", name="distance_in_km", type="number", min=0) }} {{ macros::input(label="Kommentar", name="comments", type="text") }} {{ macros::select(data=logtypes, select_name='logtype', default="Normal") }} - {% if loggedin_user.is_cox %} + {% if not only_ones %} {{ log::rower_select(id="newrower", selected=[]) }} {% endif %} @@ -86,7 +86,7 @@ {% endmacro new %} -{% macro show(log, state) %} +{% macro show(log, state, allowed_to_close=false, only_ones) %} Bootsname: {{ log.boat.name }}
Schiffsführer: {{ log.shipmaster_user.name }}
{% if log.shipmaster_only_steering %} @@ -98,8 +98,8 @@ {% endif %} {% set amount_rowers = log.rowers | length %} {% set amount_guests = log.boat.amount_seats - amount_rowers -1 %} - {% if log.shipmaster == loggedin_user.id and state == "on_water" %} - {{ log::home(log=log) }} + {% if allowed_to_close and state == "on_water" %} + {{ log::home(log=log, only_ones=only_ones) }} {% else %} Ziel: {{ log.destination }}
{% if state == "completed" %} @@ -123,7 +123,7 @@ {% endif %} {% endmacro show %} -{% macro home(log) %} +{% macro home(log, only_ones) %} Destination: diff --git a/templates/kiosk.html.tera b/templates/kiosk.html.tera new file mode 100644 index 0000000..ec212d3 --- /dev/null +++ b/templates/kiosk.html.tera @@ -0,0 +1,25 @@ +{% import "includes/macros" as macros %} +{% import "includes/forms/log" as log %} + +{% extends "base" %} + +{% block content %} +
+

Logbuch

+

Neue Ausfahrt starten

+ {{ log::new(only_ones=false, allow_any_shipmaster=true, shipmaster=-1) }} + +

Am Wasser

+ {% for log in on_water %} + {{ log::show(log=log, state="on_water", allowed_to_close=true, only_ones=false) }} +
+ {% endfor %} + +

Einträge

+ {% for log in completed %} + {{ log::show(log=log, state="completed", only_ones=false) }} +
+ {% endfor %} +
+ +{% endblock content%} diff --git a/templates/log.html.tera b/templates/log.html.tera index ae3eb18..3e8a0ac 100644 --- a/templates/log.html.tera +++ b/templates/log.html.tera @@ -7,17 +7,21 @@

Logbuch

Neue Ausfahrt starten

- {{ log::new() }} + {{ log::new(only_ones=loggedin_user.is_cox==false, allow_any_shipmaster=loggedin_user.is_cox, shipmaster=loggedin_user.id) }}

Am Wasser

{% for log in on_water %} - {{ log::show(log=log, state="on_water") }} + {% if log.shipmaster == loggedin_user.id %} + {{ log::show(log=log, state="on_water", allowed_to_close=true, only_ones=false) }} + {% else %} + {{ log::show(log=log, state="on_water", only_ones=true) }} + {% endif %}
{% endfor %}

Einträge

{% for log in completed %} - {{ log::show(log=log, state="completed") }} + {{ log::show(log=log, state="completed", only_ones=false) }}
{% endfor %}