No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Adquiere por un a帽o todos los cursos, escuelas y certificados por un precio especial.

Antes: $249

Currency
$219/a帽o

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Comprar ahora

Termina en:

0D
14H
55M
47S

Componente OrderCard

17/31
Recursos

Aportes 21

Preguntas 1

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Si quieren agregar un scroll al apartado, agreguen lo siguiente:

file: CheckoutsideMenu.jsx dentro de className del aside, agregar:

scrollable-cards

quedar铆a as铆:

className={`${context.isCheckoutSideMenuOpen ? 'flex' : 'hidden'} checkout-side-menu scrollable-cards flex-col fixed right-0 border border-black rounded-lg bg-white`}>

En styles.css agregar lo siguiente:

.scrollable-cards {
	overflow: scroll;
}

/* ===== Scrollbar CSS ===== */
  /* Firefox */
  .scrollable-cards {
    scrollbar-width: auto;
    scrollbar-color: #141414 #ffffff;
		/* overflow-x: hidden; */
  }

  /* Chrome, Edge, and Safari */
  .scrollable-cards::-webkit-scrollbar {
    width: 16px;
		/* overflow-x: hidden; */
  }

  .scrollable-cards::-webkit-scrollbar-track {
    background: #ffffff;
		/* overflow-x: hidden; */
  }

  .scrollable-cards::-webkit-scrollbar-thumb {
    background-color: #141414;
    border-radius: 10px;
    border: 3px solid #000000;
		/* overflow-x: hidden; */
  }

Resultado:

Si quieren agregar el mismo producto varias veces, cuando agregan por primera vez un producto le pueden agregar la propiedad 鈥渜uantity鈥 con valor 1. Si en cambio el producto ya fue agregado anteriormente, hay que validar que ese producto est茅 ya en el carrito y aumentarle en uno la propiedad quantity. De esta forma, podemos tambien en nuestro checkout 鈥榩intar鈥 la cantidad de productos de un mismo tipo y el valor total. Dejo el c贸digo por si les interesa.

const [cartProducts, setCartProducts] = useState([]);
	const onAdd = product => {
		const productExists = cartProducts.some(el => el.id === product.id); // dar谩 true si el producto ya se encuentra en el carrito

		if (productExists) {
			// valida la existencia
			const productCart = cartProducts.find(el => el.id === product.id); // busca el producto
			productCart.quantity += 1; // aumenta la cantidad en 1
		} else {
			product.quantity = 1; // si el producto no est谩, le agrega la propiedad quantity con valor uno, y luego setea el carrito agregando ese producto
			setCartProducts([...cartProducts, product]);
		}
		setCount(count + 1);
	};

Por ac谩 dejo como qued贸 el c贸digo para pintar la card en el checkout.

import PropTypes from 'prop-types';

export const CheckoutCard = ({ product }) => {
	CheckoutCard.propTypes = {
		product: PropTypes.object.isRequired,
	};
	return (
		<div className='border-y flex w-full p-2 h-20 items-center gap-x-2'>
			<span className='text-sm w-4'>{product.quantity}</span>
			<figure className='w-1/4 gap-3  flex justify-start'>
				<img
					className='w-full h-full object-contain rounded-lg'
					src={product.images && product.images[0]}
					alt={product.title}
				/>
			</figure>
			<span className='text-sm w-1/2'>{product.title}</span>
			<span className='font-medium text-sm'>${product.price * product.quantity}</span>
		</div>
	);
};

Si quieren hacer su propia API con endpoints y todas las configuraciones que deseen, pueden hacerla localmente con json server y hacer el deploy con Render. Es super f谩cil, les dejo un tutorial, est谩 ingles, pero funciona bien:
https://www.youtube.com/watch?v=EcxYcpF3W7c
Hagan ejemplo del tutorial y luego para actualizarla solo tienen que hacer un commit y push a la misma rama, ya que Render se conecta con github y en pocos minutos su url se actualiza. Sigan la estructura de la Fake API de Platzi para que no tengan errores de undefined en su c贸digo o si cambian la estructura, no se olviden de adaptar el c贸digo.
En el archivo db.json que creen:

