본 내용의 코드는 전부 위 링크에 있으니 참고바랍니다
주문인증 페이지 (AuthenticationPage.js)
useRef를 통해 Input focus
- 전화번호 중 지역번호는 2~3자리, 둘째 칸은 4자리, 마지막 칸은 4자리 형식으로 작성하면 다음 Input으로 focus
- 비밀번호는 4자리 형식으로 작성하면 제출버튼으로 focus
- 지역번호, 전화번호 둘째 칸, 전화번호 마지막 칸, 비밀번호, 제출버튼에 ref 속성 추가
...
// 정규표현식
const reg = useMemo(() => /^[0-9]{4}$/, []);
// 지역번호에서 전화번호 둘째칸으로 이동
useEffect(() => {
if ((/^[0-9]{2,3}$/).test(number1)) {
refNum2.current.focus();
};
}, [number1, reg]);
// 전화번호 둘째칸에서 마지막 칸으로 이동
useEffect(() => {
if (reg.test(number2)) {
refNum3.current.focus();
};
}, [number2, reg]);
// 전화번호 마지막 칸에서 비밀번호 칸으로 이동
useEffect(() => {
if (reg.test(number3)) {
refPw.current.focus();
};
}, [number3, reg]);
// 비밀번호 칸에서 제출 버튼으로 이동
useEffect(() => {
if (reg.test(pw)) {
submitFocus.current.focus();
};
}, [pw, reg]);
...
주문 인증 POST
1. 제어 컴포넌트로 인증 input 객체 생성
...
// 전화번호(지역번호, 둘째칸, 마지막 칸), 비밀번호
const [inputs, setInputs] = useState({
number1: "010",
number2: "",
number3: "",
pw: "",
});
const { number1, number2, number3, pw } = inputs;
// input 객체 생성
const onChange = (e) => {
const { value, name } = e.target;
setInputs({
...inputs,
[name]: value,
});
};
...
return
...
// 지역번호
<select name="number1" onChange={onChange} value={number1} disabled={isPosting ? true : false}>
<option value="010">010</option>
<option value="070">070</option>
<option value="011">011</option>
<option value="02">02</option>
<option value="031">031</option>
</select>
...
2. input 객체 POST
- input 값 형식 확인 후 주문인증 POST 진행
- input 값 형식이 틀렸을 경우 style 변화로 맞는 형식 안내
- 주문인증 POST 시 loading 실행
- 인증 성공 시 pw값과 주문 정보인 response.data를 OrderConfirmPage로 넘겨줌과 동시에 이동
...
// REST API 1-3: post authentication data
const handleSubmit = (e) => {
const flagNum2 = /^[0-9]{3,4}$/.test(number2);
const flagNum3 = reg.test(number3);
const flagPw = reg.test(pw);
// prevent page reset
e.preventDefault();
// loading start
setIsPosting(true);
// input 형식 검사
if (!flagNum2 || !flagNum3 || !flagPw) {
setStyleInputs({
...styleInputs,
numberNotiStyle: flagNum2 && flagNum3 ? {display: "none"} : {display: "block"},
number2Style: flagNum2 ? {borderColor: "rgb(205, 205, 205)"} : {borderColor: "#fa7979", borderWidth: "2px"},
number3Style: flagNum3 ? {borderColor: "rgb(205, 205, 205)"} : {borderColor: "#fa7979", borderWidth: "2px"},
pwNotiStyle: flagPw ? {display: "none"} : {display: "block"},
pwStyle: flagPw ? {borderColor: "rgb(205, 205, 205)"} : {borderColor: "#fa7979", borderWidth: "2px"}
});
setIsPosting(false);
return;
}
// 주문 인증 POST
const number = number1 + number2 + number3;
const inputs = { number: number, pw: pw };
axios
.post(`${hostURL}/api/orders/detail`, inputs)
.then((response) => {
// 주문 내역이 없는 경우
if (response.data.length === 0) {
alert("해당 주문 내역이 없습니다");
setIsPosting(false);
return;
}
// 주문 내역이 있는 경우
navigate("/orderconfirm", { state: response.data });
})
.catch((error) => {
console.log(error);
});
};
...
주문조회 페이지 (OrderConfirmPage.js)
useLocation을 통해 response.data 받기
- useEffect를 통해 최초 렌더링 시에만 작동
- useState를 통해 output 상태를 전달받은 주문정보로 set
...
const output = useLocation().state;
const navigate = useNavigate();
// response data
useEffect(() => {
// prevent direct URL access
if (output === null) {
navigate("/authentication");
}
});
...
Map 함수로 주문 나열
- sort 메소드를 통해 최신 순으로 나열
- key를 orderId로 설정
- 주문이 취소 됐을 경우 주문 일시와 함께 안내
- '입금 대기' 상태인 경우 추가 안내 첨부
return
...
{/* item */}
{[...output]
.sort((a, b) => {
if (a.orderDate > b.orderDate) return -1;
if (a.orderDate < b.orderDate) return 1;
return 0;
})
.map((order) => (
<div key={order.orderId} className={styles.order_box}>
<div className={styles.order_item}>
{/* item title */}
<div className={styles.order_itemTitle}>
<div>
<img src={itemImage(order)} alt={order.item.name} />
</div>
<div>
<div>{order.item.name}</div>
<div>
{order.item.price}원 / {order.count}개
</div>
</div>
</div>
{order.orderStatus !== "CANCELED" ? ( ... ) :
(
<>
{/* order cancel */}
<div className={styles.order_cancel}>
<div>
<span>주문 일시</span>: {order.orderDate.replace("T", " ").slice(0, 24)}
</div>
<div>※ 해당 주문은 취소되었습니다</div>
</div>
</>
)}
{/* payment notification */}
{(order.orderStatus === "WAITING" ||
order.orderStatus === null) && ( ... )}
</div>
))}
...
'React' 카테고리의 다른 글
React로 커머스 사이트 만들기 (7): 관리자 페이지 (2) (0) | 2023.09.24 |
---|---|
React로 커머스 사이트 만들기 (6): 관리자 페이지(1) (0) | 2023.09.24 |
React로 커머스 사이트 만들기 (4): 구매 Modal & 주문완료 페이지 (0) | 2023.09.24 |
React로 커머스 사이트 만들기 (3): 홈페이지 & 상품페이지 (2) | 2023.09.23 |
React로 커머스 사이트 만들기 (2): REST API & json-server (0) | 2023.09.23 |