add mojang endpoint status page
All checks were successful
Deploy App / docker (ubuntu-latest) (push) Successful in 1m13s

This commit is contained in:
Lee 2024-04-16 22:50:42 +01:00
parent 85793c8925
commit 46384ed26e
9 changed files with 159 additions and 11 deletions

@ -11,7 +11,7 @@
"prefix": "" "prefix": ""
}, },
"aliases": { "aliases": {
"components": "@/components", "components": "@/app/components",
"utils": "@/lib/utils" "utils": "@/common/utils"
} }
} }

@ -14,7 +14,7 @@
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.0", "clsx": "^2.1.0",
"lucide-react": "^0.368.0", "lucide-react": "^0.368.0",
"mcutils-library": "^1.1.1", "mcutils-library": "^1.1.3",
"next": "14.2.1", "next": "14.2.1",
"next-themes": "^0.3.0", "next-themes": "^0.3.0",
"react": "^18", "react": "^18",

8
pnpm-lock.yaml generated

@ -21,8 +21,8 @@ dependencies:
specifier: ^0.368.0 specifier: ^0.368.0
version: 0.368.0(react@18.2.0) version: 0.368.0(react@18.2.0)
mcutils-library: mcutils-library:
specifier: ^1.1.1 specifier: ^1.1.3
version: 1.1.1(@babel/core@7.24.4)(@types/node@20.12.7) version: 1.1.3(@babel/core@7.24.4)(@types/node@20.12.7)
next: next:
specifier: 14.2.1 specifier: 14.2.1
version: 14.2.1(@babel/core@7.24.4)(react-dom@18.2.0)(react@18.2.0) version: 14.2.1(@babel/core@7.24.4)(react-dom@18.2.0)(react@18.2.0)
@ -3516,8 +3516,8 @@ packages:
tmpl: 1.0.5 tmpl: 1.0.5
dev: false dev: false
/mcutils-library@1.1.1(@babel/core@7.24.4)(@types/node@20.12.7): /mcutils-library@1.1.3(@babel/core@7.24.4)(@types/node@20.12.7):
resolution: {integrity: sha512-OxZfC5KbqIYWcWJK+bikaCD9peCM3acgFP0e3OLLb+STU2czyaLMIt2sQ3yrqoS81emfKpaScQ5qK4nSTBGI1Q==} resolution: {integrity: sha512-LqTV8dbzShhJBD6xdZCg8S1TK0JZT3PcwwIaOZMgYVAt6bzGX3vf9lVI1JTreIhha9KQgKXTwnXxVuiLsFyueA==}
dependencies: dependencies:
axios: 1.6.8 axios: 1.6.8
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)

