Skip to content

[FE] SISC1-171 [FEAT] 이메일/비밀번호 찾기 모달, 이메일 결과/비밀번호 재설정 모달 구현#54

Merged
DongEun02 merged 11 commits into
mainfrom
SISC1-171-Find-Email-And-Password
Oct 14, 2025
Merged

[FE] SISC1-171 [FEAT] 이메일/비밀번호 찾기 모달, 이메일 결과/비밀번호 재설정 모달 구현#54
DongEun02 merged 11 commits into
mainfrom
SISC1-171-Find-Email-And-Password

Conversation

@GamjaIsMine02
Copy link
Copy Markdown
Contributor

@GamjaIsMine02 GamjaIsMine02 commented Oct 10, 2025

1) 작업한 이슈번호

SISC1-171 이메일/비밀번호 찾기 모달, 이메일 결과/비밀번호 재설정 모달

2) 변경 요약 (What & Why)

  • 무엇을 변경했는지:
    • 로그인 페이지에서 이메일/비밀번호 찾기 기능에 따른 모달 구현
    • 이메일 찾기, 비밀번호 찾기 모달은 전화번호 인증을 수행하며, 인증 시 각각의 맞는 모달로 이동
    1. 이메일 찾기 인증 시, 사용자의 이메일을 알려주는 모달 구현
    2. 비밀번호 찾기 인증 시, 비밀번호를 재설정하는 모달 구현
  • 변경했는지(문제/목표): 디자인이 변경되었으므로 수정

3) 스크린샷/동영상 (UI 변경 시)

전/후 비교, 반응형(모바일/데스크톱) 캡쳐

  • Before:
  • After:
image image image image

4) 상세 변경사항 (전부 다)

  • 라우팅/페이지: LoginForm,jsx(디자인 약간 수정)
  • 컴포넌트: VerificationModal.jsx(큰 모달 틀), FindEmailResultModal.jsx(이메일 결과 모달),ResetPasswordModal.jsx(비밀번호 재설정 모달),
  • 상태관리:
  • API 호출:
  • 스타일: VerificationModal.module.css(하나의 파일에서 여러 모달 className을 다르게 해 디자인)
  • 기타:

5) 참고사항

사용자 정보가 없을 때의 처리 필요
함수 분리 & API 연결 필요

Summary by CodeRabbit

  • New Features

    • 전화번호 기반 2단계 인증 모달, 이메일 찾기 결과 모달, 비밀번호 재설정 모달 추가; 로그인 흐름을 이메일 기반으로 전환하고 모달로 복구/재설정 절차 통합.
    • 루트 경로("/") 기본 페이지를 로그인으로 변경.
  • Refactor

    • 기존 회원가입용 이메일 인증 컴포넌트 제거 및 공용 인증 모달로 교체; 관련 상태/핸들러 명칭 정리.
  • Style

    • 로그인/회원가입 스타일 조정(텍스트 색상·정렬·구분선 추가), 전체 로그인 페이지 CSS 추가, 소셜 로그인 버튼 아이콘 크기 조정.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Oct 10, 2025

Walkthrough

로그인 루트가 기본 페이지로 바뀌고, 로그인/복구 흐름이 모달 기반으로 재구성되었습니다. VerificationModal, FindEmailResultModal, ResetPasswordModal이 추가되었고, 회원가입용 EmailVerificationModal 및 관련 스타일은 삭제되었습니다. 로그인 폼은 id 대신 email을 사용하도록 수정되었습니다.

Changes

