aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2020-08-23 14:40:03 +0200
committerHarald Eilertsen <haraldei@anduin.net>2020-08-23 14:40:03 +0200
commit129e8d34906584b5e6c3eeeb18958fc5e2c39c33 (patch)
tree1508b341155d08c5acc068bd3dc829c0f7049cf2
parent39a0268aa235ddf94bdee074cf664221711a1bb7 (diff)
downloadramaskrik-social-129e8d34906584b5e6c3eeeb18958fc5e2c39c33.tar.gz
ramaskrik-social-129e8d34906584b5e6c3eeeb18958fc5e2c39c33.tar.bz2
ramaskrik-social-129e8d34906584b5e6c3eeeb18958fc5e2c39c33.zip
Implement adding screenings in the web ui.
-rw-r--r--src/controllers/screening.rs60
-rw-r--r--src/db.rs24
-rw-r--r--src/lib.rs7
-rw-r--r--templates/screening/list.tera22
-rw-r--r--templates/screening/new.tera36
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"))
+}
diff --git a/src/db.rs b/src/db.rs
index 60ff4fc..cf1c0fb 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -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)
diff --git a/src/lib.rs b/src/lib.rs
index 76e4df8..4972205 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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>