use rocket::{ form::Form, get, post, response::{Flash, Redirect}, routes, FromForm, Route, State, }; use sqlx::SqlitePool; use crate::model::{ log::Log, planned_event::PlannedEvent, trip::{CoxHelpError, Trip, TripDeleteError, TripUpdateError}, tripdetails::TripDetails, user::CoxUser, }; #[derive(FromForm)] struct AddTripForm<'r> { day: String, //TODO: properly parse `planned_starting_time` planned_starting_time: &'r str, #[field(validate = range(1..))] max_people: i32, notes: Option<&'r str>, trip_type: Option, allow_guests: bool, } #[post("/trip", data = "")] async fn create( db: &State, data: Form>, cox: CoxUser, ) -> Flash { let trip_details_id = TripDetails::create( db, data.planned_starting_time, data.max_people, &data.day, data.notes, data.allow_guests, data.trip_type, ) .await; let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); //Okay, bc just //created Trip::new_own(db, &cox, trip_details).await; Log::create( db, format!( "Cox {} created trip on {} @ {} for {} rower", cox.name, data.day, data.planned_starting_time, data.max_people, ), ) .await; Flash::success(Redirect::to("/"), "Ausfahrt erfolgreich erstellt.") } #[derive(FromForm)] struct EditTripForm<'r> { max_people: i32, notes: Option<&'r str>, trip_type: Option, } #[post("/trip/", data = "")] async fn update( db: &State, data: Form>, trip_id: i64, cox: CoxUser, ) -> Flash { if let Some(trip) = Trip::find_by_id(db, trip_id).await { match Trip::update_own(db, &cox, &trip, data.max_people, data.notes, data.trip_type).await { Ok(_) => Flash::success(Redirect::to("/"), "Ausfahrt erfolgreich aktualisiert."), Err(TripUpdateError::NotYourTrip) => { Flash::error(Redirect::to("/"), "Nicht deine Ausfahrt!") } Err(TripUpdateError::TripDetailsDoesNotExist) => { Flash::error(Redirect::to("/"), "Ausfahrt gibt's nicht") } } } else { Flash::error(Redirect::to("/"), "Ausfahrt gibt's nicht") } } #[get("/join/")] async fn join(db: &State, planned_event_id: i64, cox: CoxUser) -> Flash { if let Some(planned_event) = PlannedEvent::find_by_id(db, planned_event_id).await { match Trip::new_join(db, &cox, &planned_event).await { Ok(_) => { Log::create( db, format!( "Cox {} helps at planned_event.id={}", cox.name, planned_event_id, ), ) .await; Flash::success(Redirect::to("/"), "Danke für's helfen!") } Err(CoxHelpError::AlreadyRegisteredAsCox) => { Flash::error(Redirect::to("/"), "Du hilfst bereits aus!") } Err(CoxHelpError::AlreadyRegisteredAsRower) => Flash::error( Redirect::to("/"), "Du hast dich bereits als Ruderer angemeldet!", ), } } else { Flash::error(Redirect::to("/"), "Event gibt's nicht") } } #[get("/remove/trip/")] async fn remove_trip(db: &State, trip_id: i64, cox: CoxUser) -> Flash { let trip = Trip::find_by_id(db, trip_id).await; match trip { None => Flash::error(Redirect::to("/"), "Trip gibt's nicht!"), Some(trip) => match trip.delete(db, &cox).await { Ok(_) => { Log::create(db, format!("Cox {} deleted trip.id={}", cox.name, trip_id)).await; Flash::success(Redirect::to("/"), "Erfolgreich gelöscht!") } Err(TripDeleteError::SomebodyAlreadyRegistered) => Flash::error( Redirect::to("/"), "Ausfahrt kann nicht gelöscht werden, da bereits jemand registriert ist!", ), Err(TripDeleteError::NotYourTrip) => { Flash::error(Redirect::to("/"), "Nicht deine Ausfahrt!") } }, } } #[get("/remove/")] async fn remove(db: &State, planned_event_id: i64, cox: CoxUser) -> Flash { if let Some(planned_event) = PlannedEvent::find_by_id(db, planned_event_id).await { Trip::delete_by_planned_event(db, &cox, &planned_event).await; Log::create( db, format!( "Cox {} deleted registration for planned_event.id={}", cox.name, planned_event_id ), ) .await; Flash::success(Redirect::to("/"), "Erfolgreich abgemeldet!") } else { Flash::error(Redirect::to("/"), "Planned_event does not exist.") } } pub fn routes() -> Vec { routes![create, join, remove, remove_trip, update] }