mirror of
https://github.com/wah-su/wah-su.github.io.git
synced 2025-04-09 01:34:40 +00:00
feat: return service status indicator
This commit is contained in:
parent
48365f5764
commit
fe5b125690
4 changed files with 137 additions and 171 deletions
|
@ -21,7 +21,7 @@
|
|||
<p class="text-xl sm:text-3xl" id="status-text">Fetching Services Status</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex flex-col-reverse gap-8 lg:flex-row lg:items-end lg:justify-between md:m-0">
|
||||
<div class="flex flex-col-reverse gap-8 lg:flex-row lg:items-end lg:justify-between">
|
||||
<div class="text-lg sm:text-2xl">
|
||||
<p>Run by <a class="underline hover:text-[#ff851b] transition-colors" href="https://wah.su/radiquum">@radiquum</a></p>
|
||||
<p>Photo by <a class="underline hover:text-[#ff851b] transition-colors" href="https://unsplash.com/@willrust">Will Rust</a> on <a class="underline hover:text-[#ff851b] transition-colors" href="https://unsplash.com/">Unsplash</a></p>
|
||||
|
@ -36,6 +36,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="static/js/checkstatus.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
84
static/js/checkstatus.js
Normal file
84
static/js/checkstatus.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
const statusIcon = document.getElementById("status-icon");
|
||||
const statusText = document.getElementById("status-text");
|
||||
|
||||
const serviceUp = {
|
||||
color: ["bg-green-500", "dark:bg-green-400"],
|
||||
text: "All Services Operational",
|
||||
};
|
||||
const serviceDegraded = {
|
||||
color: ["bg-yellow-400", "dark:bg-yellow-200"],
|
||||
text: "Degraded Services",
|
||||
};
|
||||
const serviceDown = {
|
||||
color: ["bg-red-600", "dark:bg-red-500"],
|
||||
text: "All Services Down",
|
||||
};
|
||||
const serviceUnknown = {
|
||||
color: ["bg-gray-500", "dark:bg-gray-400"],
|
||||
text: "Unknown or Failed to fetch",
|
||||
};
|
||||
|
||||
async function getServicesHealth() {
|
||||
try {
|
||||
const serviceStatus = await fetch(
|
||||
"https://status.wah.su/api/status-page/heartbeat/services"
|
||||
);
|
||||
|
||||
const services = await serviceStatus.json();
|
||||
const heartbeatDict = services.heartbeatList;
|
||||
let lastHeartbeats = [];
|
||||
|
||||
for (const [key, value] of Object.entries(heartbeatDict)) {
|
||||
lastHeartbeats.push(
|
||||
heartbeatDict[key][heartbeatDict[key].length - 1].status
|
||||
);
|
||||
}
|
||||
const count = lastHeartbeats.reduce((partialSum, a) => partialSum + a, 0);
|
||||
|
||||
switch (count) {
|
||||
case lastHeartbeats.length: {
|
||||
statusIcon.classList.add(...serviceUp.color);
|
||||
statusIcon.classList.remove(
|
||||
...serviceDegraded.color,
|
||||
...serviceDown.color,
|
||||
...serviceUnknown.color
|
||||
);
|
||||
statusText.textContent = serviceUp.text;
|
||||
break;
|
||||
}
|
||||
case 0: {
|
||||
statusIcon.classList.add(...serviceDown.color);
|
||||
statusIcon.classList.remove(
|
||||
...serviceUp.color,
|
||||
...serviceDegraded.color,
|
||||
...serviceUnknown.color
|
||||
);
|
||||
statusText.textContent = serviceDown.text;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
statusIcon.classList.add(...serviceDegraded.color);
|
||||
statusIcon.classList.remove(
|
||||
...serviceUp.color,
|
||||
...serviceDown.color,
|
||||
...serviceUnknown.color
|
||||
);
|
||||
statusText.textContent = serviceDegraded.text;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
statusIcon.classList.add(...serviceUnknown.color);
|
||||
statusIcon.classList.remove(
|
||||
...serviceUp.color,
|
||||
...serviceDegraded.color,
|
||||
...serviceDown.color
|
||||
);
|
||||
statusText.textContent = serviceUnknown.text;
|
||||
console.log("Failed to fetch services status: " + error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
getServicesHealth();
|
||||
setInterval(getServicesHealth, 600000);
|
|
@ -594,10 +594,6 @@ video {
|
|||
position: absolute;
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inset-0 {
|
||||
inset: 0px;
|
||||
}
|
||||
|
@ -606,39 +602,6 @@ video {
|
|||
z-index: -10;
|
||||
}
|
||||
|
||||
.my-auto {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
.mt-16 {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.-mt-16 {
|
||||
margin-top: -4rem;
|
||||
}
|
||||
|
||||
.-mb-16 {
|
||||
margin-bottom: -4rem;
|
||||
}
|
||||
|
||||
.-mb-32 {
|
||||
margin-bottom: -8rem;
|
||||
}
|
||||
|
||||
.-mb-64 {
|
||||
margin-bottom: -16rem;
|
||||
}
|
||||
|
||||
.-mb-48 {
|
||||
margin-bottom: -12rem;
|
||||
}
|
||||
|
||||
.-mb-40 {
|
||||
margin-bottom: -10rem;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
@ -647,18 +610,6 @@ video {
|
|||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
.h-4 {
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.h-full {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.h-8 {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.h-6 {
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
@ -667,42 +618,20 @@ video {
|
|||
height: 100dvh;
|
||||
}
|
||||
|
||||
.min-h-screen {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.w-4 {
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.w-8 {
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.w-32 {
|
||||
width: 8rem;
|
||||
}
|
||||
|
||||
.w-64 {
|
||||
width: 16rem;
|
||||
}
|
||||
|
||||
.w-96 {
|
||||
width: 24rem;
|
||||
.h-full {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.w-6 {
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.scale-110 {
|
||||
--tw-scale-x: 1.1;
|
||||
--tw-scale-y: 1.1;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
.w-96 {
|
||||
width: 24rem;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
|
@ -717,10 +646,6 @@ video {
|
|||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.items-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
@ -733,18 +658,14 @@ video {
|
|||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.gap-2 {
|
||||
gap: 0.5rem;
|
||||
.gap-4 {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.gap-8 {
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.gap-4 {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.rounded-full {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
@ -759,16 +680,19 @@ video {
|
|||
background-color: rgb(107 114 128 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.bg-cover {
|
||||
background-size: cover;
|
||||
.bg-green-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.bg-center {
|
||||
background-position: center;
|
||||
.bg-red-600 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.bg-no-repeat {
|
||||
background-repeat: no-repeat;
|
||||
.bg-yellow-400 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(250 204 21 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.object-cover {
|
||||
|
@ -776,20 +700,13 @@ video {
|
|||
object-fit: cover;
|
||||
}
|
||||
|
||||
.p-16 {
|
||||
padding: 4rem;
|
||||
}
|
||||
|
||||
.p-8 {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.text-lg {
|
||||
|
@ -802,30 +719,6 @@ video {
|
|||
line-height: 1.75rem;
|
||||
}
|
||||
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.text-4xl {
|
||||
font-size: 2.25rem;
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
|
||||
.text-3xl {
|
||||
font-size: 1.875rem;
|
||||
line-height: 2.25rem;
|
||||
}
|
||||
|
||||
.text-8xl {
|
||||
font-size: 6rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.text-white {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity, 1));
|
||||
|
@ -835,25 +728,11 @@ video {
|
|||
text-decoration-line: underline;
|
||||
}
|
||||
|
||||
.blur-3xl {
|
||||
--tw-blur: blur(64px);
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
|
||||
.blur-sm {
|
||||
--tw-blur: blur(4px);
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
|
||||
.blur-md {
|
||||
--tw-blur: blur(12px);
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
|
||||
.filter {
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
|
||||
.transition {
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
||||
|
@ -872,14 +751,6 @@ video {
|
|||
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
|
||||
}
|
||||
|
||||
.\[background-image\:url\(\'will-rust-Vv1E0zcQDCI-unsplash\.jpg\'\)\] {
|
||||
background-image: url('will-rust-Vv1E0zcQDCI-unsplash.jpg');
|
||||
}
|
||||
|
||||
.\[box-shadow\:_0_0_16px_16px_transparent_inset\] {
|
||||
box-shadow: 0 0 16px 16px transparent inset;
|
||||
}
|
||||
|
||||
.ubuntu-mono-regular {
|
||||
font-family: "Ubuntu Mono", monospace;
|
||||
font-weight: 400;
|
||||
|
@ -918,34 +789,21 @@ video {
|
|||
width: 2rem;
|
||||
}
|
||||
|
||||
.sm\:text-3xl {
|
||||
font-size: 1.875rem;
|
||||
line-height: 2.25rem;
|
||||
}
|
||||
|
||||
.sm\:text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.sm\:text-3xl {
|
||||
font-size: 1.875rem;
|
||||
line-height: 2.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.md\:m-0 {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.md\:p-16 {
|
||||
padding: 4rem;
|
||||
}
|
||||
|
||||
.md\:text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.md\:text-3xl {
|
||||
font-size: 1.875rem;
|
||||
line-height: 2.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
|
@ -968,4 +826,26 @@ video {
|
|||
.lg\:text-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.dark\:bg-gray-400 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(156 163 175 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.dark\:bg-green-400 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(74 222 128 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.dark\:bg-red-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.dark\:bg-yellow-200 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 240 138 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./index.html"],
|
||||
content: ["./index.html", "./static/js/**/*.js"],
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
|
|
Loading…
Add table
Reference in a new issue