refactor: move availability into endpoints

This commit is contained in:
Max Hohlfeld 2024-06-09 22:35:16 +02:00
parent 8bf606b4d7
commit 11c4f52baf
15 changed files with 198 additions and 214 deletions

View File

@ -1,28 +0,0 @@
use actix_identity::Identity;
use actix_web::{web, HttpResponse, Responder};
use serde::Deserialize;
use sqlx::PgPool;
use crate::models::Availabillity;
#[derive(Deserialize)]
pub struct AvailabillityPath {
pub id: i32
}
#[actix_web::delete("/availabillity/delete/{id}")]
pub async fn delete_availabillity(user: Identity, pool: web::Data<PgPool>, path: web::Path<AvailabillityPath>) -> impl Responder {
if let Ok(current_user_id) = user.id() {
let current_user_id: i32 = current_user_id.parse().unwrap();
if let Ok(availabillity_in_db) = Availabillity::read_by_id(pool.get_ref(), path.id).await {
if availabillity_in_db.user_id == current_user_id {
if let Ok(_) = Availabillity::delete(pool.get_ref(), availabillity_in_db.id).await {
return HttpResponse::NoContent().finish();
}
}
}
}
return HttpResponse::BadRequest().finish();
}

View File

@ -1,41 +0,0 @@
use actix_identity::Identity;
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
use askama::Template;
use askama_actix::TemplateToResponse;
use chrono::NaiveDate;
use serde::Deserialize;
use sqlx::PgPool;
use crate::models::{User, Role};
#[derive(Template)]
#[template(path = "availabillity_new.html")]
struct AvailabillityNewTemplate {
user: User,
date: NaiveDate
}
#[derive(Deserialize)]
pub struct AvailabillityNewQuery {
date: NaiveDate,
}
#[actix_web::get("/availabillity/new")]
pub async fn get_availabillity_new(
user: Option<Identity>,
pool: web::Data<PgPool>,
query: web::Query<AvailabillityNewQuery>,
) -> impl Responder {
if let Some(user) = user {
let current_user = User::read_by_id(pool.as_ref(), user.id().unwrap().parse().unwrap()).await.unwrap();
let template = AvailabillityNewTemplate { user: current_user, date: query.date };
template.to_response()
} else {
HttpResponse::PermanentRedirect()
.insert_header((LOCATION, "/login"))
.finish()
}
}

View File

@ -1,7 +0,0 @@
pub mod routes;
mod get_availabillity_new;
mod post_availabillity;
mod delete_availabillity;
mod update_availabillity;
pub use routes::init;

View File

@ -1,106 +0,0 @@
use actix_identity::Identity;
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
use askama::Template;
use askama_actix::TemplateToResponse;
use chrono::{NaiveDate, NaiveTime};
use sqlx::PgPool;
use crate::{calendar::post_availabillity::AvailabillityForm, models::{Availabillity, User, Role}};
use super::delete_availabillity::AvailabillityPath;
#[derive(Template)]
#[template(path = "availabillity_edit.html")]
pub struct AvailabillityEditTemplate {
user: User,
date: NaiveDate,
id: i32,
start_time: String,
end_time: String,
has_time: bool,
comment: String,
}
#[actix_web::get("/availabillity/edit/{id}")]
pub async fn get_update_availabillity(
user: Identity,
pool: web::Data<PgPool>,
path: web::Path<AvailabillityPath>,
) -> impl Responder {
let current_user = User::read_by_id(pool.as_ref(), user.id().unwrap().parse().unwrap())
.await
.unwrap();
if let Ok(availabillity) = Availabillity::read_by_id(pool.get_ref(), path.id).await {
if availabillity.user_id == user.id().unwrap().parse::<i32>().unwrap() {
let start_time = availabillity
.start_time
.unwrap_or(NaiveTime::from_hms_opt(0, 0, 0).unwrap())
.format("%R")
.to_string();
let end_time = availabillity
.end_time
.unwrap_or(NaiveTime::from_hms_opt(23, 59, 0).unwrap())
.format("%R")
.to_string();
let has_time = availabillity.start_time.is_some() && availabillity.end_time.is_some();
let comment = availabillity.comment.unwrap_or(String::new());
let template = AvailabillityEditTemplate {
user: current_user,
date: availabillity.date,
id: path.id,
start_time,
end_time,
has_time,
comment
};
return template.to_response();
}
}
HttpResponse::BadRequest().body("Availabillity with this id doesn't exist.")
}
#[actix_web::post("/availabillity/edit/{id}")]
pub async fn post_update_availabillity(
user: Identity,
pool: web::Data<PgPool>,
path: web::Path<AvailabillityPath>,
form: web::Form<AvailabillityForm>
) -> impl Responder {
if let Ok(mut availabillity) = Availabillity::read_by_id(pool.get_ref(), path.id).await {
if availabillity.user_id == user.id().unwrap().parse::<i32>().unwrap() {
let mut has_changed = false;
if availabillity.start_time != form.from {
availabillity.start_time = form.from;
has_changed = true;
}
if availabillity.end_time != form.till {
availabillity.end_time = form.till;
has_changed = true;
}
if availabillity.comment != form.comment {
availabillity.comment = form.comment.clone();
has_changed = true;
}
if has_changed {
if let Ok(_) = Availabillity::update(pool.get_ref(), path.id, &availabillity).await {
return HttpResponse::Found()
.insert_header((LOCATION, "/"))
.finish();
}
}
}
}
HttpResponse::BadRequest().body("Fehler beim erstellen")
}