@ -0,0 +1,72 @@
import { Card } from "@/app/components/card";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/app/components/ui/table";
import { cn } from "@/common/utils";
import { getMojangEndpointStatus } from "mcutils-library";
import { CachedEndpointStatus } from "mcutils-library/dist/types/cache/cachedEndpointStatus";
import Link from "next/link";
async function getData(): Promise<CachedEndpointStatus> {
const status = await getMojangEndpointStatus();
return status;
}
/**
* Gets the color of the status
*
* @param status the status of the endpoint
* @returns the color of the status
*/
function getColor(status: any): string {
switch (status) {
case "ONLINE":
return "text-green-500";
case "DEGRADED":
return "text-yellow-500";
case "OFFLINE":
return "text-red-500";
default:
return "text-gray-500";
}
}
export default async function Page(): Promise<JSX.Element> {
const { endpoints } = await getData();
const endpointsSize = Object.entries(endpoints).length;
return (
<div className="flex justify-center text-center">
<Card className="w-max xs:w-fit">
<h1 className="text-xl">Mojang Status</h1>
<p>The current status of Mojang Services</p>
<div>
{endpointsSize === 0 && <p>Unable to fetch endpoint statuses</p>}
{endpointsSize > 0 && (
<Table className="mt-4 md:w-[500px] text-start">
<TableHeader>
<TableRow>
<TableHead className="pl-1">Service</TableHead>
<TableHead className="pl-1 text-center">Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{Object.entries(endpoints).map(([url, status]) => {
return (
<TableRow key={url}>
<TableCell className="p-[0.3rem]">
<Link className="hover:text-primary transition-all" href={url} target="_blank">
{url}
</Link>
</TableCell>
<TableCell className={cn(getColor(status), "p-[0.3rem] text-center")}>{status}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
)}
</div>
</Card>
</div>
);
}

@ -54,7 +54,7 @@ export default async function Page({ params }: Params): Promise<JSX.Element> {
<LookupPlayer /> <LookupPlayer />
</div> </div>
<Card> <Card className="w-max xs:w-fit">
{player == null && <NotFound message="Invalid UUID / Username" />} {player == null && <NotFound message="Invalid UUID / Username" />}
{player != null && ( {player != null && (
<div className="flex gap-4 flex-col xs:flex-row"> <div className="flex gap-4 flex-col xs:flex-row">

@ -75,7 +75,7 @@ export default async function Page({ params: { platform, hostname } }: Params):
<LookupServer /> <LookupServer />
</div> </div>
<Card> <Card className="w-max xs:w-fit">
{server == null && <NotFound message="Server not responding" />} {server == null && <NotFound message="Server not responding" />}
{server != null && ( {server != null && (
<div className="flex gap-4 flex-col"> <div className="flex gap-4 flex-col">

@ -1,7 +1,11 @@
import { cn } from "@/common/utils";
export function Card({ export function Card({
children, children,
className,
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode;
className?: string;
}>): JSX.Element { }>): JSX.Element {
return <div className="bg-secondary rounded-lg p-3 w-max xs:w-fit">{children}</div>; return <div className={cn("bg-secondary rounded-lg p-3", className)}>{children}</div>;
} }

@ -11,6 +11,7 @@ type Page = {
const pages: Page[] = [ const pages: Page[] = [
{ title: "Player", url: "/player/Notch" }, { title: "Player", url: "/player/Notch" },
{ title: "Server", url: "/server/java/hypixel.net" }, { title: "Server", url: "/server/java/hypixel.net" },
{ title: "Mojang", url: "/mojang" },
]; ];
export default function NavBar(): JSX.Element { export default function NavBar(): JSX.Element {
@ -27,7 +28,7 @@ export default function NavBar(): JSX.Element {
<div className="flex-grow"></div> <div className="flex-grow"></div>
<div className="mr-4 flex items-center gap-2"> <div className="mr-4 flex items-center gap-2">
<div className="hidden xs:block"> <div className="hidden md:block">
<RedirectButton <RedirectButton
title="Star us on Github!" title="Star us on Github!"
url="https://github.com/RealFascinated/minecraft-helper" url="https://github.com/RealFascinated/minecraft-helper"

@ -0,0 +1,71 @@
import { cn } from "@/common/utils";
import * as React from "react";
const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
({ className, ...props }, ref) => (
<div className="relative w-full overflow-auto">
<table ref={ref} className={cn("w-full caption-bottom text-sm", className)} {...props} />
</div>
)
);
Table.displayName = "Table";
const TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className, ...props }, ref) => <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
);
TableHeader.displayName = "TableHeader";
const TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className, ...props }, ref) => (
<tbody ref={ref} className={cn("[&_tr:last-child]:border-0", className)} {...props} />
)
);
TableBody.displayName = "TableBody";
const TableFooter = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className, ...props }, ref) => (
<tfoot ref={ref} className={cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className)} {...props} />
)
);
TableFooter.displayName = "TableFooter";
const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(
({ className, ...props }, ref) => (
<tr
ref={ref}
className={cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className)}
{...props}
/>
)
);
TableRow.displayName = "TableRow";
const TableHead = React.forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(
({ className, ...props }, ref) => (
<th
ref={ref}
className={cn(
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
className
)}
{...props}
/>
)
);
TableHead.displayName = "TableHead";
const TableCell = React.forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(
({ className, ...props }, ref) => (
<td ref={ref} className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)} {...props} />
)
);
TableCell.displayName = "TableCell";
const TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(
({ className, ...props }, ref) => (
<caption ref={ref} className={cn("mt-4 text-sm text-muted-foreground", className)} {...props} />
)
);
TableCaption.displayName = "TableCaption";
export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };