Raw Json button
All checks were successful
Deploy Frontend / docker (17, 3.8.5) (push) Successful in 1m10s
All checks were successful
Deploy Frontend / docker (17, 3.8.5) (push) Successful in 1m10s
This commit is contained in:
parent
69ce0fc469
commit
9dbe9632c0
@ -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>
|
||||||
|
36
Frontend/src/app/components/ui/badge.tsx
Normal file
36
Frontend/src/app/components/ui/badge.tsx
Normal file
@ -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 }
|
105
Frontend/src/app/types/config.d.ts
vendored
105
Frontend/src/app/types/config.d.ts
vendored
@ -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;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user