- 공통 템플릿 타입 수정 (IntegratedDetailTemplate, UniversalListPage) - 페이지(app/[locale]) 타입 호환성 수정 (80개) - 재고/자재 모듈 타입 수정 (StockStatus, ReceivingManagement) - 생산 모듈 타입 수정 (WorkOrders, WorkerScreen, WorkResults) - 주문/출고 모듈 타입 수정 (ShipmentManagement, Orders) - 견적/단가 모듈 타입 수정 (Quotes, Pricing) - 건설 모듈 타입 수정 (49개, 17개 하위 모듈) - HR 모듈 타입 수정 (CardManagement, VacationManagement 등) - 설정 모듈 타입 수정 (PermissionManagement, AccountManagement 등) - 게시판 모듈 타입 수정 (BoardManagement, BoardList 등) - 회계 모듈 타입 수정 (VendorManagement, BadDebtCollection 등) - 기타 모듈 타입 수정 (CEODashboard, clients, vehicle 등) - 유틸/훅/API 타입 수정 (hooks, contexts, lib) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
166 lines
4.6 KiB
TypeScript
166 lines
4.6 KiB
TypeScript
/**
|
|
* Card Management - IntegratedDetailTemplate Config
|
|
*
|
|
* 카드관리 등록/상세/수정 페이지 설정
|
|
*/
|
|
|
|
import { CreditCard } from 'lucide-react';
|
|
import type { DetailConfig } from '@/components/templates/IntegratedDetailTemplate';
|
|
import type { Card, CardFormData, CardStatus, CardCompany } from './types';
|
|
import {
|
|
CARD_COMPANIES,
|
|
CARD_STATUS_LABELS,
|
|
getCardCompanyLabel,
|
|
} from './types';
|
|
import { getActiveEmployees } from './actions';
|
|
|
|
// 상태 옵션
|
|
const CARD_STATUS_OPTIONS = [
|
|
{ value: 'active', label: CARD_STATUS_LABELS.active },
|
|
{ value: 'suspended', label: CARD_STATUS_LABELS.suspended },
|
|
];
|
|
|
|
export const cardConfig: DetailConfig<Card> = {
|
|
title: '카드',
|
|
description: '카드 정보를 관리합니다',
|
|
icon: CreditCard,
|
|
basePath: '/hr/card-management',
|
|
|
|
// 그리드 2열
|
|
gridColumns: 2,
|
|
|
|
// 섹션 정의
|
|
sections: [
|
|
{
|
|
id: 'basic',
|
|
title: '기본 정보',
|
|
fields: ['cardCompany', 'cardNumber', 'expiryDate', 'pinPrefix', 'cardName', 'status'],
|
|
},
|
|
{
|
|
id: 'user',
|
|
title: '사용자 정보',
|
|
fields: ['userId'],
|
|
},
|
|
],
|
|
|
|
// 필드 정의
|
|
fields: [
|
|
{
|
|
key: 'cardCompany',
|
|
label: '카드사',
|
|
type: 'select',
|
|
required: true,
|
|
options: CARD_COMPANIES.map(c => ({ value: c.value, label: c.label })),
|
|
placeholder: '카드사를 선택하세요',
|
|
},
|
|
{
|
|
key: 'cardNumber',
|
|
label: '카드번호',
|
|
type: 'cardNumber',
|
|
required: true,
|
|
placeholder: '0000-0000-0000-0000',
|
|
helpText: '16자리 카드번호를 입력하세요',
|
|
},
|
|
{
|
|
key: 'expiryDate',
|
|
label: '유효기간',
|
|
type: 'text',
|
|
required: true,
|
|
placeholder: 'MMYY',
|
|
helpText: '월/년 4자리 (예: 1225)',
|
|
},
|
|
{
|
|
key: 'pinPrefix',
|
|
label: '카드 비밀번호 앞 2자리',
|
|
type: 'password',
|
|
placeholder: '**',
|
|
},
|
|
{
|
|
key: 'cardName',
|
|
label: '카드명',
|
|
type: 'text',
|
|
placeholder: '카드명을 입력해주세요',
|
|
},
|
|
{
|
|
key: 'status',
|
|
label: '상태',
|
|
type: 'select',
|
|
required: true,
|
|
options: CARD_STATUS_OPTIONS,
|
|
placeholder: '상태 선택',
|
|
},
|
|
{
|
|
key: 'userId',
|
|
label: '부서 / 이름 / 직책',
|
|
type: 'select',
|
|
placeholder: '선택해서 해당 카드의 사용자로 설정',
|
|
gridSpan: 2,
|
|
// 동적 옵션 로드
|
|
fetchOptions: async () => {
|
|
const result = await getActiveEmployees();
|
|
if (result.success && result.data) {
|
|
return result.data.map(emp => ({ value: emp.id, label: emp.label }));
|
|
}
|
|
return [];
|
|
},
|
|
},
|
|
],
|
|
|
|
// 액션 설정
|
|
actions: {
|
|
showDelete: true,
|
|
showEdit: true,
|
|
showBack: true,
|
|
deleteConfirmMessage: {
|
|
title: '카드 삭제',
|
|
description: '카드를 정말 삭제하시겠습니까?\n삭제된 카드 정보는 복구할 수 없습니다.',
|
|
},
|
|
},
|
|
|
|
// 초기 데이터 변환 (API 응답 → formData)
|
|
transformInitialData: (card: Card): Record<string, unknown> => ({
|
|
cardCompany: card.cardCompany || '',
|
|
cardNumber: card.cardNumber || '',
|
|
cardName: card.cardName || '',
|
|
expiryDate: card.expiryDate || '',
|
|
pinPrefix: '', // 비밀번호는 항상 빈 값
|
|
status: card.status || 'active',
|
|
userId: card.user?.id || '',
|
|
}),
|
|
|
|
// 제출 데이터 변환 (formData → API 요청)
|
|
transformSubmitData: (formData: Record<string, unknown>): Partial<CardFormData> => ({
|
|
cardCompany: formData.cardCompany as CardCompany,
|
|
cardNumber: formData.cardNumber as string,
|
|
cardName: formData.cardName as string,
|
|
expiryDate: formData.expiryDate as string,
|
|
pinPrefix: formData.pinPrefix as string,
|
|
status: formData.status as CardStatus,
|
|
userId: formData.userId as string,
|
|
}),
|
|
|
|
// View 모드 값 포맷터
|
|
formatViewValue: (key: string, value: unknown, data: Record<string, unknown>) => {
|
|
switch (key) {
|
|
case 'cardCompany':
|
|
return getCardCompanyLabel(value as CardCompany);
|
|
case 'expiryDate':
|
|
// MMYY → MM/YY
|
|
const date = value as string;
|
|
if (date && date.length === 4) {
|
|
return `${date.slice(0, 2)}/${date.slice(2)}`;
|
|
}
|
|
return date || '-';
|
|
case 'userId':
|
|
// 사용자 정보 조합 표시
|
|
const userData = data as unknown as Card;
|
|
if (userData.user) {
|
|
return `${userData.user.departmentName} / ${userData.user.employeeName} / ${userData.user.positionName}`;
|
|
}
|
|
return '미지정';
|
|
default:
|
|
return undefined; // 기본 렌더링 사용
|
|
}
|
|
},
|
|
};
|