Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 63 additions & 63 deletions src/components/dashboard/LeaderBoard/leaderboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import PRListModal from "./PRListModal";
import { mockContributors } from "./mockData";
import "./leaderboard.css";

const GITHUB_ORG = "recodehive";
const GITHUB_ORG = "recodehive";

// Users to exclude from the leaderboard
const EXCLUDED_USERS = ["sanjay-kv", "allcontributors", "allcontributors[bot]"];
Expand Down Expand Up @@ -44,15 +44,15 @@ interface Stats {
flooredTotalPoints: number;
}

function Badge({
count,
label,
color,
function Badge({
count,
label,
color,
onClick,
clickable = false
}: {
count: number;
label: string;
clickable = false
}: {
count: number;
label: string;
color: { background: string; color: string };
onClick?: () => void;
clickable?: boolean;
Expand All @@ -77,7 +77,7 @@ function Badge({
};

return (
<span
<span
className={`badge ${clickable ? 'clickable' : ''}`}
style={badgeStyle}
onClick={handleClick}
Expand All @@ -91,19 +91,19 @@ function Badge({
);
}

function TopPerformerCard({
contributor,
rank,
onPRClick
}: {
contributor: Contributor;
function TopPerformerCard({
contributor,
rank,
onPRClick
}: {
contributor: Contributor;
rank: number;
onPRClick: (contributor: Contributor) => void;
}) {
const { colorMode } = useColorMode();
const isDark = colorMode === "dark";
const rankClass = rank === 1 ? "top-1" : rank === 2 ? "top-2" : "top-3";

return (
<div className={`top-performer-card ${isDark ? "dark" : "light"}`}>
<img src={contributor.avatar} alt={contributor.username} className="avatar large" />
Expand All @@ -115,9 +115,9 @@ function TopPerformerCard({
{contributor.username}
</a>
<div className="badges-container">
<Badge
count={contributor.prs}
label="PRs"
<Badge
count={contributor.prs}
label="PRs"
color={{ background: "#dbeafe", color: "#2563eb" }}
onClick={() => onPRClick(contributor)}
clickable={true}
Expand All @@ -131,15 +131,15 @@ function TopPerformerCard({

export default function LeaderBoard(): JSX.Element {
// Get time filter functions from context
const {
contributors,
stats,
loading,
error,
currentTimeFilter,
setTimeFilter
const {
contributors,
stats,
loading,
error,
currentTimeFilter,
setTimeFilter
} = useCommunityStatsContext();

const { colorMode } = useColorMode();
const isDark = colorMode === "dark";

Expand All @@ -165,15 +165,15 @@ export default function LeaderBoard(): JSX.Element {
const displayContributors =
(error || contributors.length === 0)
? (typeof process !== "undefined" && process.env.NODE_ENV === "development"
? mockContributors
: [])
? mockContributors
: [])
: contributors;


// Filter out excluded users and apply search filter
const filteredContributors = contributors
.filter((contributor) =>
!EXCLUDED_USERS.some(excludedUser =>
.filter((contributor) =>
!EXCLUDED_USERS.some(excludedUser =>
contributor.username.toLowerCase() === excludedUser.toLowerCase()
)
)
Expand All @@ -191,7 +191,7 @@ export default function LeaderBoard(): JSX.Element {
const renderPaginationButtons = () => {
const pages = [];
const maxVisibleButtons = 5; // Maximum number of page buttons to show directly

// Special case: if we have 7 or fewer pages, show all of them without ellipsis
if (totalPages <= 7) {
for (let i = 1; i <= totalPages; i++) {
Expand All @@ -207,9 +207,9 @@ export default function LeaderBoard(): JSX.Element {
}
return pages;
}

// For more than 7 pages, use the ellipsis approach

// Always show first page
pages.push(
<button
Expand All @@ -220,12 +220,12 @@ export default function LeaderBoard(): JSX.Element {
1
</button>
);

// Calculate the range of pages to show (middle section)
// We want to show current page and 1-2 pages before and after when possible
let startPage = Math.max(2, currentPage - 1);
let endPage = Math.min(totalPages - 1, currentPage + 1);

// Adjust start and end page if we're near the beginning or end
if (currentPage <= 3) {
// Near the beginning, show pages 2, 3, 4
Expand All @@ -236,14 +236,14 @@ export default function LeaderBoard(): JSX.Element {
endPage = totalPages - 1;
startPage = Math.max(2, totalPages - 3);
}

// Show ellipsis if needed before the middle range
if (startPage > 2) {
pages.push(
<span key="ellipsis-1" className="pagination-ellipsis">...</span>
);
}

// Show pages in the middle range
for (let i = startPage; i <= endPage; i++) {
pages.push(
Expand All @@ -256,14 +256,14 @@ export default function LeaderBoard(): JSX.Element {
</button>
);
}

// Show ellipsis if needed after the middle range
if (endPage < totalPages - 1) {
pages.push(
<span key="ellipsis-2" className="pagination-ellipsis">...</span>
);
}

// Always show last page
pages.push(
<button
Expand All @@ -274,7 +274,7 @@ export default function LeaderBoard(): JSX.Element {
{totalPages}
</button>
);

return pages;
};

Expand All @@ -289,7 +289,7 @@ export default function LeaderBoard(): JSX.Element {
const getTimeFilterLabel = (filter: string) => {
switch (filter) {
case 'week': return '📊 This Week';
case 'month': return '📆 This Month';
case 'month': return '📆 This Month';
case 'year': return '📅 This Year';
case 'all': return '🏆 All Time';
default: return '🏆 All Time';
Expand All @@ -306,17 +306,17 @@ export default function LeaderBoard(): JSX.Element {
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<h1 className="title">recode hive Leaderboard</h1>
<h1 className="title">Recode Hive Leaderboard</h1>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was not a mistake this was done on purpose

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done on Purpose @sheikhlimon

<p className={`subtitle ${isDark ? "dark" : "light"}`}>
Top contributors across the <strong>{GITHUB_ORG}</strong> organization
Top contributors across the <strong>Recode Hive</strong> organization
</p>
</motion.div>

{/* Top 3 Performers Section */}
{!loading && filteredContributors.length > 2 && (
<div className="top-performers-container">
<div className="title-filter-container">
<h2 className={`top-performers-title ${isDark ? "dark" : "light"}`}>recode hive Top Performers</h2>
<h2 className={`top-performers-title ${isDark ? "dark" : "light"}`}>Recode Hive Top Performers</h2>
<div className="time-filter-wrapper top-title-filter">
<label htmlFor="time-period-filter" className="filter-label">Time Period:</label>
<select
Expand Down Expand Up @@ -440,11 +440,11 @@ export default function LeaderBoard(): JSX.Element {
{!loading && filteredContributors.length > 0 && (
<div className={`contributors-container ${isDark ? "dark" : "light"}`}>
{error && (
<div className="error-banner" style={{
padding: '12px',
backgroundColor: isDark ? '#fee8e7' : '#fee8e7',
color: '#dc2626',
borderRadius: '8px',
<div className="error-banner" style={{
padding: '12px',
backgroundColor: isDark ? '#fee8e7' : '#fee8e7',
color: '#dc2626',
borderRadius: '8px',
marginBottom: '16px',
fontSize: '14px',
textAlign: 'center'
Expand All @@ -453,11 +453,11 @@ export default function LeaderBoard(): JSX.Element {
</div>
)}
<div className="contributors-header">
<div className="contributor-cell rank">Rank</div>
<div className="contributor-cell avatar-cell">Avatar</div>
<div className="contributor-cell username-cell">User</div>
<div className="contributor-cell prs-cell">PRs</div>
<div className="contributor-cell points-cell">Points</div>
<div className="contributor-cell rank">Rank</div>
<div className="contributor-cell avatar-cell">Avatar</div>
<div className="contributor-cell username-cell">User</div>
<div className="contributor-cell prs-cell">PRs</div>
<div className="contributor-cell points-cell">Points</div>
</div>
{currentItems.map((contributor, index) => (
<motion.div
Expand All @@ -480,14 +480,14 @@ export default function LeaderBoard(): JSX.Element {
/>
</div>
<div className="contributor-cell username-cell">
<a href={contributor.profile} target="_blank" rel="noreferrer" className={`username-link ${isDark ? "dark" : "light"}`}>
{contributor.username}
</a>
<a href={contributor.profile} target="_blank" rel="noreferrer" className={`username-link ${isDark ? "dark" : "light"}`}>
{contributor.username}
</a>
</div>
<div className="contributor-cell prs-cell">
<Badge
count={contributor.prs}
label="PRs"
<Badge
count={contributor.prs}
label="PRs"
color={{ background: "#dbeafe", color: "#2563eb" }}
onClick={() => handlePRClick(contributor)}
clickable={true}
Expand Down Expand Up @@ -523,7 +523,7 @@ export default function LeaderBoard(): JSX.Element {
</button>
</div>
)}

{/* CTA Footer */}
<div className={`cta-footer ${isDark ? "dark" : "light"}`}>
<p className={`cta-text ${isDark ? "dark" : "light"}`}>Want to get on this leaderboard?</p>
Expand Down
Loading
Loading