Moved ProjectFields to different module. FINALLY
This commit is contained in:
parent
58c18625b6
commit
b61a1c1f0b
@ -1,38 +1,17 @@
|
|||||||
use std::{fmt::Display, str::FromStr};
|
use std::{fmt::Display, str::FromStr};
|
||||||
|
|
||||||
use chrono::NaiveTime;
|
|
||||||
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 uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
use yew_router::prelude::use_navigator;
|
use yew_router::prelude::use_navigator;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::backend::{
|
api::backend::{
|
||||||
create_location, create_new_project, get_all_agents, get_location_with_city_and_district,
|
get_project_listing,
|
||||||
get_project_listing, update_project,
|
|
||||||
},
|
},
|
||||||
components::{
|
components::{
|
||||||
admin_nav_bar::AdminNavigationBar,
|
admin_nav_bar::AdminNavigationBar,
|
||||||
datepicker::DatePicker,
|
|
||||||
dropdown::DropDown,
|
|
||||||
media_picker::MediaPicker,
|
|
||||||
new_widget::NewThingWidget,
|
|
||||||
textfield::{TextField, TextFieldType},
|
|
||||||
},
|
},
|
||||||
pages::admin::units::AdminUnits,
|
pages::admin::{fields::project::ProjectFields},
|
||||||
routes::main_router::Route,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 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.
|
/// 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.
|
||||||
@ -114,393 +93,6 @@ pub struct AdminEditPageProps {
|
|||||||
pub edit_type: EditType,
|
pub edit_type: EditType,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Properties, PartialEq, Clone)]
|
|
||||||
pub struct ProjectFieldsProps {
|
|
||||||
pub listing: Option<Listing>,
|
|
||||||
pub edittype: EditType,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
#[function_component(ProjectFields)]
|
|
||||||
pub fn generate_fields_for_project(props: &ProjectFieldsProps) -> Html {
|
|
||||||
let navigator = use_navigator().unwrap();
|
|
||||||
let user_typed = use_state(|| false);
|
|
||||||
let listing_opt = props.listing.clone();
|
|
||||||
|
|
||||||
let location_city = use_state_eq(|| String::new());
|
|
||||||
let location_district = use_state_eq(|| String::new());
|
|
||||||
let agent: UseStateHandle<Option<Agent>> = use_state_eq(|| None);
|
|
||||||
let project_state = use_state_eq(|| None);
|
|
||||||
let project_condition = use_state_eq(|| None);
|
|
||||||
let project_type = use_state_eq(|| None);
|
|
||||||
let project_description = use_state_eq(|| String::new());
|
|
||||||
let project_admin_tag: UseStateHandle<String> = use_state_eq(|| String::new());
|
|
||||||
let project_finish_date = use_state_eq(|| None);
|
|
||||||
let project_floors = use_state_eq(|| String::new());
|
|
||||||
let media: UseStateHandle<MediaList> = use_state_eq(|| MediaList {
|
|
||||||
media_list: Vec::new(),
|
|
||||||
});
|
|
||||||
let units: UseStateHandle<Vec<Unit>> = use_state_eq(|| Vec::new());
|
|
||||||
|
|
||||||
let ontype_cb = {
|
|
||||||
let user_typed = user_typed.clone();
|
|
||||||
Callback::from(move |_| {
|
|
||||||
user_typed.set(true);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
let ontypedate_cb = {
|
|
||||||
let user_typed = user_typed.clone();
|
|
||||||
Callback::from(move |_| {
|
|
||||||
user_typed.set(true);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
let onselect_cb = {
|
|
||||||
let user_typed = user_typed.clone();
|
|
||||||
Callback::from(move |_| {
|
|
||||||
user_typed.set(true);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
let onselect_cb2 = {
|
|
||||||
let user_typed = user_typed.clone();
|
|
||||||
Callback::from(move |_| {
|
|
||||||
user_typed.set(true);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
let onselect_cb3 = {
|
|
||||||
let user_typed = user_typed.clone();
|
|
||||||
Callback::from(move |_| {
|
|
||||||
user_typed.set(true);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
let onselect_cb4 = {
|
|
||||||
let user_typed = user_typed.clone();
|
|
||||||
Callback::from(move |_| {
|
|
||||||
user_typed.set(true);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let all_agents = use_state(|| Vec::new());
|
|
||||||
|
|
||||||
use_state(|| {
|
|
||||||
let all_agents = all_agents.clone();
|
|
||||||
wasm_bindgen_futures::spawn_local(async move {
|
|
||||||
match get_all_agents().await {
|
|
||||||
Ok(persisted_agents) => all_agents.set(persisted_agents),
|
|
||||||
Err(error) => {
|
|
||||||
log::error!("Error fetching agents from admin panel edit screen: {error}")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if !*user_typed {
|
|
||||||
location_city.set(listing_opt.clone().unwrap_or_default().location.city);
|
|
||||||
location_district.set(listing_opt.clone().unwrap_or_default().location.district);
|
|
||||||
agent.set(match listing_opt.clone() {
|
|
||||||
Some(listing) => Some(listing.agent),
|
|
||||||
None => {
|
|
||||||
let agents = (*all_agents).clone();
|
|
||||||
if let Some(default_agent) = agents.last() {
|
|
||||||
Some(default_agent.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
project_state.set(match listing_opt.clone() {
|
|
||||||
Some(listing) => Some(listing.project.project_state),
|
|
||||||
None => {
|
|
||||||
Some(ProjectState::InConstruction)
|
|
||||||
},
|
|
||||||
});
|
|
||||||
project_condition.set(match listing_opt.clone() {
|
|
||||||
Some(listing) => Some(listing.project.project_condition),
|
|
||||||
None => {
|
|
||||||
Some(ProjectCondition::New)
|
|
||||||
},
|
|
||||||
});
|
|
||||||
project_type.set(match listing_opt.clone() {
|
|
||||||
Some(listing) => Some(listing.project.project_type),
|
|
||||||
None => {
|
|
||||||
Some(ProjectType::Solar)
|
|
||||||
},
|
|
||||||
});
|
|
||||||
project_description.set(match listing_opt.clone() {
|
|
||||||
Some(listing) => listing.project.description,
|
|
||||||
None => "".into(),
|
|
||||||
});
|
|
||||||
project_floors.set(match listing_opt.clone() {
|
|
||||||
Some(listing) => listing.project.floors.to_string(),
|
|
||||||
None => "".into(),
|
|
||||||
});
|
|
||||||
project_admin_tag.set(match listing_opt.clone() {
|
|
||||||
Some(listing) => match listing.project.admin_tag {
|
|
||||||
Some(admin_tag) => admin_tag,
|
|
||||||
None => String::new(),
|
|
||||||
},
|
|
||||||
None => String::new(),
|
|
||||||
});
|
|
||||||
project_finish_date.set(match listing_opt.clone() {
|
|
||||||
Some(listing) => Some(listing.project.finish_date.date()),
|
|
||||||
None => None,
|
|
||||||
});
|
|
||||||
media.set(match listing_opt.clone() {
|
|
||||||
Some(listing) => listing.project.media,
|
|
||||||
None => MediaList {
|
|
||||||
media_list: Vec::new(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
units.set(match listing_opt.clone() {
|
|
||||||
Some(listing) => listing.units,
|
|
||||||
None => Vec::new(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let update_button_onclick = {
|
|
||||||
let navigator = navigator.clone();
|
|
||||||
let edit_type = props.edittype.clone();
|
|
||||||
|
|
||||||
// All fields to be sent to the backend
|
|
||||||
let location_city = location_city.clone();
|
|
||||||
let location_district = location_district.clone();
|
|
||||||
let agent = agent.clone();
|
|
||||||
let project_state = project_state.clone();
|
|
||||||
let project_condition = project_condition.clone();
|
|
||||||
let project_type = project_type.clone();
|
|
||||||
let project_description = project_description.clone();
|
|
||||||
let project_admin_tag = project_admin_tag.clone();
|
|
||||||
let project_finish_date = project_finish_date.clone();
|
|
||||||
let project_floors = project_floors.clone();
|
|
||||||
let media = media.clone();
|
|
||||||
Callback::from(move |_: MouseEvent| {
|
|
||||||
let navigator = navigator.clone();
|
|
||||||
let edit_type = edit_type.clone();
|
|
||||||
let location_city_handle = location_city.clone();
|
|
||||||
let location_district_handle = location_district.clone();
|
|
||||||
let agent_handle = agent.clone();
|
|
||||||
let project_state_handle = project_state.clone();
|
|
||||||
let project_condition_handle = project_condition.clone();
|
|
||||||
let project_type_handle = project_type.clone();
|
|
||||||
let project_description_handle = project_description.clone();
|
|
||||||
let project_admin_tag_handle = project_admin_tag.clone();
|
|
||||||
let project_finish_date_handle = project_finish_date.clone();
|
|
||||||
let project_floors_handle = project_floors.clone();
|
|
||||||
let media_handle = media.clone();
|
|
||||||
|
|
||||||
wasm_bindgen_futures::spawn_local(async move {
|
|
||||||
let location = match get_location_with_city_and_district(
|
|
||||||
(*location_city_handle).clone(),
|
|
||||||
(*location_district_handle).clone(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(location) => location,
|
|
||||||
Err(_) => {
|
|
||||||
// Create location
|
|
||||||
match create_location(NewLocationPayload {
|
|
||||||
city: (*location_city_handle).clone(),
|
|
||||||
district: (*location_district_handle).clone(),
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(location) => location,
|
|
||||||
Err(error) => {
|
|
||||||
log::error!("Couldn't create location..: {error}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let agent_id = match (*agent_handle).clone() {
|
|
||||||
Some(selected_agent) => selected_agent.id,
|
|
||||||
None => {
|
|
||||||
log::error!("Missing Field agent.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let project_state = match (*project_state_handle).clone() {
|
|
||||||
Some(selected_project_state) => selected_project_state,
|
|
||||||
None => {
|
|
||||||
log::error!("Missing Field project_state.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let project_condition = match (*project_condition_handle).clone() {
|
|
||||||
Some(selected_project_condition) => selected_project_condition,
|
|
||||||
None => {
|
|
||||||
log::error!("Missing Field project_condition.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let project_type = match (*project_type_handle).clone() {
|
|
||||||
Some(selected_project_type) => selected_project_type,
|
|
||||||
None => {
|
|
||||||
log::error!("Missing Field project_type.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let description = (*project_description_handle).clone();
|
|
||||||
let project_admin_tag = (*project_admin_tag_handle).clone();
|
|
||||||
let admin_tag = if project_admin_tag.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(project_admin_tag)
|
|
||||||
};
|
|
||||||
let finish_date = match (*project_finish_date_handle).clone() {
|
|
||||||
Some(finish_date) => finish_date.and_time(NaiveTime::default()),
|
|
||||||
None => {
|
|
||||||
log::error!("Missing Field finish_date.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let floors = match i16::from_str(&(*project_floors_handle).clone()) {
|
|
||||||
Ok(floors) => floors,
|
|
||||||
Err(error) => {
|
|
||||||
log::error!("Could not parse floors correctly. {error}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let media = (*media_handle).clone();
|
|
||||||
|
|
||||||
match edit_type {
|
|
||||||
EditType::New => {
|
|
||||||
let payload = NewProjectPayload {
|
|
||||||
project_state,
|
|
||||||
project_type,
|
|
||||||
project_condition,
|
|
||||||
agent_id,
|
|
||||||
location_id: location.id,
|
|
||||||
title: None,
|
|
||||||
description,
|
|
||||||
admin_tag,
|
|
||||||
finish_date,
|
|
||||||
floors,
|
|
||||||
media,
|
|
||||||
};
|
|
||||||
|
|
||||||
match create_new_project(payload).await {
|
|
||||||
Ok(_) => navigator.clone().push(&Route::AdminProjects),
|
|
||||||
Err(error) => log::error!("Error creating new project: {error}"),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
EditType::Existing(id) => {
|
|
||||||
let payload = UpdateProjectPayload {
|
|
||||||
id,
|
|
||||||
project_state: Some(project_state),
|
|
||||||
project_type: Some(project_type),
|
|
||||||
project_condition: Some(project_condition),
|
|
||||||
agent_id: Some(agent_id),
|
|
||||||
location_id: Some(location.id),
|
|
||||||
title: None,
|
|
||||||
description: Some(description),
|
|
||||||
admin_tag: Some(admin_tag),
|
|
||||||
finish_date: Some(finish_date),
|
|
||||||
floors: Some(floors),
|
|
||||||
media: Some(media),
|
|
||||||
};
|
|
||||||
|
|
||||||
match update_project(payload).await {
|
|
||||||
Ok(_) => navigator.clone().push(&Route::AdminProjects),
|
|
||||||
Err(error) => log::error!("Error updating project: {error}"),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<>
|
|
||||||
{
|
|
||||||
if let Some(listing) = listing_opt {
|
|
||||||
html! {
|
|
||||||
<NewThingWidget item={EditItem::Unit(listing.project.id)}/>
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
html! {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
<TextField label={"Ciudad"} value={location_city} required={true} onchange={ontype_cb.clone()}/>
|
|
||||||
<TextField label={"Distrito"} value={location_district} required={true} onchange={ontype_cb.clone()} />
|
|
||||||
<MediaPicker value={media} onchange={ontype_cb.clone()} item={jl_types::dto::item::Item::Project}/>
|
|
||||||
{if (*agent).clone().is_none() {
|
|
||||||
html! {
|
|
||||||
<div class={"textfield-container"}>
|
|
||||||
<div class={"textfield-label-required"}>{"Agente asignado"}</div>
|
|
||||||
<DropDown<Agent> options={(*all_agents).clone()} selected={agent} onchange={onselect_cb.clone()} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
html! {
|
|
||||||
<div class={"textfield-container"}>
|
|
||||||
<div class={"textfield-label-required"}>{"Agente asignado"}</div>
|
|
||||||
<DropDown<Agent> options={(*all_agents).clone()} selected={agent} onchange={onselect_cb.clone()} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{if (*project_state).clone().is_none() {
|
|
||||||
html! {
|
|
||||||
<div class={"textfield-container"}>
|
|
||||||
<div class={"textfield-label-required"}>{"Estado del Proyecto"}</div>
|
|
||||||
<DropDown<ProjectState> options={vec![ProjectState::Finished, ProjectState::InConstruction]} selected={project_state} onchange={onselect_cb2} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
html! {
|
|
||||||
<div class={"textfield-container"}>
|
|
||||||
<div class={"textfield-label-required"}>{"Estado del Proyecto"}</div>
|
|
||||||
<DropDown<ProjectState> options={vec![ProjectState::Finished, ProjectState::InConstruction]} selected={project_state} onchange={onselect_cb2} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{if (*project_condition).clone().is_none() {
|
|
||||||
html! {
|
|
||||||
<div class={"textfield-container"}>
|
|
||||||
<div class={"textfield-label-required"}>{"Condición del Proyecto"}</div>
|
|
||||||
<DropDown<ProjectCondition> options={vec![ProjectCondition::Resale, ProjectCondition::New]} selected={project_condition} onchange={onselect_cb3} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
html! {
|
|
||||||
<div class={"textfield-container"}>
|
|
||||||
<div class={"textfield-label-required"}>{"Condición del Proyecto"}</div>
|
|
||||||
<DropDown<ProjectCondition> options={vec![ProjectCondition::Resale, ProjectCondition::New]} selected={project_condition} onchange={onselect_cb3} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{if (*project_type).clone().is_none() {
|
|
||||||
html! {
|
|
||||||
<div class={"textfield-container"}>
|
|
||||||
<div class={"textfield-label-required"}>{"Tipo de Proyecto"}</div>
|
|
||||||
<DropDown<ProjectType> options={vec![ProjectType::Apartamento, ProjectType::Casa, ProjectType::Oficina, ProjectType::Local, ProjectType::Solar]} selected={project_type} onchange={onselect_cb4} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
html! {
|
|
||||||
<div class={"textfield-container"}>
|
|
||||||
<div class={"textfield-label-required"}>{"Tipo de Proyecto"}</div>
|
|
||||||
<DropDown<ProjectType> options={vec![ProjectType::Apartamento, ProjectType::Casa, ProjectType::Oficina, ProjectType::Local, ProjectType::Solar]} selected={project_type} onchange={onselect_cb4} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
<TextField label={"Pisos"} value={project_floors} required={true} onchange={ontype_cb.clone()}/>
|
|
||||||
<DatePicker label={"Fecha de entrega Est."} value={project_finish_date} required={true} onchange={ontypedate_cb.clone()}/>
|
|
||||||
<TextField label={"Descripción"} value={project_description} fieldtype={TextFieldType::TextArea} onchange={ontype_cb.clone()}/>
|
|
||||||
<TextField label={"Comentario interno"} value={project_admin_tag} onchange={ontype_cb.clone()}/>
|
|
||||||
|
|
||||||
<div class={"admin-edit-submit-button"} onclick={update_button_onclick}>
|
|
||||||
{"Actualizar"}
|
|
||||||
</div>
|
|
||||||
<AdminUnits units={units} onchange={ontype_cb.clone()}/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for EditItem {
|
impl Display for EditItem {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
1
src/pages/admin/fields/mod.rs
Normal file
1
src/pages/admin/fields/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod project;
|
393
src/pages/admin/fields/project.rs
Normal file
393
src/pages/admin/fields/project.rs
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
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 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}};
|
||||||
|
|
||||||
|
#[derive(Properties, PartialEq, Clone)]
|
||||||
|
pub struct ProjectFieldsProps {
|
||||||
|
pub listing: Option<Listing>,
|
||||||
|
pub edittype: EditType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component(ProjectFields)]
|
||||||
|
pub fn generate_fields_for_project(props: &ProjectFieldsProps) -> Html {
|
||||||
|
let navigator = use_navigator().unwrap();
|
||||||
|
let user_typed = use_state(|| false);
|
||||||
|
let listing_opt = props.listing.clone();
|
||||||
|
|
||||||
|
let location_city = use_state_eq(|| String::new());
|
||||||
|
let location_district = use_state_eq(|| String::new());
|
||||||
|
let agent: UseStateHandle<Option<Agent>> = use_state_eq(|| None);
|
||||||
|
let project_state = use_state_eq(|| None);
|
||||||
|
let project_condition = use_state_eq(|| None);
|
||||||
|
let project_type = use_state_eq(|| None);
|
||||||
|
let project_description = use_state_eq(|| String::new());
|
||||||
|
let project_admin_tag: UseStateHandle<String> = use_state_eq(|| String::new());
|
||||||
|
let project_finish_date = use_state_eq(|| None);
|
||||||
|
let project_floors = use_state_eq(|| String::new());
|
||||||
|
let media: UseStateHandle<MediaList> = use_state_eq(|| MediaList {
|
||||||
|
media_list: Vec::new(),
|
||||||
|
});
|
||||||
|
let units: UseStateHandle<Vec<Unit>> = use_state_eq(|| Vec::new());
|
||||||
|
|
||||||
|
let ontype_cb = {
|
||||||
|
let user_typed = user_typed.clone();
|
||||||
|
Callback::from(move |_| {
|
||||||
|
user_typed.set(true);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
let ontypedate_cb = {
|
||||||
|
let user_typed = user_typed.clone();
|
||||||
|
Callback::from(move |_| {
|
||||||
|
user_typed.set(true);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
let onselect_cb = {
|
||||||
|
let user_typed = user_typed.clone();
|
||||||
|
Callback::from(move |_| {
|
||||||
|
user_typed.set(true);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
let onselect_cb2 = {
|
||||||
|
let user_typed = user_typed.clone();
|
||||||
|
Callback::from(move |_| {
|
||||||
|
user_typed.set(true);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
let onselect_cb3 = {
|
||||||
|
let user_typed = user_typed.clone();
|
||||||
|
Callback::from(move |_| {
|
||||||
|
user_typed.set(true);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
let onselect_cb4 = {
|
||||||
|
let user_typed = user_typed.clone();
|
||||||
|
Callback::from(move |_| {
|
||||||
|
user_typed.set(true);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let all_agents = use_state(|| Vec::new());
|
||||||
|
|
||||||
|
use_state(|| {
|
||||||
|
let all_agents = all_agents.clone();
|
||||||
|
wasm_bindgen_futures::spawn_local(async move {
|
||||||
|
match get_all_agents().await {
|
||||||
|
Ok(persisted_agents) => all_agents.set(persisted_agents),
|
||||||
|
Err(error) => {
|
||||||
|
log::error!("Error fetching agents from admin panel edit screen: {error}")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if !*user_typed {
|
||||||
|
location_city.set(listing_opt.clone().unwrap_or_default().location.city);
|
||||||
|
location_district.set(listing_opt.clone().unwrap_or_default().location.district);
|
||||||
|
agent.set(match listing_opt.clone() {
|
||||||
|
Some(listing) => Some(listing.agent),
|
||||||
|
None => {
|
||||||
|
let agents = (*all_agents).clone();
|
||||||
|
if let Some(default_agent) = agents.last() {
|
||||||
|
Some(default_agent.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
project_state.set(match listing_opt.clone() {
|
||||||
|
Some(listing) => Some(listing.project.project_state),
|
||||||
|
None => {
|
||||||
|
Some(ProjectState::InConstruction)
|
||||||
|
},
|
||||||
|
});
|
||||||
|
project_condition.set(match listing_opt.clone() {
|
||||||
|
Some(listing) => Some(listing.project.project_condition),
|
||||||
|
None => {
|
||||||
|
Some(ProjectCondition::New)
|
||||||
|
},
|
||||||
|
});
|
||||||
|
project_type.set(match listing_opt.clone() {
|
||||||
|
Some(listing) => Some(listing.project.project_type),
|
||||||
|
None => {
|
||||||
|
Some(ProjectType::Solar)
|
||||||
|
},
|
||||||
|
});
|
||||||
|
project_description.set(match listing_opt.clone() {
|
||||||
|
Some(listing) => listing.project.description,
|
||||||
|
None => "".into(),
|
||||||
|
});
|
||||||
|
project_floors.set(match listing_opt.clone() {
|
||||||
|
Some(listing) => listing.project.floors.to_string(),
|
||||||
|
None => "".into(),
|
||||||
|
});
|
||||||
|
project_admin_tag.set(match listing_opt.clone() {
|
||||||
|
Some(listing) => match listing.project.admin_tag {
|
||||||
|
Some(admin_tag) => admin_tag,
|
||||||
|
None => String::new(),
|
||||||
|
},
|
||||||
|
None => String::new(),
|
||||||
|
});
|
||||||
|
project_finish_date.set(match listing_opt.clone() {
|
||||||
|
Some(listing) => Some(listing.project.finish_date.date()),
|
||||||
|
None => None,
|
||||||
|
});
|
||||||
|
media.set(match listing_opt.clone() {
|
||||||
|
Some(listing) => listing.project.media,
|
||||||
|
None => MediaList {
|
||||||
|
media_list: Vec::new(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
units.set(match listing_opt.clone() {
|
||||||
|
Some(listing) => listing.units,
|
||||||
|
None => Vec::new(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let update_button_onclick = {
|
||||||
|
let navigator = navigator.clone();
|
||||||
|
let edit_type = props.edittype.clone();
|
||||||
|
|
||||||
|
// All fields to be sent to the backend
|
||||||
|
let location_city = location_city.clone();
|
||||||
|
let location_district = location_district.clone();
|
||||||
|
let agent = agent.clone();
|
||||||
|
let project_state = project_state.clone();
|
||||||
|
let project_condition = project_condition.clone();
|
||||||
|
let project_type = project_type.clone();
|
||||||
|
let project_description = project_description.clone();
|
||||||
|
let project_admin_tag = project_admin_tag.clone();
|
||||||
|
let project_finish_date = project_finish_date.clone();
|
||||||
|
let project_floors = project_floors.clone();
|
||||||
|
let media = media.clone();
|
||||||
|
Callback::from(move |_: MouseEvent| {
|
||||||
|
let navigator = navigator.clone();
|
||||||
|
let edit_type = edit_type.clone();
|
||||||
|
let location_city_handle = location_city.clone();
|
||||||
|
let location_district_handle = location_district.clone();
|
||||||
|
let agent_handle = agent.clone();
|
||||||
|
let project_state_handle = project_state.clone();
|
||||||
|
let project_condition_handle = project_condition.clone();
|
||||||
|
let project_type_handle = project_type.clone();
|
||||||
|
let project_description_handle = project_description.clone();
|
||||||
|
let project_admin_tag_handle = project_admin_tag.clone();
|
||||||
|
let project_finish_date_handle = project_finish_date.clone();
|
||||||
|
let project_floors_handle = project_floors.clone();
|
||||||
|
let media_handle = media.clone();
|
||||||
|
|
||||||
|
wasm_bindgen_futures::spawn_local(async move {
|
||||||
|
let location = match get_location_with_city_and_district(
|
||||||
|
(*location_city_handle).clone(),
|
||||||
|
(*location_district_handle).clone(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(location) => location,
|
||||||
|
Err(_) => {
|
||||||
|
// Create location
|
||||||
|
match create_location(NewLocationPayload {
|
||||||
|
city: (*location_city_handle).clone(),
|
||||||
|
district: (*location_district_handle).clone(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(location) => location,
|
||||||
|
Err(error) => {
|
||||||
|
log::error!("Couldn't create location..: {error}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let agent_id = match (*agent_handle).clone() {
|
||||||
|
Some(selected_agent) => selected_agent.id,
|
||||||
|
None => {
|
||||||
|
log::error!("Missing Field agent.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let project_state = match (*project_state_handle).clone() {
|
||||||
|
Some(selected_project_state) => selected_project_state,
|
||||||
|
None => {
|
||||||
|
log::error!("Missing Field project_state.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let project_condition = match (*project_condition_handle).clone() {
|
||||||
|
Some(selected_project_condition) => selected_project_condition,
|
||||||
|
None => {
|
||||||
|
log::error!("Missing Field project_condition.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let project_type = match (*project_type_handle).clone() {
|
||||||
|
Some(selected_project_type) => selected_project_type,
|
||||||
|
None => {
|
||||||
|
log::error!("Missing Field project_type.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let description = (*project_description_handle).clone();
|
||||||
|
let project_admin_tag = (*project_admin_tag_handle).clone();
|
||||||
|
let admin_tag = if project_admin_tag.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(project_admin_tag)
|
||||||
|
};
|
||||||
|
let finish_date = match (*project_finish_date_handle).clone() {
|
||||||
|
Some(finish_date) => finish_date.and_time(NaiveTime::default()),
|
||||||
|
None => {
|
||||||
|
log::error!("Missing Field finish_date.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let floors = match i16::from_str(&(*project_floors_handle).clone()) {
|
||||||
|
Ok(floors) => floors,
|
||||||
|
Err(error) => {
|
||||||
|
log::error!("Could not parse floors correctly. {error}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let media = (*media_handle).clone();
|
||||||
|
|
||||||
|
match edit_type {
|
||||||
|
EditType::New => {
|
||||||
|
let payload = NewProjectPayload {
|
||||||
|
project_state,
|
||||||
|
project_type,
|
||||||
|
project_condition,
|
||||||
|
agent_id,
|
||||||
|
location_id: location.id,
|
||||||
|
title: None,
|
||||||
|
description,
|
||||||
|
admin_tag,
|
||||||
|
finish_date,
|
||||||
|
floors,
|
||||||
|
media,
|
||||||
|
};
|
||||||
|
|
||||||
|
match create_new_project(payload).await {
|
||||||
|
Ok(_) => navigator.clone().push(&Route::AdminProjects),
|
||||||
|
Err(error) => log::error!("Error creating new project: {error}"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
EditType::Existing(id) => {
|
||||||
|
let payload = UpdateProjectPayload {
|
||||||
|
id,
|
||||||
|
project_state: Some(project_state),
|
||||||
|
project_type: Some(project_type),
|
||||||
|
project_condition: Some(project_condition),
|
||||||
|
agent_id: Some(agent_id),
|
||||||
|
location_id: Some(location.id),
|
||||||
|
title: None,
|
||||||
|
description: Some(description),
|
||||||
|
admin_tag: Some(admin_tag),
|
||||||
|
finish_date: Some(finish_date),
|
||||||
|
floors: Some(floors),
|
||||||
|
media: Some(media),
|
||||||
|
};
|
||||||
|
|
||||||
|
match update_project(payload).await {
|
||||||
|
Ok(_) => navigator.clone().push(&Route::AdminProjects),
|
||||||
|
Err(error) => log::error!("Error updating project: {error}"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
html! {
|
||||||
|
<>
|
||||||
|
{
|
||||||
|
if let Some(listing) = listing_opt {
|
||||||
|
html! {
|
||||||
|
<NewThingWidget item={EditItem::Unit(listing.project.id)}/>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
html! {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<TextField label={"Ciudad"} value={location_city} required={true} onchange={ontype_cb.clone()}/>
|
||||||
|
<TextField label={"Distrito"} value={location_district} required={true} onchange={ontype_cb.clone()} />
|
||||||
|
<MediaPicker value={media} onchange={ontype_cb.clone()} item={jl_types::dto::item::Item::Project}/>
|
||||||
|
{if (*agent).clone().is_none() {
|
||||||
|
html! {
|
||||||
|
<div class={"textfield-container"}>
|
||||||
|
<div class={"textfield-label-required"}>{"Agente asignado"}</div>
|
||||||
|
<DropDown<Agent> options={(*all_agents).clone()} selected={agent} onchange={onselect_cb.clone()} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
html! {
|
||||||
|
<div class={"textfield-container"}>
|
||||||
|
<div class={"textfield-label-required"}>{"Agente asignado"}</div>
|
||||||
|
<DropDown<Agent> options={(*all_agents).clone()} selected={agent} onchange={onselect_cb.clone()} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{if (*project_state).clone().is_none() {
|
||||||
|
html! {
|
||||||
|
<div class={"textfield-container"}>
|
||||||
|
<div class={"textfield-label-required"}>{"Estado del Proyecto"}</div>
|
||||||
|
<DropDown<ProjectState> options={vec![ProjectState::Finished, ProjectState::InConstruction]} selected={project_state} onchange={onselect_cb2} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
html! {
|
||||||
|
<div class={"textfield-container"}>
|
||||||
|
<div class={"textfield-label-required"}>{"Estado del Proyecto"}</div>
|
||||||
|
<DropDown<ProjectState> options={vec![ProjectState::Finished, ProjectState::InConstruction]} selected={project_state} onchange={onselect_cb2} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{if (*project_condition).clone().is_none() {
|
||||||
|
html! {
|
||||||
|
<div class={"textfield-container"}>
|
||||||
|
<div class={"textfield-label-required"}>{"Condición del Proyecto"}</div>
|
||||||
|
<DropDown<ProjectCondition> options={vec![ProjectCondition::Resale, ProjectCondition::New]} selected={project_condition} onchange={onselect_cb3} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
html! {
|
||||||
|
<div class={"textfield-container"}>
|
||||||
|
<div class={"textfield-label-required"}>{"Condición del Proyecto"}</div>
|
||||||
|
<DropDown<ProjectCondition> options={vec![ProjectCondition::Resale, ProjectCondition::New]} selected={project_condition} onchange={onselect_cb3} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{if (*project_type).clone().is_none() {
|
||||||
|
html! {
|
||||||
|
<div class={"textfield-container"}>
|
||||||
|
<div class={"textfield-label-required"}>{"Tipo de Proyecto"}</div>
|
||||||
|
<DropDown<ProjectType> options={vec![ProjectType::Apartamento, ProjectType::Casa, ProjectType::Oficina, ProjectType::Local, ProjectType::Solar]} selected={project_type} onchange={onselect_cb4} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
html! {
|
||||||
|
<div class={"textfield-container"}>
|
||||||
|
<div class={"textfield-label-required"}>{"Tipo de Proyecto"}</div>
|
||||||
|
<DropDown<ProjectType> options={vec![ProjectType::Apartamento, ProjectType::Casa, ProjectType::Oficina, ProjectType::Local, ProjectType::Solar]} selected={project_type} onchange={onselect_cb4} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<TextField label={"Pisos"} value={project_floors} required={true} onchange={ontype_cb.clone()}/>
|
||||||
|
<DatePicker label={"Fecha de entrega Est."} value={project_finish_date} required={true} onchange={ontypedate_cb.clone()}/>
|
||||||
|
<TextField label={"Descripción"} value={project_description} fieldtype={TextFieldType::TextArea} onchange={ontype_cb.clone()}/>
|
||||||
|
<TextField label={"Comentario interno"} value={project_admin_tag} onchange={ontype_cb.clone()}/>
|
||||||
|
|
||||||
|
<div class={"admin-edit-submit-button"} onclick={update_button_onclick}>
|
||||||
|
{"Actualizar"}
|
||||||
|
</div>
|
||||||
|
<AdminUnits units={units} onchange={ontype_cb.clone()}/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
@ -5,3 +5,4 @@ pub mod login;
|
|||||||
pub mod projects;
|
pub mod projects;
|
||||||
pub mod start;
|
pub mod start;
|
||||||
pub mod units;
|
pub mod units;
|
||||||
|
pub mod fields;
|
Loading…
Reference in New Issue
Block a user