|
'use client'; |
|
import { useState, useEffect, useRef } from 'react'; |
|
import './HeroSection.css'; |
|
import apiClient from '@/api/apiClient'; |
|
import SkeletonLoader from '@/skeletons/HeroSection'; |
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
|
import { faPlay } from '@fortawesome/free-solid-svg-icons'; |
|
import Link from 'next/link'; |
|
|
|
const HeroSection = () => { |
|
const [currentIndex, setCurrentIndex] = useState(0); |
|
const intervalRef = useRef(null); |
|
const [fadeOut, setFadeOut] = useState(false); |
|
const [items, setItems] = useState([]); |
|
const [loading, setLoading] = useState(true); |
|
|
|
useEffect(() => { |
|
const fetchRecentItems = async () => { |
|
try { |
|
const response = await apiClient.getRecent(); |
|
console.log(response); |
|
const movies = response.movies.map(film => ({ |
|
title: film[0], |
|
description: film[2], |
|
imageUrl: film[3], |
|
type: 'Movie' |
|
})); |
|
const series = response.series.map(serie => ({ |
|
title: serie[0], |
|
description: serie[2], |
|
imageUrl: serie[3], |
|
type: 'Series' |
|
})); |
|
setItems([...movies, ...series]); |
|
} catch (error) { |
|
console.error('Error fetching recent items:', error); |
|
} finally { |
|
setLoading(false); |
|
} |
|
}; |
|
|
|
fetchRecentItems(); |
|
}, []); |
|
|
|
const startAutoSwitch = () => { |
|
if (intervalRef.current) clearInterval(intervalRef.current); |
|
intervalRef.current = setInterval(() => { |
|
setFadeOut(true); |
|
setTimeout(() => { |
|
setCurrentIndex(prevIndex => (prevIndex + 1) % items.length); |
|
setFadeOut(false); |
|
}, 200); |
|
}, 5000); |
|
}; |
|
|
|
useEffect(() => { |
|
if (items.length > 0) { |
|
startAutoSwitch(); |
|
} |
|
|
|
return () => { |
|
clearInterval(intervalRef.current); |
|
}; |
|
}, [items]); |
|
|
|
const handleIndicatorClick = (index) => { |
|
setFadeOut(true); |
|
setTimeout(() => { |
|
setCurrentIndex(index); |
|
setFadeOut(false); |
|
}, 100); |
|
startAutoSwitch(); |
|
}; |
|
|
|
if (loading) { |
|
return <SkeletonLoader />; |
|
} |
|
|
|
const { title, description, imageUrl, type } = items[currentIndex]; |
|
const linkPath = `/${type.toLowerCase()}/${encodeURIComponent(title)}`; |
|
|
|
return ( |
|
<div className="hero-container"> |
|
<div className="hero-section"> |
|
{items.map((item, index) => ( |
|
<div |
|
key={index} |
|
className={`hero-image ${index === currentIndex ? 'active' : ''} ${fadeOut ? 'fade-out' : ''}`} |
|
style={{ backgroundImage: `linear-gradient(rgba(0, 0, 0, 0.1) 0%, #11121f 100%), url("${item.imageUrl}")` }} |
|
></div> |
|
))} |
|
<div className="hero-text"> |
|
<h1 className="hero-title">{title}</h1> |
|
<Link href={linkPath}> |
|
<button className="hero-section-play-button"> |
|
<FontAwesomeIcon icon={faPlay} size="lg" /> Play |
|
</button> |
|
</Link> |
|
<p className="hero-description">{description}</p> |
|
</div> |
|
</div> |
|
|
|
<div className="hero-indicators"> |
|
{items.map((_, index) => ( |
|
<div |
|
key={index} |
|
className={`indicator ${index === currentIndex ? 'active' : ''}`} |
|
onClick={() => handleIndicatorClick(index)} |
|
></div> |
|
))} |
|
</div> |
|
</div> |
|
); |
|
}; |
|
|
|
export default HeroSection; |
|
|