Vitals/index.html

195 lines
5 KiB
HTML
Raw Normal View History

2024-03-30 18:17:35 +00:00
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
2024-03-30 18:34:31 +00:00
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css" id="change" />
2024-03-30 18:17:35 +00:00
<title>Web Vitals</title>
2024-03-30 18:34:31 +00:00
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/json.min.js"></script>
2024-03-30 18:17:35 +00:00
<style>
2024-03-30 18:20:38 +00:00
:root {
color-scheme: light dark;
}
2024-03-30 18:17:35 +00:00
body {
padding: 0;
margin: 0;
}
select, input, button {
padding: 0.5rem;
}
select, button {
cursor: pointer;
}
.jsons {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(600px, 1fr));
gap: 1rem;
}
pre {
background-color: #f4f4f4;
border: 1px solid #ddd;
border-radius: 0.5rem;
2024-03-30 18:26:48 +00:00
border-color: light-dark(#ddd, #333);
2024-03-30 18:17:35 +00:00
overflow: hidden;
margin: 0;
}
code {
height: calc(100% - (2 * 13px));
}
.top_bar {
margin: 1rem;
}
.jsons {
margin: 1rem;
}
@media (max-width: 700px) {
.top_bar {
display: flex;
flex-direction: column;
gap: 1rem;
}
.jsons {
grid-template-columns: repeat(auto-fill, minmax(100%, 1fr));
}
}
</style>
</head>
<body>
<div class="top_bar">
<select class="api">
<option value="https://theclashfruit.me/api/v2">Production (https://theclashfruit.me/api/v2)</option>
<option value="http://localhost:3000/api/v2">Local Development (http://localhost:3000/api/v2)</option>
</select>
<select class="type">
<option value="TTFB">Time to First Byte</option>
<option value="FCP">First Contentful Paint</option>
<option value="LCP">Largest Contentful Paint</option>
<option value="FID">First Input Delay</option>
<option value="CLS">Cumulative Layout Shift</option>
<option value="INP">Interaction to Next Paint</option>
</select>
<select class="theme-selector"></select>
<input class="filter" placeholder="Filter" value="v.rating == 'good'" />
<button onclick="fetchApi(input.value)">Refresh</button>
<button onclick="downloadData(input.value)">Download Data</button>
</div>
<div class="jsons"></div>
<script>
const input = document.querySelector('.api');
const select = document.querySelector('.type');
const filter = document.querySelector('.filter');
const themes = document.querySelector('.theme-selector');
let events = [];
const iC = (e) => {
const url = e.target.value;
fetchApi(url);
}
const sC = (e) => {
const vital = e.target.value;
fetchApi(input.value);
}
input.onchange = iC;
select.onchange = sC;
filter.onchange = (e) => {
fetchApi(input.value);
}
themes.onchange = (e) => {
2024-03-30 18:34:31 +00:00
document.querySelector('#change').href = `https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/${e.target.value}`;
2024-03-30 18:17:35 +00:00
}
const fetchApi = async (url) => {
const parent = document.querySelector('.jsons');
parent.innerHTML = '';
fetch(`${url}/analytics/vitals`)
.then(response => response.json())
.then(data => {
data.filter(v => v.name === select.value).filter(v => eval(`${filter.value}`)).forEach(vital => {
const div = document.createElement('pre');
div.innerHTML = `<code>${JSON.stringify(vital, null, 2)}</code>`;
parent.appendChild(div);
});
hljs.highlightAll();
});
}
const downloadData = async (url) => {
fetch(`${url}/analytics/vitals`)
.then(response => response.json())
.then(data => {
const a = document.createElement('a');
a.href = URL.createObjectURL(new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }));
a.download = `vitals-${new Date().getTime()}.json`;
a.click();
});
}
fetchApi(input.value);
fetch('https://api.cdnjs.com/libraries/highlight.js/11.9.0')
.then(response => response.json())
.then(data => {
data.files.filter(f => f.includes('.min.css')).forEach(data => {
const newOption = document.createElement('option');
newOption.value = data
.replace('styles/', '');
newOption.innerText = data
.replace('styles/', '')
.replace('.min.css', '')
.replace('/', '-');
themes.appendChild(newOption);
});
themes.value = 'github.min.css';
});
</script>
</body>
</html>