2022-05-15 10:30:15 +02:00
|
|
|
#![feature(try_trait_v2)]
|
|
|
|
|
2022-05-09 16:17:27 +02:00
|
|
|
pub mod api;
|
2022-05-15 13:08:42 +02:00
|
|
|
#[cfg(debug_assertions)]
|
|
|
|
mod debug;
|
2022-05-10 08:23:35 +02:00
|
|
|
mod i18n;
|
2022-05-05 16:30:25 +02:00
|
|
|
mod model;
|
|
|
|
mod pages;
|
2022-05-15 10:30:15 +02:00
|
|
|
pub mod session;
|
2022-05-09 16:41:11 +02:00
|
|
|
pub mod shared;
|
2022-05-15 14:05:26 +02:00
|
|
|
pub mod shopping_cart;
|
2022-05-05 16:30:25 +02:00
|
|
|
|
|
|
|
use seed::empty;
|
|
|
|
use seed::prelude::*;
|
|
|
|
|
2022-05-17 16:04:29 +02:00
|
|
|
use crate::api::NetRes;
|
2022-05-12 16:05:58 +02:00
|
|
|
use crate::i18n::I18n;
|
2022-05-09 16:17:27 +02:00
|
|
|
use crate::model::Model;
|
2022-05-16 20:29:48 +02:00
|
|
|
use crate::pages::{AdminPage, Msg, Page, PublicPage};
|
2022-05-15 10:30:15 +02:00
|
|
|
use crate::session::SessionMsg;
|
2022-05-05 16:30:25 +02:00
|
|
|
|
2022-05-11 15:56:41 +02:00
|
|
|
#[macro_export]
|
2022-05-09 16:17:27 +02:00
|
|
|
macro_rules! fetch_page {
|
|
|
|
(public $model: expr, $page: ident, $ret: expr) => {{
|
|
|
|
let p = match &mut $model.page {
|
|
|
|
crate::pages::Page::Public(p) => p,
|
|
|
|
_ => return $ret,
|
|
|
|
};
|
|
|
|
match p {
|
|
|
|
crate::pages::PublicPage::$page(p) => p,
|
|
|
|
_ => return $ret,
|
|
|
|
}
|
|
|
|
}};
|
2022-05-16 20:29:48 +02:00
|
|
|
(admin $model: expr, $page: ident, $ret: expr) => {{
|
|
|
|
let p = match &mut $model.page {
|
|
|
|
crate::pages::Page::Admin(p) => p,
|
|
|
|
_ => return $ret,
|
|
|
|
};
|
|
|
|
match p {
|
|
|
|
crate::pages::AdminPage::$page(p) => p,
|
|
|
|
_ => return $ret,
|
|
|
|
}
|
|
|
|
}};
|
2022-05-11 15:56:41 +02:00
|
|
|
(public $model: expr, $page: ident) => {{
|
|
|
|
let p = match &mut $model.page {
|
|
|
|
crate::pages::Page::Public(p) => p,
|
|
|
|
_ => return,
|
|
|
|
};
|
|
|
|
match p {
|
|
|
|
crate::pages::PublicPage::$page(p) => p,
|
|
|
|
_ => return,
|
|
|
|
}
|
|
|
|
}};
|
2022-05-16 20:29:48 +02:00
|
|
|
(admin $model: expr, $page: ident) => {{
|
|
|
|
let p = match &mut $model.page {
|
|
|
|
crate::pages::Page::Admin(p) => p,
|
|
|
|
_ => return,
|
|
|
|
};
|
|
|
|
match p {
|
|
|
|
crate::pages::AdminPage::$page(p) => p,
|
|
|
|
_ => return,
|
|
|
|
}
|
|
|
|
}};
|
2022-05-11 15:56:41 +02:00
|
|
|
(public page $page: expr, $page_name: ident) => {{
|
|
|
|
let p = match $page {
|
|
|
|
crate::pages::Page::Public(p) => p,
|
|
|
|
_ => return,
|
|
|
|
};
|
|
|
|
match p {
|
|
|
|
crate::pages::PublicPage::$page_name(p) => p,
|
|
|
|
_ => return,
|
|
|
|
}
|
|
|
|
}};
|
2022-05-12 08:38:31 +02:00
|
|
|
(public page $page: expr, $page_name: ident, $ret: expr) => {{
|
|
|
|
let p = match $page {
|
|
|
|
crate::pages::Page::Public(p) => p,
|
|
|
|
_ => {
|
|
|
|
*$page = $ret;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
match p {
|
|
|
|
crate::pages::PublicPage::$page_name(p) => p,
|
|
|
|
_ => {
|
|
|
|
*$page = $ret;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}};
|
2022-05-16 20:29:48 +02:00
|
|
|
(admin page $page: expr, $page_name: ident, $ret: expr) => {{
|
|
|
|
let p = match $page {
|
|
|
|
crate::pages::Page::Admin(p) => p,
|
|
|
|
_ => {
|
|
|
|
*$page = $ret;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
match p {
|
|
|
|
crate::pages::AdminPage::$page_name(p) => p,
|
|
|
|
_ => {
|
|
|
|
*$page = $ret;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}};
|
2022-05-09 16:17:27 +02:00
|
|
|
}
|
|
|
|
|
2022-05-05 16:30:25 +02:00
|
|
|
fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
|
2022-05-17 16:04:29 +02:00
|
|
|
orders
|
|
|
|
.subscribe(Msg::UrlChanged)
|
|
|
|
.perform_cmd(async { Msg::Config(crate::api::public::config().await) });
|
2022-05-10 16:20:37 +02:00
|
|
|
|
2022-05-15 10:30:15 +02:00
|
|
|
let mut model = Model {
|
2022-05-11 15:56:41 +02:00
|
|
|
url: url.clone().set_path(&[] as &[&str]),
|
2022-05-05 16:30:25 +02:00
|
|
|
token: LocalStorage::get("auth-token").ok(),
|
2022-05-11 15:56:41 +02:00
|
|
|
page: Page::init(url, orders),
|
2022-05-10 16:20:37 +02:00
|
|
|
logo: seed::document()
|
|
|
|
.query_selector("link[rel=icon]")
|
|
|
|
.ok()
|
|
|
|
.flatten()
|
|
|
|
.and_then(|el: web_sys::Element| el.get_attribute("href")),
|
|
|
|
shared: shared::Model::default(),
|
2022-05-12 16:05:58 +02:00
|
|
|
i18n: I18n::load(),
|
2022-05-15 14:05:26 +02:00
|
|
|
cart: Default::default(),
|
2022-05-16 16:08:14 +02:00
|
|
|
|
2022-05-17 16:04:29 +02:00
|
|
|
config: model::Config::default(),
|
2022-05-15 13:08:42 +02:00
|
|
|
#[cfg(debug_assertions)]
|
|
|
|
debug_modal: false,
|
2022-05-15 10:30:15 +02:00
|
|
|
};
|
|
|
|
|
2022-05-15 14:05:26 +02:00
|
|
|
shopping_cart::init(&mut model, orders);
|
2022-05-15 10:30:15 +02:00
|
|
|
session::init(&mut model, orders);
|
2022-05-15 13:08:42 +02:00
|
|
|
shared::init(&mut model, orders);
|
|
|
|
|
|
|
|
#[cfg(debug_assertions)]
|
|
|
|
crate::debug::init(&mut model, orders);
|
2022-05-15 10:30:15 +02:00
|
|
|
|
|
|
|
model
|
2022-05-05 16:30:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
2022-05-16 20:29:48 +02:00
|
|
|
#[cfg(debug_assertions)]
|
|
|
|
if !matches!(msg, Msg::Session(SessionMsg::CheckSession)) {
|
|
|
|
seed::log!("msg", msg);
|
|
|
|
}
|
2022-05-05 16:30:25 +02:00
|
|
|
match msg {
|
2022-05-15 13:08:42 +02:00
|
|
|
#[cfg(debug_assertions)]
|
|
|
|
Msg::NoOp => {
|
|
|
|
orders.skip();
|
|
|
|
}
|
2022-05-17 16:04:29 +02:00
|
|
|
Msg::Config(res) => {
|
|
|
|
if let NetRes::Success(config) = res {
|
|
|
|
model.config = config.into();
|
|
|
|
}
|
|
|
|
}
|
2022-05-10 16:20:37 +02:00
|
|
|
Msg::Shared(msg) => {
|
2022-05-15 14:05:26 +02:00
|
|
|
shared::update(msg, model, orders);
|
2022-05-10 16:20:37 +02:00
|
|
|
}
|
2022-05-12 08:38:31 +02:00
|
|
|
Msg::UrlChanged(subs::UrlChanged(url)) => model.page.page_changed(url, orders),
|
2022-05-18 15:40:50 +02:00
|
|
|
Msg::Public(pages::public::PublicMsg::Listing(msg)) => {
|
2022-05-11 15:56:41 +02:00
|
|
|
let page = fetch_page!(public model, Listing);
|
2022-05-13 15:24:11 +02:00
|
|
|
pages::public::listing::update(msg, page, &mut orders.proxy(Into::into));
|
2022-05-09 16:17:27 +02:00
|
|
|
}
|
2022-05-18 15:40:50 +02:00
|
|
|
Msg::Public(pages::public::PublicMsg::Product(msg)) => {
|
2022-05-11 15:56:41 +02:00
|
|
|
let page = fetch_page!(public model, Product);
|
2022-05-13 15:24:11 +02:00
|
|
|
pages::public::product::update(msg, page, &mut orders.proxy(Into::into))
|
2022-05-11 15:56:41 +02:00
|
|
|
}
|
2022-05-18 15:40:50 +02:00
|
|
|
Msg::Public(pages::public::PublicMsg::SignIn(msg)) => {
|
2022-05-13 15:24:11 +02:00
|
|
|
let page = fetch_page!(public model, SignIn);
|
|
|
|
pages::public::sign_in::update(msg, page, &mut orders.proxy(Into::into))
|
|
|
|
}
|
2022-05-18 15:40:50 +02:00
|
|
|
Msg::Public(pages::public::PublicMsg::SignUp(msg)) => {
|
2022-05-13 15:24:11 +02:00
|
|
|
let page = fetch_page!(public model, SignUp);
|
|
|
|
pages::public::sign_up::update(msg, page, &mut orders.proxy(Into::into))
|
|
|
|
}
|
2022-05-18 15:40:50 +02:00
|
|
|
Msg::Public(pages::public::PublicMsg::ShoppingCart(msg)) => {
|
2022-05-16 16:08:14 +02:00
|
|
|
let page = fetch_page!(public model, ShoppingCart);
|
|
|
|
pages::public::shopping_cart::update(msg, page, &mut orders.proxy(Into::into))
|
|
|
|
}
|
2022-05-18 15:40:50 +02:00
|
|
|
Msg::Public(pages::public::PublicMsg::Checkout(msg)) => {
|
2022-05-28 14:03:14 +02:00
|
|
|
pages::public::checkout::update(msg, model, &mut orders.proxy(Into::into))
|
2022-05-18 15:40:50 +02:00
|
|
|
}
|
|
|
|
// Admin
|
2022-05-16 20:29:48 +02:00
|
|
|
Msg::Admin(pages::admin::Msg::Landing(msg)) => {
|
|
|
|
let page = fetch_page!(admin model, Landing);
|
|
|
|
pages::admin::landing::update(msg, page, &mut orders.proxy(Into::into))
|
|
|
|
}
|
2022-05-15 10:30:15 +02:00
|
|
|
Msg::Session(msg) => {
|
|
|
|
session::update(msg, model, orders);
|
|
|
|
}
|
2022-05-16 16:08:14 +02:00
|
|
|
Msg::Cart(msg) => {
|
|
|
|
shopping_cart::update(msg, model, orders);
|
|
|
|
}
|
2022-05-15 13:08:42 +02:00
|
|
|
#[cfg(debug_assertions)]
|
|
|
|
Msg::Debug(msg) => {
|
2022-05-15 19:33:06 +02:00
|
|
|
debug::update(msg, model);
|
|
|
|
}
|
2022-05-05 16:30:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn view(model: &Model) -> Node<Msg> {
|
2022-05-15 13:08:42 +02:00
|
|
|
let view = match &model.page {
|
2022-05-11 15:56:41 +02:00
|
|
|
Page::Public(PublicPage::Listing(page)) => pages::public::listing::view(model, page),
|
|
|
|
Page::Public(PublicPage::Product(page)) => pages::public::product::view(model, page),
|
2022-05-13 15:24:11 +02:00
|
|
|
Page::Public(PublicPage::SignIn(page)) => pages::public::sign_in::view(model, page),
|
|
|
|
Page::Public(PublicPage::SignUp(page)) => pages::public::sign_up::view(model, page),
|
2022-05-16 16:08:14 +02:00
|
|
|
Page::Public(PublicPage::ShoppingCart(page)) => {
|
|
|
|
pages::public::shopping_cart::view(model, page)
|
|
|
|
}
|
2022-05-18 15:40:50 +02:00
|
|
|
Page::Public(PublicPage::Checkout(page)) => pages::public::checkout::view(model, page),
|
2022-05-16 20:29:48 +02:00
|
|
|
Page::Admin(AdminPage::Landing(page)) => pages::admin::landing::view(model, page),
|
2022-05-05 16:30:25 +02:00
|
|
|
_ => empty![],
|
2022-05-15 13:08:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
if cfg!(debug_assertions) {
|
|
|
|
use seed::*;
|
|
|
|
div![crate::debug::view(model), view]
|
|
|
|
} else {
|
|
|
|
view
|
2022-05-05 16:30:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[wasm_bindgen(start)]
|
|
|
|
pub fn start() {
|
|
|
|
App::start("main", init, update, view);
|
|
|
|
}
|