View File

@ -0,0 +1,24 @@
use actix_web::{web, HttpResponse, Responder};
use sqlx::PgPool;
use crate::{
endpoints::IdPath,
models::{Availabillity, User},
};
#[actix_web::delete("/availabillity/delete/{id}")]
pub async fn delete(
user: web::ReqData<User>,
pool: web::Data<PgPool>,
path: web::Path<IdPath>,
) -> impl Responder {
if let Ok(availabillity_in_db) = Availabillity::read_by_id(pool.get_ref(), path.id).await {
if availabillity_in_db.user_id == user.id {
if let Ok(_) = Availabillity::delete(pool.get_ref(), availabillity_in_db.id).await {
return HttpResponse::NoContent().finish();
}
}
}
return HttpResponse::BadRequest().finish();
}

View File

@ -0,0 +1,26 @@
use actix_web::{web, Responder};
use askama::Template;
use askama_actix::TemplateToResponse;
use chrono::NaiveDate;
use crate::{endpoints::NaiveDateQuery, models::{Role, User}};
#[derive(Template)]
#[template(path = "availability/new.html")]
struct AvailabillityNewTemplate {
user: User,
date: NaiveDate,
}
#[actix_web::get("/availabillity/new")]
pub async fn get(
user: web::ReqData<User>,
query: web::Query<NaiveDateQuery>,
) -> impl Responder {
let template = AvailabillityNewTemplate {
user: user.into_inner(),
date: query.date,
};
template.to_response()
}

View File

