make the server page show a minecraft style server
Some checks failed
Deploy App / docker (ubuntu-latest) (push) Failing after 28s

This commit is contained in:
Lee 2024-04-19 16:51:58 +01:00
parent 0708def9a1
commit 78709ed060
8 changed files with 62 additions and 45 deletions

@ -53,7 +53,7 @@ export default function Home(): ReactElement {
<div className="text-center flex flex-col gap-4"> <div className="text-center flex flex-col gap-4">
<div className="p-4"> <div className="p-4">
<div> <div>
<h1 className="text-4xl mb-2 font-semibold">Minecraft Utilities</h1> <h1 className="text-4xl mb-2">Minecraft Utilities</h1>
<div> <div>
<p> <p>
Minecraft Utilities offers you many endpoints to get information about a minecraft server or a player. Minecraft Utilities offers you many endpoints to get information about a minecraft server or a player.

@ -1,6 +1,7 @@
import { Card as ShadcnCard, CardContent } from "@/app/components/ui/card"; import { Card as ShadcnCard, CardContent } from "@/app/components/ui/card";
import { cn } from "@/common/utils"; import { cn } from "@/common/utils";
import { ReactElement } from "react"; import { ReactElement } from "react";
import { type ClassValue } from "clsx";
type CardProps = { type CardProps = {
/** /**
@ -9,15 +10,20 @@ type CardProps = {
children: React.ReactNode; children: React.ReactNode;
/** /**
* The class names to append. * The class names for the card.
*/ */
className?: string; classNameCard?: ClassValue;
/**
* The class names for the content.
*/
classNameContent?: ClassValue;
}; };
export function Card({ children, className }: CardProps): ReactElement { export function Card({ children, classNameCard, classNameContent }: CardProps): ReactElement {
return ( return (
<ShadcnCard className={cn(className, "pt-4")}> <ShadcnCard className={cn("p-1.5", classNameCard)}>
<CardContent>{children}</CardContent> <CardContent className={cn("p-1.5", classNameContent)}>{children}</CardContent>
</ShadcnCard> </ShadcnCard>
); );
} }

@ -42,12 +42,12 @@ export default function NavBar(): ReactElement {
<div className="z-50"> <div className="z-50">
<Link href="/" className="flex items-center gap-2"> <Link href="/" className="flex items-center gap-2">
<Logo /> <Logo />
<p className="hidden md:block">Minecraft Utilities</p> <p className="hidden lg:block text-lg font-semibold">Minecraft Utilities</p>
</Link> </Link>
</div> </div>
{/* Links */} {/* Links */}
<div className="absolute inset-x-0 flex justify-center"> <div className="absolute inset-x-0 flex justify-start ml-16 lg:ml-0 lg:justify-center xs:justify-center">
<div className="flex gap-4"> <div className="flex gap-4">
{pages.map((page, index) => { {pages.map((page, index) => {
const isActive = path.includes(page.url); const isActive = path.includes(page.url);

@ -5,6 +5,9 @@ import { ReactElement } from "react";
import { Card } from "../card"; import { Card } from "../card";
import { CodeDialog } from "../code-dialog"; import { CodeDialog } from "../code-dialog";
import { Button } from "../ui/button"; import { Button } from "../ui/button";
import config from "@root/config.json";
import { cn } from "@/common/utils";
import { minecraft } from "@/app/font/fonts";
type ServerViewProps = { type ServerViewProps = {
/** /**
@ -20,38 +23,37 @@ type ServerViewProps = {
export function ServerView({ server, favicon }: ServerViewProps): ReactElement { export function ServerView({ server, favicon }: ServerViewProps): ReactElement {
return ( return (
<div className="flex flex-col gap-2 items-center"> <div className="flex flex-col gap-2 items-center scale-75 xs:scale-100">
<Card className="w-max xs:w-fit relative"> <Card classNameContent="w-max xs:w-fit relative">
<div className="flex gap-2 flex-col"> <div
<div className="flex gap-4 flex-col xs:flex-row"> className={cn(
{favicon && ( "w-[31rem] relative p-2 flex gap-2 rounded-lg pointer-events-none",
<div className="flex justify-center xs:justify-start"> 'bg-[url("/media/server-background.png")]',
)}
>
{/* Favicon */}
<Image <Image
className="w-[64px] h-[64px]" src={favicon || `${config.apiUrl}/server/icon/fallback`}
src={favicon} alt={`${server.hostname}'s Favicon`}
width={64} width={64}
height={64} height={64}
quality={100}
alt="The server's favicon"
/> />
</div>
)}
<div className="flex flex-col"> {/* Name & MOTD */}
<h2 className="text-xl text-primary font-semibold">{server.hostname}</h2> <div className={cn("flex flex-col leading-[1.3rem] w-full", minecraft.className)}>
<div> <h1>{server.hostname}</h1>
<p> {server.motd.html.map((line: string, index: number): ReactElement => {
Players online: {formatNumber(server.players.online)}/{formatNumber(server.players.max)} return <p key={index} className="pointer-events-auto" dangerouslySetInnerHTML={{ __html: line }}></p>;
</p>
</div>
</div>
</div>
<div className="bg-background rounded-lg p-2 text-sm xs:text-lg">
{server.motd.html.map((line, index) => {
return <p key={index} dangerouslySetInnerHTML={{ __html: line }}></p>;
})} })}
</div> </div>
{/* Ping */}
<div className={cn("absolute top-0.5 right-0.5 flex items-center", minecraft.className)}>
<p>
{server.players.online}/{server.players.max}
</p>
<Image src="/media/full-ping.png" alt="Ping!" width={28} height={28} />
</div>
</div> </div>
</Card> </Card>
<div className="8xl:top-0 xs:bottom-0"> <div className="8xl:top-0 xs:bottom-0">

BIN
src/app/font/Minecraft.otf Normal file

Binary file not shown.

16
src/app/font/fonts.ts Normal file

@ -0,0 +1,16 @@
import { Inter } from "next/font/google";
import localFont from "next/font/local";
import { NextFont } from "next/dist/compiled/@next/font";
/**
* The default font to use for the site.
*/
export const inter = Inter({ subsets: ["latin"] });
/**
* The Minecraft font to use for the site.
*/
export const minecraft: NextFont = localFont({
src: "../font/Minecraft.otf",
});

@ -1,4 +1,3 @@
import { Fonts } from "@/common/fonts";
import { Metadata, Viewport } from "next"; import { Metadata, Viewport } from "next";
import Script from "next/script"; import Script from "next/script";
import { ReactElement } from "react"; import { ReactElement } from "react";
@ -9,6 +8,7 @@ import { TooltipProvider } from "./components/ui/tooltip";
import "./globals.css"; import "./globals.css";
import config from "@root/config.json"; import config from "@root/config.json";
import { inter } from "@/app/font/fonts";
export const viewport: Viewport = { export const viewport: Viewport = {
themeColor: "#3498DB", themeColor: "#3498DB",
@ -47,7 +47,7 @@ export default function RootLayout({
return ( return (
<> <>
<Script defer data-domain="mcutils.xyz" src="https://analytics.fascinated.cc/js/script.js" /> <Script defer data-domain="mcutils.xyz" src="https://analytics.fascinated.cc/js/script.js" />
<html className={Fonts.inter.className} lang="en" suppressHydrationWarning> <html className={inter.className} lang="en" suppressHydrationWarning>
<head /> <head />
<body> <body>
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem disableTransitionOnChange> <ThemeProvider attribute="class" defaultTheme="dark" enableSystem disableTransitionOnChange>

@ -1,7 +0,0 @@
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"] });
export const Fonts = {
inter: inter,
};