namespace App\Traits; use App\Models\ActivityLog; trait Loggable { public function activityLogs() { return $this->morphMany(ActivityLog::class, 'causer'); } public function logActivity($description, $properties = [], $event = null) { return ActivityLog::create([ 'log_name' => 'user', 'description' => $description, 'subject_type' => get_class($this), 'subject_id' => $this->id, 'causer_type' => get_class($this), 'causer_id' => $this->id, 'properties' => $properties, 'event' => $event, 'ip_address' => request()->ip(), 'user_agent' => request()->userAgent(), ]); } public function logLogin($status = 'success') { return $this->loginLogs()->create([ 'ip_address' => request()->ip(), 'user_agent' => request()->userAgent(), 'status' => $status, 'login_at' => now(), ]); } public function logLogout() { $log = $this->loginLogs() ->whereNull('logout_at') ->latest() ->first(); if ($log) { $log->update(['logout_at' => now()]); } } public function getLastLoginAttribute() { return $this->loginLogs() ->where('status', 'success') ->latest() ->first(); } public function getLoginCountAttribute() { return $this->loginLogs() ->where('status', 'success') ->count(); } public function getFailedLoginCountAttribute() { return $this->loginLogs() ->where('status', 'failed') ->where('created_at', '>=', now()->subDay()) ->count(); } public function getRecentActivitiesAttribute() { return $this->activityLogs() ->latest() ->limit(10) ->get(); } public function getActivityStatsAttribute() { return [ 'total_logins' => $this->login_count, 'failed_attempts' => $this->failed_login_count, 'last_login' => $this->last_login?->login_at, 'last_ip' => $this->last_login?->ip_address, 'account_age' => $this->created_at->diffForHumans(), 'days_active' => $this->created_at->diffInDays(now()), ]; } }