여기 작업할 때 db를 수정이 좀 많이 들어감
- 처음에 설계한 DB는 장바구니에 있는 모든 항목들을 결제하기 페이지에서 다 가져왔었음.
- 근데 그렇게 하다보니 장바구니에 넣지않고 바로 결제하기를 클릭할 경우에는 장바구니에 있는 상품 + 결제하기 클릭한 상품이 결제하기 페이지로 넘어가게 됨.
- 그래서 이 단계를 구분하기 위해서 DB의 수정을 하기로 함
- 주문 준비를 나타내는 orderReady의 필드를 추가해서
- 1) 검색 결과에서 장바구니로 추가될 경우에는 orderReady를 false를 주고
- 2) 장바구니에서 <주문하기> 를 클릭할 경우 orderReady 를 true로 업데이트한다.
- 그래서 결제하기 페이지에서 cart를 불러올 때 쿼리문에서 orderReady가 true인 상품들만 가져온다
- 3) 검색 결과에서 <결제하기>를 클릭할 경우에도 orderReady를 바로 true로 추가한 뒤 바로 결제 페이지로 이동한다.
- 그리고 결제하기가 완료되면 order 필드에 true로 업데이트해서 주문 목록에서는 쿼리문으로 order true로 변경하여 해당 목록만 가져오게 함
1. 검색 결과에서 결제하기 클릭할 경우
const AddPayment = async () => {
if (confirm("해당 도서를 바로 구매하시겠습니까?")) {
if (!user) {
//유저가 없으면(로그인 되어있지 않을 경우)
alert("로그인이 필요한 서비스입니다.");
navigate("/user/login"); //로그인 페이지로 이동
} else {
//DB에 저장한다.
try {
await addDoc(collection(db, "cart"), {
//컬렉션명 -interestBooks
interestBook: book.isbn, //book id
bookTitle: book.title, //book title
bookCover: book.cover, //book cover
bookLink: book.link, //book link
bookAuthor: book.author, //book author
bookPublisher: book.publisher, //book publisher
salesPrice: book.priceSales, // book sales Price
amount: 1,
priceStandard: book.priceStandard,
order: false, //주문 완료 여부
orderReady: true, // 주문 준비 (결제 준비) 완료 여부
createdAt: Date.now(), // 생성일자 오늘
username: user.displayName, // 유저 이름
userId: user.uid, // 유저 아이디
});
} catch (error) {
console.log(error); //에러는 콘솔에 출력
}
}
navigate("/user/payment"); //결제 페이지로 이동
} else {
alert("취소");
return;
}
};
2. 장바구니에서 주문하기 클릭할 경우 orderReady 업데이트
//주문하기 클릭 할 경우 문서의 orderReady을 업데이트한다.
const handleOrderReady = async (bookIds) => {
// 각각의 책(book) ID에 대해 주문을 완료합니다.
bookIds.forEach(async (bookId) => {
const q = query(
collection(db, "cart"),
where("userId", "==", user.uid),
where("interestBook", "==", bookId),
where("order", "==", false), //주문 하기 전 상품
where("orderReady", "==", false)
);
const querySnapshot = await getDocs(q);
querySnapshot.forEach(async (doc) => {
try {
const docRef = doc.ref;
await updateDoc(docRef, {
orderReady: true, //주문 준비 완료
});
} catch (error) {
console.error(error);
}
});
});
};
//주문하기 클릭 시
const handleClickPayment = () => {
if (userCart.length === 0) {
alert("장바구니에 상품이 없습니다!");
return;
} else if (userCart.length >= 1) {
if (confirm("주문하시겠습니까?")) {
const bookIds = userCart.map((cart) => cart.interestBook);
handleOrderReady(bookIds);
navigate("/user/payment");
}
return;
}
};
3. 결제하기 화면
//장바구니 가져오는 함수
const fetchUserCart = async () => {
if (user) {
//유저가 있을 경우
const q = query(
collection(db, "cart"),
where("userId", "==", user.uid), //로그인 한 유저와 동일한 데이터만
where("order", "==", false), //주문 하기 전 상품
where("orderReady", "==", true)
);
//실시간 가져오기
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);
});
}
};
다음 우편번호 찾기 api 사용해서
우편 번호 찾을 수 있고, 이 값들을 state로 관리해서 자동으로 input에 가져오게 만듬
const [userFullAddress, setFullAddress] = useState(""); //유저 주소
const [userZoneCode, setUserZoneCode] = useState(""); //유저 우편번호
//다음 우편번호 찾기 API사용
const open = useDaumPostcodePopup(postcodeScriptUrl);
const handleComplete = (data) => {
let fullAddress = data.address;
let extraAddress = "";
let zonecode = data.zonecode;
if (data.addressType === "R") {
if (data.bname !== "") {
extraAddress += data.bname;
}
if (data.buildingName !== "") {
extraAddress +=
extraAddress !== "" ? `, ${data.buildingName}` : data.buildingName;
}
fullAddress += extraAddress !== "" ? ` (${extraAddress})` : "";
}
setFullAddress(fullAddress); // e.g. '서울 성동구 왕십리로2길 20 (성수동1가)'
setUserZoneCode(zonecode);
};
const handleClick = () => {
open({ onComplete: handleComplete });
};
<input type="text" defaultValue={userZoneCode} required />
<input
className="infoInput"
type="text"
defaultValue={userFullAddress}
required
/>
4.결제 완료 화면
order -> true로 업데이트
주문 상세 확인으로 마이페이지에 있는 주문/결제 목록으로 이동한다.
onClick={() => navigate("/user/mypage?order=true")}
마이페이지는 메뉴를 선택해서 state의 값을 업데이트하고 그 값에 맞게 페이지가 출력되게 구성해놔서
디폴트 값은 관심 도서 메뉴이다.
<div className="userpageContainer">
<div className="aside">
<h3>마이페이지</h3>
<br />
<ul>
<li onClick={() => handleChange("관심 도서")}>관심 도서</li>
<li onClick={() => handleChange("주문 목록")}>주문/결제 목록</li>
</ul>
</div>
<div className="mypage">
<h2>{selectedMenu}</h2>
<div className="mypageContent">
{/* 관심 도서 컴포넌트 */}
{selectedMenu === "관심 도서" ? <InterestedBook /> : ""}
{selectedMenu === "주문 목록" ? <OrderPage /> : ""}
</div>
</div>
</div>
그래서
주문 성공페이지에서 넘어온 파라미터값을 받아서 state에 제일 처음 세팅해주면
const queryString = useLocation().search;
const queryParams = new URLSearchParams(queryString);
const query = queryParams.get("order"); // q에 해당하는 값을 쿼리스트링에서 가져옴
const [selectedMenu, setSelectedMenu] = useState("관심 도서");
//주문 완료에서 넘어올 때
useEffect(() => {
if (query === "true") {
setSelectedMenu("주문 목록");
}
}, [query]);
주문 성공 페이지에서 넘어오면 바로 주문 목록 페이지로 넘어간다
현재로써 한가지 수정해야할게
결제하기 페이지까지 넘어갔는데 페이지를 벗어날경우에는 orderReady가 true로 변경되어 있는 상태에서 벗어나다보니
장바구니에서 보이지 않는 현상이 있음 ㅠ
그래서 찾아보니까
리액트 라우터에서 기능 중 하나인 Prompt를 사용해볼려고함
https://minjung-jeon.github.io/React-Prompt/
'FRONTEND > React' 카테고리의 다른 글
[React-BookStore] 프레젠테이션 만들기 (0) | 2023.12.17 |
---|---|
[React-BookStore] netlify 배포하기 <Vite>/ firebase 도메인 등록 (0) | 2023.12.15 |
리액트 다음 우편번호 검색 API 사용하기 (0) | 2023.12.15 |
[React-BookStore] 마이페이지- 관심도서에서 장바구니로 이동 (0) | 2023.12.14 |
[React-BookStore] 장바구니 완성 (0) | 2023.12.14 |