파트너 헤더에 보유금액·KPI 칩 추가
목차
파트너 헤더 영역에 보유금액과 시스템 KPI 칩을 추가했다. 작업 자체는 뷰·스타일 파일 몇 개 수정으로 끝났지만, 그 뒤에 붙어 있는 고민이 생각보다 많았다.
파트너 관리 화면은 운영팀이 하루에도 수십 번 열어보는 화면이다. 보유금액이나 KPI 수치는 "일단 어딘가에 있다"가 아니라 "눈에 바로 들어온다"가 돼야 의미가 있다. 정보가 있어도 스크롤을 내려야 찾을 수 있거나, 숫자가 작아서 한 번 더 읽어야 한다면 사실상 없는 거나 마찬가지다. 그래서 헤더 고정 영역에 칩 형태로 올린 것.
실제로 건드린 것들
헤더 레이아웃 정렬부터 잡았다. 기존 구조는 좌측 파트너명과 우측 액션 버튼만 있었는데, 여기에 금액·KPI 칩을 끼워 넣으면서 플렉스 정렬이 틀어졌다. justify-content: space-between으로 양끝 정렬을 유지하면서 칩 그룹은 중앙 영역에 절대 위치가 아니라 플렉스 아이템으로 넣었다. 절대 위치로 박으면 반응형에서 바로 깨진다.
칩/뱃지 비주얼은 기존 뱃지 컴포넌트를 그대로 쓰면 크기와 색상이 헤더 맥락에 안 맞아서 별도 variant를 만들었다. --chip-bg, --chip-text 같은 CSS 변수를 두고 테마 레벨에서 한 번에 조정할 수 있게 했다.
.partner-header__chip {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 10px;
border-radius: 99px;
background: var(--chip-bg, #f0f4ff);
color: var(--chip-text, #3a5bd9);
font-size: 0.8125rem;
font-weight: 600;
white-space: nowrap;
}
.partner-header__chip--amount {
--chip-bg: #fff7ed;
--chip-text: #c2410c;
}
KPI 칩은 상태에 따라 색상이 달라진다. 임계값 이상이면 강조, 미달이면 경고 톤. 이 부분은 클래스를 조건부로 바인딩하는 방식으로 처리했다. 색상 분기를 인라인 스타일로 박으면 나중에 다크모드나 테마 교체할 때 전부 뜯어야 한다.
아이콘은 크기를 1em 기준으로 맞췄다. 고정 px로 박으면 부모 폰트 크기가 바뀔 때 아이콘만 따로 놀게 된다. vertical-align: middle만으로는 미묘하게 내려가는 경우가 있어서 position: relative; top: -1px 한 줄 추가로 맞췄다. 픽셀 단위 미세 조정이 귀찮지만 이게 없으면 완성도가 티가 난다.
반응형은 768px 브레이크포인트에서 칩을 헤더 하단 줄로 내렸다. 모바일에서 한 줄에 다 우겨넣으면 파트너명이 잘린다. SCSS를 쓰고 있어서 브레이크포인트 mixin을 활용했다.
@mixin respond-to($bp) {
@if $bp == 'mobile' {
@media (max-width: 767px) { @content; }
} @else if $bp == 'tablet' {
@media (min-width: 768px) and (max-width: 1023px) { @content; }
}
}
.partner-header__chips {
display: flex;
gap: 6px;
@include respond-to('mobile') {
width: 100%;
padding-top: 8px;
border-top: 1px solid var(--border-light);
}
}
이 mixin을 프로젝트 초반에 만들어두면 뷰마다 미디어쿼리 조건을 반복해서 쓰지 않아도 된다. 브레이크포인트가 바뀌어도 mixin 한 곳만 고치면 되고.
금융 도메인에서 숫자를 다룰 때
보유금액을 헤더에 노출하는 작업은 UI 작업이지만, 그 숫자가 어디서 오는지는 짚고 넘어가야 했다. 표시하는 값이 어느 시점 기준 집계인지, 캐시된 값인지 실시간 조회인지, 소수점 처리는 어떻게 되는지. 화면에 뿌리기만 하면 되는 것처럼 보여도 출처를 모르면 나중에 숫자가 안 맞는다는 제보가 왔을 때 어디서부터 봐야 하는지 모른다.
이번 건은 기존 API 응답에 이미 집계값이 있었고, 표시 형식만 결정하면 됐다. 금액 포맷은 Intl.NumberFormat으로 통일했다. 로케일과 통화 단위를 인자로 받을 수 있어서 나중에 다른 화폐 단위가 필요해져도 컴포넌트를 건드릴 필요가 없다.
const formatAmount = (value, currency = 'KRW') =>
new Intl.NumberFormat('ko-KR', {
style: 'currency',
currency,
maximumFractionDigits: 0,
}).format(value);
KPI 칩은 데이터 타입에 따라 포맷이 달랐다. 비율은 퍼센트, 건수는 정수, 금액은 통화. 각 칩이 어떤 타입인지를 데이터 레벨에서 명시해두고 렌더링 쪽에서는 타입만 보고 처리하도록 했다. 칩마다 포맷 로직을 하드코딩하면 종류가 늘어날 때 그만큼 수정 지점이 늘어난다.
작업 후기
사내 관리 화면이라고 대충 넘기기 쉬운데, 오히려 내부 도구가 외부 서비스보다 더 자주 쓰이는 경우가 많다. 운영팀이 매일 쓰는 화면이 어수선하면 그 피로가 쌓인다. 파트너 헤더 하나 정리했다고 뭔가 크게 달라진 것처럼 보이지 않지만, 숫자를 찾기 위해 한 번씩 더 스크롤하던 게 없어지면 그게 하루에 몇 번이 쌓여서 나름의 차이가 된다.
디자인 원칙이라고 거창하게 적었지만 결국 "읽기 쉽냐"로 귀결된다. 숫자는 크고 굵게, 단위·레이블은 작고 흐리게, 상태는 색으로 구분. WCAG AA 기준 대비 4.5:1은 접근성 지침이기도 하지만 그냥 가독성 기준으로도 타당하다. 색 구분이 안 되는 환경이나 야간 모드에서도 버텨야 하니까.
CSS !important를 남발하면 결국 나 자신이 나중에 고생한다. specificity 올리는 방향, 변수 활용, mixin 추출. 처음에 조금 더 시간 쓰면 나중에 수정 비용이 훨씬 줄어든다. 그걸 압축하면 작업 전 스크린샷 또는 수치 메모, 수정 후 같은 케이스 확인, 관련 화면 cross-check, 커밋은 "무엇"보다 "왜"로 남기는 것. 금융 도메인에서 숫자 하나가 어긋나면 신뢰 문제로 직결되기 때문에 이 습관은 선택이 아니다.
댓글 0
첫 댓글 달아줘.