Files
moviebox/src/components/molecules/RandomMovie/index.tsx
2025-11-09 11:10:27 +01:00

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',
};