📌 기존 문제점
취소 사유 미노출 문제
마이페이지에서 사용자가 '취소하기' 버튼을 누를 경우, 취소 사유 입력 모달이 뜨지 않고, 바로 취소 요청 상태로 변경됨.
취소 요청 함수 중복
동일한 기능을 수행하는 취소 요청 함수가 코드 내 중복되어 관리가 어려움.
취소 승인 프로세스의 비효율성
<span
className={`px-2 py-1 text-xs rounded-full ${
reservation.status === "예약 확정"
? "bg-green-100 text-green-800"
: reservation.status === "예약 완료"
? "bg-red-100 text-red-800"
: reservation.status === "취소"
? "bg-orange-100 text-orange-800"
: "bg-yellow-100 text-yellow-800"
}`}
>

{/* 필터 섹션 */}
<div className="mb-6 flex flex-wrap gap-4">
<select
className="border rounded-md px-3 py-2"
value={statusFilter}
onChange={(e) => setStatusFilter(e.target.value)}
>
<option value="all">전체 상태</option>
<option value="예약 확정">예약 확정</option>
<option value="예약 대기">예약 대기</option>
<option value="취소">예약 취소</option>
</select>
일단, 사용자가 취소하기 누르면 -> 취소 완료 목록 으로 추가되고(이미 이 시점에서 취소는 완료됨), 대신 관리자가 취소요청이 온것을 확인한다는 의미로, 취소승인 대신 '확인' 버튼을 추가. 클릭하면 해당건은 취소된 예약 목록으로 이동함.
~~
--> 위 프로세스도 수정!!!
취소하기 버튼을 누르면, 취소 사유를 선택한 후에 상태가 취소로 바뀌어야 하는데, 취소하기 누르면 상태가 취소로 먼저 바뀌고 취소 사유를 그 다음에 선택하도록 잘못되어있음
실제로 예약 상태를 바꾸지 않음
올바른 흐름은:
1."취소하기" 버튼 클릭 →
2.취소 사유 모달이 먼저 뜨고
3.사유를 선택/입력한 뒤
4.확인 시 상태가 "취소 요청" 등으로 바뀌어야함.
-사유를 먼저 선택하고
-닫기하면 닫히고
-사유선택후 취소하면 상태 취소로 변경
수정 방법
1. handleCancelRequest에서 상태 변경을 제거하고, 취소하기 버튼 클릭 시 모달만 열기
⭐실제로 예약 상태를 바꾸지 않음!!!
// 예약 취소 요청 처리
const handleCancelRequest = (reservationId) => {
// 선택된 예약 저장
setSelectedReservation(reservationId);
// 취소 사유 모달 열기
setIsCancelModalOpen(true);
};
const handleCancelConfirm = (reason) => {
const updatedReservations = reservations.map((reservation) =>
reservation.id === selectedReservation
? {
...reservation,
status: "취소",
cancelReason: reason,
}
: reservation
);
setReservations(updatedReservations);
localStorage.setItem("reservations", JSON.stringify(updatedReservations));
setIsCancelModalOpen(false);
};
<button
className="px-2 py-1 rounded-full text-xs font-medium bg-red-100 text-red-800 hover:bg-red-200"
onClick={() => handleCancelRequest(reservation.id)}
>
취소하기
</button>
🐤정리
함수 2개를 써서, 하나로 통합해야 하는거 아닌가 했는데, 찾아보니 이 구조가 안전하고 표준적인 방법이라고 한다. 다행이다.
handleCancelRequest: 예약 id만 저장하고 모달만 연다(상태 변경 X)
handleCancelConfirm: 모달에서 사유 입력 후, 이때 상태와 사유를 함께 변경
관리자가 취소하면 localStorage 에 rejectReason생기고 직접 입력한 취소사유는 저장되는데, 사용자가 취소하면, cancelReason이 저장이 안되는 이유 찾아서 수정하기
rejectReason은 관리자가 예약을 "거절"할 때 사용하는 사유이고,
cancelReason은 고객이 직접 "취소"할 때 입력하는 사유임.
고객이 마이페이지 등에서 예약 취소 시,
아래와 같이 예약 객체에 cancelReason을 추가해서 localStorage에 저장.
const updatedReservations = reservations.map((reservation) =>
reservation.id === selectedReservation
? {
...reservation,
status: "취소",
cancelReason: reason, // ← 여기서 저장
canceledAt: new Date().toLocaleString(),
}
: reservation
);
setReservations(updatedReservations);
localStorage.setItem("reservations", JSON.stringify(updatedReservations));
admin에서 쓰이는 rejectReason: reson 은 설정해둬서 저장해놨는데, user단에서는 이 작업을 안해놨기때문에 저장이 안됬었던 것. 수정하니 잘된다.
//admin 예약 취소 요청 승인
const handleDeleteCanceledReservation = (reservationId) => {
const updatedCanceledReservations = canceledReservations.filter(
(reservation) => reservation.id !== reservationId
);
// 로컬 스토리지 업데이트
const allReservations = JSON.parse(
localStorage.getItem("reservations") || "[]"
);
const updatedAllReservations = allReservations.filter(
(reservation) => reservation.id !== reservationId
);
localStorage.setItem(
"reservations",
JSON.stringify(updatedAllReservations)
);
setCanceledReservations(updatedCanceledReservations);
};
이 코드에서 이미 예약 상태는 '취소'인데, 관리자가 '취소'된 예약목록에서 하나하나 삭제해야, 그 시간이 다시 예약가능시간으로 풀린다.
처음에는 관리자를 위해서 이 방법으로 개발했는데, 사용자 입장에서는 "취소했는데 왜 바로 예약이 안 되지?"라는 혼란이 생길 수 있을 것 같다는 생각이 들었다.
예약 상태가 '취소'로 바뀌면 즉시 해당 시간이 예약 가능하도록 한다
(= 취소된 순간, 바로 그 시간대가 다시 예약 가능 목록에 노출됨)
✔️ 이 방식의 장점
vs 단점
취소된 예약은 삭제하지 말고, 상태만 '취소'로 두고, 예약 가능 시간 계산에서만 제외하기!
예약 가능 시간 계산, 예약 중복 체크, 예약 시간대 필터링 등 모든 곳에서 reservation.status !== "취소" 조건을 꼭 넣어주기.
// 해당 시간대가 이미 예약되었는지 확인
const isTimeSlotTaken = (time) => {
return existingReservations.some((reservation) => {
return (
reservation.date === selectedDate &&
reservation.time === time &&
reservation.statue !== "취소"
);
});
};

reservation.status !== "취소"
이 코드를 예약 중복 체크 함수에 추가했는데, 계속 시간이 정상적으로 안나오길래 다시 보니 오타가있었다..ㅎ
statue -> status 로 수정하니 잘 나온다.

이렇게 하면, 관리자 페이지에서 굳이 '취소' 예약을 삭제하지 않아도 예약이 '취소'로 바뀌는 즉시 해당 시간이 다시 예약 가능해진다.
위와 같은 맥락으로, 예약을 하고 나면, 상태가 예약 대기가 아닌 예약 완료로 보이도록 추가적으로 수정해준다.
전체검색으로 예약 대기 인 부분을 예약 완료로 모두 바꿔주었다.
그리고 admin에서 취소 요청 목록, 취소 완료 목록은 모두 삭제한다.
new Date().toLocaleString()
new Date().toLocaleDateString()
둘의 차이점!?
🍦new Date().toLocaleString()
날짜와 시간을 모두 문자열로 반환함.
예시: 2025. 5. 22. 오후 3:45:12
🍦new Date().toLocaleDateString()
날짜만 문자열로 반환함.
예시: 2025. 5. 22.