Files
wolfDash/src/client/ControllerCard.js
sebseb7 5febdf29c8 i18n
2025-12-21 03:46:50 +01:00

95 lines
3.8 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import { Card, CardHeader, CardContent, Divider, Grid, Box, Typography } from '@mui/material';
import EnvChart from './EnvChart';
import LevelChart from './LevelChart';
import { useI18n } from './I18nContext';
export default function ControllerCard({ controllerName, ports, range }) {
const { t } = useI18n();
const [envData, setEnvData] = useState([]);
const [portData, setPortData] = useState({});
const fetchData = async () => {
try {
if (ports.length === 0) return;
// Fetch all ports concurrently
const promises = ports.map(port =>
fetch(`api/history?devName=${encodeURIComponent(controllerName)}&port=${port.port}&range=${range}`)
.then(res => res.json())
.then(data => ({ port: port.port, data }))
);
const results = await Promise.all(promises);
const newPortData = {};
results.forEach(item => {
newPortData[item.port] = item.data;
});
setPortData(newPortData);
// Use the data from the first port for the Environment Chart
// This avoids a redundant network request
if (results.length > 0) {
setEnvData(results[0].data);
}
} catch (err) {
console.error("Fetch error", err);
}
};
// Initial Fetch & Auto-Refresh
useEffect(() => {
fetchData();
const interval = setInterval(fetchData, 60000);
return () => clearInterval(interval);
}, [controllerName, range]); // Depend on range, controllerName changes rarely
return (
<Card sx={{ mb: 4, borderRadius: 2, boxShadow: 3 }}>
<CardHeader
title={controllerName}
titleTypographyProps={{ variant: 'h5', fontWeight: 'bold', color: 'primary.main' }}
sx={{ bgcolor: 'background.paper', borderLeft: '6px solid', borderLeftColor: 'primary.main' }}
/>
<CardContent>
{/* Environment Chart */}
<Box sx={{ height: 350, mb: 6 }}>
<Typography variant="h6" color="text.secondary" gutterBottom>
{t('controller.environment')}
</Typography>
<EnvChart data={envData} range={range} />
</Box>
<Divider sx={{ mt: 2, mb: 3 }} />
{/* Port Grid */}
<Grid container spacing={3}>
{ports.map((port) => {
const isLight = port.port_name && port.port_name.toLowerCase().includes('light');
const isCO2 = port.port_name && port.port_name.toLowerCase().includes('co2');
const pData = portData[port.port] || [];
return (
<Grid size={{ xs: 12, md: 6, lg: 4 }} key={port.port}>
<Card variant="outlined" sx={{ bgcolor: 'background.paper' }}>
<CardContent>
<Typography variant="h6" gutterBottom>
{port.port_name || `${t('controller.port')} ${port.port}`}
</Typography>
<Box sx={{ height: 250 }}>
<LevelChart data={pData} isLight={isLight} isCO2={isCO2} range={range} />
</Box>
</CardContent>
</Card>
</Grid>
);
})}
</Grid>
</CardContent>
</Card>
);
}