frontend/src/components/molecules/Carousel.jsx

/**
 * @file Componente de carrusel.
 * @description Muestra una colección de tarjetas en un carrusel navegable.
 * @requires react
 * @requires prop-types
 * @requires ../atoms/Card
 * @requires ../../styles/molecules/Carousel.css
 */
import React, { useState } from "react";
import PropTypes from "prop-types";
import Card from "../atoms/Card";
import "../../styles/molecules/Carousel.css";

/**
 * @function Carousel
 * @description Renderiza un carrusel de tarjetas con controles de navegación.
 * @param {object} props - Las propiedades del componente.
 * @param {Array<object>} props.items - Una lista de objetos, cada uno con `title` y `description` para una tarjeta.
 * @returns {JSX.Element} El componente de carrusel.
 */
const Carousel = ({ items }) => {
    const [currentIndex, setCurrentIndex] = useState(0);
    const itemsPerPage = 2;

    /**
     * @function goToPrevious
     * @description Navega a la diapositiva anterior en el carrusel.
     */
    const goToPrevious = () => {
        setCurrentIndex((prevIndex) =>
            prevIndex === 0 ? Math.max(0, items.length - itemsPerPage) : prevIndex - 1
        );
    };

    /**
     * @function goToNext
     * @description Navega a la siguiente diapositiva en el carrusel.
     */
    const goToNext = () => {
        setCurrentIndex((prevIndex) =>
            prevIndex >= items.length - itemsPerPage ? 0 : prevIndex + 1
        );
    };

    if (!items || items.length === 0) {
        return <div className="carousel carousel--empty">No hay artículos disponibles</div>;
    }

    const visibleItems = items.slice(currentIndex, currentIndex + itemsPerPage);

    return (
        <div className="carousel">
            <button
                className="carousel__button carousel__button--prev"
                onClick={goToPrevious}
                aria-label="Anterior"
            >
                ‹
            </button>

            <div className="carousel__content">
                {visibleItems.map((item, index) => (
                    <Card
                        key={currentIndex + index}
                        title={item.title}
                        description={item.description}
                    />
                ))}
            </div>

            <button
                className="carousel__button carousel__button--next"
                onClick={goToNext}
                aria-label="Siguiente"
            >
                ›
            </button>

            <div className="carousel__indicators">
                {items.map((_, index) => (
                    <button
                        key={index}
                        className={`carousel__indicator ${
                            index === currentIndex ? 'carousel__indicator--active' : ''
                        }`}
                        onClick={() => setCurrentIndex(index)}
                        aria-label={`Ir al artículo ${index + 1}`}
                    />
                ))}
            </div>
        </div>
    );
};

Carousel.propTypes = {
    /** Una lista de objetos, cada uno con `title` y `description` para una tarjeta. */
    items: PropTypes.arrayOf(
        PropTypes.shape({
            /** El título de la tarjeta. */
            title: PropTypes.string.isRequired,
            /** La descripción de la tarjeta. */
            description: PropTypes.string.isRequired
        })
    ).isRequired
};

export default Carousel;