39735-vm/POSFuku/Poin.html
2026-04-19 12:17:53 +00:00

313 lines
16 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<base target="_top">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="#111111">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>POS - Cek Poin & Riwayat</title>
<style>
body { margin:0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; background:#f4f7f6; color: #333; padding-bottom: 40px; -webkit-font-smoothing: antialiased; }
.header { background:#111; color:white; padding:15px; text-align:center; position:sticky; top:0; z-index:100; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
.container { padding:12px; max-width: 600px; margin: 0 auto; }
.card { background:white; border-radius:12px; padding:15px; border: 1px solid #eee; margin-bottom:15px; transform: translateZ(0); }
.title { font-size: 16px; font-weight: 800; margin-bottom: 12px; color: #111; text-align: center; }
input { width:100%; padding:12px; margin-bottom:12px; border:1px solid #ccc; border-radius:10px; box-sizing:border-box; font-size:14px; outline: none; background: #fff; -webkit-appearance: none; }
.btn { width:100%; padding:14px; border:none; border-radius:12px; font-weight:800; cursor:pointer; font-size:14px; display: flex; align-items: center; justify-content: center; gap: 8px; }
.btn-primary { background:#e11d48; color:white; }
.btn:active { opacity: 0.7; }
.poin-badge { background:#fff1f2; color:#e11d48; padding:15px; border-radius:12px; text-align:center; margin-bottom:15px; border: 1px dashed #e11d48; }
.poin-val { font-size: 32px; font-weight: 900; display: block; margin-top: 5px; }
.history-item { border-bottom: 1px solid #f3f4f6; padding:12px 0; }
.history-item:last-child { border-bottom: none; }
.history-header { display:flex; justify-content:space-between; font-weight:800; font-size:13px; margin-bottom:5px; }
.history-id { font-size: 10px; color: #999; font-family: monospace; }
.history-status { font-size: 9px; padding: 3px 8px; border-radius: 6px; font-weight: 800; text-transform: uppercase; }
.st-selesai { background: #dcfce7; color: #166534; }
.star-rating { display: flex; justify-content: center; gap: 10px; margin: 15px 0; font-size: 32px; }
.star { cursor: pointer; color: #ddd; transition: 0.2s; }
.star.active { color: #f59e0b; }
textarea { width: 100%; height: 80px; padding: 12px; border: 1px solid #ccc; border-radius: 10px; box-sizing: border-box; font-family: inherit; font-size: 14px; margin-bottom: 12px; resize: none; outline: none; background: #fff; -webkit-appearance: none; }
.menu-list { font-size: 12px; color: #555; margin-top: 8px; background: #f9fafb; padding: 10px; border-radius: 10px; border: 1px solid #f1f5f9; }
.menu-row { display: flex; justify-content: space-between; margin-bottom: 4px; }
#loading { position:fixed; inset:0; background:#fff; display:none; flex-direction:column; justify-content:center; align-items:center; z-index:1000; }
.spinner { border:3px solid #f3f3f3; border-top:3px solid #e11d48; border-radius:50%; width:35px; height:35px; animation:spin 0.8s linear infinite; margin-bottom: 10px; }
@keyframes spin { 0% { transform:rotate(0deg); } 100% { transform:rotate(360deg); } }
.muted { color: #999; font-size: 11px; text-align: center; margin-top: 20px; }
.error-msg { color: #e11d48; font-size: 13px; text-align: center; margin-bottom: 12px; display: none; font-weight: 700; }
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-thumb { background: #ddd; border-radius: 10px; }
</style>
</head>
<body>
<div id="loading"><div class="spinner"></div><p>Mencari Data...</p></div>
<div class="header">
<div id="store-name" style="font-weight:900; font-size:20px;">POS</div>
<div style="font-size:12px; opacity:0.8;">Cek Poin & Riwayat Transaksi</div>
</div>
<div class="container">
<!-- Form Login -->
<div id="login-section" class="card">
<div class="title">Masuk ke Akun Anda</div>
<div id="error-msg" class="error-msg">Nama atau nomor WA tidak ditemukan.</div>
<input id="login-wa" type="tel" placeholder="Masukkan Nomor WA (Contoh: 0812...)">
<button class="btn btn-primary" onclick="cekData()">LIHAT RIWAYAT SAYA</button>
<div class="muted">Bisa input dengan 08... atau 62...</div>
</div>
<!-- Hasil Data -->
<div id="result-section" style="display:none;">
<div class="card">
<div class="title">Informasi Pelanggan</div>
<div style="text-align:center; margin-bottom:15px;">
<div id="res-nama" style="font-weight:900; font-size:18px;"></div>
<div id="res-wa" style="font-size:14px; color:#666;"></div>
</div>
<div class="poin-badge">
<span style="font-size:12px; font-weight:bold; text-transform:uppercase; letter-spacing:1px;">Total Poin Anda</span>
<span id="res-poin" class="poin-val">0</span>
</div>
<div id="review-box" style="margin-top:12px; padding:12px; border-radius:12px; border:1px solid #e2e8f0; background:#f8fafc;">
<div style="font-weight:900; font-size:12px; margin-bottom:6px; color:#111;">Status Review</div>
<div id="review-status" class="muted">Belum dicek.</div>
</div>
<!-- Feedback Form -->
<div id="feedback-section" style="border-top: 1px solid #eee; padding-top: 15px; margin-top: 15px;">
<div class="title" style="font-size: 14px;">Bagaimana pengalaman Anda?</div>
<div class="star-rating">
<span class="star" onclick="setRating(1)"></span>
<span class="star" onclick="setRating(2)"></span>
<span class="star" onclick="setRating(3)"></span>
<span class="star" onclick="setRating(4)"></span>
<span class="star" onclick="setRating(5)"></span>
</div>
<textarea id="fb-komentar" placeholder="Berikan saran atau kesan Anda (opsional)..."></textarea>
<button id="btn-feedback" class="btn btn-primary" onclick="kirimFeedback()">KIRIM FEEDBACK</button>
<div id="fb-success" style="display:none; text-align:center; color:#16a34a; font-weight:bold; font-size:13px;">Terima kasih atas feedback Anda!</div>
</div>
<button class="btn" style="background:#f3f4f6; color:#666; margin-top: 20px;" onclick="location.reload()">LOGOUT / KEMBALI</button>
</div>
<div class="card">
<div class="title">Riwayat Transaksi</div>
<div id="history-list"></div>
</div>
</div>
</div>
<script>
var currentRating = 0;
var currentCustomer = null;
var storeName = 'POS';
window.onload = function() {
google.script.run.withSuccessHandler(function(res) {
if (res && res.settings) {
storeName = String(res.settings.store_name || storeName);
var el = document.getElementById('store-name');
if (el) el.innerText = storeName;
try { document.title = storeName + ' - Cek Poin & Riwayat'; } catch(e) {}
}
}).getInitialData();
};
function showLoading(s, text) {
document.getElementById('loading').style.display = s ? 'flex' : 'none';
if (text) document.querySelector('#loading p').innerText = text;
else document.querySelector('#loading p').innerText = 'Mencari Data...';
}
function normalizeWA(wa) {
var clean = String(wa || '').replace(/\D/g, '');
if (clean.indexOf('0') === 0) clean = '62' + clean.slice(1);
else if (clean.indexOf('8') === 0) clean = '62' + clean;
return clean;
}
function cekData() {
var wa = document.getElementById('login-wa').value.trim();
if (!wa) { alert('Mohon isi Nomor WA!'); return; }
var cleanWA = normalizeWA(wa);
showLoading(true);
document.getElementById('error-msg').style.display = 'none';
google.script.run.withSuccessHandler(function(res) {
showLoading(false);
if (res && res.settings) {
storeName = String(res.settings.store_name || storeName);
var el = document.getElementById('store-name');
if (el) el.innerText = storeName;
try { document.title = storeName + ' - Cek Poin & Riwayat'; } catch(e) {}
}
if (res && res.pelanggan) {
displayResult(res.pelanggan, res.transaksi, cleanWA);
} else {
document.getElementById('error-msg').style.display = 'block';
}
}).withFailureHandler(function(err) {
showLoading(false);
alert('Gagal memuat data poin.\n' + (err && err.message ? err.message : err));
}).getInitialData();
}
function displayResult(allPelanggan, allHistory, targetWa) {
var p = allPelanggan.find(function(x) {
return normalizeWA(x.wa) === targetWa;
}) || null;
var entries = allHistory.filter(function(h) {
return normalizeWA(h.wa) === targetWa && (h.status === 'Selesai' || h.status === 'Review' || String(h.buktiReview || '').trim());
}).sort(function(a,b) {
return String(b.timestamp || b.tgl || '').localeCompare(String(a.timestamp || a.tgl || ''));
});
if (!p && entries.length === 0) {
document.getElementById('error-msg').style.display = 'block';
return;
}
if (!p) p = { nama: '-', wa: document.getElementById('login-wa').value.trim(), poin: 0 };
currentCustomer = p;
document.getElementById('login-section').style.display = 'none';
document.getElementById('result-section').style.display = 'block';
document.getElementById('res-nama').innerText = p.nama;
document.getElementById('res-wa').innerText = p.wa;
document.getElementById('res-poin').innerText = Number(p.poin).toLocaleString();
var reviewBox = document.getElementById('review-status');
if (reviewBox) {
var reviewHistory = entries.filter(function(h) {
return (String(h.buktiReview || '').trim() || String(h.status || '') === 'Review');
});
if (reviewHistory.length === 0) {
reviewBox.innerHTML = 'Belum ada review yang tercatat.';
} else {
var latest = reviewHistory[0];
var url = String(latest.buktiReview || '').trim();
var html = 'Sudah pernah review: <b>' + reviewHistory.length + 'x</b>';
if (url) {
html += '<div style="margin-top:8px;"><a href="' + url + '" target="_blank" style="display:inline-block; padding:10px 12px; border-radius:10px; background:#111; color:#fff; text-decoration:none; font-weight:900; font-size:12px;">LIHAT BUKTI REVIEW</a></div>';
}
reviewBox.innerHTML = html;
}
}
var historyBox = document.getElementById('history-list');
historyBox.innerHTML = '';
if (entries.length === 0) {
historyBox.innerHTML = '<div class="muted">Belum ada riwayat.</div>';
return;
}
entries.forEach(function(h) {
var div = document.createElement('div');
div.className = 'history-item';
var itemsHtml = '';
if (h.status === 'Selesai' && h.items && h.items.length) {
itemsHtml = '<div class="menu-list">';
h.items.forEach(function(it) {
itemsHtml += '<div class="menu-row"><span>' + it.qty + 'x ' + it.nama + '</span><span>Rp ' + (it.qty * it.harga).toLocaleString() + '</span></div>';
});
// Tambahkan baris pemakaian poin jika ada
var poinUsed = Number(h.poinDipakai || 0);
if (poinUsed > 0) {
itemsHtml += '<div class="menu-row" style="color:#e11d48; border-top:1px dashed #ddd; margin-top:4px; padding-top:4px;">' +
'<span>Poin Terpakai</span>' +
'<span>-Rp ' + poinUsed.toLocaleString() + '</span>' +
'</div>';
}
var poinGet = Number(h.poinDapat || 0);
if (poinGet > 0) {
itemsHtml += '<div class="menu-row" style="color:#16a34a; border-top:1px dashed #ddd; margin-top:4px; padding-top:4px;">' +
'<span>Poin Didapat</span>' +
'<span>+' + poinGet.toLocaleString() + '</span>' +
'</div>';
}
itemsHtml += '</div>';
}
var dateText = (h.timestamp ? h.timestamp.split(' ')[0] : (h.tgl ? String(h.tgl).split(' ')[0] : '-'));
var isReview = (String(h.status || '') === 'Review') || !!String(h.buktiReview || '').trim();
var statusLabel = isReview ? '<span class="history-status" style="background:#111; color:#fff;">REVIEW</span>' : '<span class="history-status st-selesai">SELESAI</span>';
var rightVal = isReview ? '' : '<span style="font-weight:900; color:#e11d48;">Rp ' + Number(h.total || 0).toLocaleString() + '</span>';
var reviewUrl = String(h.buktiReview || '').trim();
var reviewBtn = reviewUrl ? '<div style="margin-top:10px;"><a href="' + reviewUrl + '" target="_blank" style="display:inline-block; padding:10px 12px; border-radius:10px; background:#111; color:#fff; text-decoration:none; font-weight:900; font-size:12px;">LIHAT BUKTI REVIEW</a></div>' : '';
div.innerHTML = '<div class="history-header">' +
'<span>' + dateText + '</span>' +
statusLabel +
'</div>' +
'<div style="display:flex; justify-content:space-between; align-items:center;">' +
'<span class="history-id">ID: ' + h.id + '</span>' +
rightVal +
'</div>' +
itemsHtml +
(isReview ? reviewBtn : (reviewUrl ? reviewBtn : ''));
historyBox.appendChild(div);
});
}
function setRating(n) {
currentRating = n;
var stars = document.querySelectorAll('.star');
stars.forEach(function(s, idx) {
if (idx < n) s.classList.add('active');
else s.classList.remove('active');
});
}
function kirimFeedback() {
if (currentRating === 0) {
alert('Mohon berikan rating bintang!');
return;
}
var komentar = document.getElementById('fb-komentar').value.trim();
var payload = {
nama: currentCustomer.nama,
wa: currentCustomer.wa,
rating: currentRating,
komentar: komentar
};
showLoading(true, 'Mengirim Feedback...');
google.script.run.withSuccessHandler(function(res) {
showLoading(false);
if (res.success) {
document.getElementById('btn-feedback').style.display = 'none';
document.querySelectorAll('.star-rating, textarea').forEach(function(el) { el.style.pointerEvents = 'none'; el.style.opacity = '0.6'; });
document.getElementById('fb-success').style.display = 'block';
}
}).withFailureHandler(function(err) {
showLoading(false);
alert('Gagal mengirim feedback.\n' + (err && err.message ? err.message : err));
}).saveFeedback(payload);
}
</script>
</body>
</html>