136 lines
4.0 KiB
TypeScript
136 lines
4.0 KiB
TypeScript
'use client';
|
|
import { FC, useMemo, useState } from 'react';
|
|
import { Button } from '@/components/atoms/Button';
|
|
import { FaDice } from 'react-icons/fa';
|
|
import { useGlobalStore } from '@/app/store/global';
|
|
import Link from 'next/link';
|
|
|
|
type StoreFilter = 'all' | 'not_seen' | 'released' | 'favorites' | 'to_watch';
|
|
|
|
type Props = {
|
|
heading?: string;
|
|
storeFilter?: StoreFilter;
|
|
colors?: keyof typeof colorsMap;
|
|
className?: string;
|
|
};
|
|
|
|
export const RandomMovie: FC<Props> = ({
|
|
heading = 'Losowy film',
|
|
storeFilter = 'not_seen',
|
|
colors = 'purple',
|
|
className = '',
|
|
}) => {
|
|
const movies = useGlobalStore(state => state.movies);
|
|
const [selectedMovie, setSelectedMovie] = useState<Movie | null>(null);
|
|
|
|
// Filter movies based on the selected store filter.
|
|
const filteredMovies = useMemo(() => {
|
|
const today = new Date();
|
|
|
|
return movies.filter(movie => {
|
|
switch (storeFilter) {
|
|
case 'not_seen':
|
|
return !movie.seen;
|
|
case 'released':
|
|
return new Date(movie.release_date) < today;
|
|
case 'favorites':
|
|
return movie.favorite;
|
|
case 'to_watch':
|
|
return !movie.seen && new Date(movie.release_date) < today;
|
|
case 'all':
|
|
default:
|
|
return true;
|
|
}
|
|
});
|
|
}, [movies, storeFilter]);
|
|
|
|
const handleRandomize = () => {
|
|
if (filteredMovies.length === 0) return;
|
|
|
|
const randomIndex = Math.floor(Math.random() * filteredMovies.length);
|
|
const randomMovie = filteredMovies[randomIndex];
|
|
|
|
setSelectedMovie(randomMovie);
|
|
};
|
|
|
|
if (filteredMovies.length === 0) {
|
|
return (
|
|
<section className={`blocks ${className}`}>
|
|
<div className="container">
|
|
{heading && (
|
|
<div className="flex items-center gap-3 mb-6">
|
|
<div className={`p-2 rounded-lg ${colorsMap[colors]}`}>
|
|
<FaDice className="text-white" />
|
|
</div>
|
|
<h2
|
|
className={`text-3xl font-bold ${colorsMap[colors]} bg-clip-text text-transparent`}
|
|
>
|
|
{heading}
|
|
</h2>
|
|
</div>
|
|
)}
|
|
<div className="text-center py-12">
|
|
<p className="text-text/60 text-lg">Brak filmów w kategorii</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<section className={`blocks ${className}`}>
|
|
<div className="container">
|
|
{heading && (
|
|
<div className="flex justify-center mb-6">
|
|
<h2
|
|
className={`text-3xl font-bold ${colorsMap[colors]} bg-clip-text text-transparent`}
|
|
>
|
|
{heading}
|
|
</h2>
|
|
</div>
|
|
)}
|
|
|
|
<div className="text-center mb-4">
|
|
<p className="text-text/70 text-sm">
|
|
Dostępnych {filteredMovies.length} filmów
|
|
</p>
|
|
</div>
|
|
<div className="flex justify-center">
|
|
<Button
|
|
size="small"
|
|
theme="secondary"
|
|
onClick={handleRandomize}
|
|
className="flex items-center gap-2"
|
|
>
|
|
<FaDice />
|
|
Losuj film
|
|
</Button>
|
|
</div>
|
|
|
|
{selectedMovie && (
|
|
<div className="text-center mt-4">
|
|
<h3 className="text-2xl font-bold">
|
|
<Link href={`/film/${selectedMovie.id}`}>
|
|
{selectedMovie.title}
|
|
</Link>
|
|
</h3>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
const colorsMap = {
|
|
white: 'bg-gradient-to-r from-white to-gray-300',
|
|
yellow: 'bg-gradient-to-r from-yellow-400 to-orange-400',
|
|
blue: 'bg-gradient-to-r from-blue-400 to-purple-400',
|
|
green: 'bg-gradient-to-r from-green-400 to-teal-400',
|
|
red: 'bg-gradient-to-r from-red-400 to-pink-400',
|
|
purple: 'bg-gradient-to-r from-purple-400 to-pink-400',
|
|
orange: 'bg-gradient-to-r from-orange-400 to-yellow-400',
|
|
pink: 'bg-gradient-to-r from-pink-400 to-purple-400',
|
|
teal: 'bg-gradient-to-r from-teal-400 to-green-400',
|
|
gray: 'bg-gradient-to-r from-gray-400 to-gray-400',
|
|
};
|