diff --git a/Cargo.lock b/Cargo.lock
index 70ab70f..6ae120a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -721,6 +721,7 @@ dependencies = [
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-logger",
+ "web-sys",
"yew",
"yew-router",
"yew-utils",
@@ -734,6 +735,7 @@ dependencies = [
"chrono",
"chrono-tz",
"format_num",
+ "rand",
"serde",
"serde_json",
"uuid",
diff --git a/Cargo.toml b/Cargo.toml
index 416360c..debeb7f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,6 +20,7 @@ wasm-bindgen = "0.2.84"
wasm-bindgen-futures = "0.4.34"
stdweb = "0.4.20"
js-sys = "0.3"
+web-sys = "0.3.61"
# other libs
reqwest = { version = "0.11.11", features = ["rustls-tls", "json", "blocking"], default-features = false }
diff --git a/src/api/backend/mod.rs b/src/api/backend/mod.rs
index e1cd32c..98e2954 100644
--- a/src/api/backend/mod.rs
+++ b/src/api/backend/mod.rs
@@ -1,6 +1,6 @@
use std::collections::HashSet;
-use jl_types::{dto::{filters::Filter, listing::Listing, project_card::ProjectCardDto}, domain::agent::Agent};
+use jl_types::{dto::{filters::Filter, listing::Listing, project_card::ProjectCardDto, payloads::contact::ContactPayload}, domain::{agent::Agent, count::Count, contact::Contact}};
use reqwest::Method;
use uuid::Uuid;
@@ -26,4 +26,17 @@ pub async fn get_project_listing(project_id: &Uuid) -> Result
Result, err::Error> {
perform_request_without_client::>(BASE_URL.into(), Method::GET, format!("read/agent"), None, 200, Vec::new(), None).await
+}
+
+pub async fn get_all_page_visits_count() -> Result {
+ perform_request_without_client::(BASE_URL.into(), Method::GET, format!("admin/visits/count"), None, 200, Vec::new(), None).await
+}
+pub async fn get_all_contacts_count() -> Result {
+ perform_request_without_client::(BASE_URL.into(), Method::GET, format!("admin/contacts/count"), None, 200, Vec::new(), None).await
+}
+pub async fn get_all_contacts() -> Result, err::Error> {
+ perform_request_without_client::>(BASE_URL.into(), Method::GET, format!("admin/contacts"), None, 200, Vec::new(), None).await
+}
+pub async fn create_new_contact_request(contact: ContactPayload) -> Result<(), err::Error> {
+ perform_request_without_client(BASE_URL.into(), Method::POST, format!("read/contact"), Some(contact), 200, Vec::new(), None).await
}
\ No newline at end of file
diff --git a/src/pages/contact.rs b/src/pages/contact.rs
index 950aad8..9016bfd 100644
--- a/src/pages/contact.rs
+++ b/src/pages/contact.rs
@@ -1,10 +1,62 @@
+use jl_types::dto::payloads::contact::ContactPayload;
use yew::prelude::*;
-use crate::components::{nav_bar::NavigationBar, footer::PageFooter};
+use crate::{components::{nav_bar::NavigationBar, footer::PageFooter}, utils::input::{get_value_from_input_event, get_value_from_textarea_event}, api::backend::create_new_contact_request};
#[function_component(ContactPage)]
pub fn contact_page() -> Html {
+
+ let first_name = use_state(|| String::new());
+ let last_name = use_state(|| String::new());
+ let credential = use_state(|| String::new());
+ let messsage = use_state(|| String::new());
+
+ //TODO: Think about how this renders each time an input is typed onto. (Pretty sure it does, as use_state re-renders the whole component it's in when called)
+ let on_fn_input_changed = {
+ let first_name = first_name.clone();
+ Callback::from(move |e: InputEvent| {
+ first_name.set(get_value_from_input_event(e));
+ })
+ };
+ let on_ln_input_changed = {
+ let last_name = last_name.clone();
+ Callback::from(move |e: InputEvent| {
+ last_name.set(get_value_from_input_event(e));
+ })
+ };
+ let on_credential_input_changed = {
+ let credential = credential.clone();
+ Callback::from(move |e: InputEvent| {
+ credential.set(get_value_from_input_event(e));
+ })
+ };
+ let on_message_input_changed = {
+ let messsage = messsage.clone();
+ Callback::from(move |e: InputEvent| {
+ messsage.set(get_value_from_textarea_event(e));
+ })
+ };
+ let onclick_button = {
+ let first_name = first_name.clone();
+ let last_name = last_name.clone();
+ let credential = credential.clone();
+ let messsage = messsage.clone();
+ Callback::from(move |_| {
+ let contact = ContactPayload {
+ first_name: (*first_name).clone(),
+ last_name: (*last_name).clone(),
+ credential: (*credential).clone(),
+ message: (*messsage).clone()
+ };
+ wasm_bindgen_futures::spawn_local(async move {
+ match create_new_contact_request(contact).await {
+ Ok(_) => {},
+ Err(error) => log::error!("Error in sending a contact request to the backend: {error}")
+ };
+ });
+ })
+ };
html! {
<>
@@ -23,25 +75,25 @@ pub fn contact_page() -> Html {
-
diff --git a/src/pages/search.rs b/src/pages/search.rs
index df17c34..137da0e 100644
--- a/src/pages/search.rs
+++ b/src/pages/search.rs
@@ -32,14 +32,14 @@ pub fn search_page() -> Html {
cities.insert(0, OptionWrapper::new(None));
cities_handle.set(cities);
},
- Err(error) => info!("Error in loading cities: {error}")
+ Err(error) => log::error!("Error in loading cities: {error}")
};
match get_all_projects_with_filters_paged(&(*page_counter), filters).await {
Ok(projects) => {
search_results_handle.set(projects);
finished_loading.set(true);
},
- Err(error) => info!("Error in loading projects: {error}"),
+ Err(error) => log::error!("Error in loading projects: {error}"),
};
});
});
@@ -120,7 +120,7 @@ pub fn search_page() -> Html {
districts_vec.insert(0, OptionWrapper::new(None));
districts_handle.set(districts_vec);
},
- Err(error) => info!("Error in dropdown callback: {}", error),
+ Err(error) => log::error!("Error in dropdown callback: {}", error),
};
});
}
@@ -182,6 +182,10 @@ pub fn search_page() -> Html {
Some(project_district) => filters.push(Filter::InDistrict(project_district.clone())),
None => {},
};
+ match &(*unit_rooms_filter).option {
+ Some(rooms_filter) => filters.push(Filter::ByRoomCount(*rooms_filter as i32)),
+ None => {},
+ };
let search_results_handle = search_results_handle.clone();
let page_counter = page_counter.clone();
@@ -190,9 +194,8 @@ pub fn search_page() -> Html {
Ok(projects) => {
search_results_handle.set(projects)
},
- Err(error) => info!("Error in loading projects: {error}"),
+ Err(error) => log::error!("Error in loading projects: {error}"),
};
- info!("done");
});
})};
diff --git a/src/utils/input.rs b/src/utils/input.rs
new file mode 100644
index 0000000..23a1713
--- /dev/null
+++ b/src/utils/input.rs
@@ -0,0 +1,16 @@
+use wasm_bindgen::{JsCast, UnwrapThrowExt};
+use web_sys::{Event, HtmlInputElement, InputEvent, HtmlTextAreaElement};
+
+pub fn get_value_from_input_event(e: InputEvent) -> String {
+ let event: Event = e.dyn_into().unwrap_throw();
+ let event_target = event.target().unwrap_throw();
+ let target: HtmlInputElement = event_target.dyn_into().unwrap_throw();
+ target.value()
+}
+
+pub fn get_value_from_textarea_event(e: InputEvent) -> String {
+ let event: Event = e.dyn_into().unwrap_throw();
+ let event_target = event.target().unwrap_throw();
+ let target: HtmlTextAreaElement = event_target.dyn_into().unwrap_throw();
+ target.value()
+}
\ No newline at end of file
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
index f329ff6..35a5e0a 100644
--- a/src/utils/mod.rs
+++ b/src/utils/mod.rs
@@ -1 +1,2 @@
-pub mod get_value;
\ No newline at end of file
+pub mod get_value;
+pub mod input;
\ No newline at end of file