diff --git a/Cargo.lock b/Cargo.lock index 12ff715..38610fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3641,7 +3641,10 @@ name = "sentryx" version = "0.1.0" dependencies = [ "dioxus", + "js-sys", "lucide-dioxus", + "wasm-bindgen", + "web-sys", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c3a6f35..e84e32b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,10 @@ edition = "2021" [dependencies] dioxus = { version = "0.6.0", features = ["router", "fullstack"] } +js-sys = "0.3.77" lucide-dioxus = { version = "2.15.0", features = ["all-icons"] } +wasm-bindgen = "0.2.100" +web-sys = "0.3.77" [features] default = ["web"] diff --git a/assets/styles/light.css b/assets/styles/light.css deleted file mode 100644 index 72cb05d..0000000 --- a/assets/styles/light.css +++ /dev/null @@ -1,67 +0,0 @@ -:root { - /* States */ - --online: rgb(22 101 52); - --offline: rgb(153, 27, 27); - --warning: rgb(154, 52, 18); - --maintenance: rgb(30, 64, 175); - - /* States bg */ - --online-bg: rgb(220, 252, 231); - --offline-bg: rgb(254, 226, 226); - --warning-bg: rgb(255, 237, 213); - --maintenance-bg: rgb(219, 234, 254); - - /* Overview data */ - --online-ov: #16a34a; - --issue: rgb(234, 71, 12); - --cpu: rgb(37, 99, 235); - --memory: rgb(147, 51, 234); - --storage: rgb(234, 88, 12); - --network: rgb(22 163 74); - - /* Usage levels */ - --low: rgb(34, 197, 94); - --medium: rgb(234, 179, 8); - --high: rgb(239, 68, 68); - - /* Misc */ - --bg: #f1f5f9; - --fg: #0f172a; - --card-bg: #fff; - --progress-bg: rgb(226, 232, 240); - --server-icon-bg: rgb(219 234 254); -} - -.dark { - /* States */ - --online: rgb(34, 197, 94); /* bright green */ - --offline: rgb(248, 113, 113); /* soft red */ - --warning: rgb(251, 191, 36); /* yellow-orange */ - --maintenance: rgb(147, 197, 253); /* light blue */ - - /* States bg */ - --online-bg: rgba(22, 101, 52, 0.417); /* dark green */ - --offline-bg: rgb(153, 27, 27, 0.417); /* dark red */ - --warning-bg: rgb(154, 52, 18, 0.417); /* dark orange */ - --maintenance-bg: rgb(30, 64, 175, 0.417); /* dark blue */ - - /* Overview data */ - --online-ov: #16a34a; - --issue: rgb(234, 71, 12); - --cpu: rgb(37, 99, 235); - --memory: rgb(147, 51, 234); - --storage: rgb(234, 88, 12); - --network: rgb(22 163 74); - - /* Usage levels */ - --low: rgb(74, 222, 128); /* light green */ - --medium: rgb(253, 224, 71); /* light yellow */ - --high: rgb(239, 68, 68); /* red */ - - /* Misc */ - --bg: #0f172a; /* dark navy */ - --fg: #f8fafc; /* light text */ - --card-bg: #141e2f; /* dark card background 141e2f */ - --progress-bg: #27364d; - --server-icon-bg: #243756; -} diff --git a/assets/styles/theme.css b/assets/styles/theme.css new file mode 100644 index 0000000..aab9464 --- /dev/null +++ b/assets/styles/theme.css @@ -0,0 +1,101 @@ +:root { + /* States */ + --online: rgb(22 101 52); + --offline: rgb(153, 27, 27); + --warning: rgb(154, 52, 18); + --maintenance: rgb(30, 64, 175); + + /* States bg */ + --online-bg: rgb(220, 252, 231); + --offline-bg: rgb(254, 226, 226); + --warning-bg: rgb(255, 237, 213); + --maintenance-bg: rgb(219, 234, 254); + + /* Overview data */ + --online-ov: #16a34a; + --issue: rgb(234, 71, 12); + --cpu: rgb(37, 99, 235); + --memory: rgb(147, 51, 234); + --storage: rgb(234, 88, 12); + --network: rgb(22 163 74); + + /* Usage levels */ + --low: rgb(34, 197, 94); + --medium: rgb(234, 179, 8); + --high: rgb(239, 68, 68); + + /* Misc */ + --bg: #f1f5f9; + --fg: #0f172a; + --card-bg: #fff; + --progress-bg: rgb(226, 232, 240); + --server-icon-bg: rgb(219 234 254); +} + +.dark { + /* States */ + --online: rgb(34, 197, 94); /* bright green */ + --offline: rgb(248, 113, 113); /* soft red */ + --warning: rgb(246, 190, 50); /* yellow-orange */ + --maintenance: rgb(147, 197, 253); /* light blue */ + + /* States bg */ + --online-bg: rgba(22, 101, 52, 0.417); /* dark green */ + --offline-bg: rgb(153, 27, 27, 0.417); /* dark red */ + --warning-bg: rgba(102, 67, 21, 0.417); /* dark orange */ + --maintenance-bg: rgb(30, 64, 175, 0.417); /* dark blue */ + + /* Overview data */ + --online-ov: #16a34a; + --issue: rgb(234, 71, 12); + --cpu: rgb(37, 99, 235); + --memory: rgb(147, 51, 234); + --storage: rgb(234, 88, 12); + --network: rgb(22 163 74); + + /* Usage levels */ + --low: rgb(32, 232, 105); /* light green */ + --medium: rgb(237, 201, 20); /* light yellow */ + --high: rgb(232, 54, 54); /* red */ + + /* Misc */ + --bg: #0f172a; /* dark navy */ + --fg: #f8fafc; /* light text */ + --card-bg: #141e2f; /* dark card background 141e2f */ + --progress-bg: #27364d; + --server-icon-bg: #243756; +} + +.black { + /* States */ + --online: rgb(0, 255, 128); /* neon green */ + --offline: rgb(255, 77, 77); /* soft red */ + --warning: rgb(255, 193, 7); /* bright yellow */ + --maintenance: rgb(100, 181, 246); /* light blue */ + + /* States bg (dark, translucent overlays) */ + --online-bg: rgba(0, 128, 64, 0.3); /* deep green */ + --offline-bg: rgba(139, 0, 0, 0.3); /* dark red */ + --warning-bg: rgba(153, 102, 0, 0.3); /* golden brown */ + --maintenance-bg: rgba(25, 118, 210, 0.3);/* muted blue */ + + /* Overview data */ + --online-ov: #00ff80; /* neon green */ + --issue: rgb(255, 85, 0); /* warning orange */ + --cpu: rgb(66, 165, 245); /* light blue */ + --memory: rgb(200, 39, 228); /* purple */ + --storage: rgb(255, 111, 0); /* orange */ + --network: rgb(0, 200, 83); /* green */ + + /* Usage levels */ + --low: rgb(11, 226, 86); /* neon green */ + --medium: rgb(231, 215, 72); /* bright yellow */ + --high: rgb(211, 56, 48); /* red */ + + /* Misc */ + --bg: #000000; /* pure black */ + --fg: #ffffff; /* pure white */ + --card-bg: #0e0e0e; /* almost black card */ + --progress-bg: #1a1a1a; /* very dark grey */ + --server-icon-bg: #111111; /* dark grey */ +} diff --git a/src/cookie.rs b/src/cookie.rs new file mode 100644 index 0000000..f08ae32 --- /dev/null +++ b/src/cookie.rs @@ -0,0 +1,37 @@ +use wasm_bindgen::JsCast; +use web_sys::{window, HtmlDocument}; + +pub fn set_cookie(name: &str, value: &str) { + let Some(document) = window().and_then(|w| w.document()) else { + return; + }; + + let Ok(html_doc) = document.dyn_into::() else { + return; + }; + + let cookie = format!("{name}={value}; path=/"); + let _ = html_doc.set_cookie(&cookie); +} + +pub fn get_cookie(name: &str) -> Option { + let Some(document) = window().and_then(|w| w.document()) else { + return None; + }; + let Ok(html_doc) = document.dyn_into::() else { + return None; + }; + + let Ok(cookie_string) = html_doc.cookie() else { + return None; + }; + for cookie in cookie_string.split(';') { + let cookie = cookie.trim(); + if let Some((k, v)) = cookie.split_once('=') { + if k == name { + return Some(v.to_string()); + } + } + } + None +} diff --git a/src/main.rs b/src/main.rs index 7fd5ab6..513397b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,11 @@ mod backend; mod components; +mod cookie; mod dashboard; mod login; use dioxus::prelude::*; +use web_sys::window; use dashboard::Dashboard; use login::Login; @@ -19,7 +21,7 @@ enum Route { const FAVICON: Asset = asset!("/assets/favicon.ico"); const FONT_CSS: Asset = asset!("/assets/styles/font.css"); -const LIGHT_CSS: Asset = asset!("/assets/styles/light.css"); +const THEME_CSS: Asset = asset!("/assets/styles/theme.css"); fn main() { dioxus::launch(App); @@ -27,10 +29,42 @@ fn main() { #[component] fn App() -> Element { + let mut theme = use_signal(|| String::from("light")); + + use_effect({ + let mut theme = theme.clone(); + move || { + theme.set(cookie::get_cookie("theme").unwrap_or_default()); + } + }); + + use_effect({ + let theme = theme.clone(); + move || { + if let Some(document) = window().and_then(|w| w.document()) { + if let Some(html) = document.document_element() { + html.set_class_name(&*theme.read()); + } + } + } + }); + rsx! { document::Link { rel: "icon", href: FAVICON } document::Link { rel: "stylesheet", href: FONT_CSS } - document::Link { rel: "stylesheet", href: LIGHT_CSS } + document::Link { rel: "stylesheet", href: THEME_CSS } + button { + onclick: move |_| { + let d = match theme.read().as_str() { + "dark" => String::from("black"), + "black" => String::from("light"), + _ => String::from("dark") + }; + cookie::set_cookie("theme", &d); + theme.set(d); + }, + "Click" + } Router:: { } } }