// rocie - An enterprise grocery management system - Web app // // Copyright (C) 2026 Benedikt Peetz // SPDX-License-Identifier: GPL-3.0-or-later // // This file is part of Rocie. // // You should have received a copy of the License along with this program. // If not, see . use leptos::{ IntoView, component, prelude::{ElementExt, Get, Show, WriteSignal, signal}, task::spawn_local, view, }; use leptos_router::{NavigateOptions, hooks::use_navigate}; use rocie_client::models::{Barcode, BarcodeId, Product, Unit, UnitAmount, UnitId}; use rocie_macros::Form; use uuid::Uuid; use crate::{ api::{ associate_barcode_external_wrapped, get_config, product_by_id_wrapped, product_by_name_404_wrapped, product_by_name_external_wrapped, product_suggestion_by_name_wrapped, unit_by_id_wrapped, unit_property_by_id_wrapped, }, components::{ async_fetch::AsyncResource, banner::Banner, catch_errors::CatchErrors, login_wall::LoginWall, site_header::SiteHeader, }, }; #[component] pub fn AssociateBarcode() -> impl IntoView { let (errors, errors_set) = signal(None); let (show_units, show_units_set) = signal(false); view! { { let product_name_signal; Form! { on_submit = |barcode_id, product_name, amount, unit_id| { let config = get_config!(); let navigate = use_navigate(); spawn_local(async move { let output = async { let product = product_by_name_external_wrapped(&config, product_name.trim()).await?; associate_barcode_external_wrapped(&config, product.id, Barcode { amount:UnitAmount { unit: UnitId { value: unit_id }, value: u32::from(amount), }, id: BarcodeId { value: barcode_id }, }).await?; Ok::<_, leptos::error::Error>(()) }; match output.await { Ok(()) => { navigate("/associate-barcode-product", NavigateOptions::default()); }, Err(err) => { errors_set.set( Some( format!("Could not associate barcode: {err}") ) ); }, } }); }; } } } } 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 = product_suggestion_by_name_wrapped(&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 maybe_product: Option = product_by_name_404_wrapped(&product_name).await?; if let Some(product) = maybe_product { let unit_property = unit_property_by_id_wrapped(product_by_id_wrapped(product.id).await?.unit_property) .await?; let mut units = Vec::with_capacity(unit_property.units.len()); for unit_id in unit_property.units { units.push(unit_by_id_wrapped(unit_id).await?); } Ok(Some(units)) } else { Ok(None) } } else { Ok(None) } }