From 4b5b5c283682f02d5088e9c4053843479c0df7bc Mon Sep 17 00:00:00 2001 From: kushwahnihal25-rgb Date: Mon, 8 Jun 2026 21:30:15 +0530 Subject: [PATCH 1/4] Add shimmer loading skeleton for analysis dashboard --- package-lock.json | 36 ++++++++++++++++++-------- package.json | 8 +++--- src/index.css | 21 +++++++++++++++ src/pages/AnalysisDashboard.tsx | 45 +++++++++++++++++++++++++++------ 4 files changed, 87 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index d6e7bfc..0b47487 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,16 +12,16 @@ "framer-motion": "^12.38.0", "i18next": "^26.3.0", "leaflet": "^1.9.4", - "lucide-react": "^1.16.0", + "lucide-react": "^1.17.0", "onnxruntime-web": "^1.26.0", "posthog-js": "^1.376.2", - "react": "^19.2.4", - "react-dom": "^19.2.4", + "react": "^19.2.7", + "react-dom": "^19.2.7", "react-hot-toast": "^2.6.0", "react-i18next": "^17.0.8", "react-joyride": "^3.1.0", "react-leaflet": "^5.0.0", - "react-router-dom": "^7.14.0", + "react-router-dom": "^7.17.0", "tailwindcss": "^4.2.2" }, "devDependencies": { @@ -3856,6 +3856,8 @@ }, "node_modules/cookie": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", "license": "MIT", "engines": { "node": ">=18" @@ -5861,7 +5863,9 @@ } }, "node_modules/lucide-react": { - "version": "1.16.0", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.17.0.tgz", + "integrity": "sha512-9FA9evdox/JQL5PT57fdA1x/yg8T7knJ98+zjTL3UfKza6pflQUUh3XtaQIHKvnsJw1lmsEyHVlt5jchYxOQ5w==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -6250,20 +6254,24 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.2.4", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.2.4", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.4" + "react": "^19.2.7" } }, "node_modules/react-hot-toast": { @@ -6351,7 +6359,9 @@ } }, "node_modules/react-router": { - "version": "7.14.0", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.17.0.tgz", + "integrity": "sha512-FDELK7rTMlCHO5+reyXsPlmfr7N1F91lPHsWYfMEGQm/KQ+F4JFM8jGoeQDmDvdTs93Fw9aSilH+uKRb4/jXvQ==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -6371,10 +6381,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.14.0", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.17.0.tgz", + "integrity": "sha512-fyU2yjGups/hE6Xz0I5ZYbVL8Gx29eCjgpHaRaTaVU+OOAdfRX05KsvyRm0GO8YQwOkhpU3MurW1jyMUJn+zSw==", "license": "MIT", "dependencies": { - "react-router": "7.14.0" + "react-router": "7.17.0" }, "engines": { "node": ">=20.0.0" @@ -6685,6 +6697,8 @@ }, "node_modules/set-cookie-parser": { "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", "license": "MIT" }, "node_modules/set-function-length": { diff --git a/package.json b/package.json index 1525380..b370fd2 100644 --- a/package.json +++ b/package.json @@ -20,16 +20,16 @@ "framer-motion": "^12.38.0", "i18next": "^26.3.0", "leaflet": "^1.9.4", - "lucide-react": "^1.16.0", + "lucide-react": "^1.17.0", "onnxruntime-web": "^1.26.0", "posthog-js": "^1.376.2", - "react": "^19.2.4", - "react-dom": "^19.2.4", + "react": "^19.2.7", + "react-dom": "^19.2.7", "react-hot-toast": "^2.6.0", "react-i18next": "^17.0.8", "react-joyride": "^3.1.0", "react-leaflet": "^5.0.0", - "react-router-dom": "^7.14.0", + "react-router-dom": "^7.17.0", "tailwindcss": "^4.2.2" }, "devDependencies": { diff --git a/src/index.css b/src/index.css index e1d1223..055a6c0 100644 --- a/src/index.css +++ b/src/index.css @@ -396,4 +396,25 @@ input::placeholder { @media print { nav, .print\:hidden { display: none !important; } +} +@keyframes shimmer { + 0% { + background-position: -200% 0; + } + + 100% { + background-position: 200% 0; + } +} + +.skeleton-shimmer { + background: linear-gradient( + 90deg, + var(--color-surface-mid) 25%, + var(--color-surface-highest) 50%, + var(--color-surface-mid) 75% + ); + + background-size: 200% 100%; + animation: shimmer 1.5s linear infinite; } \ No newline at end of file diff --git a/src/pages/AnalysisDashboard.tsx b/src/pages/AnalysisDashboard.tsx index 771227f..201c516 100644 --- a/src/pages/AnalysisDashboard.tsx +++ b/src/pages/AnalysisDashboard.tsx @@ -1,3 +1,4 @@ +console.log("ANALYSIS DASHBOARD LOADED"); import { useEffect, useState } from 'react'; import { Link, useSearchParams } from 'react-router-dom'; import { ArrowLeft, AlertTriangle, Droplets, Eye as EyeIcon, Fish } from 'lucide-react'; @@ -19,8 +20,40 @@ function gradeColor(grade: string) { if (grade === 'B') return 'text-neon'; return 'text-error'; } +function ScanSkeleton() { + return ( +
+
+ +
+
+
+
+ + +
+
+
+
+
+ +
+
+
+
+
+
+
+ + +
+
+
+ ); +} export default function AnalysisDashboard() { + const [params] = useSearchParams(); const [scan, setScan] = useState(null); const [loading, setLoading] = useState(true); @@ -43,20 +76,16 @@ export default function AnalysisDashboard() { } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load scan data.'); } finally { - setLoading(false); + setLoading(false); } } load(); }, [params]); // ── Loading state ──────────────────────────────────────────────────────── - if (loading) { - return ( -
- -
- ); - } +if (loading) { + return ; +} // ── Error state ────────────────────────────────────────────────────────── if (error || !scan) { From 7e20e05eb6201cfd6187de3868d5cdba371c7a79 Mon Sep 17 00:00:00 2001 From: kushwahnihal25-rgb Date: Wed, 10 Jun 2026 22:58:56 +0530 Subject: [PATCH 2/4] Remove debug log from analysis dashboard --- src/pages/AnalysisDashboard.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/AnalysisDashboard.tsx b/src/pages/AnalysisDashboard.tsx index 201c516..14b355b 100644 --- a/src/pages/AnalysisDashboard.tsx +++ b/src/pages/AnalysisDashboard.tsx @@ -1,4 +1,3 @@ -console.log("ANALYSIS DASHBOARD LOADED"); import { useEffect, useState } from 'react'; import { Link, useSearchParams } from 'react-router-dom'; import { ArrowLeft, AlertTriangle, Droplets, Eye as EyeIcon, Fish } from 'lucide-react'; From f037ae9683746e42f35ed61c0eae53a0b4460dc2 Mon Sep 17 00:00:00 2001 From: kushwahnihal25-rgb Date: Fri, 12 Jun 2026 12:29:49 +0530 Subject: [PATCH 3/4] Move ScanSkeleton to shared component --- src/components/shared/ScanSkeleton.tsx | 33 ++++++++++++++++++++++++++ src/pages/AnalysisDashboard.tsx | 32 +------------------------ 2 files changed, 34 insertions(+), 31 deletions(-) create mode 100644 src/components/shared/ScanSkeleton.tsx diff --git a/src/components/shared/ScanSkeleton.tsx b/src/components/shared/ScanSkeleton.tsx new file mode 100644 index 0000000..60559fd --- /dev/null +++ b/src/components/shared/ScanSkeleton.tsx @@ -0,0 +1,33 @@ +import GlassCard from "../GlassCard"; +export default function ScanSkeleton() { + return ( +
+
+ +
+
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+
+
+
+ + +
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/AnalysisDashboard.tsx b/src/pages/AnalysisDashboard.tsx index 14b355b..dd4eca6 100644 --- a/src/pages/AnalysisDashboard.tsx +++ b/src/pages/AnalysisDashboard.tsx @@ -5,6 +5,7 @@ import GlassCard from '../components/GlassCard'; import StatusTerminal from '../components/StatusTerminal'; import { api } from '../lib/api'; import type { ScanResult } from '../lib/types'; +import ScanSkeleton from "../components/shared/ScanSkeleton"; const BIOMARKER_META = { gill_saturation: { label: 'Gill Saturation', icon: Droplets }, @@ -19,38 +20,7 @@ function gradeColor(grade: string) { if (grade === 'B') return 'text-neon'; return 'text-error'; } -function ScanSkeleton() { - return ( -
-
- -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
-
-
-
- -
-
-
- ); -} export default function AnalysisDashboard() { const [params] = useSearchParams(); From 361b12a954e1c44a42788aed7897314357fa31b3 Mon Sep 17 00:00:00 2001 From: kushwahnihal25-rgb Date: Fri, 12 Jun 2026 17:56:31 +0530 Subject: [PATCH 4/4] Revert package files to upstream state --- package-lock.json | 117 +++++----------------------------------------- package.json | 8 ++-- 2 files changed, 15 insertions(+), 110 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0b47487..6d801e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,16 +12,16 @@ "framer-motion": "^12.38.0", "i18next": "^26.3.0", "leaflet": "^1.9.4", - "lucide-react": "^1.17.0", + "lucide-react": "^1.16.0", "onnxruntime-web": "^1.26.0", "posthog-js": "^1.376.2", - "react": "^19.2.7", - "react-dom": "^19.2.7", + "react": "^19.2.4", + "react-dom": "^19.2.4", "react-hot-toast": "^2.6.0", "react-i18next": "^17.0.8", "react-joyride": "^3.1.0", "react-leaflet": "^5.0.0", - "react-router-dom": "^7.17.0", + "react-router-dom": "^7.14.0", "tailwindcss": "^4.2.2" }, "devDependencies": { @@ -2150,9 +2150,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2169,9 +2166,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2188,9 +2182,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2207,9 +2198,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2226,9 +2214,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2245,9 +2230,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2526,9 +2508,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2543,9 +2522,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2560,9 +2536,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2577,9 +2550,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2594,9 +2564,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2611,9 +2578,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2628,9 +2592,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2645,9 +2606,6 @@ "ppc64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2662,9 +2620,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2679,9 +2634,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2696,9 +2648,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2713,9 +2662,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2730,9 +2676,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2942,9 +2885,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2961,9 +2901,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2980,9 +2917,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2999,9 +2933,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3856,8 +3787,6 @@ }, "node_modules/cookie": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", "license": "MIT", "engines": { "node": ">=18" @@ -5696,9 +5625,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -5719,9 +5645,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -5742,9 +5665,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -5765,9 +5685,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -5863,9 +5780,7 @@ } }, "node_modules/lucide-react": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.17.0.tgz", - "integrity": "sha512-9FA9evdox/JQL5PT57fdA1x/yg8T7knJ98+zjTL3UfKza6pflQUUh3XtaQIHKvnsJw1lmsEyHVlt5jchYxOQ5w==", + "version": "1.16.0", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -6254,24 +6169,20 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", - "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "version": "19.2.4", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", - "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "version": "19.2.4", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.7" + "react": "^19.2.4" } }, "node_modules/react-hot-toast": { @@ -6359,9 +6270,7 @@ } }, "node_modules/react-router": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.17.0.tgz", - "integrity": "sha512-FDELK7rTMlCHO5+reyXsPlmfr7N1F91lPHsWYfMEGQm/KQ+F4JFM8jGoeQDmDvdTs93Fw9aSilH+uKRb4/jXvQ==", + "version": "7.14.0", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -6381,12 +6290,10 @@ } }, "node_modules/react-router-dom": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.17.0.tgz", - "integrity": "sha512-fyU2yjGups/hE6Xz0I5ZYbVL8Gx29eCjgpHaRaTaVU+OOAdfRX05KsvyRm0GO8YQwOkhpU3MurW1jyMUJn+zSw==", + "version": "7.14.0", "license": "MIT", "dependencies": { - "react-router": "7.17.0" + "react-router": "7.14.0" }, "engines": { "node": ">=20.0.0" @@ -6697,8 +6604,6 @@ }, "node_modules/set-cookie-parser": { "version": "2.7.2", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", - "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", "license": "MIT" }, "node_modules/set-function-length": { diff --git a/package.json b/package.json index b370fd2..1525380 100644 --- a/package.json +++ b/package.json @@ -20,16 +20,16 @@ "framer-motion": "^12.38.0", "i18next": "^26.3.0", "leaflet": "^1.9.4", - "lucide-react": "^1.17.0", + "lucide-react": "^1.16.0", "onnxruntime-web": "^1.26.0", "posthog-js": "^1.376.2", - "react": "^19.2.7", - "react-dom": "^19.2.7", + "react": "^19.2.4", + "react-dom": "^19.2.4", "react-hot-toast": "^2.6.0", "react-i18next": "^17.0.8", "react-joyride": "^3.1.0", "react-leaflet": "^5.0.0", - "react-router-dom": "^7.17.0", + "react-router-dom": "^7.14.0", "tailwindcss": "^4.2.2" }, "devDependencies": {