select([ 'roles.id', 'roles.name', 'roles.slug', 'roles.description', 'roles.dashboard_route', 'roles.priority', 'roles.is_active', 'roles.created_at', 'roles.updated_at', ]) ->leftJoin('user_roles', function ($join) { $join->on('user_roles.role_id', '=', 'roles.id') ->whereNull('user_roles.deleted_at'); }) ->selectRaw('COUNT(DISTINCT user_roles.user_id) AS user_count') ->groupBy([ 'roles.id', 'roles.name', 'roles.slug', 'roles.description', 'roles.dashboard_route', 'roles.priority', 'roles.is_active', 'roles.created_at', 'roles.updated_at', ]); if (! empty($filters['search'])) { $search = trim((string) $filters['search']); $query->where(function (Builder $q) use ($search) { $q->where('roles.name', 'like', '%'.$search.'%') ->orWhere('roles.slug', 'like', '%'.$search.'%') ->orWhere('roles.description', 'like', '%'.$search.'%'); }); } $sortBy = (string) ($filters['sort_by'] ?? 'name'); $sortDir = strtolower((string) ($filters['sort_dir'] ?? 'asc')) === 'desc' ? 'desc' : 'asc'; $allowed = ['name', 'slug', 'priority', 'is_active', 'created_at']; if (! in_array($sortBy, $allowed, true)) { $sortBy = 'name'; } $perPage = (int) ($filters['per_page'] ?? 20); $perPage = $perPage > 0 ? $perPage : 20; return $query->orderBy($sortBy, $sortDir)->paginate($perPage); } public function listUsersWithRoles(array $filters): LengthAwarePaginator { $query = DB::table('users') ->leftJoin('user_roles', function ($join) { $join->on('user_roles.user_id', '=', 'users.id') ->whereNull('user_roles.deleted_at'); }) ->leftJoin('roles', 'roles.id', '=', 'user_roles.role_id') ->select( 'users.id', 'users.firstname', 'users.lastname', 'users.email', 'users.account_id', DB::raw('GROUP_CONCAT(DISTINCT roles.name) as roles') ) ->groupBy('users.id', 'users.firstname', 'users.lastname', 'users.email', 'users.account_id'); if (! empty($filters['search'])) { $search = trim((string) $filters['search']); $query->where(function ($q) use ($search) { $q->where('users.firstname', 'like', '%'.$search.'%') ->orWhere('users.lastname', 'like', '%'.$search.'%') ->orWhere('users.email', 'like', '%'.$search.'%') ->orWhere('users.account_id', 'like', '%'.$search.'%'); }); } $sortBy = (string) ($filters['sort_by'] ?? 'lastname'); $sortDir = strtolower((string) ($filters['sort_dir'] ?? 'asc')) === 'desc' ? 'desc' : 'asc'; $allowed = ['firstname', 'lastname', 'email', 'account_id']; if (! in_array($sortBy, $allowed, true)) { $sortBy = 'lastname'; } $perPage = (int) ($filters['per_page'] ?? 20); $perPage = $perPage > 0 ? $perPage : 20; return $query->orderBy('users.'.$sortBy, $sortDir)->paginate($perPage); } }