From 3727fc0f303802fe631fb09587b3721c8fa0d544 Mon Sep 17 00:00:00 2001 From: Sukunadot <85873221+Sukunadot@users.noreply.github.com> Date: Thu, 21 Aug 2025 17:51:59 +1000 Subject: [PATCH 1/7] Add files via upload Signed-off-by: Sukunadot <85873221+Sukunadot@users.noreply.github.com> --- new-frontend/frontend/postcss.config.js | 6 ++++++ new-frontend/frontend/tailwind.config.js | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 new-frontend/frontend/postcss.config.js create mode 100644 new-frontend/frontend/tailwind.config.js diff --git a/new-frontend/frontend/postcss.config.js b/new-frontend/frontend/postcss.config.js new file mode 100644 index 0000000..1e8e944 --- /dev/null +++ b/new-frontend/frontend/postcss.config.js @@ -0,0 +1,6 @@ +// postcss.config.js +export default { + plugins: { + '@tailwindcss/postcss': {}, + }, +} \ No newline at end of file diff --git a/new-frontend/frontend/tailwind.config.js b/new-frontend/frontend/tailwind.config.js new file mode 100644 index 0000000..76ab992 --- /dev/null +++ b/new-frontend/frontend/tailwind.config.js @@ -0,0 +1,6 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], + theme: { extend: {} }, + plugins: [], +} From b6bc5d8f85f5430e454bc35f0d58f6a826af84f1 Mon Sep 17 00:00:00 2001 From: Sukunadot <85873221+Sukunadot@users.noreply.github.com> Date: Thu, 21 Aug 2025 17:52:39 +1000 Subject: [PATCH 2/7] Add files via upload Signed-off-by: Sukunadot <85873221+Sukunadot@users.noreply.github.com> --- new-frontend/frontend/src/index.css | 69 +---------------------------- 1 file changed, 1 insertion(+), 68 deletions(-) diff --git a/new-frontend/frontend/src/index.css b/new-frontend/frontend/src/index.css index 08a3ac9..a461c50 100644 --- a/new-frontend/frontend/src/index.css +++ b/new-frontend/frontend/src/index.css @@ -1,68 +1 @@ -:root { - font-family: 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; -} - -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; - } -} +@import "tailwindcss"; \ No newline at end of file From 0aae8a5116786756789f7898bfc85854f71148f8 Mon Sep 17 00:00:00 2001 From: Sukunadot <85873221+Sukunadot@users.noreply.github.com> Date: Thu, 21 Aug 2025 17:53:06 +1000 Subject: [PATCH 3/7] Add files via upload Signed-off-by: Sukunadot <85873221+Sukunadot@users.noreply.github.com> --- new-frontend/frontend/src/pages/HomePage.jsx | 179 +++++++++++++++++-- 1 file changed, 162 insertions(+), 17 deletions(-) diff --git a/new-frontend/frontend/src/pages/HomePage.jsx b/new-frontend/frontend/src/pages/HomePage.jsx index cc3f45e..91889d2 100644 --- a/new-frontend/frontend/src/pages/HomePage.jsx +++ b/new-frontend/frontend/src/pages/HomePage.jsx @@ -1,22 +1,167 @@ -import { Link } from 'react-router-dom'; +import { Link } from "react-router-dom"; + +const ThermometerIcon = (props) => ( + + + + +); +const DropletIcon = (props) => ( + + + +); +const AirIcon = (props) => ( + + + + + +); const datasets = [ - { id: 'sensor1', name: 'Sensor 1' }, - { id: 'sensor2', name: 'Sensor 2' }, - { id: 'sensor3', name: 'Sensor 3' }, + { + id: "sensor1", + name: "Sensor 1", + desc: "Temperature readings", + gradient: "from-teal-600 to-teal-500", + icon: ThermometerIcon, + status: "live", + anomalies24h: 2, + }, + { + id: "sensor2", + name: "Sensor 2", + desc: "Humidity monitoring", + gradient: "from-orange-600 to-amber-500", + icon: DropletIcon, + status: "live", + anomalies24h: 0, + }, + { + id: "sensor3", + name: "Sensor 3", + desc: "Air quality index", + gradient: "from-violet-600 to-fuchsia-500", + icon: AirIcon, + status: "offline", + anomalies24h: 5, + }, ]; -const HomePage = () => ( -
-

Available Sensor Datasets

