Skip to content

Commit a21dd78

Browse files
author
iitzIrFan
committed
Add time period filter and improve contributor sorting in leaderboard
1 parent 66c13cc commit a21dd78

File tree

1 file changed

+49
-23
lines changed

1 file changed

+49
-23
lines changed

src/components/dashboard/LeaderBoard/leaderboard.tsx

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export default function LeaderBoard(): JSX.Element {
7676
const [searchQuery, setSearchQuery] = useState("");
7777
const [currentPage, setCurrentPage] = useState(1);
7878
const [timePeriod, setTimePeriod] = useState<TimePeriod>("all");
79+
const [isSelectChanged, setIsSelectChanged] = useState(false);
7980
const itemsPerPage = 10;
8081

8182
// Get contributions within the selected time period
@@ -135,7 +136,20 @@ export default function LeaderBoard(): JSX.Element {
135136
)
136137
.filter((contributor) =>
137138
contributor.username.toLowerCase().includes(searchQuery.toLowerCase())
138-
);
139+
)
140+
// Re-sort contributors after filtering to ensure proper ranking
141+
.sort((a, b) => {
142+
// First sort by points (descending)
143+
if (b.points !== a.points) {
144+
return b.points - a.points;
145+
}
146+
// If points are equal, sort by PRs (descending)
147+
if (b.prs !== a.prs) {
148+
return b.prs - a.prs;
149+
}
150+
// If both points and PRs are equal, sort alphabetically by username (ascending)
151+
return a.username.localeCompare(b.username);
152+
});
139153

140154
const totalPages = Math.ceil(filteredContributors.length / itemsPerPage);
141155
const indexOfLast = currentPage * itemsPerPage;
@@ -260,11 +274,38 @@ export default function LeaderBoard(): JSX.Element {
260274
{/* Top 3 Performers Section */}
261275
{!loading && !error && filteredContributors.length > 2 && (
262276
<div className="top-performers-container">
263-
<h2 className={`top-performers-title ${isDark ? "dark" : "light"}`}>RecodeHive Top Performers</h2>
277+
<div className="title-filter-container">
278+
<h2 className={`top-performers-title ${isDark ? "dark" : "light"}`}>RecodeHive Top Performers</h2>
279+
<div className="time-filter-wrapper top-title-filter">
280+
<label htmlFor="time-period-filter" className="filter-label">Time Period:</label>
281+
<select
282+
id="time-period-filter"
283+
value={timePeriod}
284+
onChange={(e) => {
285+
setTimePeriod(e.target.value as TimePeriod);
286+
setCurrentPage(1);
287+
setIsSelectChanged(true);
288+
setTimeout(() => setIsSelectChanged(false), 1200);
289+
}}
290+
className={`time-filter-select ${isDark ? "dark" : "light"} ${isSelectChanged ? 'highlight-change' : ''}`}
291+
>
292+
<option value="all">🏆 All Time</option>
293+
<option value="yearly">📅 Past Year</option>
294+
<option value="monthly">📆 Past Month</option>
295+
<option value="weekly">📊 Past Week</option>
296+
</select>
297+
</div>
298+
</div>
264299
<div className="top-performers-grid">
265-
<TopPerformerCard contributor={filteredContributors[1]} rank={2} />
266-
<TopPerformerCard contributor={filteredContributors[0]} rank={1} />
267-
<TopPerformerCard contributor={filteredContributors[2]} rank={3} />
300+
{filteredContributors.length >= 2 && (
301+
<TopPerformerCard contributor={filteredContributors[1]} rank={2} />
302+
)}
303+
{filteredContributors.length >= 1 && (
304+
<TopPerformerCard contributor={filteredContributors[0]} rank={1} />
305+
)}
306+
{filteredContributors.length >= 3 && (
307+
<TopPerformerCard contributor={filteredContributors[2]} rank={3} />
308+
)}
268309
</div>
269310
</div>
270311
)}
@@ -308,7 +349,7 @@ export default function LeaderBoard(): JSX.Element {
308349
</div>
309350
)}
310351

311-
{/* Search and Filter */}
352+
{/* Search */}
312353
<div className="search-container">
313354
<div className="search-wrapper">
314355
<FaSearch className={`search-icon ${isDark ? "dark" : "light"}`} />
@@ -323,21 +364,6 @@ export default function LeaderBoard(): JSX.Element {
323364
className={`search-input ${isDark ? "dark" : "light"}`}
324365
/>
325366
</div>
326-
<div className="time-filter-wrapper">
327-
<select
328-
value={timePeriod}
329-
onChange={(e) => {
330-
setTimePeriod(e.target.value as TimePeriod);
331-
setCurrentPage(1);
332-
}}
333-
className={`time-filter-select ${isDark ? "dark" : "light"}`}
334-
>
335-
<option value="all">All Time</option>
336-
<option value="yearly">Past Year</option>
337-
<option value="monthly">Past Month</option>
338-
<option value="weekly">Past Week</option>
339-
</select>
340-
</div>
341367
</div>
342368

343369
{loading && (
@@ -393,8 +419,8 @@ export default function LeaderBoard(): JSX.Element {
393419
className={`contributor-row ${isDark ? (index % 2 === 0 ? "even" : "odd") : (index % 2 === 0 ? "even" : "odd")}`}
394420
>
395421
<div className={`contributor-cell rank-cell`}>
396-
<div className={`rank-badge ${getRankClass(indexOfFirst + index)}`}>
397-
{indexOfFirst + index + 1}
422+
<div className={`rank-badge ${getRankClass(filteredContributors.indexOf(contributor))}`}>
423+
{filteredContributors.indexOf(contributor) + 1}
398424
</div>
399425
</div>
400426
<div className="contributor-cell avatar-cell">

0 commit comments

Comments
 (0)