Skip to content

Commit cdc790e

Browse files
committed
working home
1 parent c11b7be commit cdc790e

File tree

1 file changed

+157
-69
lines changed

1 file changed

+157
-69
lines changed

src/pages/Home.tsx

Lines changed: 157 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Home.tsx
2-
import { useEffect, useState } from 'react';
2+
import { useEffect, useState, useRef } from 'react';
33
import axios from 'axios';
44
import MovieCard from '../Components/MovieCard';
55
import NavBar from '../Components/NavBar';
@@ -20,6 +20,126 @@ interface Genre {
2020
name: string;
2121
}
2222

23+
// Componente para el carrusel horizontal
24+
interface MovieCarouselProps {
25+
title: string;
26+
movies: Movie[];
27+
}
28+
29+
const MovieCarousel = ({ title, movies }: MovieCarouselProps) => {
30+
const carouselRef = useRef<HTMLDivElement>(null);
31+
const [isDragging, setIsDragging] = useState(false);
32+
const [startX, setStartX] = useState(0);
33+
const [scrollLeft, setScrollLeft] = useState(0);
34+
35+
// Función para deslizar hacia la izquierda
36+
const scrollLeft1 = () => {
37+
if (carouselRef.current) {
38+
carouselRef.current.scrollTo({
39+
left: carouselRef.current.scrollLeft - 300,
40+
behavior: 'smooth'
41+
});
42+
}
43+
};
44+
45+
// Función para deslizar hacia la derecha
46+
const scrollRight = () => {
47+
if (carouselRef.current) {
48+
carouselRef.current.scrollTo({
49+
left: carouselRef.current.scrollLeft + 300,
50+
behavior: 'smooth'
51+
});
52+
}
53+
};
54+
55+
// Gestionar eventos de mouse/touch para el deslizamiento manual
56+
const handleMouseDown = (e: React.MouseEvent) => {
57+
setIsDragging(true);
58+
setStartX(e.pageX - (carouselRef.current?.offsetLeft || 0));
59+
setScrollLeft(carouselRef.current?.scrollLeft || 0);
60+
};
61+
62+
const handleTouchStart = (e: React.TouchEvent) => {
63+
setIsDragging(true);
64+
setStartX(e.touches[0].pageX - (carouselRef.current?.offsetLeft || 0));
65+
setScrollLeft(carouselRef.current?.scrollLeft || 0);
66+
};
67+
68+
const handleMouseUp = () => {
69+
setIsDragging(false);
70+
};
71+
72+
const handleMouseMove = (e: React.MouseEvent) => {
73+
if (!isDragging) return;
74+
e.preventDefault();
75+
if (carouselRef.current) {
76+
const x = e.pageX - (carouselRef.current.offsetLeft || 0);
77+
const walk = (x - startX) * 2; // Velocidad de desplazamiento
78+
carouselRef.current.scrollLeft = scrollLeft - walk;
79+
}
80+
};
81+
82+
const handleTouchMove = (e: React.TouchEvent) => {
83+
if (!isDragging) return;
84+
if (carouselRef.current) {
85+
const x = e.touches[0].pageX - (carouselRef.current.offsetLeft || 0);
86+
const walk = (x - startX) * 2;
87+
carouselRef.current.scrollLeft = scrollLeft - walk;
88+
}
89+
};
90+
91+
return (
92+
<div className="mb-8">
93+
<div className="flex justify-between items-center mb-4">
94+
<h2 className="text-2xl font-bold">{title}</h2>
95+
<div className="flex space-x-2">
96+
<button
97+
onClick={scrollLeft1}
98+
className="bg-gray-800 hover:bg-gray-700 text-white p-2 rounded-full"
99+
aria-label="Desplazar a la izquierda"
100+
>
101+
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
102+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
103+
</svg>
104+
</button>
105+
<button
106+
onClick={scrollRight}
107+
className="bg-gray-800 hover:bg-gray-700 text-white p-2 rounded-full"
108+
aria-label="Desplazar a la derecha"
109+
>
110+
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
111+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
112+
</svg>
113+
</button>
114+
</div>
115+
</div>
116+
<div
117+
ref={carouselRef}
118+
className="flex overflow-x-auto scrollbar-hide gap-4 pb-4"
119+
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}
120+
onMouseDown={handleMouseDown}
121+
onMouseUp={handleMouseUp}
122+
onMouseLeave={handleMouseUp}
123+
onMouseMove={handleMouseMove}
124+
onTouchStart={handleTouchStart}
125+
onTouchEnd={handleMouseUp}
126+
onTouchMove={handleTouchMove}
127+
>
128+
{movies.map(movie => (
129+
<div key={movie.id} className="flex-shrink-0" style={{ width: '200px' }}>
130+
<MovieCard
131+
id={movie.id}
132+
title={movie.title}
133+
poster={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
134+
rating={movie.vote_average}
135+
/>
136+
</div>
137+
))}
138+
</div>
139+
</div>
140+
);
141+
};
142+
23143
export default function Home() {
24144
const [trendingMovies, setTrendingMovies] = useState<Movie[]>([]);
25145
const [popularMovies, setPopularMovies] = useState<Movie[]>([]);
@@ -118,20 +238,28 @@ export default function Home() {
118238
</div>
119239
);
120240

241+
const CarouselSkeleton = () => (
242+
<div className="mb-8">
243+
<div className="h-8 bg-gray-800 rounded w-64 mb-4 animate-pulse"></div>
244+
<div className="flex gap-4 overflow-x-auto pb-4">
245+
{[...Array(5)].map((_, index) => (
246+
<div key={index} className="flex-shrink-0" style={{ width: '200px' }}>
247+
<MovieCardSkeleton />
248+
</div>
249+
))}
250+
</div>
251+
</div>
252+
);
253+
121254
if (isLoading) {
122255
return (
123256
<div className="flex flex-col min-h-screen bg-gray-900 text-white">
124257
<NavBar />
125258
<div className="h-96 w-full bg-gray-800 animate-pulse mb-6"></div>
126259
<div className="container mx-auto px-4">
127-
<div className="mb-8">
128-
<div className="h-8 bg-gray-800 rounded w-64 mb-4 animate-pulse"></div>
129-
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
130-
{[...Array(10)].map((_, index) => (
131-
<MovieCardSkeleton key={index} />
132-
))}
133-
</div>
134-
</div>
260+
<CarouselSkeleton />
261+
<CarouselSkeleton />
262+
<CarouselSkeleton />
135263
</div>
136264
</div>
137265
);
@@ -196,12 +324,12 @@ export default function Home() {
196324
{/* Género */}
197325
<div className="mb-8">
198326
<h2 className="text-2xl font-bold mb-4">Explorar por Género</h2>
199-
<div className="flex flex-wrap gap-2 mb-6">
327+
<div className="flex flex-wrap gap-2 mb-6 overflow-x-auto pb-2" style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}>
200328
{genres.map(genre => (
201329
<button
202330
key={genre.id}
203331
onClick={() => handleGenreSelect(genre.id)}
204-
className={`px-4 py-2 rounded-full text-sm font-medium transition-colors ${
332+
className={`px-4 py-2 rounded-full text-sm font-medium transition-colors flex-shrink-0 ${
205333
selectedGenre === genre.id
206334
? 'bg-red-600 text-white'
207335
: 'bg-gray-800 text-gray-300 hover:bg-gray-700'
@@ -213,74 +341,34 @@ export default function Home() {
213341
</div>
214342

215343
{selectedGenre && genreMovies.length > 0 && (
216-
<div className="mb-8">
217-
<h3 className="text-xl font-semibold mb-4">
218-
{genres.find(g => g.id === selectedGenre)?.name || 'Género'} Movies
219-
</h3>
220-
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
221-
{genreMovies.slice(0, 10).map(movie => (
222-
<MovieCard
223-
key={movie.id}
224-
id={movie.id}
225-
title={movie.title}
226-
poster={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
227-
rating={movie.vote_average}
228-
/>
229-
))}
230-
</div>
231-
</div>
344+
<MovieCarousel
345+
title={`${genres.find(g => g.id === selectedGenre)?.name || 'Género'} Movies`}
346+
movies={genreMovies}
347+
/>
232348
)}
233349
</div>
234350

235351
{/* Trending Movies */}
236-
<div className="mb-8">
237-
<h2 className="text-2xl font-bold mb-4">Trending Hoy</h2>
238-
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
239-
{trendingMovies.map(movie => (
240-
<MovieCard
241-
key={movie.id}
242-
id={movie.id}
243-
title={movie.title}
244-
poster={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
245-
rating={movie.vote_average}
246-
/>
247-
))}
248-
</div>
249-
</div>
352+
<MovieCarousel title="Trending Hoy" movies={trendingMovies} />
250353

251354
{/* Popular Movies */}
252-
<div className="mb-8">
253-
<h2 className="text-2xl font-bold mb-4">Películas Populares</h2>
254-
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
255-
{popularMovies.map(movie => (
256-
<MovieCard
257-
key={movie.id}
258-
id={movie.id}
259-
title={movie.title}
260-
poster={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
261-
rating={movie.vote_average}
262-
/>
263-
))}
264-
</div>
265-
</div>
355+
<MovieCarousel title="Películas Populares" movies={popularMovies} />
266356

267357
{/* Top Rated Movies */}
268-
<div className="mb-8">
269-
<h2 className="text-2xl font-bold mb-4">Mejor Valoradas</h2>
270-
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
271-
{topRatedMovies.map(movie => (
272-
<MovieCard
273-
key={movie.id}
274-
id={movie.id}
275-
title={movie.title}
276-
poster={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
277-
rating={movie.vote_average}
278-
/>
279-
))}
280-
</div>
281-
</div>
358+
<MovieCarousel title="Mejor Valoradas" movies={topRatedMovies} />
282359
</div>
283360

361+
{/* Agregar estilos CSS para ocultar la barra de desplazamiento en todos los navegadores */}
362+
<style jsx global>{`
363+
.scrollbar-hide::-webkit-scrollbar {
364+
display: none;
365+
}
366+
.scrollbar-hide {
367+
-ms-overflow-style: none;
368+
scrollbar-width: none;
369+
}
370+
`}</style>
371+
284372
{/* Footer */}
285373
<footer className="bg-gray-950 py-8 mt-auto">
286374
<div className="container mx-auto px-4 text-center text-gray-400">

0 commit comments

Comments
 (0)