diff --git a/src/app/player/[id]/page.tsx b/src/app/player/[id]/page.tsx new file mode 100644 index 0000000..18e93c0 --- /dev/null +++ b/src/app/player/[id]/page.tsx @@ -0,0 +1,46 @@ +import { NotFound } from "@/components/not-found"; +import { Card } from "@/components/ui/card"; +import { getPlayer } from "mcutils-library"; +import { Player } from "mcutils-library/dist/types/player/player"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Lookup Player", +}; + +async function getData(id: string): Promise { + try { + const cachedPlayer = await getPlayer(id); + return cachedPlayer.player; + } catch (error) { + return null; // Player not found + } +} + +type Params = { + params: { + id: string; + }; +}; + +export default async function Page({ params }: Params) { + const player = await getData(params.id); + + return ( +
+
+

Lookup a Player

+

You can enter a players uuid or username to get information about the player.

+
+ + + {player == null && } + {player != null && ( +
+

Username: {player.username}

+
+ )} +
+
+ ); +} diff --git a/src/app/player/page.tsx b/src/app/player/page.tsx deleted file mode 100644 index d2866c1..0000000 --- a/src/app/player/page.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import PlayerSearch from "@/components/player-search"; -import { Metadata } from "next"; - -export const metadata: Metadata = { - title: "Lookup Player", -}; - -export default function Player() { - return ( -
-
-

Lookup a Player

-

You can enter a players uuid or username to get information about the player.

-
- -
- ); -} diff --git a/src/app/server/[platform]/[hostname]/page.tsx b/src/app/server/[platform]/[hostname]/page.tsx new file mode 100644 index 0000000..09f856e --- /dev/null +++ b/src/app/server/[platform]/[hostname]/page.tsx @@ -0,0 +1,88 @@ +import { capitalizeFirstLetter } from "@/common/string-utils"; +import { LookupServer } from "@/components/lookup-server"; +import { NotFound } from "@/components/not-found"; +import { Card } from "@/components/ui/card"; +import { getServer } from "mcutils-library"; +import JavaMinecraftServer from "mcutils-library/dist/types/server/javaServer"; +import { ServerPlatform } from "mcutils-library/dist/types/server/platform"; +import { MinecraftServer } from "mcutils-library/dist/types/server/server"; +import { Metadata } from "next"; + +type Params = { + params: { + platform: ServerPlatform; + hostname: string; + }; +}; + +export async function generateMetadata({ params: { platform, hostname } }: Params): Promise { + const server = await getData(platform, hostname); + if (!server) { + return { + title: "Unknown Server", + }; + } + + const { hostname: serverHostname, players } = server; + let favicon = null; + + if (platform === ServerPlatform.Java) { + const javaServer = server as JavaMinecraftServer; + favicon = javaServer.favicon && javaServer.favicon.url; + } + + const description = ` + ${capitalizeFirstLetter(platform)} Server + Hostname: ${serverHostname} + ${players.online}/${players.max} players online`; + + return { + title: `${hostname}`, + openGraph: { + title: `${hostname}`, + description: description, + images: [ + { + url: favicon || "", + }, + ], + }, + twitter: { + card: "summary", + }, + }; +} + +async function getData(platform: ServerPlatform, id: string): Promise { + console.log(platform, id); + try { + const cachedServer = await getServer(platform, id); + return cachedServer.server; + } catch (error) { + return null; // Server not found + } +} + +export default async function Page({ params: { platform, hostname } }: Params) { + const server = await getData(platform, hostname); + + return ( +
+
+

Lookup a Server

+

You can enter a server hostname to get information about the server.

+ + +
+ + + {server == null && } + {server != null && ( +
+

Hostname: {server.hostname}

+
+ )} +
+
+ ); +} diff --git a/src/app/server/page.tsx b/src/app/server/page.tsx deleted file mode 100644 index 3ca143f..0000000 --- a/src/app/server/page.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import ServerSearch from "@/components/server-search"; -import { Metadata } from "next"; - -export const metadata: Metadata = { - title: "Lookup Server", -}; - -export default function Server() { - return ( -
-
-

Lookup a Server

-

You can enter a server ip or domain to get information about the server.

-
- -
- ); -} diff --git a/src/common/string-utils.ts b/src/common/string-utils.ts new file mode 100644 index 0000000..32d0652 --- /dev/null +++ b/src/common/string-utils.ts @@ -0,0 +1,9 @@ +/** + * Capitalizes the first letter of a string + * + * @param str the string to change + * @returns the updated string + */ +export function capitalizeFirstLetter(str: string) { + return str.charAt(0).toUpperCase() + str.slice(1); +} diff --git a/src/components/loading-card.tsx b/src/components/loading-card.tsx new file mode 100644 index 0000000..be98a09 --- /dev/null +++ b/src/components/loading-card.tsx @@ -0,0 +1,9 @@ +import { Card } from "./ui/card"; + +export function LoadingCard() { + return ( + +

Loading...

+
+ ); +} diff --git a/src/components/lookup-server.tsx b/src/components/lookup-server.tsx new file mode 100644 index 0000000..732c640 --- /dev/null +++ b/src/components/lookup-server.tsx @@ -0,0 +1,38 @@ +"use client"; + +import { ServerPlatform } from "mcutils-library/dist/types/server/platform"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; +import { Button } from "./ui/button"; +import { Input } from "./ui/input"; + +export function LookupServer() { + const router = useRouter(); + const [hostname, setHostname] = useState(""); + + /** + * Set the hostname value + * + * @param event the input event + */ + const setHostnameValue = (event: React.ChangeEvent) => { + setHostname(event.target.value); + }; + + /** + * Lookup a server based on the platform + * + * @param platform the server platform + */ + const lookupServer = (platform: ServerPlatform) => { + router.push(`/server/${platform}/${hostname}`); + }; + + return ( +
+ + + +
+ ); +} diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index aab6c5a..2116912 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -7,8 +7,8 @@ type Page = { }; const pages: Page[] = [ - { title: "Player", url: "/player" }, - { title: "Server", url: "/server" }, + { title: "Player", url: "/player/Notch" }, + { title: "Server", url: "/server/java/hypixel.net" }, ]; export default function NavBar() { diff --git a/src/components/not-found.tsx b/src/components/not-found.tsx new file mode 100644 index 0000000..43f8cc7 --- /dev/null +++ b/src/components/not-found.tsx @@ -0,0 +1,12 @@ +type NotFoundProps = { + message: string; +}; + +export function NotFound({ message }: NotFoundProps) { + return ( +
+

Not Found

+

{message}

+
+ ); +} diff --git a/src/components/player-search.tsx b/src/components/player-search.tsx deleted file mode 100644 index d9abb30..0000000 --- a/src/components/player-search.tsx +++ /dev/null @@ -1,87 +0,0 @@ -"use client"; - -import { getPlayer } from "mcutils-library"; -import { Player } from "mcutils-library/dist/types/player/player"; -import Image from "next/image"; -import Link from "next/link"; -import { useState } from "react"; -import { toast } from "react-toastify"; -import { Button } from "./ui/button"; -import { Card } from "./ui/card"; -import { Input } from "./ui/input"; - -const defaultPlayerId = "Notch"; - -export default function PlayerSearch() { - const [playerId, setPlayerId] = useState(defaultPlayerId); - const [player, setPlayer] = useState(null); - - const handleLookup = async () => { - if (playerId === null || playerId.length <= 0) { - toast.error("Please enter a player ID"); - return; - } - try { - const cachedPlayer = await getPlayer(playerId); - const { player } = cachedPlayer; - - setPlayer(player); - } catch (error) { - toast.error("Unknown player"); - return; - } - }; - - const handleKeyDown = (e: any) => { - if (e.key === "Enter") { - handleLookup(); - } - }; - - return ( -
-
- setPlayerId(e.target.value)} - onKeyDown={handleKeyDown} - /> - -
- - {player && ( - -
-
- The player's Head -
-
-

- UUID: {player.uniqueId} -

-

- Name: {player.username} -

-
-

Skin Parts

-
- {Object.keys(player.skin.parts).map((part: any, index: number) => { - return ( -

- - {part} - -

- ); - })} -
-
-
-
-
- )} -
- ); -} diff --git a/src/components/server-search.tsx b/src/components/server-search.tsx deleted file mode 100644 index ee1615d..0000000 --- a/src/components/server-search.tsx +++ /dev/null @@ -1,82 +0,0 @@ -"use client"; - -import { cn } from "@/common/utils"; -import { getServer } from "mcutils-library"; -import JavaMinecraftServer from "mcutils-library/dist/types/server/javaServer"; -import { ServerPlatform } from "mcutils-library/dist/types/server/platform"; -import Image from "next/image"; -import { useState } from "react"; -import { toast } from "react-toastify"; -import { Button } from "./ui/button"; -import { Card } from "./ui/card"; -import { Input } from "./ui/input"; - -const defaultServerHostname = "play.hypixel.net"; - -export default function ServerSearch() { - const [serverHostname, setServerHostname] = useState(defaultServerHostname); - const [server, setServer] = useState(null); - - const handleLookup = async () => { - if (serverHostname === null || serverHostname.length <= 0) { - toast.error("Please enter a server hostname"); - return; - } - try { - const cachedServer = await getServer(ServerPlatform.Java, serverHostname); - const { server } = cachedServer; - setServer(server as JavaMinecraftServer); - } catch (error) { - toast.error("Unknown server"); - return; - } - }; - - const handleKeyDown = (e: any) => { - if (e.key === "Enter") { - handleLookup(); - } - }; - - return ( -
-
- setServerHostname(e.target.value)} - onKeyDown={handleKeyDown} - /> - -
- - {server && ( - -
-
-
- The server's Favicon -
- -
- {server.motd.html.map((line, index) => { - return
; - })} -
-
- -
-
- Host: {server.hostname} -
-
- Players: {server.players.online}/{server.players.max} -
-
-
- - )} -
- ); -} diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index 545d935..75b8b54 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -3,5 +3,5 @@ export function Card({ }: Readonly<{ children: React.ReactNode; }>) { - return
{children}
; + return
{children}
; } diff --git a/src/consts.ts b/src/consts.ts deleted file mode 100644 index 81b4074..0000000 --- a/src/consts.ts +++ /dev/null @@ -1 +0,0 @@ -export const API_ENDPOINT = "https://api.mcutils.xyz";