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:
@@ -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">
|
||||
© {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>
|
||||
|
||||
Reference in New Issue
Block a user