
유 동 우
디자인과 기술의 조화를 실현하는 프론트엔드 개발자 유동우 입니다.
Frontend Next React TypeScript JavaScript Git Slack
👋 Introduce
협업을 통해 최선의 결과물을 도출해 내는 것을 좋아하며 맡은 일에 후회 없도록 마무리하는 것에 뿌듯함을 느낍니다. 현재 개발 트렌드를 배우기 위해 개발 콘퍼런스에 끊임없이 참여하여 개발자로서 새로운 것을 배우는 욕심과 그에 맞게 성장하고자 하는 목표를 갖고 있습니다.
🧑💻 Career
[ 잇올 ]
2025.02 ~
AI 기술을 접목해서 학습 관리 서비스를 진행하는 에듀 테크 기업
<aside>
📄
잇올 어드민 - 합격증 검수/통계 (진행 중) 2025.11 ~
수집한 합격증의 분류 상태 점검 및 통계 데이터 시각화 기능 FE 개발
- 서버 상태 관리 및 데이터 동기화 아키텍처 설계
- React Query 기반 데이터 관리: useQuery(useCertificateVerificationsStaffDetail)와 useMutation(useCertificateVerificationsStaffMemo) 커스텀 훅을 활용하여 서버 데이터의 조회, 캐싱, 수정 로직을 분리했습니다. 이를 통해 컴포넌트는 UI 렌더링에만 집중하고, 데이터 관리의 복잡성을 대폭 감소시켰습니다.
- 데이터 정합성 유지: 메모 저장 또는 검수 결과 확정/수정 시, 뮤테이션의 onSuccess 콜백에서 연관된 쿼리(목록, 상세)의 refetch 함수를 호출하여 화면 간 데이터 불일치 문제를 해결하고 항상 최신 상태를 유지하도록 설계했습니다.
- 비동기 로딩 및 에러 처리: 데이터 로딩 상태에 따른 조건부 렌더링을 적용하여 비동기 데이터가 도착하기 전 발생할 수 있는 런타임 에러를 방지했으며, 뮤테이션의 onError 콜백을 통해 API 실패 시 사용자에게 즉각적인 피드백(팝업)을 제공하는 안정적인 로직을 구현했습니다.
- 상태 기반 동적 UI 및 비즈니스 로직 구현
- 상태에 따른 UI 제어: 검수 상태(verificationStatus) 값(예: PENDING_CONFIRMATION, DUPLICATED)에 따라 UI 컴포넌트의 속성을 동적으로 제어했습니다. 예를 들어, 특정 상태에서는 메모 입력창을 disabled 처리하고, 다른 상태에서는 버튼의 라벨('확정'/'수정')과 색상(variant)을 변경하여 사용자의 오조작을 방지하고 명확한 가이드를 제공했습니다.
- 관심사 분리를 통한 상태 관리: 좌측 패널의 선택 ID(selectedId), 필터(statusFilter)와 우측 패널의 검수 결과(results), 메모(staffMemo) 등 지역 상태를 useState로 관리하고, 필요한 상태와 핸들러만 Props로 하위 컴포넌트에 전달하는 단방향 데이터 흐름을 적용하여 컴포넌트 간 의존성을 낮추고 예측 가능한 상태 관리를 구현했습니다.
- 컨텍스트 API를 활용한 공통 기능 추상화: usePopup 커스텀 훅을 사용하여 메모 저장 결과 알림, 화면 종료 확인 등 반복적으로 사용되는 팝업 호출 로직을 표준화하고, 컴포넌트 코드의 가독성과 재사용성을 높였습니다.
- 사용자 경험(UX) 및 상호작용 최적화
- 워크플로우 자동화: useEffect 훅을 사용하여 목록 데이터 로드 시 첫 번째 항목을 자동으로 선택하고, 필터 변경으로 인해 선택된 항목이 목록에서 사라질 경우 유효한 첫 항목으로 재선택하는 로직을 구현하여 사용자의 불필요한 클릭을 최소화했습니다.
- 시각적 피드백 강화: 자동 스크롤: useRef와 scrollIntoView를 결합하여 긴 목록에서도 현재 선택된 항목이 항상 화면 중앙에 보이도록 하여 가시성을 확보했습니다.
- 실시간 입력 카운터: 메모 입력 시 maxLength와 함께 현재 글자 수를 실시간으로 표시하여 사용자에게 입력 제한에 대한 명확한 피드백을 제공했습니다.
- 데이터 손실 방지: 화면 종료 시 저장되지 않은 데이터가 있을 수 있음을 경고하는 확인(Confirm) 팝업을 구현하여, 사용자의 실수로 인한 작업 내용 소실을 방지하고 서비스 신뢰도를 향상시켰습니다.
- 해결한 문제
- 검수 리스트에서 선택 상태 유지 및 유효성 검증으로 잘못된 아이템 선택으로 인한 작업 중단 문제 해소
- 상태 필터에 따른 목록 가시성 개선과 상세 패널과의 동기화 불일치 문제 해결
- 검수 종료 시 저장되지 않은 메모 손실 경고 플로우로 오사용 방지
React.js, TypeScript, Tailwind
</aside>
<aside>
📄
잇올 스파르타 - 합격증 등록 서비스 2025.10
본인인증 후 학생이 직접 합격증을 등록하는 모바일 웹 서비스 FE 개발
- PortOne 본인인증 API를 연동하여 학생 신원 확인 프로세스를 구현했습니다. 본인인증 완료 후 학생 정보를 자동으로 폼에 채워 사용자 경험을 개선했습니다.
- 다단계 폼 플로우(본인인증 → 합격증 정보 입력 → 이미지 업로드 → 최종 제출)를 구현했고, 각 단계별 유효성 검사와 진행 상태 표시를 통해 사용자가 현재 위치를 파악할 수 있도록 했습니다.
- React Hook Form과 Zod를 활용해 합격증 정보(시험명, 합격일자, 점수 등) 입력 폼의 validation을 구현했습니다. 실시간 에러 메시지로 사용자가 즉시 입력 오류를 수정할 수 있도록 했습니다.
- Next.js App Router를 활용해 각 단계를 별도 라우트로 분리하고, 뒤로가기 시에도 이전 입력 데이터가 유지되도록 상태 관리를 했습니다.
Next.js, TypeScript, Tailwind
</aside>
<aside>
📄
잇올 어드민 - 합격증 수집/등록 2025.09 ~ 2025.11
합격증을 수집하고 분류하는 어드민 기능 FE 개발
- React Hook Form과 Zod를 결합하여 타입 안전한 폼 validation을 구현했습니다. 합격증 등록 폼에서 필수 정보(학생명, 시험명, 합격일자 등) 검증 로직을 스키마로 관리하여 유지보수성을 높였습니다.
- React Query(Tanstack Query)를 활용해 합격증 목록 조회, 등록, 수정, 삭제 작업의 서버 상태를 관리했습니다. useMutation으로 등록/수정 후 queryClient.invalidateQueries를 통해 목록을 자동으로 갱신하여 사용자 경험을 개선했습니다.
- 복잡한 필터링 기능(학생명, 시험 종류, 날짜 범위 등)을 구현했고, Zustand로 필터 상태를 관리하여 페이지 이동 후에도 필터 조건이 유지되도록 했습니다.
- 합격증 이미지 업로드 기능을 구현했으며, 이미지 미리보기와 다중 파일 업로드를 지원했습니다. 파일 크기 및 형식 제한을 클라이언트 단에서 검증하여 불필요한 서버 요청을 줄였습니다.
- TypeScript strict mode를 활성화하고 any 타입 사용을 금지하여 타입 안정성을 확보했습니다. API 응답 타입과 Form 타입을 명확하게 정의했습니다.
React.js, TypeScript, Tailwind
</aside>
<aside>
📄
잇올 몰입형 기숙학원 홈페이지 2025.04 ~ 2025.10
- Github Action과 Vercel을 이용한 CI/CD 배포 환경 구성
- Turbo Repo
- BFF(Backend for Frontend) 아키텍처 적용
- 프론트엔드에서 사용하는 데이터를 프론트 전용 API 서버에서 가공하여 제공, API 응답 구조 단순화 및 비즈니스 로직 분리
Next.js, TypeScript, Tailwind
</aside>
<aside>
📄
6월 평가원 모의고사 2025.03 ~ 2025.04
- Github Action과 Vercel을 이용한 CI/CD 배포 환경 구성
- 신청 상태(NOT_APPLY, APPLY, CLOSED, RESULT)에 따라 버튼 및 화면 동작이 달라지는 상태 기반 UI 흐름 구현
- 잔여 좌석 확인 API 연동을 통해 신청 가능 여부를 실시간으로 판단하고, 조건에 따라 페이지 이동 또는 상태 변경 처리
- 신청 폼 페이지 진입 시 sessionStorage를 활용한 인증 처리 구현
- URL 직접 접근 및 뒤로 가기 통한 우회 접근 방지
- 지역, 센터, 과목 등 동적 드롭다운 리스트 구성 및 조건부 선택 제한 처리 (ex. 공석이 없는 센터는 비활성화)
- 중복 신청, 잔여 좌석 없음 등 예외 상황에 대한 에러 코드 처리 및 사용자 피드백 제공
- 전반적인 컴포넌트 구성에 Atomic Design 패턴 적용하여 재사용성과 유지보수성 확보
Next.js, TypeScript
</aside>
[ 유니버스 AI ]
2024.07 ~ 2025.01
얼굴 인식 기술을 기반으로 편리하고 안전한 결제 솔루션을 제공하는 기업
<aside>
📄
UNIVS Studio (유니버스 스튜디오) 2024.11 ~ 2025.01
Cloud API, SDK 통합 다운로드 가능한 서비스 FE 개발
- Next.js와 TypeScript를 사용해 개발을 진행하였고, Neomorphic 디자인을 주로 사용해 화면 디자인을 하였습니다. Material UI 라이브러리를 사용해 공통으로 사용되는 컴포넌트를 만들었고, Atomic 디자인 패턴으로 컴포넌트 관리를 하였습니다. Emotion JS 로 style을 구현하였으며, emotion style이 적용된 Material 컴포넌트에는 S를 사용해 style이 적용되어 있는 컴포넌트로 구분을 하였습니다.
ex ) <S.Accordion />
- eslint 설정에 any type을 금지하여 명확한 type을 잡았습니다.
- 로그인/회원가입 구현 시 보안을 위해 랜덤 salt key를 생성해 password + salt key 조합으로 유저가 입력한 비밀번호를 hash화 해서 db에 저장하였습니다.
- NextAuth Credentials 를 사용해 로그인을 Next 서버에서 진행 후 백엔드 api를 호출하여 cookie와 session에 token을 저장하여 사용하였고, middleware를 구축해 token이 없을 때 다른 페이지에 접속 시 sign in 페이지로 return 되게 설정하였습니다.
- Zustand로 상태 관리를 진행하였고, 검색 or 페이지네이션 이동 후 다른 페이지로 넘어간 뒤에 다시 기존 페이지로 돌아가도 검색 내역 or 기존 페이지 처리를 진행하였습니다.
- 복잡한 data가 오는 api 콜에는 react-query를 사용해서 데이터 캐싱을 하였고, 메모이제이션 훅을 사용해 불필요한 api 재호출/랜더링을 막았습니다.
Next.js, TypeScript, Next-Auth, Tanstack-Query, Zustand, Material-ui, crypto-js, dayjs
</aside>
<aside>
📄
UNIVS Guard (유니버스 가드) 2024.07 ~ 2025.01
AI CCTV 얼굴, 몸 분석/매칭하는 서비스 FE 개발
- Next.js와 TypeScript를 사용해 개발을 진행하였고, Next UI를 주로 사용하여 디자인을 진행했습니다.
- 로그인/회원가입 구현 시 보안을 위해 랜덤 salt key를 생성해 password + salt key 조합으로 유저가 입력한 비밀번호를 hash화 해서 db에 저장하였습니다.
- 기존에는 cctv에 찍힌 인물과 db에 있는 인물이 일치할 때 일정 페이지 내에서만 알 수 있었는데 주 기능이 몇몇 페이지 내에 국한된 것 같아 프로젝트 전체에서 알림을 띄우는 기능을 SSE event-source-polyfill를 이용해 개발하였습니다.
- 복잡한 data가 오는 api 콜에는 react-query를 사용해서 데이터 캐싱을 하였고, 메모이제이션 훅을 사용해 불필요한 api 재호출/랜더링을 막았습니다.
- 매칭된 리스트들을 엑셀과 pdf 로 다운 받을 수 있는 기능을 개발하였고, 카메라 등록 시 하나하나 등록해야하는 불편함이 있었기 때문에 엑셀 파일에 리스트업 후 한 번에 등록할 수 있는 기능을 개발하였습니다.
- 매칭 건수, 작동 중인 카메라 수 등 지표를 한 눈에 보기 위해 recharts 를 이용해 대시보드를 구현했습니다.
Next.js, TypeScript, Next-ui, Tanstack-Query, recoil, i18next, ol, crypto-js, dayjs, recharts
</aside>