Files
wolfDash/src/client/Dashboard.js
sebseb7 eec45ee379 u
2025-12-23 06:59:23 +01:00

129 lines
5.0 KiB
JavaScript

import React, { Component } from 'react';
import { Grid, Typography, Button, ButtonGroup, Box, Alert } from '@mui/material';
import ControllerCard from './ControllerCard';
import OutputChart from './OutputChart';
import { withI18n } from './I18nContext';
import { withDevices } from './DevicesContext';
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
range: 'day', // 'day', 'week', 'month'
offset: 0
};
}
setRange = (range) => {
this.setState({ range, offset: 0 });
};
setOffset = (offset) => {
if (offset < 0) offset = 0;
this.setState({ offset });
};
render() {
const { i18n: { t }, devicesCtx: { devices, groupedDevices, loading, error } } = this.props;
const { range, offset } = this.state;
const nowMs = Date.now();
let startMs, endMs;
if (range === 'today') {
const d = new Date(nowMs);
d.setHours(0, 0, 0, 0);
const midnightMs = d.getTime();
startMs = midnightMs - (offset * 24 * 3600 * 1000);
endMs = startMs + (24 * 3600 * 1000);
} else {
const durationSec = (range === 'week' ? 7 * 24 * 3600 : (range === 'month' ? 30 * 24 * 3600 : 24 * 3600));
endMs = nowMs - (offset * durationSec * 1000);
startMs = endMs - (durationSec * 1000);
}
const dateOpts = { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' };
const dateRangeLabel = `${new Date(startMs).toLocaleString([], dateOpts)} - ${new Date(endMs).toLocaleString([], dateOpts)}`;
if (loading) return <Typography>{t('dashboard.loading')}</Typography>;
if (error) return <Alert severity="error">{error}</Alert>;
return (
<Box>
<Box
display="flex"
justifyContent="space-between"
alignItems="center"
mb={3}
sx={{
position: 'sticky',
top: 0,
zIndex: 100,
backgroundColor: '#1d2021', // Dashboard background color to cover content
padding: '10px 20px', // Added horizontal padding
borderBottom: '1px solid #3c3836',
margin: '-16px -16px 16px -16px' // Negative margin to stretch full width if inside padding
}}
>
<Typography variant="h6" sx={{ color: '#ebdbb2' }}>
{dateRangeLabel}
</Typography>
<ButtonGroup variant="contained" aria-label="outlined primary button group">
<Button
onClick={() => this.setOffset(this.state.offset + 1)}
color="inherit"
>
&lt;
</Button>
<Button
onClick={() => this.setRange('day')}
color={range === 'day' ? 'primary' : 'inherit'}
>
{t('dashboard.hours24')}
</Button>
<Button
onClick={() => this.setRange('today')}
color={range === 'today' ? 'primary' : 'inherit'}
>
1 Tag
</Button>
<Button
onClick={() => this.setRange('week')}
color={range === 'week' ? 'primary' : 'inherit'}
>
{t('dashboard.days7')}
</Button>
<Button
onClick={() => this.setRange('month')}
color={range === 'month' ? 'primary' : 'inherit'}
>
{t('dashboard.days30')}
</Button>
<Button
onClick={() => this.setOffset(this.state.offset - 1)}
disabled={this.state.offset <= 0}
color="inherit"
>
&gt;
</Button>
</ButtonGroup>
</Box>
{Object.entries(groupedDevices).map(([controllerName, ports]) => (
<ControllerCard
key={controllerName}
controllerName={controllerName}
ports={ports}
range={range}
offset={this.state.offset}
/>
))}
<OutputChart range={range} offset={this.state.offset} devices={devices} />
</Box>
);
}
}
export default withDevices(withI18n(Dashboard));