import Link from 'next/link'; import { API_BASE } from '../constants'; import NextVideoClient from './NextVideoClient'; interface VideoData { id: string; title: string; uploader: string; channel_id?: string; thumbnail: string; view_count: number; duration: string; } async function getRelatedVideos(videoId: string, title: string, uploader: string) { try { const params = new URLSearchParams({ v: videoId, title: title || '', uploader: uploader || '', limit: '15' }); const res = await fetch(`${API_BASE}/api/related?${params.toString()}`, { cache: 'no-store' }); if (!res.ok) return []; return res.json() as Promise; } catch (e) { console.error(e); return []; } } function formatViews(views: number): string { if (views >= 1000000) return (views / 1000000).toFixed(1) + 'M'; if (views >= 1000) return (views / 1000).toFixed(1) + 'K'; return views.toString(); } export default async function RelatedVideos({ videoId, title, uploader }: { videoId: string, title: string, uploader: string }) { const relatedVideos = await getRelatedVideos(videoId, title, uploader); if (relatedVideos.length === 0) { return
No related videos found.
; } const nextVideoId = relatedVideos[0].id; return (
{relatedVideos.map((video, i) => { const views = formatViews(video.view_count); const staggerClass = `stagger-${Math.min(i + 1, 6)}`; return (
{video.title} { const img = e.target as HTMLImageElement; if (img.src !== 'https://i.ytimg.com/vi/default/hqdefault.jpg') { img.src = 'https://i.ytimg.com/vi/default/hqdefault.jpg'; } }} /> {video.duration && (
{video.duration}
)}
{video.title} {video.uploader} {views} views
); })}
); }