diff --git a/src/endpoints/area/delete.rs b/src/endpoints/area/delete.rs new file mode 100644 index 00000000..e9a8711f --- /dev/null +++ b/src/endpoints/area/delete.rs @@ -0,0 +1,27 @@ +use actix_web::{web, HttpResponse, Responder}; +use sqlx::PgPool; + +use crate::{ + endpoints::IdPath, + models::{Area, Role, User}, + utils::ApplicationError, +}; + +#[actix_web::delete("/area/delete/{id}")] +pub async fn delete( + user: web::ReqData, + pool: web::Data, + path: web::Path, +) -> Result { + if user.role != Role::Admin { + return Err(ApplicationError::Unauthorized); + } + + if Area::read_by_id(pool.get_ref(), path.id).await?.is_none() { + return Ok(HttpResponse::NotFound().finish()); + }; + + Area::delete(pool.get_ref(), path.id).await?; + + return Ok(HttpResponse::Ok().finish()); +} diff --git a/src/endpoints/area/mod.rs b/src/endpoints/area/mod.rs index ec124c5a..5a54fb0b 100644 --- a/src/endpoints/area/mod.rs +++ b/src/endpoints/area/mod.rs @@ -1,8 +1,11 @@ pub mod get_new; pub mod post_new; pub mod get_edit; +pub mod post_edit; +pub mod delete; use askama::Template; +use serde::Deserialize; use crate::models::{Area, Role, User}; @@ -12,3 +15,8 @@ struct NewOrEditAreaTemplate { user: User, area: Option, } + +#[derive(Deserialize)] +struct AreaForm { + name: String, +} diff --git a/src/endpoints/area/post_edit.rs b/src/endpoints/area/post_edit.rs new file mode 100644 index 00000000..33271f34 --- /dev/null +++ b/src/endpoints/area/post_edit.rs @@ -0,0 +1,35 @@ +use actix_web::{http::header::LOCATION, web, HttpResponse, Responder}; +use sqlx::PgPool; + +use crate::{ + endpoints::IdPath, + models::{Area, Role, User}, + utils::ApplicationError, +}; + +use super::AreaForm; + +#[actix_web::post("/area/edit/{id}")] +pub async fn post( + user: web::ReqData, + pool: web::Data, + form: web::Form, + path: web::Path, +) -> Result { + if user.role != Role::Admin { + return Err(ApplicationError::Unauthorized); + } + + if let Some(area) = Area::read_by_id(pool.get_ref(), path.id).await? { + if area.name != form.name { + Area::update(pool.get_ref(), path.id, &form.name).await?; + } + + return Ok(HttpResponse::Found() + .insert_header((LOCATION, "/locations")) + .insert_header(("HX-LOCATION", "/locations")) + .finish()); + } else { + return Ok(HttpResponse::NotFound().finish()); + } +} diff --git a/src/endpoints/area/post_new.rs b/src/endpoints/area/post_new.rs index e78ba562..0c4aa707 100644 --- a/src/endpoints/area/post_new.rs +++ b/src/endpoints/area/post_new.rs @@ -1,19 +1,13 @@ use actix_web::{http::header::LOCATION, web, HttpResponse, Responder}; -use serde::Deserialize; use sqlx::PgPool; -use crate::models::{Area, Role, User}; - -#[derive(Deserialize)] -struct NewAreaForm { - name: String, -} +use crate::{endpoints::area::AreaForm, models::{Area, Role, User}}; #[actix_web::post("/area/new")] pub async fn post( user: web::ReqData, pool: web::Data, - form: web::Form, + form: web::Form, ) -> impl Responder { if user.role != Role::Admin { return HttpResponse::Unauthorized().finish(); diff --git a/src/endpoints/mod.rs b/src/endpoints/mod.rs index 8a371028..21f8be70 100644 --- a/src/endpoints/mod.rs +++ b/src/endpoints/mod.rs @@ -60,6 +60,8 @@ pub fn init(cfg: &mut ServiceConfig) { cfg.service(area::get_new::get); cfg.service(area::post_new::post); cfg.service(area::get_edit::get); + cfg.service(area::post_edit::post); + cfg.service(area::delete::delete); cfg.service(export::get_availability::get); cfg.service(export::get_availability_data::get); diff --git a/src/models/area.rs b/src/models/area.rs index 8781ecc0..36dab28f 100644 --- a/src/models/area.rs +++ b/src/models/area.rs @@ -25,10 +25,26 @@ impl Area { } pub async fn read_all(pool: &PgPool) -> Result> { - let records = query_as!(Area, "SELECT * FROM area") + let records = query_as!(Area, "SELECT * FROM area ORDER by id") .fetch_all(pool) .await?; Ok(records) } + + pub async fn update(pool: &PgPool, id: i32, name: &str) -> Result<()> { + query!("UPDATE area SET name = $1 WHERE id = $2;", name, id) + .execute(pool) + .await?; + + Ok(()) + } + + pub async fn delete(pool: &PgPool, id: i32) -> Result<()> { + sqlx::query!("DELETE FROM area WHERE id = $1;", id) + .execute(pool) + .await?; + + Ok(()) + } } diff --git a/templates/location/overview.html b/templates/location/overview.html index 0c42e59f..4591a5de 100644 --- a/templates/location/overview.html +++ b/templates/location/overview.html @@ -46,11 +46,12 @@ - +