1+ use gloo:: timers:: callback:: Timeout ;
2+ use web_sys:: window;
13use yew:: prelude:: * ;
24use yew_router:: prelude:: * ;
35
@@ -6,9 +8,21 @@ use stylist::yew::styled_component;
68use crate :: localization:: { use_localization, Localization } ;
79use 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]
1022pub 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