diff --git a/web/index.html b/web/index.html index df2f94b..34c381e 100644 --- a/web/index.html +++ b/web/index.html @@ -1,13 +1,16 @@ - - - - - - Meshstream - - -
- - - + + + + + + + ERSN Mesh + + + +
+ + + + \ No newline at end of file diff --git a/web/package.json b/web/package.json index 78ab0e8..12ad2c0 100644 --- a/web/package.json +++ b/web/package.json @@ -29,12 +29,14 @@ "@tanstack/router-devtools": "^1.116.0", "@tanstack/router-vite-plugin": "^1.116.1", "leaflet": "^1.9.4", + "lucide-react": "^0.503.0", "react": "^19.1.0", "react-dom": "^19.1.0", "react-leaflet": "^5.0.0", "react-redux": "^9.2.0" }, "devDependencies": { + "@tailwindcss/vite": "^4.1.4", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^14.6.1", @@ -51,6 +53,7 @@ "eslint-plugin-react-refresh": "^0.4.20", "jsdom": "^26.1.0", "postcss": "^8.5.3", + "tailwindcss": "^4.1.4", "typescript": "^5.8.3", "typescript-eslint": "^8.31.0", "vite": "^6.3.2", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 3d284eb..6a48abe 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -29,6 +29,9 @@ dependencies: leaflet: specifier: ^1.9.4 version: 1.9.4 + lucide-react: + specifier: ^0.503.0 + version: 0.503.0(react@19.1.0) react: specifier: ^19.1.0 version: 19.1.0 @@ -43,6 +46,9 @@ dependencies: version: 9.2.0(@types/react@19.1.2)(react@19.1.0)(redux@5.0.1) devDependencies: + '@tailwindcss/vite': + specifier: ^4.1.4 + version: 4.1.4(vite@6.3.2) '@testing-library/jest-dom': specifier: ^6.6.3 version: 6.6.3 @@ -91,6 +97,9 @@ devDependencies: postcss: specifier: ^8.5.3 version: 8.5.3 + tailwindcss: + specifier: ^4.1.4 + version: 4.1.4 typescript: specifier: ^5.8.3 version: 5.8.3 @@ -892,7 +901,6 @@ packages: jiti: 2.4.2 lightningcss: 1.29.2 tailwindcss: 4.1.4 - dev: false /@tailwindcss/oxide-android-arm64@4.1.4: resolution: {integrity: sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA==} @@ -900,7 +908,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide-darwin-arm64@4.1.4: @@ -909,7 +916,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide-darwin-x64@4.1.4: @@ -918,7 +924,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide-freebsd-x64@4.1.4: @@ -927,7 +932,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4: @@ -936,7 +940,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide-linux-arm64-gnu@4.1.4: @@ -945,7 +948,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide-linux-arm64-musl@4.1.4: @@ -954,7 +956,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide-linux-x64-gnu@4.1.4: @@ -963,7 +964,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide-linux-x64-musl@4.1.4: @@ -972,7 +972,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide-wasm32-wasi@4.1.4: @@ -980,7 +979,6 @@ packages: engines: {node: '>=14.0.0'} cpu: [wasm32] requiresBuild: true - dev: false optional: true bundledDependencies: - '@napi-rs/wasm-runtime' @@ -996,7 +994,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide-win32-x64-msvc@4.1.4: @@ -1005,7 +1002,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true /@tailwindcss/oxide@4.1.4: @@ -1024,7 +1020,6 @@ packages: '@tailwindcss/oxide-wasm32-wasi': 4.1.4 '@tailwindcss/oxide-win32-arm64-msvc': 4.1.4 '@tailwindcss/oxide-win32-x64-msvc': 4.1.4 - dev: false /@tailwindcss/postcss@4.1.4: resolution: {integrity: sha512-bjV6sqycCEa+AQSt2Kr7wpGF1bOZJ5wsqnLEkqSbM/JEHxx/yhMH8wHmdkPyApF9xhHeMSwnnkDUUMMM/hYnXw==} @@ -1036,6 +1031,17 @@ packages: tailwindcss: 4.1.4 dev: false + /@tailwindcss/vite@4.1.4(vite@6.3.2): + resolution: {integrity: sha512-4UQeMrONbvrsXKXXp/uxmdEN5JIJ9RkH7YVzs6AMxC/KC1+Np7WZBaNIco7TEjlkthqxZbt8pU/ipD+hKjm80A==} + peerDependencies: + vite: ^5.2.0 || ^6 + dependencies: + '@tailwindcss/node': 4.1.4 + '@tailwindcss/oxide': 4.1.4 + tailwindcss: 4.1.4 + vite: 6.3.2 + dev: true + /@tanstack/history@1.115.0: resolution: {integrity: sha512-K7JJNrRVvyjAVnbXOH2XLRhFXDkeP54Kt2P4FR1Kl2KDGlIbkua5VqZQD2rot3qaDrpufyUa63nuLai1kOLTsQ==} engines: {node: '>=12'} @@ -2026,7 +2032,6 @@ packages: /detect-libc@2.0.4: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} - dev: false /diff@7.0.0: resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} @@ -2066,7 +2071,6 @@ packages: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 - dev: false /entities@6.0.0: resolution: {integrity: sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==} @@ -2593,7 +2597,6 @@ packages: /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: false /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -2919,7 +2922,6 @@ packages: /jiti@2.4.2: resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} hasBin: true - dev: false /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -3022,7 +3024,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /lightningcss-darwin-x64@1.29.2: @@ -3031,7 +3032,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /lightningcss-freebsd-x64@1.29.2: @@ -3040,7 +3040,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: false optional: true /lightningcss-linux-arm-gnueabihf@1.29.2: @@ -3049,7 +3048,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /lightningcss-linux-arm64-gnu@1.29.2: @@ -3058,7 +3056,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /lightningcss-linux-arm64-musl@1.29.2: @@ -3067,7 +3064,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /lightningcss-linux-x64-gnu@1.29.2: @@ -3076,7 +3072,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /lightningcss-linux-x64-musl@1.29.2: @@ -3085,7 +3080,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /lightningcss-win32-arm64-msvc@1.29.2: @@ -3094,7 +3088,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: false optional: true /lightningcss-win32-x64-msvc@1.29.2: @@ -3103,7 +3096,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true /lightningcss@1.29.2: @@ -3122,7 +3114,6 @@ packages: lightningcss-linux-x64-musl: 1.29.2 lightningcss-win32-arm64-msvc: 1.29.2 lightningcss-win32-x64-msvc: 1.29.2 - dev: false /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} @@ -3159,6 +3150,14 @@ packages: dependencies: yallist: 3.1.1 + /lucide-react@0.503.0(react@19.1.0): + resolution: {integrity: sha512-HGGkdlPWQ0vTF8jJ5TdIqhQXZi6uh3LnNgfZ8MHiuxFfX3RZeA79r2MW2tHAZKlAVfoNE8esm3p+O6VkIvpj6w==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + react: 19.1.0 + dev: false + /lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -3869,12 +3868,10 @@ packages: /tailwindcss@4.1.4: resolution: {integrity: sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==} - dev: false /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - dev: false /tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} diff --git a/web/postcss.config.js b/web/postcss.config.js index 51a6e4e..44d2119 100644 --- a/web/postcss.config.js +++ b/web/postcss.config.js @@ -3,4 +3,4 @@ export default { '@tailwindcss/postcss': {}, autoprefixer: {}, }, -}; +}; \ No newline at end of file diff --git a/web/src/components/ConnectionStatus.tsx b/web/src/components/ConnectionStatus.tsx new file mode 100644 index 0000000..6e011f1 --- /dev/null +++ b/web/src/components/ConnectionStatus.tsx @@ -0,0 +1,55 @@ +import React from "react"; +import { WifiOff, Wifi, WifiLow, Activity, AlertCircle } from "lucide-react"; + +interface ConnectionStatusProps { + status: string; +} + +export const ConnectionStatus: React.FC = ({ + status, +}) => { + // Determine connection status type + const getStatusInfo = () => { + if (status.includes("error") || status.includes("Error")) { + return { + icon: , + text: "Connection Error", + colorClass: "text-red-400", + }; + } else if (status.includes("Reconnecting")) { + return { + icon: , + text: "Reconnecting", + colorClass: "text-amber-400", + }; + } else if (status.includes("Connecting")) { + return { + icon: , + text: "Connecting", + colorClass: "text-blue-400", + }; + } else if (status.includes("Connected")) { + return { + icon: , + text: "Connected", + colorClass: "text-green-400", + }; + } else { + // Default state or unknown status + return { + icon: , + text: status || "Unknown", + colorClass: "text-neutral-400", + }; + } + }; + + const { icon, text, colorClass } = getStatusInfo(); + + return ( +
+ {icon} + {text} +
+ ); +}; diff --git a/web/src/components/Filter.tsx b/web/src/components/Filter.tsx index 0b42e30..85d07df 100644 --- a/web/src/components/Filter.tsx +++ b/web/src/components/Filter.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React from "react"; interface FilterProps { onChange: (filter: string) => void; @@ -8,13 +8,16 @@ interface FilterProps { export const Filter: React.FC = ({ onChange, value }) => { return (
-