[d6876d]: / src / pages / Monitoring / Monitoring.tsx

Download this file

194 lines (182 with data), 5.5 kB

import React, { useState, useEffect } from 'react';
import {
  Box,
  Typography,
  Grid,
  Paper,
  Card,
  CardContent,
  LinearProgress,
  Alert,
  IconButton,
  Stack,
} from '@mui/material';
import {
  Thermostat,
  WaterDrop,
  WbSunny,
  Speed,
  Refresh as RefreshIcon,
} from '@mui/icons-material';
import { SensorData } from '../../types';

const mockSensorData: SensorData[] = [
  {
    id: '1',
    sensorId: 'FIELD-001-TEMP',
    timestamp: new Date().toISOString(),
    measurements: {
      temperature: 25.4,
      humidity: 65.2,
      soilMoisture: 0.42,
      lightIntensity: 850,
    },
    qualityIndicator: 0.95,
  },
  {
    id: '2',
    sensorId: 'FIELD-002-TEMP',
    timestamp: new Date().toISOString(),
    measurements: {
      temperature: 26.1,
      humidity: 62.8,
      soilMoisture: 0.38,
      lightIntensity: 820,
    },
    qualityIndicator: 0.92,
  },
];

const SensorCard: React.FC<{
  title: string;
  value: number;
  unit: string;
  icon: React.ReactNode;
  color: string;
}> = ({ title, value, unit, icon, color }) => (
  <Card>
    <CardContent>
      <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>
        <Box sx={{ mr: 1, color }}>{icon}</Box>
        <Typography variant="h6">{title}</Typography>
      </Box>
      <Typography variant="h4" gutterBottom>
        {value.toFixed(1)}
        <Typography variant="body1" component="span" color="text.secondary">
          {' '}
          {unit}
        </Typography>
      </Typography>
      <LinearProgress
        variant="determinate"
        value={(value / 100) * 100}
        sx={{ height: 8, borderRadius: 4 }}
      />
    </CardContent>
  </Card>
);

const Monitoring: React.FC = () => {
  const [sensorData, setSensorData] = useState<SensorData[]>(mockSensorData);
  const [lastUpdate, setLastUpdate] = useState<Date>(new Date());
  const [isLoading, setIsLoading] = useState(false);

  const refreshData = () => {
    setIsLoading(true);
    // Simulate data refresh
    setTimeout(() => {
      const newData = mockSensorData.map(sensor => ({
        ...sensor,
        measurements: {
          ...sensor.measurements,
          temperature: sensor.measurements.temperature + (Math.random() - 0.5),
          humidity: sensor.measurements.humidity + (Math.random() - 0.5),
          soilMoisture: Math.max(0, Math.min(1, sensor.measurements.soilMoisture + (Math.random() - 0.5) * 0.1)),
          lightIntensity: sensor.measurements.lightIntensity + (Math.random() - 0.5) * 50,
        },
      }));
      setSensorData(newData);
      setLastUpdate(new Date());
      setIsLoading(false);
    }, 1000);
  };

  useEffect(() => {
    const interval = setInterval(refreshData, 30000); // Refresh every 30 seconds
    return () => clearInterval(interval);
  }, []);

  return (
    <Box>
      <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
        <Typography variant="h4">Environmental Monitoring</Typography>
        <Box>
          <IconButton onClick={refreshData} disabled={isLoading}>
            <RefreshIcon />
          </IconButton>
          <Typography variant="body2" color="text.secondary">
            Last updated: {lastUpdate.toLocaleTimeString()}
          </Typography>
        </Box>
      </Box>

      {sensorData.map((sensor) => (
        <Paper key={sensor.id} sx={{ p: 2, mb: 3 }}>
          <Typography variant="h6" gutterBottom>
            Sensor: {sensor.sensorId}
          </Typography>
          
          <Grid container spacing={3}>
            <Grid item xs={12} sm={6} md={3}>
              <SensorCard
                title="Temperature"
                value={sensor.measurements.temperature}
                unit="°C"
                icon={<Thermostat />}
                color="#f44336"
              />
            </Grid>
            <Grid item xs={12} sm={6} md={3}>
              <SensorCard
                title="Humidity"
                value={sensor.measurements.humidity}
                unit="%"
                icon={<WaterDrop />}
                color="#2196f3"
              />
            </Grid>
            <Grid item xs={12} sm={6} md={3}>
              <SensorCard
                title="Soil Moisture"
                value={sensor.measurements.soilMoisture * 100}
                unit="%"
                icon={<Speed />}
                color="#4caf50"
              />
            </Grid>
            <Grid item xs={12} sm={6} md={3}>
              <SensorCard
                title="Light Intensity"
                value={sensor.measurements.lightIntensity}
                unit="lux"
                icon={<WbSunny />}
                color="#ff9800"
              />
            </Grid>
          </Grid>

          {sensor.qualityIndicator < 0.9 && (
            <Alert severity="warning" sx={{ mt: 2 }}>
              Sensor data quality below threshold. Maintenance may be required.
            </Alert>
          )}
        </Paper>
      ))}

      <Stack spacing={2}>
        {/* Placeholder for historical data charts */}
        <Paper sx={{ p: 2 }}>
          <Typography variant="h6" gutterBottom>
            24-Hour Trends
          </Typography>
          <Box sx={{ height: 200, bgcolor: 'background.default', p: 2 }}>
            <Typography variant="body2" color="text.secondary" align="center">
              Historical data visualization will be implemented here
            </Typography>
          </Box>
        </Paper>
      </Stack>
    </Box>
  );
};

export default Monitoring;