1- import React , { useState , useEffect } from 'react' ;
1+ import React , { useState , useEffect , useReducer } from 'react' ;
22import axios from 'axios' ;
33import { FiBattery , FiAlertCircle , FiClock , FiThermometer , FiPercent , FiZap , FiActivity , FiRefreshCw , FiCalendar , FiFilter } from 'react-icons/fi' ;
44import { useSettings } from '../context/SettingsContext' ;
@@ -30,11 +30,45 @@ ChartJS.register(
3030
3131const Dashboard = ( ) => {
3232 const { getPollIntervalMs, settings } = useSettings ( ) ;
33- const [ upsSystems , setUpsSystems ] = useState ( [ ] ) ;
34- const [ loading , setLoading ] = useState ( true ) ;
35- const [ error , setError ] = useState ( null ) ;
36- const [ selectedUps , setSelectedUps ] = useState ( null ) ;
33+ // Define reducer for dashboard state
34+ const initialState = {
35+ upsSystems : [ ] ,
36+ loading : true ,
37+ error : null ,
38+ selectedUpsId : null ,
39+ lastUpdated : new Date ( ) ,
40+ forceUpdate : 0 // Used to force re-renders
41+ } ;
42+
43+ const dashboardReducer = ( state , action ) => {
44+ switch ( action . type ) {
45+ case 'SET_UPS_SYSTEMS' :
46+ return {
47+ ...state ,
48+ upsSystems : action . payload ,
49+ lastUpdated : new Date ( ) ,
50+ forceUpdate : state . forceUpdate + 1 // Increment to force re-render
51+ } ;
52+ case 'SET_LOADING' :
53+ return { ...state , loading : action . payload } ;
54+ case 'SET_ERROR' :
55+ return { ...state , error : action . payload } ;
56+ case 'SET_SELECTED_UPS_ID' :
57+ return { ...state , selectedUpsId : action . payload } ;
58+ default :
59+ return state ;
60+ }
61+ } ;
62+
63+ // Use reducer instead of multiple useState calls
64+ const [ state , dispatch ] = useReducer ( dashboardReducer , initialState ) ;
65+ const { upsSystems, loading, error, selectedUpsId, lastUpdated, forceUpdate } = state ;
66+
67+ // Get the selected UPS from the current state
68+ const selectedUps = upsSystems . find ( ups => ups . id === selectedUpsId ) || null ;
69+
3770 const [ timeFilter , setTimeFilter ] = useState ( 3 ) ; // Default to 3 days
71+
3872 const {
3973 batteryHistory,
4074 loading : historyLoading ,
@@ -43,37 +77,45 @@ const Dashboard = () => {
4377 refreshData : refreshBatteryHistory ,
4478 currentTimeFilter
4579 } = useBatteryHistory ( selectedUps ?. id , timeFilter ) ;
46- const [ lastUpdated , setLastUpdated ] = useState ( new Date ( ) ) ;
4780
81+ // Effect for fetching UPS systems data
4882 useEffect ( ( ) => {
4983 const fetchUpsSystems = async ( ) => {
5084 try {
51- setLoading ( true ) ;
85+ dispatch ( { type : 'SET_LOADING' , payload : true } ) ;
5286 const response = await axios . get ( '/api/ups/systems' ) ;
53- setUpsSystems ( response . data ) ;
54- setLastUpdated ( new Date ( ) ) ;
87+ const data = response . data ;
5588
56- if ( response . data . length > 0 && ! selectedUps ) {
57- setSelectedUps ( response . data [ 0 ] ) ;
89+ // Set initial selection if needed
90+ if ( data . length > 0 && ! selectedUpsId ) {
91+ dispatch ( { type : 'SET_SELECTED_UPS_ID' , payload : data [ 0 ] . id } ) ;
5892 }
93+
94+ dispatch ( { type : 'SET_UPS_SYSTEMS' , payload : data } ) ;
95+
96+ // Log for debugging
97+ console . log ( 'UPS systems data fetched:' , data ) ;
5998 } catch ( err ) {
60- setError ( 'Failed to fetch UPS systems. Please check your connection to the NUT server.' ) ;
99+ dispatch ( {
100+ type : 'SET_ERROR' ,
101+ payload : 'Failed to fetch UPS systems. Please check your connection to the NUT server.'
102+ } ) ;
61103 console . error ( 'Error fetching UPS systems:' , err ) ;
62104 } finally {
63- setLoading ( false ) ;
105+ dispatch ( { type : 'SET_LOADING' , payload : false } ) ;
64106 }
65107 } ;
66108
67109 fetchUpsSystems ( ) ;
68110
69- // Set up polling for real-time updates using the configured poll interval
111+ // Set up polling for real-time updates
70112 const interval = setInterval ( fetchUpsSystems , getPollIntervalMs ( ) ) ;
71113
72114 return ( ) => clearInterval ( interval ) ;
73- } , [ getPollIntervalMs , selectedUps ] ) ;
115+ } , [ getPollIntervalMs , selectedUpsId ] ) ; // Added selectedUpsId back to ensure proper initial selection
74116
75117 const handleUpsSelect = ( ups ) => {
76- setSelectedUps ( ups ) ;
118+ dispatch ( { type : 'SET_SELECTED_UPS_ID' , payload : ups . id } ) ;
77119 } ;
78120
79121 const getStatusColor = ( status ) => {
@@ -226,7 +268,7 @@ const Dashboard = () => {
226268 { /* Selected UPS Details */ }
227269 < div className = "md:col-span-2" >
228270 { selectedUps && (
229- < div className = "space-y-6" >
271+ < div className = "space-y-6" key = { ` ${ selectedUps . id } - ${ selectedUps . batteryCharge } - ${ forceUpdate } ` } >
230272 < div className = "bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden" >
231273 < div className = "px-4 py-5 sm:px-6 border-b dark:border-gray-700 flex justify-between items-center" >
232274 < div >
0 commit comments