|
1 | 1 | import { Button, Card, mergeClasses } from '@fluentui/react-components'; |
2 | 2 | import { mainLayoutStyles } from '../styles/Styles'; |
3 | | -import { Sparkle24Regular, People24Regular, Mail24Regular } from '@fluentui/react-icons'; |
4 | | -import { useNavigate, useLocation } from 'react-router-dom'; |
5 | | -import { useState, useEffect } from 'react'; |
6 | | -import ThemeToggle from '../styles/ThemeToggle'; |
| 3 | +import { useNavigate } from 'react-router-dom'; |
7 | 4 | import BrandHeader from './BrandHeader'; |
8 | | -import { makeStyles, tokens } from '@fluentui/react-components'; |
9 | | - |
10 | | -// Custom styles for the navigation |
11 | | -const useNavStyles = makeStyles({ |
12 | | - navButton: { |
13 | | - position: 'relative', |
14 | | - background: 'transparent', |
15 | | - border: 'none', |
16 | | - color: tokens.colorNeutralForeground2, |
17 | | - cursor: 'pointer', |
18 | | - display: 'flex', |
19 | | - alignItems: 'center', |
20 | | - gap: tokens.spacingHorizontalS, |
21 | | - padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalL}`, |
22 | | - fontSize: tokens.fontSizeBase300, |
23 | | - fontWeight: tokens.fontWeightRegular, |
24 | | - transition: 'all 0.2s ease', |
25 | | - animationName: { |
26 | | - from: { opacity: 0, transform: 'translateY(-10px)' }, |
27 | | - to: { opacity: 1, transform: 'translateY(0)' } |
28 | | - }, |
29 | | - animationDuration: '0.5s', |
30 | | - animationTimingFunction: 'ease-out', |
31 | | - animationFillMode: 'both', |
32 | | - '&:hover': { |
33 | | - color: tokens.colorBrandForeground1, |
34 | | - '&::after': { |
35 | | - width: '100%', |
36 | | - backgroundColor: tokens.colorBrandForeground1, |
37 | | - } |
38 | | - }, |
39 | | - '&::after': { |
40 | | - content: '""', |
41 | | - position: 'absolute', |
42 | | - bottom: '0', |
43 | | - left: '0', |
44 | | - width: '0', |
45 | | - height: '3px', |
46 | | - backgroundColor: 'transparent', |
47 | | - transition: 'all 0.3s ease', |
48 | | - } |
49 | | - }, |
50 | | - navButtonActive: { |
51 | | - color: tokens.colorBrandForeground1, |
52 | | - fontWeight: tokens.fontWeightSemibold, |
53 | | - '&::after': { |
54 | | - width: '100%', |
55 | | - backgroundColor: tokens.colorBrandForeground1, |
56 | | - } |
57 | | - }, |
58 | | - navContainer: { |
59 | | - display: 'flex', |
60 | | - flexDirection: 'row', |
61 | | - gap: tokens.spacingHorizontalXL, |
62 | | - alignItems: 'center', |
63 | | - } |
64 | | -}); |
| 5 | +import { tokens } from '@fluentui/react-components'; |
65 | 6 |
|
66 | 7 | export default function PublicHeader() { |
67 | 8 | const s = mainLayoutStyles(); |
68 | | - const navStyles = useNavStyles(); |
69 | 9 | const navigate = useNavigate(); |
70 | | - const location = useLocation(); |
71 | | - const [activeSection, setActiveSection] = useState('features'); |
72 | | - |
73 | | - // Function to handle scroll to section |
74 | | - const scrollToSection = (sectionId: string) => { |
75 | | - // If we're not on the landing page, navigate to it first |
76 | | - if (location.pathname !== '/') { |
77 | | - navigate('/'); |
78 | | - // Wait for navigation to complete then scroll |
79 | | - setTimeout(() => { |
80 | | - const element = document.getElementById(sectionId); |
81 | | - if (element) { |
82 | | - element.scrollIntoView({ behavior: 'smooth', block: 'start' }); |
83 | | - } |
84 | | - setActiveSection(sectionId); |
85 | | - }, 100); |
86 | | - } else { |
87 | | - // We're already on landing page, just scroll |
88 | | - const element = document.getElementById(sectionId); |
89 | | - if (element) { |
90 | | - element.scrollIntoView({ behavior: 'smooth', block: 'start' }); |
91 | | - } |
92 | | - setActiveSection(sectionId); |
93 | | - } |
94 | | - }; |
95 | | - |
96 | | - // Handle logo click to scroll to home section |
97 | | - const handleLogoClick = () => { |
98 | | - if (location.pathname !== '/') { |
99 | | - navigate('/'); |
100 | | - setTimeout(() => { |
101 | | - const element = document.getElementById('home'); |
102 | | - if (element) { |
103 | | - element.scrollIntoView({ behavior: 'smooth', block: 'start' }); |
104 | | - } |
105 | | - setActiveSection('home'); |
106 | | - }, 100); |
107 | | - } else { |
108 | | - const element = document.getElementById('home'); |
109 | | - if (element) { |
110 | | - element.scrollIntoView({ behavior: 'smooth', block: 'start' }); |
111 | | - } |
112 | | - setActiveSection('home'); |
113 | | - } |
114 | | - }; |
115 | | - |
116 | | - // Detect active section on scroll |
117 | | - useEffect(() => { |
118 | | - if (location.pathname !== '/') { |
119 | | - setActiveSection(''); |
120 | | - return; |
121 | | - } |
122 | | - |
123 | | - const handleScroll = () => { |
124 | | - const sections = ['home', 'features', 'team', 'contact']; |
125 | | - const scrollPosition = window.scrollY + 200; // Offset for header |
126 | | - |
127 | | - // Find which section is currently in view |
128 | | - for (const sectionId of sections) { |
129 | | - const element = document.getElementById(sectionId); |
130 | | - if (element) { |
131 | | - const { offsetTop, offsetHeight } = element; |
132 | | - if (scrollPosition >= offsetTop && scrollPosition < offsetTop + offsetHeight) { |
133 | | - setActiveSection(sectionId); |
134 | | - return; |
135 | | - } |
136 | | - } |
137 | | - } |
138 | | - }; |
139 | | - |
140 | | - window.addEventListener('scroll', handleScroll); |
141 | | - handleScroll(); // Call once on mount |
142 | | - |
143 | | - return () => window.removeEventListener('scroll', handleScroll); |
144 | | - }, [location.pathname]); |
145 | 10 |
|
146 | 11 | return ( |
147 | | - <Card className={s.componentBorder}> |
148 | | - <header className={mergeClasses(s.header)} role="banner"> |
149 | | - <div onClick={handleLogoClick} style={{ cursor: 'pointer' }}> |
150 | | - <BrandHeader navigateTo="/" /> |
151 | | - </div> |
152 | | - |
153 | | - <nav className={navStyles.navContainer}> |
154 | | - <button |
155 | | - className={mergeClasses( |
156 | | - navStyles.navButton, |
157 | | - activeSection === 'features' && navStyles.navButtonActive |
158 | | - )} |
159 | | - onClick={() => scrollToSection('features')} |
160 | | - > |
161 | | - <Sparkle24Regular /> |
162 | | - Features |
163 | | - </button> |
164 | | - <button |
165 | | - className={mergeClasses( |
166 | | - navStyles.navButton, |
167 | | - activeSection === 'team' && navStyles.navButtonActive |
168 | | - )} |
169 | | - onClick={() => scrollToSection('team')} |
170 | | - > |
171 | | - <People24Regular /> |
172 | | - Our Team |
173 | | - </button> |
174 | | - <button |
175 | | - className={mergeClasses( |
176 | | - navStyles.navButton, |
177 | | - activeSection === 'contact' && navStyles.navButtonActive |
178 | | - )} |
179 | | - onClick={() => scrollToSection('contact')} |
180 | | - > |
181 | | - <Mail24Regular /> |
182 | | - Contact Us |
183 | | - </button> |
184 | | - </nav> |
| 12 | + <Card className={s.componentBorder} style={{ padding: 0 }}> |
| 13 | + <header |
| 14 | + className={mergeClasses(s.header)} |
| 15 | + role="banner" |
| 16 | + style={{ |
| 17 | + padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalXXL} ${tokens.spacingVerticalXXL} ${tokens.spacingHorizontalXXL}`, |
| 18 | + alignItems: 'center' |
| 19 | + }} |
| 20 | + > |
| 21 | + <BrandHeader navigateTo="/" /> |
185 | 22 |
|
186 | 23 | <div className={mergeClasses(s.flexRowFit, s.alignCenter, s.gap)}> |
187 | | - <ThemeToggle /> |
188 | 24 | <Button appearance="primary" onClick={() => navigate("/login")}>Log In</Button> |
189 | 25 | </div> |
190 | 26 | </header> |
|
0 commit comments