Merge branch 'staging' into 'main'

Staging

See merge request PhilippHofer/rot!37
This commit is contained in:
PhilippHofer 2023-10-05 08:03:16 +00:00
commit ca4cab3030
8 changed files with 194 additions and 84 deletions

115
Cargo.lock generated
View File

@ -164,6 +164,15 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
[[package]]
name = "atomic"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994"
dependencies = [
"bytemuck",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -249,6 +258,12 @@ version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "bytemuck"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.4.3" version = "1.4.3"
@ -518,9 +533,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.3" version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480"
dependencies = [ dependencies = [
"errno-dragonfly", "errno-dragonfly",
"libc", "libc",
@ -545,17 +560,17 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "2.0.0" version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]] [[package]]
name = "figment" name = "figment"
version = "0.10.10" version = "0.10.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4547e226f4c9ab860571e070a9034192b3175580ecea38da34fcdb53a018c9a5" checksum = "a014ac935975a70ad13a3bff2463b1c1b083b35ae4cb6309cfc59476aa7a181f"
dependencies = [ dependencies = [
"atomic", "atomic 0.6.0",
"pear", "pear",
"serde", "serde",
"toml", "toml",
@ -824,9 +839,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.0" version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
dependencies = [ dependencies = [
"ahash 0.8.3", "ahash 0.8.3",
"allocator-api2", "allocator-api2",
@ -838,7 +853,7 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
dependencies = [ dependencies = [
"hashbrown 0.14.0", "hashbrown 0.14.1",
] ]
[[package]] [[package]]
@ -1022,12 +1037,12 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.0.0" version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.14.0", "hashbrown 0.14.1",
] ]
[[package]] [[package]]
@ -1160,9 +1175,9 @@ dependencies = [
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.7" version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
@ -1206,9 +1221,9 @@ dependencies = [
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.6.3" version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]] [[package]]
name = "mime" name = "mime"
@ -1461,9 +1476,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]] [[package]]
name = "pest" name = "pest"
version = "2.7.3" version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4"
dependencies = [ dependencies = [
"memchr", "memchr",
"thiserror", "thiserror",
@ -1472,9 +1487,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_derive" name = "pest_derive"
version = "2.7.3" version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8"
dependencies = [ dependencies = [
"pest", "pest",
"pest_generator", "pest_generator",
@ -1482,9 +1497,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_generator" name = "pest_generator"
version = "2.7.3" version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a"
dependencies = [ dependencies = [
"pest", "pest",
"pest_meta", "pest_meta",
@ -1495,9 +1510,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_meta" name = "pest_meta"
version = "2.7.3" version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"pest", "pest",
@ -1705,13 +1720,13 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.9.5" version = "1.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
"regex-automata 0.3.8", "regex-automata 0.3.9",
"regex-syntax 0.7.5", "regex-syntax 0.7.5",
] ]
@ -1726,9 +1741,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.3.8" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@ -1770,7 +1785,7 @@ checksum = "58734f7401ae5cfd129685b48f61182331745b357b96f2367f01aebaf1cc9cc9"
dependencies = [ dependencies = [
"async-stream", "async-stream",
"async-trait", "async-trait",
"atomic", "atomic 0.5.3",
"binascii", "binascii",
"bytes", "bytes",
"either", "either",
@ -1883,9 +1898,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.14" version = "0.38.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" checksum = "d2f9da0cbd88f9f09e7814e388301c8414c51c62aa6ce1e4b5c551d49d96e531"
dependencies = [ dependencies = [
"bitflags 2.4.0", "bitflags 2.4.0",
"errno", "errno",
@ -2000,9 +2015,9 @@ dependencies = [
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.10.7" version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures",
@ -2011,9 +2026,9 @@ dependencies = [
[[package]] [[package]]
name = "sharded-slab" name = "sharded-slab"
version = "0.1.4" version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" checksum = "c1b21f559e07218024e7e9f90f96f601825397de0e25420135f7f952453fed0b"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
] ]
@ -2294,18 +2309,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.48" version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.48" version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2432,9 +2447,9 @@ dependencies = [
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.7.8" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
dependencies = [ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
@ -2453,11 +2468,11 @@ dependencies = [
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.19.15" version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
dependencies = [ dependencies = [
"indexmap 2.0.0", "indexmap 2.0.2",
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
@ -2546,9 +2561,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]] [[package]]
name = "ubyte" name = "ubyte"
version = "0.10.3" version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6" checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@ -2794,9 +2809,9 @@ dependencies = [
[[package]] [[package]]
name = "webpki" name = "webpki"
version = "0.22.1" version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" checksum = "07ecc0cd7cac091bf682ec5efa18b1cff79d617b84181f38b3951dbe135f607f"
dependencies = [ dependencies = [
"ring", "ring",
"untrusted", "untrusted",

View File

@ -9,8 +9,6 @@
- [] reload page -> don't throw input away! - [] reload page -> don't throw input away!
## Backend ## Backend
- [] variable for kiosk mode (needed especially for header)
- [] boat_damage -> Add user_select
# Nice to have # Nice to have
## Frontend ## Frontend

View File

@ -148,9 +148,8 @@ ORDER BY amount_seats DESC
if user.is_admin { if user.is_admin {
return Self::all(db).await; return Self::all(db).await;
} }
let boats; let boats = if user.is_cox {
if user.is_cox { sqlx::query_as!(
boats = sqlx::query_as!(
Boat, Boat,
" "
SELECT id, name, amount_seats, location_id, owner, year_built, boatbuilder, default_shipmaster_only_steering, skull, external SELECT id, name, amount_seats, location_id, owner, year_built, boatbuilder, default_shipmaster_only_steering, skull, external
@ -162,9 +161,9 @@ ORDER BY amount_seats DESC
) )
.fetch_all(db) .fetch_all(db)
.await .await
.unwrap(); //TODO: fixme .unwrap() //TODO: fixme
} else { } else {
boats = sqlx::query_as!( sqlx::query_as!(
Boat, Boat,
" "
SELECT id, name, amount_seats, location_id, owner, year_built, boatbuilder, default_shipmaster_only_steering, skull, external SELECT id, name, amount_seats, location_id, owner, year_built, boatbuilder, default_shipmaster_only_steering, skull, external
@ -176,8 +175,8 @@ ORDER BY amount_seats DESC
) )
.fetch_all(db) .fetch_all(db)
.await .await
.unwrap(); //TODO: fixme .unwrap() //TODO: fixme
} };
Self::boats_to_details(db, boats).await Self::boats_to_details(db, boats).await
} }

View File

@ -4,6 +4,8 @@ use rocket::serde::{Deserialize, Serialize};
use rocket::FromForm; use rocket::FromForm;
use sqlx::{FromRow, SqlitePool}; use sqlx::{FromRow, SqlitePool};
use super::log::Log;
#[derive(FromRow, Debug, Serialize, Deserialize)] #[derive(FromRow, Debug, Serialize, Deserialize)]
pub struct BoatDamage { pub struct BoatDamage {
pub id: i64, pub id: i64,
@ -28,6 +30,7 @@ pub struct BoatDamageWithDetails {
boat: Boat, boat: Boat,
} }
#[derive(Debug)]
pub struct BoatDamageToAdd<'r> { pub struct BoatDamageToAdd<'r> {
pub boat_id: i64, pub boat_id: i64,
pub desc: &'r str, pub desc: &'r str,
@ -35,13 +38,13 @@ pub struct BoatDamageToAdd<'r> {
pub lock_boat: bool, pub lock_boat: bool,
} }
#[derive(FromForm)] #[derive(FromForm, Debug)]
pub struct BoatDamageFixed<'r> { pub struct BoatDamageFixed<'r> {
pub desc: &'r str, pub desc: &'r str,
pub user_id_fixed: i32, pub user_id_fixed: i32,
} }
#[derive(FromForm)] #[derive(FromForm, Debug)]
pub struct BoatDamageVerified<'r> { pub struct BoatDamageVerified<'r> {
pub desc: &'r str, pub desc: &'r str,
pub user_id_verified: i32, pub user_id_verified: i32,
@ -107,6 +110,8 @@ ORDER BY created_at DESC
} }
pub async fn create(db: &SqlitePool, boatdamage: BoatDamageToAdd<'_>) -> Result<(), String> { pub async fn create(db: &SqlitePool, boatdamage: BoatDamageToAdd<'_>) -> Result<(), String> {
Log::create(db, format!("New boat damage: {boatdamage:?}")).await;
sqlx::query!( sqlx::query!(
"INSERT INTO boat_damage(boat_id, desc, user_id_created, lock_boat) VALUES (?,?,?, ?)", "INSERT INTO boat_damage(boat_id, desc, user_id_created, lock_boat) VALUES (?,?,?, ?)",
boatdamage.boat_id, boatdamage.boat_id,
@ -121,6 +126,8 @@ ORDER BY created_at DESC
} }
pub async fn fixed(&self, db: &SqlitePool, boat: BoatDamageFixed<'_>) -> Result<(), String> { pub async fn fixed(&self, db: &SqlitePool, boat: BoatDamageFixed<'_>) -> Result<(), String> {
Log::create(db, format!("Fixed boat damage: {boat:?}")).await;
sqlx::query!( sqlx::query!(
"UPDATE boat_damage SET desc=?, user_id_fixed=?, fixed_at=CURRENT_TIMESTAMP WHERE id=?", "UPDATE boat_damage SET desc=?, user_id_fixed=?, fixed_at=CURRENT_TIMESTAMP WHERE id=?",
boat.desc, boat.desc,
@ -152,7 +159,17 @@ ORDER BY created_at DESC
db: &SqlitePool, db: &SqlitePool,
boat: BoatDamageVerified<'_>, boat: BoatDamageVerified<'_>,
) -> Result<(), String> { ) -> Result<(), String> {
//TODO: Check if user is allowed to verify if let Some(verifier) = User::find_by_id(db, boat.user_id_verified).await {
if !verifier.is_tech {
Log::create(db, format!("User {verifier:?} tried to verify boat {boat:?}. The user is no tech. Manually craftted request?")).await;
return Err("You are not allowed to verify the boat!".into());
}
} else {
Log::create(db, format!("Someone tried to verify the boat {boat:?} with user_id={} which does not exist. Manually craftted request?", boat.user_id_verified)).await;
return Err("Could not find user".into());
}
Log::create(db, format!("Verified boat damage: {boat:?}")).await;
sqlx::query!( sqlx::query!(
"UPDATE boat_damage SET desc=?, user_id_verified=?, verified_at=CURRENT_TIMESTAMP WHERE id=?", "UPDATE boat_damage SET desc=?, user_id_verified=?, verified_at=CURRENT_TIMESTAMP WHERE id=?",

View File

@ -1,10 +1,10 @@
use chrono::{Local, NaiveDateTime, TimeZone}; use chrono::{NaiveDateTime, TimeZone};
use chrono_tz::Europe::Vienna; use chrono_tz::Europe::Vienna;
use rocket::FromForm; use rocket::FromForm;
use serde::Serialize; use serde::Serialize;
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
use super::{boat::Boat, rower::Rower, user::User}; use super::{boat::Boat, log::Log, rower::Rower, user::User};
#[derive(FromRow, Serialize, Clone, Debug)] #[derive(FromRow, Serialize, Clone, Debug)]
pub struct Logbook { pub struct Logbook {
@ -196,7 +196,7 @@ ORDER BY departure DESC
if let Some(arrival) = &log.arrival { if let Some(arrival) = &log.arrival {
let dep = NaiveDateTime::parse_from_str(&log.departure, "%Y-%m-%dT%H:%M").unwrap(); let dep = NaiveDateTime::parse_from_str(&log.departure, "%Y-%m-%dT%H:%M").unwrap();
let arr = NaiveDateTime::parse_from_str(&arrival, "%Y-%m-%dT%H:%M").unwrap(); let arr = NaiveDateTime::parse_from_str(arrival, "%Y-%m-%dT%H:%M").unwrap();
if arr <= dep { if arr <= dep {
return Err(LogbookCreateError::ArrivalNotAfterDeparture); return Err(LogbookCreateError::ArrivalNotAfterDeparture);
} }
@ -232,6 +232,7 @@ ORDER BY departure DESC
} }
//let departure = format!("{}+02:00", &log.departure); //let departure = format!("{}+02:00", &log.departure);
Log::create(db, format!("New trip started: {log:?}")).await;
let mut tx = db.begin().await.unwrap(); let mut tx = db.begin().await.unwrap();
@ -339,6 +340,7 @@ ORDER BY departure DESC
return Err(LogbookUpdateError::ArrivalNotAfterDeparture); return Err(LogbookUpdateError::ArrivalNotAfterDeparture);
} }
Log::create(db, format!("New trip: {log:?}")).await;
let mut tx = db.begin().await.unwrap(); let mut tx = db.begin().await.unwrap();
sqlx::query!( sqlx::query!(
@ -367,6 +369,8 @@ ORDER BY departure DESC
} }
pub async fn delete(&self, db: &SqlitePool, user: &User) -> Result<(), LogbookDeleteError> { pub async fn delete(&self, db: &SqlitePool, user: &User) -> Result<(), LogbookDeleteError> {
Log::create(db, format!("{user:?} deleted trip: {self:?}")).await;
if user.is_admin || user.id == self.shipmaster { if user.is_admin || user.id == self.shipmaster {
sqlx::query!("DELETE FROM logbook WHERE id=?", self.id) sqlx::query!("DELETE FROM logbook WHERE id=?", self.id)
.execute(db) .execute(db)

View File

@ -9,13 +9,38 @@ use rocket_dyn_templates::Template;
use sqlx::SqlitePool; use sqlx::SqlitePool;
use tera::Context; use tera::Context;
use crate::model::{ use crate::{
model::{
boat::Boat, boat::Boat,
boatdamage::{BoatDamage, BoatDamageFixed, BoatDamageToAdd, BoatDamageVerified}, boatdamage::{BoatDamage, BoatDamageFixed, BoatDamageToAdd, BoatDamageVerified},
user::{CoxUser, TechUser, User}, user::{CoxUser, TechUser, User},
},
tera::log::KioskCookie,
}; };
#[get("/")] #[get("/")]
async fn index_kiosk(
db: &State<SqlitePool>,
flash: Option<FlashMessage<'_>>,
_kiosk: KioskCookie,
) -> Template {
let boatdamages = BoatDamage::all(db).await;
let boats = Boat::all(db).await;
let coxes = User::cox(db).await;
let mut context = Context::new();
if let Some(msg) = flash {
context.insert("flash", &msg.into_inner());
}
context.insert("boatdamages", &boatdamages);
context.insert("boats", &boats);
context.insert("coxes", &coxes);
Template::render("boatdamages", context.into_json())
}
#[get("/", rank = 2)]
async fn index(db: &State<SqlitePool>, flash: Option<FlashMessage<'_>>, user: User) -> Template { async fn index(db: &State<SqlitePool>, flash: Option<FlashMessage<'_>>, user: User) -> Template {
let boatdamages = BoatDamage::all(db).await; let boatdamages = BoatDamage::all(db).await;
let boats = Boat::all(db).await; let boats = Boat::all(db).await;
@ -39,7 +64,7 @@ pub struct FormBoatDamageToAdd<'r> {
pub lock_boat: bool, pub lock_boat: bool,
} }
#[post("/", data = "<data>")] #[post("/", data = "<data>", rank = 2)]
async fn create<'r>( async fn create<'r>(
db: &State<SqlitePool>, db: &State<SqlitePool>,
data: Form<FormBoatDamageToAdd<'r>>, data: Form<FormBoatDamageToAdd<'r>>,
@ -54,7 +79,36 @@ async fn create<'r>(
match BoatDamage::create(db, boatdamage_to_add).await { match BoatDamage::create(db, boatdamage_to_add).await {
Ok(_) => Flash::success( Ok(_) => Flash::success(
Redirect::to("/boatdamage"), Redirect::to("/boatdamage"),
"Ausfahrt erfolgreich hinzugefügt", "Bootsschaden erfolgreich hinzugefügt",
),
Err(e) => Flash::error(Redirect::to("/boatdamage"), format!("Fehler: {e}")),
}
}
#[derive(FromForm)]
pub struct FormBoatDamageToAddKiosk<'r> {
pub boat_id: i64,
pub desc: &'r str,
pub lock_boat: bool,
pub user_id: i32,
}
#[post("/", data = "<data>")]
async fn create_from_kiosk<'r>(
db: &State<SqlitePool>,
data: Form<FormBoatDamageToAddKiosk<'r>>,
_kiosk: KioskCookie,
) -> Flash<Redirect> {
let boatdamage_to_add = BoatDamageToAdd {
boat_id: data.boat_id,
desc: data.desc,
lock_boat: data.lock_boat,
user_id_created: data.user_id,
};
match BoatDamage::create(db, boatdamage_to_add).await {
Ok(_) => Flash::success(
Redirect::to("/boatdamage"),
"Bootsschaden erfolgreich hinzugefügt",
), ),
Err(e) => Flash::error(Redirect::to("/boatdamage"), format!("Fehler: {e}")), Err(e) => Flash::error(Redirect::to("/boatdamage"), format!("Fehler: {e}")),
} }
@ -110,5 +164,12 @@ async fn verified<'r>(
} }
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![index, create, fixed, verified] routes![
index,
index_kiosk,
create,
fixed,
verified,
create_from_kiosk
]
} }

View File

@ -1,3 +1,5 @@
use std::net::IpAddr;
use rocket::{ use rocket::{
form::Form, form::Form,
get, get,
@ -15,6 +17,7 @@ use tera::Context;
use crate::model::{ use crate::model::{
boat::Boat, boat::Boat,
log::Log,
logbook::{ logbook::{
LogToAdd, LogToFinalize, Logbook, LogbookCreateError, LogbookDeleteError, LogToAdd, LogToFinalize, Logbook, LogbookCreateError, LogbookDeleteError,
LogbookUpdateError, LogbookUpdateError,
@ -91,7 +94,17 @@ async fn show_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie) -> Template {
} }
#[get("/kiosk/ekrv2019/<loc>")] #[get("/kiosk/ekrv2019/<loc>")]
fn new_kiosk(cookies: &CookieJar<'_>, loc: String) -> Redirect { async fn new_kiosk(
db: &State<SqlitePool>,
cookies: &CookieJar<'_>,
loc: String,
ip: Option<IpAddr>,
) -> Redirect {
Log::create(
db,
format!("New kiosk cookie set for loc '{loc}' (IP={ip:?})"),
)
.await;
let mut cookie = Cookie::new("kiosk", loc); let mut cookie = Cookie::new("kiosk", loc);
cookie.set_expires(OffsetDateTime::now_utc() + Duration::weeks(12)); cookie.set_expires(OffsetDateTime::now_utc() + Duration::weeks(12));
cookies.add_private(cookie); cookies.add_private(cookie);
@ -148,18 +161,18 @@ async fn create_logbook(db: &SqlitePool, data: Form<LogToAdd>, user: &User) -> F
.await .await
{ {
Ok(_) => Flash::success(Redirect::to("/log"), "Ausfahrt erfolgreich hinzugefügt"), Ok(_) => Flash::success(Redirect::to("/log"), "Ausfahrt erfolgreich hinzugefügt"),
Err(LogbookCreateError::BoatAlreadyOnWater) => Flash::error(Redirect::to("/log"), format!("Boot schon am Wasser")), Err(LogbookCreateError::BoatAlreadyOnWater) => Flash::error(Redirect::to("/log"), "Boot schon am Wasser"),
Err(LogbookCreateError::ShipmasterAlreadyOnWater) => Flash::error(Redirect::to("/log"), format!("Schiffsführer schon am Wasser")), Err(LogbookCreateError::ShipmasterAlreadyOnWater) => Flash::error(Redirect::to("/log"), "Schiffsführer schon am Wasser"),
Err(LogbookCreateError::RowerAlreadyOnWater(rower)) => Flash::error(Redirect::to("/log"), format!("Ruderer {} schon am Wasser", rower.name)), Err(LogbookCreateError::RowerAlreadyOnWater(rower)) => Flash::error(Redirect::to("/log"), format!("Ruderer {} schon am Wasser", rower.name)),
Err(LogbookCreateError::BoatLocked) => Flash::error(Redirect::to("/log"), format!("Boot gesperrt")), Err(LogbookCreateError::BoatLocked) => Flash::error(Redirect::to("/log"),"Boot gesperrt"),
Err(LogbookCreateError::BoatNotFound) => Flash::error(Redirect::to("/log"), format!("Boot gibt's ned")), Err(LogbookCreateError::BoatNotFound) => Flash::error(Redirect::to("/log"), "Boot gibt's ned"),
Err(LogbookCreateError::TooManyRowers(expected, actual)) => Flash::error(Redirect::to("/log"), format!("Zu viele Ruderer (Boot fasst maximal {expected}, es wurden jedoch {actual} Ruderer ausgewählt)")), Err(LogbookCreateError::TooManyRowers(expected, actual)) => Flash::error(Redirect::to("/log"), format!("Zu viele Ruderer (Boot fasst maximal {expected}, es wurden jedoch {actual} Ruderer ausgewählt)")),
Err(LogbookCreateError::RowerCreateError(rower, e)) => Flash::error(Redirect::to("/log"), format!("Fehler bei Ruderer {rower}: {e}")), Err(LogbookCreateError::RowerCreateError(rower, e)) => Flash::error(Redirect::to("/log"), format!("Fehler bei Ruderer {rower}: {e}")),
Err(LogbookCreateError::SamePersonShipmasterAndRower) => Flash::error(Redirect::to("/log"), format!("Selbe Person als Schiffsführer und Ruderer ausgewählt")), Err(LogbookCreateError::SamePersonShipmasterAndRower) => Flash::error(Redirect::to("/log"), "Selbe Person als Schiffsführer und Ruderer ausgewählt"),
Err(LogbookCreateError::ArrivalSetButNoDistance) => Flash::error(Redirect::to("/log"), format!("Distanz notwendig, wenn Ankunftszeit angegeben wurde")), Err(LogbookCreateError::ArrivalSetButNoDistance) => Flash::error(Redirect::to("/log"), "Distanz notwendig, wenn Ankunftszeit angegeben wurde"),
Err(LogbookCreateError::ArrivalSetButNoDestination) => Flash::error(Redirect::to("/log"), format!("Ziel notwendig, wenn Ankunftszeit angegeben wurde")), Err(LogbookCreateError::ArrivalSetButNoDestination) => Flash::error(Redirect::to("/log"), "Ziel notwendig, wenn Ankunftszeit angegeben wurde"),
Err(LogbookCreateError::ArrivalNotAfterDeparture) => Flash::error(Redirect::to("/log"), format!("Ankunftszeit kann nicht vor der Abfahrtszeit sein")), Err(LogbookCreateError::ArrivalNotAfterDeparture) => Flash::error(Redirect::to("/log"), "Ankunftszeit kann nicht vor der Abfahrtszeit sein"),
Err(LogbookCreateError::UserNotAllowedToUseBoat) => Flash::error(Redirect::to("/log"), format!("Schiffsführer darf dieses Boot nicht verwenden")), Err(LogbookCreateError::UserNotAllowedToUseBoat) => Flash::error(Redirect::to("/log"), "Schiffsführer darf dieses Boot nicht verwenden"),
} }
} }
@ -196,10 +209,10 @@ async fn home_logbook(
match logbook.home(db, user, data.into_inner()).await { match logbook.home(db, user, data.into_inner()).await {
Ok(_) => Flash::success(Redirect::to("/log"), "Successfully updated log"), Ok(_) => Flash::success(Redirect::to("/log"), "Successfully updated log"),
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(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(a) => {println!("{a:?}"); return Flash::error( Err(_) => Flash::error(
Redirect::to("/log"), Redirect::to("/log"),
format!("Logbook with ID {} could not be updated!", logbook_id), format!("Logbook with ID {} could not be updated!", logbook_id),
)}, ),
} }
} }

View File

@ -26,6 +26,9 @@
<div id="new-damage"> <div id="new-damage">
<form action="/boatdamage" method="post" class="grid gap-3"> <form action="/boatdamage" method="post" class="grid gap-3">
{{ log::boat_select(only_ones=false, id='boat') }} {{ log::boat_select(only_ones=false, id='boat') }}
{% if not loggedin_user %}
{{ macros::select(label='Gemeldet von', data=coxes, name='user_id') }}
{% endif %}
{{ macros::input(label='Beschreibung des Schadens', name='desc', type='text', required=true, wrapper_class='col-span-4') }} {{ macros::input(label='Beschreibung des Schadens', name='desc', type='text', required=true, wrapper_class='col-span-4') }}
<div class="col-span-4"> <div class="col-span-4">
{{ macros::checkbox(label='Boot sperren', name='lock_boat', type='text', required=true) }} {{ macros::checkbox(label='Boot sperren', name='lock_boat', type='text', required=true) }}