movie-explorer/src/objects/movie-wall.tsx

99 lines
3.7 KiB
TypeScript
Raw Normal View History

2024-05-07 16:58:39 +00:00
import React, { useState } from "react"
2024-05-06 09:09:21 +00:00
import { Config } from "../App"
import tmdb from "./tmdb"
2024-05-02 20:47:28 +00:00
2024-05-07 11:09:48 +00:00
export interface Movie {
id: number | null
poster_path: string | null
backdrop_path: string | null
title: string | null
overview: string | null
vote_average: number | null
2024-05-02 20:47:28 +00:00
}
2024-05-07 11:09:48 +00:00
2024-05-23 13:54:06 +00:00
// const sampleData = {
// adult: false,
// backdrop_path: "/jnE1GA7cGEfv5DJBoU2t4bZHaP4.jpg",
// genre_ids: [28, 878],
// id: 1094844,
// original_language: "en",
// original_title: "Ape vs. Mecha Ape",
// overview: "Recognizing the destructive power of its captive giant Ape, the military makes its own battle-ready A.I., Mecha Ape. But its first practical test goes horribly wrong, leaving the military no choice but to release the imprisoned giant ape to stop the colossal robot before it destroys downtown Chicago.",
// popularity: 2157.099,
// poster_path: "/dJaIw8OgACelojyV6YuVsOhtTLO.jpg",
// release_date: "2023-03-24",
// title: "Ape vs. Mecha Ape",
// video: false,
// vote_average: 5.538,
// vote_count: 52
// }
2024-05-02 20:47:28 +00:00
2024-05-05 21:59:33 +00:00
interface MovieWallProps extends React.ComponentPropsWithRef<"div"> {
movies: Array<Movie>;
2024-05-23 14:43:10 +00:00
setMovies: React.Dispatch<React.SetStateAction<any>>;
setChosenMovie: React.Dispatch<React.SetStateAction<any>>;
setSimilarMoviesAvailable: React.Dispatch<React.SetStateAction<boolean>>;
2024-05-06 09:09:21 +00:00
config: Config;
2024-10-05 15:16:08 +00:00
className: string
2024-05-05 21:59:33 +00:00
}
2024-10-05 15:16:08 +00:00
export function MovieWall({ movies, setMovies, config, setChosenMovie, setSimilarMoviesAvailable, className }: MovieWallProps) {
2024-05-05 21:59:33 +00:00
2024-05-23 14:43:10 +00:00
const posters: React.ReactElement[] = []
2024-05-02 20:47:28 +00:00
for (let i = 0; i < movies.length; i++) {
const movie = movies[i]
const isHighlighted = movie.vote_average ? movie.vote_average > 6 : false
2024-05-02 20:47:28 +00:00
posters.push(
2024-10-05 15:25:55 +00:00
<Poster className="w-36 h-58 rounded-xl overflow-hidden flex justify-center relative" isHighlighted={isHighlighted} movie={movie} key={movie.id} index={i}
2024-05-23 14:43:10 +00:00
listSimilar={tmdb.getSimilar}
config={config}
setMovies={setMovies}
setChosenMovie={setChosenMovie}
setSimilarMoviesAvailable={setSimilarMoviesAvailable} />
2024-05-02 20:47:28 +00:00
)
}
2024-10-05 15:16:08 +00:00
return <div className={className}>
2024-05-02 20:47:28 +00:00
{posters}
2024-10-05 15:16:08 +00:00
</div>
2024-05-02 20:47:28 +00:00
}
2024-05-05 21:59:33 +00:00
interface PosterProps extends React.ComponentPropsWithRef<"div"> {
2024-05-02 20:47:28 +00:00
movie: Movie;
2024-05-23 14:43:10 +00:00
listSimilar: (config: Config, movie: Movie, setMovies: React.Dispatch<React.SetStateAction<Array<Movie>>>, setSimilarMoviesAvailable: React.Dispatch<React.SetStateAction<boolean>>) => Promise<boolean>;
2024-05-05 21:59:33 +00:00
index: number;
2024-05-06 09:09:21 +00:00
config: Config;
2024-05-23 14:43:10 +00:00
setMovies: React.Dispatch<React.SetStateAction<Array<Movie>>>;
setChosenMovie: React.Dispatch<React.SetStateAction<Movie>>;
setSimilarMoviesAvailable: React.Dispatch<React.SetStateAction<boolean>>;
isHighlighted: boolean;
2024-10-05 15:16:08 +00:00
className: string
2024-05-02 20:47:28 +00:00
}
2024-05-05 21:59:33 +00:00
2024-10-05 15:16:08 +00:00
function Poster({ className, movie, config, listSimilar, setMovies, setChosenMovie, setSimilarMoviesAvailable, isHighlighted }: PosterProps) {
2024-05-07 16:58:39 +00:00
function clickHandler() {
setChosenMovie(movie)
listSimilar(config, movie, setMovies, setSimilarMoviesAvailable)
2024-05-07 16:58:39 +00:00
}
const [isLoading, setIsLoading] = useState(true)
const [hasError, setHasError] = useState(false)
2024-10-05 15:16:08 +00:00
return <><div className={className} >
{isLoading ?
2024-10-05 15:16:08 +00:00
<div className="m-auto text-center h-full w-full fixed">
<div className="lds-spinner"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div></div>
2024-10-05 15:25:55 +00:00
: <div className="z-10 h-full w-full absolute cursor-pointer" onClick={() => clickHandler()}>
2024-10-05 15:16:08 +00:00
hello
</div>
}
2024-10-05 15:16:08 +00:00
{hasError ?? <div className="m-auto text-center"></div>}
2024-05-07 16:58:39 +00:00
<img
src={tmdb.makeImgUrl(movie.poster_path ?? "")}
onLoad={() => setIsLoading(false)}
onError={() => setHasError(true)}
2024-05-07 16:58:39 +00:00
/>
2024-10-05 15:16:08 +00:00
</div >
2024-05-23 13:54:06 +00:00
</>
2024-05-02 20:47:28 +00:00
}