Skip to content

Commit 8e2e5f9

Browse files
committed
feat(api): add api endpoint and display results in main page
1 parent 608663c commit 8e2e5f9

17 files changed

+492
-82
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ yarn-error.log*
3232

3333
# vercel
3434
.vercel
35+
36+
.vscode

.prettierrc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

next-env.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/types/global" />

next.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
reactStrictMode: true,
3+
};

package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,17 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11+
"@material-ui/core": "^4.11.0",
12+
"axios": "^0.21.0",
1113
"next": "10.0.0",
1214
"react": "17.0.1",
13-
"react-dom": "17.0.1"
15+
"react-dom": "17.0.1",
16+
"rxjs": "^6.6.3"
17+
},
18+
"devDependencies": {
19+
"@types/node": "^14.14.6",
20+
"@types/react": "^16.9.55",
21+
"prettier": "^2.1.2",
22+
"typescript": "^4.0.5"
1423
}
1524
}

pages/_app.js

Lines changed: 0 additions & 7 deletions
This file was deleted.

pages/_app.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import "../styles/globals.css";
2+
import { AppProps } from "next/app";
3+
4+
const MyApp = ({ Component, pageProps }: AppProps) => (
5+
<Component {...pageProps} />
6+
);
7+
8+
export default MyApp;

pages/api/hello.js

Lines changed: 0 additions & 6 deletions
This file was deleted.

pages/api/users/[user].ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { NextApiRequest, NextApiResponse } from "next";
2+
import axios from "axios";
3+
4+
interface LeetCodeCount {
5+
difficulty: string;
6+
count: number;
7+
}
8+
9+
interface LeetCodeResponse {
10+
data: {
11+
data: {
12+
allQuestionsCount: LeetCodeCount[];
13+
matchedUser: {
14+
profile: { ranking: number };
15+
submitStats: {
16+
acSubmissionNum: LeetCodeCount[];
17+
};
18+
};
19+
};
20+
};
21+
}
22+
23+
interface Output {
24+
error: null | string;
25+
ranking: number | string;
26+
solved: number | string;
27+
solvedOverTotal: string;
28+
solvedPercentage: string;
29+
}
30+
31+
const query = (user: string) =>
32+
`{
33+
"operationName": "getUserProfile",
34+
"variables": { "username" : "${user}" },
35+
"query": "query getUserProfile($username: String!) { allQuestionsCount { difficulty count } matchedUser(username: $username) { profile { starRating ranking } submitStats { acSubmissionNum { difficulty count } } } }"
36+
}`;
37+
38+
const genericErrorMessage =
39+
"error: reach out to github.com/cascandaliato/leetcode-badge";
40+
41+
export default async (req: NextApiRequest, res: NextApiResponse) => {
42+
const {
43+
query: { user },
44+
} = req;
45+
46+
let output: Output;
47+
48+
try {
49+
const {
50+
data: { data },
51+
}: LeetCodeResponse = await axios.post(
52+
"https://leetcode.com/graphql",
53+
query(user as string),
54+
{
55+
headers: {
56+
"content-type": "application/json",
57+
},
58+
}
59+
);
60+
61+
if (!data.matchedUser) throw new Error("User not found");
62+
63+
const ranking = data.matchedUser.profile.ranking;
64+
65+
const solved = data.matchedUser.submitStats.acSubmissionNum.filter(
66+
({ difficulty }) => difficulty === "All"
67+
)[0].count;
68+
69+
const total = data.allQuestionsCount.filter(
70+
({ difficulty }) => difficulty === "All"
71+
)[0].count;
72+
73+
output = {
74+
error: null,
75+
ranking,
76+
solved,
77+
solvedOverTotal: `${solved}/${total}`,
78+
solvedPercentage: `${((solved / total) * 100).toFixed(1)}%`,
79+
};
80+
} catch ({ message }) {
81+
output = {
82+
error: message,
83+
ranking: genericErrorMessage,
84+
solved: genericErrorMessage,
85+
solvedOverTotal: genericErrorMessage,
86+
solvedPercentage: genericErrorMessage,
87+
};
88+
}
89+
90+
res.setHeader("Content-Type", "application/json");
91+
res.status(200).json(output);
92+
};

pages/index.js

Lines changed: 0 additions & 65 deletions
This file was deleted.

0 commit comments

Comments
 (0)