admin 계정으로 정비사 처리이력 접근 시 '직접 등록한 조치만 표시된다'는 안내와 관리자 신고 목록 링크 제공 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
155 lines
6.3 KiB
HTML
155 lines
6.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>처리 이력</title>
|
|
<link rel="stylesheet" href="/css/style.css">
|
|
<style>
|
|
.history-card {
|
|
border: 1px solid var(--gray2);
|
|
border-radius: 10px;
|
|
padding: 14px 16px;
|
|
margin-bottom: 10px;
|
|
background: white;
|
|
cursor: pointer;
|
|
transition: box-shadow .15s;
|
|
}
|
|
.history-card:hover { box-shadow: 0 3px 12px rgba(0,0,0,.1); }
|
|
.history-card.approved { border-left: 4px solid var(--green); }
|
|
.history-card.pending { border-left: 4px solid var(--orange); }
|
|
.hc-top { display:flex; justify-content:space-between; align-items:flex-start; gap:10px; margin-bottom:8px; }
|
|
.hc-title { font-size:14px; font-weight:700; color:var(--navy); }
|
|
.hc-meta { font-size:12px; color:var(--gray4); margin-top:3px; }
|
|
.hc-tags { display:flex; flex-wrap:wrap; gap:5px; margin-top:6px; }
|
|
.hc-tag { font-size:11px; padding:2px 8px; border-radius:10px; background:var(--gray1); color:var(--text2); border:1px solid var(--gray2); }
|
|
.badge-approved { background:#D1FAE5; color:#065F46; font-size:11px; font-weight:700; padding:3px 10px; border-radius:10px; white-space:nowrap; }
|
|
.badge-pending { background:#FEF3C7; color:#92400E; font-size:11px; font-weight:700; padding:3px 10px; border-radius:10px; white-space:nowrap; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<nav class="nav">
|
|
<span class="nav-brand">⚡ EV AS 관리</span>
|
|
<div id="navUser"></div>
|
|
</nav>
|
|
<div class="mech-tab-bar">
|
|
<a href="/pages/mechanic/dashboard.html">📋<span>AS 목록</span></a>
|
|
<a href="/pages/mechanic/scan.html">📷<span>QR 스캔</span></a>
|
|
<a href="/pages/mechanic/history.html" class="active">🗂<span>처리 이력</span></a>
|
|
</div>
|
|
<div class="layout">
|
|
<div class="sidebar">
|
|
<div class="sidebar-section">메뉴</div>
|
|
<a href="/pages/mechanic/dashboard.html">📋 AS 목록</a>
|
|
<a href="/pages/mechanic/scan.html">📷 QR 스캔</a>
|
|
<a href="/pages/mechanic/history.html" class="active">🗂 처리 이력</a>
|
|
</div>
|
|
<div class="main">
|
|
<h2 style="font-size:18px;font-weight:700;color:var(--navy);margin-bottom:18px">내 처리 이력</h2>
|
|
|
|
<div style="display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap;">
|
|
<select id="fStatus" style="width:auto">
|
|
<option value="">전체</option>
|
|
<option value="approved">승인 완료</option>
|
|
<option value="pending">승인 대기</option>
|
|
</select>
|
|
<select id="fResult" style="width:auto">
|
|
<option value="">전체 처리상태</option>
|
|
<option value="done">완료</option>
|
|
<option value="in_progress">진행중</option>
|
|
<option value="waiting">부품대기</option>
|
|
<option value="revisit">재방문</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div id="loading" class="alert alert-info">이력을 불러오는 중...</div>
|
|
<div id="error" class="alert alert-danger" style="display:none"></div>
|
|
<div id="list"></div>
|
|
<div id="empty" class="alert alert-info" style="display:none">처리 이력이 없습니다.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/js/api.js"></script>
|
|
<script src="/js/auth.js"></script>
|
|
<script>
|
|
Auth.require(['mechanic','admin']);
|
|
Auth.renderNav(document.getElementById('navUser'));
|
|
|
|
// admin 계정으로 접근 시 안내
|
|
if (Auth.role() === 'admin') {
|
|
document.querySelector('.main').insertAdjacentHTML('afterbegin',
|
|
`<div class="alert" style="background:#FFF8E6;border:1px solid #FFD600;border-radius:8px;padding:12px 16px;margin-bottom:16px;font-size:13px;">
|
|
⚠️ 현재 <strong>관리자(${Auth.name()})</strong> 계정으로 접속 중입니다.
|
|
처리이력은 해당 계정이 직접 등록한 조치만 표시됩니다.
|
|
정비사 이력 전체는 <a href="/pages/admin/reports.html" style="color:var(--accent);font-weight:700">관리자 신고 목록</a>에서 확인하세요.
|
|
</div>`);
|
|
}
|
|
|
|
const RESULT_LABEL = {
|
|
done: '✅ 완료',
|
|
in_progress: '🔧 진행중',
|
|
waiting: '⏳ 부품대기',
|
|
revisit: '🔄 재방문',
|
|
};
|
|
|
|
let allRepairs = [];
|
|
|
|
async function load() {
|
|
document.getElementById('loading').style.display = 'block';
|
|
document.getElementById('error').style.display = 'none';
|
|
try {
|
|
allRepairs = await API.get('/repairs/my');
|
|
render();
|
|
} catch(e) {
|
|
document.getElementById('error').textContent = '이력을 불러오지 못했습니다: ' + e.message;
|
|
document.getElementById('error').style.display = 'block';
|
|
} finally {
|
|
document.getElementById('loading').style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function render() {
|
|
const fStatus = document.getElementById('fStatus').value;
|
|
const fResult = document.getElementById('fResult').value;
|
|
|
|
let list = allRepairs;
|
|
if (fStatus === 'approved') list = list.filter(r => r.approved_at);
|
|
if (fStatus === 'pending') list = list.filter(r => !r.approved_at);
|
|
if (fResult) list = list.filter(r => r.result_status === fResult);
|
|
|
|
document.getElementById('empty').style.display = list.length ? 'none' : 'block';
|
|
document.getElementById('list').innerHTML = list.map(r => {
|
|
const isApproved = !!r.approved_at;
|
|
const dt = r.completed_at
|
|
? new Date(r.completed_at).toLocaleDateString('ko-KR', {year:'numeric',month:'2-digit',day:'2-digit'})
|
|
: '';
|
|
return `
|
|
<div class="history-card ${isApproved ? 'approved' : 'pending'}"
|
|
onclick="location.href='/pages/mechanic/repair.html?repair_id=${r.id}'">
|
|
<div class="hc-top">
|
|
<div>
|
|
<div class="hc-title">
|
|
${r.station_name || '-'} · ${r.charger_id || '-'}
|
|
</div>
|
|
<div class="hc-meta">${r.charger_name || ''} · 신고 ${r.report_count}건 · ${dt}</div>
|
|
</div>
|
|
<div style="display:flex;flex-direction:column;align-items:flex-end;gap:4px;">
|
|
<span class="${isApproved ? 'badge-approved' : 'badge-pending'}">
|
|
${isApproved ? '✅ 승인완료' : '⏳ 승인대기'}
|
|
</span>
|
|
<span style="font-size:11px;color:var(--gray4)">${RESULT_LABEL[r.result_status] || r.result_status}</span>
|
|
</div>
|
|
</div>
|
|
<div class="hc-tags">
|
|
${(r.repair_types||[]).map(t => `<span class="hc-tag">${t}</span>`).join('')}
|
|
</div>
|
|
</div>`;
|
|
}).join('');
|
|
}
|
|
|
|
document.getElementById('fStatus').onchange = render;
|
|
document.getElementById('fResult').onchange = render;
|
|
load();
|
|
</script>
|
|
</body>
|
|
</html>
|