/** * VideoList Component * * A reusable component for displaying a list/grid of videos with filtering, sorting, and pagination. */ import React, { useState, useEffect } from 'react'; import { type VideoListProps, type VideoListFilters, type VideoListSortOptions } from '../types'; import { useVideoList } from '../hooks/useVideoList'; import { VideoCard } from './VideoCard'; import { Pagination, PageInfo } from './Pagination'; export const VideoList: React.FC = ({ filters, sortOptions, limit = 20, onVideoSelect, className = '', }) => { const [localFilters, setLocalFilters] = useState(filters || {}); const [localSort, setLocalSort] = useState( sortOptions || { field: 'created_at', direction: 'desc' } ); const { videos, totalCount, currentPage, totalPages, loading, error, refetch, loadMore, hasMore, goToPage, nextPage, previousPage, updateFilters, updateSort, } = useVideoList({ initialParams: { camera_name: localFilters.cameraName, start_date: localFilters.dateRange?.start, end_date: localFilters.dateRange?.end, limit, include_metadata: true, page: 1, // Start with page 1 }, autoFetch: true, }); // Update filters when props change (without causing infinite loops) useEffect(() => { if (filters) { setLocalFilters(filters); } }, [filters]); // Update sort when props change (without causing infinite loops) useEffect(() => { if (sortOptions) { setLocalSort(sortOptions); } }, [sortOptions]); const handleVideoClick = (video: any) => { if (onVideoSelect) { onVideoSelect(video); } }; const handleLoadMore = () => { if (hasMore && loading !== 'loading') { loadMore(); } }; const containerClasses = [ 'video-list', className, ].filter(Boolean).join(' '); if (loading === 'loading' && videos.length === 0) { return (

Loading videos...

); } if (error) { return (

Error Loading Videos

{error.message}

); } if (videos.length === 0) { return (

No Videos Found

No videos match your current filters.

); } return (
{/* Top Pagination */} {totalPages > 1 && (
{/* Page Info */} {/* Pagination Controls */}
)} {/* Results Summary */}
{totalPages > 0 ? ( <>Showing page {currentPage} of {totalPages} ({totalCount} total videos) ) : ( <>Showing {videos.length} of {totalCount} videos )}
{/* Video Grid */}
{videos.map((video) => ( ))}
{/* Bottom Pagination */} {totalPages > 1 && videos.length > 0 && (
{/* Page Info */} {/* Pagination Controls */}
)} {/* Loading Indicator */} {loading === 'loading' && (
Loading videos...
)}
); };