Skip to main content

PeliculaCard

The PeliculaCard component displays a single movie with its poster, title, metadata, rating, and action buttons. It includes hover effects and integrates with the trailer modal.

Component Overview

import PeliculaCard from './components/PeliculaCard';

function App() {
  return (
    <PeliculaCard 
      pelicula={{
        id: 1,
        title: "Inception",
        year: 2010,
        duration: 148,
        rating: 8.8,
        image: "https://example.com/inception.jpg",
        trailerUrl: "https://youtube.com/embed/..."
      }} 
    />
  );
}

Props

pelicula
object
required
Movie object containing all necessary information
pelicula.id
number
required
Unique identifier for the movie
pelicula.title
string
required
Movie title
pelicula.year
number
required
Release year
pelicula.duration
number
required
Movie duration in minutes
pelicula.rating
number
required
Movie rating out of 10
pelicula.image
string
required
URL to movie poster image
pelicula.trailerUrl
string
required
YouTube embed URL for the movie trailer

Features

Image Error Handling

The component includes automatic fallback for broken images:
const [imageError, setImageError] = useState(false);

const handleImageError = () => {
  setImageError(true);
};

<img 
  src={imageError ? 'https://img.freepik.com/vector-premium/emoji-cara-nula-ilustracion_1272837-162.jpg' : pelicula.image} 
  alt={pelicula.title}
  onError={handleImageError}
/>
If the movie poster fails to load, a placeholder image is displayed automatically.

Hover Overlay

When hovering over the card, an overlay appears with a “Ver Tráiler” (Watch Trailer) button:
<div className="pelicula-card__overlay">
  <button 
    className="pelicula-card__trailer-btn"
    onClick={() => setShowTrailer(true)}
  >
    ▶ Ver Tráiler
  </button>
</div>

Integrated Trailer Modal

The component manages its own trailer modal state:
const [showTrailer, setShowTrailer] = useState(false);

{showTrailer && (
  <TrailerModal 
    pelicula={pelicula} 
    onClose={() => setShowTrailer(false)} 
  />
)}

Component Structure

const PeliculaCard = ({ pelicula }) => {
  const [showTrailer, setShowTrailer] = useState(false);
  const [imageError, setImageError] = useState(false);

  return (
    <>
      <article className="pelicula-card">
        <div className="pelicula-card__image-container">
          <img />
          <div className="pelicula-card__overlay">
            <button>Ver Tráiler</button>
          </div>
        </div>
        
        <div className="pelicula-card__content">
          <h3>{pelicula.title}</h3>
          <p>{pelicula.year}{pelicula.duration} min</p>
          <p>{pelicula.rating}/10</p>
          <Link to={`/pelicula/${pelicula.id}`}>Ver detalles</Link>
        </div>
      </article>

      {showTrailer && <TrailerModal />}
    </>
  );
};

Usage in Grid

Typically used within a PeliculaGrid component:
import PeliculaGrid from './components/PeliculaGrid';

function PeliculasPage() {
  const peliculas = [
    { id: 1, title: "Inception", /* ... */ },
    { id: 2, title: "The Matrix", /* ... */ },
  ];

  return <PeliculaGrid peliculas={peliculas} loading={false} />;
}
The grid automatically maps over movies and renders individual cards.

Full Component Code

Location: src/components/PeliculaCard.jsx:1
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import TrailerModal from './TrailerModal';

const PeliculaCard = ({ pelicula }) => {
  const [showTrailer, setShowTrailer] = useState(false);
  const [imageError, setImageError] = useState(false);

  const handleImageError = () => {
    setImageError(true);
  };

  return (
    <>
      <article className="pelicula-card">
        <div className="pelicula-card__image-container">
          <img 
            src={imageError ? 'https://img.freepik.com/vector-premium/emoji-cara-nula-ilustracion_1272837-162.jpg' : pelicula.image} 
            alt={pelicula.title}
            className="pelicula-card__image"
            onError={handleImageError}
          />
          <div className="pelicula-card__overlay">
            <button 
              className="pelicula-card__trailer-btn"
              onClick={() => setShowTrailer(true)}
            >
              ▶ Ver Tráiler
            </button>
          </div>
        </div>
        
        <div className="pelicula-card__content">
          <h3 className="pelicula-card__title">{pelicula.title}</h3>
          <p className="pelicula-card__meta">{pelicula.year}{pelicula.duration} min</p>
          <p className="pelicula-card__rating">{pelicula.rating}/10</p>
          
          <div className="pelicula-card__actions">
            <Link to={`/pelicula/${pelicula.id}`} className="pelicula-card__details-btn">
              Ver detalles
            </Link>
          </div>
        </div>
      </article>

      {showTrailer && (
        <TrailerModal 
          pelicula={pelicula} 
          onClose={() => setShowTrailer(false)} 
        />
      )}
    </>
  );
};

export default PeliculaCard;

Styling

The component uses BEM naming with these main classes:
  • .pelicula-card - Main container
  • .pelicula-card__image-container - Poster wrapper
  • .pelicula-card__image - Poster image
  • .pelicula-card__overlay - Hover overlay
  • .pelicula-card__trailer-btn - Trailer button
  • .pelicula-card__content - Text content area
  • .pelicula-card__title - Movie title
  • .pelicula-card__meta - Year and duration
  • .pelicula-card__rating - Rating display
  • .pelicula-card__details-btn - Details link button

PeliculaGrid

Container component for displaying multiple movie cards

TrailerModal

Modal used for displaying movie trailers

Build docs developers (and LLMs) love