feat(frontend): Ant Design Pro 패턴 전면 적용

@ant-design/pro-components ^2.8.10 + @ant-design/icons ^6.2 추가.

ProLayout (MainLayout):
- mix 레이아웃 (사이드바 + 헤더 통합), navTheme=light
- 자체 메뉴 트리 렌더링 (children 트리), 동적 메뉴 매핑
- 헤더 actionsRender: 정산월 MonthPicker / 알림 뱃지
- avatarProps: 그라디언트 아바타 + Dropdown 로그아웃
- token: 사이드바/헤더 컬러, pageContainer padding
- footerRender: 버전 표기

PageContainer (Pro):
- @ant-design/pro-layout 의 PageContainer 사용
- 자동 Breadcrumb / Title / extra 슬롯

ProTable 마이그레이션 (6 페이지):
- AgentList: search + valueEnum, request → PageHelper 변환
- ContractList, RecruitLedger, ExceptionLedger, SettleList, PaymentList, UserList
- 검색 폼 자동 생성 (valueType: select/dateMonth 등)
- toolBarRender: 등록/엑셀 버튼
- options: density/fullScreen/reload/setting

Dashboard:
- ProCard + StatisticCard 로 KPI 4종 그리드
- 차트 + 배치 진행 + 알림을 ProCard 로 묶음

검증:
- tsc -b 통과
- vite build 성공 (2.6MB / gzip 811KB)
- 백엔드 76건 단위테스트 영향 없음

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
GA Pro
2026-05-10 22:20:33 +09:00
parent e70589fda8
commit 020939e563
12 changed files with 1387 additions and 797 deletions
@@ -1,7 +1,5 @@
import { ReactNode } from 'react';
import { Typography } from 'antd';
const { Title } = Typography;
import { PageContainer as ProPageContainer } from '@ant-design/pro-components';
interface Props {
title: string;
@@ -11,52 +9,24 @@ interface Props {
}
/**
* 페이지 표준 컨테이너.
* - 상단: 제목 + 좌측 컬러 바 + 우측 액션
* - 본문: 흰 카드 + 그림자
* 09_UI_DESIGN.md §4 타입 A 의 시각적 보강 버전.
* Ant Design Pro 의 PageContainer 래퍼.
* - 자동 Breadcrumb / Title / Tabs / Footer 슬롯 제공
* - extra 는 우측 상단 액션 영역
*/
export default function PageContainer({ title, description, extra, children }: Props) {
return (
<div>
{/* 페이지 제목 영역 */}
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: '16px 20px',
background: '#ffffff',
borderRadius: 8,
marginBottom: 16,
boxShadow: 'var(--ga-shadow-card)',
borderLeft: '4px solid var(--ga-primary)',
}}
>
<div>
<Title level={4} style={{ margin: 0, fontSize: 18, fontWeight: 600 }}>
{title}
</Title>
{description && (
<div style={{ fontSize: 12, color: '#888', marginTop: 4 }}>
{description}
</div>
)}
</div>
{extra && <div>{extra}</div>}
</div>
{/* 본문 카드 */}
<div
style={{
background: '#ffffff',
borderRadius: 8,
padding: 20,
boxShadow: 'var(--ga-shadow-card)',
}}
>
{children}
</div>
</div>
<ProPageContainer
header={{
title,
breadcrumb: {},
ghost: false,
extra,
}}
content={
description ? <span style={{ color: '#666', fontSize: 13 }}>{description}</span> : undefined
}
>
{children}
</ProPageContainer>
);
}