feat: implement main application dashboard and user guide component
This commit is contained in:
@@ -1014,6 +1014,28 @@ function App(): JSX.Element {
|
|||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
<GlobalStyles styles={{
|
<GlobalStyles styles={{
|
||||||
|
'html, body, #root': {
|
||||||
|
margin: 0,
|
||||||
|
padding: 0,
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
overflow: 'hidden',
|
||||||
|
},
|
||||||
|
'*::-webkit-scrollbar': {
|
||||||
|
width: '8px',
|
||||||
|
height: '8px',
|
||||||
|
},
|
||||||
|
'*::-webkit-scrollbar-track': {
|
||||||
|
background: 'rgba(0, 0, 0, 0.1)',
|
||||||
|
},
|
||||||
|
'*::-webkit-scrollbar-thumb': {
|
||||||
|
background: '#153E5E',
|
||||||
|
borderRadius: '10px',
|
||||||
|
border: '2px solid rgba(0, 0, 0, 0.1)',
|
||||||
|
},
|
||||||
|
'*::-webkit-scrollbar-thumb:hover': {
|
||||||
|
background: '#1a4d75',
|
||||||
|
},
|
||||||
'.swal2-container': {
|
'.swal2-container': {
|
||||||
zIndex: '9999 !important'
|
zIndex: '9999 !important'
|
||||||
},
|
},
|
||||||
@@ -1028,7 +1050,7 @@ function App(): JSX.Element {
|
|||||||
border: '1px solid rgba(255,255,255,0.1) !important'
|
border: '1px solid rgba(255,255,255,0.1) !important'
|
||||||
}
|
}
|
||||||
}} />
|
}} />
|
||||||
<Box sx={{ display: 'flex', minHeight: '100vh', backgroundImage: 'radial-gradient(circle at 50% 0%, #153E5E 0%, #121212 100%)', bgcolor: 'transparent' }}>
|
<Box sx={{ display: 'flex', height: '100vh', width: '100vw', overflow: 'hidden', backgroundImage: 'radial-gradient(circle at 50% 0%, #153E5E 0%, #121212 100%)', bgcolor: 'transparent' }}>
|
||||||
<AppBar
|
<AppBar
|
||||||
position="fixed"
|
position="fixed"
|
||||||
sx={{
|
sx={{
|
||||||
@@ -1161,9 +1183,9 @@ function App(): JSX.Element {
|
|||||||
</Box>
|
</Box>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
||||||
<Box component="main" sx={{ flexGrow: 1, p: 3 }}>
|
<Box component="main" sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column', height: '100vh', overflow: 'hidden' }}>
|
||||||
<Toolbar />
|
<Toolbar />
|
||||||
<Container maxWidth={false} sx={{ py: 2 }}>
|
<Container maxWidth={false} sx={{ flexGrow: 1, py: 2, overflow: 'auto', display: 'flex', flexDirection: 'column' }}>
|
||||||
{activeTab === 'tuning' && <ServerTuning />}
|
{activeTab === 'tuning' && <ServerTuning />}
|
||||||
{activeTab === 'db_manager' && <MariaDbDatabaseManager versions={mariaDbVersions} />}
|
{activeTab === 'db_manager' && <MariaDbDatabaseManager versions={mariaDbVersions} />}
|
||||||
{activeTab === 'event_monitor' && <ServiceEventMonitor />}
|
{activeTab === 'event_monitor' && <ServiceEventMonitor />}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import {
|
|||||||
Grid,
|
Grid,
|
||||||
Breadcrumbs,
|
Breadcrumbs,
|
||||||
Link,
|
Link,
|
||||||
CircularProgress
|
CircularProgress,
|
||||||
|
TextField,
|
||||||
|
InputAdornment
|
||||||
} from '@mui/material'
|
} from '@mui/material'
|
||||||
import {
|
import {
|
||||||
MenuBook as GuideIcon,
|
MenuBook as GuideIcon,
|
||||||
@@ -20,7 +22,8 @@ import {
|
|||||||
Info as InfoIcon,
|
Info as InfoIcon,
|
||||||
Lightbulb as TipIcon,
|
Lightbulb as TipIcon,
|
||||||
ReportProblem as WarningIcon,
|
ReportProblem as WarningIcon,
|
||||||
PriorityHigh as CautionIcon
|
PriorityHigh as CautionIcon,
|
||||||
|
Search as SearchIcon
|
||||||
} from '@mui/icons-material'
|
} from '@mui/icons-material'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import Prism from 'prismjs'
|
import Prism from 'prismjs'
|
||||||
@@ -33,6 +36,7 @@ interface Topic {
|
|||||||
const UserGuide = () => {
|
const UserGuide = () => {
|
||||||
const { t, i18n } = useTranslation()
|
const { t, i18n } = useTranslation()
|
||||||
const [topics, setTopics] = useState<Topic[]>([])
|
const [topics, setTopics] = useState<Topic[]>([])
|
||||||
|
const [searchQuery, setSearchQuery] = useState('')
|
||||||
const [selectedTopic, setSelectedTopic] = useState<string>('index.md')
|
const [selectedTopic, setSelectedTopic] = useState<string>('index.md')
|
||||||
const [content, setContent] = useState<string>('')
|
const [content, setContent] = useState<string>('')
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
@@ -266,10 +270,15 @@ const UserGuide = () => {
|
|||||||
return elements
|
return elements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const filteredTopics = topics.filter(t =>
|
||||||
|
t.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||||
|
t.file.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ height: 'calc(100vh - 120px)', display: 'flex', flexDirection: 'column' }}>
|
<Box sx={{ height: 'calc(100vh - 140px)', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
|
||||||
{/* Breadcrumbs */}
|
{/* Breadcrumbs */}
|
||||||
<Box sx={{ mb: 3, display: 'flex', alignItems: 'center', gap: 2 }}>
|
<Box sx={{ mb: 2, display: 'flex', alignItems: 'center', gap: 2 }}>
|
||||||
<Breadcrumbs separator={<ChevronRightIcon sx={{ fontSize: '1rem', color: 'rgba(255,255,255,0.3)' }} />} aria-label="breadcrumb">
|
<Breadcrumbs separator={<ChevronRightIcon sx={{ fontSize: '1rem', color: 'rgba(255,255,255,0.3)' }} />} aria-label="breadcrumb">
|
||||||
<Link underline="hover" color="inherit" sx={{ display: 'flex', alignItems: 'center', color: 'rgba(255,255,255,0.5)', fontSize: '0.85rem' }}>
|
<Link underline="hover" color="inherit" sx={{ display: 'flex', alignItems: 'center', color: 'rgba(255,255,255,0.5)', fontSize: '0.85rem' }}>
|
||||||
<GuideIcon sx={{ mr: 0.5, fontSize: '1.1rem' }} />
|
<GuideIcon sx={{ mr: 0.5, fontSize: '1.1rem' }} />
|
||||||
@@ -290,14 +299,40 @@ const UserGuide = () => {
|
|||||||
bgcolor: 'rgba(255,255,255,0.02)',
|
bgcolor: 'rgba(255,255,255,0.02)',
|
||||||
borderColor: 'rgba(255,255,255,0.05)',
|
borderColor: 'rgba(255,255,255,0.05)',
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
overflow: 'hidden'
|
overflow: 'hidden',
|
||||||
|
height: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="overline" sx={{ px: 2, pt: 2, display: 'block', color: 'primary.main', fontWeight: 800 }}>
|
<Box sx={{ p: 2, pb: 1 }}>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
placeholder={t('common.search')}
|
||||||
|
value={searchQuery}
|
||||||
|
onChange={(e) => setSearchQuery(e.target.value)}
|
||||||
|
InputProps={{
|
||||||
|
startAdornment: (
|
||||||
|
<InputAdornment position="start">
|
||||||
|
<SearchIcon sx={{ color: 'rgba(255,255,255,0.3)', fontSize: '1.2rem' }} />
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
'& .MuiOutlinedInput-root': {
|
||||||
|
bgcolor: 'rgba(0,0,0,0.2)',
|
||||||
|
borderRadius: 2,
|
||||||
|
'& fieldset': { borderColor: 'rgba(255,255,255,0.05)' },
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Typography variant="overline" sx={{ px: 2, pt: 1, display: 'block', color: 'primary.main', fontWeight: 800 }}>
|
||||||
{t('common.topics', 'KONULAR')}
|
{t('common.topics', 'KONULAR')}
|
||||||
</Typography>
|
</Typography>
|
||||||
<List sx={{ pt: 1 }}>
|
<List sx={{ pt: 1, flexGrow: 1, overflowY: 'auto' }}>
|
||||||
{topics.map((topic) => (
|
{filteredTopics.map((topic) => (
|
||||||
<ListItem key={topic.file} disablePadding>
|
<ListItem key={topic.file} disablePadding>
|
||||||
<ListItemButton
|
<ListItemButton
|
||||||
selected={selectedTopic === topic.file}
|
selected={selectedTopic === topic.file}
|
||||||
|
|||||||
Reference in New Issue
Block a user