'use client'; import { useEffect, useRef } from 'react'; import { Activity, Film, ImageIcon, MapPin } from 'lucide-react'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Skeleton } from '@/components/ui/skeleton'; import { useProtectedMediaObjectUrl } from '@/hooks/useProtectedMedia'; import { cn } from '@/lib/utils'; import type { DetectionResultLog } from '@/types'; interface DetectionLogsProps { logs: DetectionResultLog[]; activeLogId?: string; onSelect: (log: DetectionResultLog) => void; } const formatVideoTime = (seconds: number) => { const safeSeconds = Number.isFinite(seconds) ? seconds : 0; const minutes = Math.floor(safeSeconds / 60); const secs = Math.floor(safeSeconds % 60); return `${minutes}:${secs.toString().padStart(2, '0')}`; }; function DetectionLogThumbnail({ url, label, }: { url?: string | null; label: string; }) { const { objectUrl, isLoading, isError } = useProtectedMediaObjectUrl(url); if (!url) { return (
); } if (isLoading) { return ; } if (isError || !objectUrl) { return (
N/A
); } return (
{label}
); } const DetectionLogs = ({ logs, activeLogId, onSelect }: DetectionLogsProps) => { const activeLogRef = useRef(null); useEffect(() => { activeLogRef.current?.scrollIntoView({ block: 'nearest', behavior: 'smooth', }); }, [activeLogId]); return (

Detection Logs

{logs.length === 0 ? (

No detections found

) : ( logs.map((log) => { const timestampSeconds = log.frame.timestamp_seconds; const { latitude, longitude } = log.location; const isActive = activeLogId === log.id; const label = log.detection.display_name; return ( ); }) )}
); }; export default DetectionLogs;