connect(); // Sesuai dengan konfigurasi JS Admin Anda, action diatur sebagai 'created' agar memicu reload $payload = json_encode([ 'action' => 'created', 'message' => $actionMessage ]); $mqtt->publish('pendaftaran/refresh/admin', $payload, 0); $mqtt->disconnect(); } catch (\Exception $e) { // Mencatat error ke log jika broker MQTT mati agar aplikasi user tidak ikut crash/error 500 Log::error('Gagal mengirim sinyal MQTT ke Admin: ' . $e->getMessage()); } } public function create() { // 🔥 CEK VERIFIKASI EMAIL if (!Auth::user()->hasVerifiedEmail()) { return redirect()->route('verification.notice') ->with('error', 'Silakan verifikasi email terlebih dahulu sebelum mendaftar anggota.'); } // 🔥 LOGIKA REDIRECT JIKA SUDAH DAFTAR if (Auth::user()->anggota) { // Hanya lempar ke halaman pending jika statusnya memang 'menunggu' if (Auth::user()->anggota->status === 'menunggu') { return redirect()->route('user.member.pending'); } // Jika disetujui, langsung arahkan ke halaman peminjaman/dashboard utama if (Auth::user()->anggota->status === 'disetujui') { return redirect()->route('user.peminjaman.index') ->with('info', 'Kamu sudah terdaftar sebagai anggota aktif.'); } // 💡 Catatan: Jika statusnya 'ditolak', logika akan lolos ke bawah // sehingga pengguna dapat masuk kembali ke formulir pendaftaran. } return view('user.member.create'); } /** * Tampilan Halaman Menunggu Persetujuan & Status Anggota */ public function pending() { $anggota = Auth::user()->anggota; // Jika belum mendaftar, kembalikan ke form pendaftaran if (!$anggota) { return redirect()->route('user.member.create'); } // Jika sudah disetujui, arahkan langsung ke peminjaman if ($anggota->status === 'disetujui') { return redirect()->route('user.peminjaman.index'); } // Mengembalikan view status dengan membawa data keanggotaan ($anggota) return view('user.member.pending', compact('anggota')); } public function store(Request $request) { // 🔥 CEK VERIFIKASI EMAIL if (!Auth::user()->hasVerifiedEmail()) { return back()->with('error', 'Verifikasi email terlebih dahulu.'); } $anggotaLama = Auth::user()->anggota; // 💡 DISESUAIKAN: Menggunakan kolom 'nik_nip' di database untuk aturan unique $nikNipRule = 'required|string|max:255|unique:anggota,nik_nip'; if ($anggotaLama && $anggotaLama->status === 'ditolak') { $nikNipRule = 'required|string|max:255|unique:anggota,nik_nip,' . $anggotaLama->id; } // Validasi data input form $request->validate([ 'nama' => 'required|string|max:255', 'gender' => 'required|in:Laki-laki,Perempuan', 'nik_nip' => $nikNipRule, // 💡 SUDAH DISESUAIKAN 'provinsi' => 'required|string|max:255', 'kota' => 'required|string|max:255', 'kecamatan' => 'required|string|max:255', 'desa' => 'required|string|max:255', 'kode_pos' => 'required|string|max:5', 'alamat' => 'required|string|min:10', 'no_hp' => 'nullable|string|max:20', 'foto' => 'nullable|image|mimes:jpg,jpeg,png|max:5120', ]); // Proteksi ganda status pendaftaran if ($anggotaLama) { if ($anggotaLama->status === 'menunggu' || $anggotaLama->status === 'disetujui') { return redirect()->route('user.member.pending') ->with('info', 'Pendaftaran Anda sedang diproses atau sudah aktif.'); } } $namaFoto = $anggotaLama ? $anggotaLama->foto : null; // Proses unggah foto baru jika ada file yang dikirim if ($request->hasFile('foto')) { if ($anggotaLama && $anggotaLama->foto) { if (Storage::disk('public')->exists('foto_anggota/' . $anggotaLama->foto)) { Storage::disk('public')->delete('foto_anggota/' . $anggotaLama->foto); } } $file = $request->file('foto'); $namaFoto = time() . '_' . uniqid() . '.' . $file->getClientOriginalExtension(); $file->storeAs('foto_anggota', $namaFoto, 'public'); } // Gabungkan teks wilayah administratif ke dalam kolom alamat $alamatLengkap = $request->alamat; if (!str_contains($alamatLengkap, $request->desa)) { $alamatLengkap = "Desa/Kel. {$request->desa}, Kec. {$request->kecamatan}, {$request->kota}, Provinsi {$request->provinsi}. Kode Pos: {$request->kode_pos}. Detail: " . $request->alamat; } $notifMessage = 'Ada pendaftar baru mandiri!'; if ($anggotaLama && $anggotaLama->status === 'ditolak') { // 🔥 UPDATE DATA JIKA USER DAFTAR ULANG $anggotaLama->update([ 'nama' => $request->nama, 'gender' => $request->gender, 'nik_nip' => $request->nik_nip, // 💡 DISESUAIKAN: Menyimpan ke kolom 'nik_nip' 'alamat' => $alamatLengkap, 'no_hp' => $request->no_hp ?? null, 'status' => 'menunggu', 'foto' => $namaFoto, ]); $anggota = $anggotaLama; $notifMessage = 'Seorang anggota mengajukan pendaftaran ulang!'; } else { // 🔥 BUAT BARU JIKA BELUM PERNAH DAFTAR SAMA SEKALI if (Anggota::where('email', Auth::user()->email)->exists()) { return back()->with('error', 'Email ini sudah terdaftar sebagai anggota.'); } $anggota = Anggota::create([ 'nama' => $request->nama, 'gender' => $request->gender, 'nik_nip' => $request->nik_nip, // 💡 DISESUAIKAN: Menyimpan ke kolom 'nik_nip' 'email' => Auth::user()->email, 'alamat' => $alamatLengkap, 'no_hp' => $request->no_hp ?? null, 'user_id' => Auth::id(), 'status' => 'menunggu', 'foto' => $namaFoto, ]); } // 🔥 TAMBAHAN MQTT $this->triggerAdminRefresh($notifMessage); // Kirim email notifikasi ke admin try { Mail::to('admin@bakorwil.com')->send(new AnggotaBaruMenungguPersetujuan($anggota)); } catch (\Exception $e) { Log::error('Gagal mengirim email ke admin: ' . $e->getMessage()); } Auth::user()->setRelation('anggota', $anggota); return redirect()->route('user.member.pending') ->with('success', 'Data pendaftaran berhasil diperbarui/dikirim. Mohon tunggu persetujuan admin.'); } public function index() { $anggota = Anggota::latest()->take(5)->get(); return view('user.member.index', compact('anggota')); } public function all() { $anggota = Anggota::latest()->get(); return view('user.member.all', compact('anggota')); } public static function getFotoUrl($anggota) { if ($anggota && $anggota->foto && Storage::disk('public')->exists('foto_anggota/' . $anggota->foto)) { return asset('storage/foto_anggota/' . $anggota->foto); } return asset('images/default-user.png'); } }