adding more mission trip info and making the contact form work again

This commit is contained in:
Chris Cochrun 2025-01-28 15:11:43 -06:00
parent bd3f5082c1
commit 23f132c5c1
6 changed files with 177 additions and 6 deletions

View file

@ -31,7 +31,6 @@ Teens For Christ Connection (TFC) is a rural ministry reaching out to the missio
<!-- > If you need to pay for your camp form, pay for registration ($85) [here](https://secure.myvanco.com/L-Z772/campaign/C-13JPJ) or pay for the full price ($185) [here](https://secure.myvanco.com/L-Z772/campaign/C-13JQE). --> <!-- > If you need to pay for your camp form, pay for registration ($85) [here](https://secure.myvanco.com/L-Z772/campaign/C-13JPJ) or pay for the full price ($185) [here](https://secure.myvanco.com/L-Z772/campaign/C-13JQE). -->
<!-- {{< pt src="https://videos.tfcconnection.org/videos/embed/757dc0dd-9bdc-4d79-8f81-754249ff23d2" >}} -->
<!-- ////////MT STUFF//////// --> <!-- ////////MT STUFF//////// -->
<div class="flex flex-wrap items-center"> <div class="flex flex-wrap items-center">
@ -54,6 +53,8 @@ Fill out now!
> If you need to fill out a health form, please do so [here](/health-form). Also here you can fill out the [parent](/mt-parent-form), [teacher](/mt-teacher-form), [church-related](/mt-church-form) reference forms. > If you need to fill out a health form, please do so [here](/health-form). Also here you can fill out the [parent](/mt-parent-form), [teacher](/mt-teacher-form), [church-related](/mt-church-form) reference forms.
{{< pt src="https://videos.tfcconnection.org/videos/embed/aa14bf70-adc8-4efd-b15b-37c59b31f418" >}}
## Our Vision ## Our Vision
Our vision is to change the world from the heart of America by providing disciple making opportunities that serve communities where student ministries are limited. Our vision is to change the world from the heart of America by providing disciple making opportunities that serve communities where student ministries are limited.

View file

@ -9,8 +9,8 @@ sharingLinks: false
--- ---
Right now our contact form is broken, you can email any of the staff by using their first name followed by @tfcconnection.org. Sorry for the inconvenience. <!-- Right now our contact form is broken, you can email any of the staff by using their first name followed by @tfcconnection.org. Sorry for the inconvenience. -->
<!-- We would love to get into contact with you! Just put in your name, a message and your email address and we will get right back to you! You can also email a specific staff member here if you'd like to make sure the message gets directly to them! If you don't know who to email, just leave it blank! --> We would love to get into contact with you! Just put in your name, a message and your email address and we will get right back to you! You can also email a specific staff member here if you'd like to make sure the message gets directly to them! If you don't know who to email, just leave it blank!
<!-- {{< contact-form >}} --> {{< contact-form >}}

View file

@ -20,6 +20,6 @@ Our desire to see teenagers develop a heart for missions was the main force behi
<!-- {{< /button >}} --> <!-- {{< /button >}} -->
## ##
{{< pt src="https://videos.tfcconnection.org/videos/embed/c92fc5dd-ebfd-4d13-b486-d08d281868f2" >}} {{< pt src="https://videos.tfcconnection.org/videos/embed/aa14bf70-adc8-4efd-b15b-37c59b31f418" >}}
{{< spacing >}} {{< spacing >}}

View file

@ -25,7 +25,7 @@
} }
}; };
xhr.open("POST", "https://n8n.tfcconnection.org/webhook/contact-form"); xhr.open("POST", "/contact");
xhr.send(data); xhr.send(data);
console.log(data); console.log(data);
} }

169
src/api/contact.rs Normal file
View file

