cdb_client/src/page/item_detail.rs
2025-06-07 21:27:12 +02:00

119 lines
3.7 KiB
Rust

use dioxus::prelude::*;
use dioxus_material_icons::MaterialIcon;
use crate::{page::supply::SupplyPageParam, Route, TransactionCard};
#[component]
pub fn ItemDetailPage(id: String) -> Element {
let id = use_signal(|| id.clone());
let item = crate::API.read().as_ref().unwrap().get_item(id()).unwrap();
let inventory_future = use_resource(move || async move {
let item = crate::API.read().as_ref().unwrap().get_item(id()).unwrap();
crate::api::API::get_inventory(item.uuid.clone(), None).await
});
rsx! {
div {
class: "p-4 flex flex-col h-screen",
header {
class: "text-white text-lg font-bold",
{item.name.as_str()}
}
div {
class: "flex flex-col space-y-4",
div {
class: "flex items-start space-x-4",
if let Some(image) = &item.image {
img {
src: crate::API.read().as_ref().unwrap().get_url_instance(image.to_string()),
width: "192",
class: "h-24 w-24"
}
},
div {
strong { "{item.name}" }
if let Some(category) = &item.category {
p { "{category}" }
}
}
}
EventButton {
icon: "pallet",
title: "Supply",
onclick: move |_| {
navigator().push(
Route::SupplyPage {
item: item.uuid.clone(),
param: SupplyPageParam {
only_variants: None,
force_price: None,
force_origin: None,
},
}
);
}
}
div {
class: "grid grid-cols-2 gap-4",
{item.variants.iter().map(|(key, variant)| {
rsx! {
div {
strong { {variant.name.as_str()} }
// TODO : stats
}
}
})}
}
}
div {
class: "flex-1 overflow-auto",
match &*inventory_future.read_unchecked() {
Some(inventory) => {
rsx! {
for t in inventory {
p {
key: {t.uuid.clone()},
TransactionCard { t: t.clone() }
}
}
}
},
None => {
rsx! { p { "Loading inventory..." } }
}
}
}
}
}
}
#[component]
pub fn EventButton(icon: String, title: String, onclick: EventHandler<MouseEvent>) -> Element {
rsx! {
button {
class: "\
flex items-center gap-2 px-3 py-1.5 rounded-md \
text-sm font-medium \
border border-neutral-300 dark:border-neutral-700 \
text-neutral-800 dark:text-neutral-200 \
bg-white dark:bg-neutral-900 \
hover:bg-neutral-100 dark:hover:bg-neutral-800 \
hover:shadow-sm \
transition-all duration-200 cursor-pointer w-fit",
onclick: onclick,
MaterialIcon {
name: icon,
size: 20
},
{title}
}
}
}