{
  "products": [
  {
    "id": 1,
    "title": "Handmade Fresh Table",
    "price": 687,
    "description": "Andy shoes are designed to keeping in...",
    "category": {
      "id": 5,
      "name": "Others",
      "image": "https://placeimg.com/640/480/any?r=0.591926261873231"
    },
    "images": [
      "https://placeimg.com/640/480/any?r=0.9178516507833767",
      "https://placeimg.com/640/480/any?r=0.9300320592588625",
      "https://placeimg.com/640/480/any?r=0.8807778235430017"
    ]
  },
  {
    "id": 2,
    "title": "Handmade Fresh ",
    "price": 687,
    "description": "Andy shoes",
    "category": {
      "id": 5,
      "name": "Others",
      "image": "https://placeimg.com/640/480/any?r=0.591926261873231"
    },
    "images": [
      "https://placeimg.com/640/480/any?r=0.9178516507833767",
      "https://placeimg.com/640/480/any?r=0.9300320592588625",
      "https://placeimg.com/640/480/any?r=0.8807778235430017"
    ]
  },
  	.
  	. El Resto de Productos
  	.
  ],
  "categories": [
  {
    "id": 1,
    "name": "Clothes",
    "image": "https://api.lorem.space/image/fashion?w=640&h=480&r=4278"
  },
  {
    "id": 2,
    "name": "Electronics",
    "image": "https://api.lorem.space/image/fashion?w=640&h=480&r=4278"
  },
	.
	. El Resto de Categorias
	.
  ]
}

As铆 esta mi carrito de compras hasta ahora :3

No s茅 porque tengo que agregar este detalle de PropTypes en React pero lo tengo as铆 y funciona bien (gracias a un comentario en una clase previa):

Como nota, podemos pasar directamente las props entre llaves en ves de escribir 鈥榩rops鈥 y luego hacer destructuring.

import PropTypes from 'prop-types'

export const OrderCard = ({ title, imageUrl, price }) => {
  OrderCard.propTypes = {
    title: PropTypes.node.isRequired,
    imageUrl: PropTypes.node.isRequired,
    price: PropTypes.node.isRequired,
  }

  return (
    <div className="flex justify-between items-center mb-3">
      <div className="flex items-center gap-2">
        <figure className="w-20 h-20">
          <img className="w-full h-full rounded-lg object-cover" src={imageUrl} alt={title} />
        </figure>
        <p className="text-sm font-light">{title}</p>
      </div>
      <div className="flex items-center gap-2">
        <p className="text-lg font-medium">${price}</p>
        {/* X close icon */}
        <svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="w-6 h-6 cursor-pointer">
          <path fillRule="evenodd" d="M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z" clipRule="evenodd" />
        </svg>
      </div>
    </div>
  )
}

poner opci贸n de cantidad en cada producto y multiplicar valor por cantidad:

para poner la opci贸n de elegir la cantidad deseada de cada producto agregu茅 un input en el OrderCard:

<div className='flex justify-between items-center'>
        <div className='flex  items-center gap-2'>
            <figure className='w-20 h-20'>
                <img className='w-full h-full rounded-lg object-fill' src={url} alt={name} />
            </figure>
            <div className='flex flex-col justify-center'>
                <p className='text-sm font-light'> {name} </p>
                <div className='flex items-center gap-2'>
                <label className='text-sm font-thin' htmlFor="quantity"> Qty</label>
                <input 
                className='w-1/2 border border-black rounded-lg text-md' type="number"  
                name='quantity'
                value={quantity}
                onChange={(e) => handleOnChange(e) }/>
                 </div>   
                
            </div>
            
        </div>
        <div className='flex  items-center gap-2'>
            <p className='text-lg font-medium font-mono'>{total} </p>
            <XMarkIcon className='h-6 w-6 text-black hover:cursor-pointer'></XMarkIcon>  
        </div>      
    </div>

