diff --git a/web/src/endpoints/clothing/mod.rs b/web/src/endpoints/clothing/mod.rs index f542f0f5..df3152ed 100644 --- a/web/src/endpoints/clothing/mod.rs +++ b/web/src/endpoints/clothing/mod.rs @@ -1,4 +1,5 @@ use askama::Template; +use garde::Validate; use serde::Deserialize; use crate::models::Clothing; @@ -25,7 +26,16 @@ struct ReadClothingPartialTemplate { c: Clothing, } -#[derive(Deserialize)] +#[derive(Deserialize, Validate)] struct NewOrEditClothingForm { + #[garde(length(min=3), custom(alphanumeric_or_space))] name: String, } + +fn alphanumeric_or_space(value: &str, _context: &()) -> garde::Result { + if value.chars().all(|c| c.is_alphanumeric() || c == ' ') { + return Ok(()) + } else { + return Err(garde::Error::new("Eingabe enthält unerlaubte Zeichen. Erlaubt sind Buchstaben, Zahlen und Leerzeichen.")); + } +} diff --git a/web/src/endpoints/clothing/post_edit.rs b/web/src/endpoints/clothing/post_edit.rs index b883e7bf..c0cd4425 100644 --- a/web/src/endpoints/clothing/post_edit.rs +++ b/web/src/endpoints/clothing/post_edit.rs @@ -1,4 +1,5 @@ use actix_web::{web, HttpResponse, Responder}; +use garde::Validate; use sqlx::PgPool; use crate::{ @@ -17,7 +18,7 @@ pub async fn post( path: web::Path, form: web::Form, ) -> Result { - if user.role == Role::Admin { + if user.role != Role::Admin { return Err(ApplicationError::Unauthorized); } @@ -25,6 +26,10 @@ pub async fn post( return Ok(HttpResponse::NotFound().finish()); }; + if let Err(e) = form.validate() { + return Ok(HttpResponse::UnprocessableEntity().body(e.to_string())); + }; + clothing.name = form.name.to_string(); Clothing::update(pool.get_ref(), clothing.id, &clothing.name).await?; diff --git a/web/src/endpoints/clothing/post_new.rs b/web/src/endpoints/clothing/post_new.rs index 3b88a203..2f8910c3 100644 --- a/web/src/endpoints/clothing/post_new.rs +++ b/web/src/endpoints/clothing/post_new.rs @@ -1,4 +1,5 @@ -use actix_web::{web, Responder}; +use actix_web::{web, HttpResponse, Responder}; +use garde::Validate; use sqlx::PgPool; use crate::{ @@ -13,10 +14,14 @@ pub async fn post( pool: web::Data, form: web::Form, ) -> Result { - if user.role == Role::Admin { + if user.role != Role::Admin { return Err(ApplicationError::Unauthorized); } + if let Err(e) = form.validate() { + return Ok(HttpResponse::UnprocessableEntity().body(e.to_string())); + }; + let clothing = Clothing::create(pool.get_ref(), &form.name).await?; let template = ReadClothingPartialTemplate { c: clothing }; diff --git a/web/src/endpoints/mod.rs b/web/src/endpoints/mod.rs index d7b29668..60663254 100644 --- a/web/src/endpoints/mod.rs +++ b/web/src/endpoints/mod.rs @@ -95,10 +95,10 @@ pub fn init(cfg: &mut ServiceConfig) { cfg.service(vehicle_assignment::delete::delete); cfg.service(clothing::get_overview::get); - cfg.service(clothing::get_edit::get); cfg.service(clothing::get_new::get); + cfg.service(clothing::get_edit::get); cfg.service(clothing::get_read::get); cfg.service(clothing::delete::delete); - cfg.service(clothing::post_new::post); cfg.service(clothing::post_edit::post); + cfg.service(clothing::post_new::post); } diff --git a/web/src/models/clothing.rs b/web/src/models/clothing.rs index eea98ddf..dc8563e6 100644 --- a/web/src/models/clothing.rs +++ b/web/src/models/clothing.rs @@ -23,7 +23,7 @@ impl Clothing { } pub async fn read_all(pool: &PgPool) -> Result> { - let records = query!("SELECT * FROM clothing;").fetch_all(pool).await?; + let records = query!("SELECT * FROM clothing ORDER by id;").fetch_all(pool).await?; let clothing_options = records .into_iter() diff --git a/web/static/style.scss b/web/static/style.scss index 30455ed1..c8ea4075 100644 --- a/web/static/style.scss +++ b/web/static/style.scss @@ -18,6 +18,7 @@ $primary: $crimson, @forward "bulma/sass/components/navbar"; @forward "bulma/sass/components/message"; @forward "bulma/sass/components/dropdown"; +@forward "bulma/sass/components/panel"; @forward "bulma/sass/elements/button"; @forward "bulma/sass/elements/box"; diff --git a/web/templates/clothing/clothing_entry_edit.html b/web/templates/clothing/clothing_entry_edit.html index 3f7c64a7..d691ca1b 100644 --- a/web/templates/clothing/clothing_entry_edit.html +++ b/web/templates/clothing/clothing_entry_edit.html @@ -1,26 +1,32 @@ -
  • -
    +{% if id.is_none() %}{% endif %} +
    - +
    + +
    + +
    +

    +
    - {% if let Some(id) = id %} - {% else %} -
    -
  • + {% if id.is_none() %} +{% endif %} diff --git a/web/templates/clothing/clothing_entry_read.html b/web/templates/clothing/clothing_entry_read.html index 6e4b11d0..e4b56670 100644 --- a/web/templates/clothing/clothing_entry_read.html +++ b/web/templates/clothing/clothing_entry_read.html @@ -1,23 +1,21 @@ -
  • -
    -
    -
    - {{ c.name }} -
    +
    +
    +
    + {{ c.name }} +
    -
    - - -
    +
    + +
    -
  • + diff --git a/web/templates/clothing/overview.html b/web/templates/clothing/overview.html index 96a8f81d..7e708198 100644 --- a/web/templates/clothing/overview.html +++ b/web/templates/clothing/overview.html @@ -6,17 +6,22 @@

    Anzugsordnungen

    -

    zur Auswahl bei der Erstellung von Events

    +

    zur Auswahl bei der Erstellung von Events

    -
    - + + {% endfor %} +
    + +