feat: implement MariaDB import/export wizards and dashboard UI components

This commit is contained in:
Ümit Tunç
2026-04-03 16:07:31 +03:00
parent 0802e6cb9d
commit be1901afbf
5 changed files with 60 additions and 60 deletions
@@ -257,7 +257,7 @@ export default function DashboardDetails({
<Typography variant="caption" className="text-secondary font-semibold" sx={{ letterSpacing: 0.5 }}>İşlemci Kullanımı</Typography>
<Typography variant="caption" color="primary.main" className="font-black">{cpu || 0}%</Typography>
</Box>
<LinearProgress variant="determinate" value={cpu || 0} sx={{ height: 6, borderRadius: 'var(--border-radius-full)', bgcolor: 'rgba(255,255,255,0.05)', '.MuiLinearProgress-bar': { borderRadius: 'var(--border-radius-full)', background: 'linear-gradient(90deg, var(--color-primary), var(--color-secondary))' } }} />
<LinearProgress variant="determinate" value={cpu || 0} sx={{ height: 6, borderRadius: 'var(--radius-xl)', bgcolor: 'var(--color-bg-soft)', '.MuiLinearProgress-bar': { borderRadius: 'var(--radius-xl)', background: 'linear-gradient(90deg, var(--color-primary), var(--color-secondary))' } }} />
</Box>
<Box>
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 0.5 }}>
@@ -266,7 +266,7 @@ export default function DashboardDetails({
{memory ? `${Math.round(memory / (1024 * 1024))} MB` : '0 MB'}
</Typography>
</Box>
<LinearProgress variant="determinate" value={Math.min(((memory || 0) / (1024 * 1024) / 1024) * 100, 100)} sx={{ height: 6, borderRadius: 'var(--border-radius-full)', bgcolor: 'rgba(255,255,255,0.05)', '.MuiLinearProgress-bar': { borderRadius: 'var(--border-radius-full)', background: 'linear-gradient(90deg, var(--color-secondary), #E91E63)' } }} />
<LinearProgress variant="determinate" value={Math.min(((memory || 0) / (1024 * 1024) / 1024) * 100, 100)} sx={{ height: 6, borderRadius: 'var(--radius-xl)', bgcolor: 'var(--color-bg-soft)', '.MuiLinearProgress-bar': { borderRadius: 'var(--radius-xl)', background: 'linear-gradient(90deg, var(--color-secondary), var(--color-error))' } }} />
</Box>
</Box>
);
@@ -274,8 +274,8 @@ export default function DashboardDetails({
const isPhp = serviceType === 'php';
return (
<Box sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden', bgcolor: 'background.default' }}>
<Box sx={{ p: 4, borderBottom: '1px solid rgba(255,255,255,0.05)', display: 'flex', alignItems: 'center', gap: 3 }}>
<Box sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden', bgcolor: 'var(--color-bg-dark)' }}>
<Box sx={{ p: 4, borderBottom: '1px solid var(--color-border-soft)', display: 'flex', alignItems: 'center', gap: 3 }}>
<Paper sx={{ p: 2, bgcolor: 'var(--color-bg-sidebar)', borderColor: 'var(--color-border-soft)' }} className="rounded-xl">
{serviceType === 'nginx' && <WebIcon color="primary" sx={{ fontSize: 'var(--font-size-4xl)' }} />}
{serviceType === 'apache' && <ServerIcon color="primary" sx={{ fontSize: 'var(--font-size-4xl)' }} />}
@@ -317,7 +317,7 @@ export default function DashboardDetails({
</Stack>
</Box>
<Box sx={{ borderBottom: 1, borderColor: 'rgba(255,255,255,0.05)', px: 4, bgcolor: 'rgba(255,255,255,0.01)' }}>
<Box sx={{ borderBottom: 1, borderColor: 'var(--color-border-soft)', px: 4, bgcolor: 'var(--color-bg-soft)' }}>
<Tabs value={activeTab} onChange={(_e, v) => setActiveTab(v)} textColor="primary" indicatorColor="primary" sx={{
'.MuiTab-root': { textTransform: 'none', minHeight: 48 }
}} className="font-bold text-sm">
@@ -339,7 +339,7 @@ export default function DashboardDetails({
<Typography variant="body2" className="font-black text-sm" sx={{ mb: 1.5, color: 'primary.main', display: 'flex', alignItems: 'center', gap: 1 }}>
<StatusIcon sx={{ fontSize: 'var(--font-size-base)' }} /> {t('dashboard.system_stats', 'Sistem İstatistikleri')}
</Typography>
<Paper sx={{ p: 2, bgcolor: 'rgba(255,255,255,0.02)', borderRadius: 3, border: '1px solid rgba(255,255,255,0.05)' }}>
<Paper sx={{ p: 2, bgcolor: 'var(--color-bg-soft)', borderRadius: 'var(--radius-lg)', border: '1px solid var(--color-border-soft)' }}>
<ResourceMonitor cpu={currentStatus.cpu} memory={currentStatus.memory} />
</Paper>
</Grid>
@@ -391,7 +391,7 @@ export default function DashboardDetails({
</Button>
</Box>
<Paper sx={{ flexGrow: 1, bgcolor: '#1a1a1a', borderRadius: 4, border: '1px solid rgba(255,255,255,0.05)', overflow: 'hidden', display: 'flex', flexDirection: 'column', minHeight: '60vh' }}>
<Paper sx={{ flexGrow: 1, bgcolor: 'black', borderRadius: 'var(--radius-lg)', border: '1px solid var(--color-border-soft)', overflow: 'hidden', display: 'flex', flexDirection: 'column', minHeight: '60vh' }}>
{isLoadingConfig ? (
<Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', flexGrow: 1 }}><CircularProgress /></Box>
) : (
@@ -426,7 +426,7 @@ export default function DashboardDetails({
{t('common.save').toUpperCase()}
</Button>
</Box>
<Paper sx={{ flexGrow: 1, bgcolor: '#1a1a1a', borderRadius: 4, border: '1px solid rgba(255,255,255,0.05)', overflow: 'hidden', display: 'flex', flexDirection: 'column', minHeight: '60vh' }}>
<Paper sx={{ flexGrow: 1, bgcolor: 'black', borderRadius: 'var(--radius-lg)', border: '1px solid var(--color-border-soft)', overflow: 'hidden', display: 'flex', flexDirection: 'column', minHeight: '60vh' }}>
{isLoadingConfig ? (
<Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', flexGrow: 1 }}><CircularProgress /></Box>
) : (
@@ -446,10 +446,10 @@ export default function DashboardDetails({
)}
{activeTab === 'logs' && (
<Box sx={{ bgcolor: '#0b0e11', borderRadius: 4, p: 3, height: '65vh', overflowY: 'auto', border: '1px solid rgba(255,255,255,0.05)', boxShadow: 'inset 0 0 20px rgba(0,0,0,0.5)' }}>
<Box sx={{ mb: 2, display: 'flex', alignItems: 'center', gap: 1.5, color: 'rgba(255,255,255,0.3)' }}>
<Box sx={{ bgcolor: 'var(--color-bg-medium)', borderRadius: 'var(--radius-lg)', p: 3, height: '65vh', overflowY: 'auto', border: '1px solid var(--color-border-soft)', boxShadow: 'inset 0 0 20px rgba(0,0,0,0.5)' }}>
<Box sx={{ mb: 2, display: 'flex', alignItems: 'center', gap: 1.5, color: 'var(--color-text-muted)' }}>
<LogIcon fontSize="small" />
<Typography variant="caption" sx={{ fontWeight: 700, letterSpacing: 1 }}>Gerçek Zamanlı Servis Logları</Typography>
<Typography variant="caption" className="font-bold" sx={{ letterSpacing: 1 }}>Gerçek Zamanlı Servis Logları</Typography>
</Box>
{logs.length === 0 ? (
<Box sx={{ height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', opacity: 0.2 }}>
@@ -459,8 +459,8 @@ export default function DashboardDetails({
logs.map((log, i) => (
<Typography key={i} sx={{
fontFamily: '"Fira Code", monospace',
fontSize: '0.85rem',
color: log.toLowerCase().includes('error') ? '#ff5252' : (log.toLowerCase().includes('warn') ? '#ffb142' : '#33d9b2'),
fontSize: 'var(--font-size-xs)',
color: log.toLowerCase().includes('error') ? 'var(--color-error)' : (log.toLowerCase().includes('warn') ? 'var(--color-warning)' : 'var(--color-success)'),
mb: 0.8,
lineHeight: 1.5,
opacity: 0.9
@@ -50,8 +50,8 @@ export default function DashboardSidebar({
onClick={() => setSelectedServiceId(id)}
sx={{
mb: 0.5,
border: selectedServiceId === id ? '1px solid rgba(57, 167, 255, 0.3)' : '1px solid transparent',
'&.Mui-selected': { bgcolor: 'rgba(57, 167, 255, 0.08)' }
border: selectedServiceId === id ? '1px solid var(--color-primary-soft)' : '1px solid transparent',
'&.Mui-selected': { bgcolor: 'var(--color-primary-soft)' }
}}
className="rounded-md"
>
@@ -71,8 +71,8 @@ export default function DashboardSidebar({
width: 10,
height: 10,
borderRadius: '50%',
bgcolor: isStarting ? 'warning.main' : (isRunning ? 'success.main' : 'error.main'),
boxShadow: isRunning ? '0 0 8px rgba(76, 175, 80, 0.5)' : (isStarting ? '0 0 8px rgba(255, 177, 66, 0.5)' : 'none'),
bgcolor: isStarting ? 'var(--color-warning)' : (isRunning ? 'var(--color-success)' : 'var(--color-error)'),
boxShadow: isRunning ? '0 0 8px var(--color-success-soft)' : (isStarting ? '0 0 8px var(--color-warning-soft)' : 'none'),
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
@@ -108,7 +108,7 @@ export default function DashboardSidebar({
</Box>
<Box sx={{ p: 1.5 }}>
<Typography variant="caption" className="font-semibold" sx={{ px: 1, color: 'primary.main', mb: 1, display: 'block', opacity: 0.8 }}>
<Typography variant="caption" className="font-semibold text-primary" sx={{ px: 1, mb: 1, display: 'block', opacity: 0.8 }}>
Web Sunucuları
</Typography>
<List dense disablePadding sx={{ mb: 3 }}>
@@ -116,7 +116,7 @@ export default function DashboardSidebar({
<ServiceItem id="apache" label="Apache" icon={ServerIcon} serviceKey="apache" />
</List>
<Typography variant="caption" sx={{ px: 1, color: 'primary.main', fontWeight: 600, mb: 1, display: 'block', opacity: 0.8 }}>
<Typography variant="caption" className="font-semibold text-primary" sx={{ px: 1, mb: 1, display: 'block', opacity: 0.8 }}>
PHP Sürümleri
</Typography>
<List dense disablePadding sx={{ mb: 3 }}>
@@ -131,7 +131,7 @@ export default function DashboardSidebar({
))}
</List>
<Typography variant="caption" sx={{ px: 1, color: 'primary.main', fontWeight: 600, mb: 1, display: 'block', opacity: 0.8 }}>
<Typography variant="caption" className="font-semibold text-primary" sx={{ px: 1, mb: 1, display: 'block', opacity: 0.8 }}>
Veritabanı Sürümleri
</Typography>
<List dense disablePadding>
@@ -220,19 +220,19 @@ const MariaDbExportWizard: React.FC<MariaDbExportWizardProps> = ({ open, onClose
{!exportResult ? (
<>
<Paper sx={{ p: 2, bgcolor: 'var(--color-bg-soft)', border: '1px solid var(--color-border-soft)' }} className="rounded-md">
<Typography variant="subtitle2" color="primary" className="font-bold">{t('mariadb.import.summary')}</Typography>
<Typography variant="subtitle2" sx={{ color: 'var(--color-primary)' }} className="font-bold text-md">{t('mariadb.import.summary')}</Typography>
<Divider sx={{ my: 1, opacity: 0.05 }} />
<Stack spacing={1}>
<Typography variant="body2"><strong>{t('mariadb.import.server')}:</strong> {selectedVersion}</Typography>
<Typography variant="body2"><strong>{t('mariadb.import.db')}:</strong> {selectedDb}</Typography>
<Typography variant="body2"><strong>{t('mariadb.export.target')}:</strong> {savePath}</Typography>
<Typography variant="body2"><strong>{t('mariadb.export.compression')}:</strong> {compress ? t('mariadb.export.on') : t('mariadb.export.off')}</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.import.server')}:</strong> {selectedVersion}</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.import.db')}:</strong> {selectedDb}</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.export.target')}:</strong> {savePath}</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.export.compression')}:</strong> {compress ? t('mariadb.export.on') : t('mariadb.export.off')}</Typography>
</Stack>
</Paper>
{loading && (
<Box sx={{ mt: 3, p: 2, bgcolor: 'var(--color-bg-medium)', maxHeight: '200px', overflowY: 'auto', fontFamily: 'monospace' }} className="rounded-md border-soft">
{logs.map((log, i) => (
<Typography key={i} variant="caption" sx={{ display: 'block', color: log.includes('error') ? 'error.main' : 'success.main' }}>
<Typography key={i} variant="caption" sx={{ display: 'block', color: log.includes('error') ? 'var(--color-error)' : 'var(--color-success)' }} className="text-xs">
{log}
</Typography>
))}
@@ -244,9 +244,9 @@ const MariaDbExportWizard: React.FC<MariaDbExportWizardProps> = ({ open, onClose
<Box sx={{ textAlign: 'center', py: 3 }}>
{exportResult.success ? (
<>
<SuccessIcon color="success" sx={{ fontSize: 60 }} />
<Typography variant="h6" sx={{ mt: 2 }}>{t('mariadb.import.success_title')}</Typography>
<Typography variant="body2" color="text.secondary">{exportResult.message}</Typography>
<SuccessIcon sx={{ color: 'var(--color-success)', fontSize: 'var(--font-size-4xl)' }} />
<Typography variant="h6" className="font-black text-xl" sx={{ mt: 2 }}>{t('mariadb.import.success_title')}</Typography>
<Typography variant="body2" className="text-secondary">{exportResult.message}</Typography>
<Button
variant="outlined"
sx={{ mt: 3 }}
@@ -257,9 +257,9 @@ const MariaDbExportWizard: React.FC<MariaDbExportWizardProps> = ({ open, onClose
</>
) : (
<>
<ErrorIcon color="error" sx={{ fontSize: 60 }} />
<Typography variant="h6" sx={{ mt: 2 }}>{t('mariadb.import.error_title')}</Typography>
<Typography variant="body2" color="error">{exportResult.message}</Typography>
<ErrorIcon sx={{ color: 'var(--color-error)', fontSize: 'var(--font-size-4xl)' }} />
<Typography variant="h6" className="font-black text-xl" sx={{ mt: 2 }}>{t('mariadb.import.error_title')}</Typography>
<Typography variant="body2" sx={{ color: 'var(--color-error)' }} className="text-sm">{exportResult.message}</Typography>
</>
)}
</Box>
@@ -261,19 +261,19 @@ const MariaDbImportWizard: React.FC<MariaDbImportWizardProps> = ({ open, onClose
{!importResult ? (
<>
<Paper sx={{ p: 2, bgcolor: 'var(--color-bg-soft)', border: '1px solid var(--color-border-soft)' }} className="rounded-md">
<Typography variant="subtitle2" color="primary" className="font-bold">{t('mariadb.import.summary')}</Typography>
<Typography variant="subtitle2" sx={{ color: 'var(--color-primary)' }} className="font-bold text-md">{t('mariadb.import.summary')}</Typography>
<Divider sx={{ my: 1, opacity: 0.05 }} />
<Stack spacing={1}>
<Typography variant="body2"><strong>{t('mariadb.import.file')}:</strong> {filePath.split(/[/\\]/).pop()}</Typography>
<Typography variant="body2"><strong>{t('mariadb.import.server')}:</strong> {selectedVersion}</Typography>
<Typography variant="body2"><strong>{t('mariadb.import.db')}:</strong> {dbConfig.dbName}</Typography>
<Typography variant="body2"><strong>{t('mariadb.import.user')}:</strong> {dbConfig.user}</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.import.file')}:</strong> {filePath.split(/[/\\]/).pop()}</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.import.server')}:</strong> {selectedVersion}</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.import.db')}:</strong> {dbConfig.dbName}</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.import.user')}:</strong> {dbConfig.user}</Typography>
</Stack>
</Paper>
{loading && (
<Box sx={{ mt: 3, p: 2, bgcolor: 'var(--color-bg-medium)', maxHeight: '200px', overflowY: 'auto', fontFamily: 'monospace' }} className="rounded-md border-soft">
{logs.map((log, i) => (
<Typography key={i} variant="caption" sx={{ display: 'block', color: log.includes('fail') ? 'error.main' : 'success.main' }}>
<Typography key={i} variant="caption" sx={{ display: 'block', color: log.includes('fail') ? 'var(--color-error)' : 'var(--color-success)' }} className="text-xs">
{log}
</Typography>
))}
@@ -285,24 +285,24 @@ const MariaDbImportWizard: React.FC<MariaDbImportWizardProps> = ({ open, onClose
<Box sx={{ textAlign: 'center', py: 3 }}>
{importResult.success ? (
<>
<SuccessIcon color="success" sx={{ fontSize: 60 }} />
<Typography variant="h6" sx={{ mt: 2 }}>{t('mariadb.import.success_title')}</Typography>
<Typography variant="body2" color="text.secondary">{importResult.message}</Typography>
<Paper sx={{ p: 2, mt: 3, textAlign: 'left', bgcolor: 'rgba(0,180,0,0.1)', border: '1px solid rgba(0,180,0,0.2)' }} className="rounded-md">
<Typography variant="caption" className="font-bold">{t('mariadb.import.access_info')}:</Typography>
<Typography variant="body2"><strong>{t('mariadb.import.host')}:</strong> localhost</Typography>
<Typography variant="body2"><strong>{t('mariadb.import.db')}:</strong> {dbConfig.dbName}</Typography>
<Typography variant="body2"><strong>{t('mariadb.import.user')}:</strong> {dbConfig.user}</Typography>
<Typography variant="body2"><strong>{t('mariadb.import.db_pass')}:</strong> {dbConfig.pass}</Typography>
<SuccessIcon sx={{ color: 'var(--color-success)', fontSize: 'var(--font-size-4xl)' }} />
<Typography variant="h6" className="font-black text-xl" sx={{ mt: 2 }}>{t('mariadb.import.success_title')}</Typography>
<Typography variant="body2" className="text-secondary">{importResult.message}</Typography>
<Paper sx={{ p: 2.5, mt: 3, textAlign: 'left', bgcolor: 'var(--color-success-soft)', border: '1px solid var(--color-success-soft)' }} className="rounded-lg">
<Typography variant="caption" className="font-black text-xs" sx={{ color: 'var(--color-success)', display: 'block', mb: 1, textTransform: 'uppercase' }}>{t('mariadb.import.access_info')}:</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.import.host')}:</strong> localhost</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.import.db')}:</strong> {dbConfig.dbName}</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.import.user')}:</strong> {dbConfig.user}</Typography>
<Typography variant="body2" className="text-sm"><strong>{t('mariadb.import.db_pass')}:</strong> {dbConfig.pass}</Typography>
</Paper>
</>
) : (
<>
<ErrorIcon color="error" sx={{ fontSize: 60 }} />
<Typography variant="h6" sx={{ mt: 2 }}>{t('mariadb.import.error_title')}</Typography>
<Typography variant="body2" color="error">{importResult.message}</Typography>
<Box sx={{ mt: 2, textAlign: 'left', bgcolor: '#000', p: 1, maxHeight: 150, overflowY: 'auto' }}>
{logs.slice(-5).map((l, i) => <Typography key={i} variant="caption" sx={{ color: '#fff', display: 'block' }}>{l}</Typography>)}
<ErrorIcon sx={{ color: 'var(--color-error)', fontSize: 'var(--font-size-4xl)' }} />
<Typography variant="h6" className="font-black text-xl" sx={{ mt: 2 }}>{t('mariadb.import.error_title')}</Typography>
<Typography variant="body2" sx={{ color: 'var(--color-error)' }} className="text-sm">{importResult.message}</Typography>
<Box sx={{ mt: 2, textAlign: 'left', bgcolor: 'black', p: 1, maxHeight: 150, overflowY: 'auto' }} className="rounded-md border-soft">
{logs.slice(-5).map((l, i) => <Typography key={i} variant="caption" sx={{ color: 'white', display: 'block' }} className="text-2xs font-mono">{l}</Typography>)}
</Box>
</>
)}
+8 -8
View File
@@ -216,7 +216,7 @@ const UserGuide = () => {
sx={{
mt: level === 1 ? 0 : 4,
mb: 2,
color: level === 1 ? 'primary.light' : '#fff',
color: level === 1 ? 'var(--color-primary)' : 'white',
borderBottom: level === 1 ? '1px solid var(--color-border-soft)' : 'none',
pb: level === 1 ? 1 : 0
}}
@@ -317,14 +317,14 @@ const UserGuide = () => {
}}
sx={{
'& .MuiOutlinedInput-root': {
bgcolor: 'rgba(0,0,0,0.2)',
borderRadius: 2,
'& fieldset': { borderColor: 'rgba(255,255,255,0.05)' },
bgcolor: 'var(--color-bg-medium)',
borderRadius: 'var(--radius-md)',
'& fieldset': { borderColor: 'var(--color-border-soft)' },
}
}}
/>
</Box>
<Typography variant="overline" sx={{ px: 2, pt: 1, display: 'block', color: 'primary.main', fontWeight: 800 }}>
<Typography variant="overline" className="font-black text-primary" sx={{ px: 2, pt: 1, display: 'block' }}>
{t('common.topics', 'KONULAR')}
</Typography>
<List sx={{ pt: 1, flexGrow: 1, overflowY: 'auto' }}>
@@ -336,9 +336,9 @@ const UserGuide = () => {
sx={{
py: 1.5,
borderLeft: '3px solid',
borderColor: selectedTopic === topic.file ? 'primary.main' : 'transparent',
bgcolor: selectedTopic === topic.file ? 'rgba(57, 167, 255, 0.05)' : 'transparent',
'&:hover': { bgcolor: 'rgba(255,255,255,0.05)' }
borderColor: selectedTopic === topic.file ? 'var(--color-primary)' : 'transparent',
bgcolor: selectedTopic === topic.file ? 'var(--color-primary-soft)' : 'transparent',
'&:hover': { bgcolor: 'var(--color-bg-soft)' }
}}
>
<ListItemText