128 lines
6.0 KiB
PHP
128 lines
6.0 KiB
PHP
<style>
|
|
#confirm-overlay {
|
|
display: none; position: fixed; inset: 0; z-index: 99999;
|
|
background: rgba(15,23,42,.4); backdrop-filter: blur(2px);
|
|
align-items: center; justify-content: center; padding: 20px;
|
|
}
|
|
#confirm-overlay.show { display: flex; }
|
|
#confirm-overlay.confirm-top {
|
|
align-items: flex-start; justify-content: center;
|
|
padding-top: 72px; background: transparent; backdrop-filter: none;
|
|
pointer-events: none;
|
|
}
|
|
#confirm-box {
|
|
background: #fff; border: 1px solid #e2e8f0; border-radius: 12px;
|
|
width: 100%; max-width: 400px;
|
|
box-shadow: 0 16px 48px rgba(15,23,42,.14);
|
|
animation: confirmIn .18s ease; overflow: hidden;
|
|
}
|
|
#confirm-overlay.confirm-top #confirm-box {
|
|
pointer-events: all; max-width: 460px;
|
|
box-shadow: 0 8px 28px rgba(15,23,42,.12);
|
|
}
|
|
@keyframes confirmIn { from { opacity:0; transform: translateY(-6px); } to { opacity:1; transform: none; } }
|
|
#confirm-box .cf-head {
|
|
display: flex; gap: 14px; padding: 20px 22px 0; align-items: flex-start;
|
|
}
|
|
#confirm-box .cf-icon {
|
|
width: 40px; height: 40px; border-radius: 10px; flex-shrink: 0;
|
|
display: flex; align-items: center; justify-content: center;
|
|
}
|
|
#confirm-box .cf-icon.warn { background: #fffbeb; border: 1px solid #fde68a; }
|
|
#confirm-box .cf-icon.danger { background: #fef2f2; border: 1px solid #fecaca; }
|
|
#confirm-box .cf-icon.info { background: #eff6ff; border: 1px solid #bfdbfe; }
|
|
#confirm-box .cf-text { flex: 1; min-width: 0; }
|
|
#confirm-box .cf-title { font-size: 15px; font-weight: 700; color: #0f172a; margin-bottom: 4px; }
|
|
#confirm-box .cf-msg { font-size: 13px; color: #64748b; line-height: 1.55; }
|
|
#confirm-box .cf-actions {
|
|
display: flex; gap: 8px; padding: 18px 22px 20px; justify-content: flex-end;
|
|
}
|
|
#confirm-box .cf-btn {
|
|
padding: 9px 16px; border-radius: 8px; font-size: 13px;
|
|
font-weight: 600; cursor: pointer; border: 1px solid transparent;
|
|
font-family: inherit; transition: background .15s;
|
|
}
|
|
#confirm-box .cf-cancel { background: #fff; color: #475569; border-color: #e2e8f0; }
|
|
#confirm-box .cf-cancel:hover { background: #f8fafc; }
|
|
#confirm-box .cf-ok { background: #1d4ed8; color: #fff; }
|
|
#confirm-box .cf-ok:hover { background: #1e40af; }
|
|
#confirm-box .cf-ok.danger { background: #dc2626; }
|
|
#confirm-box .cf-ok.danger:hover { background: #b91c1c; }
|
|
</style>
|
|
<div id="confirm-overlay" role="dialog" aria-modal="true">
|
|
<div id="confirm-box">
|
|
<div class="cf-head">
|
|
<div class="cf-icon warn" id="cf-icon"></div>
|
|
<div class="cf-text">
|
|
<div class="cf-title" id="cf-title">Konfirmasi</div>
|
|
<div class="cf-msg" id="cf-msg"></div>
|
|
</div>
|
|
</div>
|
|
<div class="cf-actions">
|
|
<button type="button" class="cf-btn cf-cancel" id="cf-cancel">Batal</button>
|
|
<button type="button" class="cf-btn cf-ok" id="cf-ok">Lanjutkan</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
(function(){
|
|
var overlay = document.getElementById('confirm-overlay');
|
|
var iconEl = document.getElementById('cf-icon');
|
|
var titleEl = document.getElementById('cf-title');
|
|
var msgEl = document.getElementById('cf-msg');
|
|
var btnOk = document.getElementById('cf-ok');
|
|
var btnCancel = document.getElementById('cf-cancel');
|
|
var resolver = null;
|
|
|
|
var icons = {
|
|
warn: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#d97706" stroke-width="2" stroke-linecap="round"><path d="M12 9v4m0 4h.01"/><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg>',
|
|
danger: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#dc2626" stroke-width="2" stroke-linecap="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6"/><path d="M10 11v6M14 11v6"/><path d="M9 6V4a1 1 0 011-1h4a1 1 0 011 1v2"/></svg>',
|
|
info: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5M12 8h.01"/></svg>',
|
|
move: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round"><path d="M12 2v20M2 12h20"/><circle cx="12" cy="12" r="3"/></svg>'
|
|
};
|
|
|
|
function closeConfirm(result) {
|
|
overlay.classList.remove('show', 'confirm-top');
|
|
document.body.style.overflow = '';
|
|
if (resolver) { var r = resolver; resolver = null; r(result); }
|
|
}
|
|
|
|
btnCancel.addEventListener('click', function(){ closeConfirm(false); });
|
|
btnOk.addEventListener('click', function(){ closeConfirm(true); });
|
|
overlay.addEventListener('click', function(e){ if (e.target === overlay && !overlay.classList.contains('confirm-top')) closeConfirm(false); });
|
|
document.addEventListener('keydown', function(e){
|
|
if (!overlay.classList.contains('show')) return;
|
|
if (e.key === 'Escape') closeConfirm(false);
|
|
});
|
|
|
|
window.showConfirm = function(opts) {
|
|
opts = opts || {};
|
|
var danger = !!opts.danger;
|
|
var kind = danger ? 'danger' : (opts.icon || 'warn');
|
|
iconEl.className = 'cf-icon ' + (kind === 'move' || kind === 'info' ? kind : (danger ? 'danger' : 'warn'));
|
|
iconEl.innerHTML = icons[kind] || icons.warn;
|
|
titleEl.textContent = opts.title || 'Konfirmasi';
|
|
msgEl.innerHTML = opts.message || 'Apakah Anda yakin?';
|
|
btnOk.textContent = opts.confirmText || (danger ? 'Ya, Hapus' : 'Lanjutkan');
|
|
btnCancel.textContent = opts.cancelText || 'Batal';
|
|
btnOk.classList.toggle('danger', danger);
|
|
overlay.classList.toggle('confirm-top', opts.position === 'top');
|
|
if (opts.position !== 'top') document.body.style.overflow = 'hidden';
|
|
overlay.classList.add('show');
|
|
return new Promise(function(resolve){ resolver = resolve; });
|
|
};
|
|
|
|
document.querySelectorAll('[data-confirm-logout]').forEach(function(el){
|
|
el.addEventListener('click', function(e){
|
|
e.preventDefault();
|
|
showConfirm({
|
|
title: 'Keluar dari akun',
|
|
message: 'Sesi Anda akan diakhiri. Lanjutkan keluar?',
|
|
confirmText: 'Ya, Keluar',
|
|
danger: true
|
|
}).then(function(ok){ if (ok) window.location = el.getAttribute('href'); });
|
|
});
|
|
});
|
|
})();
|
|
</script>
|