From 84cd474bcbb5d38df721634dddc51356916c72fb Mon Sep 17 00:00:00 2001 From: Ghassan Yusuf Date: Tue, 4 Aug 2026 13:47:02 +0300 Subject: [PATCH] Rebuild desktop shell on the real AdminLTE 4 package Install admin-lte@4.1.0 (+ bootstrap 5.3.8, bootstrap-icons as peer deps) and rebuild every desktop component against actual AdminLTE markup pulled from its live docs/demo, rather than a Tailwind approximation: - Real app-wrapper/app-header/app-sidebar/app-main/app-footer structure - Working PushMenu (sidebar collapse), Treeview, ColorMode (light/dark/auto) - Navbar: functional search (wired to Users list ?search=), notifications dropdown (MQTT-driven), user menu dropdown - Sidebar: grouped nav-header sections, active-route highlighting - Breadcrumbs, footer, Bootstrap card/table/pagination/progress widgets Tailwind is now imported utilities-only (no preflight) so it coexists with Bootstrap's reset; mobile shell and modals are untouched and still Tailwind. --- frontend/package-lock.json | 61 ++++++++ frontend/package.json | 2 + .../components/desktop/ActivityTimeline.tsx | 18 +-- frontend/src/components/desktop/Card.tsx | 10 +- .../src/components/desktop/ChartPanel.tsx | 25 ++-- frontend/src/components/desktop/Footer.tsx | 8 + frontend/src/components/desktop/InfoBox.tsx | 15 +- frontend/src/components/desktop/Navbar.tsx | 141 +++++++++++++++--- .../src/components/desktop/PageHeader.tsx | 43 ++++++ frontend/src/components/desktop/Sidebar.tsx | 53 ++++--- frontend/src/components/desktop/SmallBox.tsx | 26 ++++ .../components/desktop/useNotifications.ts | 33 ++++ frontend/src/components/shared/DataTable.tsx | 70 ++++----- .../src/features/dashboard/DashboardPage.tsx | 37 +++-- frontend/src/features/users/UsersListPage.tsx | 81 ++++++---- frontend/src/index.css | 15 +- frontend/src/layouts/shell/DesktopShell.tsx | 25 +++- frontend/src/layouts/shell/navConfig.ts | 20 ++- frontend/src/main.tsx | 7 + 19 files changed, 528 insertions(+), 162 deletions(-) create mode 100644 frontend/src/components/desktop/Footer.tsx create mode 100644 frontend/src/components/desktop/PageHeader.tsx create mode 100644 frontend/src/components/desktop/SmallBox.tsx create mode 100644 frontend/src/components/desktop/useNotifications.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index cec1347..04fdb07 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,7 +9,9 @@ "version": "0.0.0", "dependencies": { "@tanstack/react-query": "^5.101.4", + "admin-lte": "^4.1.0", "axios": "^1.19.0", + "bootstrap-icons": "^1.13.1", "mqtt": "^5.15.2", "qrcode": "^1.5.4", "react": "^19.2.8", @@ -421,6 +423,17 @@ "node": "^20.19.0 || >=22.12.0" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.2.tgz", @@ -1321,6 +1334,18 @@ "node": ">=6.5" } }, + "node_modules/admin-lte": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/admin-lte/-/admin-lte-4.1.0.tgz", + "integrity": "sha512-XsBJSYMYjUD0PYgTeI2/3WIeYGPtr2tUAsd7ei8Zgh5bYhGzLkTxAy7aIV/k19zifmHY9llaEZ0dPIUOKCzArA==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "bootstrap": "^5.3.8" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -1407,6 +1432,42 @@ "readable-stream": "^4.2.0" } }, + "node_modules/bootstrap": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT", + "peer": true, + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/bootstrap-icons": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.13.1.tgz", + "integrity": "sha512-ijombt4v6bv5CLeXvRWKy7CuM3TRTuPEuGaGKvTV5cz65rQSY8RQ2JcHt6b90cBBAC7s8fsf2EkQDldzCoXUjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT" + }, "node_modules/broker-factory": { "version": "3.1.15", "resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.15.tgz", diff --git a/frontend/package.json b/frontend/package.json index 8494c15..e1639ec 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,7 +11,9 @@ }, "dependencies": { "@tanstack/react-query": "^5.101.4", + "admin-lte": "^4.1.0", "axios": "^1.19.0", + "bootstrap-icons": "^1.13.1", "mqtt": "^5.15.2", "qrcode": "^1.5.4", "react": "^19.2.8", diff --git a/frontend/src/components/desktop/ActivityTimeline.tsx b/frontend/src/components/desktop/ActivityTimeline.tsx index 617cbba..9f4659d 100644 --- a/frontend/src/components/desktop/ActivityTimeline.tsx +++ b/frontend/src/components/desktop/ActivityTimeline.tsx @@ -14,20 +14,14 @@ export function ActivityTimeline({ items }: ActivityTimelineProps) { return ( {items.length === 0 ? ( -

No activity yet.

+

No activity yet.

) : ( -