고민해봤는데... 장바구니 페이지를 따로 만드는게 나을거 같음 ㅠ
틀은 대강 만들었고
파이어 베이스에서 장바구니 db불러서 안에 넣어주면 될 듯
1. 장바구니에 실시간으로 유저별 장바구니 항목 가져오기
useEffect(() => {
//장바구니 가져오는 함수
const fetchUserCart = async () => {
if (user) {
//유저가 있을 경우
const q = query(
collection(db, "cart"),
where("userId", "==", user.uid) //로그인 한 유저와 동일한 데이터만
);
//실시간 가져오기
onSnapshot(q, (snapshot) => {
const userCart = snapshot.docs.map((doc) => doc.data());
setUserCart(userCart);
});
}
};
fetchUserCart();
}, [user]); // 로그인 유저가 변경 될 때마다 실행
2. 장바구니 항목 삭제
//장바구니 삭제
const handleRemoveCart = async (value) => {
if (confirm("장바구니에서 삭제하겠습니까?")) {
//2-1)유저가 있으면(로그인)
if (user) {
try {
//쿼리문 작성
const q = query(
collection(db, "cart"), // 삭제할 컬렉션 지정
where("userId", "==", user.uid), // 현재 로그인되어있는 유저와 같은 것
where("interestBook", "==", value) //book.isbn 으로 찾음
);
const querySnapshot = await getDocs(q);
querySnapshot.forEach(async (doc) => {
try {
await deleteDoc(doc.ref); //삭제한다.
console.log("장바구니 삭제 성공!");
} catch (error) {
console.error("Error deleting document:", error);
}
});
} catch (error) {
console.error("Error querying document:", error);
}
}
} else {
return;
}
};
3. 수량 선택 및 실시간 반영하여 확인 (위의 장바구니 가져오는 함수에 onSnapshot을 사용하여
실시간으로 가져오게 만들었음)
<div className="amountSection">
<div
onClick={() =>
handleMinus(cart.interestBook, cart.amount)
}
className="minus"
>
<FaMinus />
</div>
<div className="amount">{cart.amount}</div>
<div
onClick={() =>
handlePlus(cart.interestBook, cart.amount)
}
className="plus"
>
<FaPlus />
</div>
이게 위의 부분인데
- 를 누르면 마이너스로 계산하여 업데이트 , +를 누르면 플러스로 계산하여 업데이트 하게끔 구상함
//수량 변경 - 마이너스
const handleMinus = (bookId, amount) => {
if (amount >= 2) {
const minusAmount = amount - 1;
//console.log(minusAmount);
//DB에서 마이너스 처리하기
updateCart(bookId, minusAmount);
} else {
alert("최소 1개 이상 구매가능합니다.");
}
};
//수량 변경 - 플러스
const handlePlus = (bookId, amount) => {
const plusAmount = amount + 1;
//const plusAmount = num.toString();
//DB에서 플러스 처리하기
updateCart(bookId, plusAmount);
};
그리고 마이너스의 경우 1개의 경우 마이너스를 할 수 없으니 한 개 이상 구매가능하다고 경고창 띄우고 리턴함
수량 업데이트하는 함수
// 수량 업데이트
const updateCart = async (bookId, amount) => {
//카트 컬렉션에서 인증 된 유저, 그리고 수량 선택하는 book의 id들어감
const q = query(
collection(db, "cart"),
where("userId", "==", user.uid),
where("interestBook", "==", bookId)
);
const querySnapshot = await getDocs(q);
querySnapshot.forEach(async (doc) => {
try {
const docRef = doc.ref;
await updateDoc(docRef, { amount: amount });
} catch (error) {
console.error(error);
}
});
};
4. 상품 별 총 금액 계산
<p style={{ fontWeight: "bold" }}>
총 {cart.salesPrice * cart.amount}원
</p>
5. 주문 정보의 총 수량과 총 상품금액 계산하여 주문 금액 산정하기
const [amount, setAmount] = useState([]); // 현재 장바구니의 상품 수량
const [totalAmount, setTotalAmount] = useState(null); //수량 합계
const [totalPrice, setTotalPrice] = useState(null); //금액 합계
useEffect(() => {
//장바구니 가져오는 함수
const fetchUserCart = async () => {
if (user) {
//유저가 있을 경우
const q = query(
collection(db, "cart"),
where("userId", "==", user.uid) //로그인 한 유저와 동일한 데이터만
);
//실시간 가져오기
onSnapshot(q, (snapshot) => {
const userCart = snapshot.docs.map((doc) => doc.data());
const amountResult = snapshot.docs.map((doc) => doc.data().amount);
setUserCart(userCart);
setAmount(amountResult);
//console.log(totalPrice);
});
}
};
//총 상품 수량 합계 구하기
const sumAmount = () => {
const result = userCart.reduce((prev, current) => {
return prev + current.amount;
}, 0);
setTotalAmount(result);
};
//총 상품 금액 합계 구하기
const sumPrice = () => {
const result = userCart.reduce((prev, current, index) => {
//각 상품의 가격과 수량을 곱하여 합산한다.
const itemTotalPrice = current.salesPrice * amount[index];
return prev + itemTotalPrice;
}, 0);
setTotalPrice(result);
};
fetchUserCart();
sumAmount();
sumPrice();
}, [user, userCart]); // 로그인 유저가 변경 될 때마다 실행
DB를 가져올 때 수량만 따로 가져오게 하고 state에 저장함.
reduce() 를 사용해서 배열의 합계를 구해줌
총 상품 금액 합계를 구할 때는 1개의 금액 x 수량의 금액이 나와야 하니까
userCart에서 1개의 금액을 가져오고 i번 인덱스의 amount를 곱해준 후 합한다.
참고
https://miiingo.tistory.com/365
장바구니에 도서가 없을 경우
{userCart.length === 0 ? (
<div
className="cart"
style={{
height: "500px",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<p>장바구니에 상품이 없습니다.</p>
</div>
) :
'FRONTEND > React' 카테고리의 다른 글
리액트 다음 우편번호 검색 API 사용하기 (0) | 2023.12.15 |
---|---|
[React-BookStore] 마이페이지- 관심도서에서 장바구니로 이동 (0) | 2023.12.14 |
[React-BookStore] 장바구니에 데이터 추가 (0) | 2023.12.13 |
[React-BookStore] 마이페이지 - 관심 도서 (0) | 2023.12.13 |
[React-BookStore] 도서 검색 후 관심 도서 추가하기 / 삭제하기 (0) | 2023.12.13 |