use leptos::{ IntoView, component, prelude::{Get, Read, Show, WriteSignal, expect_context, signal}, task::spawn_local, view, }; use leptos_router::{NavigateOptions, hooks::use_navigate}; use log::info; use reactive_stores::Store; use rocie_client::{ apis::Error, models::{Product, Unit}, }; use uuid::Uuid; use crate::{ ConfigState, ConfigStateStoreFields, api::{ buy_barcode_wrapper, get_product_by_name, get_product_unit_by_id, get_products_by_part_name, get_unit_by_id, }, components::{async_fetch::AsyncResource, banner::Banner, form::Form, site_header::SiteHeader}, }; #[component] pub fn Buy() -> impl IntoView { let (on_submit_errored, on_submit_errored_set) = signal(None); view! { { Form! { on_submit = |barcode_number, amount| { let config = expect_context::>(); let config = config.config().read(); spawn_local(async move { if let Err(err) = buy_barcode_wrapper(&config, barcode_number).await { let error = format!("Error in form on-submit for barcode `{barcode_number}`: {err}"); on_submit_errored_set.set(Some(error)); } else { on_submit_errored_set.set(None); info!("Bought barcode {barcode_number} {amount} times"); } }); }; } } } } #[component] pub fn AssociateBarcode() -> impl IntoView { let product_name_signal; let (show_units, show_units_set) = signal(false); view! { { Form! { on_submit = |product_name, amount, unit_id| { spawn_local(async move { let navigate = use_navigate(); info!("Got product barcode: {product_name} with amount: {amount}, and {unit_id}"); navigate("/", NavigateOptions::default()); }); }; } } } } async fn generate_suggest_products( optional_product_name: Option, ) -> Result>, leptos::error::Error> { if let Some(product_name) = optional_product_name && !product_name.is_empty() { let products = get_products_by_part_name(product_name).await?; Ok(Some(products.into_iter().map(|prod| prod.name).collect())) } else { Ok(None) } } async fn product_unit_fetcher( optinal_product_name: Option, ) -> Result>, leptos::error::Error> { if let Some(product_name) = optinal_product_name && !product_name.is_empty() { let value: Option = { match get_product_by_name(product_name).await { Ok(ok) => Ok::<_, leptos::error::Error>(Some(ok)), Err(err) => match err { Error::ResponseError(ref response_content) => { match response_content.status.as_u16() { 404 => Ok(None), _ => Err(err.into()), } } err => Err(err.into()), }, }? }; if let Some(value) = value { let (_, unit_property) = get_product_unit_by_id(value.id).await?; let mut units = Vec::with_capacity(unit_property.units.len()); for unit_id in unit_property.units { units.push(get_unit_by_id(unit_id).await?); } Ok(Some(units)) } else { Ok(None) } } else { Ok(None) } }