'use client' import { useState, useEffect } from 'react'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { toast } from 'sonner'; import { Loader2, List, Eye, RefreshCw, AlertCircle } from 'lucide-react'; // API 함수 및 타입 import { getSubmissionList, getApprovalHistory } from '@/lib/knox-api/approval/approval'; import type { SubmissionListResponse, ApprovalHistoryResponse } from '@/lib/knox-api/approval/approval'; import { formatDate } from '@/lib/utils'; // 상태 텍스트 매핑 (mock util 대체) const getStatusText = (status: string) => { const map: Record = { '-3': '암호화실패', '-2': '암호화중', '-1': '예약상신', '0': '보류', '1': '진행중', '2': '완결', '3': '반려', '4': '상신취소', '5': '전결', '6': '후완결', }; return map[status] || '알 수 없음'; }; interface ApprovalListProps { type?: 'submission' | 'history'; onItemClick?: (apInfId: string) => void; } type ListItem = { apInfId: string; subject: string; sbmDt: string; status: string; urgYn?: string; docSecuType?: string; actionType?: string; actionDt?: string; userId?: string; }; export default function ApprovalList({ type = 'submission', onItemClick }: ApprovalListProps) { const [listData, setListData] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const fetchData = async () => { setIsLoading(true); setError(null); try { let response: SubmissionListResponse | ApprovalHistoryResponse; if (type === 'submission') { response = await getSubmissionList(); } else { response = await getApprovalHistory(); } if (response.result === 'success') { setListData(response.data as unknown as ListItem[]); } else { setError('목록을 가져오는데 실패했습니다.'); toast.error('목록을 가져오는데 실패했습니다.'); } } catch (err) { console.error('목록 조회 오류:', err); setError('목록을 가져오는 중 오류가 발생했습니다.'); toast.error('목록을 가져오는 중 오류가 발생했습니다.'); } finally { setIsLoading(false); } }; const getStatusBadgeVariant = (status: string) => { switch (status) { case '2': // 완결 return 'default'; case '1': // 진행중 return 'secondary'; case '3': // 반려 return 'destructive'; case '4': // 상신취소 return 'outline'; default: return 'outline'; } }; const getSecurityTypeText = (type: string) => { const typeMap: Record = { 'PERSONAL': '개인', 'CONFIDENTIAL': '기밀', 'CONFIDENTIAL_STRICT': '극기밀' }; return typeMap[type] || type; }; const getSecurityTypeBadgeVariant = (type: string) => { switch (type) { case 'PERSONAL': return 'default'; case 'CONFIDENTIAL': return 'secondary'; case 'CONFIDENTIAL_STRICT': return 'destructive'; default: return 'outline'; } }; const getActionTypeText = (actionType: string) => { const actionMap: Record = { 'SUBMIT': '상신', 'APPROVE': '승인', 'REJECT': '반려', 'CANCEL': '취소', 'DELEGATE': '위임' }; return actionMap[actionType] || actionType; }; const handleItemClick = (apInfId: string) => { onItemClick?.(apInfId); }; // 컴포넌트 마운트 시 데이터 로드 useEffect(() => { fetchData(); }, [type]); return ( {type === 'submission' ? '상신함' : '결재 이력'} {type === 'submission' ? '상신한 결재 목록을 확인합니다.' : '결재 처리 이력을 확인합니다.' } {/* 새로고침 버튼 */}
총 {listData.length}건
{/* 에러 메시지 */} {error && (
오류

{error}

)} {/* 목록 테이블 */}
결재 ID 제목 상신일시 상태 {type === 'submission' && ( <> 긴급 보안등급 )} {type === 'history' && ( <> 처리일시 처리자 처리유형 )} 작업 {listData.length === 0 ? ( {isLoading ? '데이터를 불러오는 중...' : '데이터가 없습니다.'} ) : ( listData.map((item) => ( {item.apInfId} {item.subject} {formatDate(item.sbmDt, "kr")} {getStatusText(item.status)} {type === 'submission' && ( <> {item.urgYn === 'Y' ? ( 긴급 ) : ( 일반 )} {getSecurityTypeText(item.docSecuType || 'PERSONAL')} )} {type === 'history' && ( <> {item.actionDt ? formatDate(item.actionDt, "kr") : '-'} {item.userId || '-'} {item.actionType ? ( {getActionTypeText(item.actionType)} ) : '-'} )} )) )}
{/* 페이지네이션 영역 (향후 구현 예정) */} {listData.length > 0 && (
페이지네이션 기능은 향후 구현 예정입니다.
)}
); }