Skip to content

Commit 7796962

Browse files
committed
Modernize Look & Feel
1 parent be0ab14 commit 7796962

File tree

8 files changed

+1024
-801
lines changed

8 files changed

+1024
-801
lines changed

src/components/footer.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,43 @@ use stylist::yew::styled_component;
55
#[styled_component]
66
pub fn Footer() -> Html {
77
html! {
8-
<footer class="mt-auto flex flex-nowrap min-w-full h-3 z-40">
9-
{
10-
(1..7).into_iter().map(|color| {
11-
html! {
12-
<div class={format!("min-h-full w-1/6 bg-rainbow-{}", color)} />
13-
}
14-
}).collect::<Html>()
15-
}
8+
<footer class="mt-auto">
9+
// Copyright notice
10+
<div class={css!(r#"
11+
background: #0F172A;
12+
padding: 2rem 1rem;
13+
text-align: center;
14+
border-top: 1px solid rgba(203, 213, 225, 0.1);
15+
"#)}>
16+
<p class={css!(r#"
17+
color: rgba(203, 213, 225, 0.6);
18+
font-size: 0.875rem;
19+
line-height: 1.5;
20+
"#)}>
21+
{"© 2025 Til Mohr"}
22+
{" · "}
23+
<a href="https://github.com/CodingTil/personal-site" class={css!(r#"
24+
color: rgba(203, 213, 225, 0.6);
25+
transition: color 0.2s ease;
26+
&:hover {
27+
color: #60A5FA;
28+
}
29+
"#)}>
30+
{"Source Code"}
31+
</a>
32+
</p>
33+
</div>
34+
35+
// Rainbow bar
36+
<div class="flex flex-nowrap min-w-full h-3">
37+
{
38+
(1..7).into_iter().map(|color| {
39+
html! {
40+
<div class={format!("min-h-full w-1/6 bg-rainbow-{}", color)} />
41+
}
42+
}).collect::<Html>()
43+
}
44+
</div>
1645
</footer>
1746
}
1847
}

src/components/header.rs

Lines changed: 188 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use gloo::timers::callback::Timeout;
2+
use web_sys::window;
13
use yew::prelude::*;
24
use yew_router::prelude::*;
35

@@ -6,9 +8,21 @@ use stylist::yew::styled_component;
68
use crate::localization::{use_localization, Localization};
79
use crate::router::Route;
810

11+
fn scroll_to_section(section_id: &str) {
12+
if let Some(window) = window() {
13+
if let Some(document) = window.document() {
14+
if let Some(element) = document.get_element_by_id(section_id) {
15+
element.scroll_into_view();
16+
}
17+
}
18+
}
19+
}
20+
921
#[styled_component]
1022
pub fn Header() -> Html {
1123
let localization = use_localization();
24+
let navigator = use_navigator().unwrap();
25+
let location = use_location().unwrap();
1226

1327
let current_locale = localization.get().clone();
1428

@@ -21,54 +35,192 @@ pub fn Header() -> Html {
2135

2236
let switch_locale = Callback::from(move |_| localization.set(other_locale.clone()));
2337

24-
let header_css = css!(
25-
r#"
26-
backdrop-filter: blur(12px) saturate(180%);
27-
-webkit-backdrop-filter: blur(12px) saturate(180%);
28-
background-color: rgba(15, 23, 42, 0.85);
29-
border-bottom: 1px solid rgba(203, 213, 225, 0.1);
30-
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
31-
"#
32-
);
38+
// Check if we're on the home page
39+
let is_home = location.path() == "/";
40+
41+
// Create navigation callbacks for sections
42+
let nav_to_section = {
43+
let navigator = navigator.clone();
44+
Callback::from(move |section: String| {
45+
let section_clone = section.clone();
46+
if is_home {
47+
// Already on home, just scroll
48+
scroll_to_section(&section);
49+
} else {
50+
// Navigate to home first
51+
navigator.push(&Route::Home);
52+
// Wait a bit for the DOM to update, then scroll
53+
Timeout::new(100, move || {
54+
scroll_to_section(&section_clone);
55+
})
56+
.forget();
57+
}
58+
})
59+
};
60+
61+
let on_projects_click = {
62+
let nav = nav_to_section.clone();
63+
Callback::from(move |e: MouseEvent| {
64+
e.prevent_default();
65+
nav.emit("projects".to_string());
66+
})
67+
};
68+
69+
let on_experience_click = {
70+
let nav = nav_to_section.clone();
71+
Callback::from(move |e: MouseEvent| {
72+
e.prevent_default();
73+
nav.emit("experience".to_string());
74+
})
75+
};
76+
77+
let on_education_click = {
78+
let nav = nav_to_section.clone();
79+
Callback::from(move |e: MouseEvent| {
80+
e.prevent_default();
81+
nav.emit("education".to_string());
82+
})
83+
};
84+
85+
let on_contact_click = {
86+
let nav = nav_to_section.clone();
87+
Callback::from(move |e: MouseEvent| {
88+
e.prevent_default();
89+
nav.emit("contact".to_string());
90+
})
91+
};
3392

3493
html! {
35-
<div class={classes!("h-20", "sticky", "top-0", "z-50", "w-full", header_css)}>
36-
<nav class="container mx-auto pt-5 pb-3 max-w-7xl px-4 xl:px-0 flex justify-between items-center">
94+
<div class={css!(r#"
95+
position: fixed;
96+
top: 0;
97+
left: 0;
98+
right: 0;
99+
z-index: 1000;
100+
backdrop-filter: blur(12px) saturate(180%);
101+
-webkit-backdrop-filter: blur(12px) saturate(180%);
102+
background-color: rgba(15, 23, 42, 0.8);
103+
"#)}>
104+
<nav class={css!(r#"
105+
max-width: 80rem;
106+
margin: 0 auto;
107+
padding: 1.25rem 2rem;
108+
display: flex;
109+
justify-content: space-between;
110+
align-items: center;
111+
@media (max-width: 768px) {
112+
padding: 1rem 1.5rem;
113+
}
114+
"#)}>
37115
<Link<Route> to={Route::Home} classes={css!(r#"
38116
display: flex;
39117
align-items: center;
40118
gap: 0.75rem;
119+
color: #F1F5F9;
120+
font-weight: 700;
121+
font-size: 1.125rem;
41122
transition: all 0.2s ease;
123+
font-family: 'Space Grotesk', sans-serif;
124+
&:hover {
125+
color: #60A5FA;
126+
}
42127
"#)}>
43-
<div class={css!(r#"
44-
transition: all 0.2s ease;
45-
&:hover {
46-
transform: scale(1.1);
47-
}
48-
"#)}>
49-
<i class="fa-solid fa-trademark text-3xl text-rainbow-1" style="filter:drop-shadow(2px 2px 4px rgba(96, 165, 250, 0.3))"></i>
50-
</div>
51-
<span class="text-foreground-primary text-lg font-semibold">{"Home"}</span>
128+
<span>{"TM"}</span>
52129
</Link<Route>>
53-
<button onclick={switch_locale} class={css!(r#"
130+
131+
<div class={css!(r#"
54132
display: flex;
133+
gap: 2rem;
55134
align-items: center;
56-
gap: 0.75rem;
57-
padding: 0.5rem 1rem;
58-
border-radius: 0.5rem;
59-
background-color: rgba(51, 65, 85, 0.5);
60-
transition: all 0.2s ease;
61-
border: 1px solid rgba(203, 213, 225, 0.1);
62-
&:hover {
63-
background-color: rgba(71, 85, 105, 0.6);
64-
transform: translateY(-2px);
65-
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
66-
}
67135
"#)}>
68-
<span class="sr-only">{"Switch language to "}</span>
69-
<span class="text-foreground-primary text-lg font-semibold">{other_locale_str}</span>
70-
<i class="fa-solid fa-language text-2xl text-rainbow-1"></i>
71-
</button>
136+
<a href="#projects" onclick={on_projects_click} class={css!(r#"
137+
color: rgba(203, 213, 225, 0.8);
138+
font-weight: 500;
139+
transition: color 0.2s ease;
140+
display: flex;
141+
align-items: center;
142+
line-height: 1;
143+
cursor: pointer;
144+
&:hover {
145+
color: #F1F5F9;
146+
}
147+
@media (max-width: 640px) {
148+
display: none;
149+
}
150+
"#)}>
151+
{"Projects"}
152+
</a>
153+
<a href="#experience" onclick={on_experience_click} class={css!(r#"
154+
color: rgba(203, 213, 225, 0.8);
155+
font-weight: 500;
156+
transition: color 0.2s ease;
157+
display: flex;
158+
align-items: center;
159+
line-height: 1;
160+
cursor: pointer;
161+
&:hover {
162+
color: #F1F5F9;
163+
}
164+
@media (max-width: 640px) {
165+
display: none;
166+
}
167+
"#)}>
168+
{"Experience"}
169+
</a>
170+
<a href="#education" onclick={on_education_click} class={css!(r#"
171+
color: rgba(203, 213, 225, 0.8);
172+
font-weight: 500;
173+
transition: color 0.2s ease;
174+
display: flex;
175+
align-items: center;
176+
line-height: 1;
177+
cursor: pointer;
178+
&:hover {
179+
color: #F1F5F9;
180+
}
181+
@media (max-width: 640px) {
182+
display: none;
183+
}
184+
"#)}>
185+
{"Education"}
186+
</a>
187+
<a href="#contact" onclick={on_contact_click} class={css!(r#"
188+
color: rgba(203, 213, 225, 0.8);
189+
font-weight: 500;
190+
transition: color 0.2s ease;
191+
display: flex;
192+
align-items: center;
193+
line-height: 1;
194+
cursor: pointer;
195+
&:hover {
196+
color: #F1F5F9;
197+
}
198+
@media (max-width: 640px) {
199+
display: none;
200+
}
201+
"#)}>
202+
{"Contact"}
203+
</a>
204+
205+
<button onclick={switch_locale} class={css!(r#"
206+
padding: 0.5rem 1rem;
207+
border-radius: 0.5rem;
208+
background-color: rgba(51, 65, 85, 0.5);
209+
color: #F1F5F9;
210+
font-weight: 500;
211+
border: 1px solid rgba(203, 213, 225, 0.1);
212+
transition: all 0.2s ease;
213+
display: flex;
214+
align-items: center;
215+
line-height: 1;
216+
&:hover {
217+
background-color: rgba(71, 85, 105, 0.7);
218+
border-color: rgba(96, 165, 250, 0.3);
219+
}
220+
"#)}>
221+
{other_locale_str}
222+
</button>
223+
</div>
72224
</nav>
73225
</div>
74226
}

0 commit comments

Comments
 (0)