nextav/src/app/videos/page.tsx

94 lines
2.6 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Header } from "@/components/ui/header";
interface Video {
id: number;
title: string;
path: string;
size: number;
thumbnail: string;
}
const VideosPage = () => {
const [videos, setVideos] = useState<Video[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchVideos();
}, []);
const fetchVideos = async () => {
try {
const res = await fetch("/api/videos");
const data = await res.json();
setVideos(data);
} catch (error) {
console.error('Error fetching videos:', error);
} finally {
setLoading(false);
}
};
const formatFileSize = (bytes: number) => {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
if (loading) {
return (
<div className="flex items-center justify-center h-full">
<div className="text-lg">Loading videos...</div>
</div>
);
}
return (
<div className="p-6">
<Header title="Videos" />
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6">
{videos.map((video) => (
<Card key={video.id} className="overflow-hidden rounded-lg shadow-lg hover:shadow-xl transition-shadow duration-300 ease-in-out">
<CardContent className="p-0">
<img
src={video.thumbnail || "/placeholder.svg"}
alt={video.title}
className="w-full h-48 object-cover"
onError={(e) => {
(e.target as HTMLImageElement).src = '/placeholder.svg';
}}
/>
</CardContent>
<CardHeader className="p-4">
<CardTitle className="text-sm font-semibold truncate">{video.title}</CardTitle>
<CardDescription className="text-xs">
<span className="block">Size: {formatFileSize(video.size)}</span>
<span className="block truncate">Path: {video.path}</span>
</CardDescription>
</CardHeader>
</Card>
))}
</div>
{videos.length === 0 && (
<div className="text-center py-12">
<p className="text-gray-500">No videos found. Add media libraries to scan for videos.</p>
</div>
)}
</div>
);
};
export default VideosPage;