diff --git a/leptos/Cargo.toml b/leptos/Cargo.toml index 347311c..0630cab 100644 --- a/leptos/Cargo.toml +++ b/leptos/Cargo.toml @@ -6,10 +6,11 @@ edition = "2024" [dependencies] codee = { version = "0.3.0", features = ["json_serde"] } console_error_panic_hook = "0.1.7" -leptos = { version = "0.7.7", features = ["csr", "nightly"] } +leptos = { version = "0.7.7", features = ["csr", "nightly", "tracing"] } leptos-use = { version = "0.15.7", features = ["storage", "docs" ] } leptos_meta = "0.7.7" leptos_router = { version = "0.7.7", features = ["tracing"] } +reactive_stores = "0.1.8" serde = { workspace = true, features = ["derive"] } stylance = "0.5.5" thaw = { version = "0.4.4", features = ["csr", "nightly"] } diff --git a/leptos/Makefile b/leptos/Makefile index 17586e3..4fedb96 100644 --- a/leptos/Makefile +++ b/leptos/Makefile @@ -5,5 +5,11 @@ fmt: # cargo +nightly fmt leptosfmt src +check: + cargo clippy --no-deps -- -Dwarnings + +fix: fmt + cargo clippy --fix --allow-dirty + css: stylance . --output-file app.css diff --git a/leptos/app.css b/leptos/app.css index f5b6371..ebe4e26 100644 --- a/leptos/app.css +++ b/leptos/app.css @@ -1,5 +1,5 @@ // This file is generated from ./src/app.module.scss -.header-bb66a2d { +.header-372e0a1 { } body { @@ -12,11 +12,16 @@ main { margin: 1ex; } -.nav-bb66a2d { +.nav-372e0a1 { display: flex; flex-direction: row; } -.nav-bb66a2d a { +.nav-372e0a1 a { margin: 1ex; } + +.login-372e0a1 { + max-width: 30em; + margin: auto; +} diff --git a/leptos/index.html b/leptos/index.html index d570613..da5515c 100644 --- a/leptos/index.html +++ b/leptos/index.html @@ -4,14 +4,12 @@ - diff --git a/leptos/src/app.module.scss b/leptos/src/_app.module.scss similarity index 83% rename from leptos/src/app.module.scss rename to leptos/src/_app.module.scss index 455fcf0..e598079 100644 --- a/leptos/src/app.module.scss +++ b/leptos/src/_app.module.scss @@ -20,3 +20,8 @@ main { .nav a { margin: 1ex; } + +.login { + max-width: 30em; + margin: auto; +} diff --git a/leptos/src/app.rs b/leptos/src/app.rs index e5dd3f3..0246c53 100644 --- a/leptos/src/app.rs +++ b/leptos/src/app.rs @@ -1,35 +1,31 @@ use leptos::prelude::*; use leptos_router::components::{Route, Router, Routes}; use leptos_router::path; -use leptos_use::storage::use_local_storage; -use codee::string::JsonSerdeCodec; +use reactive_stores::Store; use thaw::*; -use crate::components::home; -use crate::storage::AppState; - -stylance::import_crate_style!( #[allow(dead_code)] app_style, "src/app.module.scss"); +use crate::components::{home, login}; +use crate::storage::GlobalState; #[component] pub fn App() -> impl IntoView { - - let (storage_email, _set_storage_email) = signal("email".to_string()); - let (_state, _set_state, _reset) = use_local_storage::(storage_email); - let theme = RwSignal::new(Theme::light()); + provide_context(Store::new(GlobalState::default())); + view! { -

"Leptos App"

- +

"Rusty App"

