aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/controllers/screening.rs49
-rw-r--r--src/db.rs20
-rw-r--r--src/lib.rs2
-rw-r--r--src/models/screening.rs3
-rw-r--r--templates/screening/edit.tera39
-rw-r--r--templates/screening/list.tera1
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,
diff --git a/src/db.rs b/src/db.rs
index 4c562ef..6bce5e8 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -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
diff --git a/src/lib.rs b/src/lib.rs
index 0f9d7b4..57d8b7a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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">