adicionalmente una funci贸n para hacer el calculo del valor:

const [quantity, setQuantity] = useState(1);
const [total, setTotal] = useState(price);

const handleOnChange = (event) => {
    setQuantity(event.target.value);
    setTotal(price * event.target.value);
    
}

Yo le quise dar la opcion al usuario que pueda subir o bajar la cantidad del producto que desea comprar desde el shopping cart

Para que no se muestre un titulo tan largo y tengamos problemas que se juntal el titulo con el precio, agregue un archivo css en donde tengo una clase con max-width y esta clase la utiliza el p de el titulo, de esta manera permitimos que no quede el titulo encima del precio

Siento mucho alivio haber tomado la INCRE脥BLE saga de TypeScript de NicoBytes, antes de llegar aqu铆. 馃ぇ

Si quieren un scroll en su componente CheckoutSideMenu solo agreguen la clase ```
overflow-y-scroll



Dejo mi proyecto hasta ahora:

![](

Para poder agregar el mismo item al carrito varias veces pueden usar el indice del item en el arreglo como key

          {context.cartProducts.map((product, index) =>
            <OrderCard key={index} product={product} />
          )}

As铆 me quedo el dise帽o.
DP: Por ahora xD

Por si alguien le sirve, en vez de no dejar agregar un producto ya existente, hice que se a帽ada 鈥渃antidades鈥

Este es el c贸digo en context file

    const incrementShoppingCart = (e, product) => {
        e.stopPropagation();
        setCount(count + 1);
        setIsCheckoutSideMenu(true);
        setIsPorductModalOpened(false);
        const productInCart = cartProducts.filter(
            (cartProduct) => cartProduct.product.id === product.id
        );
        console.info({ cartProducts });
        if (productInCart.length === 0) {
            setCartProducts((prevProducts) => [
                ...prevProducts,
                {
                    product,
                    quantity: 1,
                },
            ]);
        } else {
            setCartProducts((prevProducts) => {
                const productIndex = prevProducts.findIndex(
                    (prod) => prod.product.id === product.id
                );
                prevProducts[productIndex] = {
                    product,
                    quantity: productInCart[0].quantity + 1,
                };

                return prevProducts;
            });
        }
    };

![](

Ya resolv铆 el reto y le cambi茅 el color al div para que cuando est茅 agregado sea m谩s notorio el cambio en la interfaz del usuario
.

Tambi茅n se pueden instalar la extensi贸n React-Native/React/Redux snippets for es6/es7.
El comando _slr_les autocompleta la misma estructura con todo y el export default

Si desean agregar mas de un producto del mismo tipo,pero tienen conflictos con la 鈥榢ey鈥 que debe ser 煤nica en React,pudiera ser tentador usar el 铆ndice del elemento como 鈥榢ey鈥. Sin embargo,la propia documentaci贸n de React aconseja no hacerlo.

En su lugar decid铆 descargar una librer铆a generadora de 鈥榢eys鈥

npm i uuidv

La importo y la uso de la siguiente manera:

import { v4 as uuidv4 } from 'uuid'

return<OrderCard
              key={uuidv4()} 
              indice={index} 
              title={product.title}
              imageUrl={product.images}
              price={product.price}
              handleDelete={handleDelete}

Por supuesto,seguro que hay soluciones mejores para resolver el problema,como hacer que en una sola card se sume el numero de productos del mismo tipo y el precio a cobrar.

Pero para salir del paso y que todav铆a sea entendible,esta es la soluci贸n mas r谩pida que encontr茅.

No entiendo por que no permite comprar mas de un elemento de cada producto!!
En un ecommerce entre m谩s se compre, mejor!!