diff --git a/system1-factory/web/css/monthly-comparison.css b/system1-factory/web/css/monthly-comparison.css
index 6e8dc21..17d648c 100644
--- a/system1-factory/web/css/monthly-comparison.css
+++ b/system1-factory/web/css/monthly-comparison.css
@@ -303,3 +303,18 @@
.ds-link { color: #2563eb; font-size: 0.8rem; text-decoration: underline; }
@media (max-width: 480px) { body { max-width: 480px; margin: 0 auto; } }
+
+/* Inline Edit */
+.mc-edit-btn { background: none; border: none; color: #9ca3af; cursor: pointer; font-size: 12px; padding: 2px 6px; margin-left: auto; }
+.mc-edit-btn:hover { color: #2563eb; }
+.mc-attend-row { display: flex; align-items: center; }
+.mc-edit-form { display: flex; flex-direction: column; gap: 6px; padding: 4px 0; }
+.mc-edit-row { display: flex; align-items: center; gap: 6px; font-size: 13px; }
+.mc-edit-row label { width: 36px; font-weight: 600; color: #6b7280; font-size: 12px; }
+.mc-edit-input { width: 60px; padding: 4px 6px; border: 1px solid #d1d5db; border-radius: 6px; font-size: 13px; text-align: center; }
+.mc-edit-select { padding: 4px 6px; border: 1px solid #d1d5db; border-radius: 6px; font-size: 13px; flex: 1; }
+.mc-edit-actions { display: flex; gap: 6px; margin-top: 2px; }
+.mc-edit-save { padding: 4px 12px; background: #10b981; color: white; border: none; border-radius: 6px; font-size: 12px; cursor: pointer; }
+.mc-edit-save:hover { background: #059669; }
+.mc-edit-cancel { padding: 4px 12px; background: #e5e7eb; color: #374151; border: none; border-radius: 6px; font-size: 12px; cursor: pointer; }
+.mc-edit-cancel:hover { background: #d1d5db; }
diff --git a/system1-factory/web/js/monthly-comparison.js b/system1-factory/web/js/monthly-comparison.js
index ff6c2e9..187b24f 100644
--- a/system1-factory/web/js/monthly-comparison.js
+++ b/system1-factory/web/js/monthly-comparison.js
@@ -253,9 +253,11 @@ function renderDailyList(records) {
if (r.attendance) {
const vacInfo = r.attendance.vacation_type ? ` (${r.attendance.vacation_type})` : '';
- attendLine = `
근태관리: ${r.attendance.total_work_hours}h (${escHtml(r.attendance.attendance_type)}${vacInfo})
`;
+ const editBtn = currentMode === 'detail' ? `` : '';
+ attendLine = `근태관리: ${r.attendance.total_work_hours}h (${escHtml(r.attendance.attendance_type)}${vacInfo})${editBtn}
`;
} else if (r.status !== 'holiday') {
- attendLine = '근태관리: 미입력
';
+ const addBtn = currentMode === 'detail' ? `` : '';
+ attendLine = `근태관리: 미입력${addBtn}
`;
}
if (r.status === 'mismatch' && r.hours_diff) {
@@ -549,6 +551,71 @@ function showToast(msg, type) {
setTimeout(() => t.remove(), 3000);
}
+// ===== Inline Attendance Edit (detail mode) =====
+function getAttendanceTypeId(hours, vacTypeId) {
+ if (vacTypeId) return 4; // VACATION
+ if (hours >= 8) return 1; // REGULAR
+ if (hours > 0) return 3; // PARTIAL
+ return 0;
+}
+
+function editAttendance(date, currentHours, currentVacTypeId) {
+ const el = document.getElementById('attend-' + date);
+ if (!el) return;
+ const vacTypeId = currentVacTypeId === 'null' || currentVacTypeId === null ? '' : currentVacTypeId;
+ el.innerHTML = `
+
+ `;
+}
+
+function onVacTypeChange(date) {
+ const vacType = document.getElementById('editVacType-' + date).value;
+ const hoursInput = document.getElementById('editHours-' + date);
+ if (vacType === '1') hoursInput.value = '0'; // 연차 → 0시간
+ else if (vacType === '2') hoursInput.value = '4'; // 반차 → 4시간
+ else if (vacType === '3') hoursInput.value = '6'; // 반반차 → 6시간
+}
+
+async function saveAttendance(date) {
+ const hours = parseFloat(document.getElementById('editHours-' + date).value) || 0;
+ const vacTypeVal = document.getElementById('editVacType-' + date).value;
+ const vacTypeId = vacTypeVal ? parseInt(vacTypeVal) : null;
+ const attTypeId = getAttendanceTypeId(hours, vacTypeId);
+
+ try {
+ await window.apiCall('/attendance/records', 'POST', {
+ record_date: date,
+ user_id: currentUserId,
+ total_work_hours: hours,
+ vacation_type_id: vacTypeId,
+ attendance_type_id: attTypeId
+ });
+ showToast('근태 수정 완료', 'success');
+ await loadData(); // 전체 새로고침
+ } catch (e) {
+ showToast('저장 실패: ' + (e.message || e), 'error');
+ }
+}
+
// ESC로 모달 닫기
document.addEventListener('keydown', e => {
if (e.key === 'Escape') closeRejectModal();
diff --git a/system1-factory/web/pages/attendance/monthly-comparison.html b/system1-factory/web/pages/attendance/monthly-comparison.html
index 7e8b52f..0a72520 100644
--- a/system1-factory/web/pages/attendance/monthly-comparison.html
+++ b/system1-factory/web/pages/attendance/monthly-comparison.html
@@ -8,7 +8,7 @@
-
+