TKK_E32230908/resources/views/user/member/pending.blade.php

399 lines
14 KiB
PHP

@extends('layouts.dashboard')
@section('content')
<link href="https://fonts.googleapis.com/css2?family=Inter:wght=400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
html, body {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.pending-wrapper {
font-family: 'Inter', sans-serif;
background-color: #f8fafc;
min-height: 80vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.pending-card {
max-width: 600px;
width: 100%;
background: white;
border-radius: 24px;
padding: 50px 40px;
text-align: center;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.05);
border: 1px solid #e2e8f0;
animation: scaleIn 0.5s ease-out;
}
@keyframes scaleIn {
from { opacity: 0; transform: scale(0.9); }
to { opacity: 1; transform: scale(1); }
}
/* ==========================================================================
ICON BOXES (WARNA & ANIMASI BERDASARKAN STATUS)
========================================================================== */
.icon-box {
width: 100px;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
font-size: 40px;
border-radius: 50%;
margin: 0 auto 30px;
}
/* 1. Pending (Kuning) */
.icon-box.status-pending {
background: #fef3c7;
color: #d97706;
animation: pulse-amber 2s infinite;
}
@keyframes pulse-amber {
0% { box-shadow: 0 0 0 0 rgba(217, 119, 6, 0.2); }
70% { box-shadow: 0 0 0 20px rgba(217, 119, 6, 0); }
100% { box-shadow: 0 0 0 0 rgba(217, 119, 6, 0); }
}
/* 2. Ditolak (Merah) */
.icon-box.status-rejected {
background: #fee2e2;
color: #dc2626;
}
/* 3. Disetujui (Hijau) */
.icon-box.status-approved {
background: #dcfce7;
color: #16a34a;
animation: pulse-green 2s infinite;
}
@keyframes pulse-green {
0% { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.2); }
70% { box-shadow: 0 0 0 20px rgba(22, 163, 74, 0); }
100% { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0); }
}
/* ==========================================================================
BADGES (LABEL STATUS)
========================================================================== */
.status-badge {
padding: 6px 16px;
border-radius: 100px;
font-size: 0.8rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 20px;
display: inline-block;
}
.status-badge.status-pending {
background: #fff7ed;
color: #c2410c;
}
.status-badge.status-rejected {
background: #fef2f2;
color: #991b1b;
}
.status-badge.status-approved {
background: #f0fdf4;
color: #166534;
}
/* ==========================================================================
INFO BOXES (KOTAK DETAIL)
========================================================================== */
.info-box {
border-radius: 12px;
padding: 20px;
text-align: left;
margin-bottom: 30px;
}
.info-box.status-pending {
background: #f1f5f9;
}
.info-box.status-rejected {
background: #fff5f5;
border-left: 4px solid #f87171;
}
.info-box.status-approved {
background: #f0fdf4;
border-left: 4px solid #4ade80;
}
.pending-card h2 {
color: #1e293b;
font-weight: 800;
margin-bottom: 15px;
}
.pending-card p {
color: #64748b;
line-height: 1.6;
margin-bottom: 30px;
}
.info-item {
display: flex;
gap: 12px;
margin-bottom: 10px;
font-size: 0.9rem;
}
.info-item:last-child { margin-bottom: 0; }
/* ==========================================================================
ACTION BUTTONS (TOMBOL AKSI)
========================================================================== */
.action-group {
display: flex;
gap: 12px;
justify-content: center;
flex-wrap: wrap;
}
.btn-action {
text-decoration: none;
padding: 14px 26px;
border-radius: 12px;
font-weight: 600;
display: inline-flex;
align-items: center;
gap: 10px;
transition: 0.3s;
font-size: 0.95rem;
}
/* Tombol Merah (Daftar Ulang) */
.btn-danger-action {
background: #dc2626;
color: white;
}
.btn-danger-action:hover {
background: #b91c1c;
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(220, 38, 38, 0.3);
}
/* Tombol Putih/Abu (Hubungi Admin) */
.btn-secondary-action {
background: white;
color: #475569;
border: 1px solid #cbd5e1;
}
.btn-secondary-action:hover {
background: #f8fafc;
color: #1e293b;
border-color: #94a3b8;
transform: translateY(-2px);
}
/* Tombol Hijau (Masuk Dashboard) */
.btn-success-action {
background: #16a34a;
color: white;
}
.btn-success-action:hover {
background: #15803d;
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(22, 163, 74, 0.3);
}
</style>
<div class="pending-wrapper">
<div class="pending-card">
{{-- ================= Kondisi 1: DITOLAK ================= --}}
@if($anggota->status == 'ditolak')
<div class="icon-box status-rejected">
<i class="fas fa-user-times"></i>
</div>
<span class="status-badge status-rejected">Pendaftaran Ditolak</span>
<h2>Status Anggota Ditolak</h2>
<p>Halo, <strong>{{ Auth::user()->name }}</strong>.Pendaftaran ditolak karena data atau dokumen yang diunggah belum memenuhi persyaratan, dokumen pendukung yang tidak sesuai, foto identitas yang kurang jelas, atau informasi yang tidak dapat diverifikasi.</p>
<div class="info-box status-rejected">
<div class="info-item" style="color: #7f1d1d;">
<i class="fas fa-exclamation-circle mt-1 text-danger"></i>
<span>Silakan <strong>cek kembali data diri Anda</strong>, pastikan seluruh berkas valid, lalu daftarkan ulang profil Anda.</span>
</div>
<div class="info-item" style="color: #7f1d1d;">
<i class="fas fa-comments mt-1 text-danger"></i>
<span>Jika ada pertanyaan, Anda dapat langsung menghubungi admin via tombol di bawah ini.</span>
</div>
</div>
<div class="action-group">
<!-- Diarahkan ke form pembuatan/pengisian data awal -->
<a href="{{ route('user.member.create') }}" class="btn-action btn-danger-action">
<i class="fas fa-user-edit"></i> Cek Data & Daftar Ulang
</a>
<a href="https://wa.me/081229523471" target="_blank" class="btn-action btn-secondary-action">
<i class="fab fa-whatsapp"></i> Hubungi Admin
</a>
</div>
{{-- ================= Kondisi 2: DISETUJUI / AKTIF ================= --}}
@elseif($anggota->status == 'disetujui')
<div class="icon-box status-approved">
<i class="fas fa-user-check"></i>
</div>
<span class="status-badge status-approved">Akun Aktif</span>
<h2>Pendaftaran Disetujui!</h2>
<p>Selamat, <strong>{{ Auth::user()->name }}</strong>! Akun keanggotaan Anda telah berhasil diverifikasi oleh admin. Sekarang Anda memiliki akses penuh ke sistem.</p>
<div class="info-box status-approved">
<div class="info-item" style="color: #14532d;">
<i class="fas fa-check-circle mt-1 text-success"></i>
<span>Selamat bergabung! Silakan masuk ke dashboard utama untuk mulai menggunakan layanan keanggotaan.</span>
</div>
</div>
<div class="action-group">
<a href="{{ route('user.peminjaman.index') }}" class="btn-action btn-success-action">
<i class="fas fa-tachometer-alt"></i> Masuk Ke Dashboard
</a>
</div>
{{-- ================= Kondisi 3: MENUNGGU VERIFIKASI (DEFAULT) ================= --}}
@else
<div class="icon-box status-pending">
<i class="fas fa-hourglass-half"></i>
</div>
<span class="status-badge status-pending">Menunggu Verifikasi</span>
<h2>Pendaftaran Terkirim!</h2>
<p>Halo, <strong>{{ Auth::user()->name }}</strong>. Data pendaftaran Anda telah kami terima. Saat ini admin sedang melakukan validasi berkas dan profil Anda.</p>
<div class="info-box status-pending">
<div class="info-item">
<i class="fas fa-info-circle mt-1 text-primary"></i>
<span>Proses verifikasi biasanya memakan waktu <strong>1-2 hari kerja</strong>.</span>
</div>
<div class="info-item">
<i class="fas fa-bell mt-1 text-primary"></i>
<span>Anda dapat memantau status keanggotaan Anda di halaman ini secara berkala.</span>
</div>
</div>
@endif
</div>
</div>
{{-- Letakkan kode ini di bagian paling bawah sebelum @endsection --}}
<!-- Tambahkan Pustaka MQTT.js via CDN (jika layout utama belum memuatnya) -->
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script>
// 1. Konfigurasi MQTT Broker menggunakan WebSocket (Port default Mosquitto WS biasanya 9001 atau 8083)
const mqttBrokerUrl = 'ws://127.0.0.1:9001';
const currentUserId = "{{ Auth::id() }}"; // Mengambil ID User yang sedang login
const mqttClientId = 'laravel_blade_user_' + currentUserId + '_' + Math.random().toString(16).substr(2, 4);
const mqttClient = mqtt.connect(mqttBrokerUrl, {
clientId: mqttClientId,
clean: true,
connectTimeout: 5000,
});
// 2. Tentukan Topik Berdasarkan User ID sesuai dengan yang di-publish oleh AnggotaController
const statusTopic = 'pendaftaran/status/' + currentUserId;
mqttClient.on('connect', () => {
console.log('User terhubung ke Real-time Server via MQTT WebSocket.');
mqttClient.subscribe(statusTopic, (err) => {
if (!err) {
console.log(`Sukses mendengarkan pembaruan pada topik: ${statusTopic}`);
}
});
});
mqttClient.on('message', (topic, message) => {
try {
const payload = JSON.parse(message.toString());
console.log("Pesan Status Diterima:", payload);
// 3. Tangani Perubahan Status secara Dinamis
if (payload.status === 'disetujui') {
// Skenario 1: Admin menyetujui, meminta user melakukan tap kartu RFID ke mesin IoT
showRealtimeToast(payload.message || "Pendaftaran disetujui! Silakan tap kartu Anda pada mesin RFID.");
// Berikan jeda 2.5 detik agar pengguna sempat membaca instruksi, lalu muat ulang halaman
setTimeout(() => {
window.location.reload();
}, 2500);
} else if (payload.status === 'uid_ready') {
// Skenario 2: User sukses melakukan tap kartu RFID di alat IoT dan UID tersimpan
showRealtimeToast(payload.message || "Kartu RFID berhasil diregistrasikan! Mengalihkan ke dashboard...");
// Otomatis arahkan user langsung menuju dashboard utama peminjaman setelah 2 detik
setTimeout(() => {
window.location.href = "{{ route('user.peminjaman.index') }}";
}, 2000);
} else if (payload.status === 'ditolak' || payload.status === 'deleted') {
// Skenario 3: Pendaftaran ditolak admin atau dihapus
showRealtimeToast(payload.message || "Status pendaftaran Anda diperbarui.", "#dc2626");
setTimeout(() => {
window.location.reload();
}, 2500);
}
} catch (error) {
console.error("Gagal memproses payload pesan MQTT:", error);
}
});
mqttClient.on('error', (err) => {
console.error('Koneksi MQTT Interface Gagal: ', err);
});
// 4. Komponen Helper Pembuat Toast Notifikasi Melayang Dinamis
function showRealtimeToast(text, backgroundColor = '#16a34a') {
const toast = document.createElement('div');
toast.style.position = 'fixed';
toast.style.bottom = '30px';
toast.style.right = '30px';
toast.style.backgroundColor = backgroundColor;
toast.style.color = '#fff';
toast.style.padding = '16px 28px';
toast.style.borderRadius = '14px';
toast.style.boxShadow = '0 10px 25px -5px rgba(0,0,0,0.15)';
toast.style.zIndex = '99999';
toast.style.fontFamily = "'Inter', sans-serif";
toast.style.fontWeight = '600';
toast.style.fontSize = '0.95rem';
toast.style.transition = 'all 0.4s ease';
// Menambahkan ikon lonceng kecil di depan teks
toast.innerHTML = `<i class="fas fa-bell animate-bounce mr-2"></i> ${text}`;
document.body.appendChild(toast);
}
</script>
@endsection