I'm creating a cart and I need to add the item, the function has the id of the item as a requirement, but my item only generates the _id and not just the id. The problem to be simple for those who have a lot of knowledge, thanks in advance to the collaborators
Index.js ( Product details )
import React, { useState, useEffect } from "react";
import { useParams } from "react-router";
import Popup from "reactjs-popup";
import "reactjs-popup/dist/index.css";
import { ThreeDots } from "react-loader-spinner";
import { useCart } from "react-use-cart";
//Local
import Nav from "../../components/Nav";
import api from "../../../services/api";
import Best from "../Best/index";
import { TitleCaurosel } from "../style";
//Icons / Images
import { AiFillStar } from "react-icons/ai";
import { BsArrowLeft, BsArrowRight } from "react-icons/bs";
//Style
import {
Product,
Images,
Main,
Other,
Details,
Title,
Description,
Stars,
Colors,
Color,
ColorSelected,
Price,
Cart,
} from "./style";
const Index = () => {
const params = useParams();
const { addItem } = useCart();
const [data, setData] = useState(undefined);
const [error, setError] = useState(undefined);
const [color, setColor] = useState(undefined);
const [nameColor, setNameColor] = useState(undefined);
const [index, setIndex] = useState(0);
const [popup, setPopup] = useState(false);
const [current, setCurrent] = useState(0);
const [main, setMain] = useState(undefined);
const ref = React.createRef();
const { height, width } = useWindowDimensions();
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height,
};
}
function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(
getWindowDimensions()
);
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return windowDimensions;
}
const config = {
headers: {
"Content-type": "application/json",
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
};
useEffect(() => {
api.get(`/items/${params.id}`).then((response) => setData(response.data));
}, []);
const addToCart = () => {
if (color !== undefined) {
api
.post(
`/cart`,
{
itemId: params.id,
quantity: 1,
colors: data.images,
colorSelected: color,
img: data.images[0].src,
},
config
)
.then((response) => {
if (response.status === 200 || response.status === 201) {
window.location.pathname = "/Cart";
}
});
} else {
setError(1);
}
};
const numberFormat = (value) =>
new Intl.NumberFormat("pt-br", {
style: "currency",
currency: "BRL",
}).format(value);
const handleTab = (index) => {
setMain(undefined);
setIndex(index);
if (color !== undefined && nameColor !== undefined) {
setColor(undefined);
setNameColor(undefined);
}
};
const nextSlide = () => {
setCurrent(current === data.images.length - 1 ? 0 : current 1);
};
const prevSlide = () => {
setCurrent(current === 0 ? data.images.length - 1 : current - 1);
};
useEffect(() => {
if (data !== undefined) {
if (!Array.isArray(data.images) || data.images.length <= 0) {
return null;
}
}
});
const changeColor = (id, name) => {
setColor(id);
setNameColor(name);
setError(undefined);
const filter = data.images.filter((item) => item._id === id);
setMain(filter[0].src);
};
return data !== undefined ? (
<div>
{/*Popup*/}
{popup === true && (
<Popup
open={true}
position="center center"
onClose={() => setPopup(false)}
>
<section className="slider">
<BsArrowLeft className="left-arrow" onClick={prevSlide} />
<BsArrowRight className="right-arrow" onClick={nextSlide} />
{data.images.map((slide, index) => {
return (
<div
className={index === current ? "slide active" : "slide"}
key={index}
>
{index === current && (
<div
style={{
width: width / 2,
height: height / 2,
backgroundImage: `url(${slide.src})`,
backgroundRepeat: "no-repeat",
backgroundSize: "contain",
backgroundPosition: "center",
}}
/>
)}
</div>
);
})}
</section>
</Popup>
)}
<Nav />
<div
style={{
height: "90vh",
display: "grid",
justifyContent: "center",
alignItems: "center",
gridTemplateColumns: "85%",
gridTemplateRows: "100%",
gridColumnGap: "5px",
}}
>
<Product key={data._id}>
<Images>
<div
style={{
display: "grid",
marginRight: "3%",
height: height / 1.3,
}}
ref={ref}
>
<Other
style={{
width: width / 10,
backgroundImage: `url(${data.images[0].src})`,
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
backgroundSize: "60%",
}}
alt={`Image de ${data.name}`}
key={0}
onClick={() => handleTab(0)}
/>
{data.images[1] !== undefined && (
<Other
style={{
marginTop: "5%",
width: width / 10,
backgroundImage: `url(${data.images[1].src})`,
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
backgroundSize: "60%",
}}
alt={`Image de ${data.images[1].name}`}
key={1}
onClick={() => handleTab(1)}
/>
)}
{data.images[2] !== undefined && (
<Other
style={{
marginTop: "5%",
width: width / 10,
backgroundImage: `url(${data.images[2].src})`,
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
backgroundSize: "60%",
}}
alt={`Image de ${data.name}`}
key={2}
onClick={() => handleTab(2)}
/>
)}
{data.images[3] !== undefined && (
<Other
style={{
marginTop: "5%",
width: width / 10,
backgroundImage: `url(${data.images[3].src})`,
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
backgroundSize: "60%",
}}
alt={`Image de ${data.name}`}
key={1}
onClick={() => handleTab(3)}
/>
)}
{data.images[4] !== undefined && (
<div>
{data.images.length < 5 ? (
<Other
style={{
width: width / 10,
backgroundImage: `url(${data.images[3].src})`,
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
backgroundSize: "60%",
}}
alt={`Image de ${data.name}`}
key={2}
onClick={() => handleTab(3)}
/>
) : (
<Other
style={{
width: width / 10,
}}
onClick={() => setPopup(true)}
alt={`Image de ${data.name}`}
>
<p> 5</p>
</Other>
)}
</div>
)}
</div>
<div
style={{
backgroundColor: "#F6F6F6",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<Main
style={{
backgroundImage: `url(${
main === undefined ? data.images[index].src : main
})`,
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
backgroundSize: "80%",
width: width / 2.8,
height: height / 1.5,
}}
/>
</div>
</Images>
<Details>
<Title>{data.name}</Title>
<Description>{data.description}</Description>
<Stars>
<AiFillStar />
<AiFillStar />
<AiFillStar />
<AiFillStar />
<AiFillStar />
<p>441 Avaliações</p>
</Stars>
<Colors>
{error === undefined && color === undefined && (
<p style={{ color: "#000" }}>Selecione uma cor:</p>
)}
{error === 1 && color === undefined && (
<p style={{ color: "#ff0000" }}>
Selecione uma cor: (Obrigatório)
</p>
)}
{error === undefined &&
color !== undefined &&
nameColor !== undefined && (
<p style={{ color: "#000" }}>Cor selecionada: {nameColor}</p>
)}
<div
style={{
display: "flex",
marginTop: "1%",
width: "100%",
flexWrap: "wrap",
alignItems: "center",
}}
>
{data.images.map((item) =>
color === item._id ? (
<ColorSelected onClick={() => setColor(undefined)}>
<div style={{ backgroundColor: item.color }} />
</ColorSelected>
) : (
<Color
style={{ backgroundColor: item.color }}
onClick={() => {
changeColor(item._id, item.name);
}}
/>
)
)}
</div>
</Colors>
<Price>{numberFormat(data.price)}</Price>
{console.log(data)}
<Cart onClick={() => addItem(data)}>
Adicionar ao carrinho
</Cart>
</Details>
</Product>
</div>
<div style={{ paddingLeft: "130px" }}>
<TitleCaurosel>Você pode gostar!</TitleCaurosel>
<Best />
</div>
</div>
) : (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
width: width,
height: height,
}}
>
<ThreeDots
height="300"
width="300"
radius="9"
color="#8c6d55"
ariaLabel="three-dots-loading"
wrapperStyle={{}}
wrapperClassName=""
visible={true}
/>
</div>
);
};
export default Index;
Cart.js
import React, { useState, useEffect } from "react";
import Nav from "../components/Nav";
import Select from "react-select";
import api from "../../services/api";
import { ThreeDots } from "react-loader-spinner";
import { useCart } from "react-use-cart";
//Icons
import { BiTrash } from "react-icons/bi";
import { MdOutlineEditLocationAlt } from "react-icons/md";
import { HiOutlineShoppingBag } from "react-icons/hi";
//Style
import {
Container,
Box1,
Box2,
Box3,
Title,
Product,
Image,
Name,
Price,
Border,
Stock,
PriceTotal,
Delete,
Cupom,
BorderTraced,
Subtotal,
Items,
Total,
Checkout,
NextToBuy,
Empty,
} from "./style";
const Index = () => {
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height,
};
}
function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(
getWindowDimensions()
);
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return windowDimensions;
}
const { height, width } = useWindowDimensions();
const {
isEmpty,
items,
cartTotal,
updateItemQuantity,
removeItem,
emptyCart,
} = useCart();
return (
<Container>
{isEmpty ? (
<Empty>
<Nav />
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
textAlign: "center",
height: "80vh",
}}
>
<div>
<HiOutlineShoppingBag className="icon-empty" />
<h1>Sua sacola está vazia</h1>
<p className="text-empty">
Parece que você não adicionou nada a sua sacola. <br /> Vá em
frente e explore as principais categorias.
</p>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
textAlign: "center",
}}
>
<a className="button" href="/#Produtos">
Explorar produtos
</a>
</div>
</div>
</div>
</Empty>
) : (
<Container>
<Nav />
<div
style={{
display: "flex",
justifyContent: "center",
height: height,
marginTop: "3%",
marginBottom: "10%",
}}
>
<Box1 style={{ width: width / 2.8, height: height }}>
<Title>Seus items</Title>
</Box1>
<div>
<Box2 style={{ width: width / 4, height: height / 5 }}>
<Title>Frete</Title>
<p className="title">Endereço:</p>
<span></span>
<span></span>
<p className="title">Estimativa de entrega:</p>
<span>30/12/2022</span>
<MdOutlineEditLocationAlt />
</Box2>
<Box3 style={{ width: width / 4, height: height / 1.4 }}>
<Cupom>
<input placeholder="Cupom de desconto" />
<button>Aplicar</button>
</Cupom>
<BorderTraced />
<Subtotal>
<p>Subtotal</p>
<p></p>
</Subtotal>
<Items>
<div>
<p>Frete</p>
<p>R$ 399,99</p>
</div>
</Items>
<BorderTraced />
<Total>
<p>Total</p>
<p></p>
</Total>
<Checkout>Finalizar compra</Checkout>
<NextToBuy
onClick={() => {
window.location.pathname = "/Products";
}}
>
Continuar comprando
</NextToBuy>
</Box3>
</div>
</div>
</Container>
)}
</Container>
);
};
export default Index;
Index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Routes from './routes';
import { CartProvider } from 'react-use-cart';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<CartProvider>
<Routes />
</CartProvider>
</React.StrictMode>
);
CodePudding user response:
Not sure if this is the best/most efficient approach, but you could always create an Item object with the attributes required for the addItem() method. Then map the required data from your data object to the new item object, and instead of using addItem(data) you could use addItem(item).
CodePudding user response:
Add the property when setting the value:
useEffect(() => {
api.get(`/items/${params.id}`)
.then(({ data }) => {
setData({
...data,
id: data._id
});
});
}, []);