1+ "use client" ;
2+
3+ import { useEffect , useMemo , useState } from "react" ;
14import Image from "next/image" ;
25import Link from "next/link" ;
36import { Play , Star , Info } from "lucide-react" ;
@@ -7,19 +10,49 @@ import type { MediaItem } from "@/types/tmdb";
710import { backdropUrl } from "@/lib/tmdb" ;
811import ExpandableOverview from "@/components/ExpandableOverview" ;
912
10- export default function Hero ( { item } : { item : MediaItem } ) {
11- const backdrop = backdropUrl ( item . backdrop_path ) ;
13+ interface HeroProps {
14+ items : MediaItem [ ] ;
15+ }
16+
17+ export default function Hero ( { items } : HeroProps ) {
18+ const [ activeIndex , setActiveIndex ] = useState ( 0 ) ;
19+
20+ const safeItems = useMemo (
21+ ( ) => items . filter ( ( item ) => Boolean ( item ?. id ) ) ,
22+ [ items ] ,
23+ ) ;
24+
25+ useEffect ( ( ) => {
26+ if ( safeItems . length <= 1 ) return ;
27+
28+ const intervalId = window . setInterval ( ( ) => {
29+ setActiveIndex ( ( previousIndex ) => ( previousIndex + 1 ) % safeItems . length ) ;
30+ } , 15000 ) ;
31+
32+ return ( ) => window . clearInterval ( intervalId ) ;
33+ } , [ safeItems . length ] ) ;
34+
35+ const normalizedIndex =
36+ safeItems . length > 0 ? activeIndex % safeItems . length : 0 ;
37+ const activeItem = safeItems [ normalizedIndex ] ;
38+ if ( ! activeItem ) return null ;
39+
40+ const backdrop = backdropUrl ( activeItem . backdrop_path ) ;
1241 const detailHref =
13- item . media_type === "tv" ? `/tv/${ item . id } ` : `/movie/${ item . id } ` ;
42+ activeItem . media_type === "tv"
43+ ? `/tv/${ activeItem . id } `
44+ : `/movie/${ activeItem . id } ` ;
1445 const watchHref =
15- item . media_type === "tv" ? `/watch/tv/${ item . id } ` : `/watch/${ item . id } ` ;
46+ activeItem . media_type === "tv"
47+ ? `/watch/tv/${ activeItem . id } `
48+ : `/watch/${ activeItem . id } ` ;
1649
1750 return (
1851 < section className = "relative w-full h-[70vh] sm:h-[80vh] overflow-hidden" >
1952 { backdrop && (
2053 < Image
2154 src = { backdrop }
22- alt = { item . title }
55+ alt = { activeItem . title }
2356 fill
2457 priority
2558 className = "object-cover object-top"
@@ -40,20 +73,20 @@ export default function Hero({ item }: { item: MediaItem }) {
4073 >
4174 Trending
4275 </ Badge >
43- { item . media_type === "tv" && (
76+ { activeItem . media_type === "tv" && (
4477 < Badge className = "bg-accent-red/90 text-white text-xs uppercase tracking-wider hover:bg-accent-red/80" >
4578 TV Series
4679 </ Badge >
4780 ) }
4881 < div className = "flex items-center gap-1 text-accent-red" >
4982 < Star className = "h-4 w-4 fill-accent-red" />
5083 < span className = "text-sm font-semibold" >
51- { item . vote_average . toFixed ( 1 ) }
84+ { activeItem . vote_average . toFixed ( 1 ) }
5285 </ span >
5386 </ div >
54- { item . date && (
87+ { activeItem . date && (
5588 < span className = "text-sm text-muted-foreground" >
56- { new Date ( item . date ) . getFullYear ( ) }
89+ { new Date ( activeItem . date ) . getFullYear ( ) }
5790 </ span >
5891 ) }
5992 </ div >
@@ -62,11 +95,11 @@ export default function Hero({ item }: { item: MediaItem }) {
6295 className = "text-4xl sm:text-5xl lg:text-6xl font-bold tracking-tight leading-none"
6396 style = { { fontFamily : "var(--font-heading)" } }
6497 >
65- { item . title }
98+ { activeItem . title }
6699 </ h1 >
67100
68101 < ExpandableOverview
69- text = { item . overview }
102+ text = { activeItem . overview }
70103 fontKey = "body"
71104 fontSize = { 16 }
72105 containerWidth = { 576 }
0 commit comments