- 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.
108 lines
4.9 KiB
TypeScript
108 lines
4.9 KiB
TypeScript
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 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 */}
|
||
<div>
|
||
<div className="mb-4 flex justify-center md:justify-start">
|
||
<img src={logo} alt="Logo" className="h-20 w-20 rounded-full bg-white p-1.5 shadow-lg" width="80" height="80" />
|
||
</div>
|
||
<h3 className="text-xl font-bold mb-4">{t('nav.about')}</h3>
|
||
<p className="text-sm text-gray-400">
|
||
{t('footer.description')}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Quick Links */}
|
||
<div>
|
||
<h3 className="text-xl font-bold mb-4">{t('footer.links')}</h3>
|
||
<ul className="space-y-2 text-sm">
|
||
<li><Link to={localePath('/')} className="text-gray-400 hover:text-white transition-colors">{t('nav.home')}</Link></li>
|
||
<li><Link to={localePath('/tariffs')} className="text-gray-400 hover:text-white transition-colors">{t('nav.tariffs')}</Link></li>
|
||
<li><Link to={localePath('/about')} className="text-gray-400 hover:text-white transition-colors">{t('nav.about')}</Link></li>
|
||
<li><Link to={localePath('/blog')} className="text-gray-400 hover:text-white transition-colors">{t('nav.blog')}</Link></li>
|
||
<li><Link to={localePath('/login')} className="text-gray-400 hover:text-white transition-colors">{t('nav.login')}</Link></li>
|
||
</ul>
|
||
</div>
|
||
|
||
{/* Legal Documents */}
|
||
<div>
|
||
<h3 className="text-xl font-bold mb-4">{t('footer.legal')}</h3>
|
||
<ul className="space-y-2 text-sm">
|
||
<li><Link to={localePath('/privacy')} className="text-gray-400 hover:text-white transition-colors">{t('footer.privacy')}</Link></li>
|
||
<li><Link to={localePath('/terms')} className="text-gray-400 hover:text-white transition-colors">{t('footer.terms')}</Link></li>
|
||
<li>
|
||
<a
|
||
href="https://github.com/ospab/ospabhost8.1"
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="text-gray-400 hover:text-white transition-colors flex items-center justify-center md:justify-start gap-2"
|
||
>
|
||
<FaGithub className="text-xl" />
|
||
GitHub
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<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>
|
||
|
||
<div className="flex items-center gap-4">
|
||
{/* Theme Switcher */}
|
||
<button
|
||
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' ? 'Включить тёмную тему' : 'Включить светлую тему'}
|
||
>
|
||
{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>
|
||
</footer>
|
||
);
|
||
};
|
||
|
||
export default Footer; |