Initial commit
This commit is contained in:
commit
950be6746b
2 changed files with 120 additions and 0 deletions
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Monkeytype-stats
|
||||
|
||||
Website that shows the stats of multiple Monkeytype users
|
117
index.html
Normal file
117
index.html
Normal file
|
@ -0,0 +1,117 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>MonkeyType Profile Data</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #1e1e1e;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #333;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>MonkeyType Profile Data</h1>
|
||||
<table id="profileTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Added At</th>
|
||||
<th>Completed Tests</th>
|
||||
<th>Started Tests</th>
|
||||
<th>Time Typing</th>
|
||||
<th>Best 15s</th>
|
||||
<th>Best 30s</th>
|
||||
<th>Best 60s</th>
|
||||
<th>Best 120s</th>
|
||||
<th>Best 10w</th>
|
||||
<th>Best 25w</th>
|
||||
<th>Best 50w</th>
|
||||
<th>Best 100w</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
|
||||
<script>
|
||||
|
||||
const users = (new URLSearchParams(window.location.search)).get('users');
|
||||
|
||||
// no users passed => ask for them and reload
|
||||
if(users==null || users=='') {
|
||||
var names = prompt('Please provide user names, delimited by \',\'');
|
||||
window.location.replace(location.protocol + '//' + location.host + location.pathname + '?users=' + names);
|
||||
}
|
||||
|
||||
const urls = users.split(",").map(user => 'https://api.monkeytype.com/users/' + user.replace(' ', '') + '/profile');
|
||||
|
||||
const table = document.querySelector('#profileTable tbody');
|
||||
|
||||
for (url of urls) {
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const { name, addedAt, typingStats, personalBests } = data.data;
|
||||
const { completedTests, startedTests, timeTyping } = typingStats;
|
||||
const { time, words } = personalBests;
|
||||
|
||||
function maxReducer(prev, current) {
|
||||
return (prev > current) ? prev : current
|
||||
}
|
||||
|
||||
const best15s = time['15'].map(({ wpm }) => wpm).reduce((p, c) => maxReducer(p, c));
|
||||
const best30s = time['30'].map(({ wpm }) => wpm).reduce((p, c) => maxReducer(p, c));
|
||||
const best60s = time['60'].map(({ wpm }) => wpm).reduce((p, c) => maxReducer(p, c));
|
||||
const best120s = time['120'].map(({ wpm }) => wpm).reduce((p, c) => maxReducer(p, c));
|
||||
const best10w = words['10'].map(({ wpm }) => wpm).reduce((p, c) => maxReducer(p, c));
|
||||
const best25w = words['25'].map(({ wpm }) => wpm).reduce((p, c) => maxReducer(p, c));
|
||||
const best50w = words['50'].map(({ wpm }) => wpm).reduce((p, c) => maxReducer(p, c));
|
||||
const best100w = words['100'].map(({ wpm }) => wpm).reduce((p, c) => maxReducer(p, c));
|
||||
|
||||
const row = `
|
||||
<tr>
|
||||
<td>${name}</td>
|
||||
<td>${new Date(addedAt).toLocaleDateString()}</td>
|
||||
<td>${completedTests}</td>
|
||||
<td>${startedTests}</td>
|
||||
<td>${timeTyping.toFixed(2)}</td>
|
||||
<td>${best15s}</td>
|
||||
<td>${best30s}</td>
|
||||
<td>${best60s}</td>
|
||||
<td>${best120s}</td>
|
||||
<td>${best10w}</td>
|
||||
<td>${best25w}</td>
|
||||
<td>${best50w}</td>
|
||||
<td>${best100w}</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
table.insertAdjacentHTML('beforeend', row);
|
||||
})
|
||||
.catch(error => { alert(error); console.error(error); });
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in a new issue