name('login')->middleware('guest'); Route::post('/login', [AuthController::class, 'login'])->middleware('guest'); Route::post('/logout', [AuthController::class, 'logout'])->name('logout')->middleware('auth'); // All other routes require authentication Route::middleware('auth')->group(function () { // Web pages Route::get('/', fn() => view('welcome')); Route::get('/map', fn() => view('map')); Route::get('/data', fn() => view('data')); Route::get('/dashboard', fn() => view('dashboard'))->name('dashboard'); Route::get('/permohonan', fn() => view('permohonan'))->name('permohonan'); // Export routes — semua role authenticated bisa ekspor Route::get('/export/pdf', [ExportController::class, 'allMiskinPDF'])->name('export.pdf.all'); Route::get('/export/pdf/radius/{ibadahId}/{radius}', [ExportController::class, 'radiusMiskinPDF']) ->name('export.pdf.radius') ->where(['ibadahId' => '[0-9]+', 'radius' => '[0-9]+']); // API routes moved here for session + CSRF middleware Route::prefix('api')->group(function () { // Anggota Keluarga — baca: semua; tulis: administrator + petugas_pendataan Route::get('/miskin/{id}/anggota', [AnggotaKeluargaController::class, 'index']); Route::middleware('role:administrator|petugas_pendataan')->group(function () { Route::post('/miskin/{id}/anggota', [AnggotaKeluargaController::class, 'store']); Route::put('/miskin/{id}/anggota/{aid}', [AnggotaKeluargaController::class, 'update']); Route::delete('/miskin/{id}/anggota/{aid}', [AnggotaKeluargaController::class, 'destroy']); }); // Riwayat Bantuan — baca: semua; tulis: administrator + petugas + pengurus_ibadah Route::get('/miskin/{id}/bantuan', [BantuanController::class, 'index']); Route::middleware('role:administrator|petugas_pendataan|pengurus_ibadah')->group(function () { Route::post('/miskin/{id}/bantuan', [BantuanController::class, 'store']); Route::delete('/miskin/{id}/bantuan/{bid}', [BantuanController::class, 'destroy']); }); // Permohonan Transfer — lihat: semua; ajukan+proses: pengurus + admin Route::get('/permohonan', [TransferController::class, 'index']); Route::middleware('role:administrator|pengurus_ibadah')->group(function () { Route::post('/permohonan', [TransferController::class, 'store']); Route::put('/permohonan/{id}/respond', [TransferController::class, 'respond']); }); // Notifikasi — semua role authenticated Route::get('/notifications', function (\Illuminate\Http\Request $request) { $since = $request->query('since'); $after = $since ? \Carbon\Carbon::parse($since) : now()->subMinutes(1); $user = $request->user(); $transferQuery = \App\Models\PermohonanTransfer::query(); $pendingTransferQuery = \App\Models\PermohonanTransfer::where('status', 'pending'); if ($user->hasRole('pengurus_ibadah')) { $ownedIbadahIds = \App\Models\RumahIbadah::where('user_id', $user->id)->pluck('id'); $transferQuery->where(function ($query) use ($ownedIbadahIds) { $query->whereIn('dari_ibadah_id', $ownedIbadahIds) ->orWhereIn('ke_ibadah_id', $ownedIbadahIds); }); $pendingTransferQuery->whereIn('ke_ibadah_id', $ownedIbadahIds); } elseif (!$user->hasRole('administrator')) { $pendingTransferQuery->whereRaw('1 = 0'); } return response()->json([ 'new_ibadah' => \App\Models\RumahIbadah::where('created_at', '>', $after)->count(), 'new_miskin' => \App\Models\RumahMiskin::where('created_at', '>', $after)->count(), 'new_anggota' => \App\Models\AnggotaKeluarga::where('created_at', '>', $after)->count(), 'new_bantuan' => \App\Models\RiwayatBantuan::where('created_at', '>', $after)->count(), 'new_transfer' => $transferQuery->where('created_at', '>', $after)->count(), 'pending_transfer' => $pendingTransferQuery->count(), 'latest_ibadah' => \App\Models\RumahIbadah::max('created_at'), 'latest_miskin' => \App\Models\RumahMiskin::max('created_at'), 'latest_anggota' => \App\Models\AnggotaKeluarga::max('created_at'), 'latest_bantuan' => \App\Models\RiwayatBantuan::max('created_at'), 'latest_transfer' => \App\Models\PermohonanTransfer::max('created_at'), ]); }); Route::get('/dashboard/dosen-summary', DosenSummaryController::class); // Rumah Ibadah — read: all roles, write: administrator + pengurus_ibadah Route::get('/ibadah', [IbadahController::class, 'index']); Route::middleware('role:administrator|pengurus_ibadah')->group(function () { Route::post('/ibadah', [IbadahController::class, 'store']); Route::put('/ibadah/{id}', [IbadahController::class, 'update']); Route::delete('/ibadah/{id}', [IbadahController::class, 'destroy']); }); // Rumah Miskin — read: all roles, write: administrator + petugas_pendataan Route::get('/miskin', [MiskinController::class, 'index']); Route::middleware('role:administrator|petugas_pendataan')->group(function () { Route::post('/miskin', [MiskinController::class, 'store']); Route::put('/miskin/{id}', [MiskinController::class, 'update']); Route::delete('/miskin/{id}', [MiskinController::class, 'destroy']); }); }); // Admin routes — hanya administrator Route::middleware('role:administrator')->group(function () { Route::get('/admin/users', fn() => view('admin.users'))->name('admin.users'); Route::get('/admin/logs', fn() => view('admin.logs'))->name('admin.logs'); Route::get('/admin/settings', fn() => view('admin.settings'))->name('admin.settings'); Route::prefix('api/admin')->group(function () { Route::get('/users', [AdminUserController::class, 'index']); Route::post('/users', [AdminUserController::class, 'store']); Route::put('/users/{id}', [AdminUserController::class, 'update']); Route::delete('/users/{id}', [AdminUserController::class, 'destroy']); Route::put('/users/{id}/password', [AdminUserController::class, 'resetPassword']); Route::post('/ibadah/bulk-delete', [IbadahController::class, 'bulkDestroy']); Route::post('/miskin/bulk-delete', [MiskinController::class, 'bulkDestroy']); Route::post('/import/ibadah', [ImportController::class, 'ibadah']); Route::post('/import/miskin', [ImportController::class, 'miskin']); Route::get('/backup', [BackupController::class, 'download'])->name('admin.backup'); Route::get('/backup/list', [BackupController::class, 'listBackups']); Route::get('/backup/download/{filename}', [BackupController::class, 'downloadStored']) ->where('filename', '[^/]+'); Route::post('/restore', [BackupController::class, 'restore']); Route::get('/logs', [ActivityLogController::class, 'index']); Route::get('/stats', [ActivityLogController::class, 'stats']); Route::get('/settings', [SettingController::class, 'index']); Route::put('/settings/{key}', [SettingController::class, 'update']); }); }); });