Files
sam-react-prod/src/components/accounting/CardTransactionInquiry/cardTransactionDetailConfig.ts
유병철 24b65bd6f5 feat: 카드 거래내역 등록/상세/수정 페이지 추가
- CardTransactionDetailClient 컴포넌트 생성
- cardTransactionDetailConfig 설정 파일 추가
- actions.ts에 CRUD API 함수 추가 (create, getById, update, delete, getCardList)
- 등록/상세/수정 페이지 생성 (new, [id], [id]/edit)
- 리스트에 "카드내역 등록" 버튼 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 19:08:30 +09:00

125 lines
3.6 KiB
TypeScript

import { CreditCard } from 'lucide-react';
import type { DetailConfig, FieldDefinition } from '@/components/templates/IntegratedDetailTemplate/types';
import type { CardTransaction } from './types';
import { USAGE_TYPE_OPTIONS } from './types';
import { getCardList } from './actions';
// ===== 필드 정의 =====
const fields: FieldDefinition[] = [
// 카드 선택 (create에서만 선택 가능)
{
key: 'cardId',
label: '카드',
type: 'select',
required: true,
placeholder: '카드를 선택해주세요',
fetchOptions: async () => {
const result = await getCardList();
if (result.success) {
return result.data.map((card) => ({
value: String(card.id),
label: `${card.name} (${card.cardNumber})`,
}));
}
return [];
},
disabled: (mode) => mode === 'view',
},
// 사용일시
{
key: 'usedAt',
label: '사용일시',
type: 'datetime-local',
required: true,
placeholder: '사용일시를 선택해주세요',
disabled: (mode) => mode === 'view',
},
// 가맹점명
{
key: 'merchantName',
label: '가맹점명',
type: 'text',
required: true,
placeholder: '가맹점명을 입력해주세요',
disabled: (mode) => mode === 'view',
},
// 사용금액
{
key: 'amount',
label: '사용금액',
type: 'number',
required: true,
placeholder: '사용금액을 입력해주세요',
disabled: (mode) => mode === 'view',
},
// 적요
{
key: 'memo',
label: '적요',
type: 'text',
placeholder: '적요를 입력해주세요',
gridSpan: 2,
disabled: (mode) => mode === 'view',
},
// 사용유형
{
key: 'usageType',
label: '사용유형',
type: 'select',
placeholder: '선택',
options: USAGE_TYPE_OPTIONS.map((opt) => ({
value: opt.value,
label: opt.label,
})),
disabled: (mode) => mode === 'view',
},
];
// ===== Config 정의 =====
export const cardTransactionDetailConfig: DetailConfig = {
title: '카드 사용내역',
description: '카드 사용 내역을 등록/수정합니다',
icon: CreditCard,
basePath: '/accounting/card-transactions',
fields,
gridColumns: 2,
actions: {
showBack: true,
showDelete: true,
showEdit: true,
backLabel: '목록',
deleteLabel: '삭제',
editLabel: '수정',
deleteConfirmMessage: {
title: '카드 사용내역 삭제',
description: '이 카드 사용내역을 삭제하시겠습니까? 삭제된 데이터는 복구할 수 없습니다.',
},
},
transformInitialData: (data: Record<string, unknown>): Record<string, unknown> => {
const record = data as unknown as CardTransaction;
// usedAt을 datetime-local 형식으로 변환 (YYYY-MM-DDTHH:mm)
let usedAtFormatted = '';
if (record.usedAt) {
// "2025-01-22 14:30" 형식을 "2025-01-22T14:30" 형식으로 변환
usedAtFormatted = record.usedAt.replace(' ', 'T').slice(0, 16);
}
return {
cardId: record.id ? '' : '', // 수정 시에는 카드 변경 불가
usedAt: usedAtFormatted,
merchantName: record.merchantName || '',
amount: record.amount || 0,
memo: record.memo || '',
usageType: record.usageType || 'unset',
};
},
transformSubmitData: (formData: Record<string, unknown>) => {
return {
cardId: formData.cardId ? Number(formData.cardId) : undefined,
usedAt: formData.usedAt as string,
merchantName: formData.merchantName as string,
amount: Number(formData.amount),
memo: formData.memo as string,
usageType: formData.usageType as string,
};
},
};