Spaces:
Runtime error
Runtime error
| import React, { useState, useEffect } from 'react' | |
| import { | |
| Box, | |
| Container, | |
| AppBar, | |
| Toolbar, | |
| Typography, | |
| Tabs, | |
| Tab, | |
| Card, | |
| CardContent, | |
| Grid, | |
| Alert as MuiAlert, | |
| CircularProgress, | |
| } from '@mui/material' | |
| import { HealthDashboard } from './components/HealthDashboard' | |
| import { AlertsList } from './components/AlertsList' | |
| import { CreateAlert } from './components/CreateAlert' | |
| import { IncidentsList } from './components/IncidentsList' | |
| interface TabPanelProps { | |
| children?: React.ReactNode | |
| index: number | |
| value: number | |
| } | |
| function TabPanel(props: TabPanelProps) { | |
| const { children, value, index, ...other } = props | |
| return ( | |
| <div | |
| role="tabpanel" | |
| hidden={value !== index} | |
| id={`tabpanel-${index}`} | |
| aria-labelledby={`tab-${index}`} | |
| {...other} | |
| > | |
| {value === index && <Box sx={{ pt: 3 }}>{children}</Box>} | |
| </div> | |
| ) | |
| } | |
| function App() { | |
| const [currentTab, setCurrentTab] = useState(0) | |
| const [isLoading, setIsLoading] = useState(true) | |
| const [error, setError] = useState<string | null>(null) | |
| useEffect(() => { | |
| // Check if API is available | |
| const checkApi = async () => { | |
| try { | |
| const response = await fetch('http://localhost:8001/api/v1/health') | |
| if (!response.ok) { | |
| setError('Backend API is not responding. Make sure Docker services are running.') | |
| } | |
| setIsLoading(false) | |
| } catch (err) { | |
| setError('Cannot connect to backend API at http://localhost:8001') | |
| setIsLoading(false) | |
| } | |
| } | |
| checkApi() | |
| }, []) | |
| const handleTabChange = (event: React.SyntheticEvent, newValue: number) => { | |
| setCurrentTab(newValue) | |
| } | |
| if (isLoading) { | |
| return ( | |
| <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '100vh' }}> | |
| <CircularProgress /> | |
| </Box> | |
| ) | |
| } | |
| return ( | |
| <Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}> | |
| {/* App Bar */} | |
| <AppBar position="static" sx={{ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }}> | |
| <Toolbar> | |
| <Typography variant="h6" component="div" sx={{ flexGrow: 1, fontWeight: 'bold' }}> | |
| 🚨 Autonomous Incident Management System | |
| </Typography> | |
| <Typography variant="caption" sx={{ opacity: 0.9 }}> | |
| v0.1.0 | |
| </Typography> | |
| </Toolbar> | |
| </AppBar> | |
| {/* Main Content */} | |
| <Container maxWidth="lg" sx={{ flex: 1, py: 3 }}> | |
| {error && ( | |
| <MuiAlert severity="error" sx={{ mb: 2 }}> | |
| {error} | |
| </MuiAlert> | |
| )} | |
| {/* Tabs */} | |
| <Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 3 }}> | |
| <Tabs | |
| value={currentTab} | |
| onChange={handleTabChange} | |
| aria-label="navigation tabs" | |
| sx={{ | |
| '& .MuiTab-root': { | |
| textTransform: 'none', | |
| fontSize: '1rem', | |
| } | |
| }} | |
| > | |
| <Tab label="📊 Dashboard" id="tab-0" aria-controls="tabpanel-0" /> | |
| <Tab label="⚠️ Alerts" id="tab-1" aria-controls="tabpanel-1" /> | |
| <Tab label="➕ Create Alert" id="tab-2" aria-controls="tabpanel-2" /> | |
| <Tab label="🔴 Incidents" id="tab-3" aria-controls="tabpanel-3" /> | |
| </Tabs> | |
| </Box> | |
| {/* Tab Panels */} | |
| <TabPanel value={currentTab} index={0}> | |
| <HealthDashboard /> | |
| </TabPanel> | |
| <TabPanel value={currentTab} index={1}> | |
| <AlertsList /> | |
| </TabPanel> | |
| <TabPanel value={currentTab} index={2}> | |
| <Grid container spacing={3}> | |
| <Grid item xs={12} md={6}> | |
| <CreateAlert /> | |
| </Grid> | |
| <Grid item xs={12} md={6}> | |
| <Card sx={{ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', color: 'white' }}> | |
| <CardContent> | |
| <Typography variant="h6" gutterBottom> | |
| 💡 Quick Tips | |
| </Typography> | |
| <Typography variant="body2" component="div"> | |
| <ul style={{ marginTop: '1rem', paddingLeft: '1.5rem' }}> | |
| <li>Source: Alert origin (prometheus, datadog, etc.)</li> | |
| <li>Severity: CRITICAL, HIGH, MEDIUM, LOW, INFO</li> | |
| <li>Multiple services can be affected</li> | |
| <li>Tags help organize and filter alerts</li> | |
| <li>Metadata stores custom alert data</li> | |
| </ul> | |
| </Typography> | |
| </CardContent> | |
| </Card> | |
| </Grid> | |
| </Grid> | |
| </TabPanel> | |
| <TabPanel value={currentTab} index={3}> | |
| <IncidentsList /> | |
| </TabPanel> | |
| </Container> | |
| {/* Footer */} | |
| <Box | |
| component="footer" | |
| sx={{ | |
| background: '#f5f5f5', | |
| borderTop: '1px solid #e0e0e0', | |
| py: 2, | |
| mt: 'auto', | |
| textAlign: 'center', | |
| }} | |
| > | |
| <Typography variant="caption" color="textSecondary"> | |
| Backend: http://localhost:8001 | API Docs: http://localhost:8001/docs | |
| </Typography> | |
| </Box> | |
| </Box> | |
| ) | |
| } | |
| export default App | |