From 7a2b65effcc92a4170e1dce7fa7b0070cc8b8f86 Mon Sep 17 00:00:00 2001 From: MIGHTY1o1 Date: Thu, 10 Oct 2024 01:33:57 +0530 Subject: [PATCH] revamp crousel --- .../custom/MovieCarousel/CarouselCard.tsx | 157 ++++++------ .../custom/MovieCarousel/MovieCarousel.tsx | 231 +++++++++--------- 2 files changed, 190 insertions(+), 198 deletions(-) diff --git a/client/src/components/custom/MovieCarousel/CarouselCard.tsx b/client/src/components/custom/MovieCarousel/CarouselCard.tsx index 57d499a3..7bea7bbd 100644 --- a/client/src/components/custom/MovieCarousel/CarouselCard.tsx +++ b/client/src/components/custom/MovieCarousel/CarouselCard.tsx @@ -1,111 +1,90 @@ -import { genreMap } from "@/lib/stats" -import { SimpleMovie } from "@/Types/Movie" -import { FC } from "react" -import { useNavigate } from "react-router-dom" -import LazyImage from "../LazyLoadImage/LazyImage" -import "./CarouselCard.css" -// export interface SimpleMovie { -// movie_id: string // movie movie_id -// release_date: string -// friend?: string -// title: string | undefined -// overview: string -// poster_path: string | undefined -// backdrop_path: string -// } +import React from "react"; +import { useNavigate } from "react-router-dom"; +import { motion } from "framer-motion"; +import { ChevronRight, Calendar, Film, User } from "lucide-react"; +import { genreMap } from "@/lib/stats"; +import { SimpleMovie } from "@/Types/Movie"; +import LazyImage from "../LazyLoadImage/LazyImage"; -const image_url = "https://image.tmdb.org/t/p" +const IMAGE_URL = "https://image.tmdb.org/t/p"; -const CarouselCard: FC = ({ +const CarouselCard: React.FC = ({ movie_id, friend, title, - poster_path, backdrop_path, release_date, genre_ids, }) => { + const navigate = useNavigate(); const genreNames = genre_ids - ?.map((id) => genreMap[id]) // map genre_ids to their respective names - .filter(Boolean) // remove undefined genres in case there are any missing ids - .slice(0, 3) // - const navigate = useNavigate() + ?.map((id) => genreMap[id]) + .filter(Boolean) + .slice(0, 3); const handleClick = () => { - console.log("movie_id :", movie_id) - navigate(`/movie/${movie_id}`) - } + console.log("movie_id:", movie_id); + navigate(`/movie/${movie_id}`); + }; + return ( -
-
-
- {/* Poster Image */} - - {/* Movie Details */} -
-

{title}

