feat: add Nginx configuration editor component and integrate it into the main application interface
This commit is contained in:
Generated
+28
@@ -15,12 +15,15 @@
|
|||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@mui/icons-material": "^6.0.0",
|
"@mui/icons-material": "^6.0.0",
|
||||||
"@mui/material": "^6.0.0",
|
"@mui/material": "^6.0.0",
|
||||||
|
"@types/prismjs": "^1.26.6",
|
||||||
"axios": "^1.14.0",
|
"axios": "^1.14.0",
|
||||||
"decompress": "^4.2.1",
|
"decompress": "^4.2.1",
|
||||||
"i18next": "^23.1.0",
|
"i18next": "^23.1.0",
|
||||||
|
"prismjs": "^1.30.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-i18next": "^13.0.0",
|
"react-i18next": "^13.0.0",
|
||||||
|
"react-simple-code-editor": "^0.14.1",
|
||||||
"sweetalert2": "^11.26.24"
|
"sweetalert2": "^11.26.24"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -2478,6 +2481,12 @@
|
|||||||
"xmlbuilder": ">=11.0.1"
|
"xmlbuilder": ">=11.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/prismjs": {
|
||||||
|
"version": "1.26.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.6.tgz",
|
||||||
|
"integrity": "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/prop-types": {
|
"node_modules/@types/prop-types": {
|
||||||
"version": "15.7.15",
|
"version": "15.7.15",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
|
||||||
@@ -7778,6 +7787,15 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prismjs": {
|
||||||
|
"version": "1.30.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
|
||||||
|
"integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/process-nextick-args": {
|
"node_modules/process-nextick-args": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
@@ -7949,6 +7967,16 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-simple-code-editor": {
|
||||||
|
"version": "0.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-simple-code-editor/-/react-simple-code-editor-0.14.1.tgz",
|
||||||
|
"integrity": "sha512-BR5DtNRy+AswWJECyA17qhUDvrrCZ6zXOCfkQY5zSmb96BVUbpVAv03WpcjcwtCwiLbIANx3gebHOcXYn1EHow==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0",
|
||||||
|
"react-dom": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-transition-group": {
|
"node_modules/react-transition-group": {
|
||||||
"version": "4.4.5",
|
"version": "4.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||||
|
|||||||
@@ -27,12 +27,15 @@
|
|||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@mui/icons-material": "^6.0.0",
|
"@mui/icons-material": "^6.0.0",
|
||||||
"@mui/material": "^6.0.0",
|
"@mui/material": "^6.0.0",
|
||||||
|
"@types/prismjs": "^1.26.6",
|
||||||
"axios": "^1.14.0",
|
"axios": "^1.14.0",
|
||||||
"decompress": "^4.2.1",
|
"decompress": "^4.2.1",
|
||||||
"i18next": "^23.1.0",
|
"i18next": "^23.1.0",
|
||||||
|
"prismjs": "^1.30.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-i18next": "^13.0.0",
|
"react-i18next": "^13.0.0",
|
||||||
|
"react-simple-code-editor": "^0.14.1",
|
||||||
"sweetalert2": "^11.26.24"
|
"sweetalert2": "^11.26.24"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ import {
|
|||||||
OpenInNew as OpenIcon,
|
OpenInNew as OpenIcon,
|
||||||
Edit as EditIcon,
|
Edit as EditIcon,
|
||||||
Folder as FolderIcon,
|
Folder as FolderIcon,
|
||||||
Storage as MySQLIcon,
|
|
||||||
Language as HostIcon,
|
Language as HostIcon,
|
||||||
Launch as LaunchIcon,
|
Launch as LaunchIcon,
|
||||||
Handyman as ToolsIcon,
|
Handyman as ToolsIcon,
|
||||||
@@ -73,6 +72,7 @@ import {
|
|||||||
import Swal from 'sweetalert2'
|
import Swal from 'sweetalert2'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import MySqlImportWizard from './components/MySqlImportWizard'
|
import MySqlImportWizard from './components/MySqlImportWizard'
|
||||||
|
import NginxCodeEditor from './components/NginxCodeEditor'
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
@@ -108,7 +108,6 @@ function App(): JSX.Element {
|
|||||||
const [phpVersions, setPhpVersions] = useState<any[]>([])
|
const [phpVersions, setPhpVersions] = useState<any[]>([])
|
||||||
const [mySqlVersions, setMySqlVersions] = useState<any[]>([])
|
const [mySqlVersions, setMySqlVersions] = useState<any[]>([])
|
||||||
const [nginxVersions, setNginxVersions] = useState<any[]>([])
|
const [nginxVersions, setNginxVersions] = useState<any[]>([])
|
||||||
const [loadingVersions, setLoadingVersions] = useState(false)
|
|
||||||
const [isProjectDialogOpen, setIsProjectDialogOpen] = useState(false)
|
const [isProjectDialogOpen, setIsProjectDialogOpen] = useState(false)
|
||||||
const slugify = (text: string) => text.toLowerCase().trim().replace(/[^\w\s-]/g, '').replace(/[\s_-]+/g, '-').replace(/^-+|-+$/g, '');
|
const slugify = (text: string) => text.toLowerCase().trim().replace(/[^\w\s-]/g, '').replace(/[\s_-]+/g, '-').replace(/^-+|-+$/g, '');
|
||||||
const [newProject, setNewProject] = useState<any>({ name: '', path: '', phpVersion: '', mySqlVersion: '', host: 'localhost' })
|
const [newProject, setNewProject] = useState<any>({ name: '', path: '', phpVersion: '', mySqlVersion: '', host: 'localhost' })
|
||||||
@@ -187,14 +186,6 @@ function App(): JSX.Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRefreshVersions = async () => {
|
|
||||||
setLoadingVersions(true)
|
|
||||||
try {
|
|
||||||
await Promise.all([fetchPhpVersions(), fetchMySqlVersions(), fetchNginxVersions()])
|
|
||||||
} finally {
|
|
||||||
setLoadingVersions(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isProjectDialogOpen && !newProject.id) {
|
if (isProjectDialogOpen && !newProject.id) {
|
||||||
@@ -671,7 +662,7 @@ function App(): JSX.Element {
|
|||||||
<Typography variant="body2" color="text.secondary">Gereken PHP sürümlerini buradan indirebilir ve yönetebilirsiniz.</Typography>
|
<Typography variant="body2" color="text.secondary">Gereken PHP sürümlerini buradan indirebilir ve yönetebilirsiniz.</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<List sx={{ maxHeight: 500, overflow: 'auto' }}>
|
<List sx={{ maxHeight: 500, overflow: 'auto' }}>
|
||||||
{phpVersions.length === 0 && !loadingVersions && (
|
{phpVersions.length === 0 && (
|
||||||
<ListItem><ListItemText primary="Yükleniyor veya liste boş..." /></ListItem>
|
<ListItem><ListItemText primary="Yükleniyor veya liste boş..." /></ListItem>
|
||||||
)}
|
)}
|
||||||
{phpVersions.map((v) => (
|
{phpVersions.map((v) => (
|
||||||
@@ -712,7 +703,7 @@ function App(): JSX.Element {
|
|||||||
<Typography variant="body2" color="text.secondary">Farklı MySQL sürümlerini indirebilir ve sunucunuzda kullanabilirsiniz.</Typography>
|
<Typography variant="body2" color="text.secondary">Farklı MySQL sürümlerini indirebilir ve sunucunuzda kullanabilirsiniz.</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<List sx={{ maxHeight: 500, overflow: 'auto' }}>
|
<List sx={{ maxHeight: 500, overflow: 'auto' }}>
|
||||||
{mySqlVersions.length === 0 && !loadingVersions && (
|
{mySqlVersions.length === 0 && (
|
||||||
<ListItem><ListItemText primary="Yükleniyor veya liste boş..." /></ListItem>
|
<ListItem><ListItemText primary="Yükleniyor veya liste boş..." /></ListItem>
|
||||||
)}
|
)}
|
||||||
{mySqlVersions.map((v) => (
|
{mySqlVersions.map((v) => (
|
||||||
@@ -1417,22 +1408,9 @@ function App(): JSX.Element {
|
|||||||
<Typography variant="caption" sx={{ color: 'rgba(255,255,255,0.4)', mb: 2, display: 'block' }}>
|
<Typography variant="caption" sx={{ color: 'rgba(255,255,255,0.4)', mb: 2, display: 'block' }}>
|
||||||
Dikkat: Hatalı yapılandırma Nginx'in çalışmasını durdurabilir. Değişiklik yapmadan önce test edin.
|
Dikkat: Hatalı yapılandırma Nginx'in çalışmasını durdurabilir. Değişiklik yapmadan önce test edin.
|
||||||
</Typography>
|
</Typography>
|
||||||
<TextField
|
<NginxCodeEditor
|
||||||
fullWidth
|
|
||||||
multiline
|
|
||||||
rows={20}
|
|
||||||
value={nginxConfig}
|
value={nginxConfig}
|
||||||
onChange={(e) => setNginxConfig(e.target.value)}
|
onChange={(val) => setNginxConfig(val)}
|
||||||
sx={{
|
|
||||||
'& .MuiInputBase-root': {
|
|
||||||
fontFamily: 'monospace',
|
|
||||||
fontSize: '0.875rem',
|
|
||||||
color: '#fff'
|
|
||||||
},
|
|
||||||
'& .MuiOutlinedInput-notchedOutline': {
|
|
||||||
borderColor: 'rgba(255,255,255,0.1)'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions sx={{ p: 2, gap: 1 }}>
|
<DialogActions sx={{ p: 2, gap: 1 }}>
|
||||||
@@ -1481,22 +1459,9 @@ function App(): JSX.Element {
|
|||||||
<Typography variant="caption" sx={{ color: 'rgba(255,255,255,0.4)', mb: 2, display: 'block' }}>
|
<Typography variant="caption" sx={{ color: 'rgba(255,255,255,0.4)', mb: 2, display: 'block' }}>
|
||||||
İpucu: Bu yapılandırma sadece {selectedProjectHost} projesi için geçerlidir.
|
İpucu: Bu yapılandırma sadece {selectedProjectHost} projesi için geçerlidir.
|
||||||
</Typography>
|
</Typography>
|
||||||
<TextField
|
<NginxCodeEditor
|
||||||
fullWidth
|
|
||||||
multiline
|
|
||||||
rows={20}
|
|
||||||
value={projectNginxConfig}
|
value={projectNginxConfig}
|
||||||
onChange={(e) => setProjectNginxConfig(e.target.value)}
|
onChange={(val) => setProjectNginxConfig(val)}
|
||||||
sx={{
|
|
||||||
'& .MuiInputBase-root': {
|
|
||||||
fontFamily: 'monospace',
|
|
||||||
fontSize: '0.875rem',
|
|
||||||
color: '#fff'
|
|
||||||
},
|
|
||||||
'& .MuiOutlinedInput-notchedOutline': {
|
|
||||||
borderColor: 'rgba(255,255,255,0.1)'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions sx={{ p: 2, gap: 1 }}>
|
<DialogActions sx={{ p: 2, gap: 1 }}>
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import Editor from 'react-simple-code-editor'
|
||||||
|
import Prism from 'prismjs'
|
||||||
|
import 'prismjs/components/prism-nginx'
|
||||||
|
import 'prismjs/themes/prism-tomorrow.css'
|
||||||
|
|
||||||
|
interface NginxCodeEditorProps {
|
||||||
|
value: string
|
||||||
|
onChange: (value: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const NginxCodeEditor: React.FC<NginxCodeEditorProps> = ({ value, onChange }) => {
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
borderRadius: '4px',
|
||||||
|
overflow: 'hidden',
|
||||||
|
border: '1px solid rgba(255,255,255,0.1)',
|
||||||
|
backgroundColor: '#1e1e1e',
|
||||||
|
fontFamily: '"Fira code", "Fira Mono", monospace',
|
||||||
|
fontSize: '14px',
|
||||||
|
minHeight: '300px'
|
||||||
|
}}>
|
||||||
|
<Editor
|
||||||
|
value={value}
|
||||||
|
onValueChange={code => onChange(code)}
|
||||||
|
highlight={code => Prism.highlight(code, Prism.languages.nginx, 'nginx')}
|
||||||
|
padding={15}
|
||||||
|
style={{
|
||||||
|
fontFamily: '"Fira code", "Fira Mono", monospace',
|
||||||
|
fontSize: 14,
|
||||||
|
minHeight: '400px',
|
||||||
|
outline: 'none'
|
||||||
|
}}
|
||||||
|
textareaClassName="nginx-editor-textarea"
|
||||||
|
preClassName="nginx-editor-pre"
|
||||||
|
/>
|
||||||
|
<style>{`
|
||||||
|
.nginx-editor-textarea {
|
||||||
|
outline: none !important;
|
||||||
|
}
|
||||||
|
.nginx-editor-pre {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.token.comment { color: #6a9955; }
|
||||||
|
.token.directive { color: #569cd6; font-weight: bold; }
|
||||||
|
.token.variable { color: #9cdcfe; }
|
||||||
|
.token.string { color: #ce9178; }
|
||||||
|
.token.number { color: #b5cea8; }
|
||||||
|
.token.boolean { color: #569cd6; }
|
||||||
|
.token.operator { color: #d4d4d4; }
|
||||||
|
.token.punctuation { color: #d4d4d4; }
|
||||||
|
`}</style>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NginxCodeEditor
|
||||||
Reference in New Issue
Block a user