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,198 @@ 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+ // Get translations for navigation items
39+ let ( projects_text, experience_text, education_text, contact_text) = match current_locale {
40+ Localization :: EN => ( "Projects" , "Experience" , "Education" , "Contact" ) ,
41+ Localization :: DE => ( "Projekte" , "Erfahrung" , "Bildung" , "Kontakt" ) ,
42+ } ;
43+
44+ // Check if we're on the home page
45+ let is_home = location. path ( ) == "/" ;
46+
47+ // Create navigation callbacks for sections
48+ let nav_to_section = {
49+ let navigator = navigator. clone ( ) ;
50+ Callback :: from ( move |section : String | {
51+ let section_clone = section. clone ( ) ;
52+ if is_home {
53+ // Already on home, just scroll
54+ scroll_to_section ( & section) ;
55+ } else {
56+ // Navigate to home first
57+ navigator. push ( & Route :: Home ) ;
58+ // Wait a bit for the DOM to update, then scroll
59+ Timeout :: new ( 100 , move || {
60+ scroll_to_section ( & section_clone) ;
61+ } )
62+ . forget ( ) ;
63+ }
64+ } )
65+ } ;
66+
67+ let on_projects_click = {
68+ let nav = nav_to_section. clone ( ) ;
69+ Callback :: from ( move |e : MouseEvent | {
70+ e. prevent_default ( ) ;
71+ nav. emit ( "projects" . to_string ( ) ) ;
72+ } )
73+ } ;
74+
75+ let on_experience_click = {
76+ let nav = nav_to_section. clone ( ) ;
77+ Callback :: from ( move |e : MouseEvent | {
78+ e. prevent_default ( ) ;
79+ nav. emit ( "experience" . to_string ( ) ) ;
80+ } )
81+ } ;
82+
83+ let on_education_click = {
84+ let nav = nav_to_section. clone ( ) ;
85+ Callback :: from ( move |e : MouseEvent | {
86+ e. prevent_default ( ) ;
87+ nav. emit ( "education" . to_string ( ) ) ;
88+ } )
89+ } ;
90+
91+ let on_contact_click = {
92+ let nav = nav_to_section. clone ( ) ;
93+ Callback :: from ( move |e : MouseEvent | {
94+ e. prevent_default ( ) ;
95+ nav. emit ( "contact" . to_string ( ) ) ;
96+ } )
97+ } ;
3398
3499 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" >
100+ <div class={ css!( r#"
101+ position: fixed;
102+ top: 0;
103+ left: 0;
104+ right: 0;
105+ z-index: 1000;
106+ backdrop-filter: blur(12px) saturate(180%);
107+ -webkit-backdrop-filter: blur(12px) saturate(180%);
108+ background-color: rgba(15, 23, 42, 0.8);
109+ "# ) } >
110+ <nav class={ css!( r#"
111+ max-width: 80rem;
112+ margin: 0 auto;
113+ padding: 1.25rem 2rem;
114+ display: flex;
115+ justify-content: space-between;
116+ align-items: center;
117+ @media (max-width: 768px) {
118+ padding: 1rem 1.5rem;
119+ }
120+ "# ) } >
37121 <Link <Route > to={ Route :: Home } classes={ css!( r#"
38122 display: flex;
39123 align-items: center;
40124 gap: 0.75rem;
125+ color: #F1F5F9;
126+ font-weight: 700;
127+ font-size: 1.125rem;
41128 transition: all 0.2s ease;
129+ font-family: 'Space Grotesk', sans-serif;
130+ &:hover {
131+ color: #60A5FA;
132+ }
42133 "# ) } >
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>
134+ <span>{ "TM" } </span>
52135 </Link <Route >>
53- <button onclick={ switch_locale} class={ css!( r#"
136+
137+ <div class={ css!( r#"
54138 display: flex;
139+ gap: 2rem;
55140 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- }
67141 "# ) } >
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>
142+ <a href="#projects" onclick={ on_projects_click} class={ css!( r#"
143+ color: rgba(203, 213, 225, 0.8);
144+ font-weight: 500;
145+ transition: color 0.2s ease;
146+ display: flex;
147+ align-items: center;
148+ line-height: 1;
149+ cursor: pointer;
150+ &:hover {
151+ color: #F1F5F9;
152+ }
153+ @media (max-width: 640px) {
154+ display: none;
155+ }
156+ "# ) } >
157+ { projects_text}
158+ </a>
159+ <a href="#experience" onclick={ on_experience_click} class={ css!( r#"
160+ color: rgba(203, 213, 225, 0.8);
161+ font-weight: 500;
162+ transition: color 0.2s ease;
163+ display: flex;
164+ align-items: center;
165+ line-height: 1;
166+ cursor: pointer;
167+ &:hover {
168+ color: #F1F5F9;
169+ }
170+ @media (max-width: 640px) {
171+ display: none;
172+ }
173+ "# ) } >
174+ { experience_text}
175+ </a>
176+ <a href="#education" onclick={ on_education_click} class={ css!( r#"
177+ color: rgba(203, 213, 225, 0.8);
178+ font-weight: 500;
179+ transition: color 0.2s ease;
180+ display: flex;
181+ align-items: center;
182+ line-height: 1;
183+ cursor: pointer;
184+ &:hover {
185+ color: #F1F5F9;
186+ }
187+ @media (max-width: 640px) {
188+ display: none;
189+ }
190+ "# ) } >
191+ { education_text}
192+ </a>
193+ <a href="#contact" onclick={ on_contact_click} class={ css!( r#"
194+ color: rgba(203, 213, 225, 0.8);
195+ font-weight: 500;
196+ transition: color 0.2s ease;
197+ display: flex;
198+ align-items: center;
199+ line-height: 1;
200+ cursor: pointer;
201+ &:hover {
202+ color: #F1F5F9;
203+ }
204+ @media (max-width: 640px) {
205+ display: none;
206+ }
207+ "# ) } >
208+ { contact_text}
209+ </a>
210+
211+ <button onclick={ switch_locale} class={ css!( r#"
212+ padding: 0.5rem 1rem;
213+ border-radius: 0.5rem;
214+ background-color: rgba(51, 65, 85, 0.5);
215+ color: #F1F5F9;
216+ font-weight: 500;
217+ border: 1px solid rgba(203, 213, 225, 0.1);
218+ transition: all 0.2s ease;
219+ display: flex;
220+ align-items: center;
221+ line-height: 1;
222+ &:hover {
223+ background-color: rgba(71, 85, 105, 0.7);
224+ border-color: rgba(96, 165, 250, 0.3);
225+ }
226+ "# ) } >
227+ { other_locale_str}
228+ </button>
229+ </div>
72230 </nav>
73231 </div>
74232 }
0 commit comments