From a74a11d3a304ecf91489ae37443aaed9e7c849df Mon Sep 17 00:00:00 2001 From: GreenWizard2015 Date: Mon, 1 Jan 2024 13:44:33 +0000 Subject: [PATCH] very ugly UI --- ui/package-lock.json | 29 ++++++++++++++ ui/package.json | 1 + ui/src/App.js | 79 ++++++++++++++++++++++++++++++++++++- ui/src/api/CWaterPumpAPI.js | 27 +++++++++++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 ui/src/api/CWaterPumpAPI.js diff --git a/ui/package-lock.json b/ui/package-lock.json index da24488..d44b148 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -11,6 +11,7 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "axios": "^1.6.3", "bootstrap": "^5.3.2", "react": "^18.2.0", "react-bootstrap": "^2.9.2", @@ -5521,6 +5522,29 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz", + "integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/axobject-query": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", @@ -14789,6 +14813,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", diff --git a/ui/package.json b/ui/package.json index 4f4c0c6..0760bcf 100644 --- a/ui/package.json +++ b/ui/package.json @@ -6,6 +6,7 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "axios": "^1.6.3", "bootstrap": "^5.3.2", "react": "^18.2.0", "react-bootstrap": "^2.9.2", diff --git a/ui/src/App.js b/ui/src/App.js index 38f71d5..9f00e88 100644 --- a/ui/src/App.js +++ b/ui/src/App.js @@ -1,9 +1,86 @@ +import React, { useState, useEffect } from 'react'; import './App.css'; +import { CWaterPumpAPI } from './api/CWaterPumpAPI.js'; + +const STORE_API = 'apiAddress'; +const STORE_RUNTIME = 'runTime'; function App() { + const [apiAddress, setApiAddress] = useState(''); + const [runTime, setRunTime] = useState(1000); + + useEffect(() => { + const storedApiAddress = localStorage.getItem(STORE_API); + if (storedApiAddress) setApiAddress(storedApiAddress); + + let storedRunTime = localStorage.getItem(STORE_RUNTIME); + if (storedRunTime) { + // if string then convert to int + if (typeof storedRunTime === 'string') { + storedRunTime = parseInt(storedRunTime, 10); + } + setRunTime(storedRunTime); + } + }, []); // on mount + + const waterPumpAPI = React.useMemo( + () => { + // ensure apiAddress is started with http:// or https:// + let url = apiAddress; + if (!url.startsWith('http://') && !url.startsWith('https://')) { + url = 'http://' + url; + } + return new CWaterPumpAPI({ URL: url }); + }, [apiAddress] // only re-create if apiAddress changes + ); + + const handleStart = async () => { + try { + await waterPumpAPI.start(runTime); + alert('Water pump started successfully!'); + } catch (error) { + alert('Error starting water pump: ' + error.message); + } + }; + + const handleStop = async () => { + try { + await waterPumpAPI.stop(); + alert('Water pump stopped successfully!'); + } catch (error) { + alert('Error stopping water pump: ' + error.message); + } + }; + + const handleRunTimeChange = (event) => { + const runTime = parseInt(event.target.value, 10); + setRunTime(runTime); + localStorage.setItem(STORE_RUNTIME, runTime); + }; + + const handleApiAddressChange = (event) => { + const apiAddress = event.target.value; + setApiAddress(apiAddress); + localStorage.setItem(STORE_API, apiAddress); + }; + return (
- Tea System UI +

Tea System UI

+
+ +
+
+ +
+ +
); } diff --git a/ui/src/api/CWaterPumpAPI.js b/ui/src/api/CWaterPumpAPI.js new file mode 100644 index 0000000..c3f8f03 --- /dev/null +++ b/ui/src/api/CWaterPumpAPI.js @@ -0,0 +1,27 @@ +import axios from 'axios'; + +class CWaterPumpAPI { + constructor({ client=null, URL }) { + this._client = client || axios.create({ baseURL: URL }); + } + + async start(runTimeMs) { + const response = await this._client.get('/start', { + runTimeMs: runTimeMs + }); + return response.data; + } + + async stop() { + const response = await this._client.get('/stop'); + return response.data; + } + + async status() { + const response = await this._client.get('/status'); + return response.data; + } +} + +export default CWaterPumpAPI; +export { CWaterPumpAPI }; \ No newline at end of file