diff --git a/Cargo.lock b/Cargo.lock index 98c2622..d90b8e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -402,7 +402,7 @@ dependencies = [ "cocoa-foundation 0.1.2", "core-foundation 0.9.4", "core-graphics 0.23.2", - "foreign-types", + "foreign-types 0.5.0", "libc", "objc", ] @@ -418,7 +418,7 @@ dependencies = [ "cocoa-foundation 0.2.0", "core-foundation 0.10.0", "core-graphics 0.24.0", - "foreign-types", + "foreign-types 0.5.0", "libc", "objc", ] @@ -571,7 +571,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", "core-graphics-types 0.1.3", - "foreign-types", + "foreign-types 0.5.0", "libc", ] @@ -584,7 +584,7 @@ dependencies = [ "bitflags 2.9.0", "core-foundation 0.10.0", "core-graphics-types 0.2.0", - "foreign-types", + "foreign-types 0.5.0", "libc", ] @@ -1310,6 +1310,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "endi" version = "1.1.0" @@ -1446,6 +1455,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + [[package]] name = "foreign-types" version = "0.5.0" @@ -1453,7 +1471,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared", + "foreign-types-shared 0.3.1", ] [[package]] @@ -1467,6 +1485,12 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -1955,6 +1979,25 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "h2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.9.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.6.0" @@ -2079,6 +2122,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2", "http", "http-body", "httparse", @@ -2089,6 +2133,39 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.11" @@ -2671,6 +2748,23 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndk" version = "0.9.0" @@ -2962,6 +3056,50 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "openssl" +version = "0.10.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" +dependencies = [ + "bitflags 2.9.0", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -3043,6 +3181,8 @@ name = "personal_site" version = "1.0.0" dependencies = [ "dioxus", + "reqwest", + "serde_json", ] [[package]] @@ -3490,26 +3630,34 @@ checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "base64", "bytes", + "encoding_rs", "futures-core", "futures-util", + "h2", "http", "http-body", "http-body-util", "hyper", + "hyper-rustls", + "hyper-tls", "hyper-util", "ipnet", "js-sys", "log", "mime", "mime_guess", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", + "system-configuration", "tokio", + "tokio-native-tls", "tokio-util", "tower", "tower-service", @@ -3544,6 +3692,20 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -3591,6 +3753,48 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "rustls" +version = "0.23.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7149975849f1abb3832b246010ef62ccc80d3a76169517ada7188252b9cfb437" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.20" @@ -3612,12 +3816,44 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.0", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "selectors" version = "0.22.0" @@ -4003,6 +4239,12 @@ dependencies = [ "quote", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -4045,6 +4287,27 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.9.0", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -4234,6 +4497,26 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.14" @@ -4458,6 +4741,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.4" @@ -4500,6 +4789,12 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version-compare" version = "0.2.0" @@ -5413,6 +5708,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + [[package]] name = "zerovec" version = "0.10.4" diff --git a/Cargo.toml b/Cargo.toml index 74e75de..4e13d9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,9 +5,10 @@ authors = ["darkicewolf50 "] edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] dioxus = { version = "0.6.0", features = ["router"] } +reqwest = { version = "0.12.15", features = ["json"] } +serde_json = "1" [features] default = ["web"] diff --git a/assets/styling/contactme.css b/assets/styling/contactme.css index cbb2337..b35da95 100644 --- a/assets/styling/contactme.css +++ b/assets/styling/contactme.css @@ -15,21 +15,14 @@ border-radius: var(--card-border-radius); flex-direction: column; justify-content: center; + margin: 2svh 0.5svw; + padding: 2svh 1svw; + max-width: 600px; } #ContactMe p { - margin: 2svh 2svw; - padding: 0svh 2svw; -} - -#contact-me { - display: flex; - justify-content: center; - flex-direction: column; - background-color: transparent; - border-radius: 0px; - margin: 2svh 0.5svw; - padding: 0svh 1svw; + margin: 2svh 0svw; + padding: 0svh 0svw; } #contact-me input { @@ -66,16 +59,6 @@ border-color: transparent; } -#ContactMe form { - display: flex; - justify-content: center; - flex-direction: column; - background-color: transparent; - border-radius: 0px; - margin: 2svh 0.5svw; - padding: 0svh 1svw; -} - #ContactMe input { background-color: var(--card-background-color); border-radius: var(--card-border-radius); diff --git a/src/views/contact_me.rs b/src/views/contact_me.rs index a0d02c7..ab6b92d 100644 --- a/src/views/contact_me.rs +++ b/src/views/contact_me.rs @@ -1,6 +1,8 @@ -use std::collections::HashMap; +use reqwest::Client; +use serde_json; -use dioxus::{logger::tracing, prelude::*}; +// use dioxus::logger::tracing; +use dioxus::prelude::*; use crate::views::Contact; @@ -8,18 +10,15 @@ const CONTACTME_CSS: Asset = asset!("/assets/styling/contactme.css"); #[component] pub fn ContactMe() -> Element { - let mut pre_form: Signal> = use_signal(|| { - HashMap::from([ - ("Name", "".to_string()), - ("Email", "".to_string()), - ("Message", "".to_string()), - ]) - }); + let mut contact_me_name = use_signal(|| String::new()); + let mut contact_me_email = use_signal(|| String::new()); + let mut contact_me_message = use_signal(|| String::new()); - let mut error_box_message: Signal = use_signal(|| "".to_string()); + let mut _error_box_message = use_signal(|| String::new()); rsx! { document::Link { rel: "stylesheet", href: CONTACTME_CSS } + title { "Brock Tomlinson - Contact" } div { id: "ContactMe", div { h2 { "Get in Touch" } @@ -29,46 +28,111 @@ pub fn ContactMe() -> Element { } } div { - div { id: "contact-me", - label { "Name" } - input { - oninput: move |event| { - pre_form.write().insert("Name", event.value()); - }, - } - label { "Email" } - input { - r#type: "email", - oninput: move |event| { - pre_form.write().insert("Email", event.value()); - }, - } - label { "Message" } - textarea { - oninput: move |event| { - pre_form.write().insert("Message", event.value()); - }, - } - p { "{error_box_message}" } - button { - r#type: "submit", - onclick: move |_| tracing::info!("Clicked!\n{:?}", pre_form), - "Submit" - } + // div { id: "contact-me", + label { "Name" } + input { + oninput: move |event| { + contact_me_name.set(event.value()); + }, } + label { "Email" } + input { + oninput: move |event| { + contact_me_email.set(event.value()); + }, + } + label { "Message" } + textarea { + oninput: move |event| { + contact_me_message.set(event.value()); + }, + } + p { "{_error_box_message}" } + button { + onclick: move |_| async move { + send_message( + contact_me_name(), + contact_me_email(), + contact_me_message(), + _error_box_message, + ) + .await + }, + "Submit" + } + // } } } Contact {} } } -// onsubmit:move |event| { log::info!("Submitted! {event:?}"), -// FormEvent { -// value: "NameEmailMessageSubmit", -// values: { -// "name": FormValue(["asdasd"]), -// "message": FormValue(["asdads"]), -// "email": FormValue(["adasdad@asdasd.asdads"]) -// }, -// valid: false -// } +async fn send_message(name: String, email: String, message: String, mut recived: Signal) { + if name == "".to_string() && email == "".to_string() && message == "".to_string() { + recived.set("Please fill fill out the form first".to_string()); + return (); + } else if name == "".to_string() { + recived.set("Please fill in your name so I know who I am contacting".to_string()); + return (); + } else if email == "".to_string() { + recived.set("Please fill in your email so I can get into contact".to_string()); + return (); + } else if message == "".to_string() { + recived.set("Please write a message so I know why you wanted to be in contact".to_string()); + return (); + } + + if is_valid_email_basic(&email) == false { + recived.set("Please write a vaild email".to_string()); + return (); + } + + let json_to_send = serde_json::json!({ + "content": format!("***New Message***\n*Name*: {name}\n*Email*: [{email}](mailto:{email})\n*Message*: {message}") + }); + + let client = Client::new(); + let res = client + .post("https://discord.com/api/webhooks/1371617469281861772/uARm18pvzzs4DVNLSYNYCyl7CQk_7eglqGmBabQASow2L7NHgGRHzQhkSAKaOIZmLnn1") + .json(&json_to_send) + .send() + .await; + match res { + Ok(_) => { + recived.set("Sent Sucessfully".to_string()); + } + Err(_) => { + recived.set("An Error Occured".to_string()); + } + } +} + +fn is_valid_email_basic(email: &str) -> bool { + // Find the position of '@' + if let Some(at_pos) = email.find('@') { + // Ensure there's only one '@' + if email.rfind('@') != Some(at_pos) { + return false; + } + + // Split into local and domain parts + let local = &email[..at_pos]; + let domain = &email[at_pos + 1..]; + + // Check both parts are non-empty + if local.is_empty() || domain.is_empty() { + return false; + } + + // Check domain contains at least one '.' and it's not at the start or end + if let Some(dot_pos) = domain.find('.') { + // '.' must not be at the beginning or end of the domain + if dot_pos == 0 || dot_pos == domain.len() - 1 { + return false; + } + return true; + } + } + + false +}