| 👨💻 Nombre | 📧 Correo | 🏫 Link directo al repositorio | 🐙 Usuario GitHub |
|---|---|---|---|
| Jonathan David Fernandez Vargas | jonathanfdez62@gmail.com | LinkRepositorio | jonathand77 |
Aplicación web para descubrir películas, ver sus trailers en un modal inmersivo y armar una lista de favoritos.
Movie Time es una SPA construida con React que consume la API pública de TMDB para explorar el catálogo de películas, buscar por título, ver el trailer oficial en un reproductor superpuesto y guardar favoritos.
El código sigue una arquitectura por capas y principios SOLID aplicados a componentes funcionales y hooks: el acceso a datos vive detrás de un repositorio inyectable, el estado de la app está dividido en hooks de un solo dominio cada uno (catálogo, selección/trailer, favoritos), y la UI son componentes de presentación desacoplados de la lógica de negocio.
Antes de ejecutar el proyecto, asegurate de tener:
- Node.js 18+
- npm 9+
- Una API key de TMDB (obtenerla acá, es gratuita)
- Conexión a internet (para consultar la API de TMDB y cargar las fuentes de Google Fonts)
movie-time/
├── public/
│ ├── img/
│ │ └── MovieTime.png
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ ├── MovieTime.png
│ └── robots.txt
├── src/
│ ├── api/
│ │ └── movieRepository.js # Repositorio de películas (fábrica inyectable + instancia TMDB por defecto)
│ ├── components/
│ │ ├── AppHeader.jsx / .css # Header sticky, buscador y branding
│ │ ├── HeroSection.jsx / .css # Película destacada (backdrop, rating, acciones)
│ │ ├── TrailerModal.jsx / .css # Reproductor de trailer en modal
│ │ ├── MovieGrid.jsx / .css # Grilla de resultados (loading/empty states)
│ │ ├── MovieCard.jsx / .css # Tarjeta de película individual
│ │ ├── FavoritesPanel.jsx / .css # Panel de favoritos (sticky en desktop)
│ │ └── Icon.jsx # Set de íconos SVG inline, extensible
│ ├── constants/
│ │ └── tmdb.js # Config de TMDB (baseUrl, imageBaseUrl, apiKey)
│ ├── hooks/
│ │ ├── useMovies.js # Facade: compone los 3 hooks de abajo
│ │ ├── useMovieCatalog.js # Catálogo + búsqueda
│ │ ├── useSelectedMovie.js # Película seleccionada + trailer
│ │ └── useFavorites.js # Lista de favoritos
│ ├── styles/
│ │ └── theme.css # Tokens de diseño y primitivas compartidas
│ ├── utils/
│ │ ├── movieUtils.js # Funciones puras (título, año, rating, imágenes)
│ │ └── browser.js # Wrappers de window (scroll, reload)
│ ├── types.js # Typedefs JSDoc de dominio (Movie, Video)
│ ├── App.js / App.css # Composición raíz
│ └── index.js / index.css # Punto de entrada
├── .env.example
├── package.json
└── README.md
git clone https://github.com/Jonathand77/movie-time.git
cd movie-timecopy .env.example .env # en Windows (o: cp .env.example .env)Editá .env y completá tu API key:
REACT_APP_TMDB_API_KEY=<tu_api_key_de_tmdb>Sin esta variable la app arranca igual, pero las peticiones a TMDB van a fallar (se loguea un aviso en consola).
npm installnpm startLa app queda disponible en:
http://localhost:3000
npm run build| Variable | Requerida | Descripción |
|---|---|---|
REACT_APP_TMDB_API_KEY |
Sí | API key de TMDB usada por src/constants/tmdb.js para autenticar las peticiones |
.env está en .gitignore — nunca se commitea. .env.example es la plantilla versionada que indica qué variables hacen falta.
| Principio | Cómo se aplica |
|---|---|
| SRP | El estado se dividió en useMovieCatalog, useSelectedMovie y useFavorites (un dominio por hook) en vez de un único hook que hiciera todo. TrailerModal se separó de HeroSection: cada uno maneja una sola responsabilidad. |
| OCP | Icon.jsx acepta un ícono nuevo vía children sin tener que modificar el archivo para cada caso puntual. |
| LSP | Todas las funciones del repositorio de películas devuelven la misma forma de datos (Promise con arrays/objetos ya "desempaquetados"), por lo que son intercambiables para quien las consume. |
| ISP | HeroSection solo recibe las props que realmente usa (info de película + favoritos); el control del modal de trailer vive aparte en TrailerModal, con su propia interfaz mínima. |
| DIP | src/api/movieRepository.js expone una fábrica (createTmdbMovieRepository) en vez de funciones sueltas atadas a axios. Los hooks reciben el repositorio como parámetro inyectable (con la instancia real como valor por defecto), lo que permite testear con un doble sin tocar red. |
api/: acceso a datos, sin conocer nada de UI.hooks/: estado y orquestación, sin conocer detalles de red ni de renderizado.components/: presentación pura, reciben datos y callbacks por props.utils/: funciones puras y sin efectos secundarios, fáciles de testear.constants/ytypes.js: configuración y contratos de datos centralizados.
- Tokens de diseño (colores, fuentes, sombras) centralizados en
src/styles/theme.css, con primitivas compartidas (.btn,.glass-panel,.content-panel) usadas por varios componentes. - Cada componente tiene su propio
.cssco-ubicado junto al.jsx, en vez de un único archivo de estilos gigante. - Tipografía: Inter para texto y Outfit para títulos, cargadas vía Google Fonts.
- Animaciones de entrada, hover y estados de carga (skeletons con shimmer) en header, hero, tarjetas y modal, respetando
prefers-reduced-motionpara accesibilidad.
- Búsqueda de películas en tiempo real por título, con botón de limpiar y estado de carga con spinner.
- Película destacada con backdrop dinámico, rating, año y entrada animada al cambiar de selección.
- Reproducción del trailer oficial en un modal con spinner de carga, cierre por botón, click afuera o tecla
ESC, y foco accesible. - Gestión de favoritos (añadir/quitar) con panel sticky en desktop y estado vacío ilustrado.
- Grilla de resultados con skeletons durante la carga inicial y estado vacío cuando una búsqueda no encuentra nada.
- Recarga rápida desde el logo del header.
- Experiencia responsive para mobile, tablet y desktop.
- Tests unitarios de las funciones puras de
src/utils/movieUtils.js(título, año, rating, URLs de imagen, selección de trailer). - Tests del hook
useFavoritesconrenderHook/actde@testing-library/react. - Test de render de
App.jsmockeandouseMovies. - Stack de testing:
@testing-library/react+@testing-library/jest-dom, sobre Jest (víareact-scripts test).
Ejecutar las pruebas:
npm testnpm start: entorno de desarrollo con hot-reload.npm test: ejecuta la suite de tests.npm run build: build optimizada de producción.npm run eject: extracción de la configuración de Create React App (irreversible).