normalizedSort(); $direction = $query->normalizedDirection(); $like = '%' . $query->search . '%'; return Prompt::query() ->with('tags') ->when( $query->search !== null && $query->search !== '', fn (Builder $q) => $q->where( fn (Builder $w) => $w ->where('name', 'like', $like) ->orWhere('description', 'like', $like) ->orWhere('body', 'like', $like) ), ) ->when( $query->tag !== null && $query->tag !== '', fn (Builder $q) => $q->whereHas('tags', fn (Builder $t) => $t->where('name', $query->tag)), ) ->when($query->favoritesOnly, fn (Builder $q) => $q->where('is_favorite', true)) ->when( $sort === 'last_used_at', // NULLs always sort last: `IS NULL` is 0/1, so a first // ascending pass groups non-NULLs before NULLs in either // direction, then the value itself orders within the group. fn (Builder $q) => $q ->orderByRaw('last_used_at IS NULL') ->orderBy('last_used_at', $direction), fn (Builder $q) => $q->orderBy($sort, $direction), ) ->orderBy('id', 'desc') ->paginate(self::PER_PAGE); } /** * All tags, alphabetically (for filter dropdowns). */ public function tags(): Collection { return Tag::query()->orderBy('name')->get(); } }