Created
March 10, 2025 06:08
-
-
Save SH20RAJ/776fd496fc0e16bb493b3f5d0ddeeafe to your computer and use it in GitHub Desktop.
Leetmatric
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Document</title> | |
<link rel="stylesheet" href="style.css"> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>Leetmatric</h1> | |
<p>Enter your username below:</p> | |
<div class="user-container"> | |
<input type="text" placeholder="enter your username here"id="user-input"> | |
<button id="search-btn">Search </button> | |
</div> | |
<div class="stats-container"> | |
<div class="progress"> | |
<div class="progress-item circle "> | |
<div class="easy-progress "> | |
<span id="easy-label"></span> | |
Easy | |
</div> | |
</div> | |
<div class="progress-item circle"> | |
<div class="medium-progress "> | |
<span id="medium-label"></span> | |
Medium | |
</div> | |
</div> | |
<div class="progress-item circle"> | |
<div class="hard-progress "> | |
<span id="hard-label"></span> | |
Hard | |
</div> | |
</div> | |
</div> | |
<div class="stat-card"> | |
</div> | |
</div> | |
</div> | |
<script src="script.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(".mediumProgress"); | |
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"); | |
function validateUsername(username){ | |
if(username.trim()===""){ | |
alert("Username should not be empty"); | |
return false; | |
} | |
const regex=/^[a-zA-Z0-9._-]{3,16}$/; | |
const isMatching= regex.test(username); | |
if(!isMatching){ | |
alert("Invalid Username"); | |
} | |
return isMatching; | |
} | |
async function fetchUserDetails(username){ | |
try{ | |
searchButton.textContent="Searching.."; | |
searchButton.disabled=true; | |
const proxyUrl = 'https://cors-anywhere.herokuapp.com/'; | |
const targetUrl = 'https://leetcode.com/graphql'; | |
const myHeaders = new Headers(); | |
myHeaders.append("Content-Type", "application/json"); | |
myHeaders.append("Origin", "https://leetcode.com"); | |
myHeaders.append("Referer", "https://leetcode.com"); | |
myHeaders.append("Access-Control-Allow-Origin", "*"); | |
const graphql = JSON.stringify({ | |
query: ` | |
query getUserProfile($username: String!) { | |
matchedUser(username: $username) { | |
submitStats: submitStatsGlobal { | |
acSubmissionNum { | |
difficulty | |
count | |
} | |
} | |
} | |
} | |
`, | |
variables: { "username": username } | |
}); | |
const requestOptions = { | |
method: "POST", | |
headers: myHeaders, | |
body: graphql, | |
mode: "cors", | |
credentials: "omit" | |
}; | |
const response = await fetch(proxyUrl + targetUrl, requestOptions); | |
if(!response.ok){ | |
throw new Error(`HTTP error! status: ${response.status}`); | |
} | |
const data = await response.json(); | |
if (data.errors) { | |
throw new Error(data.errors[0].message || "API Error"); | |
} | |
updateUI(data.data); | |
} | |
catch(error){ | |
console.error("Error:", error); | |
statsContainer.innerHTML = `<p>Error: ${error.message}</p>`; | |
} | |
finally{ | |
searchButton.textContent = "Search"; | |
searchButton.disabled = false; | |
} | |
} | |
function updateUI(data) { | |
if (!data || !data.matchedUser || !data.matchedUser.submitStats) { | |
throw new Error("Invalid data format"); | |
} | |
const stats = data.matchedUser.submitStats.acSubmissionNum.reduce((acc, curr) => { | |
acc[curr.difficulty.toLowerCase()] = curr.count; | |
return acc; | |
}, {}); | |
easyLabel.textContent = stats.easy || 0; | |
mediumLabel.textContent = stats.medium || 0; | |
hardLabel.textContent = stats.hard || 0; | |
} | |
searchButton.addEventListener('click', function(){ | |
const username = usernameInput.value; | |
console.log("loggin username", username); | |
if(validateUsername(username)){ | |
fetchUserDetails(username); | |
} | |
}) | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
font-family: 'Arial', sans-serif; | |
} | |
body { | |
background-color: #f5f5f5; | |
min-height: 100vh; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
} | |
.container { | |
background-color: white; | |
padding: 2rem; | |
border-radius: 10px; | |
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); | |
width: 90%; | |
max-width: 800px; | |
} | |
h1 { | |
color: #2c3e50; | |
text-align: center; | |
margin-bottom: 1rem; | |
} | |
p { | |
color: #666; | |
text-align: center; | |
margin-bottom: 2rem; | |
} | |
.user-container { | |
display: flex; | |
gap: 1rem; | |
margin-bottom: 2rem; | |
} | |
#user-input { | |
flex: 1; | |
padding: 0.8rem; | |
border: 2px solid #ddd; | |
border-radius: 5px; | |
font-size: 1rem; | |
transition: border-color 0.3s; | |
} | |
#user-input:focus { | |
outline: none; | |
border-color: #3498db; | |
} | |
#search-btn { | |
padding: 0.8rem 1.5rem; | |
background-color: #3498db; | |
color: white; | |
border: none; | |
border-radius: 5px; | |
cursor: pointer; | |
transition: background-color 0.3s; | |
} | |
#search-btn:hover { | |
background-color: #2980b9; | |
} | |
#search-btn:disabled { | |
background-color: #bdc3c7; | |
cursor: not-allowed; | |
} | |
.stats-container { | |
margin-top: 2rem; | |
} | |
.progress { | |
display: flex; | |
justify-content: space-around; | |
flex-wrap: wrap; | |
gap: 2rem; | |
} | |
.progress-item { | |
text-align: center; | |
} | |
.circle { | |
width: 150px; | |
height: 150px; | |
border-radius: 50%; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
position: relative; | |
background: #f8f9fa; | |
} | |
.easy-progress, .medium-progress, .hard-progress { | |
width: 100%; | |
height: 100%; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
color: #2c3e50; | |
} | |
.easy-progress span, .medium-progress span, .hard-progress span { | |
font-size: 1.5rem; | |
font-weight: bold; | |
margin-bottom: 0.5rem; | |
} | |
.easy-progress { | |
border: 8px solid #00b8a3; | |
border-radius: 50%; | |
} | |
.medium-progress { | |
border: 8px solid #ffc01e; | |
border-radius: 50%; | |
} | |
.hard-progress { | |
border: 8px solid #ff375f; | |
border-radius: 50%; | |
} | |
.stat-card { | |
margin-top: 2rem; | |
padding: 1rem; | |
background-color: #f8f9fa; | |
border-radius: 5px; | |
} | |
@media (max-width: 768px) { | |
.container { | |
padding: 1rem; | |
width: 95%; | |
} | |
.user-container { | |
flex-direction: column; | |
} | |
.circle { | |
width: 120px; | |
height: 120px; | |
} | |
.progress { | |
gap: 1rem; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment