18 - Mostrar Película (Detalle al hacer clic)
Objetivo
Implementar la funcionalidad para mostrar los detalles de una película cuando se hace clic en un botón específico.
Paso a Paso
1. Importar useState y Link de React
import { useState } from 'react';
import { Link } from 'react-router-dom';2. Crear estados para la película activa
const [activeMovie, setActiveMovie] = useState(null);
const [activeIndex, setActiveIndex] = useState(-1);3. Crear función para seleccionar película activa
const setActiveMovieHandler = (movie, index) => {
setActiveMovie(movie);
setActiveIndex(index);
};4. Agregar botón en cada película para mostrar detalles
En el componente de lista de películas, agregar un botón con icono:
<button
onClick={() => setActiveMovieHandler(movie, index)}
className="btn btn-sm btn-info"
>
<i className="bi bi-eye"></i>
</button>5. Implementar panel de detalles con operador ternario
<div className="detail-panel">
{activeMovie ? (
<div className="movie-detail">
{/* Contenido cuando hay película seleccionada */}
</div>
) : (
<div className="no-selection">
<h3>Primero selecciona una película</h3>
<p>Haz clic en el ícono de ojo de cualquier película para ver sus detalles aquí</p>
</div>
)}
</div>6. Mostrar información detallada de la película
Cuando hay una película activa, mostrar:
<div className="movie-detail">
<h2>{activeMovie.title}</h2>
<div className="movie-info">
<div className="info-row">
<label>Año:</label>
<span>{activeMovie.year}</span>
</div>
<div className="info-row">
<label>Sinopsis:</label>
<p>{activeMovie.synopsis}</p>
</div>
<div className="movie-cover">
<img
src={activeMovie.cover}
alt={activeMovie.title}
className="img-fluid"
/>
</div>
<div className="actions">
<Link
to={`/movies/${activeMovie.id}/edit`}
className="btn btn-warning"
>
<i className="bi bi-pencil"></i> Editar
</Link>
</div>
</div>
</div>7. Estilos CSS básicos
.detail-panel {
padding: 20px;
background-color: #f8f9fa;
border-radius: 8px;
min-height: 400px;
}
.movie-detail h2 {
color: #333;
margin-bottom: 20px;
}
.info-row {
margin-bottom: 15px;
}
.info-row label {
font-weight: bold;
margin-right: 10px;
color: #555;
}
.movie-cover {
margin: 20px 0;
}
.movie-cover img {
max-width: 100%;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.no-selection {
text-align: center;
padding: 50px 20px;
color: #666;
}
.no-selection h3 {
margin-bottom: 10px;
}
.actions {
margin-top: 20px;
}Código completo del componente:
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
const MovieList = ({ movies }) => {
const [activeMovie, setActiveMovie] = useState(null);
const [activeIndex, setActiveIndex] = useState(-1);
const setActiveMovieHandler = (movie, index) => {
setActiveMovie(movie);
setActiveIndex(index);
};
return (
<div className="container">
<div className="row">
{/* Lista de películas */}
<div className="col-md-6">
<h2>Lista de Películas</h2>
{movies.map((movie, index) => (
<div key={movie.id} className="movie-item">
<h3>{movie.title}</h3>
<button
onClick={() => setActiveMovieHandler(movie, index)}
className="btn btn-sm btn-info"
>
<i className="bi bi-eye"></i> Ver detalles
</button>
</div>
))}
</div>
{/* Panel de detalles */}
<div className="col-md-6">
<div className="detail-panel">
{activeMovie ? (
<div className="movie-detail">
<h2>{activeMovie.title}</h2>
<div className="movie-info">
<div className="info-row">
<label>Año:</label>
<span>{activeMovie.year}</span>
</div>
<div className="info-row">
<label>Sinopsis:</label>
<p>{activeMovie.synopsis}</p>
</div>
<div className="movie-cover">
<img
src={activeMovie.cover}
alt={activeMovie.title}
className="img-fluid"
/>
</div>
<div className="actions">
<Link
to={`/movies/${activeMovie.id}/edit`}
className="btn btn-warning"
>
<i className="bi bi-pencil"></i> Editar
</Link>
</div>
</div>
</div>
) : (
<div className="no-selection">
<h3>Primero selecciona una película</h3>
<p>Haz clic en el ícono de ojo de cualquier película para ver sus detalles aquí</p>
</div>
)}
</div>
</div>
</div>
</div>
);
};
export default MovieList;Resumen
Estados: Creamos dos estados para controlar la película activa y su índice
Función handler: Implementamos una función que actualiza los estados cuando se hace clic
Botón de acción: Agregamos un botón en cada película que llama al handler
Panel condicional: Usamos un operador ternario para mostrar detalles o mensaje de selección
Información detallada: Desplegamos todos los datos de la película seleccionada
Enlace de edición: Proporcionamos un botón para editar la película actual
Próximos pasos
En el siguiente tutorial implementaremos la funcionalidad para editar películas existentes utilizando el formulario que ya tenemos creado.
Comentarios
Publicar un comentario