new mojang status page, and add color to the embed based on if there was any offline or degraded

This commit is contained in:
Lee 2024-04-19 18:50:12 +01:00
parent 7305714b12
commit 93ea24762c
5 changed files with 58 additions and 44 deletions

@ -24,7 +24,7 @@
"clipboard-copy": "^4.0.1", "clipboard-copy": "^4.0.1",
"clsx": "^2.1.0", "clsx": "^2.1.0",
"lucide-react": "^0.372.0", "lucide-react": "^0.372.0",
"mcutils-library": "^1.2.2", "mcutils-library": "^1.2.4",
"moment": "^2.30.1", "moment": "^2.30.1",
"next": "14.2.2", "next": "14.2.2",
"next-themes": "^0.3.0", "next-themes": "^0.3.0",

8
pnpm-lock.yaml generated

@ -51,8 +51,8 @@ dependencies:
specifier: ^0.372.0 specifier: ^0.372.0
version: 0.372.0(react@18.2.0) version: 0.372.0(react@18.2.0)
mcutils-library: mcutils-library:
specifier: ^1.2.2 specifier: ^1.2.4
version: 1.2.2(@babel/core@7.24.4)(@types/node@20.12.7) version: 1.2.4(@babel/core@7.24.4)(@types/node@20.12.7)
moment: moment:
specifier: ^2.30.1 specifier: ^2.30.1
version: 2.30.1 version: 2.30.1
@ -4360,8 +4360,8 @@ packages:
tmpl: 1.0.5 tmpl: 1.0.5
dev: false dev: false
/mcutils-library@1.2.2(@babel/core@7.24.4)(@types/node@20.12.7): /mcutils-library@1.2.4(@babel/core@7.24.4)(@types/node@20.12.7):
resolution: {integrity: sha512-OlzntolwWxkhdYUGbgHEK0ZbFFtqwUE/wbh+hTPtExLguebv3pCjPr0dBecVjOvtCs2mIyTA7u1rQOsEUh4CVg==} resolution: {integrity: sha512-CO5jEYAWgnTyJt5G9/bB4/rhSs9W5Ll2hxAOP+sIy9JVGhzkZQnet1kxD9oVwu75hEOmlOxNWt1IiUhYMmqN1A==}
dependencies: dependencies:
jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2)
ts-jest: 29.1.2(@babel/core@7.24.4)(jest@29.7.0)(typescript@5.4.5) ts-jest: 29.1.2(@babel/core@7.24.4)(jest@29.7.0)(typescript@5.4.5)

