79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import { Play, Clock, ExternalLink } from 'lucide-react';
|
|
import { YoutubeIcon as Youtube } from '@/components/icons/YoutubeIcon';
|
|
import { VideoChapter } from '@/lib/data';
|
|
|
|
interface VideoPlayerProps {
|
|
youtubeId: string;
|
|
youtubeUrl: string;
|
|
title: string;
|
|
chapters?: VideoChapter[];
|
|
}
|
|
|
|
export function VideoPlayer({ youtubeId, youtubeUrl, title, chapters }: VideoPlayerProps) {
|
|
const [activeSeconds, setActiveSeconds] = useState(0);
|
|
|
|
const embedUrl = `https://www.youtube.com/embed/${youtubeId}?autoplay=0&start=${activeSeconds}`;
|
|
|
|
const handleChapterClick = (seconds: number) => {
|
|
setActiveSeconds(seconds);
|
|
};
|
|
|
|
return (
|
|
<div className="w-full space-y-4">
|
|
{/* Video Container */}
|
|
<div className="relative w-full aspect-video rounded-2xl overflow-hidden bg-slate-900 border border-slate-800 shadow-2xl group">
|
|
<iframe
|
|
src={embedUrl}
|
|
title={title}
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
allowFullScreen
|
|
className="w-full h-full border-0"
|
|
/>
|
|
</div>
|
|
|
|
{/* Chapters / Timestamps Quick Jumps */}
|
|
{chapters && chapters.length > 0 && (
|
|
<div className="bg-slate-900/80 p-4 rounded-xl border border-slate-800 space-y-3">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-xs font-bold text-slate-300 uppercase tracking-wider flex items-center gap-1.5">
|
|
<Clock className="w-3.5 h-3.5 text-red-400" />
|
|
Timestamped Chapters
|
|
</span>
|
|
<a
|
|
href={youtubeUrl}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="text-xs text-red-400 hover:text-red-300 flex items-center gap-1 font-medium transition-colors"
|
|
>
|
|
<span>Watch on YouTube</span>
|
|
<ExternalLink className="w-3 h-3" />
|
|
</a>
|
|
</div>
|
|
|
|
<div className="flex flex-wrap gap-2">
|
|
{chapters.map((chap) => (
|
|
<button
|
|
key={chap.time}
|
|
onClick={() => handleChapterClick(chap.seconds)}
|
|
className={`flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium transition-all ${
|
|
activeSeconds === chap.seconds
|
|
? 'bg-red-600 text-white shadow-md shadow-red-600/30 ring-1 ring-red-400'
|
|
: 'bg-slate-800/80 text-slate-300 hover:bg-slate-800 hover:text-white border border-slate-700/60'
|
|
}`}
|
|
>
|
|
<span className="font-mono text-[11px] text-red-400 font-bold bg-slate-950/60 px-1.5 py-0.5 rounded">
|
|
{chap.time}
|
|
</span>
|
|
<span>{chap.title}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|