user ? $pengajuan->user->nama_lengkap : 'Penduduk'; // Penyesuaian emoji berdasarkan status $statusEmoji = 'â„šī¸'; if ($statusBaru === 'disetujui') $statusEmoji = '✅'; if ($statusBaru === 'ditolak') $statusEmoji = '❌'; $message = "đŸ“ĸ *NOTIFIKASI E-SURAT*\n\n" . "Halo, *{$namaUser}*\n" . "Surat *{$pengajuan->jenis_surat}* Anda telah *" . strtoupper($statusBaru) . "* {$statusEmoji}\n" . "đŸ”ĸ *No Surat:* " . ($pengajuan->nomor_surat ?? '-') . "\n\n" . "--- _E-Surat Desa_ ---"; try { Http::withoutVerifying()->post("https://api.telegram.org/bot{$token}/sendMessage", [ 'chat_id' => $chatId, 'text' => $message, 'parse_mode' => 'Markdown', ]); } catch (\Exception $e) { \Log::error("Telegram Gagal: " . $e->getMessage()); } } /** * FUNGSI BARU: Admin & Super Admin menambah User baru */ public function storeUser(Request $request) { // Proteksi tingkat tinggi: Hanya admin/super admin if (!in_array(Auth::user()->role, ['admin', 'super admin'])) { return redirect()->back()->with('error', 'Akses ditolak! Anda bukan admin.'); } $request->validate([ 'username' => 'required|unique:users,username|max:255', 'nama_lengkap' => 'required|string|max:255', 'password' => 'required|min:6', 'role' => 'required|in:admin,user', // Super admin hanya bisa dibuat via DB/Seeder demi keamanan ]); try { User::create([ 'username' => $request->username, 'nama_lengkap' => $request->nama_lengkap, 'password' => Hash::make($request->password), // Gunakan Hash agar aman 'role' => $request->role, ]); return redirect()->back()->with('success', 'User baru berhasil ditambahkan!'); } catch (\Exception $e) { return redirect()->back()->with('error', 'Gagal menambah user: ' . $e->getMessage()); } } /** * HALAMAN UTAMA ADMIN (INDEX) */ public function index() { $pengajuan = PengajuanSurat::with('user')->orderBy('created_at', 'desc')->paginate(7); $totalMenunggu = PengajuanSurat::where('status', 'menunggu')->count(); $totalDisetujui = PengajuanSurat::where('status', 'disetujui')->count(); // Ambil data user untuk ditampilkan di form tambah user jika perlu $users = User::all(); return view('pengajuan', compact('pengajuan', 'totalMenunggu', 'totalDisetujui', 'users')); } /** * HALAMAN DASHBOARD USER (INDEX USER) */ public function indexUser() { $userId = Auth::id(); $dataValidasi = DB::table('validasi')->where('user_id', $userId)->first(); $status_validasi = $dataValidasi ? strtoupper($dataValidasi->status) : 'BELUM_ISI'; $pengajuan = PengajuanSurat::where('user_id', $userId) ->orderBy('created_at', 'desc') ->paginate(7); $totalMenunggu = PengajuanSurat::where('user_id', $userId)->where('status', 'menunggu')->count(); $totalDisetujui = PengajuanSurat::where('user_id', $userId)->where('status', 'disetujui')->count(); $totalDitolak = PengajuanSurat::where('user_id', $userId)->where('status', 'ditolak')->count(); return view('user.pengajuan', compact('pengajuan', 'totalMenunggu', 'totalDisetujui', 'totalDitolak', 'status_validasi')); } /** * MENYIMPAN PENGAJUAN BARU (STORE) */ public function store(Request $request) { $user = Auth::user(); $isAdmin = in_array($user->role, ['admin', 'super admin']); if (!$isAdmin) { $validasi = DB::table('validasi')->where('user_id', $user->id)->first(); if (!$validasi || strtoupper($validasi->status) !== 'DISETUJUI') { return redirect()->back()->with('error', 'Akses ditolak! Anda belum divalidasi sebagai penduduk.'); } } $request->validate([ 'nomor_surat' => 'required|string|max:100', 'jenis_surat' => 'required|string', 'tanggal_pengajuan' => 'required|date', 'keterangan' => 'required|string', 'berkas_persyaratan' => 'required|file|mimes:pdf|max:2048', ]); try { $namaFile = null; if ($request->hasFile('berkas_persyaratan')) { $file = $request->file('berkas_persyaratan'); $namaFile = time() . '_' . $file->getClientOriginalName(); $file->move(public_path('berkas_pengajuan'), $namaFile); } PengajuanSurat::create([ 'user_id' => $user->id, 'nomor_surat' => $request->nomor_surat, 'jenis_surat' => $request->jenis_surat, 'tanggal_pengajuan' => $request->tanggal_pengajuan, 'keterangan' => $request->keterangan, 'status' => 'menunggu', 'berkas_persyaratan' => $namaFile, ]); return redirect()->back()->with('success', 'Pengajuan berhasil dikirim!'); } catch (\Exception $e) { return redirect()->back()->with('error', 'Gagal menyimpan: ' . $e->getMessage()); } } /** * MENGUBAH DATA PENGAJUAN (UPDATE) */ public function update(Request $request, $id) { $pengajuan = PengajuanSurat::findOrFail($id); $user = Auth::user(); $isAdmin = in_array($user->role, ['admin', 'super admin']); if (!$isAdmin && $pengajuan->user_id !== $user->id) { return redirect()->back()->with('error', 'Akses ditolak.'); } // Validasi diperingkas $request->validate([ 'nomor_surat' => 'required', 'jenis_surat' => 'required', 'berkas_persyaratan' => 'nullable|file|mimes:pdf|max:2048', ]); $statusLama = $pengajuan->status; $statusBaru = $request->status; $pengajuan->nomor_surat = $request->nomor_surat; $pengajuan->jenis_surat = $request->jenis_surat; $pengajuan->keterangan = $request->keterangan; if ($request->has('tanggal_pengajuan')) { $pengajuan->tanggal_pengajuan = $request->tanggal_pengajuan; } if ($isAdmin && $request->has('status')) { $pengajuan->status = $statusBaru; } if ($request->hasFile('berkas_persyaratan')) { if ($pengajuan->berkas_persyaratan && File::exists(public_path('berkas_pengajuan/' . $pengajuan->berkas_persyaratan))) { File::delete(public_path('berkas_pengajuan/' . $pengajuan->berkas_persyaratan)); } $file = $request->file('berkas_persyaratan'); $namaFile = time() . '_' . $file->getClientOriginalName(); $file->move(public_path('berkas_pengajuan'), $namaFile); $pengajuan->berkas_persyaratan = $namaFile; } $pengajuan->save(); // Kirim notifikasi jika status berubah oleh Admin if ($isAdmin && $statusBaru && $statusBaru !== $statusLama) { $this->sendTelegramNotification($pengajuan, $statusBaru); } return redirect()->back()->with('success', 'Data pengajuan berhasil diperbarui!'); } /** * MENGHAPUS PENGAJUAN (DESTROY) */ public function destroy($id) { $pengajuan = PengajuanSurat::findOrFail($id); $user = Auth::user(); $isAdmin = in_array($user->role, ['admin', 'super admin']); if (!$isAdmin && $pengajuan->user_id !== $user->id) { return redirect()->back()->with('error', 'Akses ditolak.'); } // Hapus file fisik if ($pengajuan->berkas_persyaratan) { $path = public_path('berkas_pengajuan/' . $pengajuan->berkas_persyaratan); if (File::exists($path)) { File::delete($path); } } $pengajuan->delete(); return redirect()->back()->with('success', 'Data berhasil dihapus'); } }