개발 기록/도서관 관리 시스템

[Library Management System] 25.10.28 | (구현) 마이페이지 비밀번호 변경, 회원탈퇴 기능 구현

dev.jelee 2025. 10. 28. 22:01

[ 작업한 내용 ]

# Frontend

1. 비밀번호 수정 기능 구현

- input 태그 속성에서 title, content, placeholder에 각각 들어갈 메시지 구분

const modalData = {
  dialogEmail: {
    title: "이메일 수정",
    content: "새로운 이메일 주소를 입력해주세요.",
    placeholder: "새 이메일 입력",
  },
  dialogPw: {
    title: "비밀번호 수정",
    content: "새로운 비밀번호를 입력해주세요.",
    placeholderOri: "새 비밀번호 입력",
    placeholderRe: "새 비밀번호 확인 입력",
  }
}

 

- 비밀 번호 수정 버튼 클릭시 api 호출하고 patch로 요청하고 결과 응답 받기.

const updatePw = async () => {
  try {
    const response = await axios.patch(
      "http://localhost:8080/api/v1/user/me/password",
      { password: pwValue,
        repassword: repwValue,
      },
      { withCredentials: true },
    );

    console.log(response.data.data);
    setData(response.data.data);

  } catch (error) {
    console.log("Error: ", error);
    setError(error);
  } finally {
    setLoading(false);
  }
}

const handleClick = async () => {
  if (id === "dialogEmail") {
    await updateEmail();
    alert("이메일 변경 성공");
  } else if (id === "dialogPw") {
    await updatePw();
    alert("비밀번호 변경 성공");
  }

  await fetchUser(); 
  setEmailValue("");
  setPwValue("");
  setRepwValue("");
  document.getElementById(id)?.close();
}

 

- 비밀번호 수정은 input태그를 두 개를 사용해야 해서 id가 dialogEmail, dialogPw로 구분하여 비밀번호만 input 태그 두 개를 추가함

{ id === "dialogPw" && (
	<> 
		...
		<input 
      type="text" 
      placeholder={placeholderOri}
      className="
        border p-2 border-gray-300 outline-none
        w-full
        text-sm 
        focus:border-teal-600
      "
      value={pwValue}
      onChange={ (e) => setPwValue(e.target.value)}
    />
    <input 
      type="text" 
      placeholder={placeholderRe}
      className="
        border p-2 border-gray-300 outline-none
        w-full
        text-sm 
        focus:border-teal-600
      "
      value={repwValue}
      onChange={ (e) => setRepwValue(e.target.value) }
    />
</>

2. 회원탈퇴 기능 구현

- 회원탈퇴 버튼을 button 태그로 변경하고 modal 컴포넌트도 id로 구분

<button 
  command="show-modal" 
  commandfor="dialogDelAccount"
  className="px-4 py-3 
    border border-gray-500 
    self-start leading-none
    text-gray-500 
    hover:border-red-700
    hover:text-red-700
    cursor-pointer
  ">회원탈퇴</button>
<MyPageInfoModal id="dialogDelAccount" />

 

- modal 창에서 사용할 텍스트를 객체로 관리

dialogDelAccount: {
  title: "회원 탈퇴",
  content: "사용중인 비밀번호를 입력해주세요.",
  placeholder: "비밀번호 입력",
}

 

- 회원탈퇴 버튼을 클릭하면 api 호출하여 탈퇴 요청을 post로 하고 결과 응답받기.

const delAccount = async () => {
  try {
    const response = await axios.post(
      "http://localhost:8080/api/v1/user/me/withdraw",
      { password: delPwValue },
      { withCredentials: true },
    );

    console.log("회원탈퇴: ", response.data.data);
    setData(response.data.data);
    alert("회원탈퇴 성공");
    navigate("/");
    
  } catch (error) {
    console.log("Error: ", error.response.data);
    setError(error.response.data);
    alert(error.response.data.message);
  } finally {
    setLoading(false);
  }
}


const handleClick = async () => {
  if (id === "dialogEmail") {
    await updateEmail();
  } else if (id === "dialogPw") {
    await updatePw();
  } else if (id === "dialogDelAccount") {
    await delAccount();
  }

  await fetchUser(); 
  setEmailValue("");
  setPwValue("");
  setRepwValue("");
  setDelPwValue("");
  document.getElementById(id)?.close();
}

 

- modal창 id가 dialogDelAccount인 경우 개별로 구현

{ id === "dialogDelAccount" && (
  <>
		...
		<input 
      type="text" 
      placeholder={placeholder}
      className="
        border p-2 border-gray-300 outline-none
        w-full
        text-sm 
        focus:border-teal-600
      "
      value={delPwValue}
      onChange={ (e) => setDelPwValue(e.target.value) }
    />
  </>
)}

 

- 이메일/비밀번호 수정과 회원탈퇴의 모달창의 버튼 텍스트가 다르기 때문에 삼항연산자로 구분하도록 수정

<button 
  type="button" command="close" commandfor={id} 
  class="
    inline-flex w-full justify-center rounded-md 
    bg-teal-600 hover:bg-teal-700 
    text-sm font-semibold text-white shadow-xs 
    px-3 py-2 sm:ml-3 sm:w-auto
  "
  onClick={handleClick}
>{id === 'dialogDelAccount' ? "탈퇴" : "변경"}</button>

3. 특정 도서의 리뷰 전체 조회 수정

- AuthenticationPrincipal을 적용 시켜 놓아서 로그인한 사용자만 특정 도서의 리뷰가 조회가 되는 버그 발생. 해당 관련 소스 코드 제거.