diff --git a/src/components/MoviesPage/MoviesPage.tsx b/src/components/MoviesPage/MoviesPage.tsx
index fa75a8c..06cb412 100644
--- a/src/components/MoviesPage/MoviesPage.tsx
+++ b/src/components/MoviesPage/MoviesPage.tsx
@@ -1,11 +1,9 @@
import { Badge, Button, Card, Image, Text } from '@mantine/core';
-import { useEffect, useState } from 'react';
+import { useState } from 'react';
import { Link } from 'react-router-dom';
import { MoviesFilter } from '../../@types/MovieState';
-import MovieType from '../../@types/MovieType';
-import { getMovieById } from '../../apiHandler/api';
import no_poster from '../../assets/no-poster.webp';
-import { useGetMoviesByFilterQuery } from '../../features/moviesApiSlice';
+import { useGetMoviesByFilterQuery, useGetMoviesDetailsQuery } from '../../features/moviesApiSlice';
import { useAppSelector } from '../../store/hooks';
import ButtonAddToPlaylist from '../ui/ButtonAddToPlaylist/ButtonAddToPlaylist';
import Loader from '../ui/Loader/Loader';
@@ -26,50 +24,25 @@ const truncateTextWithSlice = (text: string, maxLength: number) =>
function MoviesPage({ title, filter }: { title: string; filter: MoviesFilter }) {
const { data: movieList } = useGetMoviesByFilterQuery(filter);
const logged = useAppSelector((state) => state.settings.user.logged);
- const [detailedMovies, setDetailedMovies] = useState
([]);
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
- const [loading, setLoading] = useState(true);
-
- useEffect(() => {
- async function fetchDetails() {
- if (!movieList || movieList.length === 0) {
- return;
- }
- setLoading(true);
- // impossible to use RTK Query here
- const promisesList = movieList.map((movie) =>
- getMovieById(movie.tmdb_id.toString())
- .then((response) => ({ ...movie, ...response.data.data }))
- .catch((error) => {
- // eslint-disable-next-line no-console
- console.error(`Error fetching details for movie ${movie.tmdb_id}:`, error);
- })
- );
- try {
- const results = await Promise.all(promisesList);
- setDetailedMovies(results);
- } catch (error) {
- // eslint-disable-next-line no-console
- console.error('Error fetching movie details:', error);
- } finally {
- setLoading(false);
- }
- }
- fetchDetails();
- }, [movieList]);
-
- const sortedMovieList = detailedMovies.slice().sort((a, b) => {
- if (sortOrder === 'asc') {
- return new Date(a.release_date).getTime() - new Date(b.release_date).getTime();
- }
- return new Date(b.release_date).getTime() - new Date(a.release_date).getTime();
+ const { data: detailedMovies, isLoading } = useGetMoviesDetailsQuery(movieList || [], {
+ skip: !movieList || movieList.length === 0,
});
+ const sortedMovieList = detailedMovies?.length
+ ? detailedMovies.slice().sort((a, b) => {
+ if (sortOrder === 'asc') {
+ return new Date(a.release_date).getTime() - new Date(b.release_date).getTime();
+ }
+ return new Date(b.release_date).getTime() - new Date(a.release_date).getTime();
+ })
+ : [];
+
const toggleSortOrder = () => {
setSortOrder((prevSortOrder) => (prevSortOrder === 'asc' ? 'desc' : 'asc'));
};
- return loading ? (
+ return isLoading ? (
diff --git a/src/features/moviesApiSlice.ts b/src/features/moviesApiSlice.ts
index 05f1e7c..ac84ad7 100644
--- a/src/features/moviesApiSlice.ts
+++ b/src/features/moviesApiSlice.ts
@@ -37,6 +37,24 @@ export const moviesApiSlice = apiSlice.enhanceEndpoints({ addTagTypes: ['MovieUs
query: (filter: MoviesFilter) => ({
url: `/movie/${filter}`,
}),
+ async onQueryStarted(_params, { dispatch, queryFulfilled }) {
+ // Prefetch all movies of the list
+ const { data: movies } = await queryFulfilled;
+ movies.forEach((movie: MovieType) => {
+ dispatch(moviesApiSlice.endpoints.getMovieById.initiate(movie.tmdb_id.toString()));
+ });
+ },
+ }),
+ getMoviesDetails: builder.query({
+ // Fetch all movies of the list
+ async queryFn(movieList: MovieType[], { dispatch }): Promise<{ data: MovieType[] }> {
+ const detailPromises = movieList.map((movie) =>
+ dispatch(moviesApiSlice.endpoints.getMovieById.initiate(movie.tmdb_id.toString()))
+ );
+ const results = await Promise.all(detailPromises);
+ const data = results.map((result) => result.data).filter((movie): movie is MovieType => !!movie);
+ return { data };
+ },
}),
getGenres: builder.query({
query: () => ({
@@ -195,6 +213,7 @@ export const {
useGetUserdataMovieByIdQuery,
useGetMoviesByParamsQuery,
useGetMoviesByFilterQuery,
+ useGetMoviesDetailsQuery,
useGetGenresQuery,
useSearchMoviesQuery,
usePostReviewMutation,