diff --git a/public/server-assets/style.css b/public/server-assets/style.css index 0dd9a0c..dc9e36f 100644 --- a/public/server-assets/style.css +++ b/public/server-assets/style.css @@ -56,12 +56,22 @@ header img.logo { } /* For automatic logo switching in dark mode */ -.logo-light { display: none; } -.logo-dark { display: block; } +.logo-light { + display: none; +} + +.logo-dark { + display: block; +} @media (prefers-color-scheme: dark) { - .logo-dark { display: none; } - .logo-light { display: block; } + .logo-dark { + display: none; + } + + .logo-light { + display: block; + } } h1 { @@ -77,7 +87,8 @@ table { margin-top: 1rem; } -th, td { +th, +td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid var(--border-color); @@ -169,4 +180,4 @@ footer { text-align: center; font-size: 0.875rem; opacity: 0.6; -} +} \ No newline at end of file diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 6c1ed5d..78e2b12 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -389,11 +389,19 @@ function App(): JSX.Element { } }, [logs, logDialogOpen]) + const handleOpenNginxConfig = async () => { + if (window.api && window.api.invoke) { + const config = await window.api.invoke('nginx:config:get') + setNginxConfig(config) + setIsNginxConfigOpen(true) + } + } + const handleSaveNginxConfig = async () => { if (window.api && window.api.invoke) { const result = await window.api.invoke('nginx:config:save', nginxConfig) if (result.success) { - Swal.fire({ title: t('common.success'), text: t('server.nginx.config_saved'), icon: 'success', background: '#1e1e1e', color: '#fff' }) + Swal.fire({ title: t('common.success'), text: t('server.nginx.config_saved'), icon: 'success' }) setIsNginxConfigOpen(false) } } @@ -411,7 +419,7 @@ function App(): JSX.Element { if (window.api && window.api.invoke) { const result = await window.api.invoke('apache:config:save', apacheConfig) if (result.success) { - Swal.fire({ title: t('common.success'), text: t('server.apache.config_saved'), icon: 'success', background: '#1e1e1e', color: '#fff' }) + Swal.fire({ title: t('common.success'), text: t('server.apache.config_saved'), icon: 'success' }) setIsApacheConfigOpen(false) } } @@ -420,7 +428,7 @@ function App(): JSX.Element { const handleTestApacheConfig = async () => { if (window.api && window.api.invoke) { const result = await window.api.invoke('apache:config:test') - Swal.fire({ title: result.success ? t('common.success') : t('common.error'), text: result.message, icon: result.success ? 'success' : 'error', background: '#1e1e1e', color: '#fff' }) + Swal.fire({ title: result.success ? t('common.success') : t('common.error'), text: result.message, icon: result.success ? 'success' : 'error' }) } } @@ -462,32 +470,36 @@ function App(): JSX.Element { const updateSwal = (currentSrv?: string) => { const html = ` -
+
${services.map(srv => { const label = getDisplayLabel(srv); const res = results[srv]; - let icon = ''; - let statusColor = 'rgba(255,255,255,0.4)'; + let iconClass = 'swal-status-icon'; + let noteClass = 'swal-status-note'; let note = operation === 'start' ? t('common.ready') : t('common.running'); if (res?.success) { - icon = ''; - statusColor = '#33d9b2'; + iconClass += ' success'; + noteClass += ' success'; note = operation === 'start' ? t('common.started') : t('common.stopped'); } else if (res?.error) { - icon = ''; - statusColor = '#ff5252'; + iconClass += ' error'; + noteClass += ' error'; note = t('common.error'); } else if (srv === currentSrv) { - icon = ''; - statusColor = '#39A7FF'; + iconClass += ' loading swal2-loading-dots'; + noteClass += ' loading'; note = operation === 'start' ? t('common.starting') : t('common.stopping'); } - return '
' + - '' + icon + ' ' + label + '' + - '' + note.toUpperCase() + '' + - '
'; + return ` +
+ + ${label} + + ${note.toUpperCase()} +
+ `; }).join('')}
`; @@ -499,8 +511,6 @@ function App(): JSX.Element { html: '
', allowOutsideClick: false, showConfirmButton: false, - background: '#1a1d21', - color: '#fff', customClass: { title: 'swal-title-small' }, @@ -598,9 +608,7 @@ function App(): JSX.Element { icon: 'warning', showCancelButton: true, confirmButtonText: t('common.yes_delete'), - cancelButtonText: t('common.cancel'), - background: '#1e1e1e', - color: '#fff' + cancelButtonText: t('common.cancel') }) if (result.isConfirmed) { @@ -639,8 +647,6 @@ function App(): JSX.Element { showCancelButton: !result.success && !!errorInfo?.host, confirmButtonText: !result.success && errorInfo?.host ? t('common.go_to_fix') : t('common.ok'), cancelButtonText: t('common.close'), - background: '#1e1e1e', - color: '#fff', width: '600px' }).then((alertResult) => { if (alertResult.isConfirmed && !result.success && errorInfo?.host) { @@ -667,10 +673,7 @@ function App(): JSX.Element { Swal.fire({ title: t('common.success'), text: t('server.nginx.config_saved'), - icon: 'success', - background: '#1e1e1e', - color: '#fff', - customClass: { popup: 'swal2-dark-popup' } + icon: 'success' }) setIsProjectNginxConfigOpen(false) } @@ -762,9 +765,7 @@ function App(): JSX.Element { icon: 'warning', showCancelButton: true, confirmButtonText: t('mariadb_process_monitor.kill_btn'), - cancelButtonText: t('common.cancel'), - background: '#1a1d21', - color: '#fff' + cancelButtonText: t('common.cancel') }) if (result.isConfirmed) { @@ -789,13 +790,7 @@ function App(): JSX.Element { maxWidth="lg" fullWidth PaperProps={{ - sx: { - bgcolor: '#1a1d21', - backgroundImage: 'none', - color: '#fff', - borderRadius: 2, - border: '1px solid rgba(255,255,255,0.1)' - } + className: 'mui-custom-dialog-paper' }} > @@ -1167,7 +1162,12 @@ function App(): JSX.Element { )} {v.status === 'installed' && ( - + + + + )} @@ -1920,11 +1920,7 @@ function App(): JSX.Element { maxWidth="lg" fullWidth PaperProps={{ - sx: { - bgcolor: '#1a1d21', - color: '#fff', - borderRadius: 2 - } + className: 'mui-custom-dialog-paper' }} > @@ -2016,12 +2012,7 @@ function App(): JSX.Element { maxWidth="md" fullWidth PaperProps={{ - sx: { - bgcolor: '#1e1e1e', - color: '#fff', - borderRadius: 3, - border: '1px solid rgba(255,255,255,0.1)' - } + className: 'mui-custom-dialog-paper' }} > @@ -2067,12 +2058,7 @@ function App(): JSX.Element { maxWidth="md" fullWidth PaperProps={{ - sx: { - bgcolor: '#1e1e1e', - color: '#fff', - borderRadius: 3, - border: '1px solid rgba(255,255,255,0.1)' - } + className: 'mui-custom-dialog-paper' }} > @@ -2112,16 +2098,14 @@ function App(): JSX.Element { ${formattedMessage}
${!result.success && errorInfo ? ` -
-

- {t('server.project_nginx.error_line', { line: errorInfo.line })} +

` : ''} `, icon: result.success ? 'success' : 'error', - background: '#1e1e1e', - color: '#fff', width: '600px' }) } @@ -2150,12 +2134,7 @@ function App(): JSX.Element { maxWidth="md" fullWidth PaperProps={{ - sx: { - bgcolor: '#1e1e1e', - color: '#fff', - borderRadius: 3, - border: '1px solid rgba(255,255,255,0.1)' - } + className: 'mui-custom-dialog-paper' }} > diff --git a/src/renderer/src/components/MariaDbDatabaseManager.tsx b/src/renderer/src/components/MariaDbDatabaseManager.tsx index c2061fb..39f4737 100644 --- a/src/renderer/src/components/MariaDbDatabaseManager.tsx +++ b/src/renderer/src/components/MariaDbDatabaseManager.tsx @@ -88,8 +88,6 @@ const MariaDbDatabaseManager: React.FC = ({ version input: 'text', inputLabel: t('mariadb_manager.db_name_label'), showCancelButton: true, - background: '#1e1e1e', - color: '#fff', inputValidator: (value) => { if (!value) return t('common.error_required') return null @@ -99,10 +97,10 @@ const MariaDbDatabaseManager: React.FC = ({ version if (dbName) { const result = await window.api.invoke('mariadb:create-db', { versionId: selectedVersion, dbName }) if (result.success) { - Swal.fire({ icon: 'success', title: t('common.ok'), background: '#1e1e1e', color: '#fff' }) + Swal.fire({ icon: 'success', title: t('common.ok') }) fetchData() } else { - Swal.fire({ icon: 'error', title: t('common.error'), text: result.message, background: '#1e1e1e', color: '#fff' }) + Swal.fire({ icon: 'error', title: t('common.error'), text: result.message }) } } } @@ -112,9 +110,7 @@ const MariaDbDatabaseManager: React.FC = ({ version title: t('common.are_you_sure'), text: t('mariadb_manager.delete_db_confirm', { db: dbName }), icon: 'warning', - showCancelButton: true, - background: '#1e1e1e', - color: '#fff' + showCancelButton: true }) if (result.isConfirmed) { @@ -122,7 +118,7 @@ const MariaDbDatabaseManager: React.FC = ({ version if (res.success) { fetchData() } else { - Swal.fire({ icon: 'error', title: t('common.error'), text: res.message, background: '#1e1e1e', color: '#fff' }) + Swal.fire({ icon: 'error', title: t('common.error'), text: res.message }) } } } @@ -135,8 +131,6 @@ const MariaDbDatabaseManager: React.FC = ({ version `` + ``, focusConfirm: false, - background: '#1e1e1e', - color: '#fff', preConfirm: () => { const user = (document.getElementById('swal-user') as HTMLInputElement).value const host = (document.getElementById('swal-host') as HTMLInputElement).value @@ -152,10 +146,10 @@ const MariaDbDatabaseManager: React.FC = ({ version if (formValues) { const result = await window.api.invoke('mariadb:create-user', { versionId: selectedVersion, ...formValues }) if (result.success) { - Swal.fire({ icon: 'success', title: t('common.ok'), background: '#1e1e1e', color: '#fff' }) + Swal.fire({ icon: 'success', title: t('common.ok') }) fetchData() } else { - Swal.fire({ icon: 'error', title: t('common.error'), text: result.message, background: '#1e1e1e', color: '#fff' }) + Swal.fire({ icon: 'error', title: t('common.error'), text: result.message }) } } } @@ -165,9 +159,7 @@ const MariaDbDatabaseManager: React.FC = ({ version title: t('common.are_you_sure'), text: t('mariadb_manager.delete_user_confirm', { user: `${user}@${host}` }), icon: 'warning', - showCancelButton: true, - background: '#1e1e1e', - color: '#fff' + showCancelButton: true }) if (result.isConfirmed) { @@ -175,7 +167,7 @@ const MariaDbDatabaseManager: React.FC = ({ version if (res.success) { fetchData() } else { - Swal.fire({ icon: 'error', title: t('common.error'), text: res.message, background: '#1e1e1e', color: '#fff' }) + Swal.fire({ icon: 'error', title: t('common.error'), text: res.message }) } } } diff --git a/src/renderer/src/components/MariaDbExportWizard.tsx b/src/renderer/src/components/MariaDbExportWizard.tsx index d2e962e..d03c77f 100644 --- a/src/renderer/src/components/MariaDbExportWizard.tsx +++ b/src/renderer/src/components/MariaDbExportWizard.tsx @@ -272,7 +272,15 @@ const MariaDbExportWizard: React.FC = ({ open, onClose } return ( - + {t('mariadb.export.wizard_title')} diff --git a/src/renderer/src/components/MariaDbImportWizard.tsx b/src/renderer/src/components/MariaDbImportWizard.tsx index 49689b1..ac04e75 100644 --- a/src/renderer/src/components/MariaDbImportWizard.tsx +++ b/src/renderer/src/components/MariaDbImportWizard.tsx @@ -316,7 +316,15 @@ const MariaDbImportWizard: React.FC = ({ open, onClose } return ( - + {t('mariadb.import.wizard_title')} diff --git a/src/renderer/src/components/PhpExtensionManager.tsx b/src/renderer/src/components/PhpExtensionManager.tsx index 7898e8a..f9f75f7 100644 --- a/src/renderer/src/components/PhpExtensionManager.tsx +++ b/src/renderer/src/components/PhpExtensionManager.tsx @@ -79,9 +79,7 @@ const PhpExtensionManager: React.FC = ({ open, onClose allowOutsideClick: false, didOpen: () => { Swal.showLoading() - }, - background: '#1e1e1e', - color: '#fff' + } }) try { @@ -95,15 +93,13 @@ const PhpExtensionManager: React.FC = ({ open, onClose text: t('php.extensions.success_msg'), icon: 'success', timer: 2000, - showConfirmButton: false, - background: '#1e1e1e', - color: '#fff' + showConfirmButton: false }) setIsRawEditorOpen(false) fetchExtensions() } } catch (error: any) { - Swal.fire({ title: 'Hata', text: error.message, icon: 'error', background: '#1e1e1e', color: '#fff' }) + Swal.fire({ title: 'Hata', text: error.message, icon: 'error' }) } finally { setIsSavingRaw(false) } @@ -131,9 +127,7 @@ const PhpExtensionManager: React.FC = ({ open, onClose allowOutsideClick: false, didOpen: () => { Swal.showLoading() - }, - background: '#1e1e1e', - color: '#fff' + } }) } @@ -147,10 +141,10 @@ const PhpExtensionManager: React.FC = ({ open, onClose Swal.close() } } else { - Swal.fire({ title: t('common.error'), text: result.message, icon: 'error', background: '#1e1e1e', color: '#fff' }) + Swal.fire({ title: t('common.error'), text: result.message, icon: 'error' }) } } catch (error: any) { - Swal.fire({ title: t('common.error'), text: error.message, icon: 'error', background: '#1e1e1e', color: '#fff' }) + Swal.fire({ title: t('common.error'), text: error.message, icon: 'error' }) } finally { setSaving(null) } @@ -169,13 +163,7 @@ const PhpExtensionManager: React.FC = ({ open, onClose maxWidth="sm" fullWidth PaperProps={{ - sx: { - bgcolor: '#1e1e1e', - color: '#fff', - backgroundImage: 'none', - borderRadius: 2, - border: '1px solid rgba(255,255,255,0.1)' - } + className: 'mui-custom-dialog-paper' }} > @@ -280,13 +268,7 @@ const PhpExtensionManager: React.FC = ({ open, onClose maxWidth="md" fullWidth PaperProps={{ - sx: { - bgcolor: '#1a1a1a', - color: '#fff', - borderRadius: 2, - backgroundImage: 'none', - border: '1px solid rgba(255,255,255,0.1)' - } + className: 'mui-custom-dialog-paper' }} > diff --git a/src/renderer/src/components/ProjectManager/ProjectDetails.tsx b/src/renderer/src/components/ProjectManager/ProjectDetails.tsx index 84f255a..468de77 100644 --- a/src/renderer/src/components/ProjectManager/ProjectDetails.tsx +++ b/src/renderer/src/components/ProjectManager/ProjectDetails.tsx @@ -150,9 +150,7 @@ export default function ProjectDetails({ toast: true, position: 'top-end', showConfirmButton: false, - timer: 3000, - background: '#1e1e1e', - color: '#fff' + timer: 3000 }); onRefreshProjects(); } @@ -160,9 +158,7 @@ export default function ProjectDetails({ Swal.fire({ icon: 'error', title: t('common.error'), - text: e.message, - background: '#1e1e1e', - color: '#fff' + text: e.message }); } finally { setIsConfigSaving(false); @@ -186,9 +182,7 @@ export default function ProjectDetails({ toast: true, position: 'top-end', showConfirmButton: false, - timer: 3000, - background: '#1e1e1e', - color: '#fff' + timer: 3000 }); if (onRefreshProjects) onRefreshProjects(); } @@ -196,9 +190,7 @@ export default function ProjectDetails({ Swal.fire({ icon: 'error', title: t('common.error'), - text: error.message, - background: '#1e1e1e', - color: '#fff' + text: error.message }); } finally { setIsSaving(false); diff --git a/src/renderer/src/components/ServerTuning.tsx b/src/renderer/src/components/ServerTuning.tsx index 647aea8..0b9c631 100644 --- a/src/renderer/src/components/ServerTuning.tsx +++ b/src/renderer/src/components/ServerTuning.tsx @@ -337,13 +337,7 @@ export default function ServerTuning() { maxWidth="sm" fullWidth PaperProps={{ - sx: { - bgcolor: '#1a1d21', - backgroundImage: 'none', - color: '#fff', - borderRadius: 4, - border: '1px solid rgba(255,255,255,0.1)' - } + className: 'mui-custom-dialog-paper' }} > diff --git a/src/renderer/src/locales/ru.json b/src/renderer/src/locales/ru.json new file mode 100644 index 0000000..dee8495 --- /dev/null +++ b/src/renderer/src/locales/ru.json @@ -0,0 +1,360 @@ +{ + "common": { + "actions": "Действие", + "start": "Запустить", + "stop": "Остановить", + "started": "Запущено", + "restart": "Перезапустить", + "settings": "Настройки", + "tools": "Инструменты", + "close": "Закрыть", + "quit": "Выход", + "save": "Сохранить", + "user_guide": "Руководство пользователя", + "port": "Порт", + "all": "Все", + "export": "Экспорт", + "import": "Импорт", + "ok": "ОК", + "cancel": "Отмена", + "error": "Ошибка!", + "success": "Успешно!", + "warning": "Предупреждение", + "info": "Информация", + "delete": "Удалить", + "edit": "Редактировать", + "refresh": "Обновить", + "search": "Поиск", + "loading": "Загрузка...", + "starting": "Запуск...", + "running": "Работает", + "stopped": "Остановлено", + "stopping": "Остановка...", + "ready": "Готово.", + "waiting_process": "Ожидание процесса...", + "executable_not_found": "Файл не найден", + "are_you_sure": "Вы уверены?", + "yes_delete": "Да, удалить", + "go_to_fix": "Перейти к исправлению", + "select": "ВЫБРАТЬ", + "next": "ДАЛЕЕ", + "back": "НАЗАД", + "finish": "ЗАВЕРШИТЬ", + "download": "СКАЧАТЬ", + "available": "Доступно", + "reset": "Сбросить", + "copy": "Копировать", + "browse": "Обзор", + "delete_confirm": "Вы уверены, что хотите удалить этот проект?", + "stop_status": "Остановка", + "reset_confirm_title": "Вы уверены?", + "reset_confirm_text": "Вы хотите сбросить данные {{service}}? Это действие удалит все данные и выполнит чистую установку.", + "reset_btn": "Да, сбросить", + "operating": "Операция выполняется...", + "please_wait": "Пожалуйста, подождите...", + "status": "Статус" + }, + "dashboard": { + "title": "Панель управления", + "status": "Статус сервера", + "services": "Сервисы", + "active_version": "Активная версия PHP", + "quick_look": "Быстрый обзор", + "start_all": "Запустить все", + "stop_all": "Остановить все", + "starting_all": "Запуск всех сервисов", + "stopping_all": "Остановка всех сервисов", + "all_started": "Все сервисы запущены.", + "all_stopped": "Все сервисы остановлены.", + "overview": "Обзор", + "service_settings": "Настройки сервиса", + "project_settings": "Настройки проекта", + "select_service": "Пожалуйста, выберите сервис", + "system_stats": "СИСТЕМНАЯ СТАТИСТИКА", + "service_info": "ИНФОРМАЦИЯ О СЕРВИСЕ" + }, + "projects": { + "title": "Мои проекты", + "add_new": "Добавить новый проект", + "search": "Поиск проекта или хоста...", + "edit": "Редактировать проект", + "empty": "Проекты пока не добавлены.", + "name": "Название проекта", + "path": "Путь к папке", + "host": "Хост / Домен", + "hostname_placeholder": "Имя хоста (напр: local.test)", + "php_version": "Версия PHP", + "mariadb_version": "Версия MariaDB", + "server_type": "Веб-сервер", + "apache_htaccess": "Apache (с поддержкой htaccess)", + "actions": "Действия", + "no_php_warning": "Сначала необходимо скачать версию PHP", + "added": "Проект успешно добавлен.", + "updated": "Проект успешно обновлен.", + "deleted": "Проект удален.", + "delete_confirm": "Вы уверены, что хотите удалить этот проект? Ваши файлы не будут удалены, проект просто исчезнет из списка.", + "browse": "Обзор", + "overview": "Обзор", + "database": "База данных", + "site_domain": "Адрес сайта", + "web_server": "Веб-сервер", + "site_path": "Путь к файлам", + "open_site": "ОТКРЫТЬ САЙТ", + "stop_site": "ОСТАНОВИТЬ САЙТ", + "start_site": "ЗАПУСТИТЬ САЙТ", + "no_site_selected": "Пожалуйста, сначала выберите сайт.", + "server_settings": "НАСТРОЙКИ СЕРВЕРА", + "manual_edit_warning": "При ручном редактировании этих настроек в начало добавляется # MANUAL_EDIT, и система прекращает автоматические обновления.", + "no_project_selected": "Пожалуйста, выберите проект из списка или создайте новый." + }, + "settings": { + "general": "Общие настройки", + "saved": "Настройки сохранены.", + "save_failed": "Не удалось сохранить настройки.", + "language": "Язык", + "nginx_port": "Порт Nginx", + "apache_port": "Порт Apache", + "php_port": "Порт PHP-FPM", + "mariadb_port": "Порт MariaDB", + "remote_access": "Разрешить удаленный доступ", + "server_type_select": "Тип сервера по умолчанию", + "php_versions": "Версии PHP", + "mariadb_versions": "Версии MariaDB", + "nginx_versions": "Версии Nginx", + "apache_versions": "Версии Apache", + "php_versions_desc": "Здесь вы можете скачивать и управлять необходимыми версиями PHP.", + "mariadb_versions_desc": "Управление версиями MariaDB.", + "nginx_versions_desc": "Управление версиями Nginx.", + "apache_versions_desc": "Управление версиями Apache.", + "nginx_port_desc": "Порт, на котором будет работать Nginx (по умолчанию: 80)", + "cli_env": "CLI и переменные окружения", + "cli_env_desc": "Управляйте настройками PATH, чтобы запускать команды PHP и MariaDB напрямую из любого терминала (CMD, PowerShell).", + "cli_enabled": "Интеграция с системным PATH активна", + "cli_enabled_desc": "Если включено, папка 'bin' Multi-PHP будет добавлена в переменную PATH пользователя.", + "cli_default_php": "Версия PHP по умолчанию (php)", + "cli_default_php_desc": "Выберите, какая версия будет использоваться при выполнении команды 'php'.", + "cli_default_mariadb": "Версия MariaDB по умолчанию (mysql)", + "cli_default_mariadb_desc": "Версия по умолчанию для команд 'mysql' или 'mariadb'.", + "cli_sync_btn": "Синхронизировать команды", + "cli_path_found": "Настройка PATH найдена:", + "cli_path_not_found": "Настройка PATH еще не выполнена", + "cli_sync_success": "Команды CLI успешно обновлены.", + "cli_aliases_title": "Созданные команды (псевдонимы)", + "cli_restart_warning": "Внимание: Чтобы изменения PATH вступили в силу, необходимо закрыть и снова открыть окна терминала/CMD.", + "cli_table_command": "Команда", + "cli_table_version": "Вызываемая версия", + "cli_table_path": "Путь к файлу" + }, + "server": { + "nginx": { + "title": "Nginx", + "config": "Настройки Nginx", + "config_title": "Конфигурация Nginx (nginx.conf)", + "config_warning": "Внимание: Неправильная конфигурация может остановить работу Nginx. Протестируйте перед сохранением.", + "test_config": "Проверить конфигурацию", + "save_reload": "Сохранить и перезагрузить", + "config_saved": "Конфигурация Nginx успешно сохранена.", + "test_failed": "Ошибка конфигурации" + }, + "apache": { + "title": "Apache", + "config": "Настройки Apache", + "config_title": "Конфигурация Apache (httpd.conf)", + "config_desc": "Этот файл является основным (глобальным) конфигурационным файлом сервера Apache.", + "test_config": "Проверить конфигурацию", + "save_reload": "Сохранить и перезагрузить", + "config_saved": "Конфигурация Apache сохранена." + }, + "project_nginx": { + "title": "Конфигурация Nginx для {{host}}", + "tip": "Совет: Эта конфигурация применима только к проекту {{host}}.", + "error_line": "Строка ошибки: {{line}}" + } + }, + "pma": { + "ready_desc": "phpMyAdmin готов к управлению базами данных.", + "install_desc": "Установите phpMyAdmin для управления базами данных через веб-интерфейс.", + "installing": "УСТАНОВКА...", + "install_button": "НАЧАТЬ УСТАНОВКУ", + "open": "ОТКРЫТЬ", + "progress": "Загрузка... %{{progress}}" + }, + "mariadb": { + "import": { + "title": "Импорт данных MariaDB", + "desc": "Быстро загрузите выбранный .sql файл или архив в базу данных.", + "button": "ИМПОРТ", + "wizard_title": "Мастер быстрого дампа/импорта MariaDB", + "step1": "Выбор данных", + "step2": "Выбор сервера", + "step3": "Конфигурация базы данных", + "step4": "Итог и выполнение", + "step1_desc": "Пожалуйста, выберите файл .sql или архив (.zip, .tar.gz) для загрузки.", + "step2_desc": "Выберите сервер MariaDB, на который будет загружен файл.", + "step3_desc": "Настройте параметры базы данных и пользователя.", + "no_file": "Файл не выбран...", + "root_pass": "Пароль Root (если есть)", + "root_pass_helper": "Введите текущий пароль пользователя 'root' в MariaDB. Оставьте пустым, если пароля нет.", + "db_name": "Имя базы данных", + "db_user": "Пользователь БД", + "db_pass": "Пароль пользователя", + "summary": "Итоговая информация", + "file": "Файл", + "server": "Сервер", + "db": "База данных", + "user": "Пользователь", + "success_title": "Успешно!", + "error_title": "Произошла ошибка!", + "access_info": "Информация для доступа", + "host": "Хост", + "starting": "[Система] Процесс запущен...", + "overwrite_title": "База данных уже существует!", + "overwrite_desc": "База данных '{{dbName}}' уже существует. Хотите перезаписать её? Все текущие данные будут удалены!", + "btn_summary": "ПОСМОТРЕТЬ ИТОГ", + "btn_start": "НАЧАТЬ ИМПОРТ" + }, + "export": { + "title": "Экспорт данных MariaDB", + "desc": "Безопасно создавайте резервные копии баз данных в форматах .sql или .sql.gz.", + "button": "ЭКСПОРТ", + "wizard_title": "Мастер экспорта базы данных MariaDB", + "step1": "Выбор сервера", + "step2": "Выбор базы данных", + "step3": "Настройки экспорта", + "step4": "Итог и выполнение", + "step1_desc": "Выберите сервер MariaDB, на котором находится база данных.", + "step2_desc": "Выберите базу данных для экспорта.", + "step3_desc": "Укажите место сохранения и формат файла.", + "placeholder": "Файл для сохранения...", + "compress": "Сжать с помощью Gzip (.sql.gz)", + "target": "Цель", + "compression": "Сжатие", + "on": "Включено (.gz)", + "off": "Выключено (.sql)", + "btn_show_file": "ПОКАЗАТЬ ФАЙЛ", + "btn_start": "НАЧАТЬ ЭКСПОРТ", + "starting": "[Система] Процесс экспорта запущен...", + "no_db_found": "На выбранном сервере не найдено доступных баз данных.", + "list_error": "Не удалось получить список баз данных: " + }, + "wizard": { + "import_title": "Мастер импорта данных MariaDB", + "export_title": "Мастер экспорта данных MariaDB", + "select_version": "Выберите версию MariaDB", + "select_db": "Выберите базу данных", + "select_file": "Выберите файл", + "import_success": "Данные успешно импортированы.", + "export_success": "Данные успешно экспортированы." + } + }, + "diagnostics": { + "logs": "Логи ошибок", + "noLogs": "Записей в логах пока нет." + }, + "php": { + "extensions": { + "title": "Расширения PHP {{version}}", + "desc": "Управляйте расширениями через php.ini", + "search_placeholder": "Поиск расширения... (mysql, gd, mbstring...)", + "search_file_placeholder": "Поиск в файле...", + "raw_editor": "RAW РЕДАКТОР", + "none": "Расширения отсутствуют.", + "not_found": "Расширение не найдено.", + "active": "Активно", + "ini_edit": "Редактировать php.ini ({{version}})", + "file_open_tip": "Открыть файл в системе", + "saving": "Сохранение конфигурации", + "restarting": "Перезапуск сервиса PHP...", + "adjusting": "Настройка расширения", + "adjusting_desc": "{{extName}}: режим {{mode}}, выполняется перезапуск PHP...", + "save_restart_btn": "СОХРАНИТЬ И ПЕРЕЗАПУСТИТЬ", + "saving_btn": "СОХРАНЕНИЕ...", + "save_error": "Ошибка при сохранении расширений.", + "success_msg": "Конфигурация сохранена, сервис перезапущен.", + "prev_match": "Пред. (Shift+Enter)", + "next_match": "След. (Enter)" + } + }, + "mariadb_process_monitor": { + "title": "Список процессов БД", + "auto_refresh_desc": "Список процессов обновляется автоматически каждые 3 секунды.", + "kill_btn": "KILL", + "kill_confirm": "Вы уверены, что хотите завершить этот процесс?", + "refresh_btn": "Обновить", + "click_to_view_sql": "Нажмите, чтобы просмотреть SQL-запрос", + "query_details": "Детали запроса", + "no_processes": "Активных процессов не найдено.", + "columns": { + "id": "ID", + "user": "Пользователь", + "host": "Хост", + "db": "База данных", + "command": "Команда", + "time": "Время", + "state": "Статус", + "info": "Информация", + "progress": "Прогресс" + } + }, + "tuning": { + "title": "Оптимизация", + "desc": "Оптимизируйте производительность PHP и MariaDB с помощью критических лимитов ресурсов.", + "php_total": "Экземпляр PHP", + "mariadb_total": "Экземпляр MariaDB", + "tune_btn": "НАСТРОИТЬ", + "saving": "Применение изменений...", + "restart_notice": "Для вступления в силу некоторых изменений требуется перезапуск сервисов.", + "parameters": { + "memory_limit": "Лимит памяти", + "memory_limit_desc": "Максимальный объем памяти, который может использовать скрипт.", + "max_execution_time": "Макс. время выполнения", + "max_execution_time_desc": "Максимальное время работы скрипта в секундах.", + "post_max_size": "Макс. размер POST", + "post_max_size_desc": "Максимальный объем данных POST, принимаемый PHP.", + "upload_max_filesize": "Лимит загрузки файлов", + "upload_max_filesize_desc": "Максимальный размер загружаемого файла.", + "max_input_vars": "Макс. входных переменных", + "max_input_vars_desc": "Количество входных переменных (GET/POST/Cookie), которые могут быть приняты.", + "max_connections": "Макс. соединений", + "max_connections_desc": "Максимальное количество одновременных клиентских подключений.", + "innodb_buffer_pool_size": "Буферный пул InnoDB", + "innodb_buffer_pool_size_desc": "Критично для производительности. Хранит индексы и данные в памяти.", + "key_buffer_size": "Размер буфера ключей", + "key_buffer_size_desc": "Индексные блоки для таблиц MyISAM (общие для всех потоков).", + "max_allowed_packet": "Макс. размер пакета", + "max_allowed_packet_desc": "Максимальный размер одного SQL-запроса или результата." + } + }, + "service_monitor": { + "title": "Логи сервисов", + "desc": "Отслеживайте историю запуска, остановки и ошибок сервисов.", + "event_log": "Журнал событий", + "clear_confirm": "Вы уверены, что хотите очистить всю историю событий?", + "chart_title": "График активности сервисов", + "no_events": "Событий пока не зарегистрировано.", + "columns": { + "service": "Сервис", + "action": "Действие", + "status": "Статус", + "timestamp": "Время", + "details": "Детали" + } + }, + "mariadb_manager": { + "title": "Управление БД", + "databases_title": "Базы данных", + "users_title": "Пользователи", + "create_db_btn": "Новая база данных", + "create_db_title": "Создать новую базу данных", + "db_name_label": "Имя базы данных", + "db_name": "База данных", + "db_size": "Размер", + "create_user_btn": "Новый пользователь", + "create_user_title": "Создать нового пользователя", + "user_label": "Имя пользователя", + "password_label": "Пароль", + "delete_db_confirm": "Вы уверены, что хотите удалить базу данных '{{db}}'? Это действие необратимо!", + "delete_user_confirm": "Вы уверены, что хотите удалить пользователя '{{user}}'?", + "no_active_version": "Пожалуйста, сначала выберите установленную версию MariaDB или скачайте её." + } +} \ No newline at end of file diff --git a/src/renderer/src/styles/GlobalStyles.tsx b/src/renderer/src/styles/GlobalStyles.tsx index 15654e6..b5f8fca 100644 --- a/src/renderer/src/styles/GlobalStyles.tsx +++ b/src/renderer/src/styles/GlobalStyles.tsx @@ -104,6 +104,75 @@ const styles = { padding: '10px !important', borderRadius: '5px !important', border: '1px solid rgba(255,255,255,0.1) !important' + }, + // Service List Alert Classes + '.swal-service-list': { + textAlign: 'left', + fontFamily: "'Inter', sans-serif", + paddingTop: '10px' + }, + '.swal-service-item': { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + marginBottom: '6px', + padding: '8px 14px', + background: 'rgba(0,0,0,0.2)', + border: '1px solid rgba(255,255,255,0.03)', + borderRadius: '8px', + fontSize: '0.8rem' + }, + '.swal-service-label': { + fontWeight: 600, + display: 'flex', + alignItems: 'center' + }, + '.swal-status-icon': { + marginRight: '12px', + fontSize: '0.8rem', + color: 'rgba(255,255,255,0.1)' + }, + '.swal-status-icon.success': { + color: '#33d9b2' + }, + '.swal-status-icon.error': { + color: '#ff5252' + }, + '.swal-status-icon.loading': { + color: '#39A7FF' + }, + '.swal-status-note': { + fontSize: '0.65rem', + fontWeight: 800, + letterSpacing: '0.5px', + textTransform: 'uppercase', + color: 'rgba(255,255,255,0.4)' + }, + '.swal-status-note.success': { + color: '#33d9b2' + }, + '.swal-status-note.error': { + color: '#ff5252' + }, + '.swal-status-note.loading': { + color: '#39A7FF' + }, + // Global Dialog Styling (for MUI PaperProps removal) + '.mui-custom-dialog-paper': { + background: '#1a1d21 !important', + backgroundImage: 'none !important', + color: '#fff !important', + borderRadius: '16px !important', + border: '1px solid rgba(255,255,255,0.1) !important', + boxShadow: '0 24px 48px rgba(0,0,0,0.5) !important' + }, + '.swal-error-footer': { + marginTop: '15px !important', + textAlign: 'center !important' + }, + '.swal-error-line': { + fontSize: '0.9rem !important', + color: '#ffb142 !important' } }