-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
123 lines (104 loc) · 5.58 KB
/
Copy pathscript.js
File metadata and controls
123 lines (104 loc) · 5.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
document.addEventListener("DOMContentLoaded", function() {
// grabbing all the needed elements
const searchButton = document.getElementById("search-btn");
const usernameInput = document.getElementById("username-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 cardStatsConatainer = document.querySelector(".stats-cards");
// basic check to ensure user didn't enter gibberish
function validateUsername(username) {
if(username.trim() === "") {
alert("Please enter a valid username.");
return false;
}
const regex = /^[a-zA-Z0-9_-]{1,15}$/;
const isMatching = regex.test(username);
if(!isMatching) {
alert("Username can only contain letters, numbers, underscores, and hyphens, and must be between 1 and 15 characters long.");
}
return isMatching;
}
// fetch the actual data
async function fetchUserDetails(username) {
try{
searchButton.textContent = "Searching...";
searchButton.disabled = true;
statsContainer.style.setProperty("display", "none");
const proxyUrl = "https://cors-anywhere.herokuapp.com/";
const targetUrl = "https://leetcode.com/graphql";
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
// query payload
const graphql = JSON.stringify({
query: "\n query userSessionProgress($username: String!) {\n allQuestionsCount {\n difficulty\n count\n }\n matchedUser(username: $username) {\n 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,
redirect: "follow"
};
const response = await fetch(proxyUrl+targetUrl, requestOptions);
if(!response.ok) {
throw new Error("User not found");
}
const parsedData = await response.json();
console.log("Logging data: ", parsedData);
displayUserData(parsedData);
}
catch(error) {
statsContainer.innerHTML = `<p>${error.message}</p>`;
statsContainer.style.setProperty("display", "block");
}
finally{
searchButton.textContent = "Search";
searchButton.disabled = false;
}
}
// handle the css circle updates
function updateProgress(solved, total, label, circle){
const progressDegree = total > 0 ? (solved / total) * 100 : 0;
circle.style.setProperty("--progress-degree", `${progressDegree}%`);
label.textContent = `${solved}/${total}`;
}
// display everything on the DOM
function displayUserData(parsedData) {
statsContainer.style.setProperty("display", "block");
const totalEasyQues = parsedData.data.allQuestionsCount[1].count;
const totalMediumQues = parsedData.data.allQuestionsCount[2].count;
const totalHardQues = parsedData.data.allQuestionsCount[3].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 cardData = [
{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 data: ", cardData);
// render out the bottom cards
cardStatsConatainer.innerHTML = cardData.map(
data =>
`<div class="card">
<h4>${data.label}</h4>
<p>${data.value}</p>
</div>`
).join("");
}
searchButton.addEventListener("click", function() {
const username = usernameInput.value;
if(validateUsername(username)) {
fetchUserDetails(username);
}
})
})