'use client'; /** * 단계 상세 클라이언트 컴포넌트 * * 라우팅: * - /[id]/steps/[stepId] → 상세 보기 * - /[id]/steps/[stepId]?mode=edit → 수정 * - /[id]/steps/new → 등록 */ import { useState, useEffect } from 'react'; import { useSearchParams } from 'next/navigation'; import { StepDetail } from './StepDetail'; import { StepForm } from './StepForm'; import { getProcessStepById } from './actions'; import type { ProcessStep } from '@/types/process'; import { DetailPageSkeleton } from '@/components/ui/skeleton'; import { ErrorCard } from '@/components/ui/error-card'; import { toast } from 'sonner'; type DetailMode = 'view' | 'edit' | 'create'; interface StepDetailClientProps { processId: string; stepId: string; } export function StepDetailClient({ processId, stepId }: StepDetailClientProps) { const searchParams = useSearchParams(); const modeFromQuery = searchParams.get('mode') as DetailMode | null; const isNewMode = stepId === 'new'; const [mode] = useState(() => { if (isNewMode) return 'create'; if (modeFromQuery === 'edit') return 'edit'; return 'view'; }); const [stepData, setStepData] = useState(null); const [isLoading, setIsLoading] = useState(!isNewMode); const [error, setError] = useState(null); useEffect(() => { if (isNewMode) { setIsLoading(false); return; } const loadData = async () => { setIsLoading(true); setError(null); try { const result = await getProcessStepById(processId, stepId); if (result.success && result.data) { setStepData(result.data); } else { setError(result.error || '단계 정보를 찾을 수 없습니다.'); toast.error('단계를 불러오는데 실패했습니다.'); } } catch (err) { console.error('단계 조회 실패:', err); setError('단계 정보를 불러오는 중 오류가 발생했습니다.'); toast.error('단계를 불러오는데 실패했습니다.'); } finally { setIsLoading(false); } }; loadData(); }, [processId, stepId, isNewMode]); if (isLoading) { return ; } if (error && !isNewMode) { return ( ); } if (mode === 'create') { return ; } if (mode === 'edit' && stepData) { return ; } if (mode === 'view' && stepData) { return ; } return ( ); }