Files
sam-react-prod/src/components/vehicle-management/ForkliftDetail/config.tsx
유병철 e5f0f5da61 feat(WEB): 차량 관리 기능 추가 및 CEO 대시보드 Enhanced 섹션 적용
차량 관리 (신규):
- VehicleList/VehicleDetail: 차량 목록/상세
- ForkliftList/ForkliftDetail: 지게차 목록/상세
- VehicleLogList/VehicleLogDetail: 운행일지 목록/상세
- 관련 페이지 라우트 추가 (/vehicle-management/*)

CEO 대시보드:
- Enhanced 섹션 컴포넌트 적용 (아이콘 + 컬러 테마)
- EnhancedStatusBoardSection, EnhancedDailyReportSection, EnhancedMonthlyExpenseSection
- TodayIssueSection 개선

IntegratedDetailTemplate:
- FieldInput, FieldRenderer 기능 확장

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 14:53:20 +09:00

431 lines
12 KiB
TypeScript

'use client';
/**
* 지게차 관리 상세 페이지 설정
* 레거시 5130 사이트 등록 폼 기준 (2025-01-28 스크린샷 검증)
*/
import { Truck } from 'lucide-react';
import type {
DetailConfig,
FieldDefinition,
SectionDefinition,
} from '@/components/templates/IntegratedDetailTemplate/types';
import type { Forklift, ForkliftFormData, PartsChangeRecord, ForkliftMaintenanceRecord } from '../types';
import { EditableTable, EditableColumn } from '@/components/common/EditableTable';
// ===== 부속품 교환 기록 테이블 컬럼 =====
const partsChangeColumns: EditableColumn<PartsChangeRecord>[] = [
{
key: 'date',
header: '교환일',
type: 'text',
placeholder: 'YYYY-MM-DD',
width: '140px',
},
{
key: 'mileage',
header: '주행거리',
type: 'text',
placeholder: '예: 5000',
width: '120px',
align: 'right',
},
{
key: 'cost',
header: '비용',
type: 'text',
placeholder: '예: 50,000',
width: '120px',
align: 'right',
},
];
// ===== 정비내역 테이블 컬럼 =====
const maintenanceColumns: EditableColumn<ForkliftMaintenanceRecord>[] = [
{
key: 'date',
header: '정비일자',
type: 'text',
placeholder: 'YYYY-MM-DD',
width: '140px',
},
{
key: 'description',
header: '정비내역 기록',
type: 'text',
placeholder: '정비 내용 입력',
},
{
key: 'cost',
header: '비용',
type: 'text',
placeholder: '예: 150,000',
width: '120px',
align: 'right',
},
];
// ===== 새 행 생성 함수 =====
let partsRecordIdCounter = 0;
const createNewPartsRecord = (): PartsChangeRecord => ({
id: `parts-${Date.now()}-${++partsRecordIdCounter}`,
date: '',
mileage: '',
cost: '',
});
let maintenanceRecordIdCounter = 0;
const createNewMaintenanceRecord = (): ForkliftMaintenanceRecord => ({
id: `maint-${Date.now()}-${++maintenanceRecordIdCounter}`,
date: '',
description: '',
cost: '',
});
// ===== 필드 정의 (5130 스크린샷 순서대로) =====
export const forkliftFields: FieldDefinition[] = [
// Row 1: 지게차번호, 차종, 구매유형
{
key: 'vehicleNumber',
label: '지게차번호',
type: 'text',
required: true,
placeholder: '지게차번호 입력',
validation: [
{ type: 'required', message: '지게차번호를 입력해주세요.' },
],
},
{
key: 'vehicleType',
label: '차종',
type: 'text',
required: true,
placeholder: '예: 3톤 디젤',
validation: [
{ type: 'required', message: '차종을 입력해주세요.' },
],
},
{
key: 'purchaseType',
label: '구매유형',
type: 'select',
placeholder: '구매유형 선택',
options: [
{ label: '리스', value: '리스' },
{ label: '렌트', value: '렌트' },
{ label: '회사 소유', value: '회사 소유' },
],
},
// Row 2: 담당자(정), 담당자(부)
{
key: 'managerMain',
label: '담당자(정)',
type: 'text',
placeholder: '담당자(정) 입력',
},
{
key: 'managerSub',
label: '담당자(부)',
type: 'text',
placeholder: '담당자(부) 입력',
},
// Row 3: 구입업체, 구입업체 연락처
{
key: 'purchaseCompany',
label: '구입업체',
type: 'text',
placeholder: '구입업체명 입력',
},
{
key: 'purchaseCompanyContact',
label: '구입업체 연락처',
type: 'text',
placeholder: '예: 031-123-4567',
},
// Row 4: 총 주행거리, 기록일
{
key: 'totalMileage',
label: '총 주행거리 (km)',
type: 'text',
placeholder: 'km',
},
{
key: 'mileageRecordDate',
label: '기록일',
type: 'date',
placeholder: '연도.월.일.',
},
// Row 5: 최초등록일, 구매일자
{
key: 'firstRegistrationDate',
label: '최초등록일',
type: 'date',
placeholder: '연도.월.일.',
},
{
key: 'purchaseDate',
label: '구매일자',
type: 'date',
placeholder: '연도.월.일.',
},
// 부속품 교환주기, 부속품 교환 기록 테이블
{
key: 'partsChangeCycle',
label: '부속품 교환주기(Km)',
type: 'text',
placeholder: 'Km',
},
{
key: 'partsChangeRecords',
label: '부속품 교환일',
type: 'custom',
gridSpan: 2,
formatValue: (value: unknown) => {
const records = (value as PartsChangeRecord[]) || [];
if (records.length === 0) return '기록 없음';
return records.map((record, index) =>
`${index + 1}. ${record.date} / 주행거리: ${record.mileage}km / 비용: ${record.cost}`
).join('\n');
},
renderField: ({ value, onChange, mode }) => {
const records = (value as PartsChangeRecord[]) || [];
const isViewMode = mode === 'view';
if (isViewMode) {
if (records.length === 0) {
return <div className="text-muted-foreground"> </div>;
}
return (
<div className="space-y-1">
{records.map((record, index) => (
<div key={record.id} className="text-sm">
{index + 1}. {record.date} / : {record.mileage}km / : {record.cost}
</div>
))}
</div>
);
}
return (
<EditableTable
columns={partsChangeColumns}
data={records}
onChange={(newData) => onChange(newData)}
createNewRow={createNewPartsRecord}
addButtonLabel="부속품 교환일 추가"
emptyMessage="교환 기록이 없습니다. 기록을 추가해주세요."
showRowNumber={true}
compact={true}
/>
);
},
},
// 정비내역 테이블
{
key: 'maintenanceRecords',
label: '정비내역',
type: 'custom',
gridSpan: 2,
formatValue: (value: unknown) => {
const records = (value as ForkliftMaintenanceRecord[]) || [];
if (records.length === 0) return '기록 없음';
return records.map((record, index) =>
`${index + 1}. ${record.date}: ${record.description} (비용: ${record.cost}원)`
).join('\n');
},
renderField: ({ value, onChange, mode }) => {
const records = (value as ForkliftMaintenanceRecord[]) || [];
const isViewMode = mode === 'view';
if (isViewMode) {
if (records.length === 0) {
return <div className="text-muted-foreground"> </div>;
}
return (
<div className="space-y-1">
{records.map((record, index) => (
<div key={record.id} className="text-sm">
{index + 1}. {record.date}: {record.description} (: {record.cost})
</div>
))}
</div>
);
}
return (
<EditableTable
columns={maintenanceColumns}
data={records}
onChange={(newData) => onChange(newData)}
createNewRow={createNewMaintenanceRecord}
addButtonLabel="정비내역 추가"
emptyMessage="정비 기록이 없습니다. 기록을 추가해주세요."
showRowNumber={true}
compact={true}
/>
);
},
},
// 비고
{
key: 'remarks',
label: '비고',
type: 'textarea',
placeholder: '비고 입력',
gridSpan: 2,
},
];
// ===== 섹션 정의 (5130 스크린샷 순서대로) =====
export const forkliftSections: SectionDefinition[] = [
{
id: 'basicInfo',
title: '기본 정보',
description: '지게차의 기본 정보를 입력하세요',
fields: ['vehicleNumber', 'vehicleType', 'purchaseType'],
},
{
id: 'managerInfo',
title: '담당자 정보',
description: '담당자 정보를 입력하세요',
fields: ['managerMain', 'managerSub'],
},
{
id: 'purchaseCompanyInfo',
title: '구입업체 정보',
description: '구입업체 관련 정보를 입력하세요',
fields: ['purchaseCompany', 'purchaseCompanyContact'],
},
{
id: 'mileageInfo',
title: '주행거리 정보',
description: '주행거리 관련 정보를 입력하세요',
fields: ['totalMileage', 'mileageRecordDate'],
},
{
id: 'purchaseInfo',
title: '등록/구매 정보',
description: '등록 및 구매 관련 정보를 입력하세요',
fields: ['firstRegistrationDate', 'purchaseDate'],
},
{
id: 'partsInfo',
title: '부속품 교환',
description: '부속품 교환 관련 정보를 입력하세요',
fields: ['partsChangeCycle', 'partsChangeRecords'],
},
{
id: 'maintenanceSection',
title: '정비내역',
description: '정비 관련 정보를 입력하세요',
fields: ['maintenanceRecords'],
},
{
id: 'remarksSection',
title: '비고',
description: '기타 정보를 입력하세요',
fields: ['remarks'],
},
];
// ===== 설정 =====
export const forkliftDetailConfig: DetailConfig<Forklift> = {
title: '지게차',
description: '지게차 정보를 관리합니다',
icon: Truck,
basePath: '/ko/vehicle-management/forklift',
fields: forkliftFields,
sections: forkliftSections,
gridColumns: 2,
actions: {
submitLabel: '저장',
cancelLabel: '취소',
showDelete: true,
deleteLabel: '삭제',
showEdit: true,
editLabel: '수정',
showBack: true,
backLabel: '목록',
deleteConfirmMessage: {
title: '지게차 삭제',
description: '이 지게차를 삭제하시겠습니까? 삭제된 데이터는 복구할 수 없습니다.',
},
},
transformInitialData: (data: Forklift) => ({
vehicleNumber: data.vehicleNumber || '',
vehicleType: data.vehicleType || '',
purchaseType: data.purchaseType || '',
managerMain: data.managerMain || '',
managerSub: data.managerSub || '',
purchaseCompany: data.purchaseCompany || '',
purchaseCompanyContact: data.purchaseCompanyContact || '',
totalMileage: data.totalMileage || '',
mileageRecordDate: data.mileageRecordDate || '',
firstRegistrationDate: data.firstRegistrationDate || '',
purchaseDate: data.purchaseDate || '',
partsChangeCycle: data.partsChangeCycle || '',
partsChangeRecords: data.partsChangeRecords || [],
maintenanceRecords: data.maintenanceRecords || [],
remarks: data.remarks || '',
}),
transformSubmitData: (formData): Partial<ForkliftFormData> => ({
vehicleNumber: formData.vehicleNumber as string,
vehicleType: formData.vehicleType as string,
purchaseType: formData.purchaseType as string,
managerMain: formData.managerMain as string,
managerSub: formData.managerSub as string,
purchaseCompany: formData.purchaseCompany as string,
purchaseCompanyContact: formData.purchaseCompanyContact as string,
totalMileage: formData.totalMileage as string,
mileageRecordDate: formData.mileageRecordDate as string,
firstRegistrationDate: formData.firstRegistrationDate as string,
purchaseDate: formData.purchaseDate as string,
partsChangeCycle: formData.partsChangeCycle as string,
partsChangeRecords: formData.partsChangeRecords as PartsChangeRecord[],
maintenanceRecords: formData.maintenanceRecords as ForkliftMaintenanceRecord[],
remarks: formData.remarks as string,
}),
};
// ===== 등록 페이지 Config =====
export const forkliftCreateConfig: DetailConfig = {
title: '지게차',
description: '지게차 정보를 입력하세요',
icon: Truck,
basePath: '/vehicle-management/forklift',
fields: forkliftFields,
sections: forkliftSections,
gridColumns: 2,
actions: {
showBack: true,
showSave: true,
submitLabel: '저장',
backLabel: '닫기',
},
};
// ===== 수정 페이지 Config =====
export const forkliftEditConfig: DetailConfig = {
title: '지게차',
description: '지게차 정보를 수정합니다',
icon: Truck,
basePath: '/vehicle-management/forklift',
fields: forkliftFields,
sections: forkliftSections,
gridColumns: 2,
actions: {
showBack: true,
showSave: true,
submitLabel: '저장',
backLabel: '닫기',
},
};