diff --git a/src/endpoints/location/delete.rs b/src/endpoints/location/delete.rs new file mode 100644 index 00000000..ecadbbd5 --- /dev/null +++ b/src/endpoints/location/delete.rs @@ -0,0 +1,18 @@ +use actix_web::{http::header::LOCATION, web, HttpResponse, Responder}; +use sqlx::PgPool; + +use crate::{endpoints::IdPath, models::User, utils::ApplicationError}; + + +#[actix_web::delete("/locations/delete/{id}")] +pub async fn delete ( + user: web::ReqData, + pool: web::Data, + path: web::Path +) -> Result { + + Ok(HttpResponse::Found() + .insert_header((LOCATION, "/locations")) + .insert_header(("HX-LOCATION", "/locations")) + .finish()) +} diff --git a/src/endpoints/location/get_edit.rs b/src/endpoints/location/get_edit.rs new file mode 100644 index 00000000..07a3546b --- /dev/null +++ b/src/endpoints/location/get_edit.rs @@ -0,0 +1,38 @@ +use actix_web::{web, HttpResponse, Responder}; +use askama_actix::TemplateToResponse; +use sqlx::PgPool; + +use crate::{ + endpoints::{location::LocationTemplate, IdPath}, + models::{Area, Location, Role, User}, + utils::ApplicationError, +}; + +#[actix_web::get("/locations/edit/{id}")] +pub async fn get( + user: web::ReqData, + pool: web::Data, + path: web::Path, +) -> Result { + if user.role == Role::AreaManager && user.role == Role::Admin { + return Err(ApplicationError::Unauthorized); + } + + let Some(location) = Location::read_by_id(pool.get_ref(), path.id).await? else { + return Ok(HttpResponse::NotFound().finish()); + }; + + let mut areas = None; + + if user.role == Role::Admin { + areas = Some(Area::read_all(pool.get_ref()).await?); + } + + let template = LocationTemplate { + user: user.into_inner(), + areas, + location: Some(location), + }; + + Ok(template.to_response()) +} diff --git a/src/endpoints/location/get_new.rs b/src/endpoints/location/get_new.rs index 9ea7a715..e14c5de4 100644 --- a/src/endpoints/location/get_new.rs +++ b/src/endpoints/location/get_new.rs @@ -1,16 +1,8 @@ use actix_web::{web, HttpResponse, Responder}; -use askama::Template; use askama_actix::TemplateToResponse; use sqlx::PgPool; -use crate::models::{Area, Role, User}; - -#[derive(Template)] -#[template(path = "location/new.html")] -pub struct NewLocationTemplate { - user: User, - areas: Option>, -} +use crate::{endpoints::location::LocationTemplate, models::{Area, Role, User}}; #[actix_web::get("/locations/new")] pub async fn get(user: web::ReqData, pool: web::Data) -> impl Responder { @@ -21,9 +13,10 @@ pub async fn get(user: web::ReqData, pool: web::Data) -> impl Resp areas = Some(Area::read_all(pool.get_ref()).await.unwrap()); } - let template = NewLocationTemplate { + let template = LocationTemplate { user: user.into_inner(), areas, + location: None }; return template.to_response(); diff --git a/src/endpoints/location/mod.rs b/src/endpoints/location/mod.rs index 01438498..0a6dc649 100644 --- a/src/endpoints/location/mod.rs +++ b/src/endpoints/location/mod.rs @@ -1,3 +1,26 @@ -pub mod get_overview; +use askama::Template; +use serde::Deserialize; + +use crate::models::{Area, Location, Role, User}; +use crate::filters; + pub mod get_new; +pub mod get_overview; pub mod post_new; +pub mod get_edit; +pub mod post_edit; +pub mod delete; + +#[derive(Template)] +#[template(path = "location/new_or_edit.html")] +pub struct LocationTemplate { + user: User, + areas: Option>, + location: Option, +} + +#[derive(Deserialize)] +pub struct LocationForm { + name: String, + area: Option, +} diff --git a/src/endpoints/location/post_edit.rs b/src/endpoints/location/post_edit.rs new file mode 100644 index 00000000..1318b8b3 --- /dev/null +++ b/src/endpoints/location/post_edit.rs @@ -0,0 +1,33 @@ +use actix_web::{http::header::LOCATION, web, HttpResponse, Responder}; +use sqlx::PgPool; + +use crate::{ + endpoints::{location::LocationForm, IdPath}, + models::{Location, Role, User}, + utils::ApplicationError, +}; + +#[actix_web::post("/locations/edit/{id}")] +pub async fn post( + user: web::ReqData, + pool: web::Data, + form: web::Form, + path: web::Path, +) -> Result { + if user.role == Role::AreaManager && user.role == Role::Admin { + return Err(ApplicationError::Unauthorized); + } + + let area_id = if user.role == Role::Admin && form.area.is_some() { + form.area.unwrap() + } else { + user.area_id + }; + + Location::update(pool.get_ref(), path.id, &form.name, area_id).await?; + + Ok(HttpResponse::Found() + .insert_header((LOCATION, "/locations")) + .insert_header(("HX-LOCATION", "/locations")) + .finish()) +} diff --git a/src/endpoints/location/post_new.rs b/src/endpoints/location/post_new.rs index 1c1bade2..37e70b6e 100644 --- a/src/endpoints/location/post_new.rs +++ b/src/endpoints/location/post_new.rs @@ -1,42 +1,38 @@ use actix_web::{http::header::LOCATION, web, HttpResponse, Responder}; -use serde::Deserialize; use sqlx::PgPool; -use crate::models::{Location, Role, User}; - -#[derive(Deserialize)] -pub struct NewLocationForm { - name: String, - area: Option, -} +use crate::{ + endpoints::location::LocationForm, + models::{Location, Role, User}, utils::ApplicationError, +}; #[actix_web::post("/locations/new")] pub async fn post( user: web::ReqData, pool: web::Data, - form: web::Form, -) -> impl Responder { - - if user.role == Role::AreaManager || user.role == Role::Admin { - let mut area_id = user.area_id; - - if user.role == Role::Admin && form.area.is_some() { - area_id = form.area.unwrap(); - } - - match Location::create(pool.get_ref(), &form.name, area_id).await { - Ok(_) => { - return HttpResponse::Found() - .insert_header((LOCATION, "/locations")) - .insert_header(("HX-LOCATION", "/locations")) - .finish() - } - Err(err) => { - println!("{}", err); - return HttpResponse::InternalServerError().finish(); - } - } + form: web::Form, +) -> Result { + if user.role == Role::AreaManager && user.role == Role::Admin { + return Err(ApplicationError::Unauthorized); } - return HttpResponse::Unauthorized().finish(); + let mut area_id = user.area_id; + + if user.role == Role::Admin && form.area.is_some() { + area_id = form.area.unwrap(); + } + + // TODO: rework + match Location::create(pool.get_ref(), &form.name, area_id).await { + Ok(_) => { + return Ok(HttpResponse::Found() + .insert_header((LOCATION, "/locations")) + .insert_header(("HX-LOCATION", "/locations")) + .finish()) + } + Err(err) => { + println!("{}", err); + return Ok(HttpResponse::InternalServerError().finish()); + } + } } diff --git a/src/models/location.rs b/src/models/location.rs index e388e5c0..ae3f2815 100644 --- a/src/models/location.rs +++ b/src/models/location.rs @@ -41,9 +41,7 @@ impl Location { } pub async fn read_all(pool: &PgPool) -> anyhow::Result> { - let records = query!("SELECT * FROM location") - .fetch_all(pool) - .await?; + let records = query!("SELECT * FROM location").fetch_all(pool).await?; let locations = records .iter() @@ -78,4 +76,42 @@ impl Location { Ok(locations) } + + pub async fn read_by_id(pool: &PgPool, id: i32) -> super::Result> { + let record = query!("SELECT * FROM location WHERE id = $1;", id) + .fetch_optional(pool) + .await?; + + let location = record.and_then(|r| { + Some(Location { + id: r.id, + name: r.name, + area_id: r.areaid, + area: None, + }) + }); + + Ok(location) + } + + pub async fn update(pool: &PgPool, id: i32, name: &str, area_id: i32) -> super::Result<()> { + query!( + "UPDATE location SET name = $1, areaid = $2 WHERE id = $3;", + name, + area_id, + id + ) + .execute(pool) + .await?; + + Ok(()) + } + + pub async fn delete(pool: &PgPool, id: i32) -> super::Result<()> { + sqlx::query!("DELETE FROM location WHERE id = $1;", id) + .execute(pool) + .await?; + + Ok(()) + } } diff --git a/templates/area/new_or_edit.html b/templates/area/new_or_edit.html index 562c9101..08fb1193 100644 --- a/templates/area/new_or_edit.html +++ b/templates/area/new_or_edit.html @@ -5,7 +5,7 @@
{% if area.is_some() %}
-

