feat(CEODashboard): Phase 3 - 카드/가지급금 관리 모달 API 연동

Phase 3: Modal Component Integration (cm1-cm4)

### 새 파일
- cardManagementConfigTransformers.ts: API 응답을 모달 설정으로 변환
  - transformCm1ModalConfig: 카드 사용액 상세
  - transformCm2ModalConfig: 가지급금 상세
  - transformCm3ModalConfig: 법인세 시뮬레이션
  - transformCm4ModalConfig: 종합소득세 시뮬레이션
  - 유틸리티: formatKoreanCurrency, calculateChangeRate, formatPercentage

### 수정 파일
- cardManagementConfigs.ts:
  - getCardManagementModalConfigWithData() 추가
  - API 데이터 우선, 없을 시 fallback 설정 사용

- useCardManagementModals.ts:
  - fetchModalData()가 데이터 직접 반환하도록 수정
  - CardManagementModalData 타입 추가

- CEODashboard.tsx:
  - useCardManagementModals 훅 연동
  - handleCardManagementCardClick에서 API 데이터 사용
This commit is contained in:
2026-01-22 23:11:19 +09:00
parent 1ba0561ee9
commit bf11b13aee
5 changed files with 608 additions and 22 deletions

View File

@@ -30,6 +30,14 @@ import type {
/** 카드 ID 타입 */
export type CardManagementCardId = 'cm1' | 'cm2' | 'cm3' | 'cm4';
/** 모달 데이터 반환 타입 */
export interface CardManagementModalData {
cm1Data?: CardDashboardDetailApiResponse | null;
cm2Data?: LoanDashboardApiResponse | null;
cm3Data?: TaxSimulationApiResponse | null;
cm4Data?: TaxSimulationApiResponse | null;
}
/** Hook 반환 타입 */
export interface UseCardManagementModalsReturn {
/** cm1: 카드 사용액 상세 데이터 */
@@ -44,8 +52,8 @@ export interface UseCardManagementModalsReturn {
loading: boolean;
/** 에러 메시지 */
error: string | null;
/** 특정 카드의 모달 데이터 조회 */
fetchModalData: (cardId: CardManagementCardId) => Promise<void>;
/** 특정 카드의 모달 데이터 조회 - 데이터 직접 반환 */
fetchModalData: (cardId: CardManagementCardId) => Promise<CardManagementModalData>;
/** 모든 카드 데이터 조회 */
fetchAllData: () => Promise<void>;
/** 데이터 초기화 */
@@ -78,12 +86,14 @@ export function useCardManagementModals(): UseCardManagementModalsReturn {
/**
* cm1: 카드 사용액 상세 데이터 조회
* @returns 조회된 데이터 (실패 시 null)
*/
const fetchCm1Data = useCallback(async () => {
const fetchCm1Data = useCallback(async (): Promise<CardDashboardDetailApiResponse | null> => {
try {
const response = await fetchCardTransactionDashboard();
if (response.success) {
if (response.success && response.data) {
setCm1Data(response.data);
return response.data;
} else {
throw new Error(response.message || '카드 거래 데이터 조회 실패');
}
@@ -96,12 +106,14 @@ export function useCardManagementModals(): UseCardManagementModalsReturn {
/**
* cm2: 가지급금 상세 데이터 조회
* @returns 조회된 데이터 (실패 시 null)
*/
const fetchCm2Data = useCallback(async () => {
const fetchCm2Data = useCallback(async (): Promise<LoanDashboardApiResponse | null> => {
try {
const response = await fetchLoanDashboard();
if (response.success) {
if (response.success && response.data) {
setCm2Data(response.data);
return response.data;
} else {
throw new Error(response.message || '가지급금 데이터 조회 실패');
}
@@ -115,14 +127,16 @@ export function useCardManagementModals(): UseCardManagementModalsReturn {
/**
* cm3 & cm4: 세금 시뮬레이션 데이터 조회
* cm3은 법인세 (corporate_tax), cm4는 소득세 (income_tax) 사용
* @returns 조회된 데이터 (실패 시 null)
*/
const fetchTaxData = useCallback(async () => {
const fetchTaxData = useCallback(async (): Promise<TaxSimulationApiResponse | null> => {
try {
const response = await fetchTaxSimulation();
if (response.success) {
if (response.success && response.data) {
// cm3, cm4 모두 같은 데이터 소스 사용 (표시만 다름)
setCm3Data(response.data);
setCm4Data(response.data);
return response.data;
} else {
throw new Error(response.message || '세금 시뮬레이션 데이터 조회 실패');
}
@@ -135,25 +149,31 @@ export function useCardManagementModals(): UseCardManagementModalsReturn {
/**
* 특정 카드의 모달 데이터 조회
* @returns 조회된 모달 데이터 객체 (카드 ID에 해당하는 데이터만 포함)
*/
const fetchModalData = useCallback(
async (cardId: CardManagementCardId) => {
async (cardId: CardManagementCardId): Promise<CardManagementModalData> => {
setLoading(true);
setError(null);
const result: CardManagementModalData = {};
try {
switch (cardId) {
case 'cm1':
await fetchCm1Data();
result.cm1Data = await fetchCm1Data();
break;
case 'cm2':
await fetchCm2Data();
result.cm2Data = await fetchCm2Data();
break;
case 'cm3':
case 'cm4':
case 'cm4': {
// cm3, cm4는 같은 API 사용
await fetchTaxData();
const taxData = await fetchTaxData();
result.cm3Data = taxData;
result.cm4Data = taxData;
break;
}
default:
throw new Error(`알 수 없는 카드 ID: ${cardId}`);
}
@@ -163,6 +183,8 @@ export function useCardManagementModals(): UseCardManagementModalsReturn {
} finally {
setLoading(false);
}
return result;
},
[fetchCm1Data, fetchCm2Data, fetchTaxData]
);