i18n (Phase C batch 6): settings(JS), mikrotik, discounts, collector_payments, attendance ID/EN

This commit is contained in:
oxpoe committed 2026-10-09 07:32:48 +07:00
1 parent fd13f3fa1b
commit 6ed6945970
7 files changed
+204 -72

No files matched your search

+20 -20
View File
@@ -131,34 +131,34 @@
<div class="stat-grid" style="grid-template-columns:repeat(4,1fr)">
<div class="sc p">
<i class="bi bi-people sc-icon"></i>
<div class="sc-label">Total Karyawan</div>
<div class="sc-label"><%= t('admin.att.total_staff','Total Karyawan') %></div>
<div class="sc-val"><%= totalAll %></div>
<div class="sc-sub">Hari ini</div>
<div class="sc-sub"><%= t('admin.att.today','Hari ini') %></div>
</div>
<div class="sc s">
<i class="bi bi-check-circle sc-icon"></i>
<div class="sc-label">Sedang Bekerja</div>
<div class="sc-label"><%= t('admin.att.working','Sedang Bekerja') %></div>
<div class="sc-val"><%= checkedInAll %></div>
<div class="sc-sub">Check-in</div>
</div>
<div class="sc p">
<i class="bi bi-door-open sc-icon"></i>
<div class="sc-label">Sudah Pulang</div>
<div class="sc-label"><%= t('admin.att.checked_out','Sudah Pulang') %></div>
<div class="sc-val"><%= checkedOutAll %></div>
<div class="sc-sub">Check-out</div>
</div>
<div class="sc d">
<i class="bi bi-clock-history sc-icon"></i>
<div class="sc-label">Terlambat</div>
<div class="sc-label"><%= t('admin.att.late','Terlambat') %></div>
<div class="sc-val"><%= lateCheckIns.length %></div>
<div class="sc-sub">Setelah 08:30</div>
<div class="sc-sub"><%= t('admin.att.after_0830','Setelah 08:30') %></div>
</div>
</div>
<!-- Breakdown by Type -->
<div class="stat-grid" style="grid-template-columns:repeat(4,1fr);margin-top:16px">
<div class="sc" style="border-left:3px solid #3b82f6">
<div class="sc-label"><i class="bi bi-person-workspace"></i> Teknisi</div>
<div class="sc-label"><i class="bi bi-person-workspace"></i> <%= t('admin.att.technician','Teknisi') %></div>
<div class="sc-val"><%= techStats.total || 0 %></div>
<div class="sc-sub">
<span style="color:#22c55e"><%= techStats.checked_in || 0 %> aktif</span> •
@@ -174,7 +174,7 @@
</div>
</div>
<div class="sc" style="border-left:3px solid #22c55e">
<div class="sc-label"><i class="bi bi-cash-coin"></i> Kasir</div>
<div class="sc-label"><i class="bi bi-cash-coin"></i> <%= t('admin.att.cashier','Kasir') %></div>
<div class="sc-val"><%= cashierStats.total || 0 %></div>
<div class="sc-sub">
<span style="color:#22c55e"><%= cashierStats.checked_in || 0 %> aktif</span> •
@@ -195,7 +195,7 @@
<% if (lateCheckIns.length > 0) { %>
<div class="card" style="margin-top:20px;border-left:3px solid #ef4444">
<div class="card-hd">
<h6><i class="bi bi-exclamation-triangle"></i> Terlambat Check-in (<%= lateCheckIns.length %>)</h6>
<h6><i class="bi bi-exclamation-triangle"></i> <%= t('admin.att.late_checkin','Terlambat Check-in') %> (<%= lateCheckIns.length %>)</h6>
</div>
<div class="tbl-wrap">
<table class="dtbl">
@@ -203,8 +203,8 @@
<tr>
<th><%= t('pwa.field.name','Nama') %></th>
<th><%= t('common.type','Tipe') %></th>
<th>Waktu Check-in</th>
<th>Terlambat</th>
<th><%= t('admin.att.checkin_time','Waktu Check-in') %></th>
<th><%= t('admin.att.late','Terlambat') %></th>
</tr>
</thead>
<tbody>
@@ -231,7 +231,7 @@
<% if (notCheckedOut.length > 0) { %>
<div class="card" style="margin-top:20px;border-left:3px solid #f59e0b">
<div class="card-hd">
<h6><i class="bi bi-bell"></i> Belum Check-out (<%= notCheckedOut.length %>)</h6>
<h6><i class="bi bi-bell"></i> <%= t('admin.att.not_checkout','Belum Check-out') %> (<%= notCheckedOut.length %>)</h6>
</div>
<div class="tbl-wrap">
<table class="dtbl">
@@ -240,7 +240,7 @@
<th><%= t('pwa.field.name','Nama') %></th>
<th><%= t('common.type','Tipe') %></th>
<th>Check-in</th>
<th>Durasi</th>
<th><%= t('admin.att.duration','Durasi') %></th>
</tr>
</thead>
<tbody>
@@ -267,7 +267,7 @@
<!-- All Attendance Records -->
<div class="card" style="margin-top:20px">
<div class="card-hd">
<h6><i class="bi bi-calendar-check"></i> Semua Absensi - <%= parseDateInTimezone(selectedDate).toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) %></h6>
<h6><i class="bi bi-calendar-check"></i> <%= t('admin.att.all_attendance','Semua Absensi') %> - <%= parseDateInTimezone(selectedDate).toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) %></h6>
</div>
<% if (attendances.length > 0) { %>
@@ -279,10 +279,10 @@
<th><%= t('common.type','Tipe') %></th>
<th>Check-in</th>
<th>Check-out</th>
<th>Durasi</th>
<th><%= t('admin.att.duration','Durasi') %></th>
<th><%= t('common.status','Status') %></th>
<th>Lokasi</th>
<th>Foto</th>
<th><%= t('admin.att.location','Lokasi') %></th>
<th><%= t('admin.att.photo','Foto') %></th>
<th><%= t('common.actions','Aksi') %></th>
</tr>
</thead>
@@ -336,13 +336,13 @@
<div class="photo-stack">
<% if (att.check_in_photo) { %>
<a href="<%= att.check_in_photo %>" target="_blank" class="photo-item">
<img src="<%= att.check_in_photo %>" alt="Foto check-in" class="photo-thumb">
<img src="<%= att.check_in_photo %>" alt="<%= t('admin.att.photo','Foto') %> check-in" class="photo-thumb">
In
</a>
<% } %>
<% if (att.check_out_photo) { %>
<a href="<%= att.check_out_photo %>" target="_blank" class="photo-item">
<img src="<%= att.check_out_photo %>" alt="Foto check-out" class="photo-thumb">
<img src="<%= att.check_out_photo %>" alt="<%= t('admin.att.photo','Foto') %> check-out" class="photo-thumb">
Out
</a>
<% } %>
@@ -402,7 +402,7 @@
}
function editAttendance(id) {
const checkIn = prompt('Waktu Check-in (YYYY-MM-DD HH:MM:SS):');
const checkIn = prompt('<%= t('admin.att.checkin_time','Waktu Check-in') %> (YYYY-MM-DD HH:MM:SS):');
if (!checkIn) return;
const checkOut = prompt('Waktu Check-out (YYYY-MM-DD HH:MM:SS) - kosongkan jika belum:');
+14 -14
View File
@@ -2,7 +2,7 @@
<html lang="<%= lang || 'id' %>">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Approval Pembayaran Kolektor | <%= company %></title>
<title><%= t('admin.cpay.title','Approval Pembayaran Kolektor') %> | <%= company %></title>
<link rel="stylesheet" href="/vendor/bootstrap-icons/bootstrap-icons.min.css">
<link rel="stylesheet" href="/css/admin.css">
</head>
@@ -14,7 +14,7 @@
<div class="tb-title">
<button class="hb-menu" onclick="toggleSidebar()"><i class="bi bi-list"></i></button>
<i class="bi bi-check2-square"></i>
<span>Approval Pembayaran Kolektor</span>
<span><%= t('admin.cpay.title','Approval Pembayaran Kolektor') %></span>
</div>
<div class="tb-right">
<span class="adm-badge"><i class="bi bi-person-fill"></i> <%= (typeof session !== 'undefined' && session.isCashier) ? t('admin.role.cashier', 'Kasir') : t('admin.role.admin', 'Admin') %></span>
@@ -31,20 +31,20 @@
<div class="card">
<div class="card-hd">
<h6><i class="bi bi-list-ul"></i> Daftar Request (<%= (rows || []).length %>)</h6>
<h6><i class="bi bi-list-ul"></i> <%= t('admin.cpay.list','Daftar Request') %> (<%= (rows || []).length %>)</h6>
</div>
<div class="hint" style="padding:12px 16px 0 16px;font-size:12px;color:var(--muted)">
Label proses membantu membedakan request yang memang menunggu approval, request yang otomatis langsung lunas oleh kolektor, dan request yang sudah diproses admin atau kasir.
</div>
<div style="padding:12px 16px 0 16px;display:flex;gap:10px;flex-wrap:wrap">
<select id="processFilter" class="fs" style="max-width:220px">
<option value="all">Semua Proses</option>
<option value="pending">Butuh Approval</option>
<option value="auto">Auto Kolektor</option>
<option value="admin">Disetujui Admin</option>
<option value="cashier">Disetujui Kasir</option>
<option value="rejected">Ditolak Manual</option>
<option value="manual">Diproses Manual</option>
<option value="all"><%= t('admin.cpay.opt_all','Semua Proses') %></option>
<option value="pending"><%= t('admin.cpay.opt_pending','Butuh Approval') %></option>
<option value="auto"><%= t('admin.cpay.opt_auto','Auto Kolektor') %></option>
<option value="admin"><%= t('admin.cpay.opt_admin','Disetujui Admin') %></option>
<option value="cashier"><%= t('admin.cpay.opt_cashier','Disetujui Kasir') %></option>
<option value="rejected"><%= t('admin.cpay.opt_rejected','Ditolak Manual') %></option>
<option value="manual"><%= t('admin.cpay.opt_manual','Diproses Manual') %></option>
</select>
</div>
<div class="tbl-wrap">
@@ -54,9 +54,9 @@
<th><%= t('collector.col_time','Waktu') %></th>
<th><%= t('collector.role','Kolektor') %></th>
<th><%= t('common.customer','Pelanggan') %></th>
<th>Tagihan</th>
<th><%= t('admin.cpay.th_invoice','Tagihan') %></th>
<th class="num"><%= t('collector.col_amount','Nominal') %></th>
<th>Proses</th>
<th><%= t('admin.cpay.th_process','Proses') %></th>
<th><%= t('common.status','Status') %></th>
<th><%= t('common.actions','Aksi') %></th>
</tr>
@@ -119,12 +119,12 @@
<div class="act-menu" style="min-width:270px">
<form method="POST" action="/admin/collector-payments/<%= r.id %>/approve" style="display:flex;gap:6px;padding:4px 4px 6px">
<input class="fc" name="decided_note" placeholder="Catatan (opsional)" style="font-size:12px">
<button class="btn btn-s btn-sm" type="submit" title="Approve"><i class="bi bi-check-lg"></i> Setujui</button>
<button class="btn btn-s btn-sm" type="submit" title="Approve"><i class="bi bi-check-lg"></i> <%= t('admin.cpay.approve','Setujui') %></button>
</form>
<div class="act-sep"></div>
<form method="POST" action="/admin/collector-payments/<%= r.id %>/reject" style="display:flex;gap:6px;padding:4px">
<input class="fc" name="decided_note" placeholder="Alasan (opsional)" style="font-size:12px">
<button class="btn btn-d btn-sm" type="submit" title="Reject"><i class="bi bi-x-lg"></i> Tolak</button>
<button class="btn btn-d btn-sm" type="submit" title="Reject"><i class="bi bi-x-lg"></i> <%= t('admin.cpay.reject','Tolak') %></button>
</form>
</div>
</div>
+27 -27
View File
@@ -2,7 +2,7 @@
<html lang="<%= lang || 'id' %>">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Diskon Tagihan | <%= company %></title>
<title><%= t('admin.disc.title','Diskon Tagihan') %> | <%= company %></title>
<link rel="stylesheet" href="/vendor/bootstrap-icons/bootstrap-icons.min.css">
<link rel="stylesheet" href="/css/admin.css">
<style>
@@ -16,7 +16,7 @@
<%- include('partials/sidebar', { activePage: 'discounts', company }) %>
<div class="mw">
<div class="topbar">
<div class="tb-title"><button class="hb-menu" onclick="toggleSidebar()"><i class="bi bi-list"></i></button><i class="bi bi-percent"></i> Diskon Tagihan</div>
<div class="tb-title"><button class="hb-menu" onclick="toggleSidebar()"><i class="bi bi-list"></i></button><i class="bi bi-percent"></i> <%= t('admin.disc.title','Diskon Tagihan') %></div>
<div class="tb-right">
<span class="adm-badge"><i class="bi bi-person-fill"></i> <%= (typeof session !== 'undefined' && session.isCashier) ? 'Kasir' : 'Admin' %></span>
<a href="/admin/logout" class="btn btn-g btn-sm"><i class="bi bi-box-arrow-left"></i></a>
@@ -33,42 +33,42 @@
<form method="POST" action="/admin/discounts/apply" id="discForm">
<!-- Konfigurasi diskon -->
<div class="card mb16">
<div class="card-hd"><h6><i class="bi bi-sliders"></i> Pengaturan Diskon</h6></div>
<div class="card-hd"><h6><i class="bi bi-sliders"></i> <%= t('admin.disc.settings_title','Pengaturan Diskon') %></h6></div>
<div class="card-bd">
<div class="form-row">
<div class="fg">
<label class="fl">Target</label>
<select class="fs" name="apply_mode" id="applyMode">
<option value="selected" selected>Pelanggan terpilih (batch)</option>
<option value="single">Satu pelanggan (1 per 1)</option>
<option value="all">Semua pelanggan aktif</option>
<option value="selected" selected><%= t('admin.disc.opt_selected','Pelanggan terpilih (batch)') %></option>
<option value="single"><%= t('admin.disc.opt_single','Satu pelanggan (1 per 1)') %></option>
<option value="all"><%= t('admin.disc.opt_all','Semua pelanggan aktif') %></option>
</select>
</div>
<div class="fg" id="singleWrap" style="display:none">
<label class="fl">Pilih Pelanggan</label>
<label class="fl"><%= t('admin.disc.pick_customer','Pilih Pelanggan') %></label>
<select class="fs" name="customer_id">
<option value="">-- pilih pelanggan --</option>
<option value=""><%= t('admin.disc.ph_pick_customer','-- pilih pelanggan --') %></option>
<% customers.forEach(function(c){ %>
<option value="<%= c.id %>"><%= c.customer_code || c.id %> — <%= c.name %><%= c.area ? ' ('+c.area+')' : '' %></option>
<% }); %>
</select>
</div>
<div class="fg">
<label class="fl">Tipe Diskon</label>
<label class="fl"><%= t('admin.disc.disc_type','Tipe Diskon') %></label>
<select class="fs" name="discount_type" id="discType">
<option value="percent">Persen (%)</option>
<option value="amount">Nominal (Rp)</option>
<option value="percent"><%= t('admin.disc.opt_percent','Persen (%)') %></option>
<option value="amount"><%= t('admin.disc.opt_amount','Nominal (Rp)') %></option>
</select>
</div>
<div class="fg">
<label class="fl">Nilai Diskon</label>
<input class="fc" type="number" name="discount_value" id="discValue" min="1" step="1" placeholder="mis. 10 (persen) / 20000 (Rp)" required>
<div class="hint" id="discHint">Persen dihitung dari harga dasar (sebelum PPN/USO).</div>
<label class="fl"><%= t('admin.disc.disc_value','Nilai Diskon') %></label>
<input class="fc" type="number" name="discount_value" id="discValue" min="1" step="1" placeholder="<%= t('admin.disc.ph_value','mis. 10 (persen) / 20000 (Rp)') %>" required>
<div class="hint" id="discHint"><%= t('admin.disc.disc_hint','Persen dihitung dari harga dasar (sebelum PPN/USO).') %></div>
</div>
</div>
<div class="form-row">
<div class="fg">
<label class="fl">Periode Tagihan — Bulan</label>
<label class="fl"><%= t('admin.disc.period_month','Periode Tagihan — Bulan') %></label>
<select class="fs" name="period_month">
<% const mNames=['Januari','Februari','Maret','April','Mei','Juni','Juli','Agustus','September','Oktober','November','Desember'];
for(let m=1;m<=12;m++){ %>
@@ -77,7 +77,7 @@
</select>
</div>
<div class="fg">
<label class="fl">Tahun</label>
<label class="fl"><%= t('admin.disc.year','Tahun') %></label>
<select class="fs" name="period_year">
<% for(let y=(timeInfo.year||new Date().getFullYear())+1; y>=2023; y--){ %>
<option value="<%= y %>" <%= (timeInfo.year===y)?'selected':'' %>><%= y %></option>
@@ -85,13 +85,13 @@
</select>
</div>
<div class="fg" style="flex:2">
<label class="fl">Catatan (opsional)</label>
<input class="fc" name="note" placeholder="mis. promo bulan kemerdekaan">
<label class="fl"><%= t('admin.disc.note_opt','Catatan (opsional)') %></label>
<input class="fc" name="note" placeholder="<%= t('admin.disc.ph_note','mis. promo bulan kemerdekaan') %>">
</div>
</div>
<div style="display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-top:6px">
<div class="hint"><i class="bi bi-info-circle"></i> Diskon berlaku ke tagihan <b>belum bayar</b> pada periode terpilih. Tagihan lunas/hangus tidak diubah. Kode unik QRIS akan digenerate ulang dari nominal baru.</div>
<button type="submit" class="btn btn-p" id="applyBtn"><i class="bi bi-percent"></i> Terapkan Diskon</button>
<div class="hint"><i class="bi bi-info-circle"></i> <%- t('admin.disc.apply_hint','Diskon berlaku ke tagihan <b>belum bayar</b> pada periode terpilih. Tagihan lunas/hangus tidak diubah. Kode unik QRIS akan digenerate ulang dari nominal baru.') %></div>
<button type="submit" class="btn btn-p" id="applyBtn"><i class="bi bi-percent"></i> <%= t('admin.disc.apply','Terapkan Diskon') %></button>
</div>
</div>
</div>
@@ -100,9 +100,9 @@
<div class="card mb16" id="custCard">
<div class="card-hd">
<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;width:100%">
<h6 style="margin:0"><i class="bi bi-people"></i> Pilih Pelanggan (<%= customers.length %>)</h6>
<h6 style="margin:0"><i class="bi bi-people"></i> <%= t('admin.disc.pick_customer','Pilih Pelanggan') %> (<%= customers.length %>)</h6>
<div class="disc-filter">
<span class="disc-badge" id="selCount" title="Jumlah pelanggan terpilih">0 dipilih</span>
<span class="disc-badge" id="selCount" title="Jumlah pelanggan terpilih">0 <%= t('admin.disc.selected','dipilih') %></span>
<label style="display:flex;align-items:center;gap:6px;font-size:12px;cursor:pointer">
<input type="checkbox" id="selectAll" style="width:16px;height:16px"> Pilih semua yang tampil
</label>
@@ -146,7 +146,7 @@
<!-- Riwayat -->
<div class="card">
<div class="card-hd"><h6><i class="bi bi-clock-history"></i> Riwayat Diskon (100 terakhir)</h6></div>
<div class="card-hd"><h6><i class="bi bi-clock-history"></i> <%= t('admin.disc.history','Riwayat Diskon (100 terakhir)') %></h6></div>
<div class="tbl-wrap">
<table class="dtbl">
<thead>
@@ -158,7 +158,7 @@
<th class="num" style="width:120px">Potongan</th>
<th class="num" style="width:120px">Awal → Akhir</th>
<th style="width:110px">Oleh</th>
<th>Catatan</th>
<th><%= t('admin.disc.th_note','Catatan') %></th>
</tr>
</thead>
<tbody>
@@ -201,7 +201,7 @@
function syncHint(){
hint.textContent = (type.value === 'percent')
? 'Persen dihitung dari harga dasar (sebelum PPN/USO). Contoh: 10 = potong 10%.'
? '<%= t('admin.disc.disc_hint','Persen dihitung dari harga dasar (sebelum PPN/USO).') %> Contoh: 10 = potong 10%.'
: 'Nominal potongan langsung dalam Rupiah. Contoh: 20000 = potong Rp 20.000.';
}
type.addEventListener('change', syncHint); syncHint();
@@ -217,8 +217,8 @@
var applyBtn = document.getElementById('applyBtn');
function updateSelCount(){
var n = document.querySelectorAll('#custTable .cust-sel:checked').length;
if (selCount) selCount.textContent = n + ' dipilih';
if (applyBtn) applyBtn.innerHTML = '<i class="bi bi-percent"></i> Terapkan Diskon' + ((mode.value === 'selected' && n) ? ' (' + n + ')' : '');
if (selCount) selCount.textContent = n + ' <%= t('admin.disc.selected','dipilih') %>';
if (applyBtn) applyBtn.innerHTML = '<i class="bi bi-percent"></i> <%= t('admin.disc.apply','Terapkan Diskon') %>' + ((mode.value === 'selected' && n) ? ' (' + n + ')' : '');
}
all.addEventListener('change', function(){ visibleBoxes().forEach(function(b){ b.checked = all.checked; }); updateSelCount(); });
document.getElementById('custTable').addEventListener('change', function(e){ if (e.target && e.target.classList.contains('cust-sel')) updateSelCount(); });
+4 -4
View File
@@ -85,7 +85,7 @@
</div>
<div id="refresh-indicator" style="position:absolute;top:-8px;right:0;font-size:11px;color:var(--muted);display:none;align-items:center;gap:4px">
<i class="bi bi-arrow-clockwise" style="animation:spin 1s linear infinite"></i>
<span>Memperbarui...</span>
<span><%= t('admin.mt.updating','Memperbarui...') %></span>
</div>
</div>
<style>
@@ -250,7 +250,7 @@
</div>
</div>
<div class="form-row">
<div class="fg"><label class="fl">Limit Uptime (e.g. 1h)</label><input class="fc" id="h_uptime"></div>
<div class="fg"><label class="fl"><%= t('admin.mt.limit_uptime','Limit Uptime (e.g. 1h)') %></label><input class="fc" id="h_uptime"></div>
<div class="fg"><label class="fl">MAC Address</label><input class="fc" id="h_mac"></div>
</div>
<div class="fg"><label class="fl">Comment</label><input class="fc" id="h_comment"></div>
@@ -267,7 +267,7 @@
<div class="mo" id="onlineUsersModal">
<div class="mb" style="max-width:900px">
<div class="mh">
<span class="mt"><i class="bi bi-ethernet"></i> Daftar User PPPoE Online</span>
<span class="mt"><i class="bi bi-ethernet"></i> <%= t('admin.mt.online_list','Daftar User PPPoE Online') %></span>
<button class="mc" onclick="closeModal('onlineUsersModal')">&times;</button>
</div>
<div class="mbody" style="max-height:500px;overflow-y:auto">
@@ -307,7 +307,7 @@
<div class="mo" id="offlineUsersModal">
<div class="mb" style="max-width:800px">
<div class="mh">
<span class="mt"><i class="bi bi-plug"></i> Daftar User PPPoE Offline</span>
<span class="mt"><i class="bi bi-plug"></i> <%= t('admin.mt.offline_list','Daftar User PPPoE Offline') %></span>
<button class="mc" onclick="closeModal('offlineUsersModal')">&times;</button>
</div>
<div class="mbody" style="max-height:500px;overflow-y:auto">
+5 -5
View File
@@ -315,7 +315,7 @@
</div>
</div>
<div class="hint" style="margin:0 0 10px;padding:12px;border:1px dashed var(--border);border-radius:10px;background:var(--bg2)">
<i class="bi bi-robot"></i> <strong>Otomatisasi dipindah:</strong> Auto-Nonaktif, Auto-Hapus, Auto-Peringatan &amp; Auto-Lunas kini tertata di menu <a href="/admin/automation" style="color:var(--primary);font-weight:800">Automation &rarr;</a>
<i class="bi bi-robot"></i> <strong>Otomatisasi dipindah:</strong> Auto-Nonaktif, Auto-Hapus, Auto-Peringatan &amp; Auto-<%= t('admin.set.ew_paid','Lunas') %> kini tertata di menu <a href="/admin/automation" style="color:var(--primary);font-weight:800">Automation &rarr;</a>
</div>
<div class="hint" style="margin-top:6px;color:var(--warning)">
<i class="bi bi-info-circle"></i> <strong><%= t('admin.set.colpay_label','Pembayaran Kolektor:') %></strong> <%= t('admin.set.colpay_desc','Pengaturan approval pembayaran kolektor sekarang diatur per akun kolektor pada menu Manajemen Kolektor, bukan dari pengaturan global.') %>
@@ -1031,7 +1031,7 @@ async function loadEwalletLogs() {
if (!res.ok || !data.ok) throw new Error(data.error || 'Gagal memuat log');
const rows = Array.isArray(data.rows) ? data.rows : [];
if (rows.length === 0) {
body.innerHTML = '<tr><td colspan="7" class="text-center text-muted">Belum ada data.</td></tr>';
body.innerHTML = '<tr><td colspan="7" class="text-center text-muted"><%= t('admin.set.no_data','Belum ada data.') %></td></tr>';
return;
}
const newest = rows[0];
@@ -1056,9 +1056,9 @@ async function loadEwalletLogs() {
const md = Number(r.matched_donation_order_id || 0) || 0;
const isMatched = !!(mi || mv || md);
let statusBadge;
if (!parsed) statusBadge = '<span class="ew-badge ew-gray">Bukan transaksi</span>';
else if (isMatched) statusBadge = '<span class="ew-badge ew-green">Lunas</span>';
else statusBadge = '<span class="ew-badge ew-amber">Belum cocok</span>';
if (!parsed) statusBadge = '<span class="ew-badge ew-gray"><%= t('admin.set.ew_not_tx','Bukan transaksi') %></span>';
else if (isMatched) statusBadge = '<span class="ew-badge ew-green"><%= t('admin.set.ew_paid','Lunas') %></span>';
else statusBadge = '<span class="ew-badge ew-amber"><%= t('admin.set.ew_unmatched','Belum cocok') %></span>';
const amountHtml = (amountNum == null)
? '<span class="muted">—</span>'
: ('<span class="mono" style="font-weight:800;' + (parsed ? 'color:var(--primary)' : 'color:var(--muted)') + '">Rp ' + amountNum.toLocaleString('id-ID') + '</span>');