diff --git a/service_events.json b/service_events.json index dc474f2..0fbd3c9 100644 --- a/service_events.json +++ b/service_events.json @@ -1,4 +1,296 @@ [ + { + "service": "apache", + "action": "start", + "status": "success", + "id": "lgv4wfd9z", + "timestamp": 1775140992722 + }, + { + "service": "apache", + "action": "exit", + "status": "failure", + "details": "Exit code: 1", + "id": "5dk3998of", + "timestamp": 1775140991358 + }, + { + "service": "nginx", + "action": "start", + "status": "success", + "id": "cbna1e6ai", + "timestamp": 1775140987786 + }, + { + "service": "nginx", + "action": "exit", + "status": "failure", + "details": "Exit code: 1", + "id": "tjf4mzo3m", + "timestamp": 1775140986436 + }, + { + "service": "php:8.5.4", + "action": "start", + "status": "success", + "id": "7ygjwfbhs", + "timestamp": 1775140953402 + }, + { + "service": "apache", + "action": "start", + "status": "success", + "id": "w02iyi0or", + "timestamp": 1775140952366 + }, + { + "service": "mariadb:10.11.8", + "action": "exit", + "status": "failure", + "details": "Exit code: 1", + "id": "0klrn76qy", + "timestamp": 1775140941299 + }, + { + "service": "mariadb:11.4.2", + "action": "exit", + "status": "failure", + "details": "Exit code: 1", + "id": "db5o443dt", + "timestamp": 1775140941292 + }, + { + "service": "php:8.5.4", + "action": "exit", + "status": "failure", + "details": "Exit code: null", + "id": "zfqnezt7g", + "timestamp": 1775140941010 + }, + { + "service": "php:8.5.4", + "action": "stop", + "status": "info", + "id": "70y5a19bj", + "timestamp": 1775140940997 + }, + { + "service": "apache", + "action": "exit", + "status": "failure", + "details": "Exit code: null", + "id": "xdkf6g1n3", + "timestamp": 1775140940604 + }, + { + "service": "apache", + "action": "stop", + "status": "info", + "id": "g2phz0x6z", + "timestamp": 1775140940596 + }, + { + "service": "mariadb:10.11.8", + "action": "start", + "status": "success", + "id": "k3qhdtk8j", + "timestamp": 1775140913371 + }, + { + "service": "mariadb:11.4.2", + "action": "start", + "status": "success", + "id": "pmz5hp51i", + "timestamp": 1775140913348 + }, + { + "service": "mariadb:10.11.8", + "action": "exit", + "status": "failure", + "details": "Exit code: 1", + "id": "d6h8pfi4x", + "timestamp": 1775140913325 + }, + { + "service": "apache", + "action": "start", + "status": "success", + "id": "61svs2nni", + "timestamp": 1775140913315 + }, + { + "service": "apache", + "action": "exit", + "status": "failure", + "details": "Exit code: 1", + "id": "sh8b2psvq", + "timestamp": 1775140913286 + }, + { + "service": "mariadb:11.4.2", + "action": "exit", + "status": "failure", + "details": "Exit code: 1", + "id": "xlewxzma7", + "timestamp": 1775140913265 + }, + { + "service": "mariadb:10.11.8", + "action": "start", + "status": "success", + "id": "fxljacg0r", + "timestamp": 1775140644165 + }, + { + "service": "mariadb:11.4.2", + "action": "start", + "status": "success", + "id": "2x2e657x6", + "timestamp": 1775140644143 + }, + { + "service": "mariadb:10.11.8", + "action": "exit", + "status": "failure", + "details": "Exit code: 1", + "id": "bofkspx9l", + "timestamp": 1775140644120 + }, + { + "service": "apache", + "action": "start", + "status": "success", + "id": "p19gbtez8", + "timestamp": 1775140644109 + }, + { + "service": "mariadb:11.4.2", + "action": "exit", + "status": "failure", + "details": "Exit code: 1", + "id": "tpwmg05yt", + "timestamp": 1775140644091 + }, + { + "service": "apache", + "action": "exit", + "status": "failure", + "details": "Exit code: 1", + "id": "rjr42oskg", + "timestamp": 1775140644044 + }, + { + "service": "php:5.6.40", + "action": "start", + "status": "success", + "id": "q5322glbz", + "timestamp": 1775140633948 + }, + { + "service": "php:7.4.33", + "action": "start", + "status": "success", + "id": "hbumn81gj", + "timestamp": 1775140633920 + }, + { + "service": "php:8.2.30", + "action": "start", + "status": "success", + "id": "jkel0o90s", + "timestamp": 1775140633897 + }, + { + "service": "php:8.5.4", + "action": "start", + "status": "success", + "id": "aan0ox1gd", + "timestamp": 1775140633876 + }, + { + "service": "mariadb:10.11.8", + "action": "start", + "status": "success", + "id": "3uk4uaxt4", + "timestamp": 1775140633650 + }, + { + "service": "mariadb:11.4.2", + "action": "start", + "status": "success", + "id": "rridkshjr", + "timestamp": 1775140633626 + }, + { + "service": "apache", + "action": "start", + "status": "success", + "id": "ckihmcjmc", + "timestamp": 1775140632885 + }, + { + "service": "nginx", + "action": "start", + "status": "success", + "id": "b2qv8h1o2", + "timestamp": 1775140632811 + }, + { + "service": "php:5.6.40", + "action": "start", + "status": "success", + "id": "zf5suzjqk", + "timestamp": 1775139676530 + }, + { + "service": "php:7.4.33", + "action": "start", + "status": "success", + "id": "ilid4cesf", + "timestamp": 1775139676510 + }, + { + "service": "php:8.2.30", + "action": "start", + "status": "success", + "id": "w42ipljsj", + "timestamp": 1775139676489 + }, + { + "service": "php:8.5.4", + "action": "start", + "status": "success", + "id": "0nji2mx0x", + "timestamp": 1775139676471 + }, + { + "service": "mariadb:11.4.2", + "action": "start", + "status": "success", + "id": "mi80ksddx", + "timestamp": 1775139676130 + }, + { + "service": "mariadb:10.11.8", + "action": "start", + "status": "success", + "id": "wy2jqt3or", + "timestamp": 1775139676106 + }, + { + "service": "apache", + "action": "start", + "status": "success", + "id": "18fd2tclr", + "timestamp": 1775139675486 + }, + { + "service": "nginx", + "action": "start", + "status": "success", + "id": "shmd1zuyl", + "timestamp": 1775139675417 + }, { "service": "php:5.6.40", "action": "start", diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 8cc8401..e190334 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -39,10 +39,9 @@ import { Tabs, Tab, InputAdornment, + Grid, CircularProgress, Stack, - Grid, - Avatar, Table, TableBody, TableCell, @@ -72,16 +71,11 @@ import { Close as CloseIcon, ContentCopy as ContentCopyIcon, OpenInNew as OpenIcon, - Edit as EditIcon, - Folder as FolderIcon, - Language as HostIcon, - Launch as LaunchIcon, - Handyman as ToolsIcon, Restore as ResetIcon, - Search as SearchIcon, Tune as TuningIcon, History as HistoryIcon, - MenuBook as GuideIcon + MenuBook as GuideIcon, + Handyman as ToolsIcon } from '@mui/icons-material' import Swal from 'sweetalert2' import { useTranslation } from 'react-i18next' @@ -95,6 +89,7 @@ import PhpExtensionManager from './components/PhpExtensionManager' import ServerTuning from './components/ServerTuning' import ServiceEventMonitor from './components/ServiceEventMonitor' import UserGuide from './components/UserGuide' +import ProjectManager from './components/ProjectManager/ProjectManager' declare global { interface Window { @@ -192,6 +187,8 @@ function App(): JSX.Element { const [selectedProjectHost, setSelectedProjectHost] = useState('') const [isPhpExtensionsOpen, setIsPhpExtensionsOpen] = useState(false) const [selectedPhpVersion, setSelectedPhpVersion] = useState('') + const [selectedProjectId, setSelectedProjectId] = useState(null) + const [projectDetailTab, setProjectDetailTab] = useState(0) const parseNginxError = (message: string) => { const match = message.match(/in (.*):(\d+)/) @@ -606,70 +603,15 @@ function App(): JSX.Element { ); }; - const ProjectResourceMonitor = ({ serverStats, phpStats, serverType }: { serverStats?: ServiceInfo; phpStats?: ServiceInfo; serverType: string }) => { - const hasServerStat = serverStats?.cpu !== undefined || serverStats?.memory !== undefined; - const hasPhpStat = phpStats?.cpu !== undefined || phpStats?.memory !== undefined; - - if (!hasServerStat && !hasPhpStat) return null; - - const renderMiniStats = (stats?: ServiceInfo, label: string = 'Service') => { - if (!stats) return null; - const cpu = stats.cpu || 0; - const memory = stats.memory || 0; - const ramMB = Math.round(memory / (1024 * 1024)); - const ramPercent = Math.min((ramMB / 1024) * 100, 100); - - return ( - - - {label.toUpperCase()} - - {cpu}% - {formatMemory(memory)} - - - - - - - - ); - }; - - return ( - - {renderMiniStats(serverStats, serverType)} - {renderMiniStats(phpStats, 'PHP')} - - ); - }; const handleAddProject = async () => { if (!window.api) return + let result; if (newProject.id) { - await window.api.updateProject(newProject) + result = await window.api.updateProject(newProject) } else { - await window.api.addProject(newProject) + result = await window.api.addProject(newProject) + if (result && result.id) setSelectedProjectId(result.id) } setIsProjectDialogOpen(false) setNewProject({ name: '', path: '', phpVersion: '', mariaDbVersion: '', host: 'localhost' }) @@ -694,6 +636,7 @@ function App(): JSX.Element { if (result.isConfirmed) { await window.api.removeProject(id) + if (selectedProjectId === id) setSelectedProjectId(null) setNotification({ open: true, message: t('projects.deleted'), severity: 'success' }) fetchProjects() } @@ -2008,192 +1951,50 @@ function App(): JSX.Element { )} - {activeTab === 'projects' && ( - - - - {t('projects.title')} - - setProjectSearch(e.target.value)} - sx={{ - minWidth: { sm: 300 }, - bgcolor: 'rgba(255, 255, 255, 0.03)', - borderRadius: 1, - '& .MuiOutlinedInput-root': { - color: '#fff', - '& fieldset': { borderColor: 'rgba(255, 255, 255, 0.1)' }, - '&:hover fieldset': { borderColor: 'rgba(255, 255, 255, 0.2)' }, - } - }} - InputProps={{ - startAdornment: ( - - - - ), - endAdornment: projectSearch && ( - - setProjectSearch('')} sx={{ color: 'rgba(255, 255, 255, 0.3)' }}> - - - - ) - }} - /> - - - - {projects.length === 0 ? ( - - {t('projects.empty')} - - ) : (() => { - const filteredProjects = projects.filter(p => - p.name.toLowerCase().includes(projectSearch.toLowerCase()) || - p.host.toLowerCase().includes(projectSearch.toLowerCase()) + { + setNewProject({ name: '', path: '', phpVersion: '', mariaDbVersion: '', host: 'localhost', serverType: 'nginx' }) + setIsProjectDialogOpen(true) + }} + onEditProject={(p) => { + setNewProject(p) + setIsProjectDialogOpen(true) + }} + onRemoveProject={handleRemoveProject} + onToggleStatus={async (p: any) => { + const isRunning = ( + (p.serverType === 'apache' ? status.apache?.status : status.nginx?.status) === 'running' && + status[`php:${p.phpVersion}`]?.status === 'running' ); - - if (filteredProjects.length === 0) { - return ( - - - - {t('common.not_found', 'Eşleşen proje bulunamadı')} - - - ); + if (isRunning) { + await window.api.stopService(p.serverType === 'apache' ? 'apache' : 'nginx'); + await window.api.stopService(`php:${p.phpVersion}`); + } else { + await window.api.startService(p.serverType === 'apache' ? 'apache' : 'nginx'); + await window.api.startService(`php:${p.phpVersion}`); } - - return ( - - {filteredProjects.map((project) => ( - - - - - - - - - - {project.name} - - - {project.path.length > 40 ? '...' + project.path.slice(-37) : project.path} - - - - - - { - setNewProject(project) - setIsProjectDialogOpen(true) - }} sx={{ color: 'rgba(255,255,255,0.4)', '&:hover': { color: '#39A7FF' } }}> - - - - {project.serverType !== 'apache' && ( - - handleOpenProjectNginxConfig(project.host)} sx={{ color: 'rgba(255,255,255,0.4)', '&:hover': { color: '#39A7FF' } }}> - - - - )} - - handleRemoveProject(project.id)} sx={{ color: 'rgba(255,255,255,0.4)', '&:hover': { color: '#ff4444' } }}> - - - - - - - - - } - label={`PHP ${project.phpVersion}`} - sx={{ bgcolor: 'rgba(71, 74, 255, 0.1)', color: '#777bb4', fontWeight: 600, border: '1px solid rgba(71, 74, 255, 0.2)' }} - /> - : } - label={project.serverType === 'apache' ? 'Apache' : 'Nginx'} - sx={{ bgcolor: 'rgba(255, 255, 255, 0.05)', color: '#fff', fontWeight: 600 }} - /> - - - - - - - - - {project.host} - - - - - - - - ))} - - ) - })()} - + fetchStatus(); + }} + onOpenSite={(p: any) => { + const port = p.serverType === 'apache' ? settings.apachePort : settings.nginxPort + window.open(`http://localhost:${port}/${p.host}/`, '_blank') + }} + onOpenFolder={(path: string) => window.api.invoke('open-path', path)} + onManageDb={() => setActiveTab('db_manager')} + /> )} + diff --git a/src/renderer/src/components/ProjectManager/ProjectDetails.tsx b/src/renderer/src/components/ProjectManager/ProjectDetails.tsx new file mode 100644 index 0000000..b66e758 --- /dev/null +++ b/src/renderer/src/components/ProjectManager/ProjectDetails.tsx @@ -0,0 +1,216 @@ +import { + Box, + Typography, + Avatar, + IconButton, + Button, + Tabs, + Tab, + Grid, + Chip, + Divider, + Stack, + Tooltip +} from '@mui/material' +import { + Folder as ProjectIcon, + FolderOpen as FolderOpenIcon, + Stop as StopIcon, + PlayArrow as StartIcon, + Launch as LaunchIcon, + Edit as EditIcon, + Delete as DeleteIcon, + Tune as TuningIcon, + OpenInNew as OpenIcon +} from '@mui/icons-material' +import ProjectResourceMonitor from './ProjectResourceMonitor' + +interface ProjectDetailsProps { + project: any; + status: any; + settings: any; + projectDetailTab: number; + setProjectDetailTab: (v: number) => void; + t: any; + onEdit: () => void; + onDelete: () => void; + onToggleStatus: () => void; + onOpenSite: () => void; + onOpenFolder: () => void; + onManageDb: () => void; +} + +export default function ProjectDetails({ + project: p, + status, + settings, + projectDetailTab, + setProjectDetailTab, + t, + onEdit, + onDelete, + onToggleStatus, + onOpenSite, + onOpenFolder, + onManageDb +}: ProjectDetailsProps) { + if (!p) { + return ( + + + {t('projects.no_project_selected')} + + ); + } + + const isRunning = ( + (p.serverType === 'apache' ? status.apache?.status : status.nginx?.status) === 'running' && + status[`php:${p.phpVersion}`]?.status === 'running' + ); + + return ( + + + + + + + + {p.name} + + + {p.path} + + + + + + + + + + + + + + + + + + + + + + + + + setProjectDetailTab(v)} textColor="primary" indicatorColor="primary"> + + + + + + + {projectDetailTab === 0 && ( + + + + {t('projects.site_domain')} + + {p.host}.local + + + + + + {t('projects.web_server')} + + {p.serverType.toUpperCase()} + + + + + + {t('projects.php_version')} + + {p.phpVersion} + + + + + + + + + {t('dashboard.status')} + + + + + + )} + + {projectDetailTab === 1 && ( + + + + + {t('projects.mariadb_version')} + MariaDB {p.mariadbVersion} + + + + + + + + + Host + localhost + + + Port + {settings.mariaDbPort} + + + Username + root + + + Password + (no password) + + + + + )} + + + ); +} diff --git a/src/renderer/src/components/ProjectManager/ProjectManager.tsx b/src/renderer/src/components/ProjectManager/ProjectManager.tsx new file mode 100644 index 0000000..b36e972 --- /dev/null +++ b/src/renderer/src/components/ProjectManager/ProjectManager.tsx @@ -0,0 +1,83 @@ +import { Box } from '@mui/material' +import ProjectSidebar from './ProjectSidebar' +import ProjectDetails from './ProjectDetails' + +interface ProjectManagerProps { + projects: any[]; + status: any; + settings: any; + projectSearch: string; + setProjectSearch: (v: string) => void; + selectedProjectId: string | null; + setSelectedProjectId: (v: string | null) => void; + projectDetailTab: number; + setProjectDetailTab: (v: number) => void; + t: any; + onAddProject: () => void; + onEditProject: (p: any) => void; + onRemoveProject: (id: string) => void; + onToggleStatus: (p: any) => void; + onOpenSite: (p: any) => void; + onOpenFolder: (path: string) => void; + onManageDb: () => void; +} + +export default function ProjectManager({ + projects, + status, + settings, + projectSearch, + setProjectSearch, + selectedProjectId, + setSelectedProjectId, + projectDetailTab, + setProjectDetailTab, + t, + onAddProject, + onEditProject, + onRemoveProject, + onToggleStatus, + onOpenSite, + onOpenFolder, + onManageDb +}: ProjectManagerProps) { + + // Defensive check: find selected project + const p = projects.find(proj => proj && proj.id === selectedProjectId); + + return ( + + + + onEditProject(p)} + onDelete={() => onRemoveProject(p.id)} + onToggleStatus={() => onToggleStatus(p)} + onOpenSite={() => onOpenSite(p)} + onOpenFolder={() => onOpenFolder(p.path)} + onManageDb={onManageDb} + /> + + ); +} diff --git a/src/renderer/src/components/ProjectManager/ProjectResourceMonitor.tsx b/src/renderer/src/components/ProjectManager/ProjectResourceMonitor.tsx new file mode 100644 index 0000000..f98ea8b --- /dev/null +++ b/src/renderer/src/components/ProjectManager/ProjectResourceMonitor.tsx @@ -0,0 +1,78 @@ +import { Box, Typography, LinearProgress } from '@mui/material' + +interface ServiceInfo { + status: string; + cpu?: number; + memory?: number; +} + +interface ProjectResourceMonitorProps { + serverStats?: ServiceInfo; + phpStats?: ServiceInfo; + serverType: string; +} + +const formatMemory = (bytes?: number) => { + if (!bytes) return '' + const mb = bytes / (1024 * 1024) + if (mb > 1024) return `${(mb / 1024).toFixed(1)} GB` + return `${Math.round(mb)} MB` +} + +export default function ProjectResourceMonitor({ serverStats, phpStats, serverType }: ProjectResourceMonitorProps) { + const hasServerStat = serverStats?.cpu !== undefined || serverStats?.memory !== undefined; + const hasPhpStat = phpStats?.cpu !== undefined || phpStats?.memory !== undefined; + + if (!hasServerStat && !hasPhpStat) return null; + + const renderMiniStats = (stats?: ServiceInfo, label: string = 'Service') => { + if (!stats) return null; + const cpu = stats.cpu || 0; + const memory = stats.memory || 0; + const ramMB = Math.round(memory / (1024 * 1024)); + const ramPercent = Math.min((ramMB / 1024) * 100, 100); + + return ( + + + {label.toUpperCase()} + + {cpu}% + {formatMemory(memory)} + + + + + + + + ); + }; + + return ( + + {renderMiniStats(serverStats, serverType)} + {renderMiniStats(phpStats, 'PHP')} + + ); +} diff --git a/src/renderer/src/components/ProjectManager/ProjectSidebar.tsx b/src/renderer/src/components/ProjectManager/ProjectSidebar.tsx new file mode 100644 index 0000000..5b3b23b --- /dev/null +++ b/src/renderer/src/components/ProjectManager/ProjectSidebar.tsx @@ -0,0 +1,156 @@ +import { + Box, + Typography, + TextField, + InputAdornment, + IconButton, + Tooltip, + List, + ListItemButton +} from '@mui/material' +import { + Search as SearchIcon, + Folder as ProjectIcon +} from '@mui/icons-material' + +interface ProjectSidebarProps { + projects: any[]; + projectSearch: string; + setProjectSearch: (v: string) => void; + selectedProjectId: string | null; + setSelectedProjectId: (v: string | null) => void; + status: any; + t: any; + onAddProject: () => void; +} + +export default function ProjectSidebar({ + projects, + projectSearch, + setProjectSearch, + selectedProjectId, + setSelectedProjectId, + status, + t, + onAddProject +}: ProjectSidebarProps) { + + const filtered = projects.filter(p => { + if (!p) return false; + const nameMatch = p.name?.toLowerCase().includes(projectSearch.toLowerCase()) ?? false; + const hostMatch = p.host?.toLowerCase().includes(projectSearch.toLowerCase()) ?? false; + return nameMatch || hostMatch; + }); + + // Grouping + const grouped = filtered.reduce((acc: any, p) => { + const v = p.phpVersion ? `PHP ${p.phpVersion}` : 'Unknown PHP'; + if (!acc[v]) acc[v] = []; + acc[v].push(p); + return acc; + }, {}); + + return ( + + + + + {t('projects.title')} + + + + + + + + setProjectSearch(e.target.value)} + InputProps={{ + startAdornment: ( + + + + ), + sx: { fontSize: '0.85rem', bgcolor: 'rgba(0,0,0,0.2)' } + }} + /> + + + + {filtered.length === 0 ? ( + + {t('projects.empty')} + + ) : ( + Object.entries(grouped).sort().map(([version, projs]: [string, any]) => ( + + + {version} + + + {projs.map((p: any) => { + const isRunning = ( + (p.serverType === 'apache' ? status.apache?.status : status.nginx?.status) === 'running' && + status[`php:${p.phpVersion}`]?.status === 'running' + ); + const serverStats = p.serverType === 'apache' ? status.apache : status.nginx; + const phpStats = status[`php:${p.phpVersion}`]; + + return ( + setSelectedProjectId(p.id)} + sx={{ + borderRadius: 2, + mb: 0.5, + border: selectedProjectId === p.id ? '1px solid rgba(57, 167, 255, 0.3)' : '1px solid transparent', + '&.Mui-selected': { bgcolor: 'rgba(57, 167, 255, 0.08)' } + }} + > + + + + + {p.name} + + + + + {(p.serverType || '').toUpperCase()} • {p.host} + + {isRunning && ( + + {Math.round((serverStats?.cpu || 0) + (phpStats?.cpu || 0))}% CPU + + )} + + + + ); + })} + + + )) + )} + + + ); +} diff --git a/src/renderer/src/locales/de.json b/src/renderer/src/locales/de.json index 989861f..49348a1 100644 --- a/src/renderer/src/locales/de.json +++ b/src/renderer/src/locales/de.json @@ -76,7 +76,16 @@ "added": "Projekt erfolgreich hinzugefügt.", "updated": "Projekt erfolgreich aktualisiert.", "deleted": "Projekt wurde gelöscht.", - "delete_confirm": "Sind Sie sicher, dass Sie dieses Projekt löschen möchten? Ihre Dateien werden nicht gelöscht, nur aus der Liste entfernt." + "delete_confirm": "Sind Sie sicher, dass Sie dieses Projekt löschen möchten? Ihre Dateien werden nicht gelöscht, nur aus der Liste entfernt.", + "overview": "Übersicht", + "database": "Datenbank", + "site_domain": "Site-Domain", + "web_server": "Webserver", + "site_path": "Site-Pfad", + "open_site": "SITE ÖFFNEN", + "stop_site": "SITE STOPPEN", + "start_site": "SITE STARTEN", + "no_project_selected": "Bitte wählen Sie ein Projekt aus der Liste aus oder erstellen Sie ein neues." }, "settings": { "general": "Allgemeine Einstellungen", diff --git a/src/renderer/src/locales/en.json b/src/renderer/src/locales/en.json index 132d710..a495dd2 100644 --- a/src/renderer/src/locales/en.json +++ b/src/renderer/src/locales/en.json @@ -82,7 +82,16 @@ "added": "Project added successfully.", "updated": "Project updated successfully.", "deleted": "Project deleted.", - "delete_confirm": "Are you sure you want to delete this project? Your files will not be deleted, only removed from the list." + "delete_confirm": "Are you sure you want to delete this project? Your files will not be deleted, only removed from the list.", + "overview": "Overview", + "database": "Database", + "site_domain": "Site Domain", + "web_server": "Web Server", + "site_path": "Site Path", + "open_site": "OPEN SITE", + "stop_site": "STOP SITE", + "start_site": "START SITE", + "no_project_selected": "Please select a project from the list or create a new one." }, "settings": { "general": "General Settings", diff --git a/src/renderer/src/locales/tr.json b/src/renderer/src/locales/tr.json index 7eae219..3a4536b 100644 --- a/src/renderer/src/locales/tr.json +++ b/src/renderer/src/locales/tr.json @@ -83,11 +83,19 @@ "updated": "Proje başarıyla güncellendi.", "deleted": "Proje silindi.", "delete_confirm": "Bu projeyi silmek istediğinize emin misiniz? Dosyalarınız silinmez, sadece listeden kaldırılır.", - "browse": "Gözat" + "browse": "Gözat", + "overview": "Genel Bakış", + "database": "Veritabanı", + "site_domain": "Site Adresi", + "web_server": "Web Sunucusu", + "site_path": "Dosya Yolu", + "open_site": "SİTEYİ AÇ", + "stop_site": "SİTEYİ DURDUR", + "start_site": "SİTEYİ BAŞLAT", + "no_project_selected": "Lütfen listeden bir proje seçin veya yeni bir tane oluşturun." }, "settings": { "general": "Genel Ayarlar", - "server_settings": "Sunucu Ayarları", "saved": "Ayarlar kaydedildi.", "save_failed": "Ayarlar kaydedilemedi.", "language": "Dil",