Added functionality for update project button. New & Update work fine.
This commit is contained in:
parent
81c826c099
commit
f9897472c7
@ -1,17 +1,23 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use jl_types::{
|
||||
domain::{agent::Agent, contact::Contact, count::Count},
|
||||
domain::{agent::Agent, contact::Contact, count::Count, location::Location, project::Project},
|
||||
dto::{
|
||||
filters::Filter, listing::Listing, payloads::contact::ContactPayload,
|
||||
project_card::ProjectCardDto,
|
||||
filters::Filter,
|
||||
item::Item,
|
||||
listing::Listing,
|
||||
payloads::{
|
||||
contact::ContactPayload,
|
||||
location::NewLocationPayload,
|
||||
project::{NewProjectPayload, UpdateProjectPayload},
|
||||
},
|
||||
project_card::ProjectCardDto,
|
||||
},
|
||||
};
|
||||
use reqwest::Method;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::base::{perform_request_without_client, perform_multipart_request_without_client};
|
||||
use super::base::{perform_multipart_request_without_client, perform_request_without_client};
|
||||
|
||||
const BASE_URL: &str = "http://localhost:8095/";
|
||||
|
||||
@ -150,6 +156,59 @@ pub async fn create_new_contact_request(contact: ContactPayload) -> Result<(), e
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_location_with_city_and_district(
|
||||
city: String,
|
||||
district: String,
|
||||
) -> Result<Location, err::Error> {
|
||||
perform_request_without_client::<String, Location>(
|
||||
BASE_URL.into(),
|
||||
Method::GET,
|
||||
format!("read/location/{city}/{district}"),
|
||||
None,
|
||||
200,
|
||||
Vec::new(),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn create_new_project(project: NewProjectPayload) -> Result<Project, err::Error> {
|
||||
perform_request_without_client(
|
||||
BASE_URL.into(),
|
||||
Method::POST,
|
||||
format!("admin/project"),
|
||||
Some(project),
|
||||
200,
|
||||
Vec::new(),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
}
|
||||
pub async fn create_location(location: NewLocationPayload) -> Result<Location, err::Error> {
|
||||
perform_request_without_client(
|
||||
BASE_URL.into(),
|
||||
Method::POST,
|
||||
format!("admin/location"),
|
||||
Some(location),
|
||||
200,
|
||||
Vec::new(),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
}
|
||||
pub async fn update_project(project: UpdateProjectPayload) -> Result<Project, err::Error> {
|
||||
perform_request_without_client(
|
||||
BASE_URL.into(),
|
||||
Method::PUT,
|
||||
format!("admin/project"),
|
||||
Some(project),
|
||||
200,
|
||||
Vec::new(),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn upload_image(item: Item, body: Vec<u8>) -> Result<String, err::Error> {
|
||||
perform_multipart_request_without_client(
|
||||
BASE_URL.into(),
|
||||
|
@ -85,7 +85,7 @@ pub async fn perform_multipart_request_without_client<R: DeserializeOwned>(
|
||||
let part = reqwest::multipart::Part::bytes(body).file_name("image");
|
||||
let form = reqwest::multipart::Form::new();
|
||||
let form = form.part("image", part);
|
||||
|
||||
|
||||
match req_incomplete.multipart(form).send().await {
|
||||
// Error handling here
|
||||
Ok(res) => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use jl_types::{domain::{agent::Agent}};
|
||||
use jl_types::domain::agent::Agent;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::use_navigator;
|
||||
|
||||
|
@ -11,17 +11,14 @@ use crate::{
|
||||
#[function_component(AdminUnit)]
|
||||
pub fn admin_project(props: &AdminUnitProps) -> Html {
|
||||
let navigator = use_navigator().unwrap();
|
||||
let price_usd = format!(
|
||||
"${}",
|
||||
{
|
||||
let price_separated = props.unit.price_usd.separate_with_commas();
|
||||
if price_separated.contains(".") {
|
||||
price_separated
|
||||
} else {
|
||||
format!("{price_separated}.00")
|
||||
}
|
||||
let price_usd = format!("${}", {
|
||||
let price_separated = props.unit.price_usd.separate_with_commas();
|
||||
if price_separated.contains(".") {
|
||||
price_separated
|
||||
} else {
|
||||
format!("{price_separated}.00")
|
||||
}
|
||||
);
|
||||
});
|
||||
let is_attempting_delete = use_state(|| false);
|
||||
let delete_unit = {
|
||||
let is_attempting_delete = is_attempting_delete.clone();
|
||||
|
@ -3,7 +3,10 @@ use js_sys::Uint8Array;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::{components::textfield::{get_value_from_input_event, get_files_from_input_event}, api};
|
||||
use crate::{
|
||||
api,
|
||||
components::textfield::{get_files_from_input_event, get_value_from_input_event},
|
||||
};
|
||||
|
||||
#[function_component(MediaPicker)]
|
||||
pub fn media_picker(props: &MediaPickerProps) -> Html {
|
||||
@ -95,7 +98,6 @@ fn render_media_list(props: &MediaListProps) -> Html {
|
||||
let onchange_cb = props.onchange.clone();
|
||||
let item = props.item.clone();
|
||||
Callback::from(move |e: InputEvent| {
|
||||
|
||||
match onchange_cb.clone() {
|
||||
Some(cb) => cb.emit(String::new()),
|
||||
None => {}
|
||||
@ -117,14 +119,18 @@ fn render_media_list(props: &MediaListProps) -> Html {
|
||||
let mut media = (*media_handle).clone();
|
||||
media.media_list.push(Media::Photo(url));
|
||||
media_handle.set(media);
|
||||
},
|
||||
Err(error) => log::error!("Error uploading image to backend: {error}"),
|
||||
}
|
||||
Err(error) => {
|
||||
log::error!("Error uploading image to backend: {error}")
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
None => {log::error!("No files in first element of filelist...")}
|
||||
}
|
||||
None => {
|
||||
log::error!("No files in first element of filelist...")
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
None => {
|
||||
log::error!("Something weird happened. No files after selecting files")
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
pub mod admin_agent;
|
||||
pub mod admin_nav_bar;
|
||||
pub mod admin_project;
|
||||
pub mod admin_unit;
|
||||
pub mod agent_card;
|
||||
pub mod datepicker;
|
||||
pub mod dropdown;
|
||||
@ -12,5 +14,3 @@ pub mod nav_bar;
|
||||
pub mod new_widget;
|
||||
pub mod project_card;
|
||||
pub mod textfield;
|
||||
pub mod admin_unit;
|
||||
pub mod admin_agent;
|
@ -1,6 +1,12 @@
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::{api::backend::get_all_agents, components::{admin_nav_bar::AdminNavigationBar, admin_agent::AdminAgent, new_widget::NewThingWidget}, pages::admin::edit::EditItem};
|
||||
use crate::{
|
||||
api::backend::get_all_agents,
|
||||
components::{
|
||||
admin_agent::AdminAgent, admin_nav_bar::AdminNavigationBar, new_widget::NewThingWidget,
|
||||
},
|
||||
pages::admin::edit::EditItem,
|
||||
};
|
||||
|
||||
#[function_component(AdminAgents)]
|
||||
pub fn admin_agents() -> Html {
|
||||
|
@ -20,14 +20,14 @@ pub fn admin_contacts() -> Html {
|
||||
});
|
||||
});
|
||||
html! {
|
||||
<>
|
||||
<AdminNavigationBar/>
|
||||
<div class={"admin-page-container"}>
|
||||
<div class={"admin-start-container"}>
|
||||
<div class={"admin-panel-page-title"}>{"Solicitudes de Contacto"}</div>
|
||||
//TODO: Finish this
|
||||
<>
|
||||
<AdminNavigationBar/>
|
||||
<div class={"admin-page-container"}>
|
||||
<div class={"admin-start-container"}>
|
||||
<div class={"admin-panel-page-title"}>{"Solicitudes de Contacto"}</div>
|
||||
//TODO: Finish this
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,35 @@
|
||||
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,
|
||||
dto::{
|
||||
listing::Listing,
|
||||
payloads::{project::{NewProjectPayload, UpdateProjectPayload}, location::NewLocationPayload},
|
||||
},
|
||||
};
|
||||
use uuid::Uuid;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::use_navigator;
|
||||
|
||||
use crate::{
|
||||
api::backend::{get_all_agents, get_project_listing},
|
||||
api::backend::{
|
||||
create_location, create_new_project, get_all_agents, get_location_with_city_and_district,
|
||||
get_project_listing, update_project,
|
||||
},
|
||||
components::{
|
||||
admin_nav_bar::AdminNavigationBar,
|
||||
datepicker::DatePicker,
|
||||
dropdown::DropDown,
|
||||
media_picker::MediaPicker,
|
||||
textfield::{TextField, TextFieldType}, new_widget::NewThingWidget,
|
||||
}, pages::admin::units::AdminUnits,
|
||||
new_widget::NewThingWidget,
|
||||
textfield::{TextField, TextFieldType},
|
||||
},
|
||||
pages::admin::units::AdminUnits,
|
||||
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.
|
||||
@ -70,7 +80,7 @@ pub fn edit_page(props: &AdminEditPageProps) -> Html {
|
||||
{
|
||||
match props.edit_item {
|
||||
EditItem::Agent => {html! {}},
|
||||
EditItem::Project => {html! { <ProjectFields listing={(*listing).clone()}/> }},
|
||||
EditItem::Project => {html! { <ProjectFields listing={(*listing).clone()} edittype={props.edit_type.clone()}/> }},
|
||||
EditItem::Unit(_) => {html! {}},
|
||||
}
|
||||
}
|
||||
@ -104,11 +114,13 @@ pub struct AdminEditPageProps {
|
||||
#[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();
|
||||
|
||||
@ -228,6 +240,154 @@ pub fn generate_fields_for_project(props: &ProjectFieldsProps) -> Html {
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
//TODO: Create the location first.
|
||||
//TODO: Then send the updateprojectpayload.
|
||||
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! {
|
||||
<>
|
||||
@ -313,7 +473,7 @@ pub fn generate_fields_for_project(props: &ProjectFieldsProps) -> Html {
|
||||
<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"}>
|
||||
<div class={"admin-edit-submit-button"} onclick={update_button_onclick}>
|
||||
{"Actualizar"}
|
||||
</div>
|
||||
<AdminUnits units={(*units).clone()}/>
|
||||
|
@ -4,4 +4,4 @@ pub mod edit;
|
||||
pub mod login;
|
||||
pub mod projects;
|
||||
pub mod start;
|
||||
pub mod units;
|
||||
pub mod units;
|
||||
|
@ -1,11 +1,7 @@
|
||||
use jl_types::domain::unit::Unit;
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::{
|
||||
components::{
|
||||
admin_unit::AdminUnit,
|
||||
},
|
||||
};
|
||||
use crate::components::admin_unit::AdminUnit;
|
||||
|
||||
#[function_component(AdminUnits)]
|
||||
pub fn admin_units(props: &AdminUnitProps) -> Html {
|
||||
@ -27,5 +23,5 @@ pub fn admin_units(props: &AdminUnitProps) -> Html {
|
||||
|
||||
#[derive(PartialEq, Properties, Clone)]
|
||||
pub struct AdminUnitProps {
|
||||
pub units: Vec<Unit>
|
||||
}
|
||||
pub units: Vec<Unit>,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user