/* tkpurchase-partner-portal.js - Partner portal logic */ let portalSchedules = []; let portalCheckins = {}; let partnerCompanyId = null; async function loadMySchedules() { try { const r = await api('/schedules/my'); portalSchedules = r.data || []; } catch(e) { console.warn('Load schedules error:', e); portalSchedules = []; } } async function loadMyCheckins() { try { const r = await api('/checkins/my'); const list = r.data || []; portalCheckins = {}; list.forEach(c => { if (c.schedule_id) portalCheckins[c.schedule_id] = c; }); } catch(e) { console.warn('Load checkins error:', e); portalCheckins = {}; } } async function renderScheduleCards() { await Promise.all([loadMySchedules(), loadMyCheckins()]); const container = document.getElementById('scheduleCards'); const noMsg = document.getElementById('noScheduleMessage'); if (!portalSchedules.length) { container.innerHTML = ''; noMsg.classList.remove('hidden'); return; } noMsg.classList.add('hidden'); container.innerHTML = portalSchedules.map(s => { const checkin = portalCheckins[s.id]; const isCheckedIn = checkin && !checkin.check_out_time; const isCheckedOut = checkin && checkin.check_out_time; const hasReport = checkin && checkin.has_work_report; // Step indicators const step1Class = checkin ? 'text-emerald-600' : 'text-gray-400'; const step2Class = isCheckedIn || isCheckedOut ? 'text-emerald-600' : 'text-gray-400'; const step3Class = isCheckedOut ? 'text-emerald-600' : 'text-gray-400'; return `

${escapeHtml(s.workplace_name || '작업장 미지정')}

${formatDate(s.start_date) === formatDate(s.end_date) ? formatDate(s.start_date) : formatDate(s.start_date) + ' ~ ' + formatDate(s.end_date)}
${s.work_description ? `

${escapeHtml(s.work_description)}

` : ''}
예상 ${s.expected_workers || 0}명 ${s.notes ? `${escapeHtml(s.notes)}` : ''}
1. 작업 시작
2. 업무현황
3. 작업 종료
${!checkin ? `

작업 시작

` : `
체크인 완료 (${formatTime(checkin.check_in_time)}) · ${checkin.actual_worker_count || 0}명
`}
${isCheckedIn ? `

업무현황 입력

업무현황을 먼저 저장한 후 작업을 종료하세요.

` : ''} ${isCheckedOut ? `
작업 종료 완료 (${formatTime(checkin.check_out_time)})
${hasReport ? '
업무현황 제출 완료
' : ''}
` : ''}
`; }).join(''); } async function doCheckIn(scheduleId) { const workerCount = parseInt(document.getElementById('checkinWorkers_' + scheduleId).value) || 1; const workerNames = document.getElementById('checkinNames_' + scheduleId).value.trim(); const body = { schedule_id: scheduleId, actual_worker_count: workerCount, worker_names: workerNames || null }; try { await api('/checkins', { method: 'POST', body: JSON.stringify(body) }); showToast('체크인 완료'); renderScheduleCards(); } catch(e) { showToast(e.message || '체크인 실패', 'error'); } } async function submitWorkReport(checkinId, scheduleId) { const workContent = document.getElementById('reportContent_' + checkinId).value.trim(); if (!workContent) { showToast('작업내용을 입력하세요', 'error'); return; } const body = { checkin_id: checkinId, schedule_id: scheduleId, actual_workers: parseInt(document.getElementById('reportWorkers_' + checkinId).value) || 0, work_content: workContent, progress_rate: parseInt(document.getElementById('reportProgress_' + checkinId).value) || 0, issues: document.getElementById('reportIssues_' + checkinId).value.trim() || null, next_plan: document.getElementById('reportNextPlan_' + checkinId).value.trim() || null }; try { await api('/work-reports', { method: 'POST', body: JSON.stringify(body) }); showToast('업무현황이 저장되었습니다'); renderScheduleCards(); } catch(e) { showToast(e.message || '저장 실패', 'error'); } } async function doCheckOut(checkinId) { if (!confirm('작업을 종료하시겠습니까? 업무현황을 먼저 저장했는지 확인하세요.')) return; try { await api('/checkins/' + checkinId + '/checkout', { method: 'PUT' }); showToast('작업 종료 (체크아웃) 완료'); renderScheduleCards(); } catch(e) { showToast(e.message || '체크아웃 실패', 'error'); } } function initPartnerPortal() { if (!initAuth()) return; // Check if partner account const token = getToken(); const decoded = decodeToken(token); if (!decoded || !decoded.partner_company_id) { location.href = '/'; return; } partnerCompanyId = decoded.partner_company_id; document.getElementById('welcomeCompanyName').textContent = decoded.partner_company_name || decoded.name || '협력업체'; renderScheduleCards(); }