'use client'; /** * 단계 등록/수정 폼 컴포넌트 * * 기획서 스크린샷 2 기준: * - 기본 정보: 단계코드(자동), 단계명, 필수여부, 승인여부, 검사여부, 상태 * - 연결 정보: 유형(팝업/없음), 도달(Select) * - 완료 정보: 유형(선택 완료 시 완료/클릭 시 완료) */ import { useState, useCallback } from 'react'; import { useRouter } from 'next/navigation'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Button } from '@/components/ui/button'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate'; import { toast } from 'sonner'; import { Settings, Eye } from 'lucide-react'; import type { ProcessStep, StepConnectionType, StepCompletionType, InspectionSetting, } from '@/types/process'; import { STEP_CONNECTION_TYPE_OPTIONS, STEP_COMPLETION_TYPE_OPTIONS, STEP_CONNECTION_TARGET_OPTIONS, DEFAULT_INSPECTION_SETTING, } from '@/types/process'; import { createProcessStep, updateProcessStep } from './actions'; import type { DetailConfig } from '@/components/templates/IntegratedDetailTemplate/types'; import { InspectionSettingModal } from './InspectionSettingModal'; import { InspectionPreviewModal } from './InspectionPreviewModal'; const stepCreateConfig: DetailConfig = { title: '단계', description: '새로운 단계를 등록합니다', basePath: '', fields: [], actions: { showBack: true, showEdit: false, showDelete: false, showSave: true, submitLabel: '등록', }, }; const stepEditConfig: DetailConfig = { ...stepCreateConfig, title: '단계', description: '단계 정보를 수정합니다', actions: { ...stepCreateConfig.actions, submitLabel: '저장', }, }; interface StepFormProps { mode: 'create' | 'edit'; processId: string; initialData?: ProcessStep; } export function StepForm({ mode, processId, initialData }: StepFormProps) { const router = useRouter(); const isEdit = mode === 'edit'; // 기본 정보 const [stepName, setStepName] = useState(initialData?.stepName || ''); const [isRequired, setIsRequired] = useState( initialData?.isRequired ? '필수' : '선택' ); const [needsApproval, setNeedsApproval] = useState( initialData?.needsApproval ? '필요' : '불필요' ); const [needsInspection, setNeedsInspection] = useState( initialData?.needsInspection ? '필요' : '불필요' ); const [isActive, setIsActive] = useState( initialData?.isActive !== false ? '사용' : '미사용' ); // 연결 정보 const [connectionType, setConnectionType] = useState( initialData?.connectionType || '없음' ); const [connectionTarget, setConnectionTarget] = useState( initialData?.connectionTarget || '' ); // 완료 정보 const [completionType, setCompletionType] = useState( initialData?.completionType || '클릭 시 완료' ); // 검사 설정 const [inspectionSetting, setInspectionSetting] = useState( initialData?.inspectionSetting || DEFAULT_INSPECTION_SETTING ); // 모달 상태 const [isInspectionSettingOpen, setIsInspectionSettingOpen] = useState(false); const [isInspectionPreviewOpen, setIsInspectionPreviewOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); // 검사여부가 "필요"인지 확인 const isInspectionEnabled = needsInspection === '필요'; // 제출 const handleSubmit = async (): Promise<{ success: boolean; error?: string }> => { if (!stepName.trim()) { toast.error('단계명을 입력해주세요.'); return { success: false, error: '단계명을 입력해주세요.' }; } const stepData: Omit = { stepCode: initialData?.stepCode || `STP-${Date.now().toString().slice(-6)}`, stepName: stepName.trim(), isRequired: isRequired === '필수', needsApproval: needsApproval === '필요', needsInspection: needsInspection === '필요', isActive: isActive === '사용', order: initialData?.order || 0, connectionType, connectionTarget: connectionType === '팝업' ? connectionTarget : undefined, completionType, inspectionSetting: isInspectionEnabled ? inspectionSetting : undefined, }; setIsLoading(true); try { if (isEdit && initialData?.id) { const result = await updateProcessStep(processId, initialData.id, stepData); if (result.success) { toast.success('단계가 수정되었습니다.'); router.push(`/ko/master-data/process-management/${processId}`); return { success: true }; } else { toast.error(result.error || '수정에 실패했습니다.'); return { success: false, error: result.error }; } } else { const result = await createProcessStep(processId, stepData); if (result.success) { toast.success('단계가 등록되었습니다.'); router.push(`/ko/master-data/process-management/${processId}`); return { success: true }; } else { toast.error(result.error || '등록에 실패했습니다.'); return { success: false, error: result.error }; } } } catch { toast.error('처리 중 오류가 발생했습니다.'); return { success: false, error: '처리 중 오류가 발생했습니다.' }; } finally { setIsLoading(false); } }; const handleCancel = () => { router.push(`/ko/master-data/process-management/${processId}`); }; const renderFormContent = useCallback( () => (
{/* 기본 정보 */} 기본 정보
setStepName(e.target.value)} placeholder="예: 자재투입" />
{/* 연결 정보 */} 연결 정보
{/* 검사여부가 "필요"일 때 버튼 표시 */} {isInspectionEnabled && ( <> )}
{/* 완료 정보 */} 완료 정보
), [ stepName, isRequired, needsApproval, needsInspection, isActive, connectionType, connectionTarget, completionType, initialData?.stepCode, isInspectionEnabled, ] ); const config = isEdit ? stepEditConfig : stepCreateConfig; return ( <> {/* 검사 설정 모달 */} {/* 검사 미리보기 모달 */} ); }