diff --git a/web/src/lib.rs b/web/src/lib.rs index db5b4b8..dce2c6c 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -136,7 +136,10 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders) { } #[cfg(debug_assertions)] Msg::Debug(msg) => { - crate::debug::update(msg, model); + debug::update(msg, model); + } + Msg::Cart(msg) => { + shopping_cart::update(msg, model, orders); } } } diff --git a/web/src/pages.rs b/web/src/pages.rs index a158fcb..6c9b92e 100644 --- a/web/src/pages.rs +++ b/web/src/pages.rs @@ -15,6 +15,7 @@ pub enum Msg { UrlChanged(subs::UrlChanged), Shared(shared::SharedMsg), Session(crate::session::SessionMsg), + Cart(crate::shopping_cart::CartMsg), #[cfg(debug_assertions)] Debug(crate::debug::DebugMsg), } diff --git a/web/src/pages/public/listing.rs b/web/src/pages/public/listing.rs index 98cf670..ab2f9eb 100644 --- a/web/src/pages/public/listing.rs +++ b/web/src/pages/public/listing.rs @@ -1,11 +1,13 @@ use std::collections::{HashMap, HashSet}; +use model::Quantity; use seed::app::Orders; use seed::prelude::*; use seed::*; use crate::api::NetRes; use crate::pages::Urls; +use crate::shopping_cart::CartMsg; #[derive(Debug)] pub struct ListingPage { @@ -20,7 +22,7 @@ pub struct ListingPage { #[derive(Debug)] pub enum Msg { FetchProducts, - ProductFetched(crate::api::NetRes), + ProductFetched(NetRes), } pub fn init(url: Url, orders: &mut impl Orders) -> ListingPage { @@ -69,11 +71,15 @@ fn filter_products(model: &mut ListingPage) { .collect(); } -pub fn update(msg: Msg, model: &mut ListingPage, orders: &mut impl Orders) { +pub fn update(msg: Msg, model: &mut ListingPage, orders: &mut impl Orders) { match msg { Msg::FetchProducts => { orders.skip().perform_cmd({ - async { Msg::ProductFetched(crate::api::public::fetch_products().await) } + async { + crate::Msg::Public( + Msg::ProductFetched(crate::api::public::fetch_products().await).into(), + ) + } }); } Msg::ProductFetched(NetRes::Success(products)) => { @@ -109,7 +115,7 @@ pub fn update(msg: Msg, model: &mut ListingPage, orders: &mut impl Orders) } pub fn view(model: &crate::Model, page: &ListingPage) -> Node { - let products: Vec> = if page.visible_products.is_empty() { + let products: Vec> = if page.visible_products.is_empty() { page.product_ids .iter() .filter_map(|id| page.products.get(id)) @@ -135,7 +141,7 @@ pub fn view(model: &crate::Model, page: &ListingPage) -> Node { ] } -fn product(model: &crate::Model, product: &model::api::Product) -> Node { +fn product(model: &crate::Model, product: &model::api::Product) -> Node { use rusty_money::{iso, Money}; let price = Money::from_minor(**product.price as i64, iso::PLN).to_string(); @@ -151,6 +157,9 @@ fn product(model: &crate::Model, product: &model::api::Product) -> Node { .product() .add_path_part((*product.id as i32).to_string()); + let quantity_unit = product.quantity_unit; + let product_id = product.id; + div![ C!["w-full px-4 lg:px-0"], div![ @@ -181,7 +190,16 @@ fn product(model: &crate::Model, product: &model::api::Product) -> Node { C!["flex items-center justify-between"], a![ C!["px-6 py-2 text-sm text-white bg-indigo-500 rounded-lg outline-none hover:bg-indigo-600 ring-indigo-300"], - model.i18n.t("Add to Cart") + ev(Ev::Click, move |ev| { + ev.prevent_default(); + ev.stop_propagation(); + crate::Msg::from(CartMsg::AddItem { + product_id, + quantity_unit, + quantity: Quantity::try_from(1).unwrap_or_default() + }) + }), + model.i18n.t("Add to Cart"), ], div![C!["mt-1 text-xl font-semibold"], price], ] diff --git a/web/src/pages/public/product.rs b/web/src/pages/public/product.rs index 4986020..5400b7a 100644 --- a/web/src/pages/public/product.rs +++ b/web/src/pages/public/product.rs @@ -5,7 +5,7 @@ use crate::api::NetRes; #[derive(Debug)] pub enum Msg { - ProductFetched(crate::api::NetRes), + ProductFetched(NetRes), SelectImage(usize), } @@ -33,7 +33,7 @@ pub fn init(mut url: Url, orders: &mut impl Orders) -> ProductPage { pub fn page_changed(_url: Url, _model: &mut ProductPage) {} -pub fn update(msg: Msg, model: &mut ProductPage, _orders: &mut impl Orders) { +pub fn update(msg: Msg, model: &mut ProductPage, _orders: &mut impl Orders) { match msg { Msg::ProductFetched(NetRes::Success(product)) => { model.product = Some(product); diff --git a/web/src/pages/public/sign_in.rs b/web/src/pages/public/sign_in.rs index 7f07583..0cc452f 100644 --- a/web/src/pages/public/sign_in.rs +++ b/web/src/pages/public/sign_in.rs @@ -25,7 +25,7 @@ pub fn init(mut _url: Url, _orders: &mut impl Orders) -> SignInPage { pub fn page_changed(_url: Url, _model: &mut SignInPage) {} -pub fn update(_msg: Msg, _model: &mut SignInPage, _orders: &mut impl Orders) {} +pub fn update(_msg: Msg, _model: &mut SignInPage, _orders: &mut impl Orders) {} pub fn view(model: &crate::Model, page: &SignInPage) -> Node { let home = Urls::new(&model.url).home(); diff --git a/web/src/pages/public/sign_up.rs b/web/src/pages/public/sign_up.rs index eb697c3..fa7d863 100644 --- a/web/src/pages/public/sign_up.rs +++ b/web/src/pages/public/sign_up.rs @@ -35,7 +35,7 @@ pub fn init(mut _url: Url, _orders: &mut impl Orders) -> SignUpPage { pub fn page_changed(_url: Url, _model: &mut SignUpPage) {} -pub fn update(msg: Msg, model: &mut SignUpPage, orders: &mut impl Orders) { +pub fn update(msg: Msg, model: &mut SignUpPage, orders: &mut impl Orders) { match msg { Msg::LoginChanged(value) => { model.login = Login::new(value); @@ -58,14 +58,17 @@ pub fn update(msg: Msg, model: &mut SignUpPage, orders: &mut impl Orders) { let password_confirmation = model.password_confirmation.clone(); orders.perform_cmd(async move { - Msg::AccountCreated( - crate::api::public::sign_up(model::api::CreateAccountInput { - email, - login, - password, - password_confirmation, - }) - .await, + crate::Msg::Public( + Msg::AccountCreated( + crate::api::public::sign_up(model::api::CreateAccountInput { + email, + login, + password, + password_confirmation, + }) + .await, + ) + .into(), ) }); } diff --git a/web/src/shopping_cart.rs b/web/src/shopping_cart.rs index a58fc06..0f7f04e 100644 --- a/web/src/shopping_cart.rs +++ b/web/src/shopping_cart.rs @@ -18,7 +18,13 @@ pub enum CartMsg { }, } -pub type Items = indexmap::IndexMap; +impl From for Msg { + fn from(msg: CartMsg) -> Self { + Msg::Cart(msg) + } +} + +pub type Items = indexmap::IndexMap; #[derive(Debug, Serialize, Deserialize)] pub struct Item {