Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 1x 4x 4x 4x 4x 3x 1x 4x | import { useState } from "react"; import { DateTime } from "luxon"; import { IMovie } from "@/interfaces"; import { MovieRating } from "@/components/molecules"; import moviePlacegolder from "@/assets/poster-placeholder.svg"; export const Movie = ({ movie }: { movie: IMovie }) => { const MoviePoster = () => { const [hasLoaded, setHasLoaded] = useState(false); const handleOnLoad = () => { setHasLoaded(true); }; if (movie.poster_path) return ( <div className="relative"> {!hasLoaded && <div className="absolute inset-0 bg-gray-300 animate-pulse"></div>} <img src={`https://image.tmdb.org/t/p/w342/${movie.poster_path}`} alt={movie.title} onLoad={handleOnLoad} className={`w-full h-full rounded-t-xl object-cover ${ hasLoaded ? "opacity-100" : "opacity-0" } transition-opacity duration-300`} /> </div> ); return <img src={moviePlacegolder} alt="Movie Poster Placeholder" className="bg-[#dbdbdb] rounded-t-xl" />; }; return ( <div className="h-full border rounded-xl flex flex-col shadow-md cursor-pointer"> <MoviePoster /> <div className="p-3 flex flex-col justify-between h-full"> <div className="flex flex-col gap-[1px]"> <span className="font-bold">{movie.title}</span> <span className="text-gray-500"> {DateTime.fromISO(movie.release_date).toLocaleString({ month: "long", day: "2-digit", year: "numeric", })} </span> </div> <MovieRating vote={movie.vote_average} /> </div> </div> ); }; |