diff --git a/src/pages/admin/edit.rs b/src/pages/admin/edit.rs index 35aba56..72c6e53 100644 --- a/src/pages/admin/edit.rs +++ b/src/pages/admin/edit.rs @@ -1,38 +1,17 @@ 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 yew::prelude::*; use yew_router::prelude::use_navigator; use crate::{ api::backend::{ - create_location, create_new_project, get_all_agents, get_location_with_city_and_district, - get_project_listing, update_project, + get_project_listing, }, components::{ admin_nav_bar::AdminNavigationBar, - datepicker::DatePicker, - dropdown::DropDown, - media_picker::MediaPicker, - new_widget::NewThingWidget, - textfield::{TextField, TextFieldType}, }, - pages::admin::units::AdminUnits, - routes::main_router::Route, + pages::admin::{fields::project::ProjectFields}, }; /// 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, } -#[derive(Properties, PartialEq, Clone)] -pub struct ProjectFieldsProps { - pub listing: Option, - 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> = 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 = use_state_eq(|| String::new()); - let project_finish_date = use_state_eq(|| None); - let project_floors = use_state_eq(|| String::new()); - let media: UseStateHandle = use_state_eq(|| MediaList { - media_list: Vec::new(), - }); - let units: UseStateHandle> = 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! { - - } - } else { - html! {} - } - } - - - - {if (*agent).clone().is_none() { - html! { -
-
{"Agente asignado"}
- options={(*all_agents).clone()} selected={agent} onchange={onselect_cb.clone()} /> -
- } - } else { - html! { -
-
{"Agente asignado"}
- options={(*all_agents).clone()} selected={agent} onchange={onselect_cb.clone()} /> -
- } - } - } - {if (*project_state).clone().is_none() { - html! { -
-
{"Estado del Proyecto"}
- options={vec![ProjectState::Finished, ProjectState::InConstruction]} selected={project_state} onchange={onselect_cb2} /> -
- } - } else { - html! { -
-
{"Estado del Proyecto"}
- options={vec![ProjectState::Finished, ProjectState::InConstruction]} selected={project_state} onchange={onselect_cb2} /> -
- } - } - } - - {if (*project_condition).clone().is_none() { - html! { -
-
{"Condición del Proyecto"}
- options={vec![ProjectCondition::Resale, ProjectCondition::New]} selected={project_condition} onchange={onselect_cb3} /> -
- } - } else { - html! { -
-
{"Condición del Proyecto"}
- options={vec![ProjectCondition::Resale, ProjectCondition::New]} selected={project_condition} onchange={onselect_cb3} /> -
- } - } - } - {if (*project_type).clone().is_none() { - html! { -
-
{"Tipo de Proyecto"}
- options={vec![ProjectType::Apartamento, ProjectType::Casa, ProjectType::Oficina, ProjectType::Local, ProjectType::Solar]} selected={project_type} onchange={onselect_cb4} /> -
- } - } else { - html! { -
-
{"Tipo de Proyecto"}
- options={vec![ProjectType::Apartamento, ProjectType::Casa, ProjectType::Oficina, ProjectType::Local, ProjectType::Solar]} selected={project_type} onchange={onselect_cb4} /> -
- } - } - } - - - - - -
- {"Actualizar"} -
- - - } -} - impl Display for EditItem { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/src/pages/admin/fields/mod.rs b/src/pages/admin/fields/mod.rs new file mode 100644 index 0000000..432f815 --- /dev/null +++ b/src/pages/admin/fields/mod.rs @@ -0,0 +1 @@ +pub mod project; \ No newline at end of file diff --git a/src/pages/admin/fields/project.rs b/src/pages/admin/fields/project.rs new file mode 100644 index 0000000..b72c7e9 --- /dev/null +++ b/src/pages/admin/fields/project.rs @@ -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, + 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> = 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 = use_state_eq(|| String::new()); + let project_finish_date = use_state_eq(|| None); + let project_floors = use_state_eq(|| String::new()); + let media: UseStateHandle = use_state_eq(|| MediaList { + media_list: Vec::new(), + }); + let units: UseStateHandle> = 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! { + + } + } else { + html! {} + } + } + + + + {if (*agent).clone().is_none() { + html! { +
+
{"Agente asignado"}
+ options={(*all_agents).clone()} selected={agent} onchange={onselect_cb.clone()} /> +
+ } + } else { + html! { +
+
{"Agente asignado"}
+ options={(*all_agents).clone()} selected={agent} onchange={onselect_cb.clone()} /> +
+ } + } + } + {if (*project_state).clone().is_none() { + html! { +
+
{"Estado del Proyecto"}
+ options={vec![ProjectState::Finished, ProjectState::InConstruction]} selected={project_state} onchange={onselect_cb2} /> +
+ } + } else { + html! { +
+
{"Estado del Proyecto"}
+ options={vec![ProjectState::Finished, ProjectState::InConstruction]} selected={project_state} onchange={onselect_cb2} /> +
+ } + } + } + + {if (*project_condition).clone().is_none() { + html! { +
+
{"Condición del Proyecto"}
+ options={vec![ProjectCondition::Resale, ProjectCondition::New]} selected={project_condition} onchange={onselect_cb3} /> +
+ } + } else { + html! { +
+
{"Condición del Proyecto"}
+ options={vec![ProjectCondition::Resale, ProjectCondition::New]} selected={project_condition} onchange={onselect_cb3} /> +
+ } + } + } + {if (*project_type).clone().is_none() { + html! { +
+
{"Tipo de Proyecto"}
+ options={vec![ProjectType::Apartamento, ProjectType::Casa, ProjectType::Oficina, ProjectType::Local, ProjectType::Solar]} selected={project_type} onchange={onselect_cb4} /> +
+ } + } else { + html! { +
+
{"Tipo de Proyecto"}
+ options={vec![ProjectType::Apartamento, ProjectType::Casa, ProjectType::Oficina, ProjectType::Local, ProjectType::Solar]} selected={project_type} onchange={onselect_cb4} /> +
+ } + } + } + + + + + +
+ {"Actualizar"} +
+ + + } +} \ No newline at end of file diff --git a/src/pages/admin/mod.rs b/src/pages/admin/mod.rs index 4042ad5..9f024e8 100644 --- a/src/pages/admin/mod.rs +++ b/src/pages/admin/mod.rs @@ -5,3 +5,4 @@ pub mod login; pub mod projects; pub mod start; pub mod units; +pub mod fields; \ No newline at end of file