969 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			969 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html lang="ko">
 | |
| <head>
 | |
|     <meta charset="UTF-8">
 | |
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | |
|     <title>근태현황 대시보드</title>
 | |
|     <script src="https://cdn.tailwindcss.com"></script>
 | |
|     <script>
 | |
|         tailwind.config = {
 | |
|             theme: {
 | |
|                 extend: {
 | |
|                     colors: {
 | |
|                         primary: {
 | |
|                             50: '#eff6ff',
 | |
|                             100: '#dbeafe',
 | |
|                             200: '#bfdbfe',
 | |
|                             300: '#93c5fd',
 | |
|                             400: '#60a5fa',
 | |
|                             500: '#3b82f6',
 | |
|                             600: '#2563eb',
 | |
|                             700: '#1d4ed8',
 | |
|                             800: '#1e40af',
 | |
|                             900: '#1e3a8a',
 | |
|                         },
 | |
|                         success: {
 | |
|                             50: '#f0fdf4',
 | |
|                             100: '#dcfce7',
 | |
|                             200: '#bbf7d0',
 | |
|                             300: '#86efac',
 | |
|                             400: '#4ade80',
 | |
|                             500: '#22c55e',
 | |
|                             600: '#16a34a',
 | |
|                             700: '#15803d',
 | |
|                             800: '#166534',
 | |
|                             900: '#14532d',
 | |
|                         },
 | |
|                         warning: {
 | |
|                             50: '#fffbeb',
 | |
|                             100: '#fef3c7',
 | |
|                             200: '#fde68a',
 | |
|                             300: '#fcd34d',
 | |
|                             400: '#fbbf24',
 | |
|                             500: '#f59e0b',
 | |
|                             600: '#d97706',
 | |
|                             700: '#b45309',
 | |
|                             800: '#92400e',
 | |
|                             900: '#78350f',
 | |
|                         },
 | |
|                         danger: {
 | |
|                             50: '#fef2f2',
 | |
|                             100: '#fee2e2',
 | |
|                             200: '#fecaca',
 | |
|                             300: '#fca5a5',
 | |
|                             400: '#f87171',
 | |
|                             500: '#ef4444',
 | |
|                             600: '#dc2626',
 | |
|                             700: '#b91c1c',
 | |
|                             800: '#991b1b',
 | |
|                             900: '#7f1d1d',
 | |
|                         }
 | |
|                     },
 | |
|                     animation: {
 | |
|                         'fade-in': 'fadeIn 0.5s ease-in-out',
 | |
|                         'slide-up': 'slideUp 0.3s ease-out',
 | |
|                         'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
 | |
|                     },
 | |
|                     keyframes: {
 | |
|                         fadeIn: {
 | |
|                             '0%': { opacity: '0' },
 | |
|                             '100%': { opacity: '1' },
 | |
|                         },
 | |
|                         slideUp: {
 | |
|                             '0%': { transform: 'translateY(10px)', opacity: '0' },
 | |
|                             '100%': { transform: 'translateY(0)', opacity: '1' },
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     </script>
 | |
|     <style>
 | |
|         .glass-effect {
 | |
|             background: rgba(255, 255, 255, 0.25);
 | |
|             backdrop-filter: blur(10px);
 | |
|             border: 1px solid rgba(255, 255, 255, 0.18);
 | |
|         }
 | |
|         .gradient-bg {
 | |
|             background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 | |
|         }
 | |
|         .card-hover {
 | |
|             transition: all 0.3s ease;
 | |
|         }
 | |
|         .card-hover:hover {
 | |
|             transform: translateY(-5px);
 | |
|             box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
 | |
|         }
 | |
|         
 | |
|         /* 스크롤바 스타일링 */
 | |
|         .custom-scrollbar::-webkit-scrollbar {
 | |
|             width: var(--scrollbar-width, 16px); /* 동적 스크롤바 너비 */
 | |
|         }
 | |
|         
 | |
|         .custom-scrollbar::-webkit-scrollbar-track {
 | |
|             background: rgba(255, 255, 255, 0.1);
 | |
|             border-radius: 8px;
 | |
|         }
 | |
|         
 | |
|         .custom-scrollbar::-webkit-scrollbar-thumb {
 | |
|             background: rgba(255, 255, 255, 0.3);
 | |
|             border-radius: 8px;
 | |
|             border: 2px solid rgba(255, 255, 255, 0.1);
 | |
|         }
 | |
|         
 | |
|         .custom-scrollbar::-webkit-scrollbar-thumb:hover {
 | |
|             background: rgba(255, 255, 255, 0.5);
 | |
|         }
 | |
|     </style>
 | |
| </head>
 | |
| <body class="gradient-bg min-h-screen">
 | |
|     <div class="container mx-auto px-4 py-8">
 | |
|         <!-- 헤더 -->
 | |
|         <div class="text-center mb-8 animate-fade-in">
 | |
|             <h1 class="text-4xl font-bold text-white mb-2">근태현황 대시보드</h1>
 | |
|             <p class="text-white/80 text-lg">-- 기능 테스트 중입니다 --</p>
 | |
|             
 | |
|             <!-- 스크롤바 설정 -->
 | |
|             <div class="mt-4 flex items-center justify-center gap-4">
 | |
|                 <label class="text-white/70 text-sm font-medium">스크롤바 크기:</label>
 | |
|                 <select id="scrollbarSize" class="bg-white/20 backdrop-blur-sm border border-white/30 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:ring-2 focus:ring-primary-400 transition-all">
 | |
|                     <option value="8">작게 (8px)</option>
 | |
|                     <option value="12">보통 (12px)</option>
 | |
|                     <option value="16" selected>크게 (16px)</option>
 | |
|                     <option value="20">매우 크게 (20px)</option>
 | |
|                     <option value="24">터치용 (24px)</option>
 | |
|                     <option value="32">매우 터치용 (32px)</option>
 | |
|                 </select>
 | |
|             </div>
 | |
|         </div>
 | |
| 
 | |
|         <!-- 통계 카드 -->
 | |
|         <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-6 mb-8">
 | |
|             
 | |
|             <!-- 출근 카드 -->
 | |
|             <div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up cursor-pointer" onclick="showPresentUserModal()">
 | |
|                 <div class="flex items-center justify-between">
 | |
|                     <div>
 | |
|                         <p class="text-white/70 text-sm font-medium">출근</p>
 | |
|                         <p class="text-3xl font-bold text-white" id="presentCount">0</p>
 | |
|                     </div>
 | |
|                     <div class="w-12 h-12 bg-success-500/20 rounded-full flex items-center justify-center">
 | |
|                         <svg class="w-6 h-6 text-success-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                             <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
 | |
|                         </svg>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
| 
 | |
|             <!-- 휴가 카드 -->
 | |
|             <div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up">
 | |
|                 <div class="flex items-center justify-between">
 | |
|                     <div>
 | |
|                         <p class="text-white/70 text-sm font-medium">휴가</p>
 | |
|                         <p class="text-3xl font-bold text-white" id="leaveCount">0</p>
 | |
|                     </div>
 | |
|                     <div class="w-12 h-12 bg-warning-500/20 rounded-full flex items-center justify-center">
 | |
|                         <svg class="w-6 h-6 text-warning-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                             <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
 | |
|                         </svg>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
| 
 | |
|             <!-- 휴가요청 카드 -->
 | |
|             <div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up cursor-pointer" onclick="showHolidayRequestModal()">
 | |
|                 <div class="flex items-center justify-between">
 | |
|                     <div>
 | |
|                         <p class="text-white/70 text-sm font-medium">휴가요청</p>
 | |
|                         <p class="text-3xl font-bold text-white" id="leaveRequestCount">0</p>
 | |
|                     </div>
 | |
|                     <div class="w-12 h-12 bg-primary-500/20 rounded-full flex items-center justify-center">
 | |
|                         <svg class="w-6 h-6 text-primary-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                             <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
 | |
|                         </svg>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
| 
 | |
|             <!-- 구매요청 카드(NR) -->
 | |
|             <div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up cursor-pointer" onclick="showPurchaseNRModal()">
 | |
|                 <div class="flex items-center justify-between">
 | |
|                     <div>
 | |
|                         <p class="text-white/70 text-sm font-medium">구매요청(NR)</p>
 | |
|                         <p class="text-3xl font-bold text-white" id="purchaseCountNR">0</p>
 | |
|                     </div>
 | |
|                     <div class="w-12 h-12 bg-danger-500/20 rounded-full flex items-center justify-center">
 | |
|                         <svg class="w-6 h-6 text-danger-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                             <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"></path>
 | |
|                         </svg>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
| 
 | |
| 			<!-- 구매요청 카드(CR) -->
 | |
|             <div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up cursor-pointer" onclick="showPurchaseCRModal()">
 | |
|                 <div class="flex items-center justify-between">
 | |
|                     <div>
 | |
|                         <p class="text-white/70 text-sm font-medium">구매요청(CR)</p>
 | |
|                         <p class="text-3xl font-bold text-white" id="purchaseCountCR">0</p>
 | |
|                     </div>
 | |
|                     <div class="w-12 h-12 bg-danger-500/20 rounded-full flex items-center justify-center">
 | |
|                         <svg class="w-6 h-6 text-danger-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                             <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"></path>
 | |
|                         </svg>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
| 
 | |
| 
 | |
|         </div>
 | |
| 
 | |
|         <!-- 휴가자 현황 테이블 -->
 | |
|         <div class="glass-effect rounded-2xl overflow-hidden animate-slide-up">
 | |
|             <div class="px-6 py-4 border-b border-white/10">
 | |
|                 <h2 class="text-xl font-semibold text-white flex items-center">
 | |
|                     <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>
 | |
|                     </svg>
 | |
|                     휴가자 현황
 | |
|                 </h2>
 | |
|             </div>
 | |
|             <div class="overflow-x-auto">
 | |
|                 <table class="w-full">
 | |
|                     <thead class="bg-white/10">
 | |
|                         <tr>
 | |
|                             <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">이름</th>
 | |
|                             <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">휴가 종류</th>
 | |
|                             <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">시작일</th>
 | |
|                             <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">종료일</th>
 | |
|                             <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">사유</th>
 | |
|                         </tr>
 | |
|                     </thead>
 | |
|                     <tbody id="holidayTable" class="divide-y divide-white/10">
 | |
|                         <!-- 데이터가 여기에 표시됩니다 -->
 | |
|                     </tbody>
 | |
|                 </table>
 | |
|             </div>
 | |
|         </div>
 | |
| 
 | |
|         <!-- 로딩 인디케이터 -->
 | |
|         <div id="loadingIndicator" class="fixed top-4 right-4 bg-white/20 backdrop-blur-sm rounded-full px-4 py-2 text-white text-sm hidden">
 | |
|             <div class="flex items-center">
 | |
|                 <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
 | |
|                 데이터 업데이트 중...
 | |
|             </div>
 | |
|         </div>
 | |
| 
 | |
|         <!-- 출근 대상자 모달 -->
 | |
|         <div id="presentUserModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm hidden z-50">
 | |
|             <div class="flex items-center justify-center min-h-screen p-4">
 | |
|                 <div class="glass-effect rounded-2xl w-full max-w-4xl max-h-[80vh] overflow-hidden animate-slide-up">
 | |
|                     <!-- 모달 헤더 -->
 | |
|                     <div class="px-6 py-4 border-b border-white/10 flex items-center justify-between">
 | |
|                         <h2 class="text-xl font-semibold text-white flex items-center">
 | |
|                             <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
 | |
|                             </svg>
 | |
|                             금일 출근 대상자 목록
 | |
|                         </h2>
 | |
|                         <button onclick="hidePresentUserModal()" class="text-white/70 hover:text-white transition-colors">
 | |
|                             <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
 | |
|                             </svg>
 | |
|                         </button>
 | |
|                     </div>
 | |
|                     
 | |
|                     <!-- 모달 내용 -->
 | |
|                     <div class="overflow-x-auto max-h-[60vh] custom-scrollbar">
 | |
|                         <table class="w-full">
 | |
|                             <thead class="bg-white/10 sticky top-0">
 | |
|                                 <tr>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">사번</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">이름</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">공정</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">직급</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">상태</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">이메일</th>
 | |
|                                 </tr>
 | |
|                             </thead>
 | |
|                             <tbody id="presentUserTable" class="divide-y divide-white/10">
 | |
|                                 <!-- 데이터가 여기에 표시됩니다 -->
 | |
|                             </tbody>
 | |
|                         </table>
 | |
|                     </div>
 | |
|                     
 | |
|                     <!-- 모달 푸터 -->
 | |
|                     <div class="px-6 py-4 border-t border-white/10 flex justify-between items-center">
 | |
|                         <p class="text-white/70 text-sm">총 <span id="presentUserCount">0</span>명</p>
 | |
|                         <button onclick="hidePresentUserModal()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
 | |
|                             닫기
 | |
|                         </button>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
| 
 | |
|         <!-- 휴가요청 모달 -->
 | |
|         <div id="holidayRequestModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm hidden z-50">
 | |
|             <div class="flex items-center justify-center min-h-screen p-4">
 | |
|                 <div class="glass-effect rounded-2xl w-full max-w-6xl max-h-[80vh] overflow-hidden animate-slide-up">
 | |
|                     <!-- 모달 헤더 -->
 | |
|                     <div class="px-6 py-4 border-b border-white/10 flex items-center justify-between">
 | |
|                         <h2 class="text-xl font-semibold text-white flex items-center">
 | |
|                             <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
 | |
|                             </svg>
 | |
|                             휴가 신청 목록
 | |
|                         </h2>
 | |
|                         <button onclick="hideHolidayRequestModal()" class="text-white/70 hover:text-white transition-colors">
 | |
|                             <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
 | |
|                             </svg>
 | |
|                         </button>
 | |
|                     </div>
 | |
|                     
 | |
|                     <!-- 모달 내용 -->
 | |
|                     <div class="overflow-x-auto max-h-[60vh] custom-scrollbar">
 | |
|                         <table class="w-full">
 | |
|                             <thead class="bg-white/10 sticky top-0">
 | |
|                                 <tr>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">사번</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">이름</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">항목</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">일자</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">요청일</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">요청시간</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">비고</th>
 | |
|                                 </tr>
 | |
|                             </thead>
 | |
|                             <tbody id="holidayRequestTable" class="divide-y divide-white/10">
 | |
|                                 <!-- 데이터가 여기에 표시됩니다 -->
 | |
|                             </tbody>
 | |
|                         </table>
 | |
|                     </div>
 | |
|                     
 | |
|                     <!-- 모달 푸터 -->
 | |
|                     <div class="px-6 py-4 border-t border-white/10 flex justify-between items-center">
 | |
|                         <p class="text-white/70 text-sm">총 <span id="holidayRequestCount">0</span>건</p>
 | |
|                         <button onclick="hideHolidayRequestModal()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
 | |
|                             닫기
 | |
|                         </button>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
| 
 | |
|         <!-- 구매NR 모달 -->
 | |
|         <div id="purchaseNRModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm hidden z-50">
 | |
|             <div class="flex items-center justify-center min-h-screen p-4">
 | |
|                 <div class="glass-effect rounded-2xl w-full max-w-7xl max-h-[80vh] overflow-hidden animate-slide-up">
 | |
|                     <!-- 모달 헤더 -->
 | |
|                     <div class="px-6 py-4 border-b border-white/10 flex items-center justify-between">
 | |
|                         <h2 class="text-xl font-semibold text-white flex items-center">
 | |
|                             <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"></path>
 | |
|                             </svg>
 | |
|                             구매요청(NR) 목록
 | |
|                         </h2>
 | |
|                         <button onclick="hidePurchaseNRModal()" class="text-white/70 hover:text-white transition-colors">
 | |
|                             <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
 | |
|                             </svg>
 | |
|                         </button>
 | |
|                     </div>
 | |
|                     
 | |
|                     <!-- 모달 내용 -->
 | |
|                     <div class="overflow-x-auto max-h-[60vh] custom-scrollbar">
 | |
|                         <table class="w-full">
 | |
|                             <thead class="bg-white/10 sticky top-0">
 | |
|                                 <tr>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">요청일</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">공정</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">품명</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">규격</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">단위</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">수량</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">단가</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">금액</th>
 | |
|                                 </tr>
 | |
|                             </thead>
 | |
|                             <tbody id="purchaseNRTable" class="divide-y divide-white/10">
 | |
|                                 <!-- 데이터가 여기에 표시됩니다 -->
 | |
|                             </tbody>
 | |
|                         </table>
 | |
|                     </div>
 | |
|                     
 | |
|                     <!-- 모달 푸터 -->
 | |
|                     <div class="px-6 py-4 border-t border-white/10 flex justify-between items-center">
 | |
|                         <p class="text-white/70 text-sm">총 <span id="purchaseNRCount">0</span>건</p>
 | |
|                         <button onclick="hidePurchaseNRModal()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
 | |
|                             닫기
 | |
|                         </button>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
| 
 | |
|         <!-- 구매CR 모달 -->
 | |
|         <div id="purchaseCRModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm hidden z-50">
 | |
|             <div class="flex items-center justify-center min-h-screen p-4">
 | |
|                 <div class="glass-effect rounded-2xl w-full max-w-7xl max-h-[80vh] overflow-hidden animate-slide-up">
 | |
|                     <!-- 모달 헤더 -->
 | |
|                     <div class="px-6 py-4 border-b border-white/10 flex items-center justify-between">
 | |
|                         <h2 class="text-xl font-semibold text-white flex items-center">
 | |
|                             <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"></path>
 | |
|                             </svg>
 | |
|                             구매요청(CR) 목록
 | |
|                         </h2>
 | |
|                         <button onclick="hidePurchaseCRModal()" class="text-white/70 hover:text-white transition-colors">
 | |
|                             <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 | |
|                                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
 | |
|                             </svg>
 | |
|                         </button>
 | |
|                     </div>
 | |
|                     
 | |
|                     <!-- 모달 내용 -->
 | |
|                     <div class="overflow-x-auto max-h-[60vh] custom-scrollbar">
 | |
|                         <table class="w-full">
 | |
|                             <thead class="bg-white/10 sticky top-0">
 | |
|                                 <tr>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">요청일</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">공정</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">품명</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">규격</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">단위</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">수량</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">단가</th>
 | |
|                                     <th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">금액</th>
 | |
|                                 </tr>
 | |
|                             </thead>
 | |
|                             <tbody id="purchaseCRTable" class="divide-y divide-white/10">
 | |
|                                 <!-- 데이터가 여기에 표시됩니다 -->
 | |
|                             </tbody>
 | |
|                         </table>
 | |
|                     </div>
 | |
|                     
 | |
|                     <!-- 모달 푸터 -->
 | |
|                     <div class="px-6 py-4 border-t border-white/10 flex justify-between items-center">
 | |
|                         <p class="text-white/70 text-sm">총 <span id="purchaseCRCount">0</span>건</p>
 | |
|                         <button onclick="hidePurchaseCRModal()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
 | |
|                             닫기
 | |
|                         </button>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
|     </div>
 | |
| 
 | |
|     <script>
 | |
|     // 휴가 인원 Ajax 업데이트
 | |
|     function updateLeaveCount() {
 | |
|         showLoading();
 | |
|         fetch('http://127.0.0.1:7979/Dashboard/TodayCountH')
 | |
|             .then(response => response.text())
 | |
|             .then(data => {
 | |
|                 const cleanData = data.replace(/"/g, '');
 | |
|                 const count = parseInt(cleanData, 10);
 | |
|                 animateNumberChange('leaveCount', count);
 | |
|                 hideLoading();
 | |
|             })
 | |
|             .catch(error => {
 | |
|                 console.error('휴가 인원 업데이트 중 오류 발생:', error);
 | |
|                 hideLoading();
 | |
|             });
 | |
|     }
 | |
| 
 | |
|     // 휴가자 목록 Ajax 업데이트
 | |
|     function updateHolidayList() {
 | |
|         showLoading();
 | |
|         fetch('http://127.0.0.1:7979/Dashboard/GetholyUser')
 | |
|             .then(response => response.json())
 | |
|             .then(data => {
 | |
|                 let tableRows = '';
 | |
|                 if (data && data.length > 0) {
 | |
|                     data.forEach(item => {
 | |
|                         tableRows += `
 | |
|                             <tr class="hover:bg-white/5 transition-colors">
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white">${item.name || '-'}(${item.uid})</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap">
 | |
|                                     <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-warning-500/20 text-warning-300">
 | |
|                                         ${item.cate || '-'}
 | |
|                                     </span>
 | |
|                                 </td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.sdate || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.edate || '-'}</td>
 | |
|                                 <td class="px-6 py-4 text-white/80">${item.HolyReason || '-'}</td>
 | |
|                             </tr>
 | |
|                         `;
 | |
|                     });
 | |
|                 } else {
 | |
|                     tableRows = `
 | |
|                         <tr>
 | |
|                             <td colspan="5" class="px-6 py-8 text-center text-white/50">
 | |
|                                 현재 휴가자가 없습니다
 | |
|                             </td>
 | |
|                         </tr>
 | |
|                     `;
 | |
|                 }
 | |
|                 document.getElementById('holidayTable').innerHTML = tableRows;
 | |
|                 hideLoading();
 | |
|             })
 | |
|             .catch(error => {
 | |
|                 console.error('휴가자 목록 업데이트 중 오류 발생:', error);
 | |
|                 document.getElementById('holidayTable').innerHTML = `
 | |
|                     <tr>
 | |
|                         <td colspan="5" class="px-6 py-8 text-center text-danger-400">
 | |
|                             데이터를 불러오는 중 오류가 발생했습니다
 | |
|                         </td>
 | |
|                     </tr>
 | |
|                 `;
 | |
|                 hideLoading();
 | |
|             });
 | |
|     }
 | |
| 
 | |
|     // 구매요청 데이터 Ajax 업데이트
 | |
|     function updatePurchaseCount() {
 | |
|         showLoading();
 | |
|         fetch('http://127.0.0.1:7979/DashBoard/GetPurchaseWaitCount')
 | |
|             .then(response => response.json())
 | |
|             .then(data => {
 | |
|                 if (data) {
 | |
|                     // NR 구매요청 카운트 업데이트
 | |
|                     if (data.NR !== undefined) {
 | |
|                         animateNumberChange('purchaseCountNR', data.NR);
 | |
|                     }
 | |
|                     
 | |
|                     // CR 구매요청 카운트 업데이트
 | |
|                     if (data.CR !== undefined) {
 | |
|                         animateNumberChange('purchaseCountCR', data.CR);
 | |
|                     }
 | |
|                 }
 | |
|                 hideLoading();
 | |
|             })
 | |
|             .catch(error => {
 | |
|                 console.error('구매요청 데이터 업데이트 중 오류 발생:', error);
 | |
|                 hideLoading();
 | |
|             });
 | |
|     }
 | |
| 
 | |
|      // 휴가요청 데이터 Ajax 업데이트
 | |
|      function updateHolydayRequestCount() {
 | |
|         showLoading();
 | |
|         fetch('http://127.0.0.1:7979/DashBoard/GetHolydayRequestCount')
 | |
|             .then(response => response.json())
 | |
|             .then(data => {
 | |
|                 if (data) {
 | |
|                     // NR 구매요청 카운트 업데이트
 | |
|                     if (data.HOLY !== undefined) {
 | |
|                         animateNumberChange('leaveRequestCount', data.HOLY);
 | |
|                     }            
 | |
|                 }
 | |
|                 hideLoading();
 | |
|             })
 | |
|             .catch(error => {
 | |
|                 console.error('휴가요청 데이터 업데이트 중 오류 발생:', error);
 | |
|                 hideLoading();
 | |
|             });
 | |
|     }
 | |
| 
 | |
| 	 // 사용자카운트 데이터 Ajax 업데이트
 | |
|      function updateCurrentUserCount() {
 | |
|         showLoading();
 | |
|         fetch('http://127.0.0.1:7979/DashBoard/GetCurrentUserCount')
 | |
|             .then(response => response.json())
 | |
|             .then(data => {
 | |
|                 if (data) {
 | |
|                     // NR 구매요청 카운트 업데이트
 | |
|                     if (data.Count !== undefined) {
 | |
|                         animateNumberChange('presentCount', data.Count);
 | |
|                     }            
 | |
|                 }
 | |
|                 hideLoading();
 | |
|             })
 | |
|             .catch(error => {
 | |
|                 console.error('현재유저 카운트 업데이트 중 오류 발생:', error);
 | |
|                 hideLoading();
 | |
|             });
 | |
|     }
 | |
| 
 | |
|     // 숫자 애니메이션
 | |
|     function animateNumberChange(elementId, newValue) {
 | |
|         const element = document.getElementById(elementId);
 | |
|         const currentValue = parseInt(element.textContent) || 0;
 | |
|         const increment = (newValue - currentValue) / 20;
 | |
|         let current = currentValue;
 | |
|         
 | |
|         const timer = setInterval(() => {
 | |
|             current += increment;
 | |
|             if ((increment > 0 && current >= newValue) || (increment < 0 && current <= newValue)) {
 | |
|                 element.textContent = newValue;
 | |
|                 clearInterval(timer);
 | |
|             } else {
 | |
|                 element.textContent = Math.floor(current);
 | |
|             }
 | |
|         }, 50);
 | |
|     }
 | |
| 
 | |
|     // 로딩 표시
 | |
|     function showLoading() {
 | |
|         document.getElementById('loadingIndicator').classList.remove('hidden');
 | |
|     }
 | |
| 
 | |
|     function hideLoading() {
 | |
|         document.getElementById('loadingIndicator').classList.add('hidden');
 | |
|     }
 | |
| 
 | |
|     // 페이지 로드 시 데이터 업데이트
 | |
|     updateLeaveCount();
 | |
|     updateHolidayList();
 | |
|     updatePurchaseCount();
 | |
|     updateHolydayRequestCount();
 | |
| 	updateCurrentUserCount();
 | |
| 
 | |
|     // 스크롤바 크기 설정 초기화
 | |
|     initializeScrollbarSize();
 | |
| 
 | |
|     // 30초마다 데이터 새로고침
 | |
|     setInterval(() => {
 | |
|         updateLeaveCount();
 | |
|         updateHolidayList();
 | |
|         updatePurchaseCount();
 | |
|         updateHolydayRequestCount();
 | |
| 		updateCurrentUserCount();
 | |
|     }, 30000);
 | |
| 
 | |
|     // 출근 대상자 모달 표시
 | |
|     function showPresentUserModal() {
 | |
|         document.getElementById('presentUserModal').classList.remove('hidden');
 | |
|         loadPresentUserList();
 | |
|     }
 | |
| 
 | |
|     // 출근 대상자 모달 숨기기
 | |
|     function hidePresentUserModal() {
 | |
|         document.getElementById('presentUserModal').classList.add('hidden');
 | |
|     }
 | |
| 
 | |
|     // 출근 대상자 목록 로드
 | |
|     function loadPresentUserList() {
 | |
|         showLoading();
 | |
|         fetch('http://127.0.0.1:7979/DashBoard/GetPresentUserList')
 | |
|             .then(response => response.json())
 | |
|             .then(data => {
 | |
|                 let tableRows = '';
 | |
|                 if (data && data.length > 0) {
 | |
|                     data.forEach(item => {
 | |
|                         const statusClass = item.useUserState == 1 ? 'bg-success-500/20 text-success-300' : 'bg-danger-500/20 text-danger-300';
 | |
|                         const statusText = item.useUserState == 1 ? '활성' : '비활성';
 | |
|                         
 | |
|                         tableRows += `
 | |
|                             <tr class="hover:bg-white/5 transition-colors">
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white">${item.id || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white">${item.name || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.processs || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.grade || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap">
 | |
|                                     <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${statusClass}">
 | |
|                                         ${statusText}
 | |
|                                     </span>
 | |
|                                 </td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.email || '-'}</td>
 | |
|                             </tr>
 | |
|                         `;
 | |
|                     });
 | |
|                     document.getElementById('presentUserCount').textContent = data.length;
 | |
|                 } else {
 | |
|                     tableRows = `
 | |
|                         <tr>
 | |
|                             <td colspan="5" class="px-6 py-8 text-center text-white/50">
 | |
|                                 출근 대상자가 없습니다
 | |
|                             </td>
 | |
|                         </tr>
 | |
|                     `;
 | |
|                     document.getElementById('presentUserCount').textContent = '0';
 | |
|                 }
 | |
|                 document.getElementById('presentUserTable').innerHTML = tableRows;
 | |
|                 hideLoading();
 | |
|             })
 | |
|             .catch(error => {
 | |
|                 console.error('출근 대상자 목록 로드 중 오류 발생:', error);
 | |
|                 document.getElementById('presentUserTable').innerHTML = `
 | |
|                     <tr>
 | |
|                         <td colspan="5" class="px-6 py-8 text-center text-danger-400">
 | |
|                             데이터를 불러오는 중 오류가 발생했습니다
 | |
|                         </td>
 | |
|                     </tr>
 | |
|                 `;
 | |
|                 document.getElementById('presentUserCount').textContent = '0';
 | |
|                 hideLoading();
 | |
|             });
 | |
|     }
 | |
| 
 | |
|     // ESC 키로 모달 닫기
 | |
|     document.addEventListener('keydown', function(event) {
 | |
|         if (event.key === 'Escape') {
 | |
|             hidePresentUserModal();
 | |
|             hideHolidayRequestModal();
 | |
|             hidePurchaseNRModal();
 | |
|             hidePurchaseCRModal();
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     // 모달 외부 클릭으로 닫기
 | |
|     document.getElementById('presentUserModal').addEventListener('click', function(event) {
 | |
|         if (event.target === this) {
 | |
|             hidePresentUserModal();
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     // 휴가요청 모달 표시
 | |
|     function showHolidayRequestModal() {
 | |
|         document.getElementById('holidayRequestModal').classList.remove('hidden');
 | |
|         loadHolidayRequestList();
 | |
|     }
 | |
| 
 | |
|     // 휴가요청 모달 숨기기
 | |
|     function hideHolidayRequestModal() {
 | |
|         document.getElementById('holidayRequestModal').classList.add('hidden');
 | |
|     }
 | |
| 
 | |
|     // 휴가요청 목록 로드
 | |
|     function loadHolidayRequestList() {
 | |
|         showLoading();
 | |
|         fetch('http://127.0.0.1:7979/DashBoard/GetholyRequestUser')
 | |
|             .then(response => response.json())
 | |
|             .then(data => {
 | |
|                 let tableRows = '';
 | |
|                 if (data && data.length > 0) {
 | |
|                     data.forEach(item => {
 | |
|                         // 일자 포맷팅 (시작일 ~ 종료일)
 | |
|                         const startDate = item.sdate ? new Date(item.sdate).toLocaleDateString('ko-KR') : '-';
 | |
|                         const endDate = item.edate ? new Date(item.edate).toLocaleDateString('ko-KR') : '-';
 | |
|                         const dateRange = startDate !== '-' && endDate !== '-' ? `${startDate} ~ ${endDate}` : '-';
 | |
|                         
 | |
|                         // 요청일 포맷팅
 | |
|                         const requestDate = item.holyday ? new Date(item.holyday).toLocaleDateString('ko-KR') : '-';
 | |
|                         
 | |
|                         tableRows += `
 | |
|                             <tr class="hover:bg-white/5 transition-colors">
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white">${item.uid || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white">${item.name || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap">
 | |
|                                     <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-primary-500/20 text-primary-300">
 | |
|                                         ${item.cate || '-'}
 | |
|                                     </span>
 | |
|                                 </td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${dateRange}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${requestDate}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.holytime || '-'}</td>
 | |
|                                 <td class="px-6 py-4 text-white/80">${item.remakr || '-'}</td>
 | |
|                             </tr>
 | |
|                         `;
 | |
|                     });
 | |
|                     document.getElementById('holidayRequestCount').textContent = data.length;
 | |
|                 } else {
 | |
|                     tableRows = `
 | |
|                         <tr>
 | |
|                             <td colspan="7" class="px-6 py-8 text-center text-white/50">
 | |
|                                 휴가 신청이 없습니다
 | |
|                             </td>
 | |
|                         </tr>
 | |
|                     `;
 | |
|                     document.getElementById('holidayRequestCount').textContent = '0';
 | |
|                 }
 | |
|                 document.getElementById('holidayRequestTable').innerHTML = tableRows;
 | |
|                 hideLoading();
 | |
|             })
 | |
|             .catch(error => {
 | |
|                 console.error('휴가요청 목록 로드 중 오류 발생:', error);
 | |
|                 document.getElementById('holidayRequestTable').innerHTML = `
 | |
|                     <tr>
 | |
|                         <td colspan="7" class="px-6 py-8 text-center text-danger-400">
 | |
|                             데이터를 불러오는 중 오류가 발생했습니다
 | |
|                         </td>
 | |
|                     </tr>
 | |
|                 `;
 | |
|                 document.getElementById('holidayRequestCount').textContent = '0';
 | |
|                 hideLoading();
 | |
|             });
 | |
|     }
 | |
| 
 | |
|     // 휴가요청 모달 외부 클릭으로 닫기
 | |
|     document.getElementById('holidayRequestModal').addEventListener('click', function(event) {
 | |
|         if (event.target === this) {
 | |
|             hideHolidayRequestModal();
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     // 구매NR 모달 표시
 | |
|     function showPurchaseNRModal() {
 | |
|         document.getElementById('purchaseNRModal').classList.remove('hidden');
 | |
|         loadPurchaseNRList();
 | |
|     }
 | |
| 
 | |
|     // 구매NR 모달 숨기기
 | |
|     function hidePurchaseNRModal() {
 | |
|         document.getElementById('purchaseNRModal').classList.add('hidden');
 | |
|     }
 | |
| 
 | |
|     // 구매NR 목록 로드
 | |
|     function loadPurchaseNRList() {
 | |
|         showLoading();
 | |
|         fetch('http://127.0.0.1:7979/DashBoard/GetPurchaseNRList')
 | |
|             .then(response => response.json())
 | |
|             .then(data => {
 | |
|                 let tableRows = '';
 | |
|                 if (data && data.length > 0) {
 | |
|                     data.forEach(item => {
 | |
|                         // 요청일 포맷팅
 | |
|                         const requestDate = item.pdate ? new Date(item.pdate).toLocaleDateString('ko-KR') : '-';
 | |
|                         
 | |
|                         // 금액 포맷팅 (천 단위 콤마)
 | |
|                         const amount = item.pumamt ? Number(item.pumamt).toLocaleString() : '-';
 | |
|                         const price = item.pumprice ? Number(item.pumprice).toLocaleString() : '-';
 | |
|                         
 | |
|                         tableRows += `
 | |
|                             <tr class="hover:bg-white/5 transition-colors">
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${requestDate}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.process || '-'}</td>
 | |
|                                 <td class="px-6 py-4 text-white">${item.pumname || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumscale || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumunit || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumqtyreq || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${price}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white font-medium">${amount}</td>
 | |
|                             </tr>
 | |
|                         `;
 | |
|                     });
 | |
|                     document.getElementById('purchaseNRCount').textContent = data.length;
 | |
|                 } else {
 | |
|                     tableRows = `
 | |
|                         <tr>
 | |
|                             <td colspan="8" class="px-6 py-8 text-center text-white/50">
 | |
|                                 구매요청이 없습니다
 | |
|                             </td>
 | |
|                         </tr>
 | |
|                     `;
 | |
|                     document.getElementById('purchaseNRCount').textContent = '0';
 | |
|                 }
 | |
|                 document.getElementById('purchaseNRTable').innerHTML = tableRows;
 | |
|                 hideLoading();
 | |
|             })
 | |
|             .catch(error => {
 | |
|                 console.error('구매NR 목록 로드 중 오류 발생:', error);
 | |
|                 document.getElementById('purchaseNRTable').innerHTML = `
 | |
|                     <tr>
 | |
|                         <td colspan="8" class="px-6 py-8 text-center text-danger-400">
 | |
|                             데이터를 불러오는 중 오류가 발생했습니다
 | |
|                         </td>
 | |
|                     </tr>
 | |
|                 `;
 | |
|                 document.getElementById('purchaseNRCount').textContent = '0';
 | |
|                 hideLoading();
 | |
|             });
 | |
|     }
 | |
| 
 | |
|     // 구매NR 모달 외부 클릭으로 닫기
 | |
|     document.getElementById('purchaseNRModal').addEventListener('click', function(event) {
 | |
|         if (event.target === this) {
 | |
|             hidePurchaseNRModal();
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     // 구매CR 모달 표시
 | |
|     function showPurchaseCRModal() {
 | |
|         document.getElementById('purchaseCRModal').classList.remove('hidden');
 | |
|         loadPurchaseCRList();
 | |
|     }
 | |
| 
 | |
|     // 구매CR 모달 숨기기
 | |
|     function hidePurchaseCRModal() {
 | |
|         document.getElementById('purchaseCRModal').classList.add('hidden');
 | |
|     }
 | |
| 
 | |
|     // 구매CR 목록 로드
 | |
|     function loadPurchaseCRList() {
 | |
|         showLoading();
 | |
|         fetch('http://127.0.0.1:7979/DashBoard/GetPurchaseCRList')
 | |
|             .then(response => response.json())
 | |
|             .then(data => {
 | |
|                 let tableRows = '';
 | |
|                 if (data && data.length > 0) {
 | |
|                     data.forEach(item => {
 | |
|                         // 요청일 포맷팅
 | |
|                         const requestDate = item.pdate ? new Date(item.pdate).toLocaleDateString('ko-KR') : '-';
 | |
|                         
 | |
|                         // 금액 포맷팅 (천 단위 콤마)
 | |
|                         const amount = item.pumamt ? Number(item.pumamt).toLocaleString() : '-';
 | |
|                         const price = item.pumprice ? Number(item.pumprice).toLocaleString() : '-';
 | |
|                         
 | |
|                         tableRows += `
 | |
|                             <tr class="hover:bg-white/5 transition-colors">
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${requestDate}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.process || '-'}</td>
 | |
|                                 <td class="px-6 py-4 text-white">${item.pumname || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumscale || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumunit || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumqtyreq || '-'}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white/80">${price}</td>
 | |
|                                 <td class="px-6 py-4 whitespace-nowrap text-white font-medium">${amount}</td>
 | |
|                             </tr>
 | |
|                         `;
 | |
|                     });
 | |
|                     document.getElementById('purchaseCRCount').textContent = data.length;
 | |
|                 } else {
 | |
|                     tableRows = `
 | |
|                         <tr>
 | |
|                             <td colspan="8" class="px-6 py-8 text-center text-white/50">
 | |
|                                 구매요청이 없습니다
 | |
|                             </td>
 | |
|                         </tr>
 | |
|                     `;
 | |
|                     document.getElementById('purchaseCRCount').textContent = '0';
 | |
|                 }
 | |
|                 document.getElementById('purchaseCRTable').innerHTML = tableRows;
 | |
|                 hideLoading();
 | |
|             })
 | |
|             .catch(error => {
 | |
|                 console.error('구매CR 목록 로드 중 오류 발생:', error);
 | |
|                 document.getElementById('purchaseCRTable').innerHTML = `
 | |
|                     <tr>
 | |
|                         <td colspan="8" class="px-6 py-8 text-center text-danger-400">
 | |
|                             데이터를 불러오는 중 오류가 발생했습니다
 | |
|                         </td>
 | |
|                     </tr>
 | |
|                 `;
 | |
|                 document.getElementById('purchaseCRCount').textContent = '0';
 | |
|                 hideLoading();
 | |
|             });
 | |
|     }
 | |
| 
 | |
|     // 구매CR 모달 외부 클릭으로 닫기
 | |
|     document.getElementById('purchaseCRModal').addEventListener('click', function(event) {
 | |
|         if (event.target === this) {
 | |
|             hidePurchaseCRModal();
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     // 스크롤바 크기 초기화
 | |
|     function initializeScrollbarSize() {
 | |
|         const savedSize = localStorage.getItem('scrollbarSize') || '16';
 | |
|         const select = document.getElementById('scrollbarSize');
 | |
|         select.value = savedSize;
 | |
|         updateScrollbarSize(savedSize);
 | |
|         
 | |
|         // 콤보박스 변경 이벤트 리스너
 | |
|         select.addEventListener('change', function() {
 | |
|             const size = this.value;
 | |
|             updateScrollbarSize(size);
 | |
|             localStorage.setItem('scrollbarSize', size);
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     // 스크롤바 크기 업데이트
 | |
|     function updateScrollbarSize(size) {
 | |
|         document.documentElement.style.setProperty('--scrollbar-width', size + 'px');
 | |
|     }
 | |
|     </script>
 | |
| </body>
 | |
| </html>  | 