@ -0,0 +1,169 @@
use std::{
collections::{BTreeMap, HashMap},
fs,
};
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
use actix_web::{post, web, HttpResponse};
use color_eyre::{eyre::eyre, Result};
use lettre::{
message::{header::ContentType, Attachment, MultiPart, SinglePart},
Message,
};
use maud::{html, Markup, PreEscaped, DOCTYPE};
use reqwest::Client;
use serde_json::json;
use sqlx::SqliteConnection;
use tracing::{error, info};
#[derive(Debug, MultipartForm)]
struct ContactForm {
name: Text<String>,
email: Text<String>,
staff: Text<String>,
message: Text<String>,
}
impl From<&ContactForm> for HashMap<i32, String> {
fn from(form: &ContactForm) -> Self {
let mut map = HashMap::new();
map.insert(169, form.name.0.clone());
map.insert(169, form.email.0.clone());
map.insert(169, form.staff.0.clone());
map.insert(169, form.message.0.clone());
map
}
}
impl ContactForm {
async fn build_email(&self) -> Markup {
html! {
(DOCTYPE)
meta charset="utf-8";
html {
head {
title { (self.name.0) " filled out a contact form!" }
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 { "Contact form for " (self.name.0) "!" }
hr;
p { "Email: " (self.email.0) }
p { "To: " (self.staff.0) }
hr;
p { (self.message.0) }
}
}
}
}
async fn store_form(&self) -> Result<()> {
let client = Client::new();
let map = HashMap::from(self);
let mut json = HashMap::new();
json.insert("data", map);
let link = r#"https://staff.tfcconnection.org/apps/tables/#/table/14/row/757"#;
let res = client
.post("https://staff.tfcconnection.org/ocs/v2.php/apps/tables/api/2/tables/14/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()
))
}
}
async fn send_email(&mut self) -> Result<()> {
let name = self.name.clone();
let email_subject = format!("Contact form for {}!", name);
info!("{name} contact form!");
let email = self.build_email().await;
let email = SinglePart::html(email.into_string());
if let Ok(m) = Message::builder()
.from(
"TFC ADMIN <no-reply@mail.tfcconnection.org>"
.parse()
.unwrap(),
)
.to("Chris Cochrun <chris@tfcconnection.org>".parse().unwrap())
.to("Ethan Rose <ethan@tfcconnection.org>".parse().unwrap())
.subject(email_subject)
.singlepart(email)
{
crate::email::send_email(m).await
} else {
Err(eyre!("Email incorrect"))
}
}
}
#[post("/api/mt-parent-form")]
pub async fn mt_parent_form(MultipartForm(mut form): MultipartForm<ContactForm>) -> HttpResponse {
match form.store_form().await {
Ok(_) => info!("Successfully sent form to nextcloud!"),
Err(e) => error!("There was an erroring sending form to nextcloud: {e}"),
}
match form.send_email().await {
Ok(_) => info!("Successfully sent email"),
Err(e) => error!("There was an error sending the email: {e}"),
}
HttpResponse::Ok().body("thankyou")
}
#[cfg(test)]
mod test {
use actix_web::test;
use pretty_assertions::assert_eq;
use sqlx::Connection;
use tracing::debug;
use super::*;
fn form() -> ContactForm {
ContactForm {
name: Text(String::from("Bilbo Braggins")),
email: Text(String::from("biblo@hobbits.us")),
staff: Text(String::from("Uncle")),
message: Text(String::from("Very")),
}
}
#[test]
async fn test_nc_post() {
let form = form();
assert!(!form.name.is_empty());
let res = form.store_form().await;
match res {
Ok(_) => assert!(true, "passed storing test"),
Err(e) => assert!(false, "Failed storing test: {e}"),
}
}
#[test]
async fn test_email() {
let mut form = form();
assert!(!form.name.is_empty());
match form.send_email().await {
Ok(_) => assert!(true, "passed emailing test"),
Err(e) => assert!(false, "Failed emailing test: {e}"),
}
}
}

View file

@ -1,5 +1,6 @@
pub mod camp_form; pub mod camp_form;
// pub mod errors; // pub mod errors;
pub mod contact;
pub mod health_form; pub mod health_form;
pub mod local_trip_form; pub mod local_trip_form;
pub mod mt_church_form; pub mod mt_church_form;