update: admin scan

main
marszayn 2025-08-06 10:29:29 +07:00
parent a677ad959e
commit bed92f8ab0
2 changed files with 175 additions and 42 deletions

View File

@ -562,8 +562,8 @@
showModal(type, title, message, showCloseButton = true) { showModal(type, title, message, showCloseButton = true) {
const iconHtml = { const iconHtml = {
'success': '<div class="w-20 h-20 mx-auto bg-green-100 rounded-full flex items-center justify-center shadow-lg"><i class="w-10 h-10 text-green-600" data-lucide="check-circle"></i></div>', 'success': '<div class="w-20 h-20 mx-auto bg-green-100 rounded-full flex items-center justify-center shadow-lg"><svg class="w-10 h-10 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg></div>',
'error': '<div class="w-20 h-20 mx-auto bg-red-100 rounded-full flex items-center justify-center shadow-lg"><i class="w-10 h-10 text-red-600" data-lucide="x-circle"></i></div>', 'error': '<div class="w-20 h-20 mx-auto bg-red-100 rounded-full flex items-center justify-center shadow-lg"><svg class="w-10 h-10 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg></div>',
'loading': '<div class="w-20 h-20 mx-auto bg-blue-100 rounded-full flex items-center justify-center shadow-lg"><div class="loading-spinner-modal"></div></div>' 'loading': '<div class="w-20 h-20 mx-auto bg-blue-100 rounded-full flex items-center justify-center shadow-lg"><div class="loading-spinner-modal"></div></div>'
}; };
@ -584,53 +584,62 @@
'transform': 'scale(1)' 'transform': 'scale(1)'
}, 300); }, 300);
if (typeof lucide !== 'undefined') { // Auto hide untuk loading modal setelah 3 detik jika tidak ada tombol
lucide.createIcons(); if (!showCloseButton && type === 'loading') {
setTimeout(() => {
this.hideModal();
}, 3000);
} }
} }
showSuccessModal(code, tanggal, waktu) { showSuccessModal(code, tanggal, waktu) {
// Custom success modal dengan UI yang lebih keren // Custom success modal dengan UI yang lebih keren
const successIcon = ` const successIcon = `
<div class="w-24 h-24 mx-auto bg-gradient-to-r from-green-400 to-emerald-500 rounded-full flex items-center justify-center shadow-xl mb-4"> <div class="w-28 h-28 mx-auto bg-gradient-to-r from-green-400 to-emerald-500 rounded-full flex items-center justify-center shadow-xl mb-6 animate-pulse">
<i class="w-12 h-12 text-white" data-lucide="check-circle"></i> <svg class="w-16 h-16 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path>
</svg>
</div> </div>
`; `;
const successContent = ` const successContent = `
<div class="bg-gradient-to-r from-green-50 to-emerald-50 rounded-xl p-4 mb-6 border border-green-200"> <div class="bg-gradient-to-br from-green-50 via-emerald-50 to-teal-50 rounded-2xl p-6 border border-green-200 shadow-inner">
<div class="flex items-center justify-center mb-3"> <div class="flex items-center justify-center mb-4">
<div class="bg-green-100 rounded-lg px-3 py-1"> <div class="bg-gradient-to-r from-green-500 to-emerald-600 text-white rounded-xl px-4 py-2 shadow-lg">
<span class="text-green-800 font-mono font-bold text-lg">${code}</span> <span class="font-mono font-bold text-xl tracking-wider">${code}</span>
</div> </div>
</div> </div>
<div class="grid grid-cols-2 gap-3 text-sm"> <div class="space-y-4">
<div class="bg-white rounded-lg p-3 text-center border border-green-100"> <div class="bg-white rounded-xl p-4 shadow-sm border border-green-100">
<div class="text-green-600 font-medium mb-1">Status</div>
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<div class="w-2 h-2 bg-green-500 rounded-full mr-2"></div> <div class="flex items-center space-x-3">
<span class="text-gray-700 font-semibold">Aktif</span> <div class="w-3 h-3 bg-green-500 rounded-full animate-pulse"></div>
<span class="text-gray-700 font-semibold text-lg">Status Aktif</span>
<div class="w-3 h-3 bg-green-500 rounded-full animate-pulse"></div>
</div>
</div> </div>
</div> </div>
<div class="bg-white rounded-lg p-3 text-center border border-green-100"> <div class="grid grid-cols-2 gap-3">
<div class="text-green-600 font-medium mb-1">Waktu Scan</div> <div class="bg-white rounded-xl p-4 text-center shadow-sm border border-green-100">
<div class="text-gray-700 font-semibold">${waktu}</div> <div class="text-green-600 font-medium mb-2 text-sm">⏰ Waktu Scan</div>
</div> <div class="text-gray-800 font-bold text-lg">${waktu}</div>
</div> </div>
<div class="mt-3 bg-white rounded-lg p-3 border border-green-100"> <div class="bg-white rounded-xl p-4 text-center shadow-sm border border-green-100">
<div class="text-green-600 font-medium mb-1 text-center">Tanggal</div> <div class="text-green-600 font-medium mb-2 text-sm">📅 Tanggal</div>
<div class="text-gray-700 font-semibold text-center text-sm">${tanggal}</div> <div class="text-gray-800 font-bold text-sm leading-tight">${tanggal}</div>
</div>
</div>
</div> </div>
</div> </div>
`; `;
$('#modal-icon').html(successIcon); $('#modal-icon').html(successIcon);
$('#modal-title').html('<span class="text-2xl">🎉 Scan Berhasil!</span>'); $('#modal-title').html('<span class="text-2xl font-bold bg-gradient-to-r from-green-600 to-emerald-600 bg-clip-text text-transparent">🎉 Scan Berhasil!</span>');
$('#modal-message').html(successContent); $('#modal-message').html(successContent);
$('#modal-close').html('<i class="w-5 h-5 mr-2" data-lucide="check"></i>Selesai').show(); $('#modal-close').hide(); // Sembunyikan tombol
$('#scan-modal').removeClass('hidden'); $('#scan-modal').removeClass('hidden');
@ -639,37 +648,69 @@
'transform': 'scale(1)' 'transform': 'scale(1)'
}, 300); }, 300);
if (typeof lucide !== 'undefined') { // Auto hide setelah 2 detik
lucide.createIcons(); setTimeout(() => {
} this.hideModal();
}, 2000);
} }
showErrorModal(code) { showErrorModal(code) {
// Custom error modal dengan UI yang lebih keren // Custom error modal dengan UI yang lebih keren
const errorIcon = ` const errorIcon = `
<div class="w-24 h-24 mx-auto bg-gradient-to-r from-red-400 to-rose-500 rounded-full flex items-center justify-center shadow-xl mb-4"> <div class="w-28 h-28 mx-auto bg-gradient-to-r from-red-400 to-rose-500 rounded-full flex items-center justify-center shadow-xl mb-6 animate-pulse">
<i class="w-12 h-12 text-white" data-lucide="x-circle"></i> <svg class="w-16 h-16 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</div> </div>
`; `;
const errorContent = ` const errorContent = `
<div class="bg-gradient-to-r from-red-50 to-rose-50 rounded-xl p-4 mb-4 border border-red-200"> <div class="bg-gradient-to-br from-red-50 via-rose-50 to-pink-50 rounded-2xl p-6 border border-red-200 shadow-inner">
<div class="flex items-center justify-center mb-3"> <div class="flex items-center justify-center mb-4">
<div class="bg-red-100 rounded-lg px-3 py-1"> <div class="bg-gradient-to-r from-red-500 to-rose-600 text-white rounded-xl px-4 py-2 shadow-lg">
<span class="text-red-800 font-mono font-bold">${code}</span> <span class="font-mono font-bold text-xl tracking-wider">${code}</span>
</div> </div>
</div> </div>
<div class="text-center text-red-700">
<div class="font-semibold mb-1">Kode SPJ tidak ditemukan</div> <div class="space-y-4">
<div class="text-sm opacity-75">Silakan periksa kembali kode yang Anda masukkan</div> <div class="bg-white rounded-xl p-4 shadow-sm border border-red-100">
<div class="text-center">
<div class="flex items-center justify-center mb-2">
<svg class="w-6 h-6 text-red-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"></path>
</svg>
<span class="text-red-700 font-bold text-lg">SPJ Tidak Ditemukan</span>
</div>
<div class="text-red-600 text-sm opacity-90 leading-relaxed">
Kode yang Anda masukkan tidak terdaftar dalam sistem.<br>
Silakan periksa kembali atau hubungi administrator.
</div>
</div>
</div>
<div class="bg-yellow-50 rounded-xl p-4 border border-yellow-200">
<div class="flex items-start">
<svg class="w-5 h-5 text-yellow-600 mr-2 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<div class="text-yellow-800 text-sm">
<div class="font-semibold mb-1">💡 Tips:</div>
<div class="text-xs leading-relaxed">
• Pastikan QR Code dalam kondisi baik<br>
• Coba scan ulang dengan pencahayaan yang cukup<br>
• Gunakan input manual jika diperlukan
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
`; `;
$('#modal-icon').html(errorIcon); $('#modal-icon').html(errorIcon);
$('#modal-title').html('<span class="text-xl">❌ SPJ Tidak Ditemukan</span>'); $('#modal-title').html('<span class="text-xl font-bold bg-gradient-to-r from-red-600 to-rose-600 bg-clip-text text-transparent">❌ Scan Gagal</span>');
$('#modal-message').html(errorContent); $('#modal-message').html(errorContent);
$('#modal-close').html('<i class="w-5 h-5 mr-2" data-lucide="arrow-left"></i>Coba Lagi').show(); $('#modal-close').hide(); // Sembunyikan tombol
$('#scan-modal').removeClass('hidden'); $('#scan-modal').removeClass('hidden');
@ -678,9 +719,10 @@
'transform': 'scale(1)' 'transform': 'scale(1)'
}, 300); }, 300);
if (typeof lucide !== 'undefined') { // Auto hide setelah 2 detik
lucide.createIcons(); setTimeout(() => {
} this.hideModal();
}, 2000);
} }
hideModal() { hideModal() {

View File

@ -1,3 +1,94 @@
/* Modal animations and enhancements */
#scan-modal {
backdrop-filter: blur(8px);
transition: all 0.3s ease;
}
#scan-modal .bg-white {
transform-origin: center center;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
/* Enhanced modal auto-hide animation */
.modal-auto-hide {
animation: modalAutoHide 0.4s ease-in-out;
}
@keyframes modalAutoHide {
0% {
opacity: 1;
transform: scale(1);
}
80% {
opacity: 1;
transform: scale(1.02);
}
100% {
opacity: 0;
transform: scale(0.95);
}
}
/* Success modal specific animations */
.success-gradient-bg {
background: linear-gradient(135deg, #10b981, #059669, #047857);
animation: gradientShift 2s ease-in-out;
}
@keyframes gradientShift {
0%,
100% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
}
/* Error modal specific animations */
.error-gradient-bg {
background: linear-gradient(135deg, #ef4444, #dc2626, #b91c1c);
animation: gradientShift 2s ease-in-out;
}
/* Enhanced pulse animation for icons */
.icon-pulse {
animation: iconPulse 1.5s ease-in-out infinite;
}
@keyframes iconPulse {
0%,
100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.1);
opacity: 0.8;
}
}
/* Card shadow effects */
.card-shadow-success {
box-shadow: 0 10px 25px rgba(16, 185, 129, 0.2);
}
.card-shadow-error {
box-shadow: 0 10px 25px rgba(239, 68, 68, 0.2);
}
/* Responsive modal improvements */
@media (max-width: 640px) {
#scan-modal .bg-white {
margin: 16px;
max-width: calc(100vw - 32px);
}
#scan-modal .bg-white .space-y-4 > div {
margin-bottom: 12px;
}
}
.scanner-container { .scanner-container {
position: relative; position: relative;
background: #1a1a1a; background: #1a1a1a;