118 lines
3.5 KiB
TypeScript
118 lines
3.5 KiB
TypeScript
"use client";
|
|
import { FC, useState } from "react";
|
|
import { MovieCard } from "@/components/atoms/MovieCard";
|
|
import { Movie } from "@/types/global";
|
|
import { useGlobalStore } from "@/app/store/globalStore";
|
|
import { Dropdown } from "@/components/atoms/Dropdown";
|
|
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
|
|
|
type Props = {
|
|
heading?: string;
|
|
overrideMovies?: Movie[];
|
|
|
|
filterSeen?: 0 | 1;
|
|
filterFavorites?: 0 | 1;
|
|
filterUpcoming?: 0 | 1;
|
|
filterReleased?: 0 | 1;
|
|
|
|
fluid?: boolean;
|
|
showFilters?: boolean;
|
|
sort?: "title" | "releaseDate" | "popularity";
|
|
sortDirection?: "asc" | "desc";
|
|
};
|
|
|
|
export const MovieList: FC<Props> = ({
|
|
heading,
|
|
overrideMovies,
|
|
filterSeen,
|
|
filterFavorites,
|
|
filterUpcoming,
|
|
filterReleased,
|
|
fluid = false,
|
|
showFilters = true,
|
|
sort = "releaseDate",
|
|
sortDirection = "asc",
|
|
}) => {
|
|
const { movies: storeMovies } = useGlobalStore();
|
|
const [filter, setFilter] = useState<"title" | "releaseDate" | "popularity">(
|
|
sort
|
|
);
|
|
const [parent] = useAutoAnimate();
|
|
|
|
const movies = overrideMovies || storeMovies;
|
|
|
|
const filteredMovies = movies.filter((movie) => {
|
|
let result = true;
|
|
const today = new Date();
|
|
if (filterSeen !== undefined) {
|
|
result = movie.seen === !!filterSeen;
|
|
}
|
|
if (filterFavorites !== undefined) {
|
|
result = result && movie.favorite === !!filterFavorites;
|
|
}
|
|
if (filterUpcoming !== undefined) {
|
|
const releaseDate = new Date(movie.release_date);
|
|
result =
|
|
result && filterUpcoming ? releaseDate > today : releaseDate < today;
|
|
}
|
|
if (filterReleased !== undefined) {
|
|
const releaseDate = new Date(movie.release_date);
|
|
result =
|
|
result && filterReleased ? releaseDate < today : releaseDate > today;
|
|
}
|
|
return result;
|
|
});
|
|
|
|
let sortedMovies = filteredMovies.sort((a, b) => {
|
|
if (filter === "title") return a.title.localeCompare(b.title);
|
|
if (filter === "releaseDate")
|
|
return (
|
|
new Date(b.release_date).getTime() - new Date(a.release_date).getTime()
|
|
);
|
|
if (filter === "popularity") return b.popularity - a.popularity;
|
|
return 0;
|
|
});
|
|
|
|
if (sortDirection === "desc") {
|
|
sortedMovies = sortedMovies.reverse();
|
|
}
|
|
|
|
return (
|
|
<section className="blocks">
|
|
<div className={`${fluid ? "max-w-full px-4" : "container"}`}>
|
|
{heading && (
|
|
<div className="row">
|
|
<div className="col-12 md:col-10 flex gap-2 items-center">
|
|
{showFilters && (
|
|
<Dropdown
|
|
items={[
|
|
{ label: "Tytuł", value: "title" },
|
|
{ label: "Data premiery", value: "releaseDate" },
|
|
{ label: "Popularność", value: "popularity" },
|
|
]}
|
|
defaultValue={filter}
|
|
callback={(value) => setFilter(value as "title")}
|
|
/>
|
|
)}
|
|
<h2 className="text-2xl font-bold">{heading}</h2>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{filteredMovies.length === 0 && (
|
|
<p className="text-text/60 text-sm">Brak filmów</p>
|
|
)}
|
|
{filteredMovies.length > 0 && (
|
|
<div
|
|
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-y-6 gap-3 sm:gap-6 mt-8 justify-center"
|
|
ref={parent}
|
|
>
|
|
{sortedMovies.map((movie) => (
|
|
<MovieCard key={movie.id} layout="aurora" {...movie} />
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|