From 55f00eb2091bcbbc23f77fd941ac5088060e884b Mon Sep 17 00:00:00 2001 From: Akash Singh Date: Thu, 14 Mar 2024 19:49:05 +0530 Subject: [PATCH] Add Leetcode Badges on About page --- .../src/context/CommunityStats/index.tsx | 88 ++++- .../src/prepverse-theme/about-me-profile.tsx | 19 +- .../about-section/leetcode-section.tsx | 318 ++++++++++++++++++ 3 files changed, 416 insertions(+), 9 deletions(-) create mode 100644 documentation/src/prepverse-theme/about-section/leetcode-section.tsx diff --git a/documentation/src/context/CommunityStats/index.tsx b/documentation/src/context/CommunityStats/index.tsx index 01079cd3..138fa82b 100644 --- a/documentation/src/context/CommunityStats/index.tsx +++ b/documentation/src/context/CommunityStats/index.tsx @@ -16,7 +16,13 @@ interface ICommunityStatsContext { githubAvatarUrl: string; githubAvatarPageUrl: string; githubAvatarName: string; - githubCommitCount: number; + leetcodeBadgeImg: string; + leetcodeBadgeCount: number; + solvedProblem: number; + easySolved: number; + mediumSolved: number; + hardSolved: number; + totalLCProblem: number; loading: boolean; refetch: () => Promise; } @@ -26,7 +32,6 @@ export const CommunityStatsContext = createContext< >(undefined); const ACCESS_TOKEN = process.env.REACT_APP_FOLLOWERS_ACCESS_KEY; -console.log(ACCESS_TOKEN); export const CommunityStatsProvider: FC = ({ children }) => { const [loading, setLoading] = useState(true); @@ -35,6 +40,13 @@ export const CommunityStatsProvider: FC = ({ children }) => { const [githubAvatarUrl, setGithubAvatarUrl] = useState([]); const [githubAvatarPageUrl, setGithubAvatarPageUrl] = useState([]); const [githubAvatarName, setGithubAvatarName] = useState([]); + const [leetcodeBadgeImg, setLeetcodeBadgeImg] = useState([]); + const [leetcodeBadgeCount, setLeetcodeBadgesCount] = useState(0); + const [solvedProblem, setSolvedProblem] = useState(0); + const [easySolved, setEasySolved] = useState(0); + const [mediumSolved, setMediumSolved] = useState(0); + const [hardSolved, setHardSolved] = useState(0); + const [totalLCProblem, setTotalLCProblem] = useState(0); const fetchGithubCount = useCallback(async (signal: AbortSignal) => { try { @@ -74,15 +86,13 @@ export const CommunityStatsProvider: FC = ({ children }) => { method: "GET", headers: { "Content-Type": "application/json", - // "Authorization": `token ${ACCESS_TOKEN}`, + "Authorization": `token ${ACCESS_TOKEN}`, }, signal, }, ); - const followers = await fetchFollowerDetails.json(); allFollowers = [...allFollowers, ...followers]; - // Check if there are more pages const linkHeader = fetchFollowerDetails.headers.get("Link"); const hasNextPage = linkHeader && linkHeader.includes('rel="next"'); @@ -109,6 +119,43 @@ export const CommunityStatsProvider: FC = ({ children }) => { }; }) ); + + let allBadges = []; + const fetchBadgeDetails = await fetch( + `https://alfa-leetcode-api.onrender.com/akashsingh3031/badges`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + // "Authorization": `token ${ACCESS_TOKEN}`, + }, + signal, + }, + ); + + const fetchSolvedProblemsDetails = await fetch( + `https://alfa-leetcode-api.onrender.com/akashsingh3031/solved`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + // "Authorization": `token ${ACCESS_TOKEN}`, + }, + signal, + }, + ); + + const fetchTotalLCProblem = await fetch( + `https://alfa-leetcode-api.onrender.com/problems`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + // "Authorization": `token ${ACCESS_TOKEN}`, + }, + signal, + }, + ); const starCount = await fetchStarCounts.json(); setGithubStarCount(starCount.stargazers_count); @@ -123,6 +170,30 @@ export const CommunityStatsProvider: FC = ({ children }) => { setGithubAvatarName(sortedAvatarNames); setGithubAvatarUrl(sortedAvatarUrls); setGithubAvatarPageUrl(sortedAvatarPageUrls); + + const badgeDetails = await fetchBadgeDetails.json(); + const badgesCount = badgeDetails.badgesCount; + const badges = badgeDetails.badges.map(badge => { + const iconUrl = badge.icon.startsWith('https://') ? badge.icon : `https://leetcode.com${badge.icon}`; + return { + id: badge.id, + displayName: badge.displayName, + icon: iconUrl, + creationDate: badge.creationDate + }; + }); + allBadges = [...allBadges, ...badges]; + setLeetcodeBadgeImg(allBadges); + setLeetcodeBadgesCount(badgesCount); + + const solvedProblemsDetails = await fetchSolvedProblemsDetails.json(); + setSolvedProblem(solvedProblemsDetails.solvedProblem); + setEasySolved(solvedProblemsDetails.easySolved); + setMediumSolved(solvedProblemsDetails.mediumSolved); + setHardSolved(solvedProblemsDetails.hardSolved); + + const totalLCProblem = await fetchTotalLCProblem.json(); + setTotalLCProblem(totalLCProblem.totalQuestions); } catch (error) { } finally { setLoading(false); @@ -154,6 +225,13 @@ export const CommunityStatsProvider: FC = ({ children }) => { githubAvatarUrl, githubAvatarPageUrl, githubAvatarName, + leetcodeBadgeImg, + leetcodeBadgeCount, + solvedProblem, + easySolved, + mediumSolved, + hardSolved, + totalLCProblem, loading, refetch: fetchGithubCount, }; diff --git a/documentation/src/prepverse-theme/about-me-profile.tsx b/documentation/src/prepverse-theme/about-me-profile.tsx index b6f7ca96..08d0ccdf 100644 --- a/documentation/src/prepverse-theme/about-me-profile.tsx +++ b/documentation/src/prepverse-theme/about-me-profile.tsx @@ -9,6 +9,7 @@ import { LandingSectionCtaButton } from "./landing-section-cta-button"; import { GitHubFollowers } from "./about-section/github-followers"; import { GithubFollowersAvatar } from "./about-section/github-followers-avatar"; import { EduExpJourney } from "./about-section/edu-exp"; +import { LeetCodeSection } from "./about-section/leetcode-section"; const GithubFollowers = ({ className }: { className?: string }) => { return ( @@ -40,15 +41,25 @@ const Journey = ({ className }: { className?: string }) => { ); }; +const LeetCodeStats = ({ className }: { className?: string }) => { + return ( + + ); +}; + const apps = [ { - name: "My Journey", - showcase: Journey, + name: "LeetCode Stats", + showcase: LeetCodeStats, }, { name: "GitHub Followers", showcase: GithubFollowers, }, + { + name: "My Journey", + showcase: Journey, + }, ]; export const AboutMeProfile = ({ className }: { className?: string }) => { @@ -117,7 +128,7 @@ export const AboutMeProfile = ({ className }: { className?: string }) => { "font-semibold", )} > - Akash Singh + Akash Singh 

{ className={clsx( "rounded-3xl", "flex", - "w-full", + "w-auto", "landing-lg:w-full", "items-center", "justify-start", diff --git a/documentation/src/prepverse-theme/about-section/leetcode-section.tsx b/documentation/src/prepverse-theme/about-section/leetcode-section.tsx new file mode 100644 index 00000000..7d76673f --- /dev/null +++ b/documentation/src/prepverse-theme/about-section/leetcode-section.tsx @@ -0,0 +1,318 @@ +import clsx from "clsx"; +import React, { useState, useEffect } from "react"; +import { useCommunityStatsContext } from "@site/src/context/CommunityStats"; +import { CommonThemedImage } from "../common-themed-image"; +import { Spinner } from "../spinner"; + +const LeecodeBadges = ({ className }: { className?: string }) => { + const { leetcodeBadgeImg, leetcodeBadgeCount, loading } = useCommunityStatsContext(); + const [borderColors, setBorderColors] = useState([]); + const [backgroundColors, setBackgroundColors] = useState([]); + + useEffect(() => { + const colors = leetcodeBadgeImg.map(() => getRandomColor()); + setBorderColors(colors); + const backgroundColorsWithOpacity = colors.map(color => `${color.slice(0, -1)},0.1)`); + setBackgroundColors(backgroundColorsWithOpacity); + }, [leetcodeBadgeImg]); + + function getRandomColor() { + const r = Math.floor(Math.random() * 256); + const g = Math.floor(Math.random() * 256); + const b = Math.floor(Math.random() * 256); + return `rgb(${r},${g},${b})`; + } + + const renderBadgesByCategory = (category: string, badges: any[]) => { + return ( +

+
+ {category} +
+
+ {badges.map((badge, index) => ( +
+ + {index+1} +
+ {badge.displayName} +
+
+ {badge.creationDate} +
+
+ ))} +
+
+ ); + }; + + return ( +
+ +
+ Total Badges:  + {loading ? ( + + ) : ( + + {leetcodeBadgeCount} + + )} +
+
+
+ {renderBadgesByCategory("Competition Medals", leetcodeBadgeImg.filter(badge => badge.displayName.includes("Annual Badge") || badge.displayName.includes("Days Badge")))} + {renderBadgesByCategory("Daily Medals", leetcodeBadgeImg.filter(badge => badge.displayName.includes("LeetCoding Challenge")))} + {renderBadgesByCategory("Study Plan Medals", leetcodeBadgeImg.filter(badge => !badge.displayName.includes("Annual Badge") && !badge.displayName.includes("LeetCoding Challenge") && !badge.displayName.includes("Days Badge")))} +
+
+ ); +}; + +const journey = [ + { + name: "Leecode Badges", + showcase: LeecodeBadges, + }, +]; + +export const LeetCodeSection: React.FC = () => { + const [activeApp, setActiveApp] = React.useState(journey[0]); + const ShowcaseComponent = React.useMemo(() => { + return activeApp.showcase; + }, [activeApp.name]); + + return ( +
+
+
+
+
f.name === activeApp.name, + )})) translateZ(0px)`, + }} + /> + {journey.map((LeetCode, index) => ( + + ))} +
+
+
+
+ +
+
+ ); +};