Recomiendo que cuando se abra el aside de checkout y después que le das click a alguna tarjeta de nuevo, cerrar el aside de chekout porque sigue quedando abierto por debajo
Introducción
Construye una tienda online con React
Enrutamiento y estructura base
Instalación de React con Vite y TailwindCSS
Análisis de rutas y componentes en React
Enrutamiento con React Router DOM
Componente Navbar
Componente de Layout
Componente de Card
Consumiendo la FakeStore API para pintar cards
Manejo de estado global con Context
Contexto global de la aplicación
Contador de productos en el carrito
Abriendo el detalle de cada producto
Reto: heroicons con TailwindCSS
Maquetando el ProductDetail
Mostrando productos en ProductDetail
Carrito de Compras
Agregando productos al carrito
SideMenu del carrito de compras
Componente OrderCard
Evitando productos duplicados en el carrito
Eliminar productos del carrito
Suma total de productos en el carrito
Checkout y Órdenes de Compra
Flujo para crear una nueva orden
Checkout de productos en el carrito
Página de MyOrders: lista de órdenes
Página de MyOrder: órden individual
Reto: órdenes de compra con TailwindCSS
Filtrando productos desde el frontend
Buscador de productos
Filtrando títulos con JavaScript
Filtrando categorías con JavaScript
Corrigiendo bugs de la aplicación
Próximos pasos
Deploy de React en Netlify
¿Preparada o preparado para un Laboratorio de React?
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Estefany Aguilar
Aportes 20
Preguntas 2
Recomiendo que cuando se abra el aside de checkout y después que le das click a alguna tarjeta de nuevo, cerrar el aside de chekout porque sigue quedando abierto por debajo
No sé si a alguien más le pase como a mí, la Card de ‘My order’ no se mostraba por un problema de estilos, pero sí era renderizada en el navegador.
Solamente le agregué un top-20 a las clases de tailwind:
<aside
className={`${context.IsCheckoutSideMenuOpen ? 'flex' : 'hidden'} checkout-side-menu flex-col fixed top-20 right-0 border border-black rounded-lg bg-white`}
>
CheckoutSideMenu
en Home
?Una posible causa. Según lo que estuve viendo, parece ser un problema con el enrutamiento y la forma en que se renderiza el componente. Es posible que el componente CheckoutSideMenu
esté oculto por <AppRouters />
Un compañero en los comentarios de estudio de Platzi sugiere agregarle top-20
y así debería funcionar.
Otra posible solución sugerida por otro compañero es colocar el componente CheckoutSideMenu
en el componente Home
, pero le argumentan lo siguiente:
El problema es que si luego quieres abrir el componente desde otra página, no se va a poder si está solo en
Home
.
Mi posible solución es agregar el componente en el componente Layout
, ya que se puede compartir con otras páginas y no sería necesario agregarle top-20
.
Cuando apretamos el signo + , le añadí esta notificacion/alerta:
Tal vez ya muchos lo sepan y sea un poco tarde decirlo pero
si en vez de crear carpeta escriben ‘NombreCarpeta/index.jsx’ se crean la carpeta y contendrá el nombre del archivo que pusieron en este caso index
Hay una extensión que me ayuda a cuando agrego propiedades o un usestate, este se agrega con un tab.
Te comparto lo comparto:
https://marketplace.visualstudio.com/items?itemName=TabNine.tabnine-vscode
Seria recomendable cerrar el addProductToCart con la sentencia
context.closeCheckoutSideMenu() para cuando se clickea en la tarjeta?
Para simplificar el código he creado un componente Aside:
import { XMarkIcon } from "@heroicons/react/24/solid";
const Aside = (props) => {
const {
isOpen,
title,
children,
onClose
} = props;
return (
<aside className={`${isOpen ? "flex" : "hidden"} w-[360px] h-[calc(100vh-80px)] flex flex-col fixed right-0 border border-black rounded-lg bg-white p-6`}>
<div className="flex justify-between items-center">
<h2 className="font-medium text-xl">{title}</h2>
<div>
<XMarkIcon
className="h-6 w-6 text-black cursor-pointer"
onClick={() => onClose()}
/>
</div>
</div>
{children}
</aside>
)
}
export { Aside }
ProductDetail:
import { useContext } from 'react';
import { ShoppingCartContext } from '../../Context';
import { Aside } from '../Aside';
const ProductDetail = () => {
const {
isProductDetailOpen,
closeProductDetail,
productDetail
} = useContext(ShoppingCartContext);
return (
<Aside isOpen={isProductDetailOpen} title="Detail" onClose={() => closeProductDetail()}>
<figure>
<img
className="w-full h-hull rounded-lg"
src={productDetail.images}
alt={productDetail.title}
/>
</figure>
<p className='flex flex-col'>
<span className="font-medium text-2xl mb-2">{productDetail.price}</span>
<span className="font-medium text-md">{productDetail.title}</span>
<span className='font-light text-sm'>{productDetail.description}</span>
</p>
</Aside>
);
}
export { ProductDetail }
Checkout:
import { useContext } from "react"
import { ShoppingCartContext } from "../../Context"
import { Aside } from "../Aside";
const CheckoutSideMenu = () => {
const {
isCheckoutSideMenu,
closeCheckoutSideMenu
} = useContext(ShoppingCartContext);
return (
<Aside isOpen={isCheckoutSideMenu} title="My order" onClose={() => closeCheckoutSideMenu()}>
</Aside>
)
}
export { CheckoutSideMenu }
creo que vieron openheimer
Sugerencia:
A los 11’ del video se incluye el componente “CheckoutSideMenu” en el App.
Veo que el compnente “CheckoutSideMenu” puede ser incluido dentro del componente “Home” en vez de que sea incluido dentro del App.
Entonces solo dentro del App tendríamos 3 elementos:
Context provider
Router
NavBar
Aquí va el código incluido dentro del componente Home:
import { useState, useEffect } from 'react'
import Layout from '../../components/layout/Layout'
import Card from '../../components/card/Card'
import ProductDetail from '../../components/productdetail/ProductDetail'
import CheckoutSideMenu from '../../components/checkoutsidemenu/CheckoutSideMenu'
const url = 'https://api.escuelajs.co/api/v1/products'
function Home() {
const [items, setItems] = useState(null)
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(datita => {
setItems(datita)
console.log(datita.length)
console.log('datita', datita)
})
}, [])
return (
<Layout>
Home
<div className='grid gap-4 grid-cols-4 w-full max-w-screen-lg'>
{
items?.map((item) =>{
return <Card key={item.id} item={item} />
})
}
</div>
<ProductDetail/>
<CheckoutSideMenu/>
</Layout>
)
}
export default Home
Si tienen alguna observación, bienvenida sea.
se cayó la API
Les comparto mi avance
En el minuto 8:30 menciona el error que existe en los 2 botones donde se traslapan el ProductDetail y el CheckoutSideMenu lo que hice para solucionarlo fue cambiar el orden de las etiquetas <figure/> ,<p> ,<button> y algunas modificaciones mínimas en el css
El orden y el ccs destacado para que nos se traslapen los eventos y se mantenga todo en su lugar es el siguiente:
<div className='relative'>
<figure className='relative'
onClick={() => showProductDetail(data)}>
<span className='absolute'>Categoria</span>
<img src='....' alt='..'/>
<p>
<span>Titulo</span>
<span>Precio</span>
</p>
</figure>
<button className='absolute top-0 right-0'>
+
</button>
</div>
Como se podrán dar cuenta metí la etiqueta <p> dentro de <figure> y saque de <figure> el <button>
El primer <div> se pone también en relative y el Button en absolute.
Y queda todo separado 😃
Aun así les dejo captura de mi código por si quedo alguna duda.
import { useContext } from 'react’
import { OrderContext } from '…/…/Context’
import BuildingStorefrontIcon from ‘@heroicons/react/24/outline/BuildingStorefrontIcon’
const Card = (data) => {
//Order . count items
const context = useContext(OrderContext)
//funcion para agregar items a la orden
const addItemsToOrder = (itemData) => {
context.setCount(context.count +1)
context.setOrders([…context.ordersItems, itemData])
}
return(
<div
className=‘grid place-items-center’>
<div className=‘bg-gradient-to-br from-sky-700 … w-56 h-30 rounded-2xl’>
<figure className=‘relative mb-3 w-full’>
<div
className='text-black text-lg font-bold absolute py-2 bottom-2 right-2 flex justify-center items-center bg-white w-8 h-8 p-1 rounded-full’
onClick={() => addItemsToOrder(data.data)}>
<BuildingStorefrontIcon></BuildingStorefrontIcon>
</div>
<h1 className=‘text-center py-2 text-3xl’>{data.data.nombre}</h1>
<h1 className=‘text-center py-2 text-2xl font-bold’>Gs.: {data.data.precio.toLocaleString()}</h1>
</figure>
</div>
</div>
)
}
export default Card
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?