this current code needs pagination and sort, how i do?

I wrote a code that retrieves the user list and finds the progress on the retrieved data, but I need to sort the asc based on the progress and it should be pagination, but I don't know how to do it

Since there are many users, is there a way to do pagination and sorting by query without using foreach?

Below is the code, it is the code to find the progress and it is not good because it uses foreach, is there a better way?? Pagination is also required

$users = \App\Models\ChallengeUserPivot::where('challenge_id', $challenge_id)->get();

foreach($users as $user){
    $user_data = \App\Models\User::where('id', $user['user_id'])->first();
    $temp_progress = [];
    $temp_progress['total'] = 0;
    $temp_progress['doing'] = 0;
    foreach($challenge->ChallengeMissions as $key => $mission){
        $temp = ChallengeFunction::missionState($user_data, $mission);
        $temp_progress['total'] += (int)$temp['have_to_mission_count'];
        $temp_progress['doing'] += $temp['cert_count'];
    $user['progress'] = ($temp_progress['doing'] / $temp_progress['total']) * 100;

You need to add to your query a limiter and an offset and increment the offset for each pagination. So here you need to specify how many rows you would like to get (just assuming here where to insert the limit):

\App\Models\ChallengeUserPivot::where('challenge_id', $challenge_id)->get(1000);

And for the next 1000 rows you need to ad an offset of 1000 rows.

So first rows is 0-1000 next is 1000-2000 and so on. That way you don't need to fetch all rows in one call.

Previous : Highlight matching text filter javascript
Next : Collapsible element using javascript how to collapse by default