수업 기본 설정 폼: Zod 조건부 검증과 이탈 방지 훅
· 약 2분
그룹 수업의 예약 오픈 시점, 예약 마감 시점, 폐강 시점을 센터 단위 기본값으로 정해 두는 "수업 기본 설정" 페이지를 만들었다. 수업을 새로 만들 때 이 값이 기본으로 채워진다.
조건이 걸린 검증
폼은 react-hook-form에 zodResolver를 붙였다. 까다로운 건 조건부 규칙이었다. 예약 마감을 "수업 시작 전 N분"으로 고르면 N은 1 이상이어야 하고, "수업 시작 시"나 "종료 시"를 고르면 N은 상관없다. 필드 단위 규칙으로는 표현이 안 돼서 superRefine에서 묶어 검사했다.
.superRefine((data, ctx) => {
const isBeforeStart =
!data.isBookingClosedAtStarted && !data.isBookingClosedAtEnded;
if (isBeforeStart && data.bookingClosingTime === 0) {
ctx.addIssue({ code: 'custom', path: ['bookingClosingTime'], message: '1분 이상 입력해 주세요.' });
}
});
스키마 옆에 기본값 객체와 z.infer 타입을 같이 두니 폼, 테스트, 생성 화면이 같은 기준을 본다. 생성 화면에서는 설정값을 불러오는 래퍼 컴포넌트를 하나 두고 기존 그룹 수업 폼에 기본값으로 넘겼다.
QA에서 재미있는 버그가 하나 나왔다. 시간 입력은 일·시간·분 칸으로 나뉘어 보이는데, 첫 칸에 register의 ref를 연결해 두었더니 RHF가 분 단위 전체 값을 그 칸에 써 버렸다. 보이는 입력칸에서 register를 떼고 값은 setValue로만 관리하게 바꿨다. 에러 시 포커스 이동도 form.setFocus 대신 직접 만든 ref로 처리했다.
