diff --git a/Readme.md b/Readme.md index 42c0de0..1ae3b86 100644 --- a/Readme.md +++ b/Readme.md @@ -22,7 +22,7 @@ - [x] Space between Unit selection menu and unit media on empty unit features - [x] Make the navbar logo bigger - [x] Finish agents screen -- [ ] Finish Contact us screen +- [x] Finish Contact us screen - [x] Link agent info with details screen, remove hardcoded pic and details - [x] Whatsapp button should direct to agent's phone number wa.me link @@ -31,5 +31,5 @@ New todo's - [ ] Static image folder for start page - [ ] Admin panel with page loads & contact us clicks - [ ] Put JL on top of the Agents section -- [ ] If someone enters the page from an agent, make anything that appears on the website reference them. +- [x] If someone enters the page from an agent, make anything that appears on the website reference them. - [x] Contact us Functionality \ No newline at end of file diff --git a/src/api/backend/mod.rs b/src/api/backend/mod.rs index 98e2954..e9c0699 100644 --- a/src/api/backend/mod.rs +++ b/src/api/backend/mod.rs @@ -28,6 +28,10 @@ pub async fn get_all_agents() -> 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_agent_with_shortcode(shortcode: &String) -> Result { + perform_request_without_client::(BASE_URL.into(), Method::GET, format!("read/agent/{shortcode}"), 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 } diff --git a/src/pages/details.rs b/src/pages/details.rs index 89efadd..375c602 100644 --- a/src/pages/details.rs +++ b/src/pages/details.rs @@ -1,15 +1,52 @@ -use jl_types::{dto::listing::Listing, domain::{unit_type::UnitType, unit::Unit}}; +use jl_types::{dto::listing::Listing, domain::{unit_type::UnitType, unit::Unit, agent::Agent}}; use log::{error}; use thousands::Separable; use uuid::Uuid; use yew::prelude::*; +use yew_router::{prelude::{use_location}}; -use crate::{components::{nav_bar::NavigationBar, media_slideshow::MediaSlideshow, floating_widget::FloatingWidget, feature::FeatureItem, footer::PageFooter}, api::backend::get_project_listing}; +use crate::{components::{nav_bar::NavigationBar, media_slideshow::MediaSlideshow, floating_widget::FloatingWidget, feature::FeatureItem, footer::PageFooter}, api::backend::{get_project_listing, get_agent_with_shortcode}, utils::storage::{self, StorageKey}}; const ALPHABET_LETTERS: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; #[function_component(DetailsPage)] pub fn details_page(props: &DetailsPageProps) -> Html { + // Agent shortcode part + let location = use_location().unwrap(); + let query_params: Vec<(String, String)> = location.query().unwrap(); + + let override_agent_handle: UseStateHandle> = use_state(|| None); + + for query_param in query_params { + if query_param.0 == String::from("shortcode") { + // Store shortcode in localstorage + match storage::store_in_local_storage(StorageKey::AgentShortcode, &query_param.1) { + Ok(_) => {}, + Err(error) => log::error!("Error storing agent shortcode in localstorage\n: {}", error), + }; + } + } + + let persisted_shortcode_res = storage::get_from_local_storage(StorageKey::AgentShortcode); + match persisted_shortcode_res { + Ok(persisted_shortcode_opt) => { + match persisted_shortcode_opt { + Some(persisted_shortcode) => { + // Get agent from server + let override_agent_handle = override_agent_handle.clone(); + wasm_bindgen_futures::spawn_local(async move { + match get_agent_with_shortcode(&persisted_shortcode).await { + Ok(agent) => { override_agent_handle.set(Some(agent)) }, + Err(error) => error!("Error fetching agent with shortcode. Error: {:?}", error), + }; + }) + }, + None => {} + } + }, + Err(error) => log::error!("Error reading agent shortcode from localstorage\n: {}", error), + }; + // Project loading part let finished_loading = use_state(|| false); let listing_handle: UseStateHandle = use_state(|| Listing::default()); let selected_unit_handle = use_state(|| 0); @@ -54,7 +91,10 @@ pub fn details_page(props: &DetailsPageProps) -> Html { html!{ <> - +
{ if *finished_loading { @@ -67,12 +107,21 @@ pub fn details_page(props: &DetailsPageProps) -> Html { // Agent
// Profile pic - {"agent_pfp"}/ + {"agent_pfp"}/
-
{listing.agent.full_name}
+
{ + if let Some(overriden_agent) = (*override_agent_handle).clone() + { overriden_agent.full_name.clone() } else { listing.agent.full_name.clone() } + }
{ - format_phone_number(&listing.agent.credential) + format_phone_number(&{ + if let Some(overriden_agent) = (*override_agent_handle).clone() + { overriden_agent.credential.clone() } else { listing.agent.credential.clone() } + }) }
diff --git a/src/pages/mod.rs b/src/pages/mod.rs index 4cd1a6d..7796b72 100644 --- a/src/pages/mod.rs +++ b/src/pages/mod.rs @@ -4,5 +4,4 @@ pub mod details; pub mod not_found; pub mod contact; pub mod admin; -pub mod agents; -pub mod thanks; \ No newline at end of file +pub mod agents; \ No newline at end of file diff --git a/src/pages/thanks.rs b/src/pages/thanks.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 35a5e0a..47709df 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,2 +1,3 @@ pub mod get_value; -pub mod input; \ No newline at end of file +pub mod input; +pub mod storage; \ No newline at end of file diff --git a/src/utils/storage.rs b/src/utils/storage.rs new file mode 100644 index 0000000..2705fef --- /dev/null +++ b/src/utils/storage.rs @@ -0,0 +1,53 @@ +use std::fmt::Display; + +use err::{MessageResource, Error}; +use web_sys::window; + +pub enum StorageKey { + AgentShortcode, +} +impl Display for StorageKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + StorageKey::AgentShortcode => write!(f, "agentshortcode"), + } + } +} + +/// Store a simple string in local storage. Result is just for error handling, +/// no value is returned in case of success. +pub fn store_in_local_storage(key: StorageKey, val: &str) -> Result<(), Error> { + match window() { + Some(window) => match window.local_storage() { + Ok(local_storage_opt) => match local_storage_opt { + Some(local_storage) => match local_storage.set_item(key.to_string().as_str(), val) { + Ok(_) => Ok(()), + Err(js_err) => Err(Error::IO(MessageResource::new_from_string(format!("JsValue: {:#?}", js_err.as_string())))), + }, + None => Err(Error::IO(MessageResource::new_from_str("Error accessing local storage instance from window object. Result was fine, option came back as none."))), + }, + Err(e) => Err(Error::IO(MessageResource::new_from_string(format!("Error accessing local storage instance from window object. Resulting error: {:#?}", e.as_string())))), + }, + None => Err(Error::IO(MessageResource::new_from_string(format!("Error accessing Window object.")))), + } +} + +/// Call all the javascript API's to get an item from LocalStorage +/// This fn returns a Result> Since there can be an error +/// accessing the objects/instances needed to access the item and there +/// can also be an absence of the item itself. +pub fn get_from_local_storage(key: StorageKey) -> Result, Error> { + match window() { + Some(window) => match window.local_storage() { + Ok(local_storage_opt) => match local_storage_opt { + Some(local_storage) => match local_storage.get_item(key.to_string().as_str()) { + Ok(value) => Ok(value), + Err(js_err) => Err(Error::IO(MessageResource::new_from_string(format!("JsValue: {:#?}", js_err.as_string())))), + }, + None => Err(Error::IO(MessageResource::new_from_str("Error accessing local storage instance from window object. Result was fine, option came back as none."))), + }, + Err(e) => Err(Error::IO(MessageResource::new_from_string(format!("Error accessing local storage instance from window object. Resulting error: {:#?}", e.as_string())))), + }, + None => Err(Error::IO(MessageResource::new_from_string(format!("Error accessing Window object.")))), + } +} \ No newline at end of file