'use client'; import { useState, useEffect } from 'react'; import Link from 'next/link'; import { useParams, useSearchParams } from 'next/navigation'; import { ArrowLeft, MessageSquare, ChevronDown, Loader2, GitCompareArrows, } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Separator } from '@/components/ui/separator'; import { Skeleton } from '@/components/ui/skeleton'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { cn } from '@/lib/utils'; interface Version { id: string; versionNumber: number; versionLabel: string | null; providerId: string; videoId: string; originalUrl: string; title: string | null; thumbnailUrl: string | null; duration: number | null; isActive: boolean; _count: { comments: number }; } interface VideoData { id: string; title: string; description: string | null; projectId: string; project: { name: string; }; versions: Version[]; } function getEmbedUrl(version: Version) { if (version.providerId === 'youtube') { return `https://www.youtube.com/embed/${version.videoId}?enablejsapi=1&rel=0&modestbranding=1`; } return version.originalUrl; } export default function CompareVersionsPage() { const params = useParams(); const searchParams = useSearchParams(); const projectId = params.projectId as string; const videoId = params.videoId as string; const [video, setVideo] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [leftVersionId, setLeftVersionId] = useState(null); const [rightVersionId, setRightVersionId] = useState(null); useEffect(() => { async function fetchVideo() { try { const res = await fetch(`/api/projects/${projectId}/videos/${videoId}`); if (!res.ok) { setError('Failed to load video'); setLoading(false); return; } const response = await res.json(); const data = response.data; setVideo(data); // Set initial versions from query params or defaults const leftParam = searchParams.get('left'); const rightParam = searchParams.get('right'); if (data.versions.length >= 2) { // Sort versions ascending for comparison (older on left, newer on right) const sorted = [...data.versions].sort( (a: Version, b: Version) => a.versionNumber - b.versionNumber ); setLeftVersionId( leftParam && sorted.find((v: Version) => v.id === leftParam) ? leftParam : sorted[sorted.length - 2].id ); setRightVersionId( rightParam && sorted.find((v: Version) => v.id === rightParam) ? rightParam : sorted[sorted.length - 1].id ); } else if (data.versions.length === 1) { setLeftVersionId(data.versions[0].id); setRightVersionId(data.versions[0].id); } } catch { setError('Failed to load video'); } finally { setLoading(false); } } fetchVideo(); }, [projectId, videoId, searchParams]); const leftVersion = video?.versions.find((v) => v.id === leftVersionId); const rightVersion = video?.versions.find((v) => v.id === rightVersionId); if (loading) { return (
{Array.from({ length: 2 }).map((_, i) => (
))}
); } if (error || !video || video.versions.length < 2) { return (

{error || 'Need at least 2 versions to compare'}

); } return (
{/* Header */}
Back to Video
Compare Versions • {video.title}
{/* Side-by-side comparison */}
{/* Left panel */}
{video.versions.map((v) => ( setLeftVersionId(v.id)} disabled={v.id === rightVersionId} > v{v.versionNumber} {v.versionLabel || `Version ${v.versionNumber}`} ))}
{leftVersion?._count.comments || 0} comments
{leftVersion && (