Files
wolfDash/src/client/ControllerCard.js
sebseb7 5f4c4a55d8 u
2025-12-23 05:58:03 +01:00

119 lines
4.4 KiB
JavaScript

import React, { Component } from 'react';
import { Card, CardHeader, CardContent, Divider, Grid, Box, Typography } from '@mui/material';
import EnvChart from './EnvChart';
import LevelChart from './LevelChart';
import { withI18n } from './I18nContext';
class ControllerCard extends Component {
constructor(props) {
super(props);
this.state = {
envData: [],
portData: {}
};
this.interval = null;
}
componentDidMount() {
this.fetchData();
this.interval = setInterval(() => this.fetchData(), 60000);
}
componentDidUpdate(prevProps) {
if (prevProps.controllerName !== this.props.controllerName ||
prevProps.range !== this.props.range) {
this.fetchData();
}
}
componentWillUnmount() {
if (this.interval) {
clearInterval(this.interval);
}
}
fetchData = async () => {
const { controllerName, ports, range } = this.props;
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;
});
this.setState({ portData: newPortData });
// Use the data from the first port for the Environment Chart
// This avoids a redundant network request
if (results.length > 0) {
this.setState({ envData: results[0].data });
}
} catch (err) {
console.error("Fetch error", err);
}
};
render() {
const { controllerName, ports, range, i18n: { t } } = this.props;
const { envData, portData } = this.state;
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>
);
}
}
export default withI18n(ControllerCard);