const { useState, useEffect } = React; function Kuntae() { // 상태 관리 const [kuntaeData, setKuntaeData] = useState([]); const [isLoading, setIsLoading] = useState(false); const [filters, setFilters] = useState({ startDate: '', endDate: '' }); // 통계 데이터 const [statistics, setStatistics] = useState({ totalDays: 0, approvedDays: 0, pendingDays: 0, rejectedDays: 0 }); // 컴포넌트 마운트시 초기화 useEffect(() => { initializeFilters(); }, []); // 초기 필터 설정 (이번 달) const initializeFilters = () => { const now = new Date(); const firstDay = new Date(now.getFullYear(), now.getMonth(), 1); const lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0); setFilters({ startDate: firstDay.toISOString().split('T')[0], endDate: lastDay.toISOString().split('T')[0] }); // 초기 데이터 로드 loadKuntaeData({ startDate: firstDay.toISOString().split('T')[0], endDate: lastDay.toISOString().split('T')[0] }); }; // 근태 데이터 로드 const loadKuntaeData = async (searchFilters = filters) => { setIsLoading(true); try { let url = '/Kuntae/GetData'; const params = new URLSearchParams(); if (searchFilters.startDate) params.append('startDate', searchFilters.startDate); if (searchFilters.endDate) params.append('endDate', searchFilters.endDate); if (params.toString()) { url += '?' + params.toString(); } const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP ${response.status}: 데이터를 불러오는데 실패했습니다.`); } const responseData = await response.json(); if (Array.isArray(responseData)) { setKuntaeData(responseData); updateStatistics(responseData); } else if (responseData.error) { throw new Error(responseData.error); } else { setKuntaeData([]); updateStatistics([]); } } catch (error) { console.error('Error loading kuntae data:', error); setKuntaeData([]); updateStatistics([]); showNotification('데이터를 불러오는데 실패했습니다: ' + error.message, 'error'); } finally { setIsLoading(false); } }; // 통계 업데이트 const updateStatistics = (data) => { const totalDays = data.length; const approvedDays = data.filter(item => item.status === '승인').length; const pendingDays = data.filter(item => item.status === '대기').length; const rejectedDays = data.filter(item => item.status === '반려').length; setStatistics({ totalDays, approvedDays, pendingDays, rejectedDays }); }; // 필터 변경 핸들러 const handleFilterChange = (field, value) => { setFilters(prev => ({ ...prev, [field]: value })); }; // 검색 실행 const handleSearch = () => { loadKuntaeData(); }; // 유틸리티 함수들 const formatDate = (dateString) => { if (!dateString) return '-'; const date = new Date(dateString); return date.toLocaleDateString('ko-KR'); }; const getStatusColor = (status) => { switch (status) { case '승인': return 'bg-green-100 text-green-800'; case '대기': return 'bg-yellow-100 text-yellow-800'; case '반려': return 'bg-red-100 text-red-800'; default: return 'bg-gray-100 text-gray-800'; } }; // 알림 표시 함수 const showNotification = (message, type = 'info') => { const colors = { info: 'bg-blue-500/90 backdrop-blur-sm', success: 'bg-green-500/90 backdrop-blur-sm', warning: 'bg-yellow-500/90 backdrop-blur-sm', error: 'bg-red-500/90 backdrop-blur-sm' }; const notification = document.createElement('div'); notification.className = `fixed top-4 right-4 ${colors[type]} text-white px-4 py-3 rounded-lg z-50 transition-all duration-300 transform translate-x-0 opacity-100 shadow-lg border border-white/20`; notification.innerHTML = `
${message}
`; notification.style.transform = 'translateX(100%)'; notification.style.opacity = '0'; document.body.appendChild(notification); setTimeout(() => { notification.style.transform = 'translateX(0)'; notification.style.opacity = '1'; }, 10); setTimeout(() => { notification.style.transform = 'translateX(100%)'; notification.style.opacity = '0'; setTimeout(() => notification.remove(), 300); }, 3000); }; return (
{/* 개발중 경고 메시지 */}

🚧 개발중인 기능입니다

일부 기능이 정상적으로 동작하지 않을 수 있습니다.

{/* 검색 및 필터 섹션 */}
handleFilterChange('startDate', e.target.value)} className="w-full px-3 py-2 bg-white/20 border border-white/30 rounded-md text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-white/50 focus:border-transparent" />
handleFilterChange('endDate', e.target.value)} className="w-full px-3 py-2 bg-white/20 border border-white/30 rounded-md text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-white/50 focus:border-transparent" />
{/* 통계 카드 */}

총 신청건

{statistics.totalDays}

승인

{statistics.approvedDays}

대기

{statistics.pendingDays}

반려

{statistics.rejectedDays}

{/* 데이터 테이블 */}
{isLoading ? ( ) : kuntaeData.length === 0 ? ( ) : ( kuntaeData.map((item, index) => ( )) )}
신청일 시작일 종료일 휴가종류 일수 상태 사유
데이터를 불러오는 중...

근태 데이터가 없습니다.

{formatDate(item.requestDate)} {formatDate(item.startDate)} {formatDate(item.endDate)} {item.type || '-'} {item.days || '0'}일 {item.status || '-'}
{item.reason || '-'}
); }