-
- - {/* */} - -
- {/* //animate presence used to animate things which are entering - and leaving the viewport */} - {/* - {isHovered && ( - - {overview} - +
+
+ + +
+

{title}

+
+
+ + {release_date} +
+
+ + {genreNames?.join(", ")} +
+
+ {friend && ( +
+ + + Watched by {friend} + +
)} - */} - {/* Release Date and Genre */} - {friend && ( -

- Watched by{" "} - - {friend} - -

- )} -
+ + View Details + + +
+
-
- ) -} + + ); +}; -export default CarouselCard +export default CarouselCard; \ No newline at end of file diff --git a/client/src/components/custom/MovieCarousel/MovieCarousel.tsx b/client/src/components/custom/MovieCarousel/MovieCarousel.tsx index c01454cd..0693dbec 100644 --- a/client/src/components/custom/MovieCarousel/MovieCarousel.tsx +++ b/client/src/components/custom/MovieCarousel/MovieCarousel.tsx @@ -1,106 +1,27 @@ -// import { useState, useEffect } from "react" -// import CarouselCard from "./CarouselCard" -// import { useFriendTopMovies } from "@/services/friendsService" -// import { useMovieList } from "@/services/movieService" -// import { SimpleMovie } from "@/Types/Movie" - -// const MovieCarousel = () => { -// const { -// data: friendMoviesData, -// isLoading: isFriendMoviesLoading, -// error: friendMoviesError, -// } = useFriendTopMovies() -// const { -// data: topMovies, -// isLoading: isTopMoviesLoading, -// error: topMoviesError, -// } = useMovieList("popular", 1) -// const [carouselMovies, setCarouselMovies] = useState([]) - -// console.log("friendMoviesData :", friendMoviesData) - -// useEffect(() => { -// if (friendMoviesData && friendMoviesData.length > 0) { -// // If we have friend movies, use them -// const movies = friendMoviesData.flatMap((friendData) => -// friendData.movies.slice(0, 2).map((movie) => ({ -// ...movie, -// friend: friendData.friend, -// })) -// ) -// console.log("movies :", movies) -// if(movies.length === 0){ -// if(topMovies){ -// setCarouselMovies( -// topMovies.map((movie) => ({ ...movie, friend: "" })) -// ) -// } -// } -// else{ -// setCarouselMovies(movies) -// } -// // setCarouselMovies(movies) -// } else if (topMovies) { -// // If no friend movies, use top movies from TMDB -// setCarouselMovies( -// topMovies.map((movie) => ({ ...movie, friend: "" })) -// ) -// } -// // if(topMovies && friendMoviesData && friendMoviesData.length > 0 && carouselMovies.length === 0){ -// // setCarouselMovies( -// // topMovies.map((movie) => ({ ...movie, friend: "" })) -// // ) -// // } -// }, [friendMoviesData, topMovies]) - -// if (isFriendMoviesLoading || isTopMoviesLoading) { -// return
Loading...
-// } - -// if (friendMoviesError || topMoviesError) { -// return
Error loading movies
-// } - -// return ( -//
-// {carouselMovies.map((movie) => ( -// -// ))} -//
-// ) -// } - -// export default MovieCarousel - -import { useState, useEffect } from "react" -import CarouselCard from "./CarouselCard" -import { useFriendTopMovies } from "@/services/friendsService" -import { useMovieList } from "@/services/movieService" -import { SimpleMovie } from "@/Types/Movie" - -const MovieCarousel = () => { +import React, { useState, useEffect, useCallback, useRef } from "react"; +import CarouselCard from "./CarouselCard"; +import { useFriendTopMovies } from "@/services/friendsService"; +import { useMovieList } from "@/services/movieService"; +import { SimpleMovie } from "@/Types/Movie"; + +const MovieCarousel: React.FC = () => { const { data: friendMoviesData, isLoading: isFriendMoviesLoading, error: friendMoviesError, - } = useFriendTopMovies() + } = useFriendTopMovies(); const { data: topMovies, isLoading: isTopMoviesLoading, error: topMoviesError, - } = useMovieList("popular", 1) - const [carouselMovies, setCarouselMovies] = useState([]) + } = useMovieList("popular", 1); + + const [carouselMovies, setCarouselMovies] = useState([]); + const [currentSlide, setCurrentSlide] = useState(0); + const [isDragging, setIsDragging] = useState(false); + const [startX, setStartX] = useState(0); + const [dragOffset, setDragOffset] = useState(0); + const carouselRef = useRef(null); useEffect(() => { if (friendMoviesData && friendMoviesData.length > 0) { @@ -109,37 +30,129 @@ const MovieCarousel = () => { ...movie, friend: friendData.friend, })) - ) + ); if (movies.length > 0) { - setCarouselMovies(movies) + setCarouselMovies(movies); } else if (topMovies) { setCarouselMovies( topMovies.map((movie) => ({ ...movie, friend: "" })) - ) + ); } } else if (topMovies) { setCarouselMovies( topMovies.map((movie) => ({ ...movie, friend: "" })) - ) + ); } - }, [friendMoviesData, topMovies]) + }, [friendMoviesData, topMovies]); + + const updateSlide = useCallback((newSlide: number) => { + setCurrentSlide(Math.max(0, Math.min(newSlide, carouselMovies.length - 1))); + }, [carouselMovies.length]); + + const handleMouseDown = (e: React.MouseEvent) => { + setIsDragging(true); + setStartX(e.pageX - dragOffset); + }; + + const handleMouseMove = (e: React.MouseEvent) => { + if (!isDragging) return; + const currentX = e.pageX - startX; + setDragOffset(currentX); + }; + + const handleMouseUp = () => { + if (!isDragging) return; + setIsDragging(false); + + const slideWidth = carouselRef.current?.offsetWidth || 0; + const dragThreshold = slideWidth / 4; + + if (Math.abs(dragOffset) > dragThreshold) { + const direction = dragOffset > 0 ? -1 : 1; + updateSlide(currentSlide + direction); + } + + setDragOffset(0); + }; + + useEffect(() => { + const handleMouseUpOutside = () => { + if (isDragging) { + handleMouseUp(); + } + }; + + document.addEventListener('mouseup', handleMouseUpOutside); + return () => { + document.removeEventListener('mouseup', handleMouseUpOutside); + }; + }, [isDragging, handleMouseUp]); if (isFriendMoviesLoading || isTopMoviesLoading) { - return
Loading...
+ return
Loading...
; } if (friendMoviesError || topMoviesError) { - return
Error loading movies
+ return
Error loading movies
; + } + + if (carouselMovies.length === 0) { + return
No movies available
; } return ( -
- {carouselMovies.map((movie) => ( - - ))} +
+
+ {carouselMovies.map((movie) => ( + + ))} +
+ + {currentSlide > 0 && ( + + )} + {currentSlide < carouselMovies.length - 1 && ( + + )} + +
+ {carouselMovies.map((_, index) => ( +
+ ))} +
- ) -} + ); +}; -export default MovieCarousel +export default MovieCarousel; \ No newline at end of file