ccfb674318
continuous-integration/drone/push Build is passing
- Implement Social Features: Shared Tasks, Global Access, Privacy Settings (Leaderboard/Searchable). - Add Leaderboard Page and API. - Enhance Auth: Support Email/Username login, explicit duplicate registration errors. - Fix: Admin login password hash regression. - Refactor: Move to wouter for routing, add Admin Dashboard and User Management. - Add Setup Wizard. - Update UI with Sidebar and Gamification elements.
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Moon, Sun } from 'lucide-react';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
export default function ThemeToggle() {
|
|
const { t } = useTranslation();
|
|
const [isDark, setIsDark] = useState(false);
|
|
|
|
useEffect(() => {
|
|
// Check for saved theme preference or default to light mode
|
|
const savedTheme = localStorage.getItem('theme');
|
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
|
|
const shouldBeDark = savedTheme === 'dark' || (!savedTheme && prefersDark);
|
|
setIsDark(shouldBeDark);
|
|
|
|
// Apply theme to document
|
|
if (shouldBeDark) {
|
|
document.documentElement.classList.add('dark');
|
|
} else {
|
|
document.documentElement.classList.remove('dark');
|
|
}
|
|
}, []);
|
|
|
|
const toggleTheme = () => {
|
|
const newTheme = !isDark;
|
|
setIsDark(newTheme);
|
|
|
|
if (newTheme) {
|
|
document.documentElement.classList.add('dark');
|
|
localStorage.setItem('theme', 'dark');
|
|
} else {
|
|
document.documentElement.classList.remove('dark');
|
|
localStorage.setItem('theme', 'light');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Button
|
|
variant="outline"
|
|
size="icon"
|
|
onClick={toggleTheme}
|
|
className="w-10 h-10 rounded-full border-2 border-primary/20 hover:border-primary hover:bg-primary/10 transition-all duration-300"
|
|
title={t('app.toggleTheme')}
|
|
>
|
|
{isDark ? (
|
|
<Moon className="h-5 w-5 text-violet-500 transition-all" />
|
|
) : (
|
|
<Sun className="h-5 w-5 text-orange-500 transition-all" />
|
|
)}
|
|
<span className="sr-only">{isDark ? t('theme.dark') : t('theme.light')}</span>
|
|
</Button>
|
|
);
|
|
} |