Skip to content
Draft
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ bundled.css
/assets/gen_assets/
/src/extras/

Cargo.lock

# NixOs output folder
/result

Expand Down
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2024"

[workspace]
exclude = ["design-system-components"]
exclude = ["design-system-components/"]

[lib]
crate-type = ["cdylib", "rlib"]
Expand Down Expand Up @@ -38,7 +38,8 @@ ssr = [
"leptos/ssr",
"leptos_meta/ssr",
"leptos_router/ssr",
"leptos-use/ssr"
"leptos-use/ssr",
"leptos-use/actix"
]
development = []

Expand Down
14 changes: 4 additions & 10 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use leptos_router::{

use crate::{
components::{HeadInformation, Header},
pages::{Aprende, Communities, Index},
pages::{Aprende, Blog, Communities, Events, Index},
};

pub fn shell(options: LeptosOptions) -> impl IntoView {
Expand Down Expand Up @@ -60,16 +60,10 @@ pub fn App() -> impl IntoView {
<Header />
<Routes fallback=|| "Not found.">
<Route path=path!("/") view=Index />
<Route path=path!("comunidad") view=Communities />
// <Route
// path=path!("colaboradores")
// view=Contributors
// />
// <Route
// path=path!("proyectos")
// view=Projects
// />
<Route path=path!("aprende") view=Aprende />
<Route path=path!("comunidad") view=Communities />
<Route path=path!("eventos") view=Events />
<Route path=path!("blog") view=Blog />
</Routes>
</main>
// <Footer />
Expand Down
59 changes: 38 additions & 21 deletions src/components/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ use crate::{
components::icons::{NewLogoRustDarkPageIcon, NewLogoRustLightPageIcon},
context::theme_provider::{Theme, use_theme},
};
use leptos::{leptos_dom::logging::console_log, prelude::*};
use leptos::prelude::*;
use leptos_use::{use_media_query, use_window};
use rustlanges_components::{
button::{Button, Variant},
icons::{Moon, SunLine, SunMoon},
};

/// Path that redirects to the book in spanish from RustLangEs
const BOOK_PATH: &str = "https://book.rustlang-es.org/";

/// Path that redirects to the discord community server
const JOIN_PATH: &str = "https://discord.rustlang-es.org/";

#[island]
pub fn Header() -> impl IntoView {
let this = use_window();
Expand Down Expand Up @@ -43,7 +49,7 @@ pub fn Header() -> impl IntoView {

let active_link_class = move |link: &str| {
if path() == format!("{link:?}") {
"text-red-500 dark:text-orange-300"
"font-bold text-red-500 dark:text-orange-300"
} else {
""
}
Expand All @@ -52,42 +58,53 @@ pub fn Header() -> impl IntoView {
let handler = move |_| {
let current_theme = theme.get();
match current_theme {
Theme::System => theme.set(Theme::Dark),
Theme::Dark => theme.set(Theme::Light),
Theme::Light => theme.set(Theme::System),
Theme::Light => theme.set(Theme::Dark),
Theme::Dark | Theme::System => theme.set(Theme::Light),
}
};

view! {
<header class="w-full py-[8px] px-[24px] flex flex-column items-center justify-between">
{move || logo()} <div class="flex flex-column gap-[24px] items-center">
<a href="/" class=move || active_link_class("/")>
{move || logo()}
</a>
<div class="flex flex-column gap-[24px] items-center">
<div class="gap-[16px] hidden md:flex">
<a href="/" class=move || active_link_class("/")>
<a href="/" class=move || format!("font-semibold {}", active_link_class("/"))>
Inicio
</a>
<a href="/aprende" class=move || active_link_class("/aprende")>
<a href="/aprende" class=move || format!("font-semibold {}", active_link_class("/aprende"))>
Aprende Rust
</a>
<a href="/comunidad" class=move || active_link_class("/comunidad")>
<a href="/comunidad" class=move || format!("font-semibold {}", active_link_class("/comunidad"))>
Comunidad
</a>
<a href="/eventos" class=move || active_link_class("/eventos")>
<a href="/eventos" class=move || format!("font-semibold {}", active_link_class("/eventos"))>
Eventos
</a>
<a href="https://blog.rustlang-es.org">Blog</a>
<a href="/blog" class=move || format!("font-semibold {}", active_link_class("/blog"))>
Blog
</a>
</div>
<div class="flex gap-[16px] items-center flex-wrap">
<Button
variant=Variant::Secondary
label="El Libro"
on_click=|_| {}
<a
href=BOOK_PATH
class="hidden md:block"
/>
<Button
variant=Variant::Primary
label="¡Únete!"
on_click=move |_| console_log("hola")
/>
target="_blank"
rel="noopener noreferrer"
>
<Button variant=Variant::Secondary label="El Libro" on_click=|_| {} />
</a>

<a
href=JOIN_PATH
class="hidden md:block"
target="_blank"
rel="noopener noreferrer"
>
<Button variant=Variant::Primary label="¡Únete!" on_click=move |_| {} />
</a>

<Button
variant=Variant::Icon
on_click=handler
Expand Down
38 changes: 22 additions & 16 deletions src/context/theme_provider.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use std::fmt::Display;

use leptos::{
children::Children,
prelude::{RwSignal, use_context, *},
server::codee::string::JsonSerdeCodec,
*,
};
use leptos_use::{storage::use_local_storage, use_media_query};
use leptos_use::{use_cookie, use_media_query};
use serde::{Deserialize, Serialize};

/// Defines an enumeration for UI themes.
///
/// This enum can be cloned, copied, and compared for equality.
Expand All @@ -25,20 +28,23 @@ impl Default for Theme {
}
}

#[allow(clippy::inherent_to_string)]
impl Theme {
impl Display for Theme {
/// Converts the `Theme` variant into a corresponding string.
pub fn to_string(self) -> String {
String::from(match self {
Theme::Light => "light",
Theme::Dark => "dark",
Theme::System => "system",
})
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Theme::Light => "light",
Theme::Dark => "dark",
Theme::System => "system",
}
)
}
}

/// Define a constant for the local storage key used to store the theme setting.
const STORAGE_KEY: &str = "theme";
/// Define a constant for the cookie key used to store the theme setting.
const COOKIE_KEY: &str = "theme";

/// Updates the class selector for the respective theme.
/// This function is responsible for applying the correct CSS class to the HTML and body elements based on the current theme.
Expand Down Expand Up @@ -102,16 +108,16 @@ pub fn ThemeProvider(children: Children) -> impl IntoView {
let is_dark_preferred_signal = use_media_query("(prefers-color-scheme: dark)");

// Attempt to retrieve the theme from local storage
let (theme_storage_state, set_theme_storage_state, _) =
use_local_storage::<Theme, JsonSerdeCodec>(STORAGE_KEY);
let (theme_storage_state, set_theme_storage_state) =
use_cookie::<Theme, JsonSerdeCodec>(COOKIE_KEY);

let theme_state = RwSignal::new(theme_storage_state.get_untracked());
let theme_state = RwSignal::new(theme_storage_state.get_untracked().unwrap_or_default());
provide_context(theme_state);

// Update local storage and CSS whenever the theme state changes
Effect::new(move |_| {
let current_theme = theme_state();
set_theme_storage_state.set(current_theme);
let current_theme: Theme = theme_state();
set_theme_storage_state.set(Some(current_theme));
update_css_for_theme(
current_theme,
is_dark_preferred_signal(),
Expand Down
4 changes: 4 additions & 0 deletions src/pages/blog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use leptos::{IntoView, component};

#[component]
pub fn Blog() -> impl IntoView {}
4 changes: 4 additions & 0 deletions src/pages/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use leptos::{IntoView, component};

#[component]
pub fn Events() -> impl IntoView {}
4 changes: 4 additions & 0 deletions src/pages/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
mod aprende;
mod blog;
mod communities;
mod contributors;
mod events;
mod index;
mod projects;

pub use aprende::Aprende;
pub use blog::Blog;
pub use communities::Communities;
pub use contributors::Contributors;
pub use events::Events;
pub use index::Index;
pub use projects::Projects;