bazzar/web/src/shopping_cart.rs

114 lines
2.9 KiB
Rust
Raw Normal View History

2022-05-15 14:05:26 +02:00
use model::{ProductId, Quantity, QuantityUnit};
use seed::prelude::*;
use serde::{Deserialize, Serialize};
use crate::{Model, Msg};
#[derive(Debug)]
pub enum CartMsg {
AddItem {
quantity: Quantity,
quantity_unit: QuantityUnit,
product_id: ProductId,
},
ModifyItem {
quantity: Quantity,
quantity_unit: QuantityUnit,
product_id: ProductId,
},
Remove(ProductId),
Hover,
Leave,
2022-05-15 14:05:26 +02:00
}
2022-05-15 19:33:06 +02:00
impl From<CartMsg> for Msg {
fn from(msg: CartMsg) -> Self {
Msg::Cart(msg)
}
}
pub type Items = indexmap::IndexMap<ProductId, Item>;
2022-05-15 14:05:26 +02:00
#[derive(Debug, Serialize, Deserialize)]
pub struct Item {
pub product_id: ProductId,
pub quantity: Quantity,
pub quantity_unit: QuantityUnit,
2022-05-15 14:05:26 +02:00
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct ShoppingCart {
pub cart_id: Option<model::ShoppingCartId>,
pub items: Items,
#[serde(skip)]
pub hover: bool,
2022-05-15 14:05:26 +02:00
}
pub fn init(model: &mut Model, _orders: &mut impl Orders<Msg>) {
model.cart = load_local();
}
pub fn update(msg: CartMsg, model: &mut Model, _orders: &mut impl Orders<Msg>) {
match msg {
CartMsg::AddItem {
quantity,
quantity_unit,
product_id,
} => {
{
let items: &mut Items = &mut model.cart.items;
let entry: &mut Item = items.entry(product_id).or_insert_with(|| Item {
quantity: Quantity::from_u32(0),
2022-05-15 14:05:26 +02:00
quantity_unit,
product_id,
});
entry.quantity = entry.quantity + quantity;
2022-05-15 14:05:26 +02:00
entry.quantity_unit = quantity_unit;
}
store_local(&model.cart);
}
CartMsg::ModifyItem {
product_id,
quantity_unit,
quantity,
} => {
if **quantity == 0 {
model.cart.items.remove(&product_id);
} else {
let items: &mut Items = &mut model.cart.items;
let entry: &mut Item = items.entry(product_id).or_insert_with(|| Item {
quantity,
quantity_unit,
product_id,
});
entry.quantity = quantity;
entry.quantity_unit = quantity_unit;
}
store_local(&model.cart);
}
CartMsg::Remove(product_id) => {
model.cart.items.remove(&product_id);
store_local(&model.cart);
}
CartMsg::Hover => {
model.cart.hover = true;
}
CartMsg::Leave => {
model.cart.hover = false;
}
2022-05-15 14:05:26 +02:00
}
}
fn load_local() -> ShoppingCart {
match LocalStorage::get("ct") {
Ok(cart) => cart,
Err(e) => {
seed::error!("Storage error", e);
ShoppingCart::default()
}
}
2022-05-15 14:05:26 +02:00
}
fn store_local(cart: &ShoppingCart) {
LocalStorage::insert("ct", cart).ok();
}