From a1dfa6b6fa3e801152e619d12df195598510b51c Mon Sep 17 00:00:00 2001 From: Rainnny7 Date: Wed, 17 Apr 2024 20:37:49 -0400 Subject: [PATCH] Updates --- Frontend/bun.lockb | Bin 167118 -> 176941 bytes Frontend/package.json | 3 + .../app/(pages)/player/[[...slug]]/page.tsx | 4 +- Frontend/src/app/components/copy-button.tsx | 28 +++ Frontend/src/app/components/embed.tsx | 8 + .../components/landing/statistic-counters.tsx | 2 +- .../app/components/player/player-result.tsx | 161 ++++++++------ .../src/app/components/ui/context-menu.tsx | 200 ++++++++++++++++++ Frontend/src/app/layout.tsx | 1 - Frontend/tailwind.config.ts | 158 +++++++------- 10 files changed, 418 insertions(+), 147 deletions(-) create mode 100644 Frontend/src/app/components/copy-button.tsx create mode 100644 Frontend/src/app/components/ui/context-menu.tsx diff --git a/Frontend/bun.lockb b/Frontend/bun.lockb index bacd45caa889eefa5f60d6912b9da6179d0a0673..61d9b926efce062fb1792bd19a099fff50a63fa3 100644 GIT binary patch delta 36106 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 Aa{vGU diff --git a/Frontend/package.json b/Frontend/package.json index fa92606..a2f1f17 100644 --- a/Frontend/package.json +++ b/Frontend/package.json @@ -13,10 +13,13 @@ "dependencies": { "@heroicons/react": "^2.1.3", "@hookform/resolvers": "^3.3.4", + "@radix-ui/react-context-menu": "^2.1.5", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-tooltip": "^1.0.7", "class-variance-authority": "^0.7.0", + "clipboard-copy": "^4.0.1", "clsx": "^2.1.0", "lucide-react": "^0.370.0", "next": "14.2.1", diff --git a/Frontend/src/app/(pages)/player/[[...slug]]/page.tsx b/Frontend/src/app/(pages)/player/[[...slug]]/page.tsx index 1a2052e..138fe4c 100644 --- a/Frontend/src/app/(pages)/player/[[...slug]]/page.tsx +++ b/Frontend/src/app/(pages)/player/[[...slug]]/page.tsx @@ -59,7 +59,7 @@ const PlayerPage = async ({ params }: PageProps): Promise => { {/* Player Result */} - {result && } + {result && } @@ -92,11 +92,13 @@ export const generateMetadata = async ({ if (code === 400) { return Embed({ title: "Invalid Player", + color: "#EB4034", description: "The player you searched for is invalid.", }); } else if (code === 404) { return Embed({ title: "Player Not Found", + color: "#EB4034", description: "The player you searched for was not found.", }); } diff --git a/Frontend/src/app/components/copy-button.tsx b/Frontend/src/app/components/copy-button.tsx new file mode 100644 index 0000000..d51fcf3 --- /dev/null +++ b/Frontend/src/app/components/copy-button.tsx @@ -0,0 +1,28 @@ +"use client"; + +import { ReactElement, ReactNode } from "react"; +import copy from "clipboard-copy"; + +/** + * Props for the copy button. + */ +type CopyButtonProps = { + /** + * The content to copy when + * this component is clicked. + */ + content: string; + + /** + * The children to render in this button. + */ + children: ReactNode; +}; + +/** + * A component that copies + */ +const CopyButton = ({ content, children }: CopyButtonProps): ReactElement => ( + +); +export default CopyButton; diff --git a/Frontend/src/app/components/embed.tsx b/Frontend/src/app/components/embed.tsx index cfdcabc..c82d51f 100644 --- a/Frontend/src/app/components/embed.tsx +++ b/Frontend/src/app/components/embed.tsx @@ -9,6 +9,12 @@ type EmbedProps = { */ title: string; + /** + * The color of this embed, undefined + * for no custom color. + */ + color?: string | undefined; + /** * The description of the embed. */ @@ -28,6 +34,7 @@ type EmbedProps = { */ const Embed = ({ title, + color, description, thumbnail = "", }: EmbedProps): Metadata => { @@ -45,6 +52,7 @@ const Embed = ({ twitter: { card: "summary", }, + themeColor: color, }; }; export default Embed; diff --git a/Frontend/src/app/components/landing/statistic-counters.tsx b/Frontend/src/app/components/landing/statistic-counters.tsx index 7fd3b7f..633ea73 100644 --- a/Frontend/src/app/components/landing/statistic-counters.tsx +++ b/Frontend/src/app/components/landing/statistic-counters.tsx @@ -8,7 +8,7 @@ import { ReactElement } from "react"; */ const StatisticCounters = (): ReactElement => (
-
+
diff --git a/Frontend/src/app/components/player/player-result.tsx b/Frontend/src/app/components/player/player-result.tsx index 9acc54d..8bb43d6 100644 --- a/Frontend/src/app/components/player/player-result.tsx +++ b/Frontend/src/app/components/player/player-result.tsx @@ -4,6 +4,14 @@ import { CachedPlayer, SkinPart } from "restfulmc-lib"; import { ReactElement } from "react"; import { Badge } from "@/components/ui/badge"; import config from "@/config"; +import { + ContextMenu, + ContextMenuContent, + ContextMenuItem, + ContextMenuTrigger, +} from "@/components/ui/context-menu"; +import CopyButton from "@/components/copy-button"; +import * as querystring from "node:querystring"; /** * The result of a player search. @@ -12,6 +20,7 @@ import config from "@/config"; * @returns the player result jsx */ const PlayerResult = ({ + query, player: { uniqueId, username, @@ -19,77 +28,99 @@ const PlayerResult = ({ legacy, }, }: { + query: string; player: CachedPlayer; }): ReactElement => ( -
- {/* Raw Json */} -
- - - Raw Json - - -
+ + +
+ {/* Raw Json */} +
+ + + Raw Json + + +
-
- {/* Details */} -
- {/* Player Head */} - {`${username}'s +
+ {/* Details */} +
+ {/* Player Head */} + {`${username}'s - {/* Name, Unique ID, and Badges */} -
-

- {username} -

- - {uniqueId} - + {/* Name, Unique ID, and Badges */} +
+

+ {username} +

+ + {uniqueId} + - {/* Legacy Badge */} - {legacy && ( -

- Legacy -

- )} + {/* Legacy Badge */} + {legacy && ( +

+ Legacy +

+ )} +
+
+ + {/* Skin Parts */} +
+ {/* Header */} +

Skin Parts

+ + {/* Skin Parts */} +
+ {Object.entries(parts) + .filter( + ([part]) => + part === SkinPart.HEAD || + part === SkinPart.FACE || + part === SkinPart.BODY_FLAT + ) + .map(([part, url], index) => ( + + {`${username}'s + + ))} +
+
- - {/* Skin Parts */} -
- {/* Header */} -

Skin Parts

- - {/* Skin Parts */} -
- {Object.entries(parts) - .filter( - ([part]) => - part === SkinPart.HEAD || - part === SkinPart.FACE || - part === SkinPart.BODY_FLAT - ) - .map(([part, url], index) => ( - - {`${username}'s - - ))} -
-
-
-
+ + + + Copy Player Username + + + Copy Player UUID + + + + Copy Share URL + + + + ); export default PlayerResult; diff --git a/Frontend/src/app/components/ui/context-menu.tsx b/Frontend/src/app/components/ui/context-menu.tsx new file mode 100644 index 0000000..2bd9c6b --- /dev/null +++ b/Frontend/src/app/components/ui/context-menu.tsx @@ -0,0 +1,200 @@ +"use client" + +import * as React from "react" +import * as ContextMenuPrimitive from "@radix-ui/react-context-menu" +import { Check, ChevronRight, Circle } from "lucide-react" + +import { cn } from "@/app/lib/utils" + +const ContextMenu = ContextMenuPrimitive.Root + +const ContextMenuTrigger = ContextMenuPrimitive.Trigger + +const ContextMenuGroup = ContextMenuPrimitive.Group + +const ContextMenuPortal = ContextMenuPrimitive.Portal + +const ContextMenuSub = ContextMenuPrimitive.Sub + +const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup + +const ContextMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName + +const ContextMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName + +const ContextMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName + +const ContextMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName + +const ContextMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +ContextMenuCheckboxItem.displayName = + ContextMenuPrimitive.CheckboxItem.displayName + +const ContextMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName + +const ContextMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName + +const ContextMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName + +const ContextMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +ContextMenuShortcut.displayName = "ContextMenuShortcut" + +export { + ContextMenu, + ContextMenuTrigger, + ContextMenuContent, + ContextMenuItem, + ContextMenuCheckboxItem, + ContextMenuRadioItem, + ContextMenuLabel, + ContextMenuSeparator, + ContextMenuShortcut, + ContextMenuGroup, + ContextMenuPortal, + ContextMenuSub, + ContextMenuSubContent, + ContextMenuSubTrigger, + ContextMenuRadioGroup, +} diff --git a/Frontend/src/app/layout.tsx b/Frontend/src/app/layout.tsx index 8f2ba0b..6708bd2 100644 --- a/Frontend/src/app/layout.tsx +++ b/Frontend/src/app/layout.tsx @@ -1,4 +1,3 @@ -import Footer from "@/components/footer"; import Navbar from "@/components/navbar"; import { TooltipProvider } from "@/components/ui/tooltip"; import config from "@/config"; diff --git a/Frontend/tailwind.config.ts b/Frontend/tailwind.config.ts index 94bcd01..609822f 100644 --- a/Frontend/tailwind.config.ts +++ b/Frontend/tailwind.config.ts @@ -1,86 +1,86 @@ import type { Config } from "tailwindcss"; -const { fontFamily, screens } = require("tailwindcss/defaultTheme"); +const { screens } = require("tailwindcss/defaultTheme"); const config = { - darkMode: ["class"], - content: ["./src/app/**/*.{ts,tsx}"], - theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, - }, - extend: { - colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", - }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", - }, - destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, - accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", - }, + darkMode: ["class"], + content: ["./src/app/**/*.{ts,tsx}"], + theme: { + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", + }, + }, + extend: { + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, - // Custom Colors - "navbar-background": "hsl(var(--navbar-background))", - "minecraft-green-1": "hsl(var(--minecraft-green-1))", - "minecraft-green-2": "hsl(var(--minecraft-green-2))", - "minecraft-green-3": "hsl(var(--minecraft-green-3))", - "minecraft-green-4": "hsl(var(--minecraft-green-4))", - }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - keyframes: { - "accordion-down": { - from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: "0" }, - }, - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, - screens: { - xs: "475px", - ...screens, - }, - }, - plugins: [require("tailwindcss-animate")], + // Custom Colors + "navbar-background": "hsl(var(--navbar-background))", + "minecraft-green-1": "hsl(var(--minecraft-green-1))", + "minecraft-green-2": "hsl(var(--minecraft-green-2))", + "minecraft-green-3": "hsl(var(--minecraft-green-3))", + "minecraft-green-4": "hsl(var(--minecraft-green-4))", + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + keyframes: { + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, + }, + screens: { + xs: "475px", + ...screens, + }, + }, + plugins: [require("tailwindcss-animate")], } satisfies Config; export default config;