diff --git a/Cargo.lock b/Cargo.lock index 85b2cd3..73f0de7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1001,6 +1001,7 @@ dependencies = [ "rocket_contrib", "serde", "serde_derive", + "serde_json", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 521e1ad..c5e5384 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" rocket = "0.4.5" diesel = { version = "1.4", features = ["sqlite"] } serde_derive = "1.0" +serde_json = "1.0" serde = "1.0" [dependencies.rocket_contrib] diff --git a/database.sqlite b/database.sqlite index 8cd686c..1043498 100644 Binary files a/database.sqlite and b/database.sqlite differ diff --git a/migrations/2020-07-23-093057_add_vertretung/up.sql b/migrations/2020-07-23-093057_add_vertretung/up.sql index df6adef..b71f0b8 100644 --- a/migrations/2020-07-23-093057_add_vertretung/up.sql +++ b/migrations/2020-07-23-093057_add_vertretung/up.sql @@ -1,6 +1,6 @@ -- Your SQL -CREATE TABLE Vertretungen +CREATE TABLE vertretungen ( id Integer PRIMARY KEY NOT NULL, klassen_id Integer NOT NULL, diff --git a/migrations/2020-07-25-085330_rename_id_columns/down.sql b/migrations/2020-07-25-085330_rename_id_columns/down.sql new file mode 100644 index 0000000..d0fc2f5 --- /dev/null +++ b/migrations/2020-07-25-085330_rename_id_columns/down.sql @@ -0,0 +1,6 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE klassen RENAME COLUMN klassen_id TO id; +ALTER TABLE vertretungen RENAME COLUMN vertretungen_id TO id; +ALTER TABLE vertretungen RENAME COLUMN klassen_id TO klasse_id; +ALTER TABLE vertretungen RENAME COLUMN stunden_id TO stunde_id; +ALTER TABLE stunden RENAME COLUMN stunden_id TO id; \ No newline at end of file diff --git a/migrations/2020-07-25-085330_rename_id_columns/up.sql b/migrations/2020-07-25-085330_rename_id_columns/up.sql new file mode 100644 index 0000000..10e1e30 --- /dev/null +++ b/migrations/2020-07-25-085330_rename_id_columns/up.sql @@ -0,0 +1,6 @@ +-- Your SQL goes here +ALTER TABLE klassen RENAME COLUMN id TO klassen_id; +ALTER TABLE vertretungen RENAME COLUMN id TO vertretungen_id; +ALTER TABLE vertretungen RENAME COLUMN klasse_id TO klassen_id; +ALTER TABLE vertretungen RENAME COLUMN stunde_id TO stunden_id; +ALTER TABLE stunden RENAME COLUMN id TO stunden_id; diff --git a/migrations/2020-07-25-155433_rename_colum_to_singular/down.sql b/migrations/2020-07-25-155433_rename_colum_to_singular/down.sql new file mode 100644 index 0000000..e1862d5 --- /dev/null +++ b/migrations/2020-07-25-155433_rename_colum_to_singular/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE vertretungen RENAME COLUMN klasse_id TO klassen_id; +ALTER TABLE vertretungen RENAME COLUMN stunde_id TO stunden_id; \ No newline at end of file diff --git a/migrations/2020-07-25-155433_rename_colum_to_singular/up.sql b/migrations/2020-07-25-155433_rename_colum_to_singular/up.sql new file mode 100644 index 0000000..6bdabd8 --- /dev/null +++ b/migrations/2020-07-25-155433_rename_colum_to_singular/up.sql @@ -0,0 +1,3 @@ +-- Your SQL goes here +ALTER TABLE vertretungen RENAME COLUMN klassen_id TO klasse_id; +ALTER TABLE vertretungen RENAME COLUMN stunden_id TO stunde_id; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index cf083af..452946a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,11 +8,20 @@ extern crate rocket_contrib; extern crate diesel; #[macro_use] extern crate serde_derive; +extern crate serde_json; + +use std::collections::HashMap; pub mod models; pub mod schema; -use crate::models::Klassen; +use crate::diesel::GroupedBy; +use crate::models::{Klasse, Stunde, Vertretung}; use crate::schema::klassen; +use crate::schema::stunden; +use crate::schema::vertretungen; +use diesel::prelude::*; +use diesel::BelongingToDsl; +use diesel::QueryDsl; use diesel::RunQueryDsl; use rocket::request::{Form, FromParam}; use rocket::response::Redirect; @@ -42,21 +51,84 @@ struct DbConn(databases::diesel::SqliteConnection); #[derive(Debug, Serialize)] struct ListAllContext { - klassen: Vec, + klassen: Vec<(Klasse, Vec)>, parent: String, } +enum QueryClasses { + All, + KlassenId(i32), +} + +fn query_all_classes(conn: DbConn) -> Vec<(Klasse, Vec)> { + let all_classes = klassen::table + .load::(&*conn) + .expect("database acess classes"); + let and_substitutions = Vertretung::belonging_to(&all_classes) + .load::(&*conn) + .expect("database acess Vertretungen") + .grouped_by(&all_classes); + let combined_classes = all_classes + .into_iter() + .zip(and_substitutions) + .filter(|x| x.1.len() > 0) + .collect::>(); + combined_classes +} + +fn query_one_class<'a>( + conn: DbConn, + id: i32, +) -> (Klasse, HashMap)>) { + let mut ret: HashMap)> = HashMap::new(); + let class = klassen::dsl::klassen + .filter(klassen::dsl::klassen_id.eq(id)) + .first::(&*conn) + .expect("database acess classes"); + //let stund: Vec = stunden::table.load(&*conn).expect("Loading Stunden"); + let times: Vec<(Vertretung, Stunde)> = Vertretung::belonging_to(&class) + .inner_join(stunden::table.on(vertretungen::stunde_id.eq(stunden::stunden_id))) + .load(&*conn) + .expect("database access Stunden"); + for (vert, stun) in times { + let stun_ord = stun.ordinal.to_string(); + let verts = ret.entry(stun_ord).or_insert((stun, Vec::new())); + verts.1.push(vert); + } + (class, ret) +} + #[get("/")] fn index(conn: DbConn) -> Template { + let combined_classes = query_all_classes(conn); Template::render( "uebersicht", ListAllContext { - klassen: klassen::dsl::klassen.load(&*conn).expect("database acess"), + klassen: combined_classes, parent: "base".to_string(), }, ) } +#[derive(Debug, Serialize)] +struct ListOneContext { + klasse: Klasse, + vertretungen: HashMap)>, + parent: String, +} + +#[get("/klasse/")] +fn klasse_view(conn: DbConn, class_id: i32) -> Template { + let class = query_one_class(conn, class_id); + let (klasse, vertretungen) = class; + let cont = ListOneContext { + klasse: klasse, + vertretungen: vertretungen, + parent: "base".to_string(), + }; + Template::render("klasse", cont) +} + #[get("/add/klasse")] fn get_klasse_form() -> Template { Template::render("add_klasse_form", "") @@ -91,6 +163,7 @@ fn main() { StaticFiles::from(concat!(env!("CARGO_MANIFEST_DIR"), "/static")), ) .mount("/", routes![index]) + .mount("/", routes![klasse_view]) .mount("/admin/", routes![get_klasse_form]) .mount("/admin/", routes![post_klasse_form]) .launch(); diff --git a/src/models.rs b/src/models.rs index add47fd..17dca6a 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,39 +1,43 @@ use super::schema::{klassen, vertretungen}; +use std::cmp::Eq; -#[derive(Queryable, Debug, Serialize)] -pub struct Stunden { - pub id: i32, +#[derive(Queryable, Debug, Serialize, Hash, PartialEq, Clone)] +pub struct Stunde { + pub stunden_id: i32, pub title: String, pub short: String, pub ordinal: i32, } +impl Eq for Stunde {} + #[derive(Identifiable, Queryable, Debug, Serialize, Associations)] -#[belongs_to(Klassen)] -#[belongs_to(Stunden)] +#[belongs_to(Klasse)] +#[belongs_to(Stunde)] #[table_name = "vertretungen"] -pub struct Vertretungen { +pub struct Vertretung { pub id: i32, - pub klassen_id: i32, - pub stunden_id: i32, + pub klasse_id: i32, + pub stunde_id: i32, pub fehlend: String, pub vertretung: String, pub kommentar: String, } -#[derive(Identifiable, Queryable, Debug, Serialize)] +#[derive(Identifiable, Queryable, Debug, Serialize, Associations)] #[table_name = "klassen"] -pub struct Klassen { - pub id: i32, +#[primary_key(klassen_id)] +pub struct Klasse { + pub klassen_id: i32, pub stufe: i32, pub gruppe: String, pub titel: Option, pub ordnung: i32, } -#[derive(Insertable)] +#[derive(Serialize, Insertable)] #[table_name = "klassen"] -pub struct NewKlassen { +pub struct NewKlasse { pub stufe: i32, pub gruppe: String, pub titel: Option, diff --git a/src/schema.rs b/src/schema.rs index 5972880..5037069 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -1,8 +1,8 @@ table! { - vertretungen (id) { - id -> Integer, - klassen_id -> Integer, - stunden_id -> Integer, + vertretungen (vertretungen_id) { + vertretungen_id -> Integer, + klasse_id -> Integer, + stunde_id -> Integer, fehlend -> Text, vertretung -> Text, kommentar -> Text, @@ -10,8 +10,8 @@ table! { } table! { - klassen (id) { - id -> Integer, + klassen (klassen_id) { + klassen_id -> Integer, stufe -> Integer, gruppe -> Text, titel -> Nullable, @@ -20,8 +20,8 @@ table! { } table! { - stunden (id) { - id -> Integer, + stunden (stunden_id) { + stunden_id -> Integer, title -> Text, short -> Text, ordinal -> Integer, diff --git a/static/style.css b/static/style.css index bf508da..43d346c 100644 --- a/static/style.css +++ b/static/style.css @@ -19,27 +19,53 @@ a:hover { a:visited { color: #fcb6b6; } + +div.erkl { + margin-top: 10px; + font-size: 0.7em; + color: #74787c; +} + +div.vert { + width:100%; + text-align: center; + margin-top: 5px; +} + +table.vertretungsplan { + padding: 15px; + border-spacing: 10px; +} + +table.vertretungsplan td, table.vertretungsplan th { + padding: 15px; + width: 130px; + height: 100px; + border: 1px solid rgb(255, 255, 255); +} + + + .grid-container { display: grid; grid-template-columns: auto auto auto auto; grid-gap: 30px; padding: 10px; - background-color: #23272a; + background-color: #005a9e; align-items: stretch; } -.grid-item div { +.grid-item { display: table-cell; border: 1px solid #ccc; - font-size: 48px; box-shadow: 2px 2px 6px 0px rgba(0, 0, 0, 0.2); max-width: 100%; width: 215px; height: 200px; margin: auto; text-align: center; - line-height: 200px; - background-color: #2c2f33; + /*line-height: 200px;*/ + background-color: #0050b8; } .grid { diff --git a/templates/klasse.hbs b/templates/klasse.hbs new file mode 100644 index 0000000..f9bbf3c --- /dev/null +++ b/templates/klasse.hbs @@ -0,0 +1,27 @@ +{{#* inline "page"}} +

Klasse {{klasse.stufe}}{{klasse.gruppe}}

+ + {{#each vertretungen}} + + + {{#each this.1}} + + {{/each}} + + {{/each}} +
+ Stunde: {{this.0.title}} + +
+
Vertretung für:
+
{{this.fehlend}}
+
+
+
Vertretung durch:
+
{{this.vertretung}}
+
+
+{{/inline}} + +{{! remove whitespaces with ~ }} +{{~> (parent)~}} \ No newline at end of file diff --git a/templates/uebersicht.hbs b/templates/uebersicht.hbs index 63fd880..5a48bba 100644 --- a/templates/uebersicht.hbs +++ b/templates/uebersicht.hbs @@ -1,10 +1,12 @@ {{#* inline "page"}} -

Vertretungen

-
    - {{#each klassen}} -
  • {{this.id}}. {{this.stufe}}{{this.gruppe}}
  • - {{/each}} -
- {{/inline}} - {{! remove whitespaces with ~ }} - {{~> (parent)~}} +

Vertretungen

+
+ {{#each klassen}} +
+

{{this.0.klassen_id}}. {{this.0.stufe}}{{this.0.gruppe}}
{{this.1}}

+
+ {{/each}} +
+{{/inline}} +{{! remove whitespaces with ~ }} +{{~> (parent)~}} \ No newline at end of file