From 6c316fbf84d02f41ddad8586a37565bf2da7b8d1 Mon Sep 17 00:00:00 2001 From: Lars Behrends Date: Sat, 11 Apr 2026 01:27:58 +0200 Subject: [PATCH] Update DetailView.tsx --- src/components/DetailView.tsx | 113 +++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 22 deletions(-) diff --git a/src/components/DetailView.tsx b/src/components/DetailView.tsx index cbf4872..96d6ff9 100644 --- a/src/components/DetailView.tsx +++ b/src/components/DetailView.tsx @@ -1,6 +1,6 @@ import { Media, Staff } from '@/types'; import { useNavigate } from 'react-router-dom'; -import { useState } from 'react'; +import { useState, useMemo, useEffect } from 'react'; import { Play, Bookmark, @@ -27,6 +27,44 @@ export default function DetailView({ media, onPersonClick }: DetailViewProps) { const navigate = useNavigate(); const [castLimit, setCastLimit] = useState(6); const [showAllCast, setShowAllCast] = useState(false); + const [expandedSeasons, setExpandedSeasons] = useState>(new Set()); + + // Group episodes by season + const episodesBySeason = useMemo(() => { + if (!media.episodes) return {}; + const grouped: Record = {}; + media.episodes.forEach(episode => { + if (!grouped[episode.season]) { + grouped[episode.season] = []; + } + grouped[episode.season].push(episode); + }); + // Sort episodes within each season by episode number + Object.keys(grouped).forEach(season => { + grouped[Number(season)].sort((a, b) => a.episode_number - b.episode_number); + }); + return grouped; + }, [media.episodes]); + + // Expand first season by default on mount + useEffect(() => { + const seasons = Object.keys(episodesBySeason).map(Number).sort((a, b) => a - b); + if (seasons.length > 0) { + setExpandedSeasons(new Set([seasons[0]])); + } + }, [episodesBySeason]); + + const toggleSeason = (season: number) => { + setExpandedSeasons(prev => { + const newSet = new Set(prev); + if (newSet.has(season)) { + newSet.delete(season); + } else { + newSet.add(season); + } + return newSet; + }); + }; const displayedCast = showAllCast ? media.staff : (media.staff?.slice(0, castLimit) || []); const hasMoreCast = (media.staff?.length || 0) > castLimit; @@ -254,6 +292,9 @@ export default function DetailView({ media, onPersonClick }: DetailViewProps) {
{media.episodes.length} Episode{media.episodes.length !== 1 ? 's' : ''}
+
+ {Object.keys(episodesBySeason).length} Season{Object.keys(episodesBySeason).length !== 1 ? 's' : ''} +
@@ -269,29 +310,57 @@ export default function DetailView({ media, onPersonClick }: DetailViewProps) {
-
- {media.episodes.map(episode => ( -
-
-
- {episode.title} -
-
-
-
-

- S{episode.season}:E{episode.episode_number} • {episode.title} -

- {episode.air_date} • {episode.duration}m +
+ {Object.keys(episodesBySeason) + .map(Number) + .sort((a, b) => a - b) + .map(season => ( +
+
+ + + {expandedSeasons.has(season) && ( +
+ {episodesBySeason[season].map(episode => ( +
+
+
+ {episode.title} +
+
+
+
+

+ E{episode.episode_number} • {episode.title} +

+ {episode.air_date} • {episode.duration}m +
+

+ {episode.description} +

+
+
+ +
+ ))} +
+ )}
- -
- ))} + ))}
)}