@ -4,10 +4,11 @@ import { generateEmbed } from "@/common/embed";
import { capitalizeFirstLetter } from "@/common/string-utils"; import { capitalizeFirstLetter } from "@/common/string-utils";
import { formatTime } from "@/common/time-utils"; import { formatTime } from "@/common/time-utils";
import { cn } from "@/common/utils"; import { cn } from "@/common/utils";
import { getMojangEndpointStatus } from "mcutils-library"; import { CachedEndpointStatus, getMojangEndpointStatus, Status } from "mcutils-library";
import { Metadata } from "next"; import { Metadata, Viewport } from "next";
import Link from "next/link"; import Link from "next/link";
import { ReactElement } from "react"; import { ReactElement } from "react";
import { Colors } from "@/common/colors";
/** /**
* Force the page to be dynamic, so it will be regenerated on every request * Force the page to be dynamic, so it will be regenerated on every request
@ -43,15 +44,31 @@ function formatStatus(status: any): string {
return capitalizeFirstLetter(status.toLowerCase()); return capitalizeFirstLetter(status.toLowerCase());
} }
export async function generateViewport(): Promise<Viewport> {
const { endpoints } = await getMojangEndpointStatus();
let warning = false;
for (const endpoint of endpoints) {
if (endpoint.status != Status.ONLINE) {
warning = true;
break;
}
}
return {
themeColor: warning ? Colors.yellow : Colors.green,
};
}
export async function generateMetadata(): Promise<Metadata> { export async function generateMetadata(): Promise<Metadata> {
const { endpoints } = await getMojangEndpointStatus(); const { endpoints } = await getMojangEndpointStatus();
let description = Object.entries(endpoints) let description = "Current Mojang API Status:\n";
.map(([url, status]) => { for (const endpoint of endpoints) {
return `${url}: ${formatStatus(status)}`; const { name, hostname, status } = endpoint;
})
.join("\n"); description += `${name} (${hostname}): ${status}\n`;
description += `\n\nEmbed Cache: ${formatTime(new Date())}`; }
return generateEmbed({ return generateEmbed({
title: "Mojang Status", title: "Mojang Status",
@ -61,7 +78,6 @@ export async function generateMetadata(): Promise<Metadata> {
export default async function Page(): Promise<ReactElement> { export default async function Page(): Promise<ReactElement> {
const { endpoints } = await getMojangEndpointStatus(); const { endpoints } = await getMojangEndpointStatus();
const endpointsSize = Object.entries(endpoints).length;
return ( return (
<div> <div>
@ -69,35 +85,32 @@ export default async function Page(): Promise<ReactElement> {
<h1 className="text-xl">Mojang Status</h1> <h1 className="text-xl">Mojang Status</h1>
<p>The current status of Mojang Services</p> <p>The current status of Mojang Services</p>
</div> </div>
<Card classNameContent="w-full xs:w-fit text-left"> <Card classNameCard="py-0 pb-2" classNameContent="w-[23rem] md:w-[35rem] text-left">
<div> <div className="flex flex-col divide-y gap-2">
{endpointsSize === 0 && <p>Unable to fetch endpoint statuses</p>} {endpoints.length == 0 && <p>Unable to fetch endpoint statuses</p>}
{endpointsSize > 0 && ( {endpoints.length > 0 &&
<Table className="md:w-[500px] text-start"> endpoints.map((endpoint: CachedEndpointStatus) => {
<TableHeader> const { name, hostname, status } = endpoint;
<TableRow>
<TableHead className="pl-1 h-8">Service</TableHead> const url = `https://${hostname}`;
<TableHead className="pl-1 h-8">Status</TableHead> return (
</TableRow> <div key={name} className="flex flex-row justify-between pt-2">
</TableHeader> <div className="flex flex-col leading-[1.5rem]">
<TableBody> <p className="font-semibold">{name}</p>
{Object.entries(endpoints).map(([url, status]) => { <Link
return ( href={url}
<TableRow key={url}> className="text-sm text-primary hover:opacity-75 transition-all transform-gpu"
<TableCell className="p-[0.3rem]"> target="_blank"
<Link className="hover:text-primary transition-all" href={url} target="_blank"> >
{url} <p>{url}</p>
</Link> </Link>
</TableCell> </div>
<TableCell className={cn(getColor(status), "p-[0.3rem] text-left")}> <div className={cn("flex items-center font-semibold", getColor(status))}>
{formatStatus(status)} <p>{formatStatus(status)}</p>
</TableCell> </div>
</TableRow> </div>
); );
})} })}
</TableBody>
</Table>
)}
</div> </div>
</Card> </Card>
</div> </div>

@ -40,7 +40,7 @@
--secondary-foreground: 0 0% 98%; --secondary-foreground: 0 0% 98%;
--muted: 0 0% 15%; --muted: 0 0% 15%;
--muted-foreground: 240 5% 64.9%; --muted-foreground: 240 5% 64.9%;
--accent: 12 6.5% 15.1%; --accent: 12 6.5% 75%;
--accent-foreground: 0 0% 98%; --accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%; --destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 85.7% 97.3%; --destructive-foreground: 0 85.7% 97.3%;

@ -4,4 +4,5 @@
export const Colors = { export const Colors = {
green: "#0FFF50", green: "#0FFF50",
red: "#8B0000", red: "#8B0000",
yellow: "#FFD700",
}; };