- 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>
125 lines
3.6 KiB
TypeScript
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,
|
|
};
|
|
},
|
|
}; |