Raw Json button
All checks were successful
Deploy Frontend / docker (17, 3.8.5) (push) Successful in 1m10s

This commit is contained in:
Braydon 2024-04-17 19:43:35 -04:00
parent 69ce0fc469
commit 9dbe9632c0
4 changed files with 157 additions and 98 deletions

@ -1,6 +1,7 @@
{ {
"siteName": "RESTfulMC", "siteName": "RESTfulMC",
"siteUrl": "http://localhost:3000", "siteUrl": "http://localhost:3000",
"apiEndpoint": "https://api.restfulmc.cc",
"analyticsDomain": "restfulmc.cc", "analyticsDomain": "restfulmc.cc",
"metadata": { "metadata": {
"title": { "title": {

@ -1,8 +1,9 @@
/* eslint-disable @next/next/no-img-element */
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { CachedPlayer, SkinPart } from "restfulmc-lib"; import { CachedPlayer, SkinPart } from "restfulmc-lib";
import { ReactElement } from "react"; import { ReactElement } from "react";
import { Badge } from "@/components/ui/badge";
import config from "@/config";
/** /**
* The result of a player search. * The result of a player search.
@ -20,57 +21,73 @@ const PlayerResult = ({
}: { }: {
player: CachedPlayer; player: CachedPlayer;
}): ReactElement => ( }): ReactElement => (
<div className="px-2 py-3 flex flex-col gap-3 items-center bg-muted rounded-xl divide-y divide-zinc-700"> <div className="relative px-2 py-3 flex flex-col items-center bg-muted rounded-xl">
{/* Details */} {/* Raw Json */}
<div className="flex gap-5 items-center"> <div className="absolute top-[7.25rem] right-3">
{/* Player Head */} <Link
<Image href={`${config.apiEndpoint}/player/${username}`}
className="w-24 h-24 sm:w-28 sm:h-28 md:w-32 md:h-32" target="_blank"
src={parts.HEAD} >
alt={`${username}'s Head`} <Badge className="bg-minecraft-green-3 hover:bg-minecraft-green-3 hover:opacity-85 text-white font-semibold uppercase transition-all transform-gpu">
width={128} Raw Json
height={128} </Badge>
/> </Link>
{/* Name, Unique ID, and Badges */}
<div className="flex flex-col gap-1.5">
<h1 className="text-xl font-bold text-minecraft-green-3">
{username}
</h1>
<code className="text-xs xs:text-sm text-zinc-300">
{uniqueId}
</code>
{/* Legacy Badge */}
{legacy && (
<p className="text-sm font-semibold uppercase">Legacy</p>
)}
</div>
</div> </div>
{/* Skin Parts */} <div className="w-full flex flex-col gap-3 justify-center items-center divide-y divide-zinc-700">
<div className="pt-3 w-[90%] flex flex-col gap-3"> {/* Details */}
{/* Header */} <div className="flex gap-5 items-center">
<h1 className="font-semibold uppercase">Skin Parts</h1> {/* Player Head */}
<Image
className="w-24 h-24 sm:w-28 sm:h-28 md:w-32 md:h-32"
src={parts.HEAD}
alt={`${username}'s Head`}
width={128}
height={128}
/>
{/* Name, Unique ID, and Badges */}
<div className="flex flex-col gap-1.5">
<h1 className="text-xl font-bold text-minecraft-green-3">
{username}
</h1>
<code className="text-xs xs:text-sm text-zinc-300">
{uniqueId}
</code>
{/* Legacy Badge */}
{legacy && (
<p className="text-sm font-semibold uppercase">
Legacy
</p>
)}
</div>
</div>
{/* Skin Parts */} {/* Skin Parts */}
<div className="flex gap-5"> <div className="pt-3 w-[90%] flex flex-col gap-3">
{Object.entries(parts) {/* Header */}
.filter( <h1 className="font-semibold uppercase">Skin Parts</h1>
([part]) =>
part === SkinPart.HEAD || {/* Skin Parts */}
part === SkinPart.FACE || <div className="flex gap-5">
part === SkinPart.BODY_FLAT {Object.entries(parts)
) .filter(
.map(([part, url], index) => ( ([part]) =>
<Link key={index} href={url} target="_blank"> part === SkinPart.HEAD ||
<img part === SkinPart.FACE ||
className="h-20 sm:h-24 md:h-28 hover:scale-[1.02] transition-all transform-gpu" part === SkinPart.BODY_FLAT
src={url} )
alt={`${username}'s ${part}`} .map(([part, url], index) => (
/> <Link key={index} href={url} target="_blank">
</Link> <img
))} className="h-20 sm:h-24 md:h-28 hover:scale-[1.02] transition-all transform-gpu"
src={url}
alt={`${username}'s ${part}`}
/>
</Link>
))}
</div>
</div> </div>
</div> </div>
</div> </div>

@ -0,0 +1,36 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/app/lib/utils"
const badgeVariants = cva(
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
{
variants: {
variant: {
default:
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
secondary:
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive:
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
outline: "text-foreground",
},
},
defaultVariants: {
variant: "default",
},
}
)
export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) {
return (
<div className={cn(badgeVariants({ variant }), className)} {...props} />
)
}
export { Badge, badgeVariants }

@ -4,46 +4,51 @@ import { Metadata, Viewport } from "next";
* Options for configuration. * Options for configuration.
*/ */
interface Config { interface Config {
/** /**
* The name of this site. * The name of this site.
*/ */
siteName: string; siteName: string;
/** /**
* The URL of this site. * The URL of this site.
*/ */
siteUrl: string; siteUrl: string;
/** /**
* The optional domain to track analytics on. * The endpoint of the API.
*/ */
analyticsDomain: string | undefined; apiEndpoint: string;
/** /**
* The metadata of this site. * The optional domain to track analytics on.
*/ */
metadata: Metadata; analyticsDomain: string | undefined;
/** /**
* The viewport of this site. * The metadata of this site.
*/ */
viewport: Viewport; metadata: Metadata;
/** /**
* Links to display on the navbar. * The viewport of this site.
* <p> */
* The key is the name of the viewport: Viewport;
* link, and the value is the URL.
* </p>
*/
navbarLinks: {
[name: string]: string;
};
/** /**
* Featured items for the landing page. * Links to display on the navbar.
*/ * <p>
featuredItems: FeaturedItemProps[]; * The key is the name of the
* link, and the value is the URL.
* </p>
*/
navbarLinks: {
[name: string]: string;
};
/**
* Featured items for the landing page.
*/
featuredItems: FeaturedItemProps[];
} }
/** /**
@ -51,23 +56,23 @@ interface Config {
* on the landing page. * on the landing page.
*/ */
type FeaturedItemProps = { type FeaturedItemProps = {
/** /**
* The name of this item. * The name of this item.
*/ */
name: string; name: string;
/** /**
* The description of this item. * The description of this item.
*/ */
description: string; description: string;
/** /**
* The image for this item. * The image for this item.
*/ */
image: string; image: string;
/** /**
* The href link for this item. * The href link for this item.
*/ */
href: string; href: string;
}; };