190 lines
6.6 KiB
Rust
190 lines
6.6 KiB
Rust
use crate::{
|
|
capsules::{
|
|
forgot_password_form::{ForgotPasswordFormProps, FORGOT_PASSWORD_FORM},
|
|
login_form::{LoginFormProps, LOGIN_FORM},
|
|
register_form::{RegisterFormProps, REGISTER_FORM},
|
|
},
|
|
components::header::Header,
|
|
global_state::AppStateRx,
|
|
state_enums::{ContentState, OpenState},
|
|
};
|
|
use perseus::prelude::*;
|
|
use sycamore::prelude::*;
|
|
|
|
cfg_if::cfg_if! {
|
|
if #[cfg(client)] {
|
|
use crate::endpoints::CARD_INFO;
|
|
use crate::templates::get_api_path;
|
|
use crate::models::card::CardTable;
|
|
}
|
|
}
|
|
|
|
#[derive(Prop)]
|
|
pub struct LayoutProps<'a, G: Html> {
|
|
pub content_state: ContentState,
|
|
pub children: Children<'a, G>,
|
|
}
|
|
|
|
// Using elements from here: https://flowbite.com/docs/components/buttons/
|
|
|
|
#[component]
|
|
pub fn Layout<'a, G: Html>(
|
|
cx: Scope<'a>,
|
|
LayoutProps {
|
|
content_state,
|
|
children,
|
|
}: LayoutProps<'a, G>,
|
|
) -> View<G> {
|
|
let global_state = Reactor::<G>::from_cx(cx).get_global_state::<AppStateRx>(cx);
|
|
// Set the theme
|
|
// TODO use theme for pages
|
|
global_state.style.theme.current.set(match content_state {
|
|
ContentState::None => (*global_state.style.theme.default.get()).clone(),
|
|
_ => (*global_state.style.theme.default.get()).clone(),
|
|
});
|
|
#[cfg(client)]
|
|
let _ = web_sys::window()
|
|
.unwrap()
|
|
.document()
|
|
.unwrap()
|
|
.document_element()
|
|
.unwrap()
|
|
.set_attribute("data-theme", &global_state.style.theme.current.get());
|
|
|
|
let children = children.call(cx);
|
|
|
|
// Check if the client is authenticated or not
|
|
#[cfg(client)]
|
|
global_state.auth.detect_state();
|
|
|
|
let content_state_header = content_state.clone();
|
|
|
|
#[cfg(client)]
|
|
{
|
|
// TODO -> try to use suspense
|
|
spawn_local_scoped(cx, async move {
|
|
let global_state = Reactor::<G>::from_cx(cx).get_global_state::<AppStateRx>(cx);
|
|
|
|
let local_card_user_pref = (*global_state.user_pref.local_card_data.get()).clone();
|
|
let card_table_loaded = (*global_state.constants.is_loaded.get()).clone();
|
|
if local_card_user_pref && !card_table_loaded {
|
|
let client = reqwest::Client::new();
|
|
let response = client
|
|
.get(get_api_path(CARD_INFO).as_str())
|
|
.send()
|
|
.await
|
|
.unwrap();
|
|
|
|
// TODO add error handling
|
|
let response = response.json::<CardTable>().await.unwrap();
|
|
global_state.constants.card_table.set(Some(response));
|
|
global_state.constants.is_loaded.set(true);
|
|
}
|
|
});
|
|
}
|
|
|
|
view! { cx,
|
|
// Main page header, including login functionality
|
|
Header(content_state = content_state_header)
|
|
|
|
// Modals
|
|
section(class = "flex-2") {
|
|
// (match (*global_state.constants.card_table.get()).clone() {
|
|
// Some(card_table) => { view!{ cx,
|
|
// p { "DONE" }
|
|
// } },
|
|
// None => { view!{ cx, p { "Loading cards" } } },
|
|
// })
|
|
|
|
(match *global_state.modals_open.login.get() {
|
|
OpenState::Open => {
|
|
view! { cx,
|
|
(LOGIN_FORM.widget(cx, "",
|
|
LoginFormProps{
|
|
remember_me: true,
|
|
}
|
|
))
|
|
}
|
|
}
|
|
OpenState::Closed => {
|
|
view!{ cx, }
|
|
}
|
|
})
|
|
(match *global_state.modals_open.register.get() {
|
|
OpenState::Open => {
|
|
view! { cx,
|
|
(REGISTER_FORM.widget(cx, "",
|
|
RegisterFormProps{
|
|
registration_code: true,
|
|
nickname: true,
|
|
email: true,
|
|
}
|
|
))
|
|
}
|
|
}
|
|
OpenState::Closed => {
|
|
view!{ cx, }
|
|
}
|
|
})
|
|
(match *global_state.modals_open.forgot_password.get() {
|
|
OpenState::Open => {
|
|
view! { cx,
|
|
(FORGOT_PASSWORD_FORM.widget(cx, "",
|
|
ForgotPasswordFormProps{}
|
|
))
|
|
}
|
|
}
|
|
OpenState::Closed => {
|
|
view!{ cx, }
|
|
}
|
|
})
|
|
}
|
|
|
|
main(style = "my-8") {
|
|
(match content_state {
|
|
ContentState::Inventory => view!{ cx,
|
|
// Body header
|
|
div (class = "container mx-auto px-6 py-3") {
|
|
nav (class = "sm:flex sm:justify-center sm:items-center mt-4") {
|
|
div (class = "flex flex-col sm:flex-row"){
|
|
a(href = "inventory",
|
|
class = "mt-3 text-gray-600 hover:underline sm:mx-3 sm:mt-0"
|
|
) { "Inventory" }
|
|
}
|
|
}
|
|
}
|
|
// Content body
|
|
div(class = "container mx-auto px-6") {
|
|
div(class = "md:flex mt-8 md:-mx-4") {
|
|
div(class = "rounded-md overflow-hidden bg-cover bg-center") {
|
|
(children)
|
|
}
|
|
}
|
|
}
|
|
},
|
|
ContentState::User => view!{ cx,
|
|
// Body header
|
|
div (class = "container mx-auto px-6 py-3") {
|
|
nav (class = "sm:flex sm:justify-center sm:items-center mt-4") {
|
|
div (class = "flex flex-col sm:flex-row"){
|
|
a(href = "inventory",
|
|
class = "mt-3 text-gray-600 hover:underline sm:mx-3 sm:mt-0"
|
|
) { "User Preferences" }
|
|
}
|
|
}
|
|
}
|
|
// Content body
|
|
div(class = "container mx-auto px-6") {
|
|
div(class = "md:flex mt-8 md:-mx-4") {
|
|
div(class = "rounded-md overflow-hidden bg-cover bg-center") {
|
|
(children)
|
|
}
|
|
}
|
|
}
|
|
},
|
|
_ => view!{ cx, },
|
|
})
|
|
}
|
|
}
|
|
}
|