123 lines
3.5 KiB
TypeScript
123 lines
3.5 KiB
TypeScript
|
|
'use client';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 점검표 상세 클라이언트 컴포넌트
|
||
|
|
*
|
||
|
|
* 라우팅:
|
||
|
|
* - /[id] → 상세 보기 (view)
|
||
|
|
* - /[id]?mode=edit → 수정 (edit)
|
||
|
|
* - ?mode=new → 등록 (create)
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { useState, useEffect } from 'react';
|
||
|
|
import { useSearchParams } from 'next/navigation';
|
||
|
|
import { ChecklistDetail } from './ChecklistDetail';
|
||
|
|
import { ChecklistForm } from './ChecklistForm';
|
||
|
|
import { getChecklistById } from './actions';
|
||
|
|
import type { Checklist } from '@/types/checklist';
|
||
|
|
import { DetailPageSkeleton } from '@/components/ui/skeleton';
|
||
|
|
import { ErrorCard } from '@/components/ui/error-card';
|
||
|
|
import { toast } from 'sonner';
|
||
|
|
|
||
|
|
type DetailMode = 'view' | 'edit' | 'create';
|
||
|
|
|
||
|
|
interface ChecklistDetailClientProps {
|
||
|
|
checklistId?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
const BASE_PATH = '/ko/master-data/checklist-management';
|
||
|
|
|
||
|
|
export function ChecklistDetailClient({ checklistId }: ChecklistDetailClientProps) {
|
||
|
|
const searchParams = useSearchParams();
|
||
|
|
const modeFromQuery = searchParams.get('mode') as DetailMode | null;
|
||
|
|
const isNewMode = !checklistId || checklistId === 'new';
|
||
|
|
|
||
|
|
const [mode, setMode] = useState<DetailMode>(() => {
|
||
|
|
if (isNewMode) return 'create';
|
||
|
|
if (modeFromQuery === 'edit') return 'edit';
|
||
|
|
return 'view';
|
||
|
|
});
|
||
|
|
|
||
|
|
const [checklistData, setChecklistData] = useState<Checklist | null>(null);
|
||
|
|
const [isLoading, setIsLoading] = useState(!isNewMode);
|
||
|
|
const [error, setError] = useState<string | null>(null);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
if (isNewMode) {
|
||
|
|
setIsLoading(false);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const loadData = async () => {
|
||
|
|
setIsLoading(true);
|
||
|
|
setError(null);
|
||
|
|
try {
|
||
|
|
const result = await getChecklistById(checklistId!);
|
||
|
|
if (result.success && result.data) {
|
||
|
|
setChecklistData(result.data);
|
||
|
|
} else {
|
||
|
|
setError(result.error || '점검표 정보를 찾을 수 없습니다.');
|
||
|
|
toast.error('점검표를 불러오는데 실패했습니다.');
|
||
|
|
}
|
||
|
|
} catch {
|
||
|
|
setError('점검표 정보를 불러오는 중 오류가 발생했습니다.');
|
||
|
|
toast.error('점검표를 불러오는데 실패했습니다.');
|
||
|
|
} finally {
|
||
|
|
setIsLoading(false);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
loadData();
|
||
|
|
}, [checklistId, isNewMode]);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
if (!isNewMode && modeFromQuery === 'edit') {
|
||
|
|
setMode('edit');
|
||
|
|
} else if (!isNewMode && !modeFromQuery) {
|
||
|
|
setMode('view');
|
||
|
|
}
|
||
|
|
}, [modeFromQuery, isNewMode]);
|
||
|
|
|
||
|
|
if (isLoading) {
|
||
|
|
return <DetailPageSkeleton sections={1} fieldsPerSection={3} />;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (error && !isNewMode) {
|
||
|
|
return (
|
||
|
|
<ErrorCard
|
||
|
|
type="network"
|
||
|
|
title="점검표 정보를 불러올 수 없습니다"
|
||
|
|
description={error}
|
||
|
|
tips={[
|
||
|
|
'해당 점검표가 존재하는지 확인해주세요',
|
||
|
|
'인터넷 연결 상태를 확인해주세요',
|
||
|
|
]}
|
||
|
|
homeButtonLabel="목록으로 이동"
|
||
|
|
homeButtonHref={BASE_PATH}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mode === 'create') {
|
||
|
|
return <ChecklistForm mode="create" />;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mode === 'edit' && checklistData) {
|
||
|
|
return <ChecklistForm mode="edit" initialData={checklistData} />;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mode === 'view' && checklistData) {
|
||
|
|
return <ChecklistDetail checklist={checklistData} />;
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<ErrorCard
|
||
|
|
type="not-found"
|
||
|
|
title="점검표를 찾을 수 없습니다"
|
||
|
|
description="요청하신 점검표 정보가 존재하지 않습니다."
|
||
|
|
homeButtonLabel="목록으로 이동"
|
||
|
|
homeButtonHref={BASE_PATH}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
}
|