From 3f8b9cb5d8fac478b52f3635733a02950f124cdb Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Mon, 8 Jan 2024 15:20:33 -0600 Subject: [PATCH] all reference forms and health apis are done --- layouts/shortcodes/mt-church-form.html | 23 ++- layouts/shortcodes/mt-parent-form.html | 22 ++- layouts/shortcodes/mt-teacher-form.html | 22 ++- src/api/church_form.rs | 191 ++++++++++++++++++++++ src/api/health_form.rs | 7 +- src/api/mod.rs | 3 + src/api/mt_form.rs | 5 +- src/api/parent_form.rs | 204 ++++++++++++++++++++++++ src/api/teacher_form.rs | 176 ++++++++++++++++++++ src/main.rs | 6 + 10 files changed, 630 insertions(+), 29 deletions(-) create mode 100644 src/api/church_form.rs create mode 100644 src/api/parent_form.rs create mode 100644 src/api/teacher_form.rs diff --git a/layouts/shortcodes/mt-church-form.html b/layouts/shortcodes/mt-church-form.html index b9f7cba..96515d6 100644 --- a/layouts/shortcodes/mt-church-form.html +++ b/layouts/shortcodes/mt-church-form.html @@ -6,15 +6,22 @@ const form = document.getElementById('form'); const data = new FormData(form); - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function() { - if (this.readyState == 4 && this.status == 200) { - // Logic directing where to send the user after form submission based on results. + + // For use in dev + // Can now start using this in production IF, + // I get the server running on the server + /* let base = "https://api.tfcconnection.org/health-form"; */ + let base = "http://localhost:4242/church-form"; + fetch(base, { + method: "POST", + body: data + }).then((res) => { + console.log(res); + if (res.ok) { window.location.href = '/thankyou/'; - }; - }; - xhr.open("POST", "https://n8n.tfcconnection.org/webhook/mt-church-form"); - xhr.send(data); + } + }); + console.log(data); console.log("Hallo!"); return false; diff --git a/layouts/shortcodes/mt-parent-form.html b/layouts/shortcodes/mt-parent-form.html index 2a625b0..2c320cd 100644 --- a/layouts/shortcodes/mt-parent-form.html +++ b/layouts/shortcodes/mt-parent-form.html @@ -6,15 +6,21 @@ const form = document.getElementById('form'); const data = new FormData(form); - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function() { - if (this.readyState == 4 && this.status == 200) { - // Logic directing where to send the user after form submission based on results. + // For use in dev + // Can now start using this in production IF, + // I get the server running on the server + /* let base = "https://api.tfcconnection.org/health-form"; */ + let base = "http://localhost:4242/parent-form"; + fetch(base, { + method: "POST", + body: data + }).then((res) => { + console.log(res); + if (res.ok) { window.location.href = '/thankyou/'; - }; - }; - xhr.open("POST", "https://n8n.tfcconnection.org/webhook/mt-parent-form"); - xhr.send(data); + } + }); + console.log(data); console.log("Hallo!"); return false; diff --git a/layouts/shortcodes/mt-teacher-form.html b/layouts/shortcodes/mt-teacher-form.html index a168dad..2de54a3 100644 --- a/layouts/shortcodes/mt-teacher-form.html +++ b/layouts/shortcodes/mt-teacher-form.html @@ -6,15 +6,21 @@ const form = document.getElementById('form'); const data = new FormData(form); - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function() { - if (this.readyState == 4 && this.status == 200) { - // Logic directing where to send the user after form submission based on results. + // For use in dev + // Can now start using this in production IF, + // I get the server running on the server + /* let base = "https://api.tfcconnection.org/health-form"; */ + let base = "http://localhost:4242/teacher-form"; + fetch(base, { + method: "POST", + body: data + }).then((res) => { + console.log(res); + if (res.ok) { window.location.href = '/thankyou/'; - }; - }; - xhr.open("POST", "https://n8n.tfcconnection.org/webhook/mt-teacher-form"); - xhr.send(data); + } + }); + console.log(data); console.log("Hallo!"); return false; diff --git a/src/api/church_form.rs b/src/api/church_form.rs new file mode 100644 index 0000000..c55ca38 --- /dev/null +++ b/src/api/church_form.rs @@ -0,0 +1,191 @@ +use actix_multipart::form::{text::Text, MultipartForm}; +use actix_web::{post, HttpResponse}; +use lettre::{ + message::MultiPart, + transport::smtp::authentication::{Credentials, Mechanism}, + Message, SmtpTransport, Transport, +}; + +#[derive(Debug, MultipartForm, Default)] +struct ChurchForm { + #[multipart(rename = "firstname")] + first_name: Option>, + #[multipart(rename = "lastname")] + last_name: Option>, + #[multipart(rename = "studentfirstname")] + student_first_name: Option>, + #[multipart(rename = "studentlastname")] + student_last_name: Option>, + relationship: Option>, + #[multipart(rename = "walk-with-jesus")] + walk: Option>, + commitment: Option>, + teachable: Option>, + #[multipart(rename = "pos-characteristics")] + positive: Option>, + #[multipart(rename = "neg-characteristics")] + negative: Option>, + #[multipart(rename = "extra-info")] + notes: Option>, +} + +#[post("/church-form")] +pub async fn church_form(MultipartForm(form): MultipartForm) -> HttpResponse { + let first = form.first_name.as_ref().unwrap().0.clone(); + let last = form.last_name.as_ref().unwrap().0.clone(); + let student = format!( + "{} {}", + form.student_first_name.as_ref().unwrap().0.clone(), + form.student_last_name.as_ref().unwrap().0.clone() + ); + let email_subject = format!( + "{} {} filled out a Church Reference form for {}!", + first, last, student + ); + let relationship = form + .relationship + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let walk = form + .walk + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let positive = form + .positive + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let negative = form + .negative + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let commitment = form + .commitment + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let teachable = form + .teachable + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let notes = form + .notes + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + log::info!("{first} {last} filled out a Church Reference form!"); + let email = markup::new! { + @markup::doctype() + html { + head { + title { @format!("{} {} filled out a Church Reference form for {}!", first, last, student) } + style { + "table { border-collapse: collapse; width: 100% }" + "td, th { padding: 8px }" + "td { text-align: left; width: 70%; word-wrap: break-word }" + "th { text-align: right; border-right: 1px solid #ddd }" + "tr { border-bottom: 1px solid #ddd }" + "h1 { text-align: center }" + } + } + body { + h1 { @format!("Church Reference form for {}!", student) } + hr; + table { + tr { + th { "Name" } + td { @format!("{} {}", first, last) } + } + tr { + th { "Student" } + td { @student } + } + tr { + th { "Relationship to teen" } + td { @relationship } + } + tr { + th { "Walk with Jesus" } + td { @walk } + } + tr { + th { "Commitment to church" } + td { @commitment } + } + tr { + th { "Teachable spirit" } + td { @teachable } + } + tr { + th { "Positive Attributes" } + td { @positive } + } + tr { + th { "Negaitive Attributes" } + td { @negative } + } + tr { + th { "Other Notes" } + td { @notes } + } + } + } + } + }; + let multi = MultiPart::alternative_plain_html(String::from("Testing"), email.to_string()); + + if let Ok(m) = Message::builder() + .from( + "TFC ADMIN " + .parse() + .unwrap(), + ) + .to("Chris Cochrun ".parse().unwrap()) + .to("Ethan Rose ".parse().unwrap()) + .subject(email_subject) + .multipart(multi) + { + let sender = SmtpTransport::relay("mail.tfcconnection.org") + .ok() + .unwrap() + .credentials(Credentials::new( + "no-reply@mail.tfcconnection.org".to_owned(), + "r9f36mNZFtiW4f".to_owned(), + )) + .authentication(vec![Mechanism::Plain]) + .build(); + match sender.send(&m) { + Ok(res) => log::info!("{:?}", res), + Err(e) => log::info!("{e}"), + } + } else { + log::info!("Email incorrect"); + } + + HttpResponse::Ok().body("hi") +} diff --git a/src/api/health_form.rs b/src/api/health_form.rs index 56dc61a..6662602 100644 --- a/src/api/health_form.rs +++ b/src/api/health_form.rs @@ -410,11 +410,13 @@ pub async fn health_form(MultipartForm(form): MultipartForm) -> Http }; let mut path: Option = Some(String::from("")); let mut file_exists = false; + let mut filename = String::from(""); log::info!("{:?}", form); log::info!("{:?}", file_exists); if let Some(f) = form.file { if let Some(file) = f.file_name { if let Some(ext) = file.rsplit(".").next() { + filename = format!("{}.{}", filename_noext, ext); path = Some(format!("./tmp/{}.{}", filename_noext, ext)); } else { path = Some(format!("./tmp/{}", file)); @@ -436,8 +438,7 @@ pub async fn health_form(MultipartForm(form): MultipartForm) -> Http let multi = if file_exists { let filebody = fs::read(path.clone().unwrap_or_default()); let content_type = ContentType::parse("image/jpg").unwrap(); - let attachment = - Attachment::new(path.unwrap_or_default()).body(filebody.unwrap(), content_type); + let attachment = Attachment::new(filename).body(filebody.unwrap(), content_type); log::info!("{:?}", attachment); MultiPart::alternative_plain_html(String::from("Testing"), email.to_string()) .singlepart(attachment) @@ -452,7 +453,7 @@ pub async fn health_form(MultipartForm(form): MultipartForm) -> Http .unwrap(), ) .to("Chris Cochrun ".parse().unwrap()) - // .to("Ethan Rose ".parse().unwrap()) + .to("Ethan Rose ".parse().unwrap()) .subject(email_subject) .multipart(multi) { diff --git a/src/api/mod.rs b/src/api/mod.rs index 3ac1875..92d4be5 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,2 +1,5 @@ +pub mod church_form; pub mod health_form; pub mod mt_form; +pub mod parent_form; +pub mod teacher_form; diff --git a/src/api/mt_form.rs b/src/api/mt_form.rs index 083e4ff..9d9455d 100644 --- a/src/api/mt_form.rs +++ b/src/api/mt_form.rs @@ -459,11 +459,13 @@ pub async fn mt_form(MultipartForm(form): MultipartForm) -> HttpResponse }; let mut path: Option = Some(String::from("")); let mut file_exists = false; + let mut filename = String::from(""); log::info!("{:?}", form); log::info!("{:?}", file_exists); if let Some(f) = form.file { if let Some(file) = f.file_name { if let Some(ext) = file.rsplit(".").next() { + filename = format!("{}.{}", filename_noext, ext); path = Some(format!("./tmp/{}.{}", filename_noext, ext)); } else { path = Some(format!("./tmp/{}", file)); @@ -485,8 +487,7 @@ pub async fn mt_form(MultipartForm(form): MultipartForm) -> HttpResponse let multi = if file_exists { let filebody = fs::read(path.clone().unwrap_or_default()); let content_type = ContentType::parse("image/jpg").unwrap(); - let attachment = - Attachment::new(path.unwrap_or_default()).body(filebody.unwrap(), content_type); + let attachment = Attachment::new(filename).body(filebody.unwrap(), content_type); log::info!("{:?}", attachment); MultiPart::alternative_plain_html(String::from("Testing"), email.to_string()) .singlepart(attachment) diff --git a/src/api/parent_form.rs b/src/api/parent_form.rs new file mode 100644 index 0000000..7d14969 --- /dev/null +++ b/src/api/parent_form.rs @@ -0,0 +1,204 @@ +use actix_multipart::form::{text::Text, MultipartForm}; +use actix_web::{post, HttpResponse}; +use lettre::{ + message::MultiPart, + transport::smtp::authentication::{Credentials, Mechanism}, + Message, SmtpTransport, Transport, +}; + +#[derive(Debug, MultipartForm, Default)] +struct ParentForm { + #[multipart(rename = "firstname")] + first_name: Option>, + #[multipart(rename = "lastname")] + last_name: Option>, + #[multipart(rename = "studentfirstname")] + student_first_name: Option>, + #[multipart(rename = "studentlastname")] + student_last_name: Option>, + email: Option>, + authority: Option>, + positive: Option>, + negative: Option>, + #[multipart(rename = "family-relation")] + family_relation: Option>, + #[multipart(rename = "previous-trip-info")] + previous_trip_info: Option>, + #[multipart(rename = "trip-feelings")] + trip_feelings: Option>, + #[multipart(rename = "extra-info")] + notes: Option>, +} + +#[post("/parent-form")] +pub async fn parent_form(MultipartForm(form): MultipartForm) -> HttpResponse { + let first = form.first_name.as_ref().unwrap().0.clone(); + let last = form.last_name.as_ref().unwrap().0.clone(); + let student = format!( + "{} {}", + form.student_first_name.as_ref().unwrap().0.clone(), + form.student_last_name.as_ref().unwrap().0.clone() + ); + let email_subject = format!( + "{} {} filled out a parent form for {}!", + first, last, student + ); + let email = form + .email + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let authority = form + .authority + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let positive = form + .positive + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let negative = form + .negative + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let family = form + .family_relation + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let previous_trip_info = form + .previous_trip_info + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let feelings = form + .trip_feelings + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let notes = form + .notes + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + log::info!("{first} {last} filled out a parent form!"); + let email = markup::new! { + @markup::doctype() + html { + head { + title { @format!("{} {} filled out a Parent Reference form for {}!", first, last, student) } + style { + "table { border-collapse: collapse; width: 100% }" + "td, th { padding: 8px }" + "td { text-align: left; width: 70%; word-wrap: break-word }" + "th { text-align: right; border-right: 1px solid #ddd }" + "tr { border-bottom: 1px solid #ddd }" + "h1 { text-align: center }" + } + } + body { + h1 { @format!("Parent Reference form for {}!", student) } + hr; + table { + tr { + th { "Name" } + td { @format!("{} {}", first, last) } + } + tr { + th { "Student" } + td { @student } + } + tr { + th { "Email" } + td { @email } + } + tr { + th { "Response to authority" } + td { @authority } + } + tr { + th { "Positive Attributes" } + td { @positive } + } + tr { + th { "Negaitive Attributes" } + td { @negative } + } + tr { + th { "Relations to Family" } + td { @family } + } + tr { + th { "Previous trip info" } + td { @previous_trip_info } + } + tr { + th { "Feelings about the trip" } + td { @feelings } + } + tr { + th { "Other Notes" } + td { @notes } + } + } + } + } + }; + let multi = MultiPart::alternative_plain_html(String::from("Testing"), email.to_string()); + + if let Ok(m) = Message::builder() + .from( + "TFC ADMIN " + .parse() + .unwrap(), + ) + .to("Chris Cochrun ".parse().unwrap()) + .to("Ethan Rose ".parse().unwrap()) + .subject(email_subject) + .multipart(multi) + { + let sender = SmtpTransport::relay("mail.tfcconnection.org") + .ok() + .unwrap() + .credentials(Credentials::new( + "no-reply@mail.tfcconnection.org".to_owned(), + "r9f36mNZFtiW4f".to_owned(), + )) + .authentication(vec![Mechanism::Plain]) + .build(); + match sender.send(&m) { + Ok(res) => log::info!("{:?}", res), + Err(e) => log::info!("{e}"), + } + } else { + log::info!("Email incorrect"); + } + + HttpResponse::Ok().body("hi") +} diff --git a/src/api/teacher_form.rs b/src/api/teacher_form.rs new file mode 100644 index 0000000..707f4f7 --- /dev/null +++ b/src/api/teacher_form.rs @@ -0,0 +1,176 @@ +use actix_multipart::form::{text::Text, MultipartForm}; +use actix_web::{post, HttpResponse}; +use lettre::{ + message::MultiPart, + transport::smtp::authentication::{Credentials, Mechanism}, + Message, SmtpTransport, Transport, +}; + +#[derive(Debug, MultipartForm, Default)] +struct TeacherForm { + #[multipart(rename = "firstname")] + first_name: Option>, + #[multipart(rename = "lastname")] + last_name: Option>, + #[multipart(rename = "studentfirstname")] + student_first_name: Option>, + #[multipart(rename = "studentlastname")] + student_last_name: Option>, + relationship: Option>, + attitudes: Option>, + positive: Option>, + negative: Option>, + #[multipart(rename = "team-challenges")] + team: Option>, + #[multipart(rename = "extra-info")] + notes: Option>, +} + +#[post("/teacher-form")] +pub async fn teacher_form(MultipartForm(form): MultipartForm) -> HttpResponse { + let first = form.first_name.as_ref().unwrap().0.clone(); + let last = form.last_name.as_ref().unwrap().0.clone(); + let student = format!( + "{} {}", + form.student_first_name.as_ref().unwrap().0.clone(), + form.student_last_name.as_ref().unwrap().0.clone() + ); + let email_subject = format!( + "{} {} filled out a teacher form for {}!", + first, last, student + ); + let relationship = form + .relationship + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let attitudes = form + .attitudes + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let positive = form + .positive + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let negative = form + .negative + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let team = form + .team + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + let notes = form + .notes + .as_ref() + .unwrap_or(&Text { + 0: String::from(""), + }) + .0 + .clone(); + log::info!("{first} {last} filled out a teacher form!"); + let email = markup::new! { + @markup::doctype() + html { + head { + title { @format!("{} {} filled out a teacher form for {}!", first, last, student) } + style { + "table { border-collapse: collapse; width: 100% }" + "td, th { padding: 8px }" + "td { text-align: left; width: 70%; word-wrap: break-word }" + "th { text-align: right; border-right: 1px solid #ddd }" + "tr { border-bottom: 1px solid #ddd }" + "h1 { text-align: center }" + } + } + body { + h1 { @format!("Teacher Reference form for {}!", student) } + hr; + table { + tr { + th { "Name" } + td { @format!("{} {}", first, last) } + } + tr { + th { "Student" } + td { @student } + } + tr { + th { "Relationship to teen" } + td { @relationship } + } + tr { + th { "Attitude in classroom" } + td { @attitudes } + } + tr { + th { "Positive Attributes" } + td { @positive } + } + tr { + th { "Negaitive Attributes" } + td { @negative } + } + tr { + th { "Teamwork" } + td { @team } + } + tr { + th { "Other Notes" } + td { @notes } + } + } + } + } + }; + let multi = MultiPart::alternative_plain_html(String::from("Testing"), email.to_string()); + + if let Ok(m) = Message::builder() + .from( + "TFC ADMIN " + .parse() + .unwrap(), + ) + .to("Chris Cochrun ".parse().unwrap()) + .to("Ethan Rose ".parse().unwrap()) + .subject(email_subject) + .multipart(multi) + { + let sender = SmtpTransport::relay("mail.tfcconnection.org") + .ok() + .unwrap() + .credentials(Credentials::new( + "no-reply@mail.tfcconnection.org".to_owned(), + "r9f36mNZFtiW4f".to_owned(), + )) + .authentication(vec![Mechanism::Plain]) + .build(); + match sender.send(&m) { + Ok(res) => log::info!("{:?}", res), + Err(e) => log::info!("{e}"), + } + } else { + log::info!("Email incorrect"); + } + + HttpResponse::Ok().body("hi") +} diff --git a/src/main.rs b/src/main.rs index a0aa1ba..51aaa1c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,11 @@ mod api; use actix_multipart::form::tempfile::TempFileConfig; use actix_web::{middleware, App, HttpServer}; +use api::church_form::church_form; use api::health_form::health_form; use api::mt_form::mt_form; +use api::parent_form::parent_form; +use api::teacher_form::teacher_form; #[actix_web::main] async fn main() -> std::io::Result<()> { @@ -20,6 +23,9 @@ async fn main() -> std::io::Result<()> { .app_data(TempFileConfig::default().directory("./tmp")) .service(mt_form) .service(health_form) + .service(parent_form) + .service(teacher_form) + .service(church_form) }) .bind(("127.0.0.1", 4242))? .workers(2)