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 {t('dashboard.loading')}; if (error) return {error}; return ( {Object.entries(groupedDevices).map(([controllerName, ports]) => ( ))} ); }