Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d677374
Update Footer.jsx
aryan-anand-sde Jan 7, 2025
0320aa6
Update Footer.jsx
aryan-anand-sde Jan 7, 2025
bd1366b
Update Footer.jsx
aryan-anand-sde Jan 7, 2025
69cbe5d
fix: Fixed the bug of unverified user shown on leaderboard
Nishant040305 Jan 7, 2025
a45dca2
style: Change the leaderboard styling with some proper ranking change
Nishant040305 Jan 7, 2025
2fdd854
Merge branch 'adityarai0705:main' into main
Nishant040305 Jan 7, 2025
70050da
style: Add rank position
Nishant040305 Jan 7, 2025
bc2cb5c
fix: Invalid User profile detail shown handled
Nishant040305 Jan 7, 2025
df10c64
Merge branch 'adityarai0705:main' into main
Nishant040305 Jan 9, 2025
8438984
Merge branch 'main' of https://github.com/Nishant040305/CodeHub
Nishant040305 Jan 9, 2025
cf426b9
Update Footer.jsx
aryan-anand-sde Jan 9, 2025
578bafd
fix: Bug fixed of Duplicate key E11000 Duplicate key error in tempUser
Nishant040305 Jan 9, 2025
0c00f78
Fix: Changed env variable name
CoderFleet Jan 9, 2025
77e9a8e
Merge pull request #68 from CoderFleet/fix/env-var-mismatch
dwargosama Jan 10, 2025
d303c3f
Update Footer.jsx
aryan-anand-sde Jan 11, 2025
d1cc2a3
Update Footer.jsx
aryan-anand-sde Jan 12, 2025
7b706a3
Update Footer.jsx
aryan-anand-sde Jan 12, 2025
b9c96fc
Merge pull request #49 from aryan-anand-sde/main
dwargosama Jan 12, 2025
52a5433
Merge pull request #76 from adityarai0705/version-1.2
dwargosama Jan 12, 2025
d2d6973
feat: Add models for storing the latest cfData and leaderboard
Nishant040305 Jan 14, 2025
f738c3a
feat: Add controllers for leaderboard related updates and fetch
Nishant040305 Jan 14, 2025
69d2df7
Chore: refactor the leaderboard.jsx frontend file and endpoints added
Nishant040305 Jan 14, 2025
cfda756
Merge branch 'adityarai0705:main' into main
Nishant040305 Jan 14, 2025
4ab4c48
Merge branch 'main' of https://github.com/Nishant040305/CodeHub
Nishant040305 Jan 14, 2025
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
4 changes: 3 additions & 1 deletion client-side/src/components/Footer/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@ export default function Footer() {
</div>
<div className="footerTitle">
<span>&#169; {year} CodeHub. All Rights Reserved.</span>
<br />
</div>
<div className="LinkContainer">
{/* <a href="mailto:computer.club@mnnit.ac.in" className="FooterLink">Contact Us</a> */}
<a href="https://github.com/adityarai0705/CodeHub/blob/main/LICENSE" className='font-normal FooterLink'>License </a>
<a href="https://github.com/adityarai0705/CodeHub/blob/main/CODE_OF_CONDUCT.md" className='font-normal FooterLink'> Code of Conduct</a>
</div>
<hr className="sectionDivider" />
<div className='additionalInfo'>
Expand All @@ -72,4 +75,3 @@ export default function Footer() {

)
}

