Skip to content

Commit 030329f

Browse files
committed
Change theme
1 parent 6073831 commit 030329f

File tree

16 files changed

+1209
-317
lines changed

16 files changed

+1209
-317
lines changed

src/app.rs

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1+
// src/app.rs
12
use std::rc::Rc;
23
use yew::prelude::*;
34
use yew_router::prelude::*;
45

56
use crate::components::layout::Layout;
7+
use crate::components::nav_context::NavProvider;
8+
use crate::components::themecontext::ThemeProvider;
9+
use crate::pages::admin::Admin;
610
use crate::pages::blog::Blog;
711
use crate::pages::blog_post::BlogPost;
812
use crate::pages::contact::Contact;
913
use crate::pages::home::Home;
14+
use crate::pages::login::Login;
1015
use crate::pages::projects::Projects;
1116
use crate::route::Route;
1217

@@ -43,50 +48,13 @@ impl Reducible for ThemeState {
4348

4449
#[function_component(App)]
4550
pub fn app() -> Html {
46-
let dark_mode = use_state(|| {
47-
// Check local storage or system preference for initial value
48-
web_sys::window()
49-
.and_then(|win| win.local_storage().ok())
50-
.flatten()
51-
.and_then(|storage| storage.get_item("darkMode").ok())
52-
.flatten()
53-
.map(|val| val == "true")
54-
.unwrap_or(false)
55-
});
56-
57-
let dark_mode = use_state(|| true); // Initial state, true for dark mode
58-
let toggle_theme = {
59-
let dark_mode = dark_mode.clone();
60-
Callback::from(move |_| {
61-
let new_mode = !*dark_mode;
62-
dark_mode.set(new_mode);
63-
64-
// Update the document class to reflect the theme change
65-
if let Some(document) = web_sys::window().and_then(|win| win.document()) {
66-
if let Some(html) = document.document_element() {
67-
if new_mode {
68-
let _ = html.class_list().add_1("dark");
69-
} else {
70-
let _ = html.class_list().remove_1("dark");
71-
}
72-
}
73-
}
74-
})
75-
};
76-
77-
let theme_context = ThemeContext {
78-
dark_mode: *dark_mode,
79-
toggle_theme,
80-
};
81-
8251
html! {
8352
<BrowserRouter>
84-
<ContextProvider<ThemeContext> context={theme_context}>
85-
<div class={classes!("min-h-screen", "transition-colors", "duration-300",
86-
if *dark_mode { "dark" } else { "" })}>
53+
<ThemeProvider>
54+
<NavProvider>
8755
<Switch<Route> render={switch} />
88-
</div>
89-
</ContextProvider<ThemeContext>>
56+
</NavProvider>
57+
</ThemeProvider>
9058
</BrowserRouter>
9159
}
9260
}
@@ -98,6 +66,8 @@ pub fn switch(route: Route) -> Html {
9866
Route::Projects => html! { <Layout><Projects /></Layout> },
9967
Route::Blog => html! { <Layout><Blog /></Layout> },
10068
Route::BlogPost { id } => html! { <Layout><BlogPost {id} /></Layout> },
69+
Route::Admin => html! { <Layout><Admin /></Layout> },
70+
Route::Login => html! { <Layout><Login /></Layout> },
10171
Route::NotFound => html! { <div class="not-found"><h1>{"404 - Not Found"}</h1></div> },
10272
}
10373
}

src/components/footer.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// src/components/footer.rs
2+
use crate::app::ThemeContext;
13
use yew::prelude::*;
24

