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

jsx
import { useState } from 'react';
import { Link } from 'react-router-dom';

2. Crear estados para la película activa

jsx
const [activeMovie, setActiveMovie] = useState(null);
const [activeIndex, setActiveIndex] = useState(-1);

3. Crear función para seleccionar película activa

jsx
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:

jsx
<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

jsx
<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:

jsx
<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

css
.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:

jsx
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

  1. Estados: Creamos dos estados para controlar la película activa y su índice

  2. Función handler: Implementamos una función que actualiza los estados cuando se hace clic

  3. Botón de acción: Agregamos un botón en cada película que llama al handler

  4. Panel condicional: Usamos un operador ternario para mostrar detalles o mensaje de selección

  5. Información detallada: Desplegamos todos los datos de la película seleccionada

  6. 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

Entradas más populares de este blog

Axios para Principiantes - Guía Paso a Paso

15-Tutorial: Crear Película en React con useState

Tutorial de React para Principiantes