- 등록(?mode=new), 상세(?mode=view), 수정(?mode=edit) URL 패턴 일괄 적용
- 중복 패턴 제거: /edit?mode=edit → ?mode=edit (16개 파일)
- 제목 일관성: {기능} 등록/상세/수정 패턴 적용
- 검수 체크리스트 문서 추가 (79개 페이지)
- UniversalListPage, IntegratedDetailTemplate 공통 컴포넌트 개선
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
116 lines
4.0 KiB
TypeScript
116 lines
4.0 KiB
TypeScript
'use client';
|
|
|
|
import { useRouter } from 'next/navigation';
|
|
import { PageLayout } from '@/components/organisms/PageLayout';
|
|
import { PageHeader } from '@/components/organisms/PageHeader';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { ClipboardList, ArrowLeft, Edit, Trash2 } from 'lucide-react';
|
|
import type { Board } from './types';
|
|
import {
|
|
BOARD_STATUS_LABELS,
|
|
BOARD_STATUS_COLORS,
|
|
BOARD_TARGET_LABELS,
|
|
} from './types';
|
|
|
|
interface BoardDetailProps {
|
|
board: Board;
|
|
onEdit: () => void;
|
|
onDelete: () => void;
|
|
}
|
|
|
|
// 날짜/시간 포맷
|
|
const formatDateTime = (dateString: string): string => {
|
|
const date = new Date(dateString);
|
|
const year = date.getFullYear();
|
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
const day = String(date.getDate()).padStart(2, '0');
|
|
const hours = String(date.getHours()).padStart(2, '0');
|
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
};
|
|
|
|
export function BoardDetail({ board, onEdit, onDelete }: BoardDetailProps) {
|
|
const router = useRouter();
|
|
|
|
const handleBack = () => {
|
|
router.push('/ko/board/board-management');
|
|
};
|
|
|
|
// 대상 표시 텍스트
|
|
const getTargetDisplay = () => {
|
|
if (board.target === 'all') {
|
|
return BOARD_TARGET_LABELS.all;
|
|
}
|
|
return board.targetName || BOARD_TARGET_LABELS.department;
|
|
};
|
|
|
|
return (
|
|
<PageLayout>
|
|
<PageHeader
|
|
title="게시판 상세"
|
|
description="게시판 정보를 조회합니다"
|
|
icon={ClipboardList}
|
|
/>
|
|
|
|
<div className="space-y-6">
|
|
{/* 게시판 정보 */}
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between">
|
|
<CardTitle className="text-base">게시판 정보</CardTitle>
|
|
<Badge className={BOARD_STATUS_COLORS[board.status]}>
|
|
{BOARD_STATUS_LABELS[board.status]}
|
|
</Badge>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<dl className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<dt className="text-sm font-medium text-muted-foreground">대상</dt>
|
|
<dd className="text-sm mt-1">{getTargetDisplay()}</dd>
|
|
</div>
|
|
<div>
|
|
<dt className="text-sm font-medium text-muted-foreground">작성자</dt>
|
|
<dd className="text-sm mt-1">{board.authorName}</dd>
|
|
</div>
|
|
<div>
|
|
<dt className="text-sm font-medium text-muted-foreground">게시판명</dt>
|
|
<dd className="text-sm mt-1">{board.boardName}</dd>
|
|
</div>
|
|
<div>
|
|
<dt className="text-sm font-medium text-muted-foreground">상태</dt>
|
|
<dd className="text-sm mt-1">
|
|
<Badge className={BOARD_STATUS_COLORS[board.status]}>
|
|
{BOARD_STATUS_LABELS[board.status]}
|
|
</Badge>
|
|
</dd>
|
|
</div>
|
|
<div>
|
|
<dt className="text-sm font-medium text-muted-foreground">등록일시</dt>
|
|
<dd className="text-sm mt-1">{formatDateTime(board.createdAt)}</dd>
|
|
</div>
|
|
</dl>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* 버튼 영역 */}
|
|
<div className="flex items-center justify-between">
|
|
<Button variant="outline" onClick={handleBack}>
|
|
<ArrowLeft className="w-4 h-4 mr-2" />
|
|
목록으로
|
|
</Button>
|
|
<div className="flex items-center gap-2">
|
|
<Button variant="outline" onClick={onDelete} className="text-destructive hover:bg-destructive hover:text-destructive-foreground">
|
|
<Trash2 className="w-4 h-4 mr-2" />
|
|
삭제
|
|
</Button>
|
|
<Button onClick={onEdit}>
|
|
<Edit className="w-4 h-4 mr-2" />
|
|
수정
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</PageLayout>
|
|
);
|
|
} |