use actix_web::{http::header::LOCATION, web, HttpResponse, Responder}; use maud::html; use sqlx::PgPool; use crate::{ endpoints::availability::AvailabilityForm, utils::{self, ApplicationError}, }; use brass_db::{ models::{Availability, AvailabilityChangeset, AvailabilityContext, User}, validation::AsyncValidate, }; #[actix_web::post("/availability/new")] pub async fn post( user: web::ReqData, pool: web::Data, form: web::Form, ) -> Result { let start = form.startdate.and_time(form.starttime); let end = form.enddate.and_time(form.endtime); let context = AvailabilityContext { pool: pool.get_ref(), user_id: user.id, availability: None, }; let mut changeset = AvailabilityChangeset { time: (start, end), comment: form.comment.clone(), }; if let Err(e) = changeset.validate_with_context(&context).await { let error_message = html! { svg class="icon is-small" { use href="/static/feather-sprite.svg#alert-triangle" {} } " " (e) }; return Ok(HttpResponse::UnprocessableEntity().body(error_message.into_string())); }; if let Some(a) = Availability::find_adjacent_by_time_for_user(pool.get_ref(), &start, &end, user.id, None) .await? { if a.end == start { changeset.time.0 = a.start; } if a.start == end { changeset.time.1 = a.end; } Availability::update(pool.get_ref(), a.id, changeset).await?; } else { Availability::create(pool.get_ref(), user.id, changeset).await?; } let url = utils::get_return_url_for_date(&form.startdate); Ok(HttpResponse::Found() .insert_header((LOCATION, url.clone())) .insert_header(("HX-LOCATION", url)) .finish()) }