Added contact request logic and connected it to the backend
This commit is contained in:
parent
49e7712407
commit
89fe0495cb
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -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",
|
||||
|
@ -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 }
|
||||
|
@ -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<Listing, err::Erro
|
||||
|
||||
pub async fn get_all_agents() -> Result<Vec<Agent>, err::Error> {
|
||||
perform_request_without_client::<String, Vec<Agent>>(BASE_URL.into(), Method::GET, format!("read/agent"), None, 200, Vec::new(), None).await
|
||||
}
|
||||
|
||||
pub async fn get_all_page_visits_count() -> Result<Count, err::Error> {
|
||||
perform_request_without_client::<String, Count>(BASE_URL.into(), Method::GET, format!("admin/visits/count"), None, 200, Vec::new(), None).await
|
||||
}
|
||||
pub async fn get_all_contacts_count() -> Result<Count, err::Error> {
|
||||
perform_request_without_client::<String, Count>(BASE_URL.into(), Method::GET, format!("admin/contacts/count"), None, 200, Vec::new(), None).await
|
||||
}
|
||||
pub async fn get_all_contacts() -> Result<Vec<Contact>, err::Error> {
|
||||
perform_request_without_client::<String, Vec<Contact>>(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
|
||||
}
|
@ -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! {
|
||||
<>
|
||||
<NavigationBar/>
|
||||
@ -23,25 +75,25 @@ pub fn contact_page() -> Html {
|
||||
<div class={"contact-us-name-container"}>
|
||||
<div class={"contact-us-textfield-container"}> // First name
|
||||
<div class={"contact-us-textfield-label"}>{"Nombre"}</div>
|
||||
<input class={"contact-us-textfield"}/>
|
||||
<input class={"contact-us-textfield"} oninput={on_fn_input_changed}/>
|
||||
</div>
|
||||
|
||||
<div class={"contact-us-textfield-container"}> // Last name
|
||||
<div class={"contact-us-textfield-label"}>{"Apellido"}</div>
|
||||
<input class={"contact-us-textfield"}/>
|
||||
<input class={"contact-us-textfield"} oninput={on_ln_input_changed}/>
|
||||
</div>
|
||||
</div>
|
||||
<div class={"contact-us-textfield-container"}> // Email or Phone number
|
||||
<div class={"contact-us-textfield-label"}>{"Número de Teléfono o Correo"}</div>
|
||||
<input class={"contact-us-textfield"}/>
|
||||
<input class={"contact-us-textfield"} oninput={on_credential_input_changed}/>
|
||||
</div>
|
||||
|
||||
<div class={"contact-us-textfield-container"}> // Message
|
||||
<div class={"contact-us-textfield-label"}>{"Mensaje"}</div>
|
||||
<textarea class={"contact-us-textarea"}/>
|
||||
<textarea class={"contact-us-textarea"} oninput={on_message_input_changed}/>
|
||||
</div>
|
||||
|
||||
<div class={"contact-us-button"}>
|
||||
<div class={"contact-us-button"} onclick={onclick_button}>
|
||||
{"Enviar"}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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");
|
||||
});
|
||||
})};
|
||||
|
||||
|
16
src/utils/input.rs
Normal file
16
src/utils/input.rs
Normal file
@ -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()
|
||||
}
|
@ -1 +1,2 @@
|
||||
pub mod get_value;
|
||||
pub mod get_value;
|
||||
pub mod input;
|
Loading…
Reference in New Issue
Block a user