35
#[derive(Properties, PartialEq)]
@@ -8,27 +10,43 @@ pub struct FooterProps {
810

911
#[function_component(Footer)]
1012
pub fn footer(props: &FooterProps) -> Html {
13+
let theme_context = use_context::<ThemeContext>().expect("ThemeContext not found");
14+
let dark_mode = theme_context.dark_mode;
15+
16+
// Define color palette based on theme
17+
let bg_footer = if dark_mode {
18+
"bg-[#4F6F52]"
19+
} else {
20+
"bg-[#739072]"
21+
};
22+
let text_color = if dark_mode {
23+
"text-[#ECE3CE]"
24+
} else {
25+
"text-[#ECE3CE]"
26+
};
27+
1128
html! {
1229
<footer class={classes!(
1330
"p-4",
1431
"flex",
1532
"justify-between",
1633
"items-center",
17-
"bg-gray-800",
18-
"text-white",
34+
"mt-auto", // Pushes the footer to the bottom of flex container
35+
bg_footer,
36+
text_color,
1937
props.class.clone()
2038
)}>
2139
<div>
2240
<p>{"© 2024 C. James Hawkins"}</p>
2341
</div>
2442
<div class="flex space-x-4">
25-
<a href="https://github.com/cjames23" class="text-white hover:text-gray-300">
43+
<a href="https://github.com/cjames23" class="hover:opacity-80 transition-opacity">
2644
<i class="fab fa-github text-xl"></i>
2745
</a>
28-
<a href="https://linkedin.com/in/cary-hawkins" class="text-white hover:text-gray-300">
46+
<a href="https://linkedin.com/in/cary-hawkins" class="hover:opacity-80 transition-opacity">
2947
<i class="fab fa-linkedin text-xl"></i>
3048
</a>
31-
<a href="mailto:[email protected]" class="text-white hover:text-gray-300">
49+
<a href="mailto:[email protected]" class="hover:opacity-80 transition-opacity">
3250
<i class="fas fa-envelope text-xl"></i>
3351
</a>
3452
</div>

src/components/header.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// src/components/header.rs
2+
use crate::app::ThemeContext;
13
use yew::prelude::*;
24

35
#[derive(Properties, PartialEq)]
@@ -8,10 +10,45 @@ pub struct HeaderProps {
810

911
#[function_component(Header)]
1012
pub fn header() -> Html {
13+
let theme_context = use_context::<ThemeContext>().expect("ThemeContext not found");
14+
let dark_mode = theme_context.dark_mode;
15+
16+
// Define color palette based on theme
17+
let bg_header = if dark_mode {
18+
"bg-[#4F6F52]"
19+
} else {
20+
"bg-[#739072]"
21+
};
22+
let text_color = if dark_mode {
23+
"text-[#ECE3CE]"
24+
} else {
25+
"text-[#ECE3CE]"
26+
};
27+
let border_color = if dark_mode {
28+
"border-[#3A4D39]"
29+
} else {
30+
"border-[#4F6F52]"
31+
};
32+
1133
html! {
12-
<div class="flex items-center p-4 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 shadow-sm">
13-
<img src="logo.svg" alt="Logo" class="h-10 w-10 mr-3" />
14-
<h1 class="text-xl font-bold text-gray-800 dark:text-white">{"C. James Hawkins"}</h1>
34+
<div class={classes!(
35+
"flex",
36+
"items-center",
37+
"justify-between",
38+
"p-4",
39+
bg_header,
40+
text_color,
41+
"border-b",
42+
border_color,
43+
"shadow-sm"
44+
)}>
45+
<div class="flex items-center">
46+
<img src="logo.svg" alt="Logo" class="h-10 w-10 mr-3" />
47+
<h1 class="text-xl font-bold">{"C. James Hawkins"}</h1>
48+
</div>
49+
<div class="flex items-center space-x-4">
50+
// Additional header elements can go here
51+
</div>
1552
</div>
1653
}
1754
}

src/components/layout.rs

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// src/components/layout.rs
12
use crate::app::ThemeContext;
23
use crate::components::footer::Footer;
34
use crate::components::header::Header;
@@ -7,45 +8,56 @@ use yew::prelude::*;
78

89
#[derive(Properties, PartialEq)]
910
pub struct LayoutProps {
10-
#[prop_or_default]
1111
pub children: Children,
1212
}
1313

1414
#[function_component(Layout)]
1515
pub fn layout(props: &LayoutProps) -> Html {
16-
let collapsed = use_state(|| false);
17-
let theme_context = use_context::<ThemeContext>().expect("Theme context not found");
16+
let nav_context = use_context::<NavContext>().expect("NavContext not found");
17+
let theme_context = use_context::<ThemeContext>().expect("ThemeContext not found");
18+
1819
let dark_mode = theme_context.dark_mode;
20+
let collapsed = nav_context.collapsed;
1921

20-
let toggle_collapsed = {
21-
let collapsed = collapsed.clone();
22-
Callback::from(move |_| collapsed.set(!*collapsed))
22+
// Define color palette based on theme
23+
let bg_primary = if dark_mode {
24+
"bg-[#3A4D39]"
25+
} else {
26+
"bg-[#ECE3CE]"
2327
};
24-
25-
let nav_context = NavContext {
26-
collapsed: *collapsed,
27-
toggle_collapsed,
28+
let bg_secondary = if dark_mode {
29+
"bg-[#4F6F52]"
30+
} else {
31+
"bg-[#739072]"
32+
};
33+
let text_primary = if dark_mode {
34+
"text-[#ECE3CE]"
35+
} else {
36+
"text-[#3A4D39]"
2837
};
29-
30-
let content_margin = if *collapsed { "ml-16" } else { "ml-64" };
3138

3239
html! {
33-
<ContextProvider<NavContext> context={nav_context}>
40+
<div class={classes!("h-screen", "flex", "overflow-hidden", bg_primary, text_primary)}>
41+
<Nav />
3442
<div class={classes!(
35-
"flex", "flex-col", "h-screen",
36-
if dark_mode { "dark" } else { "" }
43+
"flex-grow",
44+
"flex",
45+
"flex-col",
46+
"transition-all",
47+
"duration-300",
48+
if collapsed { "ml-16" } else { "ml-64" }
3749
)}>
38-
<Nav />
39-
<div class={classes!("transition-all", "duration-300", content_margin, "flex", "flex-col", "h-screen")}>
40-
<Header />
41-
<main class={classes!("flex-grow", "overflow-y-auto", "p-6", "bg-white", "dark:bg-gray-900")}>
42-
<div class="container mx-auto">
43-
{ for props.children.iter() }
44-
</div>
45-
</main>
46-
<Footer/>
47-
</div>
50+
// Fixed header
51+
<Header />
52+
53+
// Scrollable main content
54+
<main class="flex-grow overflow-y-auto">
55+
{props.children.clone()}
56+
</main>
57+
58+
// Fixed footer
59+
<Footer class={classes!(bg_secondary, text_primary)} />
4860
</div>
49-
</ContextProvider<NavContext>>
61+
</div>
5062
}
5163
}

src/components/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ pub mod footer;
33
pub mod header;
44
pub(crate) mod layout;
55
pub(crate) mod nav;
6-
mod nav_context;
6+
pub(crate) mod nav_context;
7+
pub(crate) mod themecontext;

0 commit comments

Comments
 (0)