Start cart
This commit is contained in:
parent
09d7369b0c
commit
e215bbe003
@ -8,6 +8,7 @@ mod model;
|
||||
mod pages;
|
||||
pub mod session;
|
||||
pub mod shared;
|
||||
pub mod shopping_cart;
|
||||
|
||||
use seed::empty;
|
||||
use seed::prelude::*;
|
||||
@ -81,10 +82,12 @@ fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
|
||||
.and_then(|el: web_sys::Element| el.get_attribute("href")),
|
||||
shared: shared::Model::default(),
|
||||
i18n: I18n::load(),
|
||||
cart: Default::default(),
|
||||
#[cfg(debug_assertions)]
|
||||
debug_modal: false,
|
||||
};
|
||||
|
||||
shopping_cart::init(&mut model, orders);
|
||||
session::init(&mut model, orders);
|
||||
shared::init(&mut model, orders);
|
||||
|
||||
@ -101,7 +104,7 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
orders.skip();
|
||||
}
|
||||
Msg::Shared(msg) => {
|
||||
shared::update(msg, &mut model.shared, orders);
|
||||
shared::update(msg, model, orders);
|
||||
}
|
||||
Msg::UrlChanged(subs::UrlChanged(url)) => model.page.page_changed(url, orders),
|
||||
Msg::Public(pages::public::Msg::Listing(msg)) => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use seed::Url;
|
||||
|
||||
use crate::{I18n, Page};
|
||||
use crate::{I18n, Page, shopping_cart};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Model {
|
||||
@ -10,6 +10,7 @@ pub struct Model {
|
||||
pub logo: Option<String>,
|
||||
pub shared: crate::shared::Model,
|
||||
pub i18n: I18n,
|
||||
pub cart: shopping_cart::ShoppingCart,
|
||||
#[cfg(debug_assertions)]
|
||||
pub debug_modal: bool,
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ pub enum Msg {
|
||||
Public(public::Msg),
|
||||
Admin(admin::Msg),
|
||||
UrlChanged(subs::UrlChanged),
|
||||
Shared(shared::Msg),
|
||||
Shared(shared::SharedMsg),
|
||||
Session(crate::session::SessionMsg),
|
||||
#[cfg(debug_assertions)]
|
||||
Debug(crate::debug::DebugMsg),
|
||||
|
@ -2,8 +2,9 @@ use chrono::{NaiveDateTime, TimeZone};
|
||||
use model::{AccessTokenString, RefreshTokenString};
|
||||
use seed::prelude::*;
|
||||
|
||||
use crate::pages::AdminPage;
|
||||
use crate::shared::notification::NotificationMsg;
|
||||
use crate::{Model, Msg};
|
||||
use crate::{pages, Model, Msg, Page, PublicPage};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SessionMsg {
|
||||
@ -29,11 +30,40 @@ pub fn init(model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
.ok()
|
||||
.map(model::RefreshTokenString::new);
|
||||
model.shared.exp = LocalStorage::get::<_, String>("exp").ok().and_then(|s| {
|
||||
seed::log!("Parsing ", s);
|
||||
chrono::DateTime::parse_from_rfc3339(&s)
|
||||
.ok()
|
||||
.map(|t| t.naive_utc())
|
||||
})
|
||||
});
|
||||
redirect_on_session(model, orders);
|
||||
}
|
||||
|
||||
pub fn redirect_on_session(model: &Model, orders: &mut impl Orders<Msg>) {
|
||||
seed::log!(&model.page, model.shared.me.is_some());
|
||||
match &model.page {
|
||||
Page::Admin(admin) => match admin {
|
||||
AdminPage::Landing => {}
|
||||
AdminPage::Dashboard => {}
|
||||
AdminPage::Products => {}
|
||||
AdminPage::Product => {}
|
||||
},
|
||||
Page::Public(public) if model.shared.me.is_some() => match public {
|
||||
PublicPage::SignUp(_) | PublicPage::SignIn(_) => {
|
||||
let url = model.url.clone().set_path(&[] as &[&str]);
|
||||
url.go_and_push();
|
||||
orders.send_msg(crate::Msg::UrlChanged(subs::UrlChanged(url)));
|
||||
orders.force_render_now();
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Page::Public(public) => match public {
|
||||
PublicPage::Listing(_) => {}
|
||||
PublicPage::Product(_) => {}
|
||||
PublicPage::SignIn(_) => {}
|
||||
PublicPage::SignUp(_) => {}
|
||||
PublicPage::ShoppingCart => {}
|
||||
PublicPage::Checkout => {}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(msg: SessionMsg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
@ -103,7 +133,7 @@ pub fn update(msg: SessionMsg, model: &mut Model, orders: &mut impl Orders<Msg>)
|
||||
errors.into_iter().for_each(|msg| {
|
||||
orders
|
||||
.skip()
|
||||
.send_msg(Msg::Shared(crate::shared::Msg::Notification(
|
||||
.send_msg(Msg::Shared(crate::shared::SharedMsg::Notification(
|
||||
NotificationMsg::Error(msg),
|
||||
)));
|
||||
});
|
||||
@ -133,7 +163,7 @@ pub fn update(msg: SessionMsg, model: &mut Model, orders: &mut impl Orders<Msg>)
|
||||
_ => {
|
||||
orders
|
||||
.skip()
|
||||
.send_msg(Msg::Shared(crate::shared::Msg::Notification(
|
||||
.send_msg(Msg::Shared(crate::shared::SharedMsg::Notification(
|
||||
NotificationMsg::Error("Request failed".into()),
|
||||
)));
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
use seed::app::Orders;
|
||||
|
||||
use crate::session::redirect_on_session;
|
||||
|
||||
pub mod notification;
|
||||
pub mod view;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Msg {
|
||||
pub enum SharedMsg {
|
||||
LoadMe,
|
||||
MeLoaded(crate::api::NetRes<model::Account>),
|
||||
SignIn(model::api::SignInInput),
|
||||
SignedIn(crate::api::NetRes<model::api::SessionOutput>),
|
||||
Notification(crate::shared::notification::NotificationMsg),
|
||||
Notification(notification::NotificationMsg),
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@ -22,38 +24,38 @@ pub struct Model {
|
||||
}
|
||||
|
||||
pub fn init(_model: &mut crate::Model, orders: &mut impl Orders<crate::Msg>) {
|
||||
orders.send_msg(crate::Msg::Shared(Msg::LoadMe));
|
||||
orders.send_msg(crate::Msg::Shared(SharedMsg::LoadMe));
|
||||
}
|
||||
|
||||
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<crate::Msg>) {
|
||||
pub fn update(msg: SharedMsg, model: &mut crate::Model, orders: &mut impl Orders<crate::Msg>) {
|
||||
match msg {
|
||||
Msg::LoadMe => {
|
||||
seed::log!("1");
|
||||
if let Some(token) = model.access_token.as_ref().cloned() {
|
||||
seed::log!("2");
|
||||
SharedMsg::LoadMe => {
|
||||
if let Some(token) = model.shared.access_token.as_ref().cloned() {
|
||||
orders.skip().perform_cmd(async move {
|
||||
seed::log!("3");
|
||||
Msg::MeLoaded(crate::api::public::fetch_me(token).await)
|
||||
crate::Msg::Shared(SharedMsg::MeLoaded(
|
||||
crate::api::public::fetch_me(token).await,
|
||||
))
|
||||
});
|
||||
}
|
||||
}
|
||||
Msg::MeLoaded(crate::api::NetRes::Success(account)) => {
|
||||
model.me = Some(account);
|
||||
SharedMsg::MeLoaded(crate::api::NetRes::Success(account)) => {
|
||||
model.shared.me = Some(account);
|
||||
redirect_on_session(model, orders);
|
||||
}
|
||||
Msg::MeLoaded(crate::api::NetRes::Error(_error)) => {}
|
||||
Msg::MeLoaded(crate::api::NetRes::Http(_error)) => {}
|
||||
Msg::SignIn(input) => {
|
||||
orders
|
||||
.skip()
|
||||
.perform_cmd(async { Msg::SignedIn(crate::api::public::sign_in(input).await) });
|
||||
SharedMsg::MeLoaded(crate::api::NetRes::Error(_error)) => {}
|
||||
SharedMsg::MeLoaded(crate::api::NetRes::Http(_error)) => {}
|
||||
SharedMsg::SignIn(input) => {
|
||||
orders.skip().perform_cmd(async {
|
||||
SharedMsg::SignedIn(crate::api::public::sign_in(input).await)
|
||||
});
|
||||
}
|
||||
Msg::SignedIn(crate::api::NetRes::Success(pair)) => {
|
||||
handle_auth_pair(pair, model, orders);
|
||||
SharedMsg::SignedIn(crate::api::NetRes::Success(pair)) => {
|
||||
handle_auth_pair(pair, &mut model.shared, orders);
|
||||
}
|
||||
Msg::SignedIn(crate::api::NetRes::Error(_err)) => {}
|
||||
Msg::SignedIn(crate::api::NetRes::Http(_err)) => {}
|
||||
Msg::Notification(msg) => {
|
||||
notification::update(msg, model, orders);
|
||||
SharedMsg::SignedIn(crate::api::NetRes::Error(_err)) => {}
|
||||
SharedMsg::SignedIn(crate::api::NetRes::Http(_err)) => {}
|
||||
SharedMsg::Notification(msg) => {
|
||||
notification::update(msg, &mut model.shared, orders);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ pub enum NotificationMsg {
|
||||
Clear,
|
||||
}
|
||||
|
||||
impl From<NotificationMsg> for shared::Msg {
|
||||
impl From<NotificationMsg> for shared::SharedMsg {
|
||||
fn from(msg: NotificationMsg) -> Self {
|
||||
Self::Notification(msg)
|
||||
}
|
||||
@ -152,7 +152,7 @@ pub fn message(id: uuid::Uuid, message: &str, icon: Type) -> Node<Msg> {
|
||||
ev(Ev::Click, move |ev| {
|
||||
ev.prevent_default();
|
||||
ev.stop_propagation();
|
||||
Msg::Shared(shared::Msg::Notification(NotificationMsg::Close(id)))
|
||||
Msg::Shared(shared::SharedMsg::Notification(NotificationMsg::Close(id)))
|
||||
})
|
||||
]
|
||||
]
|
||||
|
68
web/src/shopping_cart.rs
Normal file
68
web/src/shopping_cart.rs
Normal file
@ -0,0 +1,68 @@
|
||||
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,
|
||||
},
|
||||
}
|
||||
|
||||
pub type Items = indexmap::IndexMap<model::ProductId, Item>;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Item {
|
||||
product_id: ProductId,
|
||||
quantity: Quantity,
|
||||
quantity_unit: QuantityUnit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct ShoppingCart {
|
||||
pub cart_id: Option<model::ShoppingCartId>,
|
||||
pub items: Items,
|
||||
}
|
||||
|
||||
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 = 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::ModifyItem { .. } => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_local() -> ShoppingCart {
|
||||
LocalStorage::get("ct").unwrap_or_default()
|
||||
}
|
||||
fn store_local(cart: &ShoppingCart) {
|
||||
LocalStorage::insert("ct", cart).ok();
|
||||
}
|
Loading…
Reference in New Issue
Block a user