web / frontend /src /components /EpisodesPanel.tsx
Chandima Prabhath
Track bun.lockb with Git LFS
cc2caf9
raw
history blame
4.06 kB
import React from 'react';
import { Check, Play, X } from 'lucide-react';
interface Episode {
episode_number: number;
name: string;
fileName?: string;
}
interface Season {
season_number: number;
name: string;
episodes: Episode[];
}
interface PlaybackProgress {
[key: string]: {
currentTime: number;
duration: number;
lastPlayed: string;
completed: boolean;
};
}
interface EpisodesPanelProps {
seasons: Season[];
selectedSeason: string;
selectedEpisode: string;
playbackProgress: PlaybackProgress;
onSelectEpisode: (seasonName: string, episode: Episode) => void;
onClose: () => void;
showTitle?: string;
}
const EpisodesPanel: React.FC<EpisodesPanelProps> = ({
seasons,
selectedSeason,
selectedEpisode,
playbackProgress,
onSelectEpisode,
onClose,
showTitle = 'Episodes'
}) => {
// Helper function to get episode progress
const getEpisodeProgress = (seasonName: string, episodeFileName: string) => {
const episodeId = `${seasonName}-${episodeFileName}`;
return playbackProgress[episodeId] || null;
};
return (
<div className="h-full flex flex-col">
<div className="p-6 flex justify-between items-center border-b border-gray-800">
<h2 className="text-2xl font-bold text-white">{showTitle}</h2>
<button
onClick={onClose}
className="text-white hover:text-gray-300 transition-colors"
aria-label="Close episodes panel"
>
<X className="h-6 w-6" />
</button>
</div>
<div className="flex-1 overflow-y-auto p-6 space-y-8">
{seasons.map((season) => (
<div key={season.name} className="mb-6">
<h3 className="text-xl font-bold mb-3 text-white">{season.name}</h3>
<div className="space-y-2">
{season.episodes.map((episode) => {
const progress = getEpisodeProgress(season.name, episode.fileName || '');
const progressPercent = progress
? Math.min(100, Math.floor((progress.currentTime / progress.duration) * 100))
: 0;
return (
<div
key={episode.fileName}
className={`p-3 rounded-md flex items-start hover:bg-gray-800 cursor-pointer transition-colors ${selectedEpisode === episode.fileName ? 'bg-gray-800' : 'bg-gray-900/60'}`}
onClick={() => onSelectEpisode(season.name, episode)}
>
<div className="flex-shrink-0 mr-3">
{selectedEpisode === episode.fileName ? (
<div className="w-4 h-4 rounded-full bg-red-600 flex items-center justify-center">
<Play size={8} className="text-white ml-0.5" />
</div>
) : (
<div className="w-4 h-4 rounded-full bg-gray-700 flex items-center justify-center">
<span className="text-xs text-white">{episode.episode_number}</span>
</div>
)}
</div>
<div className="flex-1">
<div className="flex justify-between">
<h4 className="font-medium text-white">{episode.name}</h4>
{progress?.completed && (
<Check size={16} className="text-green-500" />
)}
</div>
<div className="relative w-full h-1 bg-gray-700 mt-2 rounded overflow-hidden">
<div
className="absolute left-0 top-0 h-full bg-red-600"
style={{ width: `${progressPercent}%` }}
/>
</div>
</div>
</div>
);
})}
</div>
</div>
))}
</div>
</div>
);
};
export default EpisodesPanel;