updating mission trip and health forms

This commit is contained in:
Chris Cochrun 2025-01-29 11:17:46 -06:00
parent 710ebb6031
commit 29bb3cb04e
4 changed files with 114 additions and 13 deletions

View file

@ -4,15 +4,14 @@
:END: :END:
* TODO Calculate age on the camp form * TODO Calculate age on the camp form
* TODO Update MT Form in Rust server and upload data to NC * TODO Create a way to add some kids to nextcloud tables fast
** TODO Add any updated questions and redesign the page to fit the next trips
** DONE Add functionality for uploading all data to the NC tables
** TODO Add a backup sqlite db so that we can still retain the info in multiple places
** TODO Make sure the form is asynchronous so that users will get their page popping back immediately
** TODO Make sure form has better validation
* DONE Create unit tests in order to automatically make sure things work * DONE Create unit tests in order to automatically make sure things work
** DONE Break down the api to functions that are testable ** DONE Break down the api to functions that are testable
* TODO Create a way to add some kids to nextcloud tables fast * DONE Update MT Form in Rust server and upload data to NC
** DONE Add any updated questions and redesign the page to fit the next trips
** DONE Add functionality for uploading all data to the NC tables
** DONE Make sure the form is asynchronous so that users will get their page popping back immediately
** DONE Make sure form has better validation
* DONE Add registration cost and info to home page, thank you page, and thank you responses * DONE Add registration cost and info to home page, thank you page, and thank you responses
SCHEDULED: <2024-04-25 Thu 09:00> SCHEDULED: <2024-04-25 Thu 09:00>
* DONE Post health form to nextcloud tables * DONE Post health form to nextcloud tables

View file

@ -386,6 +386,23 @@
Later - Send $25 to the TFC Office Later - Send $25 to the TFC Office
</label> </label>
</div> </div>
<label for="health-form" class="basis-full px-2">
Would you like to fill out the health form before paying?
</label>
<div class="basis-full">
<input type="radio" value="yes" id="registration" name="health-form"
class="form-input {{ $formClasses }}" checked>
<label for="registration" class="">
Yes
</label>
</div>
<div class="basis-full">
<input type="radio" value="no" id="registration" name="health-form"
class="form-input {{ $formClasses }}">
<label for="registration" class="">
No
</label>
</div>
<div class="basis-full mt-8"> <div class="basis-full mt-8">
<button type="submit" class="content-right rounded-lg bg-primary-700 h-12 w-24 focus:bg-primary-900 focus:ring focus:ring-primary-700 hover:bg-primary-900 float-right">Submit</button> <button type="submit" class="content-right rounded-lg bg-primary-700 h-12 w-24 focus:bg-primary-900 focus:ring focus:ring-primary-700 hover:bg-primary-900 float-right">Submit</button>
</div> </div>

View file

@ -364,6 +364,14 @@ pub async fn health_form(MultipartForm(mut form): MultipartForm<HealthForm>) ->
Err(e) => error!("There was an error sending email: {e}"), Err(e) => error!("There was an error sending email: {e}"),
} }
let map = HashMap::from(&form);
actix_rt::spawn(store_form(map).map(|r| match r {
Ok(_) => {
info!("Successfully stored health form in nextcloud!")
}
Err(e) => error!("There was an error storing form in nextcloud: {e}"),
}));
let full_name = format!("{} {}", form.first_name.0, form.last_name.0); let full_name = format!("{} {}", form.first_name.0, form.last_name.0);
match form.registration.0.as_str() { match form.registration.0.as_str() {
"now" => { "now" => {
@ -372,7 +380,7 @@ pub async fn health_form(MultipartForm(mut form): MultipartForm<HealthForm>) ->
.insert_header(("Access-Control-Expose-Headers", "*")) .insert_header(("Access-Control-Expose-Headers", "*"))
.insert_header(( .insert_header((
"HX-Redirect", "HX-Redirect",
"https://secure.myvanco.com/L-Z772/campaign/C-13JPJ", "https://secure.myvanco.com/L-Z772/campaign/C-13DM3",
)) ))
.finish() .finish()
} }
@ -393,10 +401,9 @@ pub async fn health_form(MultipartForm(mut form): MultipartForm<HealthForm>) ->
h2 { h2 {
"Thank you, " (full_name) "!" "Thank you, " (full_name) "!"
} }
p { "Can't wait to see you at camp!" }
p { p {
class { "" } class { "" }
"If you'd like to pay for your registration go to the donate tab in the top right when you are ready and find the camp registration option." "If you'd like to pay for your registration go to the donate tab in the top right when you are ready and find the right registration option."
} }
} }
}; };
@ -423,3 +430,27 @@ pub async fn health_form(MultipartForm(mut form): MultipartForm<HealthForm>) ->
} }
// HttpResponse::Ok().body("hi") // HttpResponse::Ok().body("hi")
} }
async fn store_form(map: HashMap<i32, String>) -> Result<()> {
let client = Client::new();
let mut json = HashMap::new();
json.insert("data", map);
let res = client
.post("https://staff.tfcconnection.org/ocs/v2.php/apps/tables/api/2/tables/4/rows")
.basic_auth("chris", Some("2VHeGxeC^Zf9KqFK^G@Pt!zu2q^6@b"))
.header("OCS-APIRequest", "true")
.header("Content-Type", "application/json")
.json(&json)
.send()
.await?;
if res.status().is_success() {
let res = res.text().await.unwrap();
Ok(())
} else {
Err(eyre!(
"Problem in storing data: {:?}",
res.error_for_status()
))
}
}

