diff --git a/content/_index.md b/content/_index.md
index 534a486..6019d52 100644
--- a/content/_index.md
+++ b/content/_index.md
@@ -31,7 +31,6 @@ Teens For Christ Connection (TFC) is a rural ministry reaching out to the missio
-
@@ -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.
+{{< pt src="https://videos.tfcconnection.org/videos/embed/aa14bf70-adc8-4efd-b15b-37c59b31f418" >}}
+
## 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.
diff --git a/content/contact.md b/content/contact.md
index 90263e1..6e85650 100644
--- a/content/contact.md
+++ b/content/contact.md
@@ -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.
+
-
+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 >}}
diff --git a/content/ministries/mission-trip/_index.md b/content/ministries/mission-trip/_index.md
index 05c3fce..90b3d02 100644
--- a/content/ministries/mission-trip/_index.md
+++ b/content/ministries/mission-trip/_index.md
@@ -20,6 +20,6 @@ Our desire to see teenagers develop a heart for missions was the main force behi
##
-{{< 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 >}}
diff --git a/layouts/shortcodes/contact-form.html b/layouts/shortcodes/contact-form.html
index fab3fde..6b8c0b0 100644
--- a/layouts/shortcodes/contact-form.html
+++ b/layouts/shortcodes/contact-form.html
@@ -25,7 +25,7 @@
}
};
- xhr.open("POST", "https://n8n.tfcconnection.org/webhook/contact-form");
+ xhr.open("POST", "/contact");
xhr.send(data);
console.log(data);
}
diff --git a/src/api/contact.rs b/src/api/contact.rs
new file mode 100644
index 0000000..17e6bd0
--- /dev/null
+++ b/src/api/contact.rs
@@ -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,
+ email: Text,
+ staff: Text,
+ message: Text,
+}
+
+impl From<&ContactForm> for HashMap {
+ 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 "
+ .parse()
+ .unwrap(),
+ )
+ .to("Chris Cochrun ".parse().unwrap())
+ .to("Ethan Rose ".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) -> 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}"),
+ }
+ }
+}
diff --git a/src/api/mod.rs b/src/api/mod.rs
index dbb4844..0c01222 100644
--- a/src/api/mod.rs
+++ b/src/api/mod.rs
@@ -1,5 +1,6 @@
pub mod camp_form;
// pub mod errors;
+pub mod contact;
pub mod health_form;
pub mod local_trip_form;
pub mod mt_church_form;