154 lines
4.5 KiB
JavaScript
154 lines
4.5 KiB
JavaScript
// /js/daily-issue.js
|
|
|
|
import { API, getAuthHeaders } from '/js/api-config.js';
|
|
|
|
const dateInput = document.getElementById('dateSelect');
|
|
const projectSel = document.getElementById('projectSelect');
|
|
const issueTypeSel = document.getElementById('issueTypeSelect');
|
|
const timeStartSel = document.getElementById('timeStart');
|
|
const timeEndSel = document.getElementById('timeEnd');
|
|
const workerList = document.getElementById('workerList');
|
|
const form = document.getElementById('issueForm');
|
|
|
|
// 오늘 날짜 기본 설정
|
|
const today = new Date().toISOString().split('T')[0];
|
|
dateInput.value = today;
|
|
|
|
// 시간 옵션 생성
|
|
function populateTimeOptions(startEl, endEl) {
|
|
for (let h = 0; h < 24; h++) {
|
|
for (let m of [0, 30]) {
|
|
const time = `${String(h).padStart(2, '0')}:${m === 0 ? '00' : '30'}`;
|
|
const option = new Option(time, time);
|
|
startEl.appendChild(option);
|
|
endEl.appendChild(option.cloneNode(true));
|
|
}
|
|
}
|
|
}
|
|
populateTimeOptions(timeStartSel, timeEndSel);
|
|
|
|
// 📌 프로젝트 목록
|
|
async function loadProjects() {
|
|
try {
|
|
const res = await fetch(`${API}/projects`, {
|
|
headers: getAuthHeaders()
|
|
});
|
|
const data = await res.json();
|
|
if (Array.isArray(data)) {
|
|
data.forEach(p => {
|
|
projectSel.appendChild(new Option(p.project_name, p.project_id));
|
|
});
|
|
}
|
|
} catch (err) {
|
|
console.error('프로젝트 로딩 오류:', err);
|
|
}
|
|
}
|
|
|
|
// 📌 이슈 유형 목록
|
|
async function loadIssueTypes() {
|
|
try {
|
|
const res = await fetch(`${API}/issue-types`, {
|
|
headers: getAuthHeaders()
|
|
});
|
|
const data = await res.json();
|
|
if (Array.isArray(data)) {
|
|
data.forEach(t => {
|
|
issueTypeSel.appendChild(new Option(`${t.category}:${t.subcategory}`, t.issue_type_id));
|
|
});
|
|
}
|
|
} catch (err) {
|
|
console.error('이슈 타입 로딩 오류:', err);
|
|
}
|
|
}
|
|
|
|
// 📌 작업자 목록
|
|
async function loadWorkers() {
|
|
const d = dateInput.value;
|
|
workerList.textContent = '로딩 중...';
|
|
try {
|
|
let res = await fetch(`${API}/workreports/date/${d}`, {
|
|
headers: getAuthHeaders()
|
|
});
|
|
let reports = await res.json();
|
|
|
|
if (!reports.length) {
|
|
const wRes = await fetch(`${API}/workers`, {
|
|
headers: getAuthHeaders()
|
|
});
|
|
const allWorkers = await wRes.json();
|
|
if (Array.isArray(allWorkers)) {
|
|
reports = allWorkers.map(w => ({
|
|
worker_id: w.worker_id,
|
|
worker_name: w.worker_name
|
|
}));
|
|
}
|
|
}
|
|
|
|
const seen = new Set();
|
|
workerList.innerHTML = '';
|
|
reports.forEach(r => {
|
|
if (!seen.has(r.worker_id)) {
|
|
seen.add(r.worker_id);
|
|
const btn = document.createElement('button');
|
|
btn.type = 'button';
|
|
btn.className = 'btn';
|
|
btn.textContent = r.worker_name;
|
|
btn.dataset.id = r.worker_id;
|
|
btn.addEventListener('click', () => btn.classList.toggle('selected'));
|
|
workerList.appendChild(btn);
|
|
}
|
|
});
|
|
} catch (err) {
|
|
console.error('👿 작업자 로딩 오류:', err);
|
|
workerList.textContent = '작업자 로딩 실패';
|
|
}
|
|
}
|
|
|
|
// 📌 초기 실행
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
loadProjects();
|
|
loadIssueTypes();
|
|
loadWorkers();
|
|
|
|
dateInput.addEventListener('change', loadWorkers);
|
|
|
|
form.addEventListener('submit', async e => {
|
|
e.preventDefault();
|
|
const workerIds = [...workerList.querySelectorAll('.btn.selected')].map(b => b.dataset.id);
|
|
if (!workerIds.length) return alert('작업자를 선택하세요.');
|
|
|
|
const projectId = projectSel.value;
|
|
const issueTypeId = issueTypeSel.value;
|
|
const start = timeStartSel.value;
|
|
const end = timeEndSel.value;
|
|
|
|
if (!projectId || !issueTypeId || !start || !end) return alert('모든 값을 입력하세요.');
|
|
if (end <= start) return alert('종료 시간은 시작 시간 이후여야 합니다.');
|
|
|
|
const payload = {
|
|
date: dateInput.value,
|
|
worker_id: workerIds,
|
|
project_id: projectId,
|
|
start_time: timeStartSel.value,
|
|
end_time: timeEndSel.value,
|
|
issue_type_id: issueTypeId
|
|
};
|
|
|
|
try {
|
|
const res = await fetch(`${API}/issue-reports`, {
|
|
method: 'POST',
|
|
headers: getAuthHeaders(),
|
|
body: JSON.stringify(payload)
|
|
});
|
|
const json = await res.json();
|
|
if (res.ok && json.success) {
|
|
alert('✅ 등록 완료!');
|
|
loadWorkers();
|
|
} else {
|
|
alert(json.error || '등록 실패');
|
|
}
|
|
} catch (err) {
|
|
alert('🚨 서버 오류: ' + err.message);
|
|
}
|
|
});
|
|
}); |