Skip to content

Commit 9cf9665

Browse files
committed
Reconstructs top performers in podium
1 parent 3e9ef4d commit 9cf9665

File tree

2 files changed

+238
-86
lines changed

2 files changed

+238
-86
lines changed

src/components/dashboard/LeaderBoard/leaderboard.css

Lines changed: 161 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -77,116 +77,206 @@
7777
color: #f1f1f1;
7878
}
7979

80-
.top-title-filter {
80+
/* Podium Layout */
81+
.leaderboard-podium {
8182
display: flex;
82-
align-items: center;
83-
gap: 8px;
84-
min-width: 240px;
85-
}
86-
87-
.filter-label {
88-
font-size: 14px;
89-
font-weight: 600;
90-
white-space: nowrap;
91-
}
92-
93-
.light .filter-label {
94-
color: #4b5563;
95-
}
96-
97-
.dark .filter-label {
98-
color: #d1d5db;
99-
}
100-
101-
.top-performers-grid {
102-
display: grid;
103-
grid-template-columns: 1fr 1fr 1fr;
104-
gap: 24px;
105-
justify-items: center;
106-
align-items: end;
83+
justify-content: center;
84+
align-items: flex-end;
85+
gap: 75px;
86+
padding: 50px 20px 20px;
87+
margin-bottom: 40px;
10788
}
10889

109-
.top-performer-card {
90+
.podium-card {
91+
background-color: white;
92+
padding: 20px;
93+
border-radius: 16px;
94+
width: 200px;
95+
transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out, border 0.3s;
11096
position: relative;
97+
cursor: pointer;
11198
display: flex;
11299
flex-direction: column;
113100
align-items: center;
114101
text-align: center;
115-
padding: 24px;
116-
border-radius: 12px;
117-
transition: all 0.3s ease;
102+
padding-top: 40px;
103+
z-index: 2;
118104
}
119105

120-
.light .top-performer-card {
106+
.light .podium-card {
121107
background: #fff;
122-
border: 1px solid #e2e8f0;
123-
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
108+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
124109
}
125110

126-
.dark .top-performer-card {
111+
.dark .podium-card {
127112
background: #2b303b;
128-
border: 1px solid #444;
129-
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
113+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
130114
}
131115

132-
.top-performer-card:hover {
133-
transform: translateY(-5px);
134-
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
116+
/* Staircase Height Adjustment */
117+
.first-place { transform: translateY(-60px); }
118+
.second-place { transform: translateY(-30px); }
119+
.third-place { transform: translateY(0); }
120+
121+
/* Reflection Effect */
122+
.podium-card::after {
123+
content: '';
124+
position: absolute;
125+
top: 100%;
126+
left: 0;
127+
height: 25%;
128+
width: 100%;
129+
border-radius: 0 0 16px 16px;
130+
background: linear-gradient(
131+
to bottom,
132+
rgba(255, 255, 255, 0.4) 0%,
133+
rgba(255, 255, 255, 0.3) 25%,
134+
rgba(255, 255, 255, 0.1) 75%,
135+
rgba(255, 255, 255, 0.0) 100%
136+
);
137+
transform: scaleY(-1);
138+
z-index: 1;
139+
pointer-events: none;
135140
}
136141

137-
.top-performer-card .avatar.large {
138-
width: 96px;
139-
height: 96px;
142+
.dark .podium-card::after {
143+
background: linear-gradient(
144+
to bottom,
145+
rgba(43, 48, 59, 0.4) 0%,
146+
rgba(43, 48, 59, 0.3) 25%,
147+
rgba(43, 48, 59, 0.1) 75%,
148+
rgba(43, 48, 59, 0.0) 100%
149+
);
150+
}
151+
152+
/* Reflection box-shadows */
153+
.first-place::after { box-shadow: 0 2px 6px rgba(255, 215, 0, 0.1); }
154+
.second-place::after { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); }
155+
.third-place::after { box-shadow: 0 2px 6px rgba(205, 127, 50, 0.1); }
156+
157+
/* User Photo */
158+
.podium-card .user-photo {
159+
width: 80px;
160+
height: 80px;
140161
border-radius: 50%;
141-
margin-bottom: 12px;
142-
border: 4px solid #fff;
143-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
162+
object-fit: cover;
163+
margin-bottom: 10px;
164+
border: 4px solid #f0f0f0;
144165
}
145166

146-
.dark .top-performer-card .avatar.large {
147-
border: 4px solid #23272f;
167+
.dark .podium-card .user-photo {
168+
border-color: #444;
148169
}
149170

150-
.rank-overlay {
171+
/* Rank Badge */
172+
.podium-card .rank-badge {
151173
position: absolute;
152-
top: 8px;
153-
left: 8px;
174+
top: 0;
175+
right: 50%;
176+
transform: translate(50%, -50%);
177+
width: 36px;
178+
height: 36px;
179+
border-radius: 50%;
180+
color: white;
154181
display: flex;
155182
justify-content: center;
156183
align-items: center;
157-
width: 40px;
158-
height: 40px;
159-
border-radius: 50%;
160184
font-weight: bold;
161-
color: #fff;
162-
border: 2px solid #fff;
185+
font-size: 1.2em;
186+
z-index: 10;
187+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
188+
border: 3px solid white;
163189
}
164190

165-
.rank-overlay.top-1 {
166-
background-color: #f59e0b;
167-
border-color: #fde68a;
168-
box-shadow: 0 0 10px #fde047;
191+
.dark .podium-card .rank-badge {
192+
border-color: #2b303b;
169193
}
170194

171-
.rank-overlay.top-2 {
172-
background-color: #6b7280;
173-
border-color: #d1d5db;
195+
.first-place .rank-badge { background-color: #FFD700; }
196+
.second-place .rank-badge { background-color: #555; }
197+
.third-place .rank-badge { background-color: #CD7F32; }
198+
199+
/* User Details */
200+
.podium-card .details {
201+
width: 100%;
174202
}
175203

176-
.rank-overlay.top-3 {
177-
background-color: #964b00;
178-
border-color: #fcd34d;
204+
.podium-card .username {
205+
font-weight: 700;
206+
margin: 0 0 5px 0;
207+
font-size: 1.1em;
208+
color: #4b89e3;
179209
}
180210

181-
.performer-info {
182-
margin-top: 8px;
211+
.dark .podium-card .username {
212+
color: #60a5fa;
213+
}
214+
215+
.podium-card .stats {
216+
display: flex;
217+
gap: 8px;
218+
margin-top: 5px;
219+
justify-content: center;
183220
}
184221

185-
.performer-info .username-link {
222+
.podium-card .prs,
223+
.podium-card .points {
224+
font-size: 0.8em;
225+
padding: 4px 10px;
226+
border-radius: 20px;
186227
font-weight: bold;
187-
font-size: 1.1rem;
188-
color: #6366f1;
189-
text-decoration: none;
228+
background-color: #e6e0f1;
229+
color: #6a5acd;
230+
border: none;
231+
cursor: pointer;
232+
transition: all 0.2s ease;
233+
}
234+
235+
.dark .podium-card .prs,
236+
.dark .podium-card .points {
237+
background-color: #374151;
238+
color: #8b5cf6;
239+
}
240+
241+
.podium-card .prs:hover {
242+
transform: translateY(-1px);
243+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
244+
}
245+
246+
/* Hover Effects */
247+
.podium-card:hover {
248+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
249+
}
250+
251+
.first-place:hover {
252+
transform: translateY(-65px);
253+
border-color: #FFD700;
254+
box-shadow: 0 0 15px rgba(255, 215, 0, 0.7), 0 10px 30px rgba(0, 0, 0, 0.15);
255+
}
256+
257+
.second-place:hover {
258+
transform: translateY(-35px);
259+
border-color: #C0C0C0;
260+
box-shadow: 0 0 15px rgba(192, 192, 192, 0.7), 0 10px 30px rgba(0, 0, 0, 0.15);
261+
}
262+
263+
.third-place:hover {
264+
transform: translateY(-5px);
265+
border-color: #CD7F32;
266+
box-shadow: 0 0 15px rgba(205, 127, 50, 0.7), 0 10px 30px rgba(0, 0, 0, 0.15);
267+
}
268+
269+
/* Dark Mode Hover Effects */
270+
.dark .first-place:hover {
271+
box-shadow: 0 0 15px rgba(255, 215, 0, 0.3), 0 10px 30px rgba(0, 0, 0, 0.3);
272+
}
273+
274+
.dark .second-place:hover {
275+
box-shadow: 0 0 15px rgba(192, 192, 192, 0.3), 0 10px 30px rgba(0, 0, 0, 0.3);
276+
}
277+
278+
.dark .third-place:hover {
279+
box-shadow: 0 0 15px rgba(205, 127, 50, 0.3), 0 10px 30px rgba(0, 0, 0, 0.3);
190280
}
191281

192282
/* Stats Grid */

src/components/dashboard/LeaderBoard/leaderboard.tsx

Lines changed: 77 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -364,21 +364,83 @@ export default function LeaderBoard(): JSX.Element {
364364
</div>
365365
</div>
366366
<div className="top-performers-grid">
367-
<TopPerformerCard
368-
contributor={filteredContributors[1]}
369-
rank={2}
370-
onPRClick={handlePRClick}
371-
/>
372-
<TopPerformerCard
373-
contributor={filteredContributors[0]}
374-
rank={1}
375-
onPRClick={handlePRClick}
376-
/>
377-
<TopPerformerCard
378-
contributor={filteredContributors[2]}
379-
rank={3}
380-
onPRClick={handlePRClick}
381-
/>
367+
{/* Podium-style top performers — adapted from index.html's leaderboard-podium */}
368+
<div className="leaderboard-podium">
369+
{/* Second place */}
370+
{filteredContributors[1] && (
371+
<div className="podium-card second-place">
372+
<span className="rank-badge">2</span>
373+
<img
374+
src={filteredContributors[1].avatar}
375+
alt={filteredContributors[1].username}
376+
className="user-photo"
377+
/>
378+
<div className="details">
379+
<p className="username">{filteredContributors[1].username}</p>
380+
<div className="stats">
381+
<button
382+
className="prs"
383+
onClick={() => handlePRClick(filteredContributors[1])}
384+
aria-label={`View PRs for ${filteredContributors[1].username}`}
385+
>
386+
{filteredContributors[1].prs} PRs
387+
</button>
388+
<span className="points">{filteredContributors[1].points} Points</span>
389+
</div>
390+
</div>
391+
</div>
392+
)}
393+
394+
{/* First place */}
395+
{filteredContributors[0] && (
396+
<div className="podium-card first-place">
397+
<span className="rank-badge">1</span>
398+
<img
399+
src={filteredContributors[0].avatar}
400+
alt={filteredContributors[0].username}
401+
className="user-photo"
402+
/>
403+
<div className="details">
404+
<p className="username">{filteredContributors[0].username}</p>
405+
<div className="stats">
406+
<button
407+
className="prs"
408+
onClick={() => handlePRClick(filteredContributors[0])}
409+
aria-label={`View PRs for ${filteredContributors[0].username}`}
410+
>
411+
{filteredContributors[0].prs} PRs
412+
</button>
413+
<span className="points">{filteredContributors[0].points} Points</span>
414+
</div>
415+
</div>
416+
</div>
417+
)}
418+
419+
{/* Third place */}
420+
{filteredContributors[2] && (
421+
<div className="podium-card third-place">
422+
<span className="rank-badge">3</span>
423+
<img
424+
src={filteredContributors[2].avatar}
425+
alt={filteredContributors[2].username}
426+
className="user-photo"
427+
/>
428+
<div className="details">
429+
<p className="username">{filteredContributors[2].username}</p>
430+
<div className="stats">
431+
<button
432+
className="prs"
433+
onClick={() => handlePRClick(filteredContributors[2])}
434+
aria-label={`View PRs for ${filteredContributors[2].username}`}
435+
>
436+
{filteredContributors[2].prs} PRs
437+
</button>
438+
<span className="points">{filteredContributors[2].points} Points</span>
439+
</div>
440+
</div>
441+
</div>
442+
)}
443+
</div>
382444
</div>
383445
</div>
384446
)}

0 commit comments

Comments
 (0)