'use client'; /** * 게시판관리 상세 클라이언트 컴포넌트 V2 * * 라우팅 구조 변경: /[id], /[id]/edit, /new → /[id]?mode=view|edit, /new * 기존 BoardDetail, BoardForm 컴포넌트 활용 */ import { useState, useEffect, useCallback } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { Loader2 } from 'lucide-react'; import { BoardDetail } from './BoardDetail'; import { BoardForm } from './BoardForm'; import { getBoardById, createBoard, updateBoard, deleteBoard } from './actions'; import { forceRefreshMenus } from '@/lib/utils/menuRefresh'; import type { Board, BoardFormData } from './types'; import { DetailPageSkeleton } from '@/components/ui/skeleton'; import { ErrorCard } from '@/components/ui/error-card'; import { Button } from '@/components/ui/button'; import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog'; import { toast } from 'sonner'; type DetailMode = 'view' | 'edit' | 'create'; interface BoardDetailClientV2Props { boardId?: string; initialMode?: DetailMode; } const BASE_PATH = '/ko/board/board-management'; // 게시판 코드 생성 (타임스탬프 기반) const generateBoardCode = (): string => { const timestamp = Date.now().toString(36); const random = Math.random().toString(36).substring(2, 6); return `board_${timestamp}_${random}`; }; export function BoardDetailClientV2({ boardId, initialMode }: BoardDetailClientV2Props) { const router = useRouter(); const searchParams = useSearchParams(); // URL 쿼리에서 모드 결정 const modeFromQuery = searchParams.get('mode') as DetailMode | null; const isNewMode = !boardId || boardId === 'new'; const [mode, setMode] = useState(() => { if (isNewMode) return 'create'; if (initialMode) return initialMode; if (modeFromQuery === 'edit') return 'edit'; return 'view'; }); const [boardData, setBoardData] = useState(null); const [isLoading, setIsLoading] = useState(!isNewMode); const [error, setError] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [isDeleting, setIsDeleting] = useState(false); // 데이터 로드 useEffect(() => { const loadData = async () => { if (isNewMode) { setIsLoading(false); return; } setIsLoading(true); setError(null); try { const result = await getBoardById(boardId!); if (result.success && result.data) { setBoardData(result.data); } else { setError(result.error || '게시판 정보를 찾을 수 없습니다.'); toast.error('게시판을 불러오는데 실패했습니다.'); } } catch (err) { console.error('게시판 조회 실패:', err); setError('게시판 정보를 불러오는 중 오류가 발생했습니다.'); toast.error('게시판을 불러오는데 실패했습니다.'); } finally { setIsLoading(false); } }; loadData(); }, [boardId, isNewMode]); // URL 쿼리 변경 감지 useEffect(() => { if (!isNewMode && modeFromQuery === 'edit') { setMode('edit'); } else if (!isNewMode && !modeFromQuery) { setMode('view'); } }, [modeFromQuery, isNewMode]); // 등록 핸들러 const handleCreate = async (data: BoardFormData) => { setIsSubmitting(true); setError(null); try { const result = await createBoard({ ...data, boardCode: generateBoardCode(), }); if (result.success && result.data) { await forceRefreshMenus(); toast.success('게시판이 등록되었습니다.'); router.push(BASE_PATH); } else { setError(result.error || '게시판 등록에 실패했습니다.'); toast.error(result.error || '게시판 등록에 실패했습니다.'); } } catch (err) { console.error('게시판 등록 실패:', err); setError('게시판 등록 중 오류가 발생했습니다.'); toast.error('게시판 등록 중 오류가 발생했습니다.'); } finally { setIsSubmitting(false); } }; // 수정 핸들러 const handleUpdate = async (data: BoardFormData) => { if (!boardData) return; setIsSubmitting(true); setError(null); try { const result = await updateBoard(boardData.id, { ...data, boardCode: boardData.boardCode, description: boardData.description, }); if (result.success) { await forceRefreshMenus(); toast.success('게시판이 수정되었습니다.'); router.push(`${BASE_PATH}/${boardData.id}`); } else { setError(result.error || '게시판 수정에 실패했습니다.'); toast.error(result.error || '게시판 수정에 실패했습니다.'); } } catch (err) { console.error('게시판 수정 실패:', err); setError('게시판 수정 중 오류가 발생했습니다.'); toast.error('게시판 수정 중 오류가 발생했습니다.'); } finally { setIsSubmitting(false); } }; // 삭제 핸들러 const handleDelete = () => { setDeleteDialogOpen(true); }; const confirmDelete = async () => { if (!boardData) return; setIsDeleting(true); try { const result = await deleteBoard(boardData.id); if (result.success) { await forceRefreshMenus(); toast.success('게시판이 삭제되었습니다.'); router.push(BASE_PATH); } else { setError(result.error || '삭제에 실패했습니다.'); toast.error(result.error || '삭제에 실패했습니다.'); setDeleteDialogOpen(false); } } catch (err) { console.error('게시판 삭제 실패:', err); setError('게시판 삭제 중 오류가 발생했습니다.'); toast.error('게시판 삭제 중 오류가 발생했습니다.'); setDeleteDialogOpen(false); } finally { setIsDeleting(false); } }; // 수정 모드 전환 const handleEdit = () => { router.push(`${BASE_PATH}/${boardId}?mode=edit`); }; // 로딩 중 if (isLoading) { return ; } // 에러 발생 (view/edit 모드에서) if (error && !isNewMode) { return ( ); } // 등록 모드 if (mode === 'create') { return ( <> {error && (

{error}

)} {isSubmitting && (
등록 중...
)} ); } // 수정 모드 if (mode === 'edit' && boardData) { return ( <> {error && (

{error}

)} {isSubmitting && (
저장 중...
)} ); } // 상세 보기 모드 if (mode === 'view' && boardData) { return ( <> "{boardData.boardName}" 게시판을 삭제하시겠습니까?
삭제된 게시판 정보는 복구할 수 없습니다. } loading={isDeleting} /> ); } // 데이터 없음 (should not reach here) return ( ); }