refactor: migrate to eslint flat config and format codebase with prettier

- Remove legacy .eslintrc.cjs and .eslintignore
- Add eslint.config.js with flat config, security rules (no-eval, no-implied-eval, no-new-func, no-script-url)
- Add .prettierrc and .prettierignore
- Format entire codebase with prettier
This commit is contained in:
c0mrade
2026-01-27 17:37:31 +03:00
parent 111ccc4e7a
commit bc90ba3779
133 changed files with 19972 additions and 15523 deletions

View File

@@ -1,53 +1,53 @@
import { useTranslation } from 'react-i18next'
import { useState, useRef, useEffect } from 'react'
import { useTranslation } from 'react-i18next';
import { useState, useRef, useEffect } from 'react';
const languages = [
{ code: 'ru', name: 'RU', flag: '🇷🇺', fullName: 'Русский' },
{ code: 'en', name: 'EN', flag: '🇬🇧', fullName: 'English' },
{ code: 'zh', name: 'ZH', flag: '🇨🇳', fullName: '中文' },
{ code: 'fa', name: 'FA', flag: '🇮🇷', fullName: 'فارسی' },
]
];
export default function LanguageSwitcher() {
const { i18n } = useTranslation()
const [isOpen, setIsOpen] = useState(false)
const dropdownRef = useRef<HTMLDivElement>(null)
const { i18n } = useTranslation();
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
const currentLang = languages.find((l) => l.code === i18n.language) || languages[0]
const currentLang = languages.find((l) => l.code === i18n.language) || languages[0];
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsOpen(false)
setIsOpen(false);
}
}
document.addEventListener('mousedown', handleClickOutside)
return () => document.removeEventListener('mousedown', handleClickOutside)
}, [])
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
const changeLanguage = (code: string) => {
i18n.changeLanguage(code)
i18n.changeLanguage(code);
// Set document direction for RTL languages
document.documentElement.dir = code === 'fa' ? 'rtl' : 'ltr'
setIsOpen(false)
}
document.documentElement.dir = code === 'fa' ? 'rtl' : 'ltr';
setIsOpen(false);
};
// Set initial direction on mount
useEffect(() => {
document.documentElement.dir = i18n.language === 'fa' ? 'rtl' : 'ltr'
}, [i18n.language])
document.documentElement.dir = i18n.language === 'fa' ? 'rtl' : 'ltr';
}, [i18n.language]);
return (
<div className="relative" ref={dropdownRef}>
<button
onClick={() => setIsOpen(!isOpen)}
className="flex items-center gap-1.5 px-2.5 py-2 rounded-xl border border-dark-700/50 hover:border-dark-600 bg-dark-800/50 hover:bg-dark-700 transition-all text-sm"
className="flex items-center gap-1.5 rounded-xl border border-dark-700/50 bg-dark-800/50 px-2.5 py-2 text-sm transition-all hover:border-dark-600 hover:bg-dark-700"
aria-label="Change language"
>
<span>{currentLang.flag}</span>
<span className="font-medium text-dark-200">{currentLang.name}</span>
<svg
className={`w-3.5 h-3.5 text-dark-400 transition-transform ${isOpen ? 'rotate-180' : ''}`}
className={`h-3.5 w-3.5 text-dark-400 transition-transform ${isOpen ? 'rotate-180' : ''}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
@@ -57,12 +57,12 @@ export default function LanguageSwitcher() {
</button>
{isOpen && (
<div className="absolute right-0 mt-2 w-40 bg-dark-800 rounded-xl shadow-lg border border-dark-700/50 py-1 z-50 animate-fade-in">
<div className="absolute right-0 z-50 mt-2 w-40 animate-fade-in rounded-xl border border-dark-700/50 bg-dark-800 py-1 shadow-lg">
{languages.map((lang) => (
<button
key={lang.code}
onClick={() => changeLanguage(lang.code)}
className={`w-full flex items-center gap-3 px-4 py-2.5 text-sm transition-colors ${
className={`flex w-full items-center gap-3 px-4 py-2.5 text-sm transition-colors ${
lang.code === i18n.language
? 'bg-accent-500/10 text-accent-400'
: 'text-dark-300 hover:bg-dark-700/50'
@@ -75,5 +75,5 @@ export default function LanguageSwitcher() {
</div>
)}
</div>
)
);
}