diff options
-rw-r--r-- | src/controllers/screening.rs | 60 | ||||
-rw-r--r-- | src/db.rs | 24 | ||||
-rw-r--r-- | src/lib.rs | 7 | ||||
-rw-r--r-- | templates/screening/list.tera | 22 | ||||
-rw-r--r-- | templates/screening/new.tera | 36 |
5 files changed, 134 insertions, 15 deletions
diff --git a/src/controllers/screening.rs b/src/controllers/screening.rs index 5052075..b76ae65 100644 --- a/src/controllers/screening.rs +++ b/src/controllers/screening.rs @@ -18,15 +18,67 @@ use crate::{ db, - models::AggregatedScreening, + models, }; -use rocket::get; +use std::result::Result; +use rocket::{get, post}; +use rocket::request::{Form, FromForm}; +use rocket::response::Redirect; use rocket_contrib::{ json::Json, + templates::Template, }; +use serde::Serialize; +use std::error::Error; -#[get("/")] -pub fn get_aggregated_screenings(db: db::Connection) -> Json<Vec<AggregatedScreening>> { +#[get("/", format = "application/json")] +pub fn get_aggregated_screenings(db: db::Connection) -> Json<Vec<models::AggregatedScreening>> { Json(db.get_aggregated_screenings().unwrap()) } + +#[get("/", rank = 2)] +pub fn list_screenings(db: db::Connection) -> Result<Template, Box<dyn Error>> { + #[derive(Serialize)] + struct Context { + screenings: Vec<models::AggregatedScreening>, + } + + let ctx = Context { screenings: db.get_aggregated_screenings()? }; + Ok(Template::render("screening/list", &ctx)) +} + +#[get("/new")] +pub fn new_screening(db: db::Connection) -> Result<Template, Box<dyn Error>> { + #[derive(Serialize)] + struct Context { + rooms: Vec<models::Room>, + films: Vec<models::Film>, + } + + let ctx = Context { + rooms: db.get_rooms()?, + films: db.get_films()?, + }; + + Ok(Template::render("screening/new", &ctx)) +} + +#[derive(FromForm)] +pub struct NewScreeningForm { + film_id: i32, + room_id: i32, + date: String, + start_time: String, + end_time: String, +} + +#[post("/", format = "application/x-www-form-urlencoded", data = "<screening>")] +pub fn create_screening(db: db::Connection, screening: Form<NewScreeningForm>) -> Result<Redirect, Box<dyn Error>> { + let date = chrono::NaiveDate::parse_from_str(dbg!(&screening.date), "%Y-%m-%d")?; + let start_time = chrono::NaiveTime::parse_from_str(dbg!(&screening.start_time), "%H:%M")?; + let end_time = chrono::NaiveTime::parse_from_str(dbg!(&screening.end_time), "%H:%M")?; + + db.create_screening(dbg!(screening.room_id), dbg!(screening.film_id), date, start_time, end_time)?; + Ok(Redirect::to("/screenings")) +} @@ -34,25 +34,29 @@ pub struct Connection(diesel::PgConnection); impl Connection { pub fn create_screening( &self, - room: &models::Room, - film: &models::Film, + room_id: i32, + film_id: i32, date: chrono::NaiveDate, start_time: chrono::NaiveTime, end_time: chrono::NaiveTime) -> QueryResult<usize> { - let s = models::NewScreening { - room_id: room.id, - film_id: film.id, - date: date, - start_time: start_time, - end_time: end_time, - }; - + let s = models::NewScreening { room_id, film_id, date, start_time, end_time }; diesel::insert_into(screenings::table) .values(&s) .execute(&**self) } + pub fn create_screening_from_aggregate( + &self, + room: &models::Room, + film: &models::Film, + date: chrono::NaiveDate, + start_time: chrono::NaiveTime, + end_time: chrono::NaiveTime) -> QueryResult<usize> + { + self.create_screening(room.id, film.id, date, start_time, end_time) + } + pub fn get_screenings(&self) -> QueryResult<Vec<models::Screening>> { use crate::schema::screenings::dsl::*; screenings.load(&**self) @@ -46,5 +46,10 @@ pub fn build_rocket(db_url: &str) -> Result<rocket::Rocket, Box<dyn Error>> { .mount("/", rocket_contrib::serve::StaticFiles::from("./public")) .mount("/rooms", routes![room::get_rooms_json, room::list_rooms, room::new_room, room::create_room]) .mount("/films", routes![film::get_films_json, film::list_films, film::new_film, film::create_film]) - .mount("/screenings", routes![screening::get_aggregated_screenings])) + .mount("/screenings", routes![ + screening::get_aggregated_screenings, + screening::list_screenings, + screening::new_screening, + screening::create_screening, + ])) } diff --git a/templates/screening/list.tera b/templates/screening/list.tera new file mode 100644 index 0000000..7c92303 --- /dev/null +++ b/templates/screening/list.tera @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<title>Screenings</title> +</head> +<body> +<h1>Screenings</h1> + +<p> +<a href="/screenings/new">Add screening</a></p> + +{% if screenings | length <= 0%} +No screenings defined. +{% else %} +<ul> +{% for s in screenings -%} +<li>{{ s.date }} {{ s.start_time }} - {{ s.end_time }}: {{ s.film.title }} ({{ s.room.name }})</li> +{% endfor -%} +</ul> +{% endif %} +</body> +</html> diff --git a/templates/screening/new.tera b/templates/screening/new.tera new file mode 100644 index 0000000..0c3eb73 --- /dev/null +++ b/templates/screening/new.tera @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<head> +<title>New screening</title> +</head> +<body> +<h1>New screening</h1> + +<form name="new_screening_form" action="/screenings" method="POST"> + <label for="film_id">Film: </label> + <select name="film_id"> + {% for film in films %} + <option value="{{ film.id }}">{{ film.title }}</option> + {% endfor %} + </select> + + <label for="room_id">Room: </label> + <select name="room_id"> + {% for room in rooms %} + <option value="{{ room.id }}">{{ room.name }}</option> + {% endfor %} + + <label for="date">Date: </label> + <input name="date" type="date"> + + <label for="start_time">Start time: </label> + <input name="start_time" type="time"> + + <label for="end_time">End time: </label> + <input name="end_time" type="time"> + + </select> + <input type="submit" value="Save"> +</form> +</body> +</html> |