add mojang endpoint status page
All checks were successful
Deploy App / docker (ubuntu-latest) (push) Successful in 1m13s
All checks were successful
Deploy App / docker (ubuntu-latest) (push) Successful in 1m13s
This commit is contained in:
parent
85793c8925
commit
46384ed26e
@ -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
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)
|
||||||
|
72
src/app/(pages)/mojang/page.tsx
Normal file
72
src/app/(pages)/mojang/page.tsx
Normal file
@ -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"
|
||||||
|
71
src/app/components/ui/table.tsx
Normal file
71
src/app/components/ui/table.tsx
Normal file
@ -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 };
|
Loading…
Reference in New Issue
Block a user