diff --git a/src/api/backend/mod.rs b/src/api/backend/mod.rs index 366c872..62a50b0 100644 --- a/src/api/backend/mod.rs +++ b/src/api/backend/mod.rs @@ -1,15 +1,20 @@ use std::collections::HashSet; use jl_types::{ - domain::{agent::Agent, contact::Contact, count::Count, location::Location, project::Project, unit::Unit}, + domain::{ + agent::Agent, contact::Contact, count::Count, location::Location, project::Project, + unit::Unit, + }, dto::{ filters::Filter, item::Item, listing::Listing, payloads::{ + agent::{NewAgentPayload, UpdateAgentPayload}, contact::ContactPayload, location::NewLocationPayload, - project::{NewProjectPayload, UpdateProjectPayload}, unit::UpdateUnitPayload, agent::{UpdateAgentPayload, NewAgentPayload}, + project::{NewProjectPayload, UpdateProjectPayload}, + unit::{UpdateUnitPayload, NewUnitPayload}, }, project_card::ProjectCardDto, }, @@ -213,6 +218,20 @@ pub async fn create_new_agent(agent: NewAgentPayload) -> Result Result { + perform_request_without_client( + BASE_URL.into(), + Method::POST, + format!("admin/unit"), + Some(unit), + 200, + Vec::new(), + None, + ) + .await +} + pub async fn create_new_project(project: NewProjectPayload) -> Result { perform_request_without_client( BASE_URL.into(), diff --git a/src/components/admin_agent.rs b/src/components/admin_agent.rs index f2d08a4..a0b9ffc 100644 --- a/src/components/admin_agent.rs +++ b/src/components/admin_agent.rs @@ -3,8 +3,9 @@ use yew::prelude::*; use yew_router::prelude::use_navigator; use crate::{ + api::backend::delete_agent, pages::admin::edit::{EditItem, EditType}, - routes::main_router::Route, api::backend::delete_agent, + routes::main_router::Route, }; //TODO: Add admin tag diff --git a/src/components/admin_unit.rs b/src/components/admin_unit.rs index 08a516b..ee357d9 100644 --- a/src/components/admin_unit.rs +++ b/src/components/admin_unit.rs @@ -4,8 +4,9 @@ use yew::prelude::*; use yew_router::prelude::use_navigator; use crate::{ + api::backend::delete_unit, pages::admin::edit::{EditItem, EditType}, - routes::main_router::Route, api::backend::delete_unit, + routes::main_router::Route, }; #[function_component(AdminUnit)] @@ -20,7 +21,7 @@ pub fn admin_unit(props: &AdminUnitProps) -> Html { format!("{price_separated}.00") } }); - + let delete_unit = { let is_attempting_delete = is_attempting_delete.clone(); let deletecb = props.deletecb.clone(); @@ -89,5 +90,5 @@ pub fn admin_unit(props: &AdminUnitProps) -> Html { pub struct AdminUnitProps { pub unit: Unit, pub index: usize, - pub deletecb: Callback + pub deletecb: Callback, } diff --git a/src/components/dropdown.rs b/src/components/dropdown.rs index 73549a2..942cea4 100644 --- a/src/components/dropdown.rs +++ b/src/components/dropdown.rs @@ -15,8 +15,6 @@ pub struct DropDownProps { pub onchange: Option>>, } - - #[function_component(DropDown)] pub fn dropdown( props: &DropDownProps, @@ -33,19 +31,19 @@ pub fn dropdown( .collect(); options.insert(0, None); - + options }, selection_changed: match props.onchange.clone() { Some(cb) => cb, - None => Callback::from(|_| {}) + None => Callback::from(|_| {}), }, class_css: Some("admin-dropdown".into()), - none_str: props.unpicked_text.clone() + none_str: props.unpicked_text.clone(), }, ); //if (*props.selected).is_none() {selection_changed_cb.emit( OptionWrapper::new((*props.selected).clone()));} html! { {drop_down} } -} \ No newline at end of file +} diff --git a/src/components/media_picker.rs b/src/components/media_picker.rs index 1db6b41..f39bef2 100644 --- a/src/components/media_picker.rs +++ b/src/components/media_picker.rs @@ -1,4 +1,4 @@ -use jl_types::domain::media::{Media, MediaList}; +use jl_types::{domain::media::{Media, MediaList}, dto::item::Item}; use js_sys::Uint8Array; use wasm_bindgen_futures::JsFuture; use yew::prelude::*; @@ -12,7 +12,11 @@ use crate::{ pub fn media_picker(props: &MediaPickerProps) -> Html { html! { <> -
{"Media del proyecto"}
+
{format!("Media {}", match props.item { + Item::Project => "del Proyecto", + Item::Unit => "de la Unidad", + Item::Agent => "del Agente" + })}
diff --git a/src/components/mod.rs b/src/components/mod.rs index 87f4189..0b18c99 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -12,7 +12,7 @@ pub mod media_picker; pub mod media_slideshow; pub mod nav_bar; pub mod new_widget; +pub mod number_textfield; pub mod project_card; -pub mod textfield; pub mod single_media_picker; -pub mod number_textfield; \ No newline at end of file +pub mod textfield; diff --git a/src/components/number_textfield.rs b/src/components/number_textfield.rs index ec72e61..85fbe58 100644 --- a/src/components/number_textfield.rs +++ b/src/components/number_textfield.rs @@ -1,8 +1,7 @@ - +use std::{fmt::Display, str::FromStr}; use wasm_bindgen::{JsCast, UnwrapThrowExt}; -use web_sys::{HtmlInputElement}; +use web_sys::HtmlInputElement; use yew::prelude::*; -use std::{str::FromStr, fmt::{Display}}; #[derive(Properties, PartialEq, Clone)] pub struct NumberTextFieldProps { @@ -14,23 +13,26 @@ pub struct NumberTextFieldProps(props: &NumberTextFieldProps) -> Html { +pub fn number_textfield( + props: &NumberTextFieldProps, +) -> Html { let on_input_changed = { let handle = props.value.clone(); let onchange = props.onchange.clone(); Callback::from(move |e: InputEvent| { - let value = match get_number_value_from_input_event::(e) { - Ok(float) => float, - Err(_) => { - log::error!("Error ocurred attempting to parse number on input type number. This only happens in firefox browsers."); - T::default() - }}; - match onchange.clone() { - Some(onchange) => onchange.emit(value.clone()), - None => {} - }; - handle.set(value); - }) + let value = match get_number_value_from_input_event::(e) { + Ok(float) => float, + Err(_) => { + log::error!("Error ocurred attempting to parse number on input type number. This only happens in firefox browsers."); + T::default() + } + }; + match onchange.clone() { + Some(onchange) => onchange.emit(value.clone()), + None => {} + }; + handle.set(value); + }) }; html! {
@@ -48,4 +50,4 @@ pub fn get_number_value_from_input_event(e: InputEvent) -> Result Ok(t), Err(_) => Err(()), } -} \ No newline at end of file +} diff --git a/src/components/single_media_picker.rs b/src/components/single_media_picker.rs index 7566ae5..32d66a7 100644 --- a/src/components/single_media_picker.rs +++ b/src/components/single_media_picker.rs @@ -2,10 +2,7 @@ use js_sys::Uint8Array; use wasm_bindgen_futures::JsFuture; use yew::prelude::*; -use crate::{ - api, - components::textfield::{get_files_from_input_event}, -}; +use crate::{api, components::textfield::get_files_from_input_event}; #[derive(PartialEq, Properties, Clone)] pub struct SingleMediaPickerProps { @@ -102,9 +99,8 @@ pub fn single_media_picker(props: &SingleMediaPickerProps) -> Html { } } } - +
} } - diff --git a/src/pages/admin/edit.rs b/src/pages/admin/edit.rs index 087a320..293c342 100644 --- a/src/pages/admin/edit.rs +++ b/src/pages/admin/edit.rs @@ -5,13 +5,9 @@ use yew::prelude::*; use yew_router::prelude::use_navigator; use crate::{ - api::backend::{ - get_project_listing, get_agent_with_id, get_unit_with_id, - }, - components::{ - admin_nav_bar::AdminNavigationBar, - }, - pages::admin::{fields::{project::ProjectFields, unit::UnitFields, agent::AgentFields}}, + api::backend::{get_agent_with_id, get_project_listing}, + components::admin_nav_bar::AdminNavigationBar, + pages::admin::fields::{agent::AgentFields, project::ProjectFields, unit::UnitFields}, }; /// All of the editing actions of the admin panel will lead to here. This should take an id of anything. A unit, a project, an agent. And its corresponding ID. @@ -20,11 +16,9 @@ pub fn edit_page(props: &AdminEditPageProps) -> Html { let _navigator = use_navigator().unwrap(); let listing = use_state(|| None); let agent = use_state(|| None); - let unit = use_state(|| None); use_state(|| { let listing = listing.clone(); let agent = agent.clone(); - let unit = unit.clone(); match props.edit_item { EditItem::Agent => { match props.edit_type { @@ -61,17 +55,7 @@ pub fn edit_page(props: &AdminEditPageProps) -> Html { EditItem::Unit(_) => { match props.edit_type { EditType::New => {} - EditType::Existing(uid) => { - wasm_bindgen_futures::spawn_local(async move { - let unit_result = get_unit_with_id(&uid).await; - match unit_result { - Ok(unit_persisted) => { - unit.set(Some(unit_persisted)); - } - Err(error) => log::error!("Error loading unit: {error}"), - }; - }); - } + EditType::Existing(_) => {} }; } } @@ -97,7 +81,7 @@ pub fn edit_page(props: &AdminEditPageProps) -> Html { match props.edit_item { EditItem::Agent => { html! { } }, EditItem::Project => { html! { } }, - EditItem::Unit(project_id) => { html! { } }, + EditItem::Unit(project_id) => { html! { } }, } } diff --git a/src/pages/admin/fields/agent.rs b/src/pages/admin/fields/agent.rs index 6c0e87f..917ce3c 100644 --- a/src/pages/admin/fields/agent.rs +++ b/src/pages/admin/fields/agent.rs @@ -1,8 +1,18 @@ -use jl_types::{domain::{agent::Agent, credential::CredentialType}, dto::payloads::agent::{NewAgentPayload, UpdateAgentPayload}}; +use jl_types::{ + domain::{agent::Agent, credential::CredentialType}, + dto::payloads::agent::{NewAgentPayload, UpdateAgentPayload}, +}; use yew::prelude::*; use yew_router::prelude::use_navigator; -use crate::{pages::admin::edit::{EditType}, components::{textfield::TextField, dropdown::DropDown, single_media_picker::SingleMediaPicker}, api::backend::{update_agent, create_new_agent}, routes::main_router::Route, }; +use crate::{ + api::backend::{create_new_agent, update_agent}, + components::{ + dropdown::DropDown, single_media_picker::SingleMediaPicker, textfield::TextField, + }, + pages::admin::edit::EditType, + routes::main_router::Route, +}; #[derive(Properties, PartialEq, Clone)] pub struct AgentFieldsProps { @@ -47,14 +57,12 @@ pub fn agent_fields(props: &AgentFieldsProps) -> Html { None => String::new(), }); profile_picture_url_handle.set(match agent_opt.clone() { - Some(agent) => { - agent.profile_picture_url - }, + Some(agent) => agent.profile_picture_url, None => String::new(), }); credential_type.set(match agent_opt.clone() { Some(agent) => Some(agent.credential_type), - None => None + None => None, }); credential_handle.set(match agent_opt.clone() { Some(agent) => agent.credential, @@ -96,48 +104,48 @@ pub fn agent_fields(props: &AgentFieldsProps) -> Html { let agent_name = (*agent_name_handle).clone(); let profile_picture_url = (*profile_picture_url_handle).clone(); let credential = (*credential_handle).clone(); - let credential_type = if let Some(credential_type) = (*credential_type_handle).clone(){ - credential_type - } else { - log::error!("Missing field credential_type"); - return; - }; + let credential_type = + if let Some(credential_type) = (*credential_type_handle).clone() { + credential_type + } else { + log::error!("Missing field credential_type"); + return; + }; match edit_type { EditType::New => { let agent = NewAgentPayload { credential, credential_type, full_name: agent_name, - profile_picture_url + profile_picture_url, }; match create_new_agent(agent).await { Ok(_) => navigator.push(&Route::AdminAgents), - Err(error) => log::error!("Error updating agent: {error}") + Err(error) => log::error!("Error updating agent: {error}"), }; - }, + } EditType::Existing(id) => { let agent = UpdateAgentPayload { id, credential: Some(credential), credential_type: Some(credential_type), full_name: Some(agent_name), - profile_picture_url: Some(profile_picture_url) + profile_picture_url: Some(profile_picture_url), }; match update_agent(agent).await { Ok(_) => navigator.push(&Route::AdminAgents), - Err(error) => log::error!("Error updating agent: {error}") + Err(error) => log::error!("Error updating agent: {error}"), }; } }; - }); }) }; html! { <> - + - + {if (*credential_type).clone().is_none() { match props.edittype.clone() { EditType::New => html! { @@ -179,7 +187,7 @@ pub fn agent_fields(props: &AgentFieldsProps) -> Html {
{"Actualizar"}
- + } -} \ No newline at end of file +} diff --git a/src/pages/admin/fields/mod.rs b/src/pages/admin/fields/mod.rs index 8173d63..4cc23e7 100644 --- a/src/pages/admin/fields/mod.rs +++ b/src/pages/admin/fields/mod.rs @@ -1,3 +1,3 @@ +pub mod agent; pub mod project; pub mod unit; -pub mod agent; \ No newline at end of file diff --git a/src/pages/admin/fields/project.rs b/src/pages/admin/fields/project.rs index 6efb140..3370843 100644 --- a/src/pages/admin/fields/project.rs +++ b/src/pages/admin/fields/project.rs @@ -1,10 +1,39 @@ use chrono::NaiveTime; -use jl_types::{dto::{listing::Listing, payloads::{location::NewLocationPayload, project::{UpdateProjectPayload, NewProjectPayload}}}, domain::{agent::Agent, media::MediaList, unit::Unit, project_condition::ProjectCondition, project_type::ProjectType, project_state::ProjectState}}; +use jl_types::{ + domain::{ + agent::Agent, media::MediaList, project_condition::ProjectCondition, + project_state::ProjectState, project_type::ProjectType, unit::Unit, + }, + dto::{ + listing::Listing, + payloads::{ + location::NewLocationPayload, + project::{NewProjectPayload, UpdateProjectPayload}, + }, + }, +}; +use std::str::FromStr; use yew::prelude::*; use yew_router::prelude::use_navigator; -use std::str::FromStr; -use crate::{pages::admin::{edit::{EditType, EditItem}, units::AdminUnits}, api::backend::{get_all_agents, get_location_with_city_and_district, create_location, create_new_project, update_project}, routes::main_router::Route, components::{new_widget::NewThingWidget, dropdown::DropDown, media_picker::MediaPicker, textfield::{TextField, TextFieldType}, datepicker::DatePicker}}; +use crate::{ + api::backend::{ + create_location, create_new_project, get_all_agents, get_location_with_city_and_district, + update_project, + }, + components::{ + datepicker::DatePicker, + dropdown::DropDown, + media_picker::MediaPicker, + new_widget::NewThingWidget, + textfield::{TextField, TextFieldType}, + }, + pages::admin::{ + edit::{EditItem, EditType}, + units::AdminUnits, + }, + routes::main_router::Route, +}; #[derive(Properties, PartialEq, Clone)] pub struct ProjectFieldsProps { @@ -93,9 +122,7 @@ pub fn generate_fields_for_project(props: &ProjectFieldsProps) -> Html { }); project_state.set(match listing_opt.clone() { Some(listing) => Some(listing.project.project_state), - None => { - None - }, + None => None, }); project_condition.set(match listing_opt.clone() { Some(listing) => Some(listing.project.project_condition), @@ -427,4 +454,4 @@ pub fn generate_fields_for_project(props: &ProjectFieldsProps) -> Html { } -} \ No newline at end of file +} diff --git a/src/pages/admin/fields/unit.rs b/src/pages/admin/fields/unit.rs index 8e1ba80..550cbce 100644 --- a/src/pages/admin/fields/unit.rs +++ b/src/pages/admin/fields/unit.rs @@ -1,36 +1,253 @@ -use jl_types::domain::{unit::Unit, unit_type::UnitType}; +use jl_types::{domain::{media::MediaList, unit_type::UnitType}, dto::payloads::unit::{NewUnitPayload, UpdateUnitPayload}}; use uuid::Uuid; use yew::prelude::*; use yew_router::prelude::use_navigator; -use crate::{pages::admin::edit::EditType, components::number_textfield::NumberTextField}; +use crate::{ + components::{dropdown::DropDown, number_textfield::NumberTextField, media_picker::MediaPicker, textfield::{TextField, TextFieldType}}, + pages::admin::edit::EditType, api::backend::{get_unit_with_id, create_new_unit, update_unit}, routes::main_router::Route, +}; #[derive(Properties, PartialEq, Clone)] pub struct UnitFieldsProps { - pub unit: Option, pub edittype: EditType, - pub projectid: Option, + pub projectid: Uuid, } #[function_component(UnitFields)] pub fn unit_fields(props: &UnitFieldsProps) -> Html { + + let unit_opt = use_state(|| None); + { + let unit_opt = unit_opt.clone(); + use_state(move || { + if let EditType::Existing(id) = props.edittype.clone() { + wasm_bindgen_futures::spawn_local(async move { + let unit_result = get_unit_with_id(&id).await; + match unit_result { + Ok(unit_persisted) => { + unit_opt.set(Some(unit_persisted)); + } + Err(error) => log::error!("Error loading unit: {error}"), + }; + }); + } + }); + } + + + let navigator = use_navigator().unwrap(); let user_typed = use_state(|| false); + let edit_type = props.edittype.clone(); + let project_id = props.projectid.clone(); + + let ontype_cb = { + let user_typed = user_typed.clone(); + Callback::from(move |_: String| { + user_typed.set(true); + }) + }; + let onselect_cb = { + let user_typed = user_typed.clone(); + Callback::from(move |_| { + user_typed.set(true); + }) + }; + let onchange_number_cb = { + let user_typed = user_typed.clone(); + Callback::from(move |_| { + user_typed.set(true); + }) + }; + let onchange_number_cb_2 = { + let user_typed = user_typed.clone(); + Callback::from(move |_| { + user_typed.set(true); + }) + }; + let onchange_number_cb_3 = { + let user_typed = user_typed.clone(); + Callback::from(move |_| { + user_typed.set(true); + }) + }; // Fields - let price_usd = use_state(|| 0.0); - let unit_type_handle: UseStateHandle> = use_state(|| None); - let rooms_handle: UseStateHandle = use_state(|| 0); - let bathrooms_handle: UseStateHandle = use_state(|| 0); - let area_handle: UseStateHandle = use_state(|| 0.0); - let a = 0.0; - let b = a as i32; + let price_usd = use_state_eq(|| 0.0); + let unit_type_handle: UseStateHandle> = use_state_eq(|| None); + let rooms_handle: UseStateHandle = use_state_eq(|| 0); + let bathrooms_handle: UseStateHandle = use_state_eq(|| 0); + let area_handle: UseStateHandle = use_state_eq(|| 0.0); + let media_handle: UseStateHandle = use_state_eq(|| MediaList { + media_list: Vec::new(), + }); + let unit_admin_tag_handle: UseStateHandle = use_state_eq(|| String::new()); + let unit_description_handle = use_state_eq(|| String::new()); + + if !*user_typed { + price_usd.set(match (*unit_opt).clone() { + Some(unit) => unit.price_usd, + None => 0.0, + }); + unit_type_handle.set(match (*unit_opt).clone() { + Some(unit) => Some(unit.unit_type), + None => None + }); + media_handle.set(match (*unit_opt).clone() { + Some(unit) => unit.media, + None => MediaList { + media_list: Vec::new(), + }, + }); + rooms_handle.set(match (*unit_opt).clone() { + Some(unit) => unit.rooms, + None => 0 + }); + bathrooms_handle.set(match (*unit_opt).clone() { + Some(unit) => unit.bathrooms, + None => 0 + }); + area_handle.set(match (*unit_opt).clone() { + Some(unit) => unit.area, + None => 0.0 + }); + unit_description_handle.set(match (*unit_opt).clone() { + Some(unit) => unit.description, + None => String::new(), + }); + unit_admin_tag_handle.set(match (*unit_opt).clone() { + Some(unit) => match unit.admin_tag { + Some(admin_tag) => admin_tag, + None => String::new() + }, + None => String::new(), + }); + } + let update_button_onclick = { + let navigator = navigator.clone(); + let edit_type = edit_type.clone(); + let project_id = project_id.clone(); + + let price_usd = price_usd.clone(); + let unit_type_handle: UseStateHandle> = unit_type_handle.clone(); + let rooms_handle: UseStateHandle = rooms_handle.clone(); + let bathrooms_handle: UseStateHandle = bathrooms_handle.clone(); + let area_handle: UseStateHandle = area_handle.clone(); + let media_handle: UseStateHandle = media_handle.clone(); + let unit_admin_tag_handle: UseStateHandle = unit_admin_tag_handle.clone(); + let unit_description_handle = unit_description_handle.clone(); + Callback::from(move |_: MouseEvent| { + let navigator = navigator.clone(); + let edit_type = edit_type.clone(); + let project_id = project_id.clone(); + + let price_usd = price_usd.clone(); + let unit_type_handle: UseStateHandle> = unit_type_handle.clone(); + let rooms_handle: UseStateHandle = rooms_handle.clone(); + let bathrooms_handle: UseStateHandle = bathrooms_handle.clone(); + let area_handle: UseStateHandle = area_handle.clone(); + let media_handle: UseStateHandle = media_handle.clone(); + let unit_admin_tag_handle: UseStateHandle = unit_admin_tag_handle.clone(); + let unit_description_handle = unit_description_handle.clone(); + wasm_bindgen_futures::spawn_local(async move { + let price_usd = (*price_usd).clone(); + let unit_type = match (*unit_type_handle).clone() { + Some(unit_type) => unit_type, + None => { + log::error!("Missing field unit_type"); + return; + } + }; + let rooms = (*rooms_handle).clone(); + let bathrooms = (*bathrooms_handle).clone(); + let area = (*area_handle).clone(); + let media = (*media_handle).clone(); + let unit_admin_tag_val = (*unit_admin_tag_handle).clone(); + let admin_tag = if unit_admin_tag_val.is_empty() { None } else { Some(unit_admin_tag_val) }; + let description = (*unit_description_handle).clone(); + + match edit_type { + EditType::New => { + let payload = NewUnitPayload { + project_id, + price_usd, + unit_type, + rooms, + bathrooms, + area, + admin_tag, + media, + description + }; + match create_new_unit(payload).await { + Ok(_) => navigator.clone().push(&Route::AdminProjects), + Err(error) => log::error!("Error creating new unit: {error}"), + }; + }, + EditType::Existing(id) => { + let payload = UpdateUnitPayload { + id, + price_usd: Some(price_usd), + unit_type: Some(unit_type), + rooms: Some(rooms), + bathrooms: Some(bathrooms), + area: Some(area), + admin_tag: Some(admin_tag), + media: Some(media), + description: Some(description) + }; + match update_unit(payload).await { + Ok(_) => navigator.clone().push(&Route::AdminProjects), + Err(error) => log::error!("Error creating new unit: {error}"), + }; + } + }; + }); + }) + }; html! { <> - label={String::from("Precio en USD")} required={true} value={price_usd.clone()}/> - label={String::from("Area en m^2")} required={true} value={area_handle.clone()}/> - label={String::from("Cant. de habitaciones")} required={true} value={rooms_handle.clone()}/> - label={String::from("Cant. de baños")} required={true} value={bathrooms_handle.clone()}/> + label={String::from("Precio en USD")} required={true} value={price_usd.clone()} onchange={onchange_number_cb}/> + label={String::from("Area en m^2")} required={true} value={area_handle.clone()} onchange={onchange_number_cb_2}/> + label={String::from("Cant. de habitaciones")} required={true} value={rooms_handle.clone()} onchange={onchange_number_cb_3.clone()}/> + label={String::from("Cant. de baños")} required={true} value={bathrooms_handle.clone()} onchange={onchange_number_cb_3}/> + + + // Unit type dropdown + {if (*unit_type_handle).clone().is_none() { + match props.edittype.clone() { + EditType::New => html! { +
+
{"Tipo de Unidad"}
+ selected={unit_type_handle} options={vec![UnitType::ForSale, UnitType::NotForSale] } onchange={onselect_cb} /> +
+ }, + EditType::Existing(_) => if *user_typed { + html! { +
+
{"Tipo de Unidad"}
+ selected={unit_type_handle} options={vec![UnitType::ForSale, UnitType::NotForSale] } onchange={onselect_cb} /> +
+ } + } else { + html! {} + } + } + } else { + html! { +
+
{"Tipo de Unidad"}
+ selected={unit_type_handle} options={vec![UnitType::ForSale, UnitType::NotForSale] } onchange={onselect_cb} /> +
+ } + } + } + + +
+ {"Actualizar"} +
} } diff --git a/src/pages/admin/mod.rs b/src/pages/admin/mod.rs index 9f024e8..2c7fd31 100644 --- a/src/pages/admin/mod.rs +++ b/src/pages/admin/mod.rs @@ -1,8 +1,8 @@ pub mod agents; pub mod contacts; pub mod edit; +pub mod fields; pub mod login; pub mod projects; pub mod start; pub mod units; -pub mod fields; \ No newline at end of file diff --git a/src/pages/admin/units.rs b/src/pages/admin/units.rs index b3e930f..5d71d93 100644 --- a/src/pages/admin/units.rs +++ b/src/pages/admin/units.rs @@ -5,7 +5,6 @@ use crate::components::admin_unit::AdminUnit; #[function_component(AdminUnits)] pub fn admin_units(props: &AdminUnitProps) -> Html { - let units_handle = props.units.clone(); html! {
@@ -38,5 +37,5 @@ pub fn admin_units(props: &AdminUnitProps) -> Html { #[derive(PartialEq, Properties, Clone)] pub struct AdminUnitProps { pub units: UseStateHandle>, - pub onchange: Option>, + pub onchange: Option>, } diff --git a/src/pages/search.rs b/src/pages/search.rs index 4b0b134..7d1f1d2 100644 --- a/src/pages/search.rs +++ b/src/pages/search.rs @@ -10,7 +10,9 @@ use crate::{ api::backend::{ get_all_cities, get_all_districts_in_city, get_all_projects_with_filters_paged, }, - components::{footer::PageFooter, nav_bar::NavigationBar, project_card::ProjectCard, dropdown::DropDown}, + components::{ + dropdown::DropDown, footer::PageFooter, nav_bar::NavigationBar, project_card::ProjectCard, + }, }; #[function_component(SearchPage)] @@ -31,10 +33,7 @@ pub fn search_page() -> Html { wasm_bindgen_futures::spawn_local(async move { match get_all_cities().await { Ok(cities) => { - let cities: Vec = cities - .into_iter() - .map(|location| location) - .collect(); + let cities: Vec = cities.into_iter().map(|location| location).collect(); cities_handle.set(cities); } Err(error) => log::error!("Error in loading cities: {error}"), @@ -55,19 +54,14 @@ pub fn search_page() -> Html { }); // Dropdown - let project_type_filter: UseStateHandle> = - use_state(|| None); + let project_type_filter: UseStateHandle> = use_state(|| None); // Dropdown - let project_condition_filter: UseStateHandle> = - use_state(|| None); + let project_condition_filter: UseStateHandle> = use_state(|| None); // Dropdown - let project_city_filter: UseStateHandle> = - use_state(|| None); + let project_city_filter: UseStateHandle> = use_state(|| None); // Dropdown - let project_district_filter: UseStateHandle> = - use_state(|| None); - let unit_rooms_filter: UseStateHandle> = - use_state(|| None); + let project_district_filter: UseStateHandle> = use_state(|| None); + let unit_rooms_filter: UseStateHandle> = use_state(|| None); let search_onclick = { let search_results_handle = search_results_handle.clone(); @@ -167,7 +161,7 @@ pub fn search_page() -> Html { let cloned_project_type_filter = project_type_filter.clone(); Callback::from(move |project_type: Option| { cloned_project_type_filter.set(project_type) - })} + })} options={ vec![ProjectType::Apartamento, ProjectType::Casa, ProjectType::Oficina, ProjectType::Local, ProjectType::Solar] } />
@@ -187,7 +181,7 @@ pub fn search_page() -> Html { let cloned_project_condition_filter = project_condition_filter.clone(); Callback::from(move |project_condition: Option| { cloned_project_condition_filter.set(project_condition) - })} + })} options={ vec![ProjectCondition::New, ProjectCondition::Resale]} /> @@ -226,7 +220,7 @@ pub fn search_page() -> Html { let project_district_filter = project_district_filter.clone(); Callback::from(move |project_district: Option| { project_district_filter.set(project_district) - })} + })} options={ (*districts_handle).clone() } /> @@ -238,7 +232,7 @@ pub fn search_page() -> Html { let unit_rooms_filter = unit_rooms_filter.clone(); Callback::from(move |unit_rooms: Option| { unit_rooms_filter.set(unit_rooms) - })} + })} options={ (1..10).collect::>() } />