18 changes: 15 additions & 3 deletions client-side/src/pages/DashBoard/dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,18 @@ export default function UserHome() {
if (id) {
cfID = id;
}
console.log(cfID);

const redirect = async (cfID) => {
try{
const response = await axios.get(`${process.env.REACT_APP_SERVER_BASE_URL}/check/user/${cfID}`,{withCredentials: true});
if(response.data.status === false){
navigate("/");
}
}catch(error){
console.log(error);
navigate("/");
}

}
let userData = { status: "", data: {} };
let userRating = { status: "", data: {} };
let userSubmissions = { status: "", data: {} };
Expand Down Expand Up @@ -100,14 +110,15 @@ export default function UserHome() {
// API calls and Initialisation of Data Members
try {
console.log(cfID);

const userDataAPI = await axios.get("https://codeforces.com/api/user.info?handles=" + cfID);
const userRatingAPI = await axios.get("https://codeforces.com/api/user.rating?handle=" + cfID);
const userSubmissionsAPI = await axios.get("https://codeforces.com/api/user.status?handle=" + cfID);
console.log("Api calls done");

userData.status = userDataAPI.data.status;
userData.data = userDataAPI.data.result[0];

const userUpdate = await axios.post(`${process.env.REACT_APP_SERVER_BASE_URL}/updateCFData`,{username:userData.data.handle,avatar:userData.data.avatar,rating:userData.data.rating,rank:userData.data.rank},{withCredentials: true});
userRating.status = userRatingAPI.data.status;
userRating.data = userRatingAPI.data.result;

Expand Down Expand Up @@ -244,6 +255,7 @@ export default function UserHome() {
}

useEffect(() => {
redirect(cfID);
fetchData();
}, [cfID]);

Expand Down
82 changes: 82 additions & 0 deletions client-side/src/pages/Leaderboard/LeaderUser.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React from 'react';
import './Leaderboard.css'; // Ensure this includes styles for user avatars, ranks, etc.
import { useNavigate } from 'react-router-dom';
function LeaderUser(props) {
const { avatar, name, rank, rating, positionChange, title, cfID } = props;
const navigate = useNavigate();
// Compare rating with the leaderboard
// Rank color based on Codeforces rank
const rankColor = getRankColor(title);

// Handle user click to navigate to the user's Codeforces profile
const handleUserClick = () => {
navigate(`/get-codeforces-profile/${cfID}`);
};
const handleCodeforcesRedirect = () => {
window.open(`https://codeforces.com/profile/${cfID}`, "_blank");
};

return (
<div className="leader-box" onClick={handleUserClick}>
<div className="leader-info">
<button className='p-2 bg-transparent border-none' onClick={()=>{handleCodeforcesRedirect()}}>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
id="code-forces"
width="24"
height="24"
>
<path fill="#F44336" d="M24 19.5V12a1.5 1.5 0 0 0-1.5-1.5h-3A1.5 1.5 0 0 0 18 12v7.5a1.5 1.5 0 0 0 1.5 1.5h3a1.5 1.5 0 0 0 1.5-1.5z" />
<path fill="#2196F3" d="M13.5 21a1.5 1.5 0 0 0 1.5-1.5v-15A1.5 1.5 0 0 0 13.5 3h-3C9.673 3 9 3.672 9 4.5v15c0 .828.673 1.5 1.5 1.5h3z" />
<path fill="#FFC107" d="M0 19.5c0 .828.673 1.5 1.5 1.5h3A1.5 1.5 0 0 0 6 19.5V9a1.5 1.5 0 0 0-1.5-1.5h-3C.673 7.5 0 8.172 0 9v10.5z" />
</svg>
</button>
<img src={avatar} alt={`${name} Avatar`} className="user-avatar" />
<b className='p-2 text-gray-600'>#{rank}</b><span className="leader-rank" style={{ color: rankColor }}>
{name}
</span>

</div>


<div className="leader-rating">
<div>
{positionChange === 0 && (
<span style={{ color: 'gray' }}>
<span>&#8594;</span> 0
</span>
)}
{positionChange > 0 && (
<span style={{ color: 'green' }}>
<span>&#9650;</span> +{positionChange}
</span>
)}
{positionChange < 0 && (
<span style={{ color: 'red' }}>
<span>&#9660;</span> {positionChange}
</span>
)}
</div>
</div>
</div>
);
}

function getRankColor(rank) {
switch(rank.toLowerCase()) {
case 'newbie': return '#A0A0A0'; // gray
case 'pupil': return '#66CDAA'; // medium sea green
case 'specialist': return '#40E0D0'; // turquoise (cyan)
case 'expert': return '#4682B4'; // steel blue (blue)
case 'candidate master': return '#8A2BE2'; // blue violet (purple)
case 'master': return '#FF7F50'; // coral (orange)
case 'international master': return '#B22222'; // firebrick (red)
case 'grandmaster': return '#8B0000'; // dark red
case 'international grandmaster': return '#8B0000'; // dark red
case 'legendary grandmaster': return '#8B0000'; // dark red
default: return '#000000'; // black
}
}

export default LeaderUser;
101 changes: 60 additions & 41 deletions client-side/src/pages/Leaderboard/Leaderboard.css
Original file line number Diff line number Diff line change
@@ -1,56 +1,75 @@
.leader-heading {
font-size: xx-large;
color: #F94479;
font-size: 36px;
font-weight: bold;
color: #3f3f3f;
margin-bottom: 10px;
}

.leader-description {
font-size: 16px;
color: #555;
line-height: 1.6;
max-width: 80%;
margin: 0 auto;
}
.leader-heading-container {
text-align: center;
padding: 20px;
margin-bottom: 20px;
margin-top:20px;
}

.leader-box {
padding: 10px;
background-color: white;
color: rgb(39, 8, 82);
text-align: center;
margin-left: 20px;
margin-right: 20px;
border: 0.5px solid rgb(39, 8, 82);
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 10px;
border: 1px solid #ddd;
margin: 5px 0;
border-radius: 5px;
background-color: #f7f7f7;
cursor: pointer;
transition: background-color 0.3s ease;
}

.leader-box:hover {
background-color: #e0e0e0;
}

.leader-info {
display: flex;
align-items: center;
}

.user-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 10px;
}

.leader-box:hover{
background-color: rgb(234, 227, 252);
.leader-rank {
font-size: 16px;
font-weight: bold;
}

.leader-rating {
display: flex;
align-items: center;
}

.leader-title {
.leader-rating-value {
font-size: 18px;
font-weight: bold;
width: 100%;
font-size: larger;
text-align: left;
}
.leader-date {
width: 100%;
text-align: left;
font-size: smaller;
margin-bottom: 5px;
}
.leader-body {
text-align: justify;
width: 100%;
}
pre {
white-space: pre-wrap;
}
.leader-footer {
text-align: center;
font-size: small;
margin-left: 20px;
margin-right: 20px;
margin-right: 10px;
}

.rating-change {
font-size: 16px;
}

@media screen and (max-width: 480px) {
.leader-reg{
display: none;
}
}
.positive {
color: green;
}

.negative {
color: red;
}
Loading