feature: main page - ranking list
This commit is contained in:
@@ -115,8 +115,13 @@ class UserService implements UserServiceInterface
|
|||||||
->whereColumn('msnv', 'user.msnv')
|
->whereColumn('msnv', 'user.msnv')
|
||||||
->whereBetween('date', [$startOfMonth, $endOfMonth])
|
->whereBetween('date', [$startOfMonth, $endOfMonth])
|
||||||
])
|
])
|
||||||
->orderByDesc('score')
|
->get()
|
||||||
->get();
|
->filter(fn($u) => $u->score > 0)
|
||||||
|
->sortBy([
|
||||||
|
['score', 'desc'],
|
||||||
|
['msnv', 'asc']
|
||||||
|
])
|
||||||
|
->values();
|
||||||
|
|
||||||
$currentRank = 0;
|
$currentRank = 0;
|
||||||
$prevScore = null;
|
$prevScore = null;
|
||||||
@@ -157,8 +162,13 @@ class UserService implements UserServiceInterface
|
|||||||
->whereColumn('msnv', 'user.msnv')
|
->whereColumn('msnv', 'user.msnv')
|
||||||
->whereBetween('date', [$startOfMonth, $endOfMonth])
|
->whereBetween('date', [$startOfMonth, $endOfMonth])
|
||||||
])
|
])
|
||||||
->orderByDesc('score')
|
->get()
|
||||||
->get();
|
->filter(fn($u) => $u->score > 0)
|
||||||
|
->sortBy([
|
||||||
|
['score', 'desc'],
|
||||||
|
['msnv', 'asc']
|
||||||
|
])
|
||||||
|
->values();
|
||||||
|
|
||||||
$prevScore = null;
|
$prevScore = null;
|
||||||
$rank = 1;
|
$rank = 1;
|
||||||
@@ -181,15 +191,23 @@ class UserService implements UserServiceInterface
|
|||||||
$currentUserRankItem = $userItem;
|
$currentUserRankItem = $userItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($index < 5) {
|
if ($index < 4) {
|
||||||
$rankers[] = $userItem;
|
$rankers[] = $userItem;
|
||||||
}
|
}
|
||||||
$rank++;
|
$rank++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$showCurrentUserAtBottom = false;
|
||||||
|
if ($currentUserRankItem) {
|
||||||
|
$currentUserIndex = $users->search(fn($u) => $u->msnv == $currentUser->msnv);
|
||||||
|
if ($currentUserIndex !== false && $currentUserIndex >= 4) {
|
||||||
|
$showCurrentUserAtBottom = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'rankers' => $rankers,
|
'rankers' => $rankers,
|
||||||
'currentUserRankItem' => $currentUserRankItem
|
'currentUserRankItem' => $showCurrentUserAtBottom ? $currentUserRankItem : null
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
/>
|
/>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
@if($currentUserRankItem && $currentUserRankItem->rank > 5)
|
@if($currentUserRankItem)
|
||||||
<div class="my-3 border-t border-dashed border-gray-100 mx-2"></div>
|
<div class="my-3 border-t border-dashed border-gray-100 mx-2"></div>
|
||||||
<x-ranking-item
|
<x-ranking-item
|
||||||
rank="{{ $currentUserRankItem->rank }}"
|
rank="{{ $currentUserRankItem->rank }}"
|
||||||
|
|||||||
@@ -92,4 +92,121 @@ class UserDashboardLayoutTest extends TestCase
|
|||||||
$response->assertSee('User A', false);
|
$response->assertSee('User A', false);
|
||||||
$response->assertSee('User B', false);
|
$response->assertSee('User B', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_dashboard_ranking_empty_state_when_no_data(): void
|
||||||
|
{
|
||||||
|
$user = \App\Models\User::create([
|
||||||
|
'msnv' => 5001,
|
||||||
|
'name' => 'User A',
|
||||||
|
'mail' => 'usera@runsystem.net',
|
||||||
|
'pass' => md5('password'),
|
||||||
|
'departments' => 1,
|
||||||
|
'role' => \App\Models\User::ROLE_MEMBER,
|
||||||
|
'status' => \App\Models\User::STATUS_ACTIVE,
|
||||||
|
'card' => 10,
|
||||||
|
'flag_send' => \App\Models\User::FLAG_SEND_ENABLED,
|
||||||
|
'first_login' => \App\Models\User::FIRST_LOGIN_FALSE,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
$response = $this->get('/my-page');
|
||||||
|
$response->assertOk();
|
||||||
|
$response->assertSee('Chưa có xếp hạng cho tháng này', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_dashboard_ranking_dense_rank_and_deterministic_order(): void
|
||||||
|
{
|
||||||
|
$users = [];
|
||||||
|
for ($i = 1; $i <= 5; $i++) {
|
||||||
|
$char = chr(64 + $i);
|
||||||
|
$users[$i] = \App\Models\User::create([
|
||||||
|
'msnv' => 5000 + $i,
|
||||||
|
'name' => "User {$char}",
|
||||||
|
'mail' => "user{$char}@runsystem.net",
|
||||||
|
'pass' => md5('password'),
|
||||||
|
'departments' => 1,
|
||||||
|
'role' => \App\Models\User::ROLE_MEMBER,
|
||||||
|
'status' => \App\Models\User::STATUS_ACTIVE,
|
||||||
|
'card' => 10,
|
||||||
|
'flag_send' => \App\Models\User::FLAG_SEND_ENABLED,
|
||||||
|
'first_login' => \App\Models\User::FIRST_LOGIN_FALSE,
|
||||||
|
]);
|
||||||
|
|
||||||
|
\App\Models\Administration::create([
|
||||||
|
'msnv' => 5000 + $i,
|
||||||
|
'received' => 9,
|
||||||
|
'sender' => 9999,
|
||||||
|
'sent' => 0,
|
||||||
|
'receiver' => null,
|
||||||
|
'date' => \Carbon\Carbon::now()->format('Y-m-d')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->actingAs($users[5]);
|
||||||
|
|
||||||
|
$response = $this->get('/my-page');
|
||||||
|
$response->assertOk();
|
||||||
|
|
||||||
|
$response->assertSee('User A', false);
|
||||||
|
$response->assertSee('User B', false);
|
||||||
|
$response->assertSee('User C', false);
|
||||||
|
$response->assertSee('User D', false);
|
||||||
|
$response->assertSee('User E', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_dashboard_ranking_inactive_users_excluded(): void
|
||||||
|
{
|
||||||
|
$activeUser = \App\Models\User::create([
|
||||||
|
'msnv' => 5001,
|
||||||
|
'name' => 'Active User',
|
||||||
|
'mail' => 'active@runsystem.net',
|
||||||
|
'pass' => md5('password'),
|
||||||
|
'departments' => 1,
|
||||||
|
'role' => \App\Models\User::ROLE_MEMBER,
|
||||||
|
'status' => \App\Models\User::STATUS_ACTIVE,
|
||||||
|
'card' => 10,
|
||||||
|
'flag_send' => \App\Models\User::FLAG_SEND_ENABLED,
|
||||||
|
'first_login' => \App\Models\User::FIRST_LOGIN_FALSE,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$inactiveUser = \App\Models\User::create([
|
||||||
|
'msnv' => 5002,
|
||||||
|
'name' => 'Inactive User',
|
||||||
|
'mail' => 'inactive@runsystem.net',
|
||||||
|
'pass' => md5('password'),
|
||||||
|
'departments' => 1,
|
||||||
|
'role' => \App\Models\User::ROLE_MEMBER,
|
||||||
|
'status' => \App\Models\User::STATUS_INACTIVE,
|
||||||
|
'card' => 10,
|
||||||
|
'flag_send' => \App\Models\User::FLAG_SEND_ENABLED,
|
||||||
|
'first_login' => \App\Models\User::FIRST_LOGIN_FALSE,
|
||||||
|
]);
|
||||||
|
|
||||||
|
\App\Models\Administration::create([
|
||||||
|
'msnv' => 5001,
|
||||||
|
'received' => 10,
|
||||||
|
'sender' => 9999,
|
||||||
|
'sent' => 0,
|
||||||
|
'receiver' => null,
|
||||||
|
'date' => \Carbon\Carbon::now()->format('Y-m-d')
|
||||||
|
]);
|
||||||
|
|
||||||
|
\App\Models\Administration::create([
|
||||||
|
'msnv' => 5002,
|
||||||
|
'received' => 20,
|
||||||
|
'sender' => 9999,
|
||||||
|
'sent' => 0,
|
||||||
|
'receiver' => null,
|
||||||
|
'date' => \Carbon\Carbon::now()->format('Y-m-d')
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->actingAs($activeUser);
|
||||||
|
|
||||||
|
$response = $this->get('/my-page');
|
||||||
|
$response->assertOk();
|
||||||
|
|
||||||
|
$response->assertSee('Active User', false);
|
||||||
|
$response->assertDontSee('Inactive User', false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user