feat: implement core architecture and dashboard UI for service and project management

This commit is contained in:
Ümit Tunç
2026-03-28 09:58:49 +03:00
parent 4195cdfa8b
commit 164fabc174
7 changed files with 192 additions and 25 deletions
+53 -11
View File
@@ -1,4 +1,5 @@
import { ipcMain, app, dialog } from 'electron'
import fs from 'fs'
import { processManager } from '../services/ProcessManager'
import { configService } from '../services/ConfigService'
import { downloadService } from '../services/DownloadService'
@@ -7,37 +8,78 @@ import { phpManagerService } from '../services/PhpManagerService'
import { mySqlManagerService } from '../services/MySqlManagerService'
import path from 'path'
function findExecutable(dir: string, name: string): string | null {
if (!fs.existsSync(dir)) return null
const files = fs.readdirSync(dir)
for (const file of files) {
const fullPath = path.join(dir, file)
const stat = fs.statSync(fullPath)
if (stat.isDirectory()) {
const found = findExecutable(fullPath, name)
if (found) return found
} else if (file.toLowerCase() === name.toLowerCase()) {
return fullPath
}
}
return null
}
export function registerIpcHandlers(): void {
// Service management
ipcMain.handle('services:start', async (_event, serviceName: string) => {
try {
const settings = configService.getSettings()
const binDir = path.join(app.getPath('userData'), 'bin')
if (serviceName === 'nginx') {
const rootPath = path.join(app.getAppPath(), 'www')
const configPath = await configService.generateConfig('nginx.conf.template', 'nginx.conf', {
PORT: '80',
PORT: settings.nginxPort,
PHP_PORT: settings.phpPort,
ROOT: rootPath
})
const binPath = downloadService.getBinPath('nginx', 'nginx.exe')
const nginxDir = path.join(binDir, 'nginx')
const binPath = findExecutable(nginxDir, 'nginx.exe')
if (!binPath) return { success: false, message: 'Nginx executable bulunamadı. Lütfen indirin.' }
const success = await processManager.startService('nginx', binPath, ['-c', configPath])
return { success, message: success ? 'Nginx başlatıldı.' : 'Nginx başlatılamadı.' }
return { success, message: success ? 'Nginx başlatıldı.' : 'Nginx dosyaları bulunamadı veya port meşgul.' }
}
if (serviceName === 'php') {
const configPath = await configService.generateConfig('php.ini.template', 'php.ini', {})
const binPath = downloadService.getBinPath('php8.2', 'php-cgi.exe')
const success = await processManager.startService('php', binPath, ['-b', '127.0.0.1:9001', '-c', configPath])
return { success, message: success ? 'PHP başlatıldı.' : 'PHP başlatılamadı.' }
// Find any installed PHP version
const binPath = findExecutable(binDir, 'php-cgi.exe')
if (!binPath) return { success: false, message: 'PHP executable bulunamadı. Lütfen en az bir sürüm indirin.' }
const success = await processManager.startService('php', binPath, ['-b', `127.0.0.1:${settings.phpPort}`, '-c', configPath])
return { success, message: success ? 'PHP başlatıldı.' : 'PHP dosyaları bulunamadı veya port meşgul.' }
}
if (serviceName === 'mysql') {
const dataDir = path.join(app.getPath('userData'), 'mysql_data')
const binPath = findExecutable(binDir, 'mysqld.exe')
if (!binPath) return { success: false, message: 'MySQL executable bulunamadı. Lütfen indirin.' }
// Initialize if data directory is empty
if (!fs.existsSync(dataDir) || fs.readdirSync(dataDir).length === 0) {
if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir, { recursive: true })
console.log('Initializing MySQL data directory...')
await processManager.runOnce(binPath, ['--initialize-insecure', `--datadir=${dataDir.replace(/\\/g, '/')}`])
}
const configPath = await configService.generateConfig('my.ini.template', 'my.ini', {
PORT: settings.mysqlPort,
DATADIR: dataDir,
SOCKET: '/tmp/mysql.sock'
})
const binPath = downloadService.getBinPath('mysql', 'bin/mysqld.exe')
const success = await processManager.startService('mysql', binPath, ['--defaults-file=' + configPath])
return { success, message: success ? 'MySQL başlatıldı.' : 'MySQL başlatılamadı.' }
return { success, message: success ? 'MySQL başlatıldı.' : 'MySQL dosyaları bulunamadı veya port meşgul.' }
}
return { success: false, message: 'Bilinmeyen servis.' }
@@ -140,11 +182,11 @@ export function registerIpcHandlers(): void {
})
// Config management
ipcMain.handle('config:get', async (_event, key: string) => {
return null
ipcMain.handle('config:get', async () => {
return configService.getSettings()
})
ipcMain.handle('config:save', async (_event, config: any) => {
return { success: true }
return { success: true, settings: configService.updateSettings(config) }
})
}