Add Russian translations for common settings in AdminSettings

- Introduced a dictionary for translating various settings into Russian.
- Updated the `formatSettingName` function to return translated names when available.
- Adjusted layout for sidebar and main content to improve responsiveness and organization.
This commit is contained in:
PEDZEO
2026-01-21 03:25:46 +03:00
parent 0679905c51
commit 76b2d713f1

View File

@@ -105,11 +105,61 @@ const MenuIcon = () => (
) )
// ============ HELPER FUNCTIONS ============ // ============ HELPER FUNCTIONS ============
// Словарь переводов для распространенных настроек
const SETTING_TRANSLATIONS: Record<string, string> = {
// Skip
'Skip Referral Code': 'Пропуск реферального кода',
'Skip Rules Accept': 'Пропуск принятия правил',
// HAPP
'Connect Button Happ Download Enabled': 'Кнопка скачивания Happ',
'Happ Cryptolink Redirect Template': 'Шаблон редиректа Happ',
'Happ Download Link Android': 'Ссылка скачивания Happ (Android)',
'Happ Download Link Ios': 'Ссылка скачивания Happ (iOS)',
'Happ Download Link Macos': 'Ссылка скачивания Happ (macOS)',
'Happ Download Link Pc': 'Ссылка скачивания Happ (PC)',
'Happ Download Link Windows': 'Ссылка скачивания Happ (Windows)',
// Interface
'Main Menu Mode': 'Режим главного меню',
// MiniApp
'Cabinet Remna Sub Config': 'UUID конфига RemnaWave',
'Miniapp Purchase Url': 'URL покупки в MiniApp',
'Miniapp Service Description En': 'Описание сервиса (EN)',
'Miniapp Service Description Ru': 'Описание сервиса (RU)',
'Miniapp Service Name En': 'Название сервиса (EN)',
'Miniapp Service Name Ru': 'Название сервиса (RU)',
'Miniapp Static Path': 'Путь к статике MiniApp',
'Miniapp Support Type': 'Тип поддержки MiniApp',
'Miniapp Support Url': 'URL поддержки MiniApp',
'Miniapp Tickets Enabled': 'Тикеты в MiniApp',
// Branding
'Bot Name': 'Название бота',
'Logo Letter': 'Буква логотипа',
// Connect Button
'Connect Button Enabled': 'Кнопка подключения',
'Connect Button Text': 'Текст кнопки подключения',
// Additional
'Additional Menu Enabled': 'Дополнительное меню',
'Additional Menu Items': 'Элементы доп. меню',
'Additional Menu Title': 'Заголовок доп. меню',
// Subscription Interface
'Subscription Page Layout': 'Макет страницы подписки',
// Common
'Enabled': 'Включено',
'Disabled': 'Отключено',
'Debug Mode': 'Режим отладки',
'Log Level': 'Уровень логирования',
'Api Url': 'URL API',
'Api Key': 'API ключ',
'Api Token': 'API токен',
'Webhook Url': 'URL вебхука',
'Webhook Secret': 'Секрет вебхука',
}
// Форматирование названия настройки (Snake_Case / CamelCase -> читаемый текст) // Форматирование названия настройки (Snake_Case / CamelCase -> читаемый текст)
function formatSettingName(name: string): string { function formatSettingName(name: string): string {
if (!name) return '' if (!name) return ''
// Убираем префиксы типа "Miniapp ", "Happ " и т.д. // Сначала форматируем в читаемый вид
let formatted = name let formatted = name
// CamelCase -> пробелы // CamelCase -> пробелы
.replace(/([a-z])([A-Z])/g, '$1 $2') .replace(/([a-z])([A-Z])/g, '$1 $2')
@@ -119,8 +169,11 @@ function formatSettingName(name: string): string {
.replace(/\s+/g, ' ') .replace(/\s+/g, ' ')
.trim() .trim()
// Делаем первую букву заглавной, остальные как есть // Делаем первую букву заглавной
return formatted.charAt(0).toUpperCase() + formatted.slice(1) formatted = formatted.charAt(0).toUpperCase() + formatted.slice(1)
// Проверяем есть ли перевод
return SETTING_TRANSLATIONS[formatted] || formatted
} }
// Очистка HTML тегов из описания // Очистка HTML тегов из описания
@@ -896,7 +949,7 @@ export default function AdminSettings() {
// ============ RENDER ============ // ============ RENDER ============
return ( return (
<div className="relative min-h-screen"> <div className="flex min-h-screen">
{/* Mobile overlay */} {/* Mobile overlay */}
{mobileMenuOpen && ( {mobileMenuOpen && (
<div <div
@@ -905,10 +958,10 @@ export default function AdminSettings() {
/> />
)} )}
{/* Sidebar - hidden on mobile, visible on desktop */} {/* Sidebar - drawer on mobile, static on desktop */}
<div className={` <aside className={`
fixed lg:static inset-y-0 left-0 z-50 fixed lg:sticky lg:top-0 inset-y-0 left-0 z-50
w-64 bg-dark-900 border-r border-dark-700/50 w-64 h-screen bg-dark-900 border-r border-dark-700/50 flex-shrink-0
transform transition-transform duration-200 ease-in-out transform transition-transform duration-200 ease-in-out
${mobileMenuOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'} ${mobileMenuOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'}
`}> `}>
@@ -964,10 +1017,10 @@ export default function AdminSettings() {
</div> </div>
))} ))}
</nav> </nav>
</div> </aside>
{/* Main content */} {/* Main content */}
<div className="lg:ml-64"> <main className="flex-1 min-w-0">
{/* Header */} {/* Header */}
<div className="sticky top-0 z-30 bg-dark-900/95 backdrop-blur-xl border-b border-dark-700/50 p-3 sm:p-4"> <div className="sticky top-0 z-30 bg-dark-900/95 backdrop-blur-xl border-b border-dark-700/50 p-3 sm:p-4">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
@@ -1025,7 +1078,7 @@ export default function AdminSettings() {
{activeSection === 'theme' && renderThemeContent()} {activeSection === 'theme' && renderThemeContent()}
{['payments', 'subscriptions', 'interface', 'notifications', 'database', 'system', 'users'].includes(activeSection) && renderSettingsContent()} {['payments', 'subscriptions', 'interface', 'notifications', 'database', 'system', 'users'].includes(activeSection) && renderSettingsContent()}
</div> </div>
</div> </main>
</div> </div>
) )
} }