'use client'; import { useState, useCallback, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { toast } from 'sonner'; import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate'; import type { DetailMode } from '@/components/templates/IntegratedDetailTemplate/types'; import { depositDetailConfig } from './depositDetailConfig'; import type { DepositRecord } from './types'; import { getDepositById, createDeposit, updateDeposit, deleteDeposit, getVendors, getBankAccounts, } from './actions'; import { useDevFill, generateDepositData } from '@/components/dev'; // ===== Props ===== interface DepositDetailClientV2Props { depositId?: string; initialMode?: DetailMode; } export default function DepositDetailClientV2({ depositId, initialMode = 'view', }: DepositDetailClientV2Props) { const router = useRouter(); const [mode, setMode] = useState(initialMode); const [deposit, setDeposit] = useState(null); const [isLoading, setIsLoading] = useState(initialMode !== 'create'); // ===== DevFill: 자동 입력 기능 ===== useDevFill('deposit', useCallback(async () => { if (initialMode === 'create') { // 거래처 및 계좌 목록 가져오기 const [vendorResult, bankAccountResult] = await Promise.all([ getVendors(), getBankAccounts(), ]); const vendors = vendorResult.success ? vendorResult.data : undefined; const bankAccounts = bankAccountResult.success ? bankAccountResult.data : undefined; const mockData = generateDepositData({ vendors, bankAccounts }); setDeposit(mockData as unknown as DepositRecord); toast.success('입금 데이터가 자동 입력되었습니다.'); } }, [initialMode])); // ===== 데이터 로드 ===== useEffect(() => { const loadDeposit = async () => { if (depositId && initialMode !== 'create') { setIsLoading(true); const result = await getDepositById(depositId); if (result.success && result.data) { setDeposit(result.data); } else { toast.error(result.error || '입금 내역을 불러오는데 실패했습니다.'); } setIsLoading(false); } }; loadDeposit(); }, [depositId, initialMode]); // ===== 저장/등록 핸들러 ===== const handleSubmit = useCallback( async (formData: Record): Promise<{ success: boolean; error?: string }> => { const submitData = depositDetailConfig.transformSubmitData?.(formData) || formData; if (!submitData.vendorId) { toast.error('거래처를 선택해주세요.'); return { success: false, error: '거래처를 선택해주세요.' }; } const result = mode === 'create' ? await createDeposit(submitData as Partial) : await updateDeposit(depositId!, submitData as Partial); if (result.success) { toast.success(mode === 'create' ? '입금 내역이 등록되었습니다.' : '입금 내역이 수정되었습니다.'); router.push('/ko/accounting/deposits'); return { success: true }; } else { toast.error(result.error || '저장에 실패했습니다.'); return { success: false, error: result.error }; } }, [mode, depositId, router] ); // ===== 삭제 핸들러 ===== const handleDelete = useCallback(async (): Promise<{ success: boolean; error?: string }> => { if (!depositId) return { success: false, error: 'ID가 없습니다.' }; const result = await deleteDeposit(depositId); if (result.success) { toast.success('입금 내역이 삭제되었습니다.'); router.push('/ko/accounting/deposits'); return { success: true }; } else { toast.error(result.error || '삭제에 실패했습니다.'); return { success: false, error: result.error }; } }, [depositId, router]); // ===== 모드 변경 핸들러 ===== const handleModeChange = useCallback( (newMode: DetailMode) => { if (newMode === 'edit' && depositId) { router.push(`/ko/accounting/deposits/${depositId}?mode=edit`); } else { setMode(newMode); } }, [depositId, router] ); // 타이틀 동적 설정 // IntegratedDetailTemplate: create → "{title} 등록", view → "{title}", edit → "{title} 수정" // view 모드에서 "입금 상세"로 표시하려면 직접 설정 필요 const dynamicConfig = { ...depositDetailConfig, title: mode === 'view' ? '입금 상세' : '입금', }; return ( [0]['config']} mode={mode} initialData={deposit as unknown as Record | undefined} itemId={depositId} isLoading={isLoading} onSubmit={handleSubmit} onDelete={handleDelete} onModeChange={handleModeChange} buttonPosition="top" /> ); }