From 67237982c89f5904ca966d629338f4c1636601d5 Mon Sep 17 00:00:00 2001 From: "santasri.pachhal" Date: Wed, 24 Jun 2026 00:36:27 +0530 Subject: [PATCH] feat(results): add video results skeleton and refresh detection summary UI --- .../components/VideoResultsSkeleton.tsx | 105 ++++++++++++++++++ src/app/(modules)/results/[videoId]/page.tsx | 9 +- src/components/video/annotatedVideoPlayer.tsx | 2 +- src/components/video/currentDetectionBar.tsx | 82 +++++++++----- 4 files changed, 165 insertions(+), 33 deletions(-) create mode 100644 src/app/(modules)/results/[videoId]/components/VideoResultsSkeleton.tsx diff --git a/src/app/(modules)/results/[videoId]/components/VideoResultsSkeleton.tsx b/src/app/(modules)/results/[videoId]/components/VideoResultsSkeleton.tsx new file mode 100644 index 0000000..47e2de8 --- /dev/null +++ b/src/app/(modules)/results/[videoId]/components/VideoResultsSkeleton.tsx @@ -0,0 +1,105 @@ +'use client'; + +import { Skeleton } from '@/components/ui/skeleton'; + +function StatSkeleton() { + return ( +
+ + + +
+ ); +} + +function DetectionLogSkeleton() { + return ( +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ ); +} + +export function VideoResultsSkeleton() { + return ( +
+
+
+ +
+ + +
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+ +
+
+ {Array.from({ length: 3 }).map((_, index) => ( + + ))} +
+
+
+ +
+
+ +
+
+
+ {Array.from({ length: 5 }).map((_, index) => ( + + ))} +
+
+
+
+ +
+ {Array.from({ length: 5 }).map((_, index) => ( + + ))} +
+
+
+
+ ); +} diff --git a/src/app/(modules)/results/[videoId]/page.tsx b/src/app/(modules)/results/[videoId]/page.tsx index 2de7fda..55b77b9 100644 --- a/src/app/(modules)/results/[videoId]/page.tsx +++ b/src/app/(modules)/results/[videoId]/page.tsx @@ -2,13 +2,14 @@ import { useMemo } from 'react'; import { useParams, useRouter } from 'next/navigation'; -import { ArrowLeft, Loader2, TrendingUp } from 'lucide-react'; +import { ArrowLeft, TrendingUp } from 'lucide-react'; import VideoPlayerSection from '@/components/videoPlayerSection'; import { PageHeader } from '@/components/page-header'; import { Button } from '@/components/ui/button'; import { CompletedVideoResult, DetectionType } from '@/types'; import { getDetectionModeConfig } from '@/constants/detectionModeConfig'; import { useVideoResultsQuery } from '../hooks/useVideoResults'; +import { VideoResultsSkeleton } from './components/VideoResultsSkeleton'; const inferDetectionType = (data: CompletedVideoResult): DetectionType => { if (data.detection_mode) return data.detection_mode as DetectionType; @@ -50,11 +51,7 @@ export default function VideoResultsPage() { }; if (isLoading) { - return ( -
- -
- ); + return ; } if (error) { diff --git a/src/components/video/annotatedVideoPlayer.tsx b/src/components/video/annotatedVideoPlayer.tsx index b3066d8..027d04f 100644 --- a/src/components/video/annotatedVideoPlayer.tsx +++ b/src/components/video/annotatedVideoPlayer.tsx @@ -53,7 +53,7 @@ export default function AnnotatedVideoPlayer({ ) : ( <> -

+

{isLoading ? 'Loading annotated video...' : 'Preparing video...'}

diff --git a/src/components/video/currentDetectionBar.tsx b/src/components/video/currentDetectionBar.tsx index 371fb83..9f81cc5 100644 --- a/src/components/video/currentDetectionBar.tsx +++ b/src/components/video/currentDetectionBar.tsx @@ -1,7 +1,8 @@ 'use client'; -import { MapPin } from 'lucide-react'; -import { CompletedVideoResult, DetectionResultLog } from '@/types'; +import { Activity, AlertTriangle, MapPin, SignpostBig } from 'lucide-react'; + +import type { CompletedVideoResult, DetectionResultLog } from '@/types'; interface CurrentDetectionBarProps { activeLog?: DetectionResultLog; @@ -17,17 +18,23 @@ export default function CurrentDetectionBar({ { label: 'Potholes', value: currentCounts.unique_potholes || 0, + icon: AlertTriangle, className: 'text-orange-500', + iconClassName: 'bg-orange-500/10 text-orange-500', }, { label: 'Signboards', value: currentCounts.unique_signboards || 0, + icon: SignpostBig, className: 'text-blue-500', + iconClassName: 'bg-blue-500/10 text-blue-500', }, { label: 'Total', value: currentCounts.total_detections || 0, + icon: Activity, className: 'text-green-500', + iconClassName: 'bg-green-500/10 text-green-500', }, ]; const latitude = activeLog?.latitude; @@ -38,33 +45,56 @@ export default function CurrentDetectionBar({ : undefined; return ( -
- {coordinates && ( -
-
- - +
+
+
+

+ Current Detection Summary +

+

+ Counts update as the playback timeline moves. +

+
+ + {coordinates ? ( +
+ + Location + {coordinates}
-
- )} - -
- {countItems.map((item) => ( -
-

- {item.label} -

-

- {item.value} -

-
- ))} + ) : null}
-
+ +
+ {countItems.map((item) => { + const Icon = item.icon; + + return ( +
+
+ + + +

+ {item.label} +

+
+

+ {item.value} +

+
+ ); + })} +
+ ); }