이번 포스트에서는 저번 포스트에 이어서 회원가입 약관 컴포넌트에 관련된 내용이다.
약관 동의 모달 컴포넌트
아래와 같이, 각 항목마다 관련 내용을 출력하는 모달을 구현하였다.
우선 전체 동의에 대한 코드이다.
type에 대한 선언은 리터럴 타입으로 정의해 미리 정의된 값만을 사용하도록 하였다.
type ModalType = 'privacy' | 'terms' | 'marketing' | 'youtube';
우리는 각 항목별에 대한 boolean값을 아래와 같이 정의했었다.
const [agreements, setAgreements] = useState(
savedAgreements || {
privacy: false,
terms: false,
marketing: false,
youtube: false,
}
);
Javascript에서는 Object 관련 함수를 제공하는데,
function isAllChecked() {
return Object.values(agreements).every((value) => value === true);
}
every를 사용하여 모든 값을 true로 설정하여 한번에 모든 항목이 체크되도록 하였다.
각 항목별 클릭시
각 항목 별로 클릭시 false이면 true로, true면 false로 설정해야한다.
function handleAgreementItemClick(type: ModalType) {
if (type === null) return;
if (agreements[type]) {
const newAgreements = {
...agreements,
[type]: !agreements[type],
};
setAgreements(newAgreements);
onAgreementsChange(newAgreements);
setIsChecked(false);
} else {
openModal(type);
}
}
!연산자를 사용하여 이를 구현하였다.
약관 모달 세부 내용 출력
각 항목별로 title, mesage, type을 나누어 관련 정보를 출력하도록 하였다.
const getModalContent = (type: ModalType) => {
switch (type) {
case 'privacy':
return {
title: '[필수] 개인정보처리방침',
message: '개인정보처리방침에 관한 내용입니다. 동의하시겠습니까?',
type: 'normal',
};
case 'terms':
return {
title: '[필수] 이용약관',
message: '이용약관에 관한 내용입니다. 동의하시겠습니까?',
type: 'normal',
};
case 'marketing':
return {
title: '[선택] 마케팅 이용 동의',
message:
'마케팅 이용에 동의하시면 다양한 이벤트 정보를 받아보실 수 있습니다. 동의하시겠습니까?',
type: 'normal',
};
case 'youtube':
return {
title: '[선택] 유튜브 계정 연동',
message:
'유튜브 계정 연동에 동의하시면 서비스를 더 풍부하게 이용하실 수 있습니다.',
type: 'youtube',
};
유튜브 약관동의 모달
다른 약관 동의 항목과 달리, 유튜브 약관 동의 모달은 내용이 많고, api 호출 관련 내용까지 있어서 다른 컴포넌트로 구분하였다.
checkbox로 된 점을 제외하면 위의 코드와 같이 객체로 각 항목에 대한 boolean값을 설정하여 저장했다.
따라서 작성한 코드를 다시 작성하지는 않겠다.
UX 개선
출력된 모달을 닫으려면 X 아이콘을 누를 때도 있지만, esc를 눌러 종료하는 경우가 대부분일 것이다.
이 내용을 구현해보자
모달이 출력되어 있을 때 Esc를 의미하는 Escape가 눌리면, Modal을 null로 설정하여 닫히도록 하였다.
showModal을 의존성 배열로 추가하여 변화되는 값을 리액트가 추적하도록 하였다.
useEffect(() => {
const handleEscKey = (event: KeyboardEvent) => {
if (event.key === 'Escape' && showModal) {
setModalQueue([]);
setShowModal(null);
}
};
window.addEventListener('keydown', handleEscKey);
return () => {
window.removeEventListener('keydown', handleEscKey);
};
}, [showModal]);
'패스트캠퍼스 데브캠프' 카테고리의 다른 글
파이널 프로젝트 - 회원가입 (4) - 회원정보 입력 (0) | 2025.04.03 |
---|---|
파이널 프로젝트 - 회원가입(3) - 전화번호 인증 (0) | 2025.04.03 |
파이널 프로젝트 - 회원가입(1) 약관 동의 (0) | 2025.04.03 |
파이널 프로젝트 - 코드복기(1) 내용정리 (0) | 2025.04.03 |
김민태의 데브캠프 2기 - 중간 회고 (1) | 2025.01.23 |