Bereich '{{ area.as_ref().unwrap().name }}' anlegen

+

Bereich '{{ area.as_ref().unwrap().name }}' bearbeiten

{% else %}

Neuen Bereich anlegen

diff --git a/templates/location/new.html b/templates/location/new.html deleted file mode 100644 index e7e8c13b..00000000 --- a/templates/location/new.html +++ /dev/null @@ -1,73 +0,0 @@ -{% extends "nav.html" %} - -{% block content %} -
-
- -

Neuen Ort anlegen

- -
-
- -
-
-
-
- -
-
-
-
- - {% if user.role == Role::Admin %} -
-
- -
-
-
-
-
- -
-
-
-
-
- {% endif %} - -
-
-
-
-
- -
- -
-
-
- - -
-
- - -{% endblock %} diff --git a/templates/location/new_or_edit.html b/templates/location/new_or_edit.html new file mode 100644 index 00000000..2de61549 --- /dev/null +++ b/templates/location/new_or_edit.html @@ -0,0 +1,90 @@ +{% extends "nav.html" %} + +{% block content %} +
+
+ {% if location.is_some() %} +
+

Veranstaltungsort '{{ location.as_ref().unwrap().name }}' bearbeiten

+ {% else %} + +

Neuen Ort anlegen

+ {% endif %} + +
+
+ +
+
+
+
+ +
+
+
+
+ + {% if user.role == Role::Admin %} +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ {% endif %} + +
+
+
+
+
+ +
+ +
+
+
+ +
+
+
+ + +{% endblock %}