Cohort / File(s) Summary
로그인/복구 폼 변경
frontend/src/components/login/LoginForm.jsx
로그인 식별자를 id→email로 변경하고 모달 단계 상태 추가. VerificationModal 기반 이메일 찾기/비밀번호 재설정 플로우로 전환. 더미 토큰 저장 및 내비게이션 로직 포함.
휴대폰 인증 모달 추가
frontend/src/components/VerificationModal.jsx, frontend/src/components/VerificationModal.module.css
전화번호 입력, 코드 전송/재전송, 코드 검증 및 성공 콜백을 제공하는 VerificationModal 컴포넌트 및 관련 스타일 추가.
이메일 결과/비밀번호 재설정 모달
frontend/src/components/login/FindEmailResultModal.jsx, frontend/src/components/login/ResetPasswordModal.jsx
이메일 결과 표시용 모달과 새 비밀번호 입력·검증을 수행하는 ResetPasswordModal 추가.
회원가입용 이메일 인증 제거 및 참조 갱신
frontend/src/components/signup/EmailVerificationModal.jsx (삭제), frontend/src/components/signup/EmailVerificationModal.module.css (삭제), frontend/src/components/signup/SignUpForm.jsx
기존 EmailVerificationModal 컴포넌트 및 스타일 삭제. SignUpForm에서 import 경로를 ../VerificationModal로 변경하고 popup→modal 관련 state/핸들러명 변경.
소셜 로그인 버튼·스타일 변경
frontend/src/components/login/SocialLoginButtons.jsx, frontend/src/components/login/SocialLoginButtons.module.css
Google 버튼 내부에 G 로고 이미지 사용, Naver/Kakao 버튼 내부 콘텐츠 제거. .btn img { width: 50%; height: auto; } 규칙 추가.
공통 폼 스타일 조정
frontend/src/components/LoginAndSignUpForm.module.css
.findContainer 삭제, .text 색상 변경(#9ca3af), .textContainer 및 하위 .text cursor:pointer 규칙 추가, .divider 클래스 추가.
루트 라우트 변경
frontend/src/App.jsx
기본 경로 /가 Home 대신 Login을 렌더하도록 라우트 기본값 변경.
로그인 페이지 스타일 추가
frontend/src/pages/Login.css
로그인 페이지 전용 스타일시트 추가(레이아웃, 입력 스타일, 버튼/에러 표시 등).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant LoginForm
  participant VerificationModal
  participant FindEmailResultModal
  participant ResetPasswordModal

  rect rgba(200,230,255,0.12)
    note over User,LoginForm: 이메일 찾기 흐름
    User->>LoginForm: "이메일 찾기" 클릭
    LoginForm->>VerificationModal: 모달 열기 (전화번호 인증)
    User->>VerificationModal: 번호 입력, 코드 전송/입력
    VerificationModal-->>LoginForm: onSuccess({ email })
    LoginForm->>FindEmailResultModal: 결과 모달 표시
    User->>FindEmailResultModal: 닫기
    FindEmailResultModal-->>LoginForm: onClose
  end

  rect rgba(200,255,200,0.12)
    note over User,LoginForm: 비밀번호 재설정 흐름
    User->>LoginForm: "비밀번호 찾기" 클릭
    LoginForm->>VerificationModal: 모달 열기 (전화번호 인증)
    User->>VerificationModal: 인증 완료
    VerificationModal-->>LoginForm: onSuccess()
    LoginForm->>ResetPasswordModal: 재설정 모달 표시
    User->>ResetPasswordModal: 새 비밀번호 제출
    ResetPasswordModal-->>LoginForm: onClose
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

깡충깡충 모달이 열렸네 🥕
번호 보내고 코드 쓱쓱
이메일 찾아주고 비번 새로
오래된 모듈은 살짝 벗겨
폼은 경쾌히 집으로 점프

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed 제목은 이메일 및 비밀번호 찾기 모달과 결과·재설정 모달 구현이라는 PR의 핵심 기능을 명확하게 요약하고 있어 변경 사항을 잘 반영합니다.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch SISC1-171-Find-Email-And-Password

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🧹 Nitpick comments (8)
frontend/src/components/login/ResetPasswordModal.jsx (1)

8-21: 중복된 유효성 검사 로직 개선 권장

비밀번호 유효성 검사가 isPasswordValid 변수(Line 23)와 handleSubmit 함수 내부(Lines 10-17)에서 중복으로 수행되고 있습니다. isPasswordValid 검사만으로도 충분하므로 handleSubmit 내의 중복 검사를 제거하는 것을 권장합니다.

다음과 같이 리팩토링할 수 있습니다:

  const handleSubmit = (e) => {
    e.preventDefault();
-    if (password !== confirmPassword) {
-      alert('비밀번호가 일치하지 않습니다.');
-      return;
-    }
-    if (password.length < 8) {
-      alert('비밀번호는 8자 이상이어야 합니다.');
-      return;
-    }
    console.log('비밀번호 재설정 API 호출');
    alert('비밀번호가 성공적으로 재설정되었습니다.');
    onClose();
  };

참고: 버튼이 disabled={!isPasswordValid}로 이미 보호되어 있으므로, 폼 제출 시 추가 검사가 불필요합니다.

frontend/src/components/login/FindEmailResultModal.jsx (1)

4-6: 사용되지 않는 함수 제거

handleSubmit 함수가 정의되어 있지만 컴포넌트 어디에서도 사용되지 않습니다. 죽은 코드는 제거하는 것이 좋습니다.

다음 diff를 적용하세요:

  const FindEmailResultModal = ({ onClose, result }) => {
-  const handleSubmit = (e) => {
-    e.preventDefault();
-  };
-
    return (
frontend/src/components/VerificationModal.module.css (1)

73-76: input 요소의 display: flex 검토 필요

.newPassword 클래스가 input 요소에 적용되는데 display: flex가 설정되어 있습니다. input 요소는 인라인 교체 요소(inline replaced element)이므로 flex 컨테이너로 사용하는 것이 적절하지 않으며, 의도한 효과가 나타나지 않을 수 있습니다.

width: 50%만 필요한 경우 다음과 같이 수정하는 것을 권장합니다:

.newPassword {
-  display: flex;
  width: 50%;
}

만약 flex 레이아웃이 필요하다면, input을 감싸는 컨테이너 div에 적용해야 합니다.

frontend/src/components/login/LoginForm.jsx (1)

87-101: 시맨틱 HTML 개선 권장

href 속성 없이 onClick만 있는 앵커 태그는 시맨틱하지 않으며 키보드 네비게이션에 문제가 있을 수 있습니다. button 요소를 사용하거나 href="#"preventDefault를 추가하는 것을 권장합니다.

다음과 같이 개선할 수 있습니다:

          <div>
            <a
              className={styles.text}
+              href="#"
-              onClick={() => setModalStep('verifyPhoneForEmail')}
+              onClick={(e) => {
+                e.preventDefault();
+                setModalStep('verifyPhoneForEmail');
+              }}
            >
              이메일 찾기
            </a>
            <span className={styles.divider} aria-hidden="true">
              |
            </span>
            <a
              className={styles.text}
+              href="#"
-              onClick={() => setModalStep('verifyPhoneForPassword')}
+              onClick={(e) => {
+                e.preventDefault();
+                setModalStep('verifyPhoneForPassword');
+              }}
            >
              비밀번호 찾기
            </a>
          </div>

또는 더 나은 방법으로 button 요소를 사용:

          <div>
            <button
              type="button"
              className={styles.text}
              onClick={() => setModalStep('verifyPhoneForEmail')}
            >
              이메일 찾기
            </button>
            <span className={styles.divider} aria-hidden="true">
              |
            </span>
            <button
              type="button"
              className={styles.text}
              onClick={() => setModalStep('verifyPhoneForPassword')}
            >
              비밀번호 찾기
            </button>
          </div>
frontend/src/components/VerificationModal.jsx (4)

4-4: PropTypes 또는 TypeScript로 prop 타입을 정의하세요.

런타임 타입 체크를 위해 PropTypes를 추가하거나 TypeScript로 마이그레이션하는 것을 권장합니다. 특히 onSuccess 콜백의 매개변수 형식을 명확히 해야 합니다.

PropTypes를 추가하려면:

import { useState } from 'react';
import PropTypes from 'prop-types';
import styles from './VerificationModal.module.css';

const VerificationModal = ({ title, onClose, onSuccess }) => {
  // ... existing code
};

VerificationModal.propTypes = {
  title: PropTypes.string.isRequired,
  onClose: PropTypes.func.isRequired,
  onSuccess: PropTypes.func.isRequired,
};

export default VerificationModal;

76-95: 인증번호 만료 타이머를 표시하세요.

사용자가 인증번호의 유효 시간을 알 수 있도록 카운트다운 타이머를 추가하는 것을 권장합니다.

타이머 상태 및 로직 추가:

const [timer, setTimer] = useState(180); // 3분

useEffect(() => {
  if (isCodeSent && timer > 0) {
    const interval = setInterval(() => {
      setTimer((prev) => prev - 1);
    }, 1000);
    return () => clearInterval(interval);
  }
}, [isCodeSent, timer]);

const formatTime = (seconds) => {
  const mins = Math.floor(seconds / 60);
  const secs = seconds % 60;
  return `${mins}:${secs.toString().padStart(2, '0')}`;
};

UI에 타이머 표시:

<label htmlFor="verification-code">
  인증번호 {isCodeSent && timer > 0 && `(${formatTime(timer)})`}
</label>

98-104: 닫기 버튼에 확인 로직을 추가하세요.

인증 진행 중에 모달을 닫으려 할 때 확인 메시지를 표시하여 실수로 닫는 것을 방지하세요.

+const handleClose = () => {
+  if (isCodeSent) {
+    if (window.confirm('인증을 취소하시겠습니까?')) {
+      onClose();
+    }
+  } else {
+    onClose();
+  }
+};
+
 <button
   type="button"
-  onClick={onClose}
+  onClick={handleClose}
   className={`${styles.button} ${styles.closeButton}`}
 >
   닫기
 </button>

1-112: 전반적인 개선 사항 요약

이 컴포넌트는 기본 기능은 작동하지만, 프로덕션 환경에서 사용하기 위해서는 다음 사항들을 개선해야 합니다:

  1. 보안 & 검증: 전화번호 및 인증번호 형식 검증 필수
  2. 에러 처리: Alert 대신 UI 기반 에러 메시지 표시
  3. 접근성: ARIA 속성 추가 및 키보드 네비게이션 지원
  4. UX: 로딩 상태, 타이머, 입력 필드 수정 가능 등
  5. 국제화: 하드코딩된 한국어 텍스트를 i18n 시스템으로 교체

PR 설명에 언급된 대로 API 연동이 필요하며, 위의 제안사항들을 함께 적용하면 더 견고한 컴포넌트가 될 것입니다.

위 개선 사항들 중 우선순위가 높은 항목부터 적용하시는 것을 권장합니다. 추가 도움이 필요하시면 말씀해 주세요!

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b5005b and a385a77.

📒 Files selected for processing (11)
  • frontend/src/components/LoginAndSignUpForm.module.css (1 hunks)
  • frontend/src/components/VerificationModal.jsx (1 hunks)
  • frontend/src/components/VerificationModal.module.css (1 hunks)
  • frontend/src/components/login/FindEmailResultModal.jsx (1 hunks)
  • frontend/src/components/login/LoginForm.jsx (1 hunks)
  • frontend/src/components/login/ResetPasswordModal.jsx (1 hunks)
  • frontend/src/components/login/SocialLoginButtons.jsx (1 hunks)
  • frontend/src/components/login/SocialLoginButtons.module.css (1 hunks)
  • frontend/src/components/signup/EmailVerificationModal.jsx (0 hunks)
  • frontend/src/components/signup/EmailVerificationModal.module.css (0 hunks)
  • frontend/src/components/signup/SignUpForm.jsx (4 hunks)
💤 Files with no reviewable changes (2)
  • frontend/src/components/signup/EmailVerificationModal.module.css
  • frontend/src/components/signup/EmailVerificationModal.jsx
🧰 Additional context used
🧬 Code graph analysis (4)
frontend/src/components/login/LoginForm.jsx (3)
frontend/src/components/login/ResetPasswordModal.jsx (1)
  • password (5-5)
frontend/src/components/VerificationModal.jsx (1)
  • VerificationModal (4-110)
frontend/src/components/login/FindEmailResultModal.jsx (1)
  • FindEmailResultModal (3-29)
frontend/src/components/login/ResetPasswordModal.jsx (1)
frontend/src/components/VerificationModal.jsx (1)
  • handleSubmit (24-42)
frontend/src/components/login/FindEmailResultModal.jsx (1)
frontend/src/components/VerificationModal.jsx (1)
  • handleSubmit (24-42)
frontend/src/components/VerificationModal.jsx (1)
frontend/src/components/signup/SignUpForm.jsx (1)
  • phoneNumber (10-10)
🔇 Additional comments (4)
frontend/src/components/login/ResetPasswordModal.jsx (1)

18-18: API 연동 필요

현재 비밀번호 재설정 API 호출이 구현되지 않았습니다. PR 설명에 언급된 대로 향후 실제 API 연동이 필요합니다.

frontend/src/components/login/SocialLoginButtons.module.css (1)

34-37: LGTM!

버튼 내 이미지 크기를 조정하는 스타일링이 적절합니다.

frontend/src/components/signup/SignUpForm.jsx (1)

5-5: LGTM!

EmailVerificationModal에서 공유 VerificationModal 컴포넌트로의 마이그레이션이 적절히 수행되었습니다. 상태 변수 및 핸들러 이름 변경도 일관성 있게 처리되었습니다.

Also applies to: 12-12, 46-51, 78-78, 125-130

frontend/src/components/LoginAndSignUpForm.module.css (1)

82-106: LGTM!

텍스트 컨테이너, 디바이더 스타일링 및 색상 업데이트가 새로운 모달 기반 복구 플로우를 잘 지원합니다. Flexbox 레이아웃과 스타일링이 적절하게 구현되었습니다.

Comment thread frontend/src/components/login/FindEmailResultModal.jsx Outdated
Comment thread frontend/src/components/login/LoginForm.jsx
Comment thread frontend/src/components/login/LoginForm.jsx
Comment thread frontend/src/components/login/ResetPasswordModal.jsx
Comment thread frontend/src/components/login/SocialLoginButtons.jsx
Comment thread frontend/src/components/VerificationModal.jsx
Comment thread frontend/src/components/VerificationModal.jsx
Comment thread frontend/src/components/VerificationModal.jsx
Comment thread frontend/src/components/VerificationModal.jsx
Comment thread frontend/src/components/VerificationModal.jsx
Copy link
Copy Markdown
Contributor

@gxuoo gxuoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코멘트 확인 부탁드립니다!

Comment thread frontend/src/components/login/ResetPasswordModal.jsx Outdated
Comment thread frontend/src/components/login/ResetPasswordModal.jsx
Comment thread frontend/src/components/VerificationModal.jsx Outdated
Comment thread frontend/src/components/VerificationModal.jsx
Comment thread frontend/src/components/VerificationModal.jsx Outdated
Comment thread frontend/src/components/VerificationModal.module.css
Comment thread frontend/src/components/login/SocialLoginButtons.jsx
Comment thread frontend/src/components/signup/SignUpForm.jsx
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
frontend/src/components/login/ResetPasswordModal.jsx (1)

23-23: 엄격한 동등 연산자(===) 사용 필요

==는 타입 강제 변환을 수행하여 예상치 못한 동작을 일으킬 수 있습니다. 비밀번호 비교 시 엄격한 동등 연산자(===)를 사용해야 합니다.

다음 diff를 적용하여 수정하세요:

-  const isPasswordValid = password == confirmPassword && password.length >= 8;
+  const isPasswordValid = password === confirmPassword && password.length >= 8;
🧹 Nitpick comments (2)
frontend/src/components/login/ResetPasswordModal.jsx (2)

14-16: 비밀번호 강도 요구사항 추가를 권장합니다.

현재는 8자 이상의 길이만 검증하고 있습니다. 보안을 강화하기 위해 숫자, 특수문자, 대소문자 조합 등의 추가 요구사항을 고려해보세요.

예시:

const validatePassword = (password) => {
  const minLength = password.length >= 8;
  const hasNumber = /\d/.test(password);
  const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password);
  return minLength && hasNumber && hasSpecialChar;
};

26-63: 접근성(Accessibility) 개선이 필요합니다.

모달에 적절한 ARIA 속성이 누락되어 스크린 리더 사용자가 모달을 제대로 인식하지 못할 수 있습니다.

다음 속성들을 추가하세요:

-    <div className={styles.overlay}>
+    <div className={styles.overlay} role="dialog" aria-modal="true" aria-labelledby="reset-password-title">
-      <div className={styles.modal}>
+      <div className={styles.modal}>
-        <h1>비밀번호 재설정</h1>
+        <h1 id="reset-password-title">비밀번호 재설정</h1>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a385a77 and 9e63336.

📒 Files selected for processing (3)
  • frontend/src/components/VerificationModal.jsx (1 hunks)
  • frontend/src/components/VerificationModal.module.css (1 hunks)
  • frontend/src/components/login/ResetPasswordModal.jsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/VerificationModal.jsx
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/src/components/login/ResetPasswordModal.jsx (1)
frontend/src/components/VerificationModal.jsx (1)
  • handleSubmit (28-46)
🪛 Biome (2.1.2)
frontend/src/components/VerificationModal.module.css

[error] 98-98: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.

color is already defined here.

Remove or rename the duplicate property to ensure consistent styling.

(lint/suspicious/noDuplicateProperties)

🔇 Additional comments (3)
frontend/src/components/login/ResetPasswordModal.jsx (1)

18-20: API 연결 및 에러 처리 구현 필요

현재는 placeholder console.log만 있고 실제 API 연결이 없습니다. PR 목표에서 언급된 대로 API 연결이 필요하며, try-catch를 사용한 에러 처리도 추가해야 합니다.

VerificationModal.jsx(27-45행)의 패턴을 참고하여 다음과 같이 구현할 수 있습니다:

try {
  // const result = await api.resetPassword(password);
  alert('비밀번호가 성공적으로 재설정되었습니다.');
  onClose();
} catch (error) {
  console.error('비밀번호 재설정 실패:', error);
  alert('비밀번호 재설정에 실패했습니다. 다시 시도해주세요.');
}

API 엔드포인트가 준비되었는지 확인이 필요합니다.

frontend/src/components/VerificationModal.module.css (2)

84-105: 버튼 스타일 정의 확인 완료

.button 클래스에 font-size: 16px(100행), font-weight: 500(102행)이 올바르게 정의되어 있습니다. 과거 코멘트에서 지적된 누락 사항이 해결된 것으로 보입니다.


73-76: width 속성이 50%로 제한되어 있습니다.

.newPassword 클래스가 width를 50%로 제한하고 있어 ResetPasswordModal의 비밀번호 입력 필드가 의도한 것보다 좁게 표시될 수 있습니다. 디자인 요구사항과 일치하는지 확인이 필요합니다.

피그마 디자인에서 비밀번호 입력 필드의 너비가 50%인지 확인해주세요. 만약 전체 너비를 사용해야 한다면:

 .newPassword {
   display: flex;
-  width: 50%;
+  width: 100%;
 }

Comment thread frontend/src/components/login/ResetPasswordModal.jsx
Comment thread frontend/src/components/VerificationModal.module.css
Copy link
Copy Markdown
Contributor Author

@GamjaIsMine02 GamjaIsMine02 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰 검토하고 수정해서 PR 요청했습니다! 제가 아직 모르는게 너무 많네요

Comment thread frontend/src/components/login/ResetPasswordModal.jsx Outdated
Comment thread frontend/src/components/login/ResetPasswordModal.jsx
Comment thread frontend/src/components/login/SocialLoginButtons.jsx
Comment thread frontend/src/components/VerificationModal.jsx Outdated
Comment thread frontend/src/components/VerificationModal.jsx
Comment thread frontend/src/components/VerificationModal.jsx Outdated
Comment thread frontend/src/components/VerificationModal.module.css
Comment thread frontend/src/components/login/ResetPasswordModal.jsx
Comment thread frontend/src/components/signup/SignUpForm.jsx
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (6)
frontend/src/components/VerificationModal.jsx (5)

15-15: alert 대신 인라인 메시지 UI를 사용하세요.

alert()는 UX를 저해합니다. 모달 내에 에러/성공 메시지를 표시하는 상태와 UI를 추가하는 것이 좋습니다.

상태 추가:

  const [phoneNumber, setPhoneNumber] = useState('');
  const [verificationCode, setVerificationCode] = useState('');
  const [isCodeSent, setIsCodeSent] = useState(false);
  const [sendButtonDisabled, setSendButtonDisabled] = useState(false);
+ const [message, setMessage] = useState({ type: '', text: '' });

JSX에 메시지 표시 영역 추가:

<form onSubmit={handleSubmit}>
  {message.text && (
    <div className={message.type === 'error' ? styles.errorMessage : styles.successMessage}>
      {message.text}
    </div>
  )}
  {/* ... 나머지 폼 */}
</form>

Also applies to: 23-23, 31-31, 40-40, 44-44


48-122: 접근성 향상을 위해 ARIA 속성을 추가하세요.

스크린 리더 사용자를 위해 적절한 ARIA 속성을 추가해야 합니다.

- <div className={styles.overlay}>
+ <div className={styles.overlay} role="dialog" aria-modal="true" aria-labelledby="modal-title">
    <div className={styles.modal}>
      <div className={styles.modalHeader}>
-       <h1>{title}</h1>
+       <h1 id="modal-title">{title}</h1>
        <button
          type="button"
          className={styles.closeButton}
          onClick={onClose}
+         aria-label="모달 닫기"
        >
          &times;
        </button>
      </div>

      <form onSubmit={handleSubmit}>
        <div className={styles.inputGroup}>
          <label htmlFor="phone-number">전화번호 인증</label>
          <div className={styles.verificationContainer}>
            <input
              type="tel"
              id="phone-number"
              value={phoneNumber}
              onChange={(e) => setPhoneNumber(e.target.value)}
              placeholder="'-' 없이 입력"
              className={styles.codeInput}
+             aria-required="true"
+             aria-invalid={phoneNumber && !/^01[0-9]{1}[0-9]{7,8}$/.test(phoneNumber)}
            />

19-25: API 응답에 따라 버튼 상태를 제어하세요.

현재는 3초 타이머로 버튼을 무조건 재활성화하는데, 이는 API 성공/실패와 무관합니다. 실제 API 응답을 기다린 후 상태를 변경해야 합니다.

  setSendButtonDisabled(true);
  console.log(`${phoneNumber}로 인증번호 전송 API 호출`);
- // 실제 api 추가
+ 
+ try {
+   // const response = await api.sendVerificationCode(phoneNumber);
+   alert('인증번호가 전송되었습니다.');
+   setIsCodeSent(true);
+   setTimeout(() => setSendButtonDisabled(false), 60000); // 재전송은 60초 후
+ } catch (error) {
+   console.error('인증번호 전송 실패:', error);
+   alert('인증번호 전송에 실패했습니다.');
+ } finally {
+   setSendButtonDisabled(false);
+ }
- 
- alert('인증번호가 전송되었습니다.');
- setIsCodeSent(true);
- setTimeout(() => setSendButtonDisabled(false), 3000);

36-41: 실제 API 연동 및 검증 로직을 구현하세요.

현재 mock 데이터를 사용하고 있어 실패 케이스를 테스트할 수 없습니다. 또한 인증번호 형식 검증(6자리 숫자)이 없습니다.

+ // 인증번호 형식 검증 (6자리 숫자)
+ if (!/^\d{6}$/.test(verificationCode)) {
+   alert('인증번호는 6자리 숫자여야 합니다.');
+   return;
+ }
+ 
  console.log(`${phoneNumber}와 ${verificationCode}로 인증 확인 API 호출`);

  try {
-   // <<-- 실제 API 호출 로직: const result = await api.verifyCode(phoneNumber, code) -->>
-
-   const mockResult = { email: 'user@example.com', message: '인증 성공' };
+   const result = await api.verifyCode(phoneNumber, verificationCode);
    alert('인증에 성공했습니다!');
-   onSuccess(mockResult);
+   onSuccess(result);
  } catch (error) {

100-106: 제출 버튼에 로딩 상태를 추가하세요.

사용자의 중복 클릭을 방지하고 API 호출 중임을 시각적으로 표시해야 합니다.

상태 추가:

  const [sendButtonDisabled, setSendButtonDisabled] = useState(false);
+ const [isVerifying, setIsVerifying] = useState(false);

handleSubmit 함수 수정:

  const handleSubmit = async (e) => {
    e.preventDefault();
+   setIsVerifying(true);
    
    try {
      // API 호출
      onSuccess(result);
    } catch (error) {
      console.error('인증 실패:', error);
      alert('인증번호가 올바르지 않습니다.');
+   } finally {
+     setIsVerifying(false);
    }
  };

버튼 업데이트:

  <button
    type="submit"
    className={`${styles.button} ${styles.submitButton}`}
-   disabled={!isCodeSent}
+   disabled={!isCodeSent || isVerifying}
  >
-   인증 확인
+   {isVerifying ? '확인 중...' : '인증 확인'}
  </button>
frontend/src/components/VerificationModal.module.css (1)

115-118: 중복된 color 속성을 제거하세요.

Line 115와 118에서 color 속성이 중복 정의되어 있습니다. Line 118의 color: #fff;가 Line 115의 color: white;를 덮어씁니다.

Based on static analysis hints

다음 diff를 적용하여 중복을 제거하세요:

  color: white;
  border: none;

- color: #fff;
  font-family: Pretendard;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e63336 and 7ad5803.

📒 Files selected for processing (4)
  • frontend/src/App.jsx (1 hunks)
  • frontend/src/components/VerificationModal.jsx (1 hunks)
  • frontend/src/components/VerificationModal.module.css (1 hunks)
  • frontend/src/pages/Login.css (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/src/App.jsx (1)
frontend/src/pages/Login.jsx (1)
  • Login (4-10)
🪛 Biome (2.1.2)
frontend/src/components/VerificationModal.module.css

[error] 118-118: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.

color is already defined here.

Remove or rename the duplicate property to ensure consistent styling.

(lint/suspicious/noDuplicateProperties)

🔇 Additional comments (1)
frontend/src/pages/Login.css (1)

1-109: CSS 구조가 잘 정의되어 있습니다.

로그인 페이지의 레이아웃과 스타일이 체계적으로 구성되어 있습니다. 특히 .error-message 클래스에서 고정 높이를 예약하여 레이아웃 이동을 방지한 점이 좋습니다.

Comment thread frontend/src/App.jsx
Copy link
Copy Markdown
Contributor

@DongEun02 DongEun02 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코멘트 단 건 거의 없는데 예외 처리에 좀 더 신경 써주시면 될 것 같아요

Comment thread frontend/src/components/login/ResetPasswordModal.jsx
Comment thread frontend/src/components/login/FindEmailResultModal.jsx Outdated
Copy link
Copy Markdown
Contributor Author

@GamjaIsMine02 GamjaIsMine02 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가로 수정했습니다!

Comment thread frontend/src/components/login/FindEmailResultModal.jsx Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
frontend/src/components/login/FindEmailResultModal.jsx (2)

4-6: 사용되지 않는 함수를 제거하세요.

handleSubmit 함수가 정의되어 있지만 JSX 어디에서도 사용되지 않습니다. 이 함수는 제거하는 것이 좋습니다.

다음 diff를 적용하세요:

 const FindEmailResultModal = ({ onClose, result }) => {
-  const handleSubmit = (e) => {
-    e.preventDefault();
-  };
-
   return (

3-3: PropTypes 또는 TypeScript 타입 정의를 고려해보세요.

prop 검증을 위해 PropTypes를 추가하거나 향후 TypeScript로 마이그레이션하는 것을 고려해보세요. 이는 런타임 오류를 방지하고 개발 경험을 개선할 수 있습니다.

PropTypes를 추가하는 예시:

import PropTypes from 'prop-types';
import styles from '../VerificationModal.module.css';

const FindEmailResultModal = ({ onClose, result }) => {
  // ... component code
};

FindEmailResultModal.propTypes = {
  onClose: PropTypes.func.isRequired,
  result: PropTypes.string,
};

export default FindEmailResultModal;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ad5803 and c4e92c8.

📒 Files selected for processing (1)
  • frontend/src/components/login/FindEmailResultModal.jsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/src/components/login/FindEmailResultModal.jsx (1)
frontend/src/components/VerificationModal.jsx (1)
  • handleSubmit (28-46)
🔇 Additional comments (1)
frontend/src/components/login/FindEmailResultModal.jsx (1)

13-20: 조건부 렌더링이 잘 구현되었습니다.

result가 없을 때에 대한 예외 처리가 잘 되어 있습니다. 과거 리뷰에서 지적된 null/undefined 체크가 적절하게 반영되었습니다.

Copy link
Copy Markdown
Contributor Author

@GamjaIsMine02 GamjaIsMine02 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

봇 코멘트 반영

Comment thread frontend/src/App.jsx
Comment thread frontend/src/components/VerificationModal.jsx
Comment thread frontend/src/components/VerificationModal.jsx
Comment thread frontend/src/components/VerificationModal.jsx
Comment thread frontend/src/components/VerificationModal.module.css
Comment thread frontend/src/components/login/LoginForm.jsx
Comment thread frontend/src/components/login/LoginForm.jsx
Comment thread frontend/src/components/login/ResetPasswordModal.jsx
Comment thread frontend/src/components/login/ResetPasswordModal.jsx
Comment thread frontend/src/components/login/SocialLoginButtons.jsx
Copy link
Copy Markdown
Contributor

@gxuoo gxuoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants