diff --git a/src/App.css b/src/App.css deleted file mode 100644 index b9d355df2a5956b526c004531b7b0ffe412461e0..0000000000000000000000000000000000000000 --- a/src/App.css +++ /dev/null @@ -1,42 +0,0 @@ -#root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} diff --git a/src/index.css b/src/index.css deleted file mode 100644 index 2c3fac689c7c4680cfb84bc0746512858b90b908..0000000000000000000000000000000000000000 --- a/src/index.css +++ /dev/null @@ -1,69 +0,0 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-text-size-adjust: 100%; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/src/index.module.css b/src/index.module.css new file mode 100644 index 0000000000000000000000000000000000000000..a85e6095e42b7c99d39b116118eedd2d32e9322b --- /dev/null +++ b/src/index.module.css @@ -0,0 +1,115 @@ +html { + box-sizing: border-box; +} +*, +*:before, +*:after { + box-sizing: inherit; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", + "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", + monospace; +} + +html, +body { + height: 100%; + margin: 0; + line-height: 1.5; + color: #121212; +} +.wrapper { + display: grid; + grid-template-columns: 20% auto; + grid-template-rows: 20% auto; + height: 100vh; + margin: 0; +} +.navbar { + height: 20%; + display: flex; + align-items: center; + justify-content: flex-start;; + background-color: #222; + padding: 0 20px; + color: white; +} +.divUrl { + grid-column: 2 / 3; + grid-row: 2/ 3; + margin-left: 20%; +} +h4, input[type="text"] { + display: inline-block; + vertical-align: middle; +} +h4 { + margin-right: 10px; /* add some margin between the elements */ +} +.urlInput { + width: 50%; +} +.navbar a { + margin-right: 20px; + color: white; + text-decoration: none; + font-size: 20px; +} +.navbar a:last-child { + margin-right: 0; +} +.navbar a:active { + color: rgb(62, 104, 217); +} +.header { + grid-column: 1 / 3; + display: flex; + flex-direction: column; + justify-content: flex-end; + background-color: #555; +} + +.sidebar { + grid-row: 2 / 3; +} +.sidebar h1{ + margin-left: 10%; +} +.listSensors { + padding-left: 20%; +} + +nav ul { + list-style: none; + margin: 0; + padding: 0; +} + +nav li a { + display: block; + padding: 10px; + color: black; + text-decoration: none; +} + +nav li a:hover { + background-color: #6b4d4d; +} + +.details { + display: flex; + justify-content: center; + text-align: center; + margin-top: 5%; + grid-row: 2 / 3; + grid-column: 2 / 3; +} diff --git a/src/main.jsx b/src/main.jsx index 5cc599199a209194402afe8d3ae5ca1e39bc427c..e75a2bbbb9a4b5408e501ae6275e71c899ed479e 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,10 +1,28 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App' -import './index.css' +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import Sensor from "./routes/sensor"; +import Root from "./routes/rout"; +import { + createBrowserRouter, + RouterProvider, +} from "react-router-dom"; + + +const router = createBrowserRouter([ + { + path: "/", + element: , + children: [ + { + path: "/:sensorName", + element: , + }, + ], + }, +]); ReactDOM.createRoot(document.getElementById('root')).render( - + , ) diff --git a/src/routes/rout.jsx b/src/routes/rout.jsx new file mode 100644 index 0000000000000000000000000000000000000000..95371939ea04b47c7d1186999cbe8f12db8b85e2 --- /dev/null +++ b/src/routes/rout.jsx @@ -0,0 +1,95 @@ +import styles from "../index.module.css"; +import React, { useState, useEffect } from 'react'; +import { Outlet, Link, useLoaderData } from "react-router-dom"; +import mqtt from 'precompiled-mqtt'; +export default function Root() { + const [sensors, setSensors] = useState([]); + const [brokerUrl, setBrokerUrl] = useState(''); + + const topic = 'value/#'; + const client = mqtt.connect(brokerUrl); + + useEffect(() => { + client.on('connect', () => { + console.log(`Connected to MQTT broker ${brokerUrl}`); + client.subscribe(topic, (err) => { + if (err) { + console.error('Error subscribing to topic', err); + } else { + console.log(`Subscribed to topic ${topic}`); + } + }); + }); + + client.on('message', (topic, message) => { + const sensorData = JSON.parse(message.toString()); + setSensors((prevSensors) => { + const existingSensor = prevSensors.find((sensor) => sensor.id === sensorData.id); + if (existingSensor) { + return prevSensors.map((sensor) => (sensor.id === sensorData.id ? sensorData : sensor)); + } else { + return [...prevSensors, sensorData]; + } + }); + console.log(`Received sensor data from topic ${topic}:`, sensorData); + }); + + return () => { + client.end(); + }; + }, [brokerUrl]); // effect will run whenever brokerUrl changes + + const handleUrlChange = (e) => { + const url = e.target.value; + setBrokerUrl(url); + }; + + return ( + <> +
+
+
+ Real time sensors + Other + Foo +
+
+
+

Sensors

+
+ +
+
+
+

URL :

+ +
+
+ +
+
+ + ); +} diff --git a/src/routes/sensor.jsx b/src/routes/sensor.jsx new file mode 100644 index 0000000000000000000000000000000000000000..acfed8a652c314e1176512fa4e77be2d2c299a31 --- /dev/null +++ b/src/routes/sensor.jsx @@ -0,0 +1,24 @@ +import styles from "../index.module.css"; + +export default function Sensor(){ + const sensor = { + name: "Exemple sensor name", + type: "PERCENT", + value: 0.2, + }; + + return( +
+

{sensor.name}

+

Valeur actuelle

+
+ {sensor.value} +
+

Historique

+
+ +
+
+ ); + +} \ No newline at end of file