diff --git a/web_viewer/fe_src/src/App.css b/web_viewer/fe_src/src/App.css index b2a2e3d..5f5d485 100644 --- a/web_viewer/fe_src/src/App.css +++ b/web_viewer/fe_src/src/App.css @@ -3,6 +3,8 @@ margin: 0 auto; padding: 0.5rem; overflow-x: hidden; + display: flex; + flex-direction: column; } .row { @@ -54,4 +56,25 @@ .chart { display: flex; flex-wrap: wrap; +} + +.chart-item { + flex-basis: 300px; +} + +.text-center { + text-align: center; +} + +.footer { + margin-top: 10px; +} + +.d-flex { + display: flex; +} + +.server-offline, .loading { + height: 300px; + font-size: 22px; } \ No newline at end of file diff --git a/web_viewer/fe_src/src/App.tsx b/web_viewer/fe_src/src/App.tsx index 95a6121..6e726db 100644 --- a/web_viewer/fe_src/src/App.tsx +++ b/web_viewer/fe_src/src/App.tsx @@ -1,6 +1,7 @@ import { useCallback, useEffect, useRef, useState, lazy } from "react"; import "./App.css"; import { IUpdateChart, IInverterData } from "./Intefaces"; +import Footer from "./components/Footer"; const SystemInformation = lazy(() => import("./components/SystemInformation")); const Summary = lazy(() => import("./components/Summary")); @@ -16,6 +17,8 @@ function App() { const reconnectCountRef = useRef(0); const [isSocketConnected, setIsSocketConnected] = useState(true); const hourlyCharfRef = useRef(null); + const [isInitState, setIsInitState] = useState(true); + const isFetchingRef = useRef(false); const connectSocket = useCallback(() => { if ( @@ -69,16 +72,21 @@ function App() { socketRef.current?.close(); }, []); - const fetchState = useCallback(() => { - fetch(`${import.meta.env.VITE_API_BASE_URL}/state`) - .then((res) => res.json()) - .then((json) => { - setInverterData(json); - }) - .catch((err) => { - console.error("API get state error", err); - }); - }, [setInverterData]); + const fetchState = useCallback(async () => { + try { + if (isFetchingRef.current) { + return; + } + isFetchingRef.current = true; + const res = await fetch(`${import.meta.env.VITE_API_BASE_URL}/state`); + const json = await res.json(); + setInverterData(json); + setIsInitState(false); + } catch (err) { + console.error("API get state error", err); + } + isFetchingRef.current = false; + }, [setInverterData, setIsInitState]); useEffect(() => { fetchState(); @@ -105,6 +113,17 @@ function App() { document.title = `[${deviceTimeOnly}] ${import.meta.env.VITE_APP_TITLE}`; }, [inverterData?.deviceTime]); + if (isInitState) { + return ( + <> +
+ Loading.... +
+