Skip to content

Commit

Permalink
Merge pull request #47 from Rituraj67/master
Browse files Browse the repository at this point in the history
leetcode
  • Loading branch information
imdeveshshukla authored Aug 25, 2024
2 parents fcb6148 + b0a48cf commit e28113f
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 71 deletions.
39 changes: 39 additions & 0 deletions backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

126 changes: 105 additions & 21 deletions backend/src/controller/search.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import prisma from "../../db/db.config.js";
import CryptoJS from "crypto-js";

import axios from "axios";
import { LeetCode } from "leetcode-query";

export const getUsers = async (req, res) => {
try {
Expand All @@ -23,7 +24,7 @@ export const getUsers = async (req, res) => {
take: limit,
});

let rooms= await prisma.rooms.findMany({
let rooms = await prisma.rooms.findMany({
where: {
title: {
contains: key,
Expand All @@ -37,10 +38,9 @@ export const getUsers = async (req, res) => {
},
take: limit,
});
res.status(200).send({users, rooms });
res.status(200).send({ users, rooms });
} catch (error) {
console.log(error);

}
};

Expand Down Expand Up @@ -199,29 +199,113 @@ export const getUserUpvotes = async (req, res) => {
};

export const getLCdata = async (req, res) => {
const encryptUsername = req.body.username;

try {
const bytes = CryptoJS.AES.decrypt(
encryptUsername,
process.env.LC_SECRETKEY
);
const username = bytes.toString(CryptoJS.enc.Utf8);
console.log("LC_username", username);

const data =await getLeetCodeData(username);


const user = data.matchedUser;

if (!user) {
res.status(404).send({ status: "error" });
}

const solved = user.submitStats.acSubmissionNum;

const totalSolved = solved[0].count;
const easySolved = solved[1].count;
const mediumSolved = solved[2].count;
const hardSolved = solved[3].count;

const succSubmission = solved[0].submissions;
const totalSubmission = user.submitStats.totalSubmissionNum[0].submissions;
const acceptanceRate = ((succSubmission / totalSubmission) * 100).toFixed(
2
);

const contributionPoints = user.contributions.points;
const ranking = user.profile.ranking;

const allQuestions = data.allQuestionsCount;

const encryptUsername = req.body.username;
console.log(encryptUsername);
const totalQuestions = allQuestions[0].count;
const totalEasy = allQuestions[1].count;
const totalMedium = allQuestions[2].count;
const totalHard = allQuestions[3].count;


res.status(200).send({
ranking,
totalQuestions,
totalEasy,
totalMedium,
totalHard,
easySolved,
mediumSolved,
hardSolved,
totalSolved,
acceptanceRate,
contributionPoints,
});
} catch (error) {
console.log(error);
}
};

export const getLeetCodeData = async (username) => {
try {

const query = `
{
allQuestionsCount {
difficulty
count
}
matchedUser(username: "${username}") {
submitStats {
acSubmissionNum {
difficulty
count
submissions
}
totalSubmissionNum {
difficulty
count
submissions
}
}
contributions{
points
questionCount
testcaseCount
}
profile {
ranking
reputation
}
}
const bytes = CryptoJS.AES.decrypt(encryptUsername, process.env.LC_SECRETKEY);
const username = bytes.toString(CryptoJS.enc.Utf8);
console.log("username", username);
console.log("sk", process.env.LC_SECRETKEY);



let data = await fetch(
`https://leetcode-stats-api.herokuapp.com/${username}`
}`;

const response = await axios.post(
"https://leetcode.com/graphql",
{ query },
{
headers: {
"Content-Type": "application/json",
},
}
);
let result = await data.json();
console.log(result);

res.status(202).send(result);
let data = response.data.data;
return data;
} catch (error) {
console.log(error);
}
Expand Down
10 changes: 10 additions & 0 deletions backend/src/controller/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import prisma from "../../db/db.config.js";
import jwt from "jsonwebtoken";
import bcrypt from "bcrypt";
import uploadOnCloudinary from "../utils/cloudinary.js";
import { getLeetCodeData } from "./search.js";

const getUser = async (req, res) => {
const email = req.params?.email;
Expand Down Expand Up @@ -237,6 +238,15 @@ const addLC = async (req, res) => {
const {lcusername}= req.body;

try {
const lcdata= await getLeetCodeData(lcusername);
console.log(lcdata);

const user= lcdata.matchedUser
if(!user){
res.status(404).send("user not found!");
return
}

const data= await prisma.user.update({
where:{
userID,
Expand Down
46 changes: 11 additions & 35 deletions frontend/src/components/LeetCode.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { CircularProgressbar, buildStyles } from 'react-circular-progressbar';
import 'react-circular-progressbar/dist/styles.css';
import Greencheck from '../assets/Greencheck';
import { useSelector } from 'react-redux';
import { SlBadge } from "react-icons/sl";
import { FaRankingStar } from "react-icons/fa6";
import toast from 'react-hot-toast';

import { FaTrophy } from "react-icons/fa"
import { SiLeetcode } from 'react-icons/si';
import { LeetCodeSkelton } from './Postskelton';
Expand All @@ -23,20 +23,6 @@ const LeetCode = () => {
const [isLoading, setisLoading] = useState(false)


const keysToKeep = [
"acceptanceRate",
"contributionPoints",
"easySolved",
"hardSolved",
"mediumSolved",
"ranking",
"totalEasy",
"totalHard",
"totalMedium",
"totalQuestions",
"totalSolved"
];

const {
acceptanceRate,
contributionPoints,
Expand Down Expand Up @@ -71,21 +57,14 @@ const LeetCode = () => {


let res = await axios.post(`${baseAddress}search/getLCdata/`, {username: encUsername});


if (res.data.status == "success") {
const lcdata = Object.keys(res.data)
.filter(key => keysToKeep.includes(key))
.reduce((obj, key) => {
obj[key] = res.data[key];
return obj;
}, {});

setlcdata(lcdata);
if (res.status==200) {

setlcdata(res.data);

} else {
console.log("User Not Found");
seterror("Invalid Username!")
console.log("Some error occured!");
toast.error("Some error occured!")

}

Expand Down Expand Up @@ -157,7 +136,7 @@ const LeetCode = () => {

</div>

<div style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }}>
<div style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }}>
<CircularProgressbar
value={easySolvedPercentage - easySolvedPercentage / 8}
styles={buildStyles({
Expand Down Expand Up @@ -209,7 +188,7 @@ const LeetCode = () => {
<CircularProgressbar
value={hardPercentage - easyPercentage / 8}
styles={buildStyles({
pathColor: '#512b2b', // Red for Hard
pathColor: '#512b2b',
trailColor: 'transparent',
pathTransitionDuration: 0.5,
})}
Expand All @@ -224,7 +203,7 @@ const LeetCode = () => {
<CircularProgressbar
value={hardSolvedPercentage - easySolvedPercentage / 8}
styles={buildStyles({
pathColor: '#f63737', // Red for Hard
pathColor: '#f63737',
trailColor: 'transparent',
pathTransitionDuration: 0.5,
})}
Expand All @@ -235,10 +214,7 @@ const LeetCode = () => {





{/* Display the text in the center */}
<div className="progress-text " style={{ position: 'absolute', top: '50%', left: '50%', translate: '-50% -50%', color: '#fff', textAlign: 'center' }}>
<div className="progress-text cursor-default" style={{ position: 'absolute', top: '50%', left: '50%', translate: '-50% -50%', color: '#fff', textAlign: 'center' }}>
<div className=' flex items-baseline text-gray-600'> <span className=' text-2xl font-semibold'>{showAccRate ? leftPart : totalSolved || 0}</span> <span className=' font-semibold text-sm'>{showAccRate ? `.${rightPart}%` : `/${totalQuestions || 0}`}</span></div>
<div className=' flex items-center gap-1 justify-center'> {!showAccRate && <span><Greencheck /></span>} <span className='text-black'>
{showAccRate ? 'Acceptance' : 'Solved'}</span></div>
Expand Down
Loading

0 comments on commit e28113f

Please sign in to comment.