Skip to main content
The product card system displays camera information in a visually appealing card-based layout. It consists of two main components: CardsCam for individual camera cards and ListCam for rendering collections.

CardsCam

The CardsCam component displays a single camera product with its image, model, key specifications, and a link to the detailed view.

Component Code

cardscamara.js
const CardsCam = ({camara}) => {
    let arrayImages = [camara.imagenes[0]]
    const campos = FIELDS_CARD.map(key => 
      <li key={key} className="list-group-item"> {camara[key]}</li>
    )
    
    return(
        <div className="col-sm-12 col-md-6 col-xl-4 mt-2 mb-2">
            <article>
                <div className="card border-0" id="cartas">
                    <img src={arrayImages[0]} className="img-responsivess card-image-top" alt=""/>
                    <div className="d-flex card-body justify-content-center card-modelo">
                        <h5>
                            <strong>Modelo: </strong>
                            {camara.modelo}
                        </h5>
                    </div>
                    <ul className="list-group list-group-flush ">
                        {campos}
                    </ul>
                    <div className="card-body cartas" id="footer-card">
                        <Link to={`/productos/camaras/${camara.modelo}`} className="card-link link-light">
                            Ver
                        </Link>
                    </div>
                </div>
            </article>
        </div>
    )
}

Props

camara
object
required
Camera object containing all product information

Display Fields

The card displays specific camera attributes defined in the FIELDS_CARD constant:
const.js
const FIELDS_CARD = ["diseño", "resolucion", "conectividad", "marca", "tipo_de_camara"]
These fields are mapped to list items:
cardscamara.js:7
const campos = FIELDS_CARD.map(key => 
  <li key={key} className="list-group-item"> {camara[key]}</li>
)

Card Structure

1

Product Image

Displays the first image from the imagenes array
2

Model Name

Shows the camera model in the card header
3

Specifications List

Renders key attributes as a Bootstrap list group:
  • Diseño (Design)
  • Resolución (Resolution)
  • Conectividad (Connectivity)
  • Marca (Brand)
  • Tipo de cámara (Camera Type)
4

View Link

Navigation link to detailed camera view at /productos/camaras/{modelo}

Responsive Layout

The card uses Bootstrap’s grid system for responsive sizing:
  • Mobile (col-sm-12): Full width, one card per row
  • Tablet (col-md-6): Half width, two cards per row
  • Desktop (col-xl-4): One-third width, three cards per row
The component automatically extracts and displays only the first image from the camera’s image array.

ListCam

The ListCam component renders a collection of camera cards with a results counter.

Component Code

listcam.js
const ListCam = ({camaras, resultados}) => {
    const listCamaras = camaras.map(m => <CardsCam key={m.id} camara={m} />)
    let label_resultados = listCamaras.length > 1 
      ? listCamaras.length.toString() + " Resultados" 
      : listCamaras.length.toString() + " Resultado"
    
    return(
        <div className="col-sm-12 col-md-9 ml-4 mr-4" id="listCams">
            {resultados && <div className="h3 m-2 titles justify-content-center d-flex">
                {label_resultados}
            </div>}
            <div className="row mt-3">
                {listCamaras}
            </div>
        </div>
    )
}

Props

camaras
array
required
Array of camera objects to display
resultados
boolean
required
Controls whether to display the results counter header

Features

Smart Result Counter

The component displays a grammatically correct result count:
listcam.js:4
let label_resultados = listCamaras.length > 1 
  ? listCamaras.length.toString() + " Resultados"  // Plural
  : listCamaras.length.toString() + " Resultado"   // Singular
Examples:
  • 1 camera → “1 Resultado”
  • 5 cameras → “5 Resultados”

Conditional Header

The results header only appears when resultados is true:
listcam.js:9
{resultados && <div className="h3 m-2 titles justify-content-center d-flex">
    {label_resultados}
</div>}

Grid Layout

Cameras are rendered in a responsive Bootstrap grid that automatically wraps:
<div className="row mt-3">
    {listCamaras}
</div>

Layout Behavior

The component takes up 9 columns on medium+ screens (col-md-9), designed to work alongside the 3-column NavbarAside filter sidebar:
┌─────────────────────────────────────────────┐
│  NavbarAside  │      ListCam                │
│   (3 cols)    │      (9 cols)               │
│               │  ┌──────┐ ┌──────┐ ┌──────┐ │
│  [Filters]    │  │ Card │ │ Card │ │ Card │ │
│               │  └──────┘ └──────┘ └──────┘ │
└─────────────────────────────────────────────┘

Usage Example

import { ListCam } from './components/listcam'
import { CardsCam } from './components/cardscamara'

const ProductsPage = () => {
  const cameras = useSelector((state) => state.camaras)
  
  return (
    <div className="container">
      <div className="row">
        <ListCam camaras={cameras} resultados={true} />
      </div>
    </div>
  )
}

Customization

Modifying Display Fields

To change which camera attributes appear on cards, update the FIELDS_CARD constant:
const.js
// Current fields
const FIELDS_CARD = ["diseño", "resolucion", "conectividad", "marca", "tipo_de_camara"]

// Example: Add price and remove marca
const FIELDS_CARD = ["diseño", "resolucion", "conectividad", "precio", "tipo_de_camara"]

Styling Considerations

The components use several custom CSS classes:
  • img-responsivess - Responsive image sizing
  • card-modelo - Model name header styling
  • cartas - Card body styling
  • link-light - Light-colored link styling
  • titles - Results counter title styling
Ensure your camera objects include all fields specified in FIELDS_CARD, otherwise undefined values will display on cards.

ViewCamera

Detailed camera view component

NavbarAside

Filter sidebar that works with ListCam

FilterCamara

Main filtering logic component

Build docs developers (and LLMs) love