+
- +
diff --git a/leptos/src/components/home.rs b/leptos/src/components/home.rs index b1f05b2..e239994 100644 --- a/leptos/src/components/home.rs +++ b/leptos/src/components/home.rs @@ -1,23 +1,19 @@ use leptos::prelude::*; -use leptos::logging::log; -use thaw::*; +use reactive_stores::Store; + +use crate::components::login::{AlreadyLoggedIn, Login}; +use crate::storage::{GlobalState, GlobalStateStoreFields}; #[component] pub fn Home() -> impl IntoView { + let state = expect_context::>(); - let email = RwSignal::new(String::from("")); - let password = RwSignal::new(String::from("")); - - let login_clicked = move |_| { - log!("Login button is clicked"); - log!("Email={} and password={}", email.get(), password.get()); - }; + let logged_in = state.is_logged_in(); + tracing::info!("Already logged in? {}", logged_in.get_untracked()); view! { - - - - - + }> + + } } diff --git a/leptos/src/components/login.rs b/leptos/src/components/login.rs new file mode 100644 index 0000000..1e2eb41 --- /dev/null +++ b/leptos/src/components/login.rs @@ -0,0 +1,51 @@ +// use codee::string::JsonSerdeCodec; +use leptos::prelude::*; +// use leptos_use::storage::use_local_storage; +use reactive_stores::Store; +use thaw::*; + +use crate::css::styles; +use crate::storage::{GlobalState, GlobalStateStoreFields}; + +#[component] +pub fn Login() -> impl IntoView { + let state = expect_context::>(); + let logged_in = state.is_logged_in(); + let email = state.email(); + let password = state.api_key(); + + let login_clicked = move |_| { + tracing::debug!("Login button is clicked. Email={}", email.get_untracked()); + tracing::info!("TODO: implement the login flow here"); + + *logged_in.write() = true; + }; + + view! { + + + + + + } +} + +#[component] +pub fn AlreadyLoggedIn() -> impl IntoView { + let state = expect_context::>(); + let logged_in = state.is_logged_in(); + let email = state.email(); + let password = state.api_key(); + + let logout = move |_| { + tracing::info!("Starting logout..."); + *email.write() = String::default(); + *password.write() = String::default(); + *logged_in.write() = false; + }; + + view! { +
"Already logged in"
+ + } +} diff --git a/leptos/src/components/mod.rs b/leptos/src/components/mod.rs index 429edc7..57b1827 100644 --- a/leptos/src/components/mod.rs +++ b/leptos/src/components/mod.rs @@ -1 +1,2 @@ pub(crate) mod home; +pub(crate) mod login; diff --git a/leptos/src/css.rs b/leptos/src/css.rs new file mode 100644 index 0000000..7758a01 --- /dev/null +++ b/leptos/src/css.rs @@ -0,0 +1,3 @@ +//! css module. + +stylance::import_crate_style!( #[allow(dead_code)] pub styles, "src/_app.module.scss"); diff --git a/leptos/src/main.rs b/leptos/src/main.rs index 7e8df0d..c2b7aab 100644 --- a/leptos/src/main.rs +++ b/leptos/src/main.rs @@ -2,11 +2,13 @@ use tracing_subscriber::fmt; use tracing_subscriber_wasm::MakeConsoleWriter; mod app; -mod storage; mod components; +mod css; +mod storage; fn main() { fmt() + .with_ansi(false) .with_writer(MakeConsoleWriter::default().map_trace_level_to(tracing::Level::DEBUG)) // For some reason, if we don't do this in the browser, we get a runtime error. .without_time() diff --git a/leptos/src/storage.rs b/leptos/src/storage.rs index 2e7d273..751c25f 100644 --- a/leptos/src/storage.rs +++ b/leptos/src/storage.rs @@ -1,6 +1,26 @@ -//! Storage +//! Various storage + +#![allow(dead_code)] + +use reactive_stores::Store; #[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, Default)] -pub struct AppState { +pub(crate) struct LocalStorage { + pub trainer: String, +} + +impl LocalStorage { + /// Key to use in local storage + pub const KEY: &'static str = "login-state"; +} + +/// Global state to be shared across components. +#[derive(Clone, Debug, Default, Store)] +pub struct GlobalState { + /// Current user email. pub email: String, + /// API Key + pub api_key: String, + /// Is user logged in + pub is_logged_in: bool, } diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..65a4f7e --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,12 @@ +newline_style = "unix" +use_field_init_shorthand = true +use_try_shorthand = true + +indent_style = "Block" +group_imports = "StdExternalCrate" +# report_todo = "Always" +# report_fixme = "Always" +unstable_features = true +format_strings = true +imports_granularity = "Module" +wrap_comments = true