diff --git a/src/main/services/ProcessManager.ts b/src/main/services/ProcessManager.ts index 20b9205..3a911d7 100644 --- a/src/main/services/ProcessManager.ts +++ b/src/main/services/ProcessManager.ts @@ -3,6 +3,7 @@ import path from 'path' import { app } from 'electron' import fs from 'fs' import { configService } from './ConfigService' +import { t } from '../utils/i18n' export class ProcessManager { private processes: Map = new Map() @@ -24,7 +25,7 @@ export class ProcessManager { // Initialize with default logs ['nginx', 'apache', 'php', 'mariadb'].forEach(s => { if (!this.logs.has(s)) { - this.logs.set(s, [`[${new Date().toLocaleTimeString()}] Sistem hazır. İşlem bekleniyor...`]) + this.logs.set(s, [`[${new Date().toLocaleTimeString()}] ${t('common.ready')} ${t('common.waiting_process')}`]) } }) } catch (e) { @@ -103,12 +104,12 @@ export class ProcessManager { } if (!fs.existsSync(binPath)) { - this.addLog(name, `Executable not found: ${binPath}`) + this.addLog(name, `${t('common.error')}: ${t('common.executable_not_found')} (${binPath})`) return false } try { - this.addLog(name, `Starting service with: ${binPath} ${args.join(' ')}`) + this.addLog(name, `${t('common.starting')}... (${binPath})`) const serviceEnv = { ...process.env } const binDirPath = path.dirname(binPath) @@ -127,7 +128,7 @@ export class ProcessManager { }) console.log(`[PROCESS] Started ${name} with PID ${child.pid}`) - this.addLog(name, `Process started (PID: ${child.pid})`) + this.addLog(name, `${t('common.running')} (PID: ${child.pid})`) child.stdout?.on('data', (data) => this.addLog(name, data.toString())) child.stderr?.on('data', (data) => this.addLog(name, data.toString())) @@ -138,7 +139,7 @@ export class ProcessManager { }) child.on('exit', (code) => { - this.addLog(name, `Exited with code ${code}`) + this.addLog(name, `${t('common.stopped')} (Code: ${code})`) if (code !== 0) { this.checkErrorLogs(name) } @@ -157,7 +158,7 @@ export class ProcessManager { async stopService(name: string): Promise { const child = this.processes.get(name) if (child) { - this.addLog(name, 'Stopping service...') + this.addLog(name, `${t('common.stopping')}...`) try { if (process.platform === 'win32') { child.kill() diff --git a/src/main/utils/i18n.ts b/src/main/utils/i18n.ts new file mode 100644 index 0000000..883e410 --- /dev/null +++ b/src/main/utils/i18n.ts @@ -0,0 +1,65 @@ +import fs from 'fs' +import path from 'path' +import { app } from 'electron' +import { configService } from '../services/ConfigService' + +class MainI18n { + private locales: Record = {} + + constructor() { + this.loadLocales() + } + + private loadLocales() { + try { + // In development, locales are in src/renderer/src/locales + // In production, they should be in a resources folder + const isDev = !app.isPackaged + let localesPath = '' + + if (isDev) { + localesPath = path.join(app.getAppPath(), 'src/renderer/src/locales') + } else { + // Adjust for production path + localesPath = path.join(process.resourcesPath, 'locales') + } + + if (fs.existsSync(localesPath)) { + const files = fs.readdirSync(localesPath) + files.forEach(file => { + if (file.endsWith('.json')) { + const lang = file.replace('.json', '') + const content = fs.readFileSync(path.join(localesPath, file), 'utf-8') + this.locales[lang] = JSON.parse(content) + } + }) + } + } catch (e) { + console.error('Failed to load main locales:', e) + } + } + + t(key: string, variables?: Record): string { + const lang = configService.getSettings().language || 'tr' + const parts = key.split('.') + let result = this.locales[lang] || this.locales['en'] || {} + + for (const part of parts) { + result = result?.[part] + if (!result) break + } + + if (typeof result !== 'string') return key + + if (variables) { + Object.entries(variables).forEach(([k, v]) => { + result = (result as string).replace(`{{${k}}}`, v) + }) + } + + return result + } +} + +export const i18nMain = new MainI18n() +export const t = (key: string, variables?: Record) => i18nMain.t(key, variables) diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 05c9797..2a5ecaf 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -463,8 +463,11 @@ function App(): JSX.Element { if (s === 'starting') { return } /> } + if (s === 'stopping') { + return } /> + } const color = s === 'running' ? 'success' : s === 'stopped' ? 'error' : 'warning' - return + return } const handleAddProject = async () => { diff --git a/src/renderer/src/locales/de.json b/src/renderer/src/locales/de.json index 7670261..55c32ed 100644 --- a/src/renderer/src/locales/de.json +++ b/src/renderer/src/locales/de.json @@ -24,6 +24,12 @@ "search": "Suchen", "loading": "Laden...", "starting": "Wird gestartet", + "running": "Läuft", + "stopped": "Gestoppt", + "stopping": "Wird gestoppt", + "ready": "Bereit.", + "waiting_process": "Warte auf Prozess...", + "executable_not_found": "Ausführbare Datei nicht gefunden", "are_you_sure": "Sind Sie sicher?", "yes_delete": "Ja, Löschen", "go_to_fix": "Zur Korrektur gehen", diff --git a/src/renderer/src/locales/en.json b/src/renderer/src/locales/en.json index 0a3952e..99329d3 100644 --- a/src/renderer/src/locales/en.json +++ b/src/renderer/src/locales/en.json @@ -24,6 +24,11 @@ "search": "Search", "loading": "Loading...", "starting": "Starting", + "running": "Running", + "stopped": "Stopped", + "ready": "Ready.", + "waiting_process": "Waiting for process...", + "executable_not_found": "Executable not found", "are_you_sure": "Are you sure?", "yes_delete": "Yes, delete!", "go_to_fix": "Go to Fix", @@ -44,7 +49,7 @@ "reset_btn": "Yes, Reset" }, "dashboard": { - "title": "Trunçgil Multi-PHP Server", + "title": "Dashboard", "status": "Server Status", "services": "Services", "active_version": "Active PHP Version", diff --git a/src/renderer/src/locales/tr.json b/src/renderer/src/locales/tr.json index d2c19d6..2704f5a 100644 --- a/src/renderer/src/locales/tr.json +++ b/src/renderer/src/locales/tr.json @@ -24,6 +24,12 @@ "search": "Ara", "loading": "Yükleniyor...", "starting": "Başlatılıyor", + "running": "Çalışıyor", + "stopped": "Durduruldu", + "stopping": "Durduruluyor", + "ready": "Hazır.", + "waiting_process": "İşlem bekleniyor...", + "executable_not_found": "Dosya bulunamadı", "are_you_sure": "Emin misiniz?", "yes_delete": "Evet, Sil", "go_to_fix": "Sorunu Düzeltmeye Git", @@ -43,7 +49,7 @@ "reset_btn": "Evet, Sıfırla" }, "dashboard": { - "title": "Trunçgil Multi-PHP Server", + "title": "Özet", "status": "Sunucu Durumu", "services": "Servisler", "active_version": "Aktif PHP Sürümü",