Repository navigation
Expand file tree
/
Copy pathscript.js
More file actions
120 lines (101 loc) · 5.3 KB
/
Copy pathscript.js
File metadata and controls
120 lines (101 loc) · 5.3 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
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");
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;
// Hide the container while searching so old data disappears
statsContainer.classList.add("hidden");
const graphql = {
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 }
};
// Notice we are fetching from our OWN /api/leetcode route now!
const response = await fetch('/api/leetcode', {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(graphql)
});
if(!response.ok) {
throw new Error("Unable to fetch the User details. The proxy might be having issues.");
}
const parsedData = await response.json();
console.log("Logging data: ", parsedData);
// NEW: Check if the user actually exists!
// If LeetCode can't find them, 'matchedUser' will be null and crash the code.
if(parsedData.errors || parsedData.data.matchedUser === null) {
throw new Error("User not found!");
}
displayUserData(parsedData);
}
catch(error) {
console.error(error);
// Instead of wiping out our HTML container, let's just show an alert
alert(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 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 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 },
];
cardStatsContainer.innerHTML = cardsData.map(
data =>
`<div class="card">
<h4>${data.label}</h4>
<p>${data.value}</p>
</div>`
).join("");
// Reveal the container ONLY when everything is successfully populated
statsContainer.classList.remove("hidden");
}
searchButton.addEventListener('click', function() {
const username = usernameInput.value;
if(validateUsername(username)) {
fetchUserDetails(username);
}
})
});