97 lines
3.7 KiB
TypeScript
97 lines
3.7 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import logotext from "../assets/logotext.svg";
|
|
|
|
export default function TopBar() {
|
|
const [visible, setVisible] = useState(true);
|
|
const [lastScrollY, setLastScrollY] = useState(0);
|
|
const [darkMode, setDarkMode] = useState(false);
|
|
|
|
// Function to update theme meta tag
|
|
const updateThemeColor = (isDark: boolean) => {
|
|
const themeColor = isDark ? '#c490ff' : '#6a0dad';
|
|
const metaThemeColor = document.querySelector('meta[name="theme-color"]');
|
|
if (metaThemeColor) {
|
|
metaThemeColor.setAttribute('content', themeColor);
|
|
}
|
|
};
|
|
|
|
// Initialize theme based on user preference or system preference
|
|
useEffect(() => {
|
|
const isDarkMode = localStorage.getItem('darkMode') === 'true' ||
|
|
window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
setDarkMode(isDarkMode);
|
|
document.documentElement.setAttribute('data-theme', isDarkMode ? 'dark' : 'light');
|
|
updateThemeColor(isDarkMode);
|
|
}, []);
|
|
|
|
// Function to toggle theme
|
|
const toggleTheme = () => {
|
|
const newDarkMode = !darkMode;
|
|
setDarkMode(newDarkMode);
|
|
document.documentElement.setAttribute('data-theme', newDarkMode ? 'dark' : 'light');
|
|
localStorage.setItem('darkMode', newDarkMode.toString());
|
|
updateThemeColor(newDarkMode);
|
|
};
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
const currentScrollY = window.scrollY;
|
|
|
|
// Hide the topbar when scrolling down, show when scrolling up
|
|
if (currentScrollY > lastScrollY && currentScrollY > 50) {
|
|
setVisible(false);
|
|
} else {
|
|
setVisible(true);
|
|
}
|
|
|
|
setLastScrollY(currentScrollY);
|
|
};
|
|
|
|
window.addEventListener('scroll', handleScroll, { passive: true });
|
|
|
|
return () => {
|
|
window.removeEventListener('scroll', handleScroll);
|
|
};
|
|
}, [lastScrollY]);
|
|
|
|
return (
|
|
<div
|
|
className={`fixed top-0 left-0 right-0 py-2 md:py-3 px-3 md:px-4 flex items-center transition-transform duration-300 z-20 ${
|
|
visible ? 'transform-none' : 'transform -translate-y-full'
|
|
}`}
|
|
style={{
|
|
background: 'var(--accent-gradient)',
|
|
boxShadow: '0 2px 10px var(--shadow)'
|
|
}}
|
|
>
|
|
<div className="flex items-center justify-between w-full max-w-6xl mx-auto">
|
|
<div className="flex items-center">
|
|
<div className="p-1 rounded-lg" style={{ backgroundColor: 'rgba(255, 255, 255, 0.15)', backdropFilter: 'blur(4px)' }}>
|
|
<img src={logotext} alt="REMind Logo and Text" className="h-16"/>
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
onClick={toggleTheme}
|
|
className="p-2 rounded-full focus:outline-none transition-transform hover:scale-110"
|
|
aria-label="Toggle theme"
|
|
style={{
|
|
backgroundColor: 'var(--card)',
|
|
boxShadow: '0 2px 8px var(--shadow)'
|
|
}}
|
|
>
|
|
{darkMode ? (
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 md:h-6 md:w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" style={{ color: 'var(--accent)' }}>
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
|
|
</svg>
|
|
) : (
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 md:h-6 md:w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" style={{ color: 'var(--accent-dark)' }}>
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
|
|
</svg>
|
|
)}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|