import React, { useMemo, useState } from “react”;
import { Play, Search } from “lucide-react”;
const show = {
title: “Shia Voice”,
description:
“Watch Shia Voice episodes by season. Select a season, choose an episode, and play directly from YouTube.”,
heroImage:
“https://images.unsplash.com/photo-1485846234645-a62644f84728?q=80&w=1800&auto=format&fit=crop”,
seasons: [
{
seasonNumber: 1,
episodes: [
{
number: 1,
title: “Episode 1 Title”,
description: “Short episode description goes here.”,
thumbnail: “https://img.youtube.com/vi/YOUTUBE_VIDEO_ID_1/maxresdefault.jpg”,
youtubeUrl: “https://www.youtube.com/watch?v=YOUTUBE_VIDEO_ID_1”,
},
{
number: 2,
title: “Episode 2 Title”,
description: “Short episode description goes here.”,
thumbnail: “https://img.youtube.com/vi/YOUTUBE_VIDEO_ID_2/maxresdefault.jpg”,
youtubeUrl: “https://www.youtube.com/watch?v=YOUTUBE_VIDEO_ID_2”,
},
],
},
{
seasonNumber: 2,
episodes: [
{
number: 1,
title: “Episode 1 Title”,
description: “Short episode description goes here.”,
thumbnail: “https://img.youtube.com/vi/YOUTUBE_VIDEO_ID_3/maxresdefault.jpg”,
youtubeUrl: “https://www.youtube.com/watch?v=YOUTUBE_VIDEO_ID_3”,
},
],
},
],
};
function getEmbedUrl(youtubeUrl) {
const match = youtubeUrl.match(/(?:v=|youtu\.be\/|embed\/)([a-zA-Z0-9_-]{11})/);
return match ? `https://www.youtube.com/embed/${match[1]}` : youtubeUrl;
}
export default function ShiaVoiceEpisodes() {
const [selectedSeason, setSelectedSeason] = useState(show.seasons[0].seasonNumber);
const [selectedEpisode, setSelectedEpisode] = useState(show.seasons[0].episodes[0]);
const [search, setSearch] = useState(“”);
const currentSeason = show.seasons.find((season) => season.seasonNumber === selectedSeason);
const filteredEpisodes = useMemo(() => {
return currentSeason.episodes.filter((episode) => {
const text = `${episode.title} ${episode.description}`.toLowerCase();
return text.includes(search.toLowerCase());
});
}, [currentSeason, search]);
return (
<main className=”min-h-screen bg-neutral-950 text-white”>
<section
className=”relative min-h-[70vh] bg-cover bg-center”
style={{ backgroundImage: `url(${show.heroImage})` }}
>
<div className=”absolute inset-0 bg-gradient-to-r from-black via-black/75 to-black/20″ />
<div className=”relative z-10 flex min-h-[70vh] max-w-7xl flex-col justify-end px-6 py-12 md:px-12″>
<p className=”mb-3 text-sm font-semibold uppercase tracking-[0.3em] text-red-500″>
Imam Hussein TV
</p>
<h1 className=”mb-4 max-w-3xl text-5xl font-bold md:text-7xl”>{show.title}</h1>
<p className=”mb-8 max-w-2xl text-lg text-neutral-200 md:text-xl”>{show.description}</p>
<a
href={selectedEpisode.youtubeUrl}
target=”_blank”
rel=”noreferrer”
className=”inline-flex w-fit items-center gap-3 rounded-full bg-red-600 px-6 py-3 font-semibold text-white shadow-lg transition hover:bg-red-700″
>
<Play size={20} fill=”currentColor” /> Watch on YouTube
</a>
</div>
</section>
<section className=”mx-auto max-w-7xl px-6 py-10 md:px-12″>
<div className=”mb-8 grid gap-4 md:grid-cols-[220px_1fr]”>
<select
value={selectedSeason}
onChange={(event) => {
const seasonNumber = Number(event.target.value);
const season = show.seasons.find((item) => item.seasonNumber === seasonNumber);
setSelectedSeason(seasonNumber);
setSelectedEpisode(season.episodes[0]);
setSearch(“”);
}}
className=”rounded-xl border border-neutral-700 bg-neutral-900 px-4 py-3 text-white outline-none focus:border-red-500″
>
{show.seasons.map((season) => (
<option key={season.seasonNumber} value={season.seasonNumber}>
Season {season.seasonNumber}
</option>
))}
</select>
<label className=”flex items-center gap-3 rounded-xl border border-neutral-700 bg-neutral-900 px-4 py-3 focus-within:border-red-500″>
<Search size={20} className=”text-neutral-400″ />
<input
value={search}
onChange={(event) => setSearch(event.target.value)}
placeholder=”Search episodes…”
className=”w-full bg-transparent text-white outline-none placeholder:text-neutral-500″
/>
</label>
</div>
<div className=”mb-10 overflow-hidden rounded-2xl border border-neutral-800 bg-neutral-900 shadow-2xl”>
<div className=”aspect-video w-full bg-black”>
<iframe
key={selectedEpisode.youtubeUrl}
src={getEmbedUrl(selectedEpisode.youtubeUrl)}
title={selectedEpisode.title}
className=”h-full w-full”
allow=”accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share”
allowFullScreen
/>
</div>
<div className=”p-5 md:p-7″>
<p className=”mb-2 text-sm font-semibold text-red-500″>
Season {selectedSeason}, Episode {selectedEpisode.number}
</p>
<h2 className=”mb-2 text-2xl font-bold”>{selectedEpisode.title}</h2>
<p className=”text-neutral-300″>{selectedEpisode.description}</p>
</div>
</div>
<h2 className=”mb-5 text-2xl font-bold”>Episodes</h2>
<div className=”grid gap-5 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4″>
{filteredEpisodes.map((episode) => (
<button
key={`${selectedSeason}-${episode.number}`}
onClick={() => setSelectedEpisode(episode)}
className={`group overflow-hidden rounded-2xl border bg-neutral-900 text-left shadow-lg transition hover:-translate-y-1 hover:border-red-500 ${
selectedEpisode.number === episode.number
? “border-red-500 ring-2 ring-red-500/30”
: “border-neutral-800″
}`}
>
<div className=”relative aspect-video overflow-hidden bg-neutral-800″>
<img
src={episode.thumbnail}
alt={episode.title}
className=”h-full w-full object-cover transition duration-300 group-hover:scale-105″
/>
<div className=”absolute inset-0 flex items-center justify-center bg-black/25 opacity-0 transition group-hover:opacity-100″>
<span className=”rounded-full bg-red-600 p-4″>
<Play size={22} fill=”currentColor” />
</span>
</div>
</div>
<div className=”p-4″>
<p className=”mb-1 text-xs font-semibold uppercase tracking-wide text-neutral-400″>
Episode {episode.number}
</p>
<h3 className=”mb-2 line-clamp-2 font-semibold”>{episode.title}</h3>
<p className=”line-clamp-2 text-sm text-neutral-400″>{episode.description}</p>
</div>
</button>
))}
</div>
</section>
</main>
);
}