개발 slecs

어드민 핵심 페이지 UI를 shadcn 컴포넌트로 일관되게 통일한 과정

목차

어드민 핵심 페이지들 전반에 걸쳐 shadcn/ui 컴포넌트를 일관되게 적용하는 리팩토링 작업을 했다.

왜 지금 이 작업이었나

어드민 UI를 만들다 보면 초반엔 빠르게 돌아가는 게 우선이라, 페이지마다 제각각 스타일링이 섞이기 마련이다. 이번에 손댄 파일들을 보면 ad-units, categories, posts — 어드민에서 가장 자주 쓰이는 핵심 세 도메인이다. 각 도메인에 Filters 컴포넌트, 페이지 본체, DeleteButton 컴포넌트가 포함된 걸 보면, 이미 어느 정도 기능은 완성된 상태에서 "이제 통일하자"는 시점이 온 것이다.

shadcn/ui를 프로젝트에 도입했다면 그게 곧 디자인 시스템의 기준점이 된다. 근데 막상 보면 어떤 페이지는 shadcn Button을 쓰고, 어떤 페이지는 여전히 인라인 className으로 때운 커스텀 div-button이 섞여 있는 경우가 생긴다. 이 상태가 길어지면 팀원이 새 페이지를 만들 때 어느 걸 기준으로 삼아야 할지 모르게 된다. "저 페이지는 왜 다른 컴포넌트를 써요?"라는 질문이 코드리뷰에서 나오기 시작하면, 이미 기술 부채가 쌓이고 있다는 신호다.

어떤 파일들이 어떻게 바뀌었나

파일 역할 변경 포인트
AdUnitsFilters.tsx ad-unit 목록 필터 UI shadcn Input/Select 등으로 교체
ad-units/page.tsx ad-unit 목록 페이지 레이아웃/버튼 shadcn 통일
CategoriesDeleteButton.tsx 카테고리 삭제 버튼 shadcn Button + Dialog 패턴
categories/page.tsx 카테고리 목록 페이지 전체 UI 컴포넌트 정리
PostsDeleteButton.tsx 포스트 삭제 버튼 shadcn Button + Dialog 패턴
PostsFilters.tsx 포스트 목록 필터 UI shadcn Input/Select 등으로 교체

DeleteButton 계열이 두 개 함께 바뀐 게 눈에 띈다. CategoriesDeleteButton, PostsDeleteButton — 이 두 컴포넌트는 구조가 거의 같을 텐데, 이번에 shadcn으로 맞추면서 사실상 패턴도 동기화된 셈이다. 삭제 확인 Dialog를 shadcn AlertDialog로 쓰는 게 전형적인 패턴인데, 이게 한 곳에서만 적용되어 있으면 다른 도메인 DeleteButton을 만들 때 "어느 걸 따라야 하나" 혼란이 생긴다. 이번에 두 곳 다 맞췄으니 다음에 누가 DeleteButton을 새로 만들 때 참조 기준이 생긴 것이다.

Filters 계열도 마찬가지다. AdUnitsFilters, PostsFilters — 검색/필터 UI는 Input, Select, Button의 조합이 반복되는 구조다. 각자 다른 스타일로 구현돼 있으면 사용자 입장에서도 페이지마다 필터 UI가 미묘하게 달라 보이고, 개발자 입장에서도 유지보수 포인트가 두 배가 된다.

// Before: 커스텀 인라인 스타일 섞인 필터
<input
  className="border rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
  placeholder="검색..."
/>

// After: shadcn Input으로 통일
<Input placeholder="검색..." />

코드 자체는 단순해 보이지만 이게 6개 파일에 걸쳐 일관되게 정리됐다는 게 중요하다.

리팩토링 타이밍과 팀 관점

이런 UI 일관성 리팩토링은 "언제 하냐"가 항상 애매하다. 기능 개발 중엔 우선순위에서 밀리고, 너무 늦으면 파일이 더 많아져서 작업량이 커진다. 내 기준으로는 핵심 도메인 페이지가 어느 정도 완성된 직후, 새 기능이 추가되기 전이 골든 타임이다. 이번이 딱 그 타이밍이었다.

팀원 입장에서 이 작업의 실질적인 가치는:

  • 코드리뷰 시 "왜 여기만 다른 컴포넌트?"라는 질문이 사라짐
  • 신규 페이지 만들 때 기존 페이지를 복붙해도 shadcn 기준으로 올바르게 시작할 수 있음
  • 디자인 토큰/테마 변경 시 shadcn 기준으로만 수정하면 전체 반영됨

리팩토링 커밋은 기능 추가가 없어서 PR 우선순위가 낮아 보이기 쉬운데, 나는 이런 작업을 의도적으로 스프린트 안에 슬롯을 잡아서 넣는 편이다. "나중에 하자"는 결국 안 하게 되는 경우가 대부분이라서.

다음은 나머지 어드민 페이지들도 같은 기준으로 정리할 예정이고, DeleteButton 패턴은 공통 컴포넌트로 추출하는 것도 검토 중이다. 끝.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.