Spaces:
Running
Running
| /* βββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| SentiMeter β history.js | |
| Riwayat Analisis Core Logic | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| ; | |
| SM.injectLayout('nav-history'); | |
| document.addEventListener('DOMContentLoaded', () => { | |
| renderHistory(); | |
| }); | |
| function renderHistory() { | |
| const container = document.getElementById('historyContainer'); | |
| const history = SM.getHistory(); | |
| const badge = document.getElementById('histCount'); | |
| if (badge) badge.textContent = history.length || 0; | |
| if (!history || history.length === 0) { | |
| container.innerHTML = ` | |
| <div class="history-empty reveal-up" style="--d:100ms"> | |
| <h3>Belum Ada Riwayat Analisis</h3> | |
| <p>Log aktivitas analisis Anda akan muncul di sini. Silakan mulai dengan mengunggah dan memproses file CSV pertama Anda.</p> | |
| <a href="upload" class="btn btn-primary btn-lg empty-cta">Mulai Analisis Sekarang</a> | |
| </div> | |
| `; | |
| return; | |
| } | |
| let html = ''; | |
| history.forEach((h, index) => { | |
| const d = h.data; | |
| const meta = d.meta; | |
| const dateStr = new Date(h.savedAt).toLocaleDateString('id-ID', { | |
| day: 'numeric', month: 'long', year: 'numeric', | |
| hour: '2-digit', minute: '2-digit' | |
| }); | |
| const totalPos = d.rows.filter(r => r.sentiment === 'Positif').length; | |
| const totalNeg = d.rows.filter(r => r.sentiment === 'Negatif').length; | |
| const totalNeu = d.rows.filter(r => r.sentiment === 'Netral').length; | |
| const total = meta.totalRows || 1; | |
| const pPos = ((totalPos / total) * 100).toFixed(1); | |
| const pNeg = ((totalNeg / total) * 100).toFixed(1); | |
| const pNeu = ((totalNeu / total) * 100).toFixed(1); | |
| html += ` | |
| <div class="hist-card" style="--d:${index * 80}ms"> | |
| <div class="hist-card-top"> | |
| <div class="hist-info"> | |
| <div class="hist-filename">${meta.filename || 'data.csv'}</div> | |
| <div class="hist-meta"> | |
| <span class="hist-date">Dianalisis pada ${dateStr}</span> | |
| </div> | |
| </div> | |
| <div class="hist-actions"> | |
| <button class="btn btn-primary btn-sm" onclick="viewHistory('${h.id}')">Lihat Dashboard</button> | |
| <button class="btn btn-outline btn-sm" style="color:var(--neg);border-color:var(--neg-d)" onclick="removeHistory('${h.id}')">Hapus</button> | |
| </div> | |
| </div> | |
| <div class="hist-visual"> | |
| <div class="hist-bar-outer"> | |
| <div class="hist-bar-segment pos" style="width: ${pPos}%"></div> | |
| <div class="hist-bar-segment neu" style="width: ${pNeu}%"></div> | |
| <div class="hist-bar-segment neg" style="width: ${pNeg}%"></div> | |
| </div> | |
| </div> | |
| <div class="hist-stats"> | |
| <div class="hist-stat-box"> | |
| <span class="hist-stat-label">Total Data</span> | |
| <span class="hist-stat-val">${SM.fmt(meta.totalRows)} <span class="hist-stat-unit">Baris</span></span> | |
| </div> | |
| <div class="hist-stat-box"> | |
| <span class="hist-stat-label">Positif</span> | |
| <span class="hist-stat-val pos">${pPos}%</span> | |
| </div> | |
| <div class="hist-stat-box"> | |
| <span class="hist-stat-label">Netral</span> | |
| <span class="hist-stat-val neu">${pNeu}%</span> | |
| </div> | |
| <div class="hist-stat-box"> | |
| <span class="hist-stat-label">Negatif</span> | |
| <span class="hist-stat-val neg">${pNeg}%</span> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| }); | |
| container.innerHTML = html; | |
| } | |
| window.viewHistory = function(id) { | |
| if (SM.loadHistoryItem(id)) { | |
| SM.showToast('Data riwayat berhasil dimuat.'); | |
| setTimeout(() => { | |
| window.location.href = 'dashboard'; | |
| }, 500); | |
| } else { | |
| SM.showToast('Gagal memuat riwayat data.', 'error'); | |
| } | |
| }; | |
| window.removeHistory = function(id) { | |
| const history = SM.getHistory(); | |
| const item = history.find(h => h.id === id); | |
| const filename = item ? item.data.meta.filename : 'data'; | |
| SM.showModal({ | |
| title: 'Hapus Riwayat?', | |
| message: `Apakah Anda yakin ingin menghapus riwayat analisis untuk file <b>${SM.esc(filename)}</b>? Tindakan ini tidak dapat dibatalkan.`, | |
| type: 'error', | |
| confirmText: 'Hapus Riwayat', | |
| cancelText: 'Batal', | |
| showCancel: true, | |
| isDanger: true, | |
| onConfirm: () => { | |
| SM.deleteHistoryItem(id); | |
| renderHistory(); | |
| SM.injectLayout('nav-history'); // Refresh sidebar state | |
| SM.showToast('Riwayat berhasil dihapus', 'success'); | |
| }, | |
| onCancel: () => { | |
| // Do nothing, just close | |
| } | |
| }); | |
| }; | |