@ -1,27 +1,12 @@
use actix_web::{web, HttpResponse, Responder};
use actix_web::{web, Responder};
use askama::Template;
use askama_actix::TemplateToResponse;
use chrono::{NaiveDate, Utc};
use serde::Deserialize;
use sqlx::PgPool;
use crate::models::{Area, Availabillity, Event, Function, Role, User};
use super::{
delete_availabillity::delete_availabillity,
get_availabillity_new::get_availabillity_new,
post_availabillity::post_availabillity,
update_availabillity::{get_update_availabillity, post_update_availabillity},
};
pub fn init(cfg: &mut web::ServiceConfig) {
cfg.service(get_index);
cfg.service(get_availabillity_new);
cfg.service(post_availabillity);
cfg.service(delete_availabillity);
cfg.service(get_update_availabillity);
cfg.service(post_update_availabillity);
}
#[derive(Deserialize)]
pub struct CalendarQuery {
date: Option<NaiveDate>,
@ -38,8 +23,8 @@ struct CalendarTemplate {
}
#[actix_web::get("/")]
async fn get_index(
current_user: web::ReqData<User>,
async fn get(
user: web::ReqData<User>,
pool: web::Data<PgPool>,
query: web::Query<CalendarQuery>,
) -> impl Responder {
@ -52,17 +37,18 @@ async fn get_index(
let events = Event::read_by_date_including_location(pool.get_ref(), date)
.await
.unwrap();
let availabillities = Availabillity::read_by_date_including_user(pool.get_ref(), date)
.await
.unwrap();
let template = CalendarTemplate {
user: current_user.into_inner(),
user: user.into_inner(),
date,
areas,
events,
availabillities,
};
HttpResponse::Ok().body(template.render().unwrap())
template.to_response()
}

View File

@ -0,0 +1,50 @@
use actix_web::{web, HttpResponse, Responder};
use askama_actix::TemplateToResponse;
use chrono::NaiveTime;
use sqlx::PgPool;
use crate::{
endpoints::{availability::AvailabillityEditTemplate, IdPath},
models::{Availabillity, User},
};
#[actix_web::get("/availabillity/edit/{id}")]
pub async fn get(
user: web::ReqData<User>,
pool: web::Data<PgPool>,
path: web::Path<IdPath>,
) -> impl Responder {
if let Ok(availabillity) = Availabillity::read_by_id(pool.get_ref(), path.id).await {
if availabillity.user_id == user.id {
let start_time = availabillity
.start_time
.unwrap_or(NaiveTime::from_hms_opt(0, 0, 0).unwrap())
.format("%R")
.to_string();
let end_time = availabillity
.end_time
.unwrap_or(NaiveTime::from_hms_opt(23, 59, 0).unwrap())
.format("%R")
.to_string();
let has_time = availabillity.start_time.is_some() && availabillity.end_time.is_some();
let comment = availabillity.comment.unwrap_or(String::new());
let template = AvailabillityEditTemplate {
user: user.into_inner(),
date: availabillity.date,
id: path.id,
start_time,
end_time,
has_time,
comment,
};
return template.to_response();
}
}
HttpResponse::BadRequest().body("Availabillity with this id doesn't exist.")
}

View File

@ -0,0 +1,23 @@
use askama::Template;
use chrono::NaiveDate;
use crate::models::{User,Role};
pub mod delete;
pub mod get_new;
pub mod get_update;
pub mod get_overview;
pub mod post_new;
pub mod post_update;
#[derive(Template)]
#[template(path = "availability/edit.html")]
struct AvailabillityEditTemplate {
user: User,
date: NaiveDate,
id: i32,
start_time: String,
end_time: String,
has_time: bool,
comment: String,
}

View File

@ -1,4 +1,3 @@
use actix_identity::Identity;
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
use chrono::{NaiveDate, NaiveTime};
use serde::Deserialize;
@ -11,20 +10,25 @@ pub struct AvailabillityForm {
pub date: NaiveDate,
pub from: Option<NaiveTime>,
pub till: Option<NaiveTime>,
pub comment: Option<String>
pub comment: Option<String>,
}
#[actix_web::post("/availabillity/new")]
pub async fn post_availabillity(
user: Identity,
pub async fn post(
user: web::ReqData<User>,
pool: web::Data<PgPool>,
form: web::Form<AvailabillityForm>,
) -> impl Responder {
let current_user = User::read_by_id(pool.as_ref(), user.id().unwrap().parse().unwrap())
if let Ok(_) = Availabillity::create(
pool.get_ref(),
user.id,
form.date,
form.from,
form.till,
form.comment.clone(),
)
.await
.unwrap();
if let Ok(_) = Availabillity::create(pool.get_ref(), current_user.id, form.date, form.from, form.till, form.comment.clone()).await {
{
HttpResponse::Found()
.insert_header((LOCATION, "/"))
.finish()

View File

@ -0,0 +1,47 @@
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
use sqlx::PgPool;
use crate::{
endpoints::{availability::post_new::AvailabillityForm, IdPath},
models::{Availabillity, User},
};
#[actix_web::post("/availabillity/edit/{id}")]
pub async fn post(
user: web::ReqData<User>,
pool: web::Data<PgPool>,
path: web::Path<IdPath>,
form: web::Form<AvailabillityForm>,
) -> impl Responder {
if let Ok(mut availabillity) = Availabillity::read_by_id(pool.get_ref(), path.id).await {
if availabillity.user_id == user.id {
let mut has_changed = false;
if availabillity.start_time != form.from {
availabillity.start_time = form.from;
has_changed = true;
}
if availabillity.end_time != form.till {
availabillity.end_time = form.till;
has_changed = true;
}
if availabillity.comment != form.comment {
availabillity.comment = form.comment.clone();
has_changed = true;
}
if has_changed {
if let Ok(_) = Availabillity::update(pool.get_ref(), path.id, &availabillity).await
{
return HttpResponse::Found()
.insert_header((LOCATION, "/"))
.finish();
}
}
}
}
HttpResponse::BadRequest().body("Fehler beim erstellen")
}

View File

@ -2,6 +2,7 @@ use actix_web::web::ServiceConfig;
use chrono::NaiveDate;
use serde::Deserialize;
mod availability;
mod events;
mod location;
mod user;
@ -36,6 +37,13 @@ pub fn init(cfg: &mut ServiceConfig) {
cfg.service(user::get_reset::get);
cfg.service(user::post_reset::post);
cfg.service(availability::delete::delete);
cfg.service(availability::get_new::get);
cfg.service(availability::get_overview::get);
cfg.service(availability::get_update::get);
cfg.service(availability::post_new::post);
cfg.service(availability::post_update::post);
cfg.service(events::get_new::get);
cfg.service(events::post_new::post);

View File

@ -15,7 +15,6 @@ use crate::models::User;
use crate::postgres_session_store::SqlxPostgresqlSessionStore;
mod auth;
mod calendar;
mod endpoints;
mod models;
mod middleware;
@ -116,7 +115,6 @@ async fn main() -> anyhow::Result<()> {
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(pool.clone()))
.configure(calendar::init)
.configure(endpoints::init)
.wrap(middleware::RedirectToLogin)
.wrap(middleware::LoadCurrentUser)