View file

@ -68,6 +68,8 @@ struct MtForm {
#[multipart(rename = "final-agreement")] #[multipart(rename = "final-agreement")]
final_agreement: Text<String>, final_agreement: Text<String>,
registration: Text<String>, registration: Text<String>,
#[multipart(rename = "health-form")]
health_form: Text<String>,
#[multipart(rename = "image")] #[multipart(rename = "image")]
file: Option<TempFile>, file: Option<TempFile>,
} }
@ -364,7 +366,7 @@ impl MtForm {
.unwrap(), .unwrap(),
) )
.to("Chris Cochrun <chris@tfcconnection.org>".parse().unwrap()) .to("Chris Cochrun <chris@tfcconnection.org>".parse().unwrap())
.to("Ethan Rose <ethan@tfcconnection.org>".parse().unwrap()) // .to("Ethan Rose <ethan@tfcconnection.org>".parse().unwrap())
.subject(email_subject) .subject(email_subject)
.multipart(multi) .multipart(multi)
.wrap_err("problemss") .wrap_err("problemss")
@ -391,7 +393,58 @@ pub async fn mt_form(MultipartForm(form): MultipartForm<MtForm>) -> HttpResponse
} }
Err(e) => error!("error sending email {e}"), Err(e) => error!("error sending email {e}"),
}; };
HttpResponse::Ok().body(format!("Thank you {}, you can ", name)) match form.registration.0.as_str() {
"now" => {
if form.health_form.0.as_str() == "yes" {
HttpResponse::Ok()
.insert_header(("Access-Control-Expose-Headers", "*"))
.insert_header(("HX-Redirect", "/health-form?registration=now"))
.finish()
} else {
HttpResponse::Ok()
.insert_header(("Access-Control-Expose-Headers", "*"))
.insert_header((
"HX-Redirect",
"https://secure.myvanco.com/L-Z772/campaign/C-13DM3",
))
.finish()
}
}
"later" => {
if form.health_form.0.as_str() == "yes" {
HttpResponse::Ok()
.insert_header(("Access-Control-Expose-Headers", "*"))
.insert_header(("HX-Redirect", "/health-form?registration=later"))
.finish()
} else {
HttpResponse::Ok().body(
html! {
h2 { "Thank you! {}" (name)}
p { "You can go to the health form "
a href="/health-form" { "here" }
" or you can pay for mission trip "
a href="https://secure.myvanco.com/L-Z772/campaign/C-13DM3" { "here" }
}
}
.into_string(),
)
}
}
_ => {
error!("There wasn't an option for the registration passed in.");
HttpResponse::Ok().body(
html! {
h2 { "Thank you! {}" (name)}
p { "You can go to the health form "
a href="/health-form" { "here" }
" or you can pay for mission trip "
a href="https://secure.myvanco.com/L-Z772/campaign/C-13DM3" { "here" }
}
}
.into_string(),
)
}
}
} }
async fn store_form(map: HashMap<i32, String>) -> Result<()> { async fn store_form(map: HashMap<i32, String>) -> Result<()> {
@ -465,6 +518,7 @@ mod test {
relevant_notes: Text(String::from("Willing to take the ring")), relevant_notes: Text(String::from("Willing to take the ring")),
final_agreement: Text(String::from("yes")), final_agreement: Text(String::from("yes")),
registration: Text(String::from("later")), registration: Text(String::from("later")),
health_form: Text(String::from("yes")),
file: None, file: None,
} }
} }
@ -484,7 +538,7 @@ mod test {
async fn test_email() { async fn test_email() {
let mut form = form(); let mut form = form();
assert!(!form.first_name.is_empty()); assert!(!form.first_name.is_empty());
match form.send_email().await { match form.send_email() {
Ok(_) => assert!(true, "passed emailing test"), Ok(_) => assert!(true, "passed emailing test"),
Err(e) => assert!(false, "Failed emailing test: {e}"), Err(e) => assert!(false, "Failed emailing test: {e}"),
} }