cdb_client/src/page/supply.rs
JMARyA b3a96ed3e3
init
rewrite of cdb_ui in dioxus rust. goal is to integrate into a single rust codebase
2025-05-25 20:03:42 +02:00

127 lines
3.7 KiB
Rust

use std::str::FromStr;
use dioxus::prelude::*;
use serde::{Deserialize, Serialize};
use crate::{api, page::consume::PredefinedSelector, Route};
#[component]
pub fn SupplyPage(item: String, param: SupplyPageParam) -> Element {
let item_spec = crate::API
.read()
.as_ref()
.unwrap()
.get_item(item.clone())
.unwrap();
// TODO : filter with onlyVariants
let variants = use_signal(|| {
item_spec
.variants
.into_iter()
.map(|x| x.1)
.collect::<Vec<_>>()
});
let variant = use_signal(|| variants.first().unwrap().clone());
let (item, variant) = (use_signal(|| item.clone()), use_signal(|| variant.clone()));
let origins = use_resource(move || async move {
api::API::get_unique_field(
item(),
variant().read().variant.clone(),
"origin".to_string(),
)
.await
});
let variants_str =
use_resource(
move || async move { variants.iter().map(|x| x.name.clone()).collect::<Vec<_>>() },
);
let variant_id = use_signal(|| String::new());
let origin = use_signal(|| String::new());
let mut price = use_signal(|| 0.0);
let location = use_signal(|| String::new());
let mut note = use_signal(|| String::new());
let mut state = use_signal(|| String::new());
rsx! {
h1 { "Add new Item" },
p { {state} },
// Variant Selection
PredefinedSelector {
name: "Variant",
value: variant_id,
predefined: variants_str
}
// Origin Field with Dropdown and Text Input
PredefinedSelector {
name: "Origin",
value: origin,
predefined: origins
}
// Price Field
label {
"Price: ",
input {
r#type: "number",
value: "{price}",
oninput: move |e| price.set(e.value().parse().unwrap())
}
},
// Location Dropdown
// Note
label {
"Note: ",
input {
r#type: "text",
value: "{note}",
oninput: move |e| note.set(e.value())
}
},
// Submit Button
button {
onclick: move |_| {
spawn(async move {
let variant = variants.iter().find(|x| x.name == variant_id()).unwrap().variant.clone();
let s = format!("{} {} {} {} {} {}", item(), variant, price(), origin(), location(), note());
state.set(s);
let tid = crate::api::API::supply_item(item(), variant, price(), Some(origin()), Some(location()), Some(note())).await;
navigator().replace(Route::TransactionPage { id: tid });
});
},
"Create"
}
}
}
#[derive(Clone, PartialEq, Debug, Default, Deserialize, Serialize)]
pub struct SupplyPageParam {
pub onlyVariants: Option<Vec<String>>,
pub forcePrice: Option<f64>,
pub forceOrigin: Option<String>,
}
impl std::fmt::Display for SupplyPageParam {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&serde_json::to_string(self).unwrap())
}
}
impl FromStr for SupplyPageParam {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
serde_json::from_str(s)
}
}