use axum::{extract::State, response::IntoResponse, routing::post}; use cm_lib::models::Shift; use diesel::{ExpressionMethods, OptionalExtension, QueryDsl, SelectableHelper}; use diesel_async::{scoped_futures::ScopedFutureExt, AsyncConnection, RunQueryDsl}; use crate::axum_ructe::render; use crate::AppState; pub(crate) fn router() -> axum::Router { axum::Router::new() .route("/shifts/open", post(open_shift)) .route("/shifts/close", post(close_shift)) } async fn open_shift(State(state): State) -> impl IntoResponse { let shift = { let mut conn = state.connection.get().await.unwrap(); conn.transaction(|conn| { use cm_lib::schema::shifts::dsl::*; async move { diesel::insert_into(shifts) .default_values() .execute(conn) .await?; shifts .order(id.desc()) .select(Shift::as_select()) .first(conn) .await } .scope_boxed() }) .await .optional() .unwrap() }; render!(crate::templates::home_html, shift) } async fn close_shift(State(state): State) -> impl IntoResponse { { let mut conn = state.connection.get().await.unwrap(); conn.transaction(|conn| { use cm_lib::schema::shifts::dsl::*; async move { let open_shift = shifts .filter(end.is_null()) .select(Shift::as_select()) .first(conn) .await?; diesel::update(shifts.filter(id.eq(open_shift.id))) .set(end.eq(Some(chrono::Utc::now().naive_local()))) .execute(conn) .await } .scope_boxed() }) .await .unwrap(); } render!(crate::templates::home_html, None) }