Finished unit description, changed feature to a component and added it all over the DetailsPage

This commit is contained in:
Franklin 2023-03-27 06:30:13 -04:00
parent a4229ff451
commit 42a97376a0
5 changed files with 167 additions and 123 deletions

View File

@ -69,8 +69,7 @@
left: 10px; left: 10px;
background-color: rgba(0, 0, 0, 0.633); background-color: rgba(0, 0, 0, 0.633);
border-radius: 5px; border-radius: 5px;
} }
/* Fading animation */ /* Fading animation */
.fade { .fade {

View File

@ -203,4 +203,25 @@ Divide the Details page into 3 main sections:
height: 360px; height: 360px;
background-color: rgba(128, 128, 128, 0.151); background-color: rgba(128, 128, 128, 0.151);
border-radius: 20px; border-radius: 20px;
} }
.details-body-units-description {
width: 100%;
font-size: 14px;
font-family: Inter;
line-height: 30px;
white-space: pre-line;
color: rgba(34, 34, 34, 0.873);
}
.details-body-unit-features {
display: flex;
flex-direction: column;
justify-content: stretch;
align-items: start;
gap: 25px;
width: 100%;
height: 200px;
margin-bottom: 60px;
}

30
src/components/feature.rs Normal file
View File

@ -0,0 +1,30 @@
use yew::prelude::*;
#[function_component(FeatureItem)]
pub fn feature_item(props: &FeatureItemProps) -> Html {
let props = props.clone();
html!{
<div class={"details-body-feature-item"}>
<div class={"details-body-feature-item-icon-container"}>
<i class={props.icon}></i>
</div>
<div class={"details-body-feature-item-text-container"}>
<div class={"details-body-feature-item-text-title"}>
{props.title}
</div>
<div class={"details-body-feature-item-text-subtitle"}>
{
props.subtitle
}
</div>
</div>
</div>
}
}
#[derive(Properties, PartialEq, Clone)]
pub struct FeatureItemProps {
pub title: String,
pub subtitle: String,
pub icon: String,
}

View File

@ -2,4 +2,5 @@ pub mod nav_bar;
pub mod search_filter; pub mod search_filter;
pub mod project_card; pub mod project_card;
pub mod media_slideshow; pub mod media_slideshow;
pub mod floating_widget; pub mod floating_widget;
pub mod feature;

View File

@ -1,9 +1,10 @@
use jl_types::{dto::listing::Listing, domain::unit_type::UnitType}; use jl_types::{dto::listing::Listing, domain::unit_type::UnitType};
use log::{error, info}; use log::{error, info};
use thousands::Separable;
use uuid::Uuid; use uuid::Uuid;
use yew::prelude::*; use yew::prelude::*;
use crate::{components::{nav_bar::NavigationBar, media_slideshow::MediaSlideshow, floating_widget::FloatingWidget}, api::backend::get_project_listing}; use crate::{components::{nav_bar::NavigationBar, media_slideshow::MediaSlideshow, floating_widget::FloatingWidget, feature::FeatureItem}, api::backend::get_project_listing};
#[function_component(DetailsPage)] #[function_component(DetailsPage)]
pub fn details_page(props: &DetailsPageProps) -> Html { pub fn details_page(props: &DetailsPageProps) -> Html {
@ -34,15 +35,16 @@ pub fn details_page(props: &DetailsPageProps) -> Html {
let project_title = format!("{} en {}, {}", &listing.project.project_type, &listing.location.district, &listing.location.city); let project_title = format!("{} en {}, {}", &listing.project.project_type, &listing.location.district, &listing.location.city);
//let project_description = &listing.project.description; //let project_description = &listing.project.description;
let project_media_list = listing.project.media.media_list; let project_media_list = listing.project.media.media_list;
let project_type = &listing.project.project_type.to_string(); let project_type = listing.project.project_type.to_string();
let project_condition = &listing.project.project_condition.to_string(); let project_condition = listing.project.project_condition.to_string();
let project_est_finish_date = format!("{} {}", listing.project.finish_date.format("%m/%Y"), if listing.project.finish_date.timestamp_millis() <= chrono::Utc::now().timestamp_millis() { let project_est_finish_date = format!("{} {}", listing.project.finish_date.format("%m/%Y"), if listing.project.finish_date.timestamp_millis() <= chrono::Utc::now().timestamp_millis() {
"(Listo)" "(Listo)"
} else {""}); } else {""});
let project_floors = &listing.project.floors.to_string(); let project_floors = listing.project.floors.to_string();
let cloned_selected_unit_handle = selected_unit_handle.clone(); let cloned_selected_unit_handle = selected_unit_handle.clone();
//TODO: Floating whatsapp button on this page
let selected_unit_opt = listing.units.get(*cloned_selected_unit_handle);
html!{ html!{
<> <>
<NavigationBar/> <NavigationBar/>
@ -90,63 +92,10 @@ pub fn details_page(props: &DetailsPageProps) -> Html {
// //
<div class={"details-body-features"}> <div class={"details-body-features"}>
<div class={"details-body-feature-item"}> <FeatureItem title={"Fecha de entrega"} icon={"fa-solid fa-person-digging"} subtitle={project_est_finish_date}/>
<div class={"details-body-feature-item-icon-container"}> <FeatureItem title={"Condición de venta"} icon={"fa-solid fa-handshake"} subtitle={project_condition}/>
<i class="fa-solid fa-person-digging"></i> <FeatureItem title={"Tipo de Proyecto"} icon={"fa-solid fa-house-chimney"} subtitle={project_type}/>
</div> <FeatureItem title={"Cant. de Pisos"} icon={"fa-solid fa-building"} subtitle={project_floors}/>
<div class={"details-body-feature-item-text-container"}>
<div class={"details-body-feature-item-text-title"}>
{"Fecha de entrega"}
</div>
<div class={"details-body-feature-item-text-subtitle"}>
{project_est_finish_date}
</div>
</div>
</div>
<div class={"details-body-feature-item"}>
<div class={"details-body-feature-item-icon-container"}>
<i class="fa-solid fa-handshake"></i>
</div>
<div class={"details-body-feature-item-text-container"}>
<div class={"details-body-feature-item-text-title"}>
{"Condición de venta"}
</div>
<div class={"details-body-feature-item-text-subtitle"}>
{project_condition}
</div>
</div>
</div>
<div class={"details-body-feature-item"}>
<div class={"details-body-feature-item-icon-container"}>
<i class="fa-solid fa-house-chimney"></i>
</div>
<div class={"details-body-feature-item-text-container"}>
<div class={"details-body-feature-item-text-title"}>
{"Tipo de Proyecto"}
</div>
<div class={"details-body-feature-item-text-subtitle"}>
{project_type}
</div>
</div>
</div>
<div class={"details-body-feature-item"}>
<div class={"details-body-feature-item-icon-container"}>
<i class="fa-solid fa-building"></i>
</div>
<div class={"details-body-feature-item-text-container"}>
<div class={"details-body-feature-item-text-title"}>
{"Cant. de Pisos"}
</div>
<div class={"details-body-feature-item-text-subtitle"}>
{project_floors}
</div>
</div>
</div>
</div> </div>
<div class={"details-body-divider"}></div> <div class={"details-body-divider"}></div>
@ -155,67 +104,109 @@ pub fn details_page(props: &DetailsPageProps) -> Html {
// Units part // Units part
// //
<div class={"details-body-units"}> { // If units don't exist then don't show anything
<div class={"details-body-units-title"}>{"Unidades"}</div> if let Some(unit) = selected_unit_opt {
<div class={"details-body-units-selection-container"}>
{// Maps all the units to generate the unit selection menu html! {
listing.units.iter().enumerate().map(|(index, unit)| { <div class={"details-body-units"}>
let cloned_selected_unit_handle = cloned_selected_unit_handle.clone(); <div class={"details-body-units-title"}>{"Unidades"}</div>
let select_unit_onclick_cb = { <div class={"details-body-units-selection-container"}>
let cloned_selected_unit_handle = cloned_selected_unit_handle.clone(); { // Maps all the units to generate the unit selection menu
Callback::from(move |_| cloned_selected_unit_handle.set(index)) listing.units.iter().enumerate().map(|(index, unit)| {
}; let cloned_selected_unit_handle = cloned_selected_unit_handle.clone();
html! { let select_unit_onclick_cb = {
<div class={ let cloned_selected_unit_handle = cloned_selected_unit_handle.clone();
if *cloned_selected_unit_handle == index Callback::from(move |_| cloned_selected_unit_handle.set(index))
{"details-body-units-selection-item-selected"} };
else html! {
{"details-body-units-selection-item-unselected"} <div class={
} onclick={select_unit_onclick_cb}> if *cloned_selected_unit_handle == index
{ {"details-body-units-selection-item-selected"}
match unit.unit_type { else
UnitType::ForSale => html! { {"details-body-units-selection-item-unselected"}
<> } onclick={select_unit_onclick_cb}>
<i class="fa-solid fa-house-circle-check"></i> {
<div>{format!("Unidad {}", index + 1)}</div> match unit.unit_type {
</> UnitType::ForSale => html! {
}, <>
UnitType::NotForSale => html! { <i class="fa-solid fa-house-circle-check"></i>
<> <div>{format!("Unidad {}", index + 1)}</div>
<i class="fa-solid fa-people-group"></i> </>
<div>{"Área común"}</div> },
</> UnitType::NotForSale => html! {
} <>
<i class="fa-solid fa-people-group"></i>
<div>{"Área común"}</div>
</>
}
}
}
</div>
}
}).collect::<Html>()
}
</div>
<div class={"details-body-units-media-slideshow-frame"}>
{
if unit.media.media_list.len() >= 1 {
html! {
<MediaSlideshow media_list={unit.media.media_list.clone()}/>
}
} else {
html! {
<div>{"No existen imágenes para esta Unidad."}</div>
} }
} }
</div>
}
}).collect::<Html>()
}
</div>
<div class={"details-body-units-media-slideshow-frame"}>
{
if let Some(unit) = listing.units.get(*cloned_selected_unit_handle) {
if unit.media.media_list.len() >= 1 {
html! {
<MediaSlideshow media_list={unit.media.media_list.clone()}/>
} }
} else { </div>
html! {
<div>{"No existen imágenes para esta Unidad."}</div>
}
}
} else { <div class={"details-body-units-description"}>
html! { {
<div>{"Esta unidad no existe. Esto No debería estar pasando."}</div> if unit.description.len() == 0 {
} "Esta unidad No tiene Descripción.".into()
} } else {
unit.description.clone()
}
}
</div>
<div class={"details-body-divider"}></div>
<div class={"details-body-unit-features"}>
{ // Features only to be shown on a ForSale unit
if unit.unit_type == UnitType::ForSale {
let price_separated = unit.price_usd.separate_with_commas();
html! {
<>
<FeatureItem title={"Inversión"} icon={"fa-solid fa-money-bill-trend-up"} subtitle={
if price_separated.contains(".") {
format!("${} USD", price_separated)
} else {
format!("${} USD", format!("{price_separated}.00"))
}
}/>
<FeatureItem title={"Habitaciones"} icon={"fa-solid fa-bed"} subtitle={format!("{}", unit.rooms)}/>
<FeatureItem title={"Baños"} icon={"fa-solid fa-bath"} subtitle={format!("{}", unit.bathrooms)}/>
</>
}
} else {html! {}}
}
// Features that always are shown
<FeatureItem title={"Metraje"} icon={"fa-solid fa-ruler-combined"} subtitle={format!("{}", unit.area)}/>
</div>
</div>
} }
</div> } else {
</div> html!{
<h2>{"Este proyecto no tiene unidades registradas."}</h2>
}
}
}
</div> </div>
</div> </div>
} }
@ -237,4 +228,6 @@ pub fn details_page(props: &DetailsPageProps) -> Html {
#[derive(Properties, PartialEq)] #[derive(Properties, PartialEq)]
pub struct DetailsPageProps { pub struct DetailsPageProps {
pub project_id: Uuid pub project_id: Uuid
} }