- -
-); +function StatusBadge({ status }) { + const isLive = status === "live"; + return ( + + + {isLive ? "Live" : "Offline"} + + ); +} + +export default function HomePage() { + return ( +
+ +
+
+
+ + + IoT + + Intelligent IoT +
+ + +
+
+ +
+

+ IoT Sensors Dashboard +

+

+ Time-series data, anomaly awareness, and correlation insights — all in one place. +

+
+ +
+

Available Sensor Datasets

+ +
+ {datasets.map((ds) => { + const Icon = ds.icon; + return ( + +
+
+
+ + + +
+
Dataset
+

+ {ds.name} +

+
+
+ +
+
+
+ +
+
+

{ds.desc}

+
+
+ Last 24h anomalies + 0 + ? "bg-rose-50 text-rose-600" + : "bg-emerald-50 text-emerald-600" + }`} + > + {ds.anomalies24h} + +
+
+ + View dashboard → + +
+
+ + ); + })} +
+
-export default HomePage; +
+
+ © {new Date().getFullYear()} Intelligent IoT · Built with React & Tailwind +
+
+
+ ); +} From eb4cc13b8538e26cbb3ef1158fd6c19293ac098f Mon Sep 17 00:00:00 2001 From: Sukunadot <85873221+Sukunadot@users.noreply.github.com> Date: Tue, 2 Sep 2025 18:12:57 +1000 Subject: [PATCH 4/7] Add files via upload Signed-off-by: Sukunadot <85873221+Sukunadot@users.noreply.github.com> --- .../frontend/src/components/DatasetCard.jsx | 63 +++++++++++++++++++ .../frontend/src/components/DatasetsGrid.jsx | 38 +++++++++++ .../frontend/src/components/Footer.jsx | 9 +++ .../frontend/src/components/Header.jsx | 19 ++++++ new-frontend/frontend/src/components/Icon.jsx | 14 +++++ .../frontend/src/components/Section.jsx | 10 +++ .../frontend/src/components/StatusBadge.jsx | 13 ++++ 7 files changed, 166 insertions(+) create mode 100644 new-frontend/frontend/src/components/DatasetCard.jsx create mode 100644 new-frontend/frontend/src/components/DatasetsGrid.jsx create mode 100644 new-frontend/frontend/src/components/Footer.jsx create mode 100644 new-frontend/frontend/src/components/Header.jsx create mode 100644 new-frontend/frontend/src/components/Icon.jsx create mode 100644 new-frontend/frontend/src/components/Section.jsx create mode 100644 new-frontend/frontend/src/components/StatusBadge.jsx diff --git a/new-frontend/frontend/src/components/DatasetCard.jsx b/new-frontend/frontend/src/components/DatasetCard.jsx new file mode 100644 index 0000000..97e5104 --- /dev/null +++ b/new-frontend/frontend/src/components/DatasetCard.jsx @@ -0,0 +1,63 @@ +import { Link } from "react-router-dom"; +import StatusBadge from "./StatusBadge"; +import Icon from "./Icon"; + +const GRADIENT = { + temperature: "from-teal-600 to-teal-500", + humidity: "from-orange-600 to-amber-500", + air: "from-violet-600 to-fuchsia-500", + default: "from-slate-600 to-slate-500", +}; + +export default function DatasetCard({ dataset }) { + const { + id, // string (e.g., "temp-sensor-01") + name, // display name + description, // short text + type, // "temperature" | "humidity" | "air" | ... + status, // "live" | "offline" | "degraded" + anomalies24h, // number + gradient, // optional override + } = dataset; + + const g = gradient || GRADIENT[type] || GRADIENT.default; + + return ( + +
+
+
+ + + +
+
Dataset
+

{name}

+
+
+ +
+
+
+
+
+

{description}

+
+
+ Last 24h anomalies + 0 ? "bg-rose-50 text-rose-600" : "bg-emerald-50 text-emerald-600"}`}> + {anomalies24h ?? 0} + +
+
+ + View dashboard → + +
+
+ + ); +} diff --git a/new-frontend/frontend/src/components/DatasetsGrid.jsx b/new-frontend/frontend/src/components/DatasetsGrid.jsx new file mode 100644 index 0000000..60fdadf --- /dev/null +++ b/new-frontend/frontend/src/components/DatasetsGrid.jsx @@ -0,0 +1,38 @@ +import DatasetCard from "./DatasetCard"; +import Section from "./Section"; + +function Skeleton() { + return ( +
+ {[...Array(3)].map((_, i) => ( +
+
+
+
+
+
+
+
+ ))} +
+ ); +} + +export default function DatasetsGrid({ datasets = [], loading = false, error = null }) { + return ( +
+ {error && ( +
+ Could not load datasets. Please try again. +
+ )} + {loading ? ( + + ) : ( +
+ {datasets.map((ds) => )} +
+ )} +
+ ); +} diff --git a/new-frontend/frontend/src/components/Footer.jsx b/new-frontend/frontend/src/components/Footer.jsx new file mode 100644 index 0000000..9fc1498 --- /dev/null +++ b/new-frontend/frontend/src/components/Footer.jsx @@ -0,0 +1,9 @@ +export default function Footer({ note = "Built with React & Tailwind" }) { + return ( +
+
+ © {new Date().getFullYear()} Intelligent IoT · {note} +
+
+ ); +} diff --git a/new-frontend/frontend/src/components/Header.jsx b/new-frontend/frontend/src/components/Header.jsx new file mode 100644 index 0000000..b11fb68 --- /dev/null +++ b/new-frontend/frontend/src/components/Header.jsx @@ -0,0 +1,19 @@ +export default function Header({ brand = "Intelligent IoT", nav = [] }) { + return ( +
+
+
+ + IoT + + {brand} +
+ +
+
+ ); +} \ No newline at end of file diff --git a/new-frontend/frontend/src/components/Icon.jsx b/new-frontend/frontend/src/components/Icon.jsx new file mode 100644 index 0000000..27f2a08 --- /dev/null +++ b/new-frontend/frontend/src/components/Icon.jsx @@ -0,0 +1,14 @@ +function Thermometer(props){return()} +function Droplet(props){return()} +function Air(props){return()} + +const ICONS = { + temperature: Thermometer, + humidity: Droplet, + air: Air, +}; + +export default function Icon({ name, className = "h-6 w-6" }) { + const Comp = ICONS[name] || Air; // fallback generic + return ; +} diff --git a/new-frontend/frontend/src/components/Section.jsx b/new-frontend/frontend/src/components/Section.jsx new file mode 100644 index 0000000..bc98c05 --- /dev/null +++ b/new-frontend/frontend/src/components/Section.jsx @@ -0,0 +1,10 @@ +export default function Section({ id, title, center = false, className = "", children }) { + return ( +
+ {title && ( +

{title}

+ )} + {children} +
+ ); +} \ No newline at end of file diff --git a/new-frontend/frontend/src/components/StatusBadge.jsx b/new-frontend/frontend/src/components/StatusBadge.jsx new file mode 100644 index 0000000..5ca544b --- /dev/null +++ b/new-frontend/frontend/src/components/StatusBadge.jsx @@ -0,0 +1,13 @@ +export default function StatusBadge({ status = "offline" }) { + const palette = { + live: { pill: "bg-emerald-100 text-emerald-700", dot: "bg-emerald-600", text: "Live" }, + offline:{ pill: "bg-rose-100 text-rose-700", dot: "bg-rose-600", text: "Offline" }, + degraded:{ pill:"bg-amber-100 text-amber-800", dot: "bg-amber-600", text: "Degraded" }, + }; + const s = palette[status] || palette.offline; + return ( + + {s.text} + + ); +} From 6bb859178a71f48fc6ed72d6b8b05349babdea69 Mon Sep 17 00:00:00 2001 From: Sukunadot <85873221+Sukunadot@users.noreply.github.com> Date: Tue, 2 Sep 2025 18:15:01 +1000 Subject: [PATCH 5/7] Add files via upload Signed-off-by: Sukunadot <85873221+Sukunadot@users.noreply.github.com> --- .../frontend/src/hooks/useDatasets.js | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 new-frontend/frontend/src/hooks/useDatasets.js diff --git a/new-frontend/frontend/src/hooks/useDatasets.js b/new-frontend/frontend/src/hooks/useDatasets.js new file mode 100644 index 0000000..c8fdac9 --- /dev/null +++ b/new-frontend/frontend/src/hooks/useDatasets.js @@ -0,0 +1,27 @@ +import { useEffect, useState } from "react"; + +export default function useDatasets() { + const [datasets, setDatasets] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + let cancelled = false; + (async () => { + try { + // Replace with your real endpoint + const res = await fetch("/api/datasets"); + if (!res.ok) throw new Error(`HTTP ${res.status}`); + const data = await res.json(); + if (!cancelled) setDatasets(Array.isArray(data) ? data : []); + } catch (e) { + if (!cancelled) setError(e); + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { cancelled = true; }; + }, []); + + return { datasets, loading, error }; +} From f0449afff1b7953d0fca896580afb08cbb075a80 Mon Sep 17 00:00:00 2001 From: Sukunadot <85873221+Sukunadot@users.noreply.github.com> Date: Tue, 2 Sep 2025 18:15:31 +1000 Subject: [PATCH 6/7] Add files via upload Signed-off-by: Sukunadot <85873221+Sukunadot@users.noreply.github.com> --- new-frontend/frontend/src/pages/HomePage.jsx | 166 ++----------------- 1 file changed, 12 insertions(+), 154 deletions(-) diff --git a/new-frontend/frontend/src/pages/HomePage.jsx b/new-frontend/frontend/src/pages/HomePage.jsx index 91889d2..c154acf 100644 --- a/new-frontend/frontend/src/pages/HomePage.jsx +++ b/new-frontend/frontend/src/pages/HomePage.jsx @@ -1,167 +1,25 @@ -import { Link } from "react-router-dom"; - -const ThermometerIcon = (props) => ( - - - - -); -const DropletIcon = (props) => ( - - - -); -const AirIcon = (props) => ( - - - - - -); - -const datasets = [ - { - id: "sensor1", - name: "Sensor 1", - desc: "Temperature readings", - gradient: "from-teal-600 to-teal-500", - icon: ThermometerIcon, - status: "live", - anomalies24h: 2, - }, - { - id: "sensor2", - name: "Sensor 2", - desc: "Humidity monitoring", - gradient: "from-orange-600 to-amber-500", - icon: DropletIcon, - status: "live", - anomalies24h: 0, - }, - { - id: "sensor3", - name: "Sensor 3", - desc: "Air quality index", - gradient: "from-violet-600 to-fuchsia-500", - icon: AirIcon, - status: "offline", - anomalies24h: 5, - }, -]; - -function StatusBadge({ status }) { - const isLive = status === "live"; - return ( - - - {isLive ? "Live" : "Offline"} - - ); -} +import Header from "../components/Header"; +import Section from "../components/Section"; +import DatasetsGrid from "../components/DatasetsGrid"; +import Footer from "../components/Footer"; +import useDatasets from "../hooks/useDatasets"; export default function HomePage() { + const { datasets, loading, error } = useDatasets(); + return (
- -
-
-
- - - IoT - - Intelligent IoT -
- - -
-
- -
+
+

IoT Sensors Dashboard

Time-series data, anomaly awareness, and correlation insights — all in one place.

-
- -
-

Available Sensor Datasets

- -
- {datasets.map((ds) => { - const Icon = ds.icon; - return ( - -
-
-
- - - -
-
Dataset
-

- {ds.name} -

-
-
- -
-
-
- -
-
-

{ds.desc}

-
-
- Last 24h anomalies - 0 - ? "bg-rose-50 text-rose-600" - : "bg-emerald-50 text-emerald-600" - }`} - > - {ds.anomalies24h} - -
-
- - View dashboard → - -
-
- - ); - })} -
-
- -
-
- © {new Date().getFullYear()} Intelligent IoT · Built with React & Tailwind -
-
+
+ +
); } From fcd254212da6bc2df4322992b4aa8f48b69f36a9 Mon Sep 17 00:00:00 2001 From: Bhanu Singh Thakur Date: Tue, 2 Sep 2025 19:46:22 +1000 Subject: [PATCH 7/7] updated files --- new-frontend/frontend/src/data/datasets.js | 29 +++++++++++++++++++ .../frontend/src/hooks/useDatasets.js | 14 +++++---- 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 new-frontend/frontend/src/data/datasets.js diff --git a/new-frontend/frontend/src/data/datasets.js b/new-frontend/frontend/src/data/datasets.js new file mode 100644 index 0000000..98e96c9 --- /dev/null +++ b/new-frontend/frontend/src/data/datasets.js @@ -0,0 +1,29 @@ +export const datasets = [ + { + id: "temp-01", + name: "Sensor 1", + description: "Temperature readings", + type: "temperature", + status: "live", + anomalies24h: 2, + gradient: "from-teal-600 to-teal-500", + }, + { + id: "hum-02", + name: "Sensor 2", + description: "Humidity monitoring", + type: "humidity", + status: "live", + anomalies24h: 0, + gradient: "from-orange-600 to-amber-500", + }, + { + id: "aqi-03", + name: "Sensor 3", + description: "Air quality index", + type: "air", + status: "offline", + anomalies24h: 5, + gradient: "from-violet-600 to-fuchsia-500", + }, +]; diff --git a/new-frontend/frontend/src/hooks/useDatasets.js b/new-frontend/frontend/src/hooks/useDatasets.js index c8fdac9..6b850b5 100644 --- a/new-frontend/frontend/src/hooks/useDatasets.js +++ b/new-frontend/frontend/src/hooks/useDatasets.js @@ -1,4 +1,5 @@ import { useEffect, useState } from "react"; +import { datasets as seed } from "../data/datasets"; export default function useDatasets() { const [datasets, setDatasets] = useState([]); @@ -7,19 +8,22 @@ export default function useDatasets() { useEffect(() => { let cancelled = false; + (async () => { try { - // Replace with your real endpoint - const res = await fetch("/api/datasets"); - if (!res.ok) throw new Error(`HTTP ${res.status}`); - const data = await res.json(); - if (!cancelled) setDatasets(Array.isArray(data) ? data : []); + // Try real API here later; for now just use seed + await new Promise(r => setTimeout(r, 120)); // optional tiny delay for skeleton + if (!cancelled) { + setDatasets(seed); + setError(null); + } } catch (e) { if (!cancelled) setError(e); } finally { if (!cancelled) setLoading(false); } })(); + return () => { cancelled = true; }; }, []);