feat: Implement dark mode support across the application

- Added ThemeContext to manage theme state and toggle functionality.
- Updated components to support dark mode styles, including header, dashboard, and home page.
- Enhanced CSS for smooth transitions between light and dark themes.
- Modified authentication context to handle async login operations.
- Improved user experience by preserving theme preference in local storage.
- Refactored login and register pages to handle OAuth tokens and errors more gracefully.
This commit is contained in:
2026-01-05 20:11:22 +03:00
parent 7a7d3151e8
commit 9bbf88a8f7
17 changed files with 366 additions and 318 deletions

View File

@@ -1,16 +1,19 @@
import { Link } from 'react-router-dom';
import { FaGithub } from 'react-icons/fa';
import { FaSun, FaMoon } from 'react-icons/fa';
import logo from '../assets/logo.svg';
import { useTranslation } from '../i18n';
import { useLocalePath } from '../middleware';
import { useTheme } from '../context/ThemeContext';
const Footer = () => {
const currentYear = new Date().getFullYear();
const { t, locale, setLocale } = useTranslation();
const localePath = useLocalePath();
const { theme, toggleTheme } = useTheme();
return (
<footer className="bg-gray-800 text-white py-12">
<footer className="bg-gray-800 dark:bg-gray-950 text-white py-12 transition-colors duration-200">
<div className="container mx-auto px-6">
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 text-center md:text-left">
{/* About Section */}
@@ -57,33 +60,44 @@ const Footer = () => {
</div>
</div>
<div className="mt-8 pt-8 border-t border-gray-700 flex flex-col md:flex-row justify-between items-center gap-4">
<div className="mt-8 pt-8 border-t border-gray-700 dark:border-gray-800 flex flex-col md:flex-row justify-between items-center gap-4">
<p className="text-sm text-gray-400">
&copy; {currentYear} ospab.host. {locale === 'en' ? 'All rights reserved.' : 'Все права защищены.'}
</p>
{/* Language Switcher */}
<div className="flex items-center gap-2">
<div className="flex items-center gap-4">
{/* Theme Switcher */}
<button
onClick={() => setLocale('ru')}
className={`px-3 py-1 rounded-full text-sm transition-colors ${
locale === 'ru'
? 'bg-ospab-primary text-white'
: 'text-gray-400 hover:text-white hover:bg-gray-700'
}`}
onClick={toggleTheme}
className="p-2 rounded-full text-gray-400 hover:text-white hover:bg-gray-700 dark:hover:bg-gray-800 transition-colors"
aria-label={theme === 'light' ? 'Включить тёмную тему' : 'Включить светлую тему'}
>
RU
</button>
<button
onClick={() => setLocale('en')}
className={`px-3 py-1 rounded-full text-sm transition-colors ${
locale === 'en'
? 'bg-ospab-primary text-white'
: 'text-gray-400 hover:text-white hover:bg-gray-700'
}`}
>
EN
{theme === 'light' ? <FaMoon className="text-xl" /> : <FaSun className="text-xl" />}
</button>
{/* Language Switcher */}
<div className="flex items-center gap-2">
<button
onClick={() => setLocale('ru')}
className={`px-3 py-1 rounded-full text-sm transition-colors ${
locale === 'ru'
? 'bg-ospab-primary text-white'
: 'text-gray-400 hover:text-white hover:bg-gray-700 dark:hover:bg-gray-800'
}`}
>
RU
</button>
<button
onClick={() => setLocale('en')}
className={`px-3 py-1 rounded-full text-sm transition-colors ${
locale === 'en'
? 'bg-ospab-primary text-white'
: 'text-gray-400 hover:text-white hover:bg-gray-700 dark:hover:bg-gray-800'
}`}
>
EN
</button>
</div>
</div>
</div>
</div>