From 523ace88a85625e81b4f4a339c9494e51abbb843 Mon Sep 17 00:00:00 2001
From: Sanchit Badyal <128458864+sanchit1804@users.noreply.github.com>
Date: Wed, 22 Oct 2025 21:09:16 +0530
Subject: [PATCH 1/2] LeetCodeStats
Program to check stats on leetcode using username only.
---
Javascript/LeetCodeStats/index.html | 60 ++++++++++
Javascript/LeetCodeStats/script.js | 156 ++++++++++++++++++++++++++
Javascript/LeetCodeStats/style.css | 164 ++++++++++++++++++++++++++++
3 files changed, 380 insertions(+)
create mode 100644 Javascript/LeetCodeStats/index.html
create mode 100644 Javascript/LeetCodeStats/script.js
create mode 100644 Javascript/LeetCodeStats/style.css
diff --git a/Javascript/LeetCodeStats/index.html b/Javascript/LeetCodeStats/index.html
new file mode 100644
index 0000000..a4ef644
--- /dev/null
+++ b/Javascript/LeetCodeStats/index.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+ LeetMetric
+
+
+
+
+
+
LeetMetric
+
+
+
Enter your username below:
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Javascript/LeetCodeStats/script.js b/Javascript/LeetCodeStats/script.js
new file mode 100644
index 0000000..14b708d
--- /dev/null
+++ b/Javascript/LeetCodeStats/script.js
@@ -0,0 +1,156 @@
+// https://cors-anywhere.herokuapp.com/corsdemo request temperory access here for the code to work
+
+document.addEventListener("DOMContentLoaded", function () {
+ const searchButton = document.getElementById("search-btn");
+ const usernameInput = document.getElementById("user-input");
+ const statsContainer = document.querySelector(".stats-container");
+ const easyProgressCircle = document.querySelector(".easy-progress");
+ const mediumProgressCircle = document.querySelector(".medium-progress");
+ const hardProgressCircle = document.querySelector(".hard-progress");
+ const easyLabel = document.getElementById("easy-label");
+ const mediumLabel = document.getElementById("medium-label");
+ const hardLabel = document.getElementById("hard-label");
+ const cardStatsContainer = document.querySelector(".stats-cards");
+
+ //return true or false based on a regex
+ function validateUsername(username) {
+ if (username.trim() === "") {
+ alert("Username should not be empty");
+ return false;
+ }
+ const regex = /^[a-zA-Z0-9_-]{1,15}$/;
+ const isMatching = regex.test(username);
+ if (!isMatching) {
+ alert("Invalid Username");
+ }
+ return isMatching;
+ }
+
+ async function fetchUserDetails(username) {
+ try {
+ searchButton.textContent = "Searching...";
+ searchButton.disabled = true;
+ //statsContainer.classList.add("hidden");
+
+ // const response = await fetch(url);
+ const proxyUrl = "https://cors-anywhere.herokuapp.com/";
+ const targetUrl = "https://leetcode.com/graphql/";
+
+ const myHeaders = new Headers();
+ myHeaders.append("content-type", "application/json");
+
+ const graphql = JSON.stringify({
+ query:
+ "\n query userSessionProgress($username: String!) {\n allQuestionsCount {\n difficulty\n count\n }\n matchedUser(username: $username) {\n submitStats {\n acSubmissionNum {\n difficulty\n count\n submissions\n }\n totalSubmissionNum {\n difficulty\n count\n submissions\n }\n }\n }\n}\n ",
+ variables: { username: `${username}` },
+ });
+ const requestOptions = {
+ method: "POST",
+ headers: myHeaders,
+ body: graphql,
+ };
+
+ const response = await fetch(proxyUrl + targetUrl, requestOptions);
+ if (!response.ok) {
+ throw new Error("Unable to fetch the User details");
+ }
+ const parsedData = await response.json();
+ console.log("Logging data: ", parsedData);
+
+ displayUserData(parsedData);
+ } catch (error) {
+ statsContainer.innerHTML = `${error.message}
`;
+ } finally {
+ searchButton.textContent = "Search";
+ searchButton.disabled = false;
+ }
+ }
+
+ function updateProgress(solved, total, label, circle) {
+ const progressDegree = (solved / total) * 100;
+ circle.style.setProperty("--progress-degree", `${progressDegree}%`);
+ label.textContent = `${solved}/${total}`;
+ }
+
+ function displayUserData(parsedData) {
+ const totalQues = parsedData.data.allQuestionsCount[0].count;
+ const totalEasyQues = parsedData.data.allQuestionsCount[1].count;
+ const totalMediumQues = parsedData.data.allQuestionsCount[2].count;
+ const totalHardQues = parsedData.data.allQuestionsCount[3].count;
+
+ const solvedTotalQues =
+ parsedData.data.matchedUser.submitStats.acSubmissionNum[0].count;
+ const solvedTotalEasyQues =
+ parsedData.data.matchedUser.submitStats.acSubmissionNum[1].count;
+ const solvedTotalMediumQues =
+ parsedData.data.matchedUser.submitStats.acSubmissionNum[2].count;
+ const solvedTotalHardQues =
+ parsedData.data.matchedUser.submitStats.acSubmissionNum[3].count;
+
+ updateProgress(
+ solvedTotalEasyQues,
+ totalEasyQues,
+ easyLabel,
+ easyProgressCircle
+ );
+ updateProgress(
+ solvedTotalMediumQues,
+ totalMediumQues,
+ mediumLabel,
+ mediumProgressCircle
+ );
+ updateProgress(
+ solvedTotalHardQues,
+ totalHardQues,
+ hardLabel,
+ hardProgressCircle
+ );
+
+ const cardsData = [
+ {
+ label: "Overall Submissions",
+ value:
+ parsedData.data.matchedUser.submitStats.totalSubmissionNum[0]
+ .submissions,
+ },
+ {
+ label: "Overall Easy Submissions",
+ value:
+ parsedData.data.matchedUser.submitStats.totalSubmissionNum[1]
+ .submissions,
+ },
+ {
+ label: "Overall Medium Submissions",
+ value:
+ parsedData.data.matchedUser.submitStats.totalSubmissionNum[2]
+ .submissions,
+ },
+ {
+ label: "Overall Hard Submissions",
+ value:
+ parsedData.data.matchedUser.submitStats.totalSubmissionNum[3]
+ .submissions,
+ },
+ ];
+
+ console.log("card ka data: ", cardsData);
+
+ cardStatsContainer.innerHTML = cardsData
+ .map(
+ (data) =>
+ `
+
${data.label}
+
${data.value}
+
`
+ )
+ .join("");
+ }
+
+ searchButton.addEventListener("click", function () {
+ const username = usernameInput.value;
+ console.log("logggin username: ", username);
+ if (validateUsername(username)) {
+ fetchUserDetails(username);
+ }
+ });
+});
diff --git a/Javascript/LeetCodeStats/style.css b/Javascript/LeetCodeStats/style.css
new file mode 100644
index 0000000..668d5d6
--- /dev/null
+++ b/Javascript/LeetCodeStats/style.css
@@ -0,0 +1,164 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
+}
+
+body {
+ background-color: #0f172a;
+ color: #f1f5f9;
+ height: 100vh;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+/* --- Container --- */
+.container {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ background-color: #1e293b;
+ padding: 25px;
+ border-radius: 12px;
+ width: 50%;
+ max-width: 600px;
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
+}
+
+/* --- Header --- */
+h1 {
+ font-size: 2rem;
+ color: #3a3a02;
+ text-align: center;
+ margin-bottom: 15px;
+}
+
+/* --- User Input --- */
+.user-container {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.user-input-container {
+ display: flex;
+ justify-content: space-between;
+ gap: 10px;
+}
+
+#user-input {
+ width: 80%;
+ padding: 0.5rem;
+ border-radius: 8px;
+ border: 1px solid #475569;
+ background-color: #0f172a;
+ color: #f1f5f9;
+ outline: none;
+}
+
+#user-input::placeholder {
+ color: #94a3b8;
+}
+
+#search-btn {
+ padding: 0.5rem 1rem;
+ border-radius: 8px;
+ border: none;
+ background-color: #ffff00;
+ color: #0f172a;
+ font-weight: bold;
+ cursor: pointer;
+ transition: 0.3s;
+}
+
+#search-btn:hover {
+ background-color: #ffff00;
+}
+
+.circle {
+ width: 120px;
+ height: 120px;
+ border-radius: 50%;
+ border: 4px solid #334155;
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 700;
+ flex-direction: column;
+ background: conic-gradient(
+ var(--progress-color, #22c55e) var(--progress-degree, 0%),
+ #334155 0%
+ );
+ color: #f1f5f9;
+}
+
+.circle span {
+ position: relative;
+ z-index: 2;
+ font-size: 1.2rem;
+}
+
+.circle p {
+ font-size: 0.9rem;
+ margin-top: 5px;
+ color: #cbd5e1;
+}
+
+.progress {
+ display: flex;
+ justify-content: space-around;
+ flex-wrap: wrap;
+ gap: 20px;
+ margin: 1rem 0;
+}
+
+.easy-progress {
+ --progress-color: #22c55e;
+}
+.medium-progress {
+ --progress-color: #ffff00;
+}
+.hard-progress {
+ --progress-color: #ef4444;
+}
+
+.stats-cards {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 15px;
+ justify-content: space-evenly;
+ margin-top: 1rem;
+}
+
+.card {
+ background-color: #334155;
+ color: #f1f5f9;
+ width: 45%;
+ max-width: 250px;
+ padding: 15px;
+ border-radius: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
+ transition: transform 0.3s, background 0.3s;
+}
+
+.card:hover {
+ transform: translateY(-5px);
+ background-color: #475569;
+}
+
+.card h4 {
+ font-size: 1rem;
+ color: #ffff00;
+ margin-bottom: 5px;
+}
+
+.card p {
+ font-size: 1.2rem;
+ font-weight: bold;
+}
From 0e8185b3916b6100c52c654745df4ff8cbb814de Mon Sep 17 00:00:00 2001
From: Sanchit Badyal <128458864+sanchit1804@users.noreply.github.com>
Date: Wed, 22 Oct 2025 21:12:16 +0530
Subject: [PATCH 2/2] Create README for LeetCode User Stats Tracker
Added a README file for the LeetCode User Stats Tracker web app, detailing features, setup, and usage instructions.
---
Javascript/LeetCodeStats/readme.md | 39 ++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 Javascript/LeetCodeStats/readme.md
diff --git a/Javascript/LeetCodeStats/readme.md b/Javascript/LeetCodeStats/readme.md
new file mode 100644
index 0000000..bd3f56e
--- /dev/null
+++ b/Javascript/LeetCodeStats/readme.md
@@ -0,0 +1,39 @@
+# π§© LeetCode User Stats Tracker
+
+A simple web app that lets you fetch and visualize **LeetCode user statistics** such as total problems solved, difficulty-wise progress, and overall submissions β all displayed in a clean, LeetCode-themed UI.
+
+---
+
+## π Features
+
+- π Search any LeetCode username
+- π Shows total, easy, medium, and hard problems solved
+- π§ Displays total submission counts
+- π¨ Beautiful LeetCode-inspired UI
+- π Uses LeetCodeβs GraphQL API
+- π§° Built with **HTML, CSS, and Vanilla JavaScript**
+
+---
+
+## βοΈ How It Works
+
+1. Enter a valid **LeetCode username** in the input box.
+2. Click **Search**.
+3. The app fetches live data from the [LeetCode GraphQL API](https://leetcode.com/graphql/) through a free **CORS proxy**.
+4. The data is visualized using animated circular progress bars and submission cards.
+
+---
+
+## π οΈ Setup & Usage
+'''NOTE:
+If the code fils to fetch data the go to "https://cors-anywhere.herokuapp.com/corsdemo" and request temperory access here for the code to work.
+
+
+### 1. Clone or Download
+```bash
+git clone https://github.com/your-username/leetcode-stats-tracker.git
+cd leetcode-stats-tracker
+
+
+
+