신고일시 앞에 발생일시(occurred_at) 컬럼 추가. 미입력 시 '-' 표시. 관리자·옵저버 신고 목록·대시보드 모두 반영. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
105 lines
4.5 KiB
HTML
105 lines
4.5 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>
|
|
.ro-badge{display:inline-block;padding:2px 10px;border-radius:10px;font-size:11px;font-weight:700;background:#EDE9FE;color:#5B21B6;margin-left:8px;vertical-align:middle;}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<nav class="nav">
|
|
<span class="nav-brand">⚡ EV AS 관리 <span class="ro-badge">👁 읽기전용</span></span>
|
|
<div id="navUser"></div>
|
|
</nav>
|
|
|
|
<div class="layout">
|
|
<div class="sidebar">
|
|
<div class="sidebar-section">메뉴</div>
|
|
<a href="/pages/observer/dashboard.html">📊 현황 대시보드</a>
|
|
<a href="/pages/observer/reports.html" class="active">📋 신고 목록</a>
|
|
</div>
|
|
|
|
<div class="main">
|
|
<div class="card">
|
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;flex-wrap:wrap;gap:8px;">
|
|
<div class="card-title" style="margin:0">📋 신고 목록 <span id="totalBadge" style="font-size:12px;color:var(--gray4);font-weight:400"></span></div>
|
|
</div>
|
|
|
|
<!-- 필터 -->
|
|
<div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px;">
|
|
<select id="fStatus" onchange="load()" style="padding:7px 10px;border:1px solid var(--gray3);border-radius:6px;font-size:13px;font-family:inherit;">
|
|
<option value="">전체 상태</option>
|
|
<option value="pending_approval">승인대기</option>
|
|
<option value="pending">접수</option>
|
|
<option value="in_progress">처리중</option>
|
|
<option value="waiting">부품대기</option>
|
|
<option value="revisit">재방문</option>
|
|
<option value="done">완료</option>
|
|
<option value="closed">상황종료</option>
|
|
</select>
|
|
<input type="text" id="fCharger" placeholder="충전기ID" style="padding:7px 10px;border:1px solid var(--gray3);border-radius:6px;font-size:13px;width:130px" oninput="render()">
|
|
<input type="text" id="fStation" placeholder="충전소명" style="padding:7px 10px;border:1px solid var(--gray3);border-radius:6px;font-size:13px;width:130px" oninput="render()">
|
|
</div>
|
|
|
|
<div class="tbl-wrap">
|
|
<table>
|
|
<thead><tr>
|
|
<th>접수번호</th><th>충전기ID</th><th>충전소명</th><th>CPO</th>
|
|
<th>문제유형</th><th>에러코드</th><th>발생일시</th><th>신고일시</th>
|
|
<th>정비사</th><th>조치완료</th><th>상태</th>
|
|
</tr></thead>
|
|
<tbody id="tbody"></tbody>
|
|
</table>
|
|
<div id="empty" style="display:none;text-align:center;padding:40px;color:var(--gray4);font-size:13px">신고 내역이 없습니다.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/js/api.js"></script>
|
|
<script src="/js/auth.js"></script>
|
|
<script>
|
|
Auth.require(['observer', 'admin']);
|
|
Auth.renderNav(document.getElementById('navUser'));
|
|
|
|
let _allReports = [];
|
|
|
|
async function load() {
|
|
const status = document.getElementById('fStatus').value;
|
|
try {
|
|
_allReports = await API.get('/reports' + (status ? '?status=' + status : ''));
|
|
} catch(e) { _allReports = []; }
|
|
render();
|
|
}
|
|
|
|
function render() {
|
|
const cid = document.getElementById('fCharger').value.trim().toLowerCase();
|
|
const station = document.getElementById('fStation').value.trim().toLowerCase();
|
|
let rows = _allReports;
|
|
if (cid) rows = rows.filter(r => r.charger_id?.toLowerCase().includes(cid));
|
|
if (station) rows = rows.filter(r => r.station_name?.toLowerCase().includes(station));
|
|
|
|
document.getElementById('totalBadge').textContent = `(${rows.length}건)`;
|
|
const tbody = document.getElementById('tbody');
|
|
const empty = document.getElementById('empty');
|
|
if (!rows.length) { tbody.innerHTML = ''; empty.style.display = 'block'; return; }
|
|
empty.style.display = 'none';
|
|
tbody.innerHTML = rows.map(r => `
|
|
<tr style="cursor:default">
|
|
<td>#${r.id}</td>
|
|
<td><strong>${r.charger_id}</strong></td>
|
|
<td>${r.station_name || '-'}</td>
|
|
<td>${r.cpo_name || '-'}</td>
|
|
<td>${(r.issue_types || []).join(', ') || '-'}</td>
|
|
<td>${r.error_code || '-'}</td>
|
|
<td>${r.occurred_at ? Auth.fmtDt(r.occurred_at) : '<span style="color:var(--gray4)">-</span>'}</td>
|
|
<td>${Auth.fmtDt(r.reported_at)}</td>
|
|
<td>${r.mechanic_name || '-'}</td>
|
|
<td>${r.mechanic_name && r.status === 'done' ? '완료' : '-'}</td>
|
|
<td>${Auth.statusBadge(r.status)}</td>
|
|
</tr>`).join('');
|
|
}
|
|
|
|
load();
|
|
</script>
|
|
</body></html>
|