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

88 lines
3.3 KiB
JavaScript

import React, { useState, useEffect, useCallback } from 'react';
import { Grid, Typography, Button, ButtonGroup, Box, Alert } from '@mui/material';
import ControllerCard from './ControllerCard';
import { useI18n } from './I18nContext';
export default function Dashboard() {
const { t } = useI18n();
const [groupedDevices, setGroupedDevices] = useState({});
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [range, setRange] = useState('day'); // 'day', 'week', 'month'
const fetchDevices = useCallback(async () => {
try {
// Robust API Base detection
const baseUrl = window.location.pathname.endsWith('/') ? 'api/' : 'api/';
// Actually, since we are serving from root or subpath, relative 'api/' is tricky if URL depth changes.
// Better to use a relative path that works from the page root.
// If page is /ac-dashboard/, fetch is /ac-dashboard/api/devices.
const res = await fetch('api/devices');
if (!res.ok) throw new Error('Failed to fetch devices');
const devices = await res.json();
// Group by dev_name
const grouped = devices.reduce((acc, dev) => {
if (!acc[dev.dev_name]) acc[dev.dev_name] = [];
acc[dev.dev_name].push(dev);
return acc;
}, {});
setGroupedDevices(grouped);
setLoading(false);
} catch (err) {
console.error(err);
setError(err.message);
setLoading(false);
}
}, []);
useEffect(() => {
fetchDevices();
}, [fetchDevices]);
// Auto-refresh logic (basic rerender trigger could be added here,
// but simpler to let ControllerCard handle data fetching internally based on props)
if (loading) return <Typography>{t('dashboard.loading')}</Typography>;
if (error) return <Alert severity="error">{error}</Alert>;
return (
<Box>
<Box display="flex" justifyContent="flex-end" mb={3}>
<ButtonGroup variant="contained" aria-label="outlined primary button group">
<Button
onClick={() => setRange('day')}
color={range === 'day' ? 'primary' : 'inherit'}
>
{t('dashboard.hours24')}
</Button>
<Button
onClick={() => setRange('week')}
color={range === 'week' ? 'primary' : 'inherit'}
>
{t('dashboard.days7')}
</Button>
<Button
onClick={() => setRange('month')}
color={range === 'month' ? 'primary' : 'inherit'}
>
{t('dashboard.days30')}
</Button>
</ButtonGroup>
</Box>
{Object.entries(groupedDevices).map(([controllerName, ports]) => (
<ControllerCard
key={controllerName}
controllerName={controllerName}
ports={ports}
range={range}
/>
))}
</Box>
);
}