user(); // Permission check if (!$user->can('manage-activity-logs')) { abort(403); } $query = Activity::with('causer') ->orderBy('created_at', 'desc'); // Filter by module (log_name) if ($request->filled('module')) { $query->where('log_name', $request->module); } // Filter by user (causer) if ($request->filled('user_id')) { $query->where('causer_id', $request->user_id) ->where('causer_type', User::class); } // Filter by event type if ($request->filled('event')) { $query->where('event', $request->event); } // Filter by date range if ($request->filled('date_from')) { $query->whereDate('created_at', '>=', $request->date_from); } if ($request->filled('date_to')) { $query->whereDate('created_at', '<=', $request->date_to); } // Search in description if ($request->filled('search')) { $search = $request->search; $query->where(function ($q) use ($search) { $q->where('description', 'like', "%{$search}%") ->orWhere('properties', 'like', "%{$search}%"); }); } // Sorting $sortField = $request->get('sort', 'created_at'); $sortDirection = $request->get('direction', 'desc'); $allowedSorts = ['created_at', 'log_name', 'event', 'description']; if (in_array($sortField, $allowedSorts)) { $query->orderBy($sortField, $sortDirection === 'asc' ? 'asc' : 'desc'); } $perPage = $request->get('per_page', 25); $activities = $query->paginate($perPage)->withQueryString(); // Transform for frontend $activities->through(function ($activity) { return [ 'id' => $activity->id, 'log_name' => $activity->log_name, 'description' => $activity->description, 'event' => $activity->event, 'subject_type' => $activity->subject_type ? class_basename($activity->subject_type) : null, 'subject_id' => $activity->subject_id, 'causer' => $activity->causer ? [ 'id' => $activity->causer->id, 'name' => $activity->causer->name, 'email' => $activity->causer->email, 'type' => $activity->causer->type ?? null, ] : null, 'properties' => $activity->properties?->toArray() ?? [], 'changes' => $activity->attribute_changes ?? null, 'created_at' => $activity->created_at->toISOString(), ]; }); // Get available modules for filter dropdown $modules = Activity::select('log_name') ->distinct() ->whereNotNull('log_name') ->orderBy('log_name') ->pluck('log_name'); // Get users for filter dropdown $users = User::select('id', 'name', 'email') ->whereIn('id', Activity::select('causer_id')->whereNotNull('causer_id')->distinct()) ->orderBy('name') ->get(); return Inertia::render('ActivityLogs/Index', [ 'activities' => $activities, 'modules' => $modules, 'users' => $users, 'filters' => [ 'module' => $request->get('module', ''), 'user_id' => $request->get('user_id', ''), 'event' => $request->get('event', ''), 'date_from' => $request->get('date_from', ''), 'date_to' => $request->get('date_to', ''), 'search' => $request->get('search', ''), 'per_page' => $perPage, ], ]); } public function export(Request $request): StreamedResponse { $user = auth()->user(); if (!$user->can('manage-activity-logs')) { abort(403); } $query = Activity::with('causer') ->orderBy('created_at', 'desc'); if ($request->filled('module')) { $query->where('log_name', $request->module); } if ($request->filled('user_id')) { $query->where('causer_id', $request->user_id) ->where('causer_type', User::class); } if ($request->filled('event')) { $query->where('event', $request->event); } if ($request->filled('date_from')) { $query->whereDate('created_at', '>=', $request->date_from); } if ($request->filled('date_to')) { $query->whereDate('created_at', '<=', $request->date_to); } if ($request->filled('search')) { $query->where('description', 'like', "%{$request->search}%"); } $activities = $query->get(); return response()->streamDownload(function () use ($activities) { $handle = fopen('php://output', 'w'); // CSV header fputcsv($handle, [ 'Date/Time', 'User', 'Email', 'Action', 'Module', 'Description', 'Subject', ]); foreach ($activities as $activity) { fputcsv($handle, [ $activity->created_at->format('Y-m-d H:i:s'), $activity->causer?->name ?? 'System', $activity->causer?->email ?? '', $activity->event ?? '', $activity->log_name ?? '', $activity->description, $activity->subject_type ? class_basename($activity->subject_type) . ' #' . $activity->subject_id : '', ]); } fclose($handle); }, 'activity-logs-' . now()->format('Y-m-d') . '.csv', [ 'Content-Type' => 'text/csv', ]); } }