diff options
-rw-r--r-- | src/controllers/screening.rs | 49 | ||||
-rw-r--r-- | src/db.rs | 20 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/models/screening.rs | 3 | ||||
-rw-r--r-- | templates/screening/edit.tera | 39 | ||||
-rw-r--r-- | templates/screening/list.tera | 1 |
6 files changed, 112 insertions, 2 deletions
diff --git a/src/controllers/screening.rs b/src/controllers/screening.rs index 40eefd3..cf7d1b1 100644 --- a/src/controllers/screening.rs +++ b/src/controllers/screening.rs @@ -22,7 +22,7 @@ use crate::{ }; use std::result::Result; -use rocket::{delete, get, post}; +use rocket::{delete, get, patch, post}; use rocket::request::{Form, FromForm}; use rocket::response::Redirect; use rocket_contrib::{ @@ -96,6 +96,53 @@ pub fn create_screening(db: db::Connection, screening: Form<NewScreeningForm>) - Ok(Redirect::to("/screenings")) } +#[get("/<id>")] +pub fn edit(db: db::Connection, id: i32) -> Result<Template, Box<dyn Error>> { + #[derive(Serialize)] + struct Context { + screening: models::Screening, + rooms: Vec<models::Room>, + films: Vec<models::Film>, + } + + let ctx = Context { + screening: db.get_screening(id)?, + rooms: db.get_rooms()?, + films: db.get_films()?, + }; + + Ok(Template::render("screening/edit", &ctx)) +} + +#[derive(FromForm)] +pub struct EditScreeningForm { + id: i32, + film_id: i32, + room_id: i32, + date: String, + start_time: String, + end_time: String, +} + +#[patch("/", format = "application/x-www-form-urlencoded", data = "<screening>")] +pub fn update(db: db::Connection, screening: Form<EditScreeningForm>) -> Result<Redirect, Box<dyn Error>> { + let start_time = parse_datetime(&screening.date, &screening.start_time)?; + let mut end_time = parse_datetime(&screening.date, &screening.end_time)?; + + if end_time < start_time { + end_time = end_time + chrono::Duration::days(1); + } + + db.update_screening( + screening.id, + screening.room_id, + screening.film_id, + start_time, + end_time)?; + + Ok(Redirect::to("/screenings")) +} + #[derive(FromForm)] pub struct DeleteScreeningForm { screening_id: i32, @@ -55,11 +55,31 @@ impl Connection { self.create_screening(room.id, film.id, start_time, end_time) } + pub fn update_screening( + &self, + screening_id: i32, + room_id: i32, + film_id: i32, + start_time: chrono::DateTime<chrono::Utc>, + end_time: chrono::DateTime<chrono::Utc>) -> QueryResult<usize> + { + let s = models::Screening { id: screening_id, film_id, room_id, start_time, end_time }; + diesel::update(screenings::table) + .filter(screenings::id.eq(screening_id)) + .set(&s) + .execute(&**self) + } + pub fn get_screenings(&self) -> QueryResult<Vec<models::Screening>> { use crate::schema::screenings::dsl::*; screenings.load(&**self) } + pub fn get_screening(&self, screening_id: i32) -> QueryResult<models::Screening> { + use crate::schema::screenings::dsl::*; + screenings.filter(id.eq(screening_id)).get_result(&**self) + } + pub fn get_aggregated_screenings(&self) -> QueryResult<Vec<models::AggregatedScreening>> { use crate::schema::screenings::dsl::*; let s = screenings @@ -51,6 +51,8 @@ pub fn build_rocket(db_url: &str) -> Result<rocket::Rocket, Box<dyn Error>> { screening::list_screenings, screening::new_screening, screening::create_screening, + screening::edit, + screening::update, screening::delete, ])) } diff --git a/src/models/screening.rs b/src/models/screening.rs index 1426605..8ab96e0 100644 --- a/src/models/screening.rs +++ b/src/models/screening.rs @@ -18,6 +18,7 @@ use crate::models::{Film, Room}; use crate::schema::*; +use diesel::query_builder::AsChangeset; use serde::{Deserialize, Serialize}; joinable!(screenings -> rooms (room_id)); @@ -32,7 +33,7 @@ pub struct NewScreening { pub end_time: chrono::DateTime<chrono::Utc>, } -#[derive(Deserialize, Identifiable, PartialEq, Serialize, Queryable)] +#[derive(AsChangeset, Deserialize, Identifiable, PartialEq, Serialize, Queryable)] #[table_name = "screenings"] pub struct Screening { pub id: i32, diff --git a/templates/screening/edit.tera b/templates/screening/edit.tera new file mode 100644 index 0000000..39268fe --- /dev/null +++ b/templates/screening/edit.tera @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> +<head> +<title>Edit screening</title> +</head> +<body> +<h1>Edit screening</h1> + +<form name="edit_screening_form" action="/screenings" method="POST"> + <input name="_method" value="PATCH" type="hidden"> + <input name="id" value="{{ screening.id }}" type="hidden"> + + <label for="film_id">Film: </label> + <select name="film_id"> + {% for film in films %} + <option value="{{ film.id }}"{% if film.id == screening.film_id %} selected{% endif %}>{{ film.title }}</option> + {% endfor %} + </select> + + <label for="room_id">Room: </label> + <select name="room_id"> + {% for room in rooms %} + <option value="{{ room.id }}"{% if room.id == screening.room_id %} selected{% endif %}>{{ room.name }}</option> + {% endfor %} + + <label for="date">Date: </label> + <input name="date" type="date" value="{{ screening.start_time | date }}"> + + <label for="start_time">Start time: </label> + <input name="start_time" type="time" value="{{ screening.start_time | date(format="%H:%M") }}"> + + <label for="end_time">End time: </label> + <input name="end_time" type="time" value="{{ screening.end_time | date(format="%H:%M") }}"> + + </select> + <input type="submit" value="Save"> +</form> +</body> +</html> diff --git a/templates/screening/list.tera b/templates/screening/list.tera index 21ef7e2..7112796 100644 --- a/templates/screening/list.tera +++ b/templates/screening/list.tera @@ -25,6 +25,7 @@ No screenings defined. <td>{{ s.film.title }}</td> <td>({{ s.room.name }})</td> <td> + <a href="/screenings/{{ s.id }}">Edit</a> <form class="delete-item" id="delete-screening-{{ s.id }}" action="/screenings" method="POST"> <input name="_method" value="DELETE" type="hidden"> <input name="screening_id" value="{{ s.id }}" type="hidden"> |