Files
Groupware/Project/Web/wwwroot/Kuntae/index.html
2025-07-16 11:05:55 +09:00

693 lines
34 KiB
HTML

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>근태입력 조회</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#3B82F6',
secondary: '#6B7280',
success: '#10B981',
danger: '#EF4444',
warning: '#F59E0B'
}
}
}
}
</script>
<style>
.loading {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid #f3f3f3;
border-top: 3px solid #3B82F6;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.table-container {
max-height: 600px;
overflow-y: auto;
}
.table-container::-webkit-scrollbar {
width: 8px;
}
.table-container::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
.table-container::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 4px;
}
.table-container::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- 검색 및 필터 섹션 -->
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label for="startDate" class="block text-sm font-medium text-gray-700 mb-2">시작일</label>
<input type="date" id="startDate" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
</div>
<div>
<label for="endDate" class="block text-sm font-medium text-gray-700 mb-2">종료일</label>
<input type="date" id="endDate" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
</div>
<div class="flex items-end">
<button id="searchBtn" class="w-full bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-600 transition-colors duration-200 flex items-center justify-center">
<span id="searchBtnText">조회</span>
<div id="searchBtnLoading" class="loading ml-2 hidden"></div>
</button>
</div>
</div>
</div>
<!-- 통계 카드 -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-6">
<div class="bg-white rounded-lg shadow-md p-6">
<div class="flex items-center">
<div class="p-2 bg-blue-100 rounded-lg">
<svg class="w-6 h-6 text-blue-600" 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 class="ml-4">
<p class="text-sm font-medium text-gray-600">휴가사용</p>
<p id="totalDays" class="text-2xl font-bold text-gray-900">0</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<div class="flex items-center">
<div class="p-2 bg-green-100 rounded-lg">
<svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">대체사용</p>
<p id="normalDays" class="text-2xl font-bold text-gray-900">0</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<div class="flex items-center">
<div class="p-2 bg-yellow-100 rounded-lg">
<svg class="w-6 h-6 text-yellow-600" 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 class="ml-4">
<p class="text-sm font-medium text-gray-600">잔량(년차)</p>
<p id="lateDays" class="text-2xl font-bold text-gray-900">0</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<div class="flex items-center">
<div class="p-2 bg-red-100 rounded-lg">
<svg class="w-6 h-6 text-red-600" 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>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">잔량(대체)</p>
<p id="absentDays" class="text-2xl font-bold text-gray-900">0</p>
</div>
</div>
</div>
</div>
<!-- 데이터 테이블 -->
<div class="bg-white rounded-lg shadow-md">
<div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
<h3 class="text-lg font-medium text-gray-900">근태 상세 내역</h3>
<button id="addBtn" class="bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-600 transition-colors duration-200 flex items-center">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg>
근태 추가
</button>
</div>
<div class="table-container">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50 sticky top-0">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">구분</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">시작일</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">종료일</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">사번</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">성명</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">사용(일)</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">사용(H)</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">발생(일)</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">발생(H)</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">내용</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">#</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">잔량(일)</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">잔량(H)</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">전일(일)</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">전일(H)</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">소스</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">등록자</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">등록일</th>
</tr>
</thead>
<tbody id="dataTableBody" class="bg-white divide-y divide-gray-200">
<tr id="loadingRow" class="hidden">
<td colspan="7" class="px-6 py-4 text-center">
<div class="flex items-center justify-center">
<div class="loading mr-2"></div>
<span class="text-gray-500">데이터를 불러오는 중...</span>
</div>
</td>
</tr>
<tr id="noDataRow" class="hidden">
<td colspan="7" class="px-6 py-4 text-center text-gray-500">
조회된 데이터가 없습니다.
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 근태 추가/편집 모달 -->
<div id="kuntaeModal" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full hidden z-50">
<div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
<div class="mt-3">
<div class="flex justify-between items-center mb-4">
<h3 id="modalTitle" class="text-lg font-medium text-gray-900">근태 추가</h3>
<button id="closeModal" class="text-gray-400 hover:text-gray-600">
<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>
<form id="kuntaeForm">
<input type="hidden" id="editId" name="id">
<div class="mb-4">
<label for="modalDate" class="block text-sm font-medium text-gray-700 mb-2">날짜</label>
<input type="date" id="modalDate" name="pdate" required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<label for="modalInTime" class="block text-sm font-medium text-gray-700 mb-2">출근시간</label>
<input type="time" id="modalInTime" name="intime"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
</div>
<div>
<label for="modalOutTime" class="block text-sm font-medium text-gray-700 mb-2">퇴근시간</label>
<input type="time" id="modalOutTime" name="outtime"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
</div>
</div>
<div class="mb-4">
<label for="modalMemo" class="block text-sm font-medium text-gray-700 mb-2">비고</label>
<textarea id="modalMemo" name="memo" rows="3"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
placeholder="비고사항을 입력하세요"></textarea>
</div>
<div class="flex justify-end space-x-3">
<button type="button" id="cancelBtn"
class="px-4 py-2 text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 transition-colors duration-200">
취소
</button>
<button type="submit" id="saveBtn"
class="px-4 py-2 bg-primary text-white rounded-md hover:bg-blue-600 transition-colors duration-200">
저장
</button>
</div>
</form>
</div>
</div>
</div>
<!-- 삭제 확인 모달 -->
<div id="deleteModal" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full hidden z-50">
<div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
<div class="mt-3">
<div class="flex items-center mb-4">
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100">
<svg class="h-6 w-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"></path>
</svg>
</div>
</div>
<div class="text-center">
<h3 class="text-lg font-medium text-gray-900 mb-2">근태 삭제</h3>
<p class="text-sm text-gray-500 mb-4">선택한 근태 데이터를 삭제하시겠습니까?</p>
<p id="deleteConfirmText" class="text-sm text-gray-700 mb-6"></p>
<div class="flex justify-center space-x-3">
<button id="cancelDeleteBtn"
class="px-4 py-2 text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 transition-colors duration-200">
취소
</button>
<button id="confirmDeleteBtn"
class="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 transition-colors duration-200">
삭제
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// 전역 변수
let currentData = [];
let currentEditId = null;
// 페이지 로드 시 초기화
document.addEventListener('DOMContentLoaded', function() {
initializeDates();
loadData();
setupEventListeners();
setupModalEvents();
});
// 날짜 초기화 (현재 월)
function initializeDates() {
const now = new Date();
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0);
document.getElementById('startDate').value = startOfMonth.toISOString().split('T')[0];
document.getElementById('endDate').value = endOfMonth.toISOString().split('T')[0];
}
// 이벤트 리스너 설정
function setupEventListeners() {
document.getElementById('searchBtn').addEventListener('click', loadData);
document.getElementById('addBtn').addEventListener('click', showAddModal);
// Enter 키로 검색
document.getElementById('startDate').addEventListener('keypress', function(e) {
if (e.key === 'Enter') loadData();
});
document.getElementById('endDate').addEventListener('keypress', function(e) {
if (e.key === 'Enter') loadData();
});
}
// 모달 이벤트 설정
function setupModalEvents() {
// 근태 모달 이벤트
document.getElementById('closeModal').addEventListener('click', hideKuntaeModal);
document.getElementById('cancelBtn').addEventListener('click', hideKuntaeModal);
document.getElementById('kuntaeForm').addEventListener('submit', saveKuntae);
// 삭제 모달 이벤트
document.getElementById('cancelDeleteBtn').addEventListener('click', hideDeleteModal);
document.getElementById('confirmDeleteBtn').addEventListener('click', confirmDelete);
// 모달 외부 클릭 시 닫기
document.getElementById('kuntaeModal').addEventListener('click', function(e) {
if (e.target === this) hideKuntaeModal();
});
document.getElementById('deleteModal').addEventListener('click', function(e) {
if (e.target === this) hideDeleteModal();
});
}
// 데이터 로드
async function loadData() {
const startDate = document.getElementById('startDate').value;
const endDate = document.getElementById('endDate').value;
if (!startDate || !endDate) {
alert('시작일과 종료일을 모두 입력해주세요.');
return;
}
if (new Date(startDate) > new Date(endDate)) {
alert('시작일은 종료일보다 늦을 수 없습니다.');
return;
}
showLoading(true);
try {
const response = await axios.get(`/Kuntae/GetList?sd=${startDate}&ed=${endDate}`);
if (response.data) {
currentData = response.data;
renderTable();
updateStatistics();
} else {
currentData = [];
renderTable();
}
} catch (error) {
console.error('데이터 로드 중 오류 발생:', error);
alert('데이터를 불러오는 중 오류가 발생했습니다.');
currentData = [];
renderTable();
} finally {
showLoading(false);
}
}
// 로딩 상태 표시
function showLoading(show) {
const searchBtn = document.getElementById('searchBtn');
const searchBtnText = document.getElementById('searchBtnText');
const searchBtnLoading = document.getElementById('searchBtnLoading');
const loadingRow = document.getElementById('loadingRow');
if (show) {
searchBtn.disabled = true;
searchBtnText.textContent = '조회 중...';
searchBtnLoading.classList.remove('hidden');
loadingRow.classList.remove('hidden');
} else {
searchBtn.disabled = false;
searchBtnText.textContent = '조회';
searchBtnLoading.classList.add('hidden');
loadingRow.classList.add('hidden');
}
}
// 테이블 렌더링
function renderTable() {
const tbody = document.getElementById('dataTableBody');
const noDataRow = document.getElementById('noDataRow');
// 기존 데이터 행 제거 (로딩, 노데이터 행 제외)
const existingRows = tbody.querySelectorAll('tr:not(#loadingRow):not(#noDataRow)');
existingRows.forEach(row => row.remove());
if (currentData.length === 0) {
noDataRow.classList.remove('hidden');
return;
}
noDataRow.classList.add('hidden');
currentData.forEach(item => {
const row = document.createElement('tr');
row.className = 'hover:bg-gray-50 cursor-pointer';
row.setAttribute('data-id', item.idx);
const startDate = item.sdate ? new Date(item.sdate) : null;
const endDate = item.edate ? new Date(item.edate) : null;
row.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.cate || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${startDate ? formatDate(startDate) : '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${endDate ? formatDate(endDate) : '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.uid || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.uname || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.term || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.termdr || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.drtime || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.crtime || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 max-w-xs truncate" title="${item.contents || ''}">${item.contents || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.tag || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">&nbsp;</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">&nbsp;</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">&nbsp;</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">&nbsp;</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.extcate || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.wuid || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${item.wdate || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<div class="flex space-x-2">
<button class="text-blue-600 hover:text-blue-800 edit-btn" data-id="${item.idx}">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg>
</button>
<button class="text-red-600 hover:text-red-800 delete-btn" data-id="${item.idx}">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
</svg>
</button>
</div>
</td>
`;
tbody.appendChild(row);
});
// 행 클릭 이벤트 추가
tbody.querySelectorAll('tr[data-id]').forEach(row => {
row.addEventListener('click', function(e) {
if (!e.target.closest('.edit-btn') && !e.target.closest('.delete-btn')) {
const id = this.getAttribute('data-id');
showEditModal(id);
}
});
});
// 편집 버튼 이벤트
tbody.querySelectorAll('.edit-btn').forEach(btn => {
btn.addEventListener('click', function(e) {
e.stopPropagation();
const id = this.getAttribute('data-id');
showEditModal(id);
});
});
// 삭제 버튼 이벤트
tbody.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', function(e) {
e.stopPropagation();
const id = this.getAttribute('data-id');
showDeleteModal(id);
});
});
}
// 날짜 포맷팅
function formatDate(date) {
return date.toLocaleDateString('ko-KR', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
}
// 근무시간 계산
function calculateWorkHours(item) {
if (!item.intime || !item.outtime) return '-';
try {
const inTime = new Date(`2000-01-01 ${item.intime}`);
const outTime = new Date(`2000-01-01 ${item.outtime}`);
if (outTime < inTime) {
outTime.setDate(outTime.getDate() + 1);
}
const diffMs = outTime - inTime;
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
const diffMinutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60));
return `${diffHours}시간 ${diffMinutes}`;
} catch (error) {
return '-';
}
}
// 상태 판단
function getStatus(item) {
if (!item.intime) return '결근';
if (!item.outtime) return '출근';
// 지각 판단 (예: 9시 이후 출근)
const inTime = new Date(`2000-01-01 ${item.intime}`);
const lateThreshold = new Date(`2000-01-01 09:00:00`);
if (inTime > lateThreshold) return '지각';
return '정상';
}
// 상태별 CSS 클래스
function getStatusClass(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';
case '출근': return 'bg-blue-100 text-blue-800';
default: return 'bg-gray-100 text-gray-800';
}
}
// 통계 업데이트
function updateStatistics() {
const totalDays = currentData.length;
const normalDays = currentData.filter(item => getStatus(item) === '정상').length;
const lateDays = currentData.filter(item => getStatus(item) === '지각').length;
const absentDays = currentData.filter(item => getStatus(item) === '결근').length;
document.getElementById('totalDays').textContent = totalDays;
document.getElementById('normalDays').textContent = normalDays;
document.getElementById('lateDays').textContent = lateDays;
document.getElementById('absentDays').textContent = absentDays;
}
// 근태 추가 모달 표시
function showAddModal() {
currentEditId = null;
document.getElementById('modalTitle').textContent = '근태 추가';
document.getElementById('editId').value = '';
document.getElementById('modalDate').value = new Date().toISOString().split('T')[0];
document.getElementById('modalInTime').value = '';
document.getElementById('modalOutTime').value = '';
document.getElementById('modalMemo').value = '';
document.getElementById('kuntaeModal').classList.remove('hidden');
}
// 근태 편집 모달 표시
function showEditModal(id) {
const item = currentData.find(data => (data.id || data.wdate) == id);
if (!item) {
alert('데이터를 찾을 수 없습니다.');
return;
}
currentEditId = id;
document.getElementById('modalTitle').textContent = '근태 편집';
document.getElementById('editId').value = id;
document.getElementById('modalDate').value = item.pdate ? new Date(item.pdate).toISOString().split('T')[0] : '';
document.getElementById('modalInTime').value = item.intime || '';
document.getElementById('modalOutTime').value = item.outtime || '';
document.getElementById('modalMemo').value = item.memo || '';
document.getElementById('kuntaeModal').classList.remove('hidden');
}
// 근태 모달 숨기기
function hideKuntaeModal() {
document.getElementById('kuntaeModal').classList.add('hidden');
currentEditId = null;
}
// 근태 저장
async function saveKuntae(e) {
e.preventDefault();
const formData = new FormData(e.target);
const data = {
id: formData.get('id'),
pdate: formData.get('pdate'),
intime: formData.get('intime'),
outtime: formData.get('outtime'),
memo: formData.get('memo')
};
if (!data.pdate) {
alert('날짜를 입력해주세요.');
return;
}
try {
const url = currentEditId ? '/Kuntae/Update' : '/Kuntae/Insert';
const method = currentEditId ? 'PUT' : 'POST';
const response = await axios({
method: method,
url: url,
data: data,
headers: {
'Content-Type': 'application/json'
}
});
if (response.data && response.data.success) {
alert(currentEditId ? '근태가 수정되었습니다.' : '근태가 추가되었습니다.');
hideKuntaeModal();
loadData(); // 목록 새로고침
} else {
alert(response.data?.message || '저장 중 오류가 발생했습니다.');
}
} catch (error) {
console.error('저장 중 오류 발생:', error);
alert('저장 중 오류가 발생했습니다.');
}
}
// 삭제 모달 표시
function showDeleteModal(id) {
const item = currentData.find(data => (data.id || data.wdate) == id);
if (!item) {
alert('데이터를 찾을 수 없습니다.');
return;
}
const date = new Date(item.pdate);
document.getElementById('deleteConfirmText').textContent =
`${formatDate(date)} 근태 데이터를 삭제하시겠습니까?`;
document.getElementById('confirmDeleteBtn').setAttribute('data-id', id);
document.getElementById('deleteModal').classList.remove('hidden');
}
// 삭제 모달 숨기기
function hideDeleteModal() {
document.getElementById('deleteModal').classList.add('hidden');
}
// 삭제 확인
async function confirmDelete() {
const id = document.getElementById('confirmDeleteBtn').getAttribute('data-id');
try {
const response = await axios.delete(`/Kuntae/Delete/${id}`);
if (response.data && response.data.success) {
alert('근태가 삭제되었습니다.');
hideDeleteModal();
loadData(); // 목록 새로고침
} else {
alert(response.data?.message || '삭제 중 오류가 발생했습니다.');
}
} catch (error) {
console.error('삭제 중 오류 발생:', error);
alert('삭제 중 오류가 발생했습니다.');
}
}
</script>
</body>
</html>