From 7bff22756beec82b4a1470e2d325b706dc56e5f2 Mon Sep 17 00:00:00 2001 From: Benedikt Peetz Date: Thu, 23 Oct 2025 01:36:39 +0200 Subject: feat(buy): Provide basic buy interface --- src/components/buy.rs | 212 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 182 insertions(+), 30 deletions(-) (limited to 'src/components/buy.rs') diff --git a/src/components/buy.rs b/src/components/buy.rs index 6d9402e..cb4cff4 100644 --- a/src/components/buy.rs +++ b/src/components/buy.rs @@ -1,41 +1,193 @@ -use leptos::{IntoView, component, view}; +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 rocie_client::models::UnitId; +use reactive_stores::Store; +use rocie_client::{ + apis::Error, + models::{Product, Unit}, +}; use uuid::Uuid; -use crate::components::{form::Form, site_header::SiteHeader}; +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_barcode, amount, unit_id| { - info!("Got product barcode: {product_barcode} with amount: {amount}, {unit_id}"); - }; - - - - }} + { + 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) } } -- cgit 1.4.1