use actix_web::{web, HttpRequest, HttpResponse};
use serde::{Deserialize, Serialize};
use sqlx::PgPool;
use tracing::field::Empty;
use uuid::Uuid;
use super::ApplicationResponse;
use crate::{db::NewForm, handlers::ApplicationError, services::jwt::JwtClient};
#[tracing::instrument(name = "handlers::form::list", skip(pool, jwt), fields(username=Empty, user_id=Empty))]
pub async fn list_forms(
pool: web::Data<PgPool>,
request: HttpRequest,
jwt: web::Data<JwtClient>,
) -> ApplicationResponse {
let current_user = jwt.user_or_403(request).await?;
let forms = sqlx::query!(
r#"
SELECT * FROM form
WHERE account_id=$1"#,
current_user.id,
)
.fetch_all(pool.as_ref())
.await?;
Ok(HttpResponse::Ok().body(format!("{:?},", forms)))
}
#[derive(Deserialize)]
pub struct FormGetRequest {
pub form_id: Uuid,
}
#[derive(Serialize)]
pub struct FormGetResponse {
pub fields: Vec<String>,
}
#[tracing::instrument(name = "handlers::form::get", skip(query, pool))]
pub async fn get_form(
query: web::Query<FormGetRequest>,
pool: web::Data<PgPool>,
) -> ApplicationResponse {
if let Some(form) = sqlx::query!("SELECT * FROM form WHERE id=$1", &query.form_id)
.fetch_optional(pool.as_ref())
.await?
{
let fields = sqlx::query!("SELECT * FROM form_input WHERE form_id=$1", form.id)
.fetch_all(pool.as_ref())
.await?;
let form_response_data = FormGetResponse {
fields: fields.iter().map(|f| String::from(&f.r#type)).collect(),
};
Ok(HttpResponse::Ok().body(serde_json::to_string(&form_response_data).unwrap()))
} else {
Err(ApplicationError::NotFoundError(format!(
"No form found with id {}.",
&query.form_id
)))
}
}
#[derive(Deserialize)]
pub struct FormCreationRequest {
pub qr_code_id: Uuid,
pub fields: Vec<String>,
}
#[tracing::instrument(name = "handlers::form::store", skip(json, pool, request, jwt), fields(username=Empty, user_id=Empty))]
pub async fn store_form(
json: web::Json<FormCreationRequest>,
pool: web::Data<PgPool>,
request: HttpRequest,
jwt: web::Data<JwtClient>,
) -> ApplicationResponse {
let current_user = jwt.user_or_403(request).await?;
let mut new_form = NewForm::default();
new_form.qr_code_id = json.qr_code_id;
new_form.account_id = current_user.id;
new_form.store(pool.as_ref()).await?;
let mut tx = pool.begin().await?;
for field in json.fields.iter() {
sqlx::query!(
r#"INSERT INTO form_input (id, form_id, type)
VALUES ($1, $2, $3)"#,
Uuid::new_v4(),
new_form.id,
field
)
.execute(&mut tx)
.await?;
}
tx.commit().await?;
Ok(HttpResponse::Ok().body(format!("Stored new form with id {}.", new_form.id)))
}