From f1cd72e8b3a4a702fac41be51ccb62fd9d2ad374 Mon Sep 17 00:00:00 2001 From: Rainnny7 Date: Thu, 18 Apr 2024 20:12:25 -0400 Subject: [PATCH] wow a footer! --- Frontend/.eslintrc.json | 2 +- Frontend/.gitignore | 4 +- Frontend/bun.lockb | Bin 185149 -> 180391 bytes Frontend/config.json | 14 +- Frontend/package.json | 2 +- Frontend/src/app/(pages)/docs/page.tsx | 2 +- Frontend/src/app/(pages)/mojang/page.tsx | 2 +- Frontend/src/app/(pages)/page.tsx | 4 +- .../app/(pages)/server/[[...slug]]/page.tsx | 2 +- Frontend/src/app/components/footer.tsx | 84 ++++- .../src/app/components/github-star-button.tsx | 1 - .../src/app/components/landing/background.tsx | 6 +- .../components/landing/statistic-counters.tsx | 2 +- Frontend/src/app/components/ui/badge.tsx | 54 +-- Frontend/src/app/components/ui/button.tsx | 95 ++--- .../src/app/components/ui/context-menu.tsx | 324 +++++++++--------- Frontend/src/app/components/ui/label.tsx | 18 +- Frontend/src/app/components/ui/select.tsx | 260 +++++++------- Frontend/src/app/components/ui/skeleton.tsx | 20 +- Frontend/src/app/components/ui/sonner.tsx | 49 ++- Frontend/src/app/components/ui/toast.tsx | 197 ++++++----- Frontend/src/app/components/ui/toaster.tsx | 66 ++-- Frontend/src/app/components/ui/tooltip.tsx | 42 +-- Frontend/src/app/components/ui/use-toast.ts | 290 ++++++++-------- Frontend/src/app/config.ts | 1 + Frontend/src/app/layout.tsx | 7 +- Frontend/src/app/lib/utils.ts | 2 +- Frontend/src/app/not-found.tsx | 2 +- Frontend/src/app/provider/theme-provider.tsx | 2 +- Frontend/src/app/types/config.d.ts | 30 +- Frontend/tailwind.config.ts | 1 + 31 files changed, 860 insertions(+), 725 deletions(-) diff --git a/Frontend/.eslintrc.json b/Frontend/.eslintrc.json index bffb357..0e81f9b 100644 --- a/Frontend/.eslintrc.json +++ b/Frontend/.eslintrc.json @@ -1,3 +1,3 @@ { "extends": "next/core-web-vitals" -} +} \ No newline at end of file diff --git a/Frontend/.gitignore b/Frontend/.gitignore index 80ee040..673aee7 100644 --- a/Frontend/.gitignore +++ b/Frontend/.gitignore @@ -1,6 +1,8 @@ node_modules -.next/ +.idea/ .fleet/ .vscode/ +.VSCodeCounter/ +.next/ .env*.local next-env.d.ts \ No newline at end of file diff --git a/Frontend/bun.lockb b/Frontend/bun.lockb index 7d3b1b6f607909fd3081f21a7676c95c48bf91ef..f56dc2334d479d463ef5c8f919d921a9ee86d6be 100644 GIT binary patch delta 1390 zcma)*OGuPa6vywqTISe{X{Mt_n&u;`$+4Mn)S1yz2?`{qho)v(7&R0{tJ@NT)7FNNNU|8Fo}qW79rLD=nYzS;OBSl?>^_;>qK|Vqqdk!wzY$u zap?uYLq96D9IvI+SCbI;^8JgcEn0-@>x$ZU9Y2#M1)~^fuSpXpd!L=IH3!oz*7yq= zV{weN#-lF=U%wvOX4zv7eN7z?1lMaG;n#uz%@=(O<6P*E2tIQZifJu4tNBE-9?a8y zqEQb8blsfIv4%U6G1{pZUy6Uf)L#-A>eB1XS^qUQRMdUGLpnWtJMWck9$q7l6mhfs zNTN^Ly%5%7h$~)*e&d6e%hl3R${!mu2Y9RBG~7$uFgDXC8-{pU3uC{2F9g|kbW;Cv zY9Ri$>G(Bu`cDJ(RM3$T{#olc2(aS%Hi%Z(S^zVH5(#06 zDi;gqz+~F&o^s2OXTZ^B_m#urVVTN3P>vqcRzQ0_R1Q^cVO0#!1h9hyqDKu} zfxH^fwb1?1xe|e2xjr?Hu4osac&f%(k?#gHcR;yhum)s-Y>)$T!CH_9)`9h4 z1F(UOARpL40oVi_zzJNS5V%1RCzS6W8J$0a77>VP&hsW-}P2ixA;R)^%%|d>g;64l8?+oho30xAg7}YcVLQe0ZLCC{lUS+ZlEmSvhYQDM_ zDmGm?J%wpzdZ=a&d(ySmW2{{~ubTPk5$gtGmVoKkKv=xNHvAN~K1WIb}nID3f<8#H8sY T)gBQ$X#^_84$a7aBh2CtL|4^j delta 3305 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 f ( -
+
{/* Creeper */} diff --git a/Frontend/src/app/(pages)/mojang/page.tsx b/Frontend/src/app/(pages)/mojang/page.tsx index 80c0b5f..87009b1 100644 --- a/Frontend/src/app/(pages)/mojang/page.tsx +++ b/Frontend/src/app/(pages)/mojang/page.tsx @@ -4,9 +4,9 @@ import { Metadata } from "next"; import Link from "next/link"; import { ReactElement } from "react"; import { + getMojangServerStatus, MojangServerStatus, MojangServerStatusResponse, - getMojangServerStatus, } from "restfulmc-lib"; /** diff --git a/Frontend/src/app/(pages)/page.tsx b/Frontend/src/app/(pages)/page.tsx index 3fe7911..a3dba86 100644 --- a/Frontend/src/app/(pages)/page.tsx +++ b/Frontend/src/app/(pages)/page.tsx @@ -1,8 +1,8 @@ -import Background from "@/components/landing/background"; import FeaturedContent from "@/components/landing/featured-content"; import Hero from "@/components/landing/hero"; import StatisticCounters from "@/components/landing/statistic-counters"; import { ReactElement } from "react"; +import HeroBackground from "../components/landing/background"; /** * The landing page. @@ -13,7 +13,7 @@ const LandingPage = (): ReactElement => (
{/* Hero */}
- +
diff --git a/Frontend/src/app/(pages)/server/[[...slug]]/page.tsx b/Frontend/src/app/(pages)/server/[[...slug]]/page.tsx index cb3bc8c..1ed4f0a 100644 --- a/Frontend/src/app/(pages)/server/[[...slug]]/page.tsx +++ b/Frontend/src/app/(pages)/server/[[...slug]]/page.tsx @@ -12,9 +12,9 @@ import { ReactElement } from "react"; import { CachedBedrockMinecraftServer, CachedJavaMinecraftServer, - ServerPlatform, getMinecraftServer, type RestfulMCAPIError, + ServerPlatform, } from "restfulmc-lib"; /** diff --git a/Frontend/src/app/components/footer.tsx b/Frontend/src/app/components/footer.tsx index f5ee589..af585cc 100644 --- a/Frontend/src/app/components/footer.tsx +++ b/Frontend/src/app/components/footer.tsx @@ -1,4 +1,86 @@ +import Image from "next/image"; +import Link from "next/link"; import { ReactElement } from "react"; +import config from "@/config"; +import { minecrafter } from "@/font/fonts"; +import { cn } from "@/lib/utils"; +import { FooterLinks } from "@/types/config"; -const Footer = (): ReactElement =>
FOOTER
; +const Footer = (): ReactElement => ( +
+
+ {/* Branding */} +
+ {/* Logo & Site Name */} +
+ Site Logo + +

+ {config.siteName} +

+
+ + {/* Disclaimer */} +

+ Not affiliated with Mojang or Microsoft. +

+
+ + {/* Links */} +
+ {Object.keys(config.footerLinks).map( + (header: string, groupIndex: number): ReactElement => ( +
+ {/* Header */} +

+ {header} +

+ + {/* Links */} +
+ {Object.entries( + (config.footerLinks as FooterLinks)[header] + ).map( + ( + [name, url]: [string, string], + linkIndex: number + ): ReactElement => ( + + {name} + + ) + )} +
+
+ ) + )} +
+
+
+); export default Footer; diff --git a/Frontend/src/app/components/github-star-button.tsx b/Frontend/src/app/components/github-star-button.tsx index 68fa770..5eb6ab6 100644 --- a/Frontend/src/app/components/github-star-button.tsx +++ b/Frontend/src/app/components/github-star-button.tsx @@ -33,7 +33,6 @@ const GitHubStarButton = (): ReactElement => { ); const json: any = await response.json(); // Get the JSON response setStars(json.stargazers_count); // Set the stars - console.log("fetch stars"); }; if (stars === undefined) { fetchStars(); // Fetch the stars diff --git a/Frontend/src/app/components/landing/background.tsx b/Frontend/src/app/components/landing/background.tsx index e638bc2..dbafa9d 100644 --- a/Frontend/src/app/components/landing/background.tsx +++ b/Frontend/src/app/components/landing/background.tsx @@ -2,11 +2,11 @@ import { ReactElement } from "react"; import { cn } from "../../lib/utils"; /** - * The background component. + * The background hero component. * * @returns the background jsx */ -const Background = (): ReactElement => ( +const HeroBackground = (): ReactElement => (
( )} /> ); -export default Background; +export default HeroBackground; diff --git a/Frontend/src/app/components/landing/statistic-counters.tsx b/Frontend/src/app/components/landing/statistic-counters.tsx index 633ea73..a2c0c83 100644 --- a/Frontend/src/app/components/landing/statistic-counters.tsx +++ b/Frontend/src/app/components/landing/statistic-counters.tsx @@ -7,7 +7,7 @@ import { ReactElement } from "react"; * @returns the counters jsx */ const StatisticCounters = (): ReactElement => ( -
+
diff --git a/Frontend/src/app/components/ui/badge.tsx b/Frontend/src/app/components/ui/badge.tsx index f99cedf..5990b73 100644 --- a/Frontend/src/app/components/ui/badge.tsx +++ b/Frontend/src/app/components/ui/badge.tsx @@ -1,36 +1,36 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "@/app/lib/utils" +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", - }, - } -) + "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, - VariantProps {} + extends React.HTMLAttributes, + VariantProps {} function Badge({ className, variant, ...props }: BadgeProps) { - return ( -
- ) + return ( +
+ ); } -export { Badge, badgeVariants } +export { Badge, badgeVariants }; diff --git a/Frontend/src/app/components/ui/button.tsx b/Frontend/src/app/components/ui/button.tsx index f705f1b..dc76d90 100644 --- a/Frontend/src/app/components/ui/button.tsx +++ b/Frontend/src/app/components/ui/button.tsx @@ -1,56 +1,57 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "@/app/lib/utils" +import { cn } from "@/app/lib/utils"; const buttonVariants = cva( - "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", - { - variants: { - variant: { - default: "bg-primary text-primary-foreground hover:bg-primary/90", - destructive: - "bg-destructive text-destructive-foreground hover:bg-destructive/90", - outline: - "border border-input bg-background hover:bg-accent hover:text-accent-foreground", - secondary: - "bg-secondary text-secondary-foreground hover:bg-secondary/80", - ghost: "hover:bg-accent hover:text-accent-foreground", - link: "text-primary underline-offset-4 hover:underline", - }, - size: { - default: "h-10 px-4 py-2", - sm: "h-9 rounded-md px-3", - lg: "h-11 rounded-md px-8", - icon: "h-10 w-10", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - } -) + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: + "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +); export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; } const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : "button" - return ( - - ) - } -) -Button.displayName = "Button" + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; + return ( + + ); + } +); +Button.displayName = "Button"; -export { Button, buttonVariants } +export { Button, buttonVariants }; diff --git a/Frontend/src/app/components/ui/context-menu.tsx b/Frontend/src/app/components/ui/context-menu.tsx index 2bd9c6b..a7812cc 100644 --- a/Frontend/src/app/components/ui/context-menu.tsx +++ b/Frontend/src/app/components/ui/context-menu.tsx @@ -1,200 +1,200 @@ -"use client" +"use client"; -import * as React from "react" -import * as ContextMenuPrimitive from "@radix-ui/react-context-menu" -import { Check, ChevronRight, Circle } from "lucide-react" +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" +import { cn } from "@/app/lib/utils"; -const ContextMenu = ContextMenuPrimitive.Root +const ContextMenu = ContextMenuPrimitive.Root; -const ContextMenuTrigger = ContextMenuPrimitive.Trigger +const ContextMenuTrigger = ContextMenuPrimitive.Trigger; -const ContextMenuGroup = ContextMenuPrimitive.Group +const ContextMenuGroup = ContextMenuPrimitive.Group; -const ContextMenuPortal = ContextMenuPrimitive.Portal +const ContextMenuPortal = ContextMenuPrimitive.Portal; -const ContextMenuSub = ContextMenuPrimitive.Sub +const ContextMenuSub = ContextMenuPrimitive.Sub; -const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup +const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup; const ContextMenuSubTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + } >(({ className, inset, children, ...props }, ref) => ( - - {children} - - -)) -ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName + + {children} + + +)); +ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName; const ContextMenuSubContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - -)) -ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName + +)); +ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName; const ContextMenuContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - -)) -ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName + + + +)); +ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName; const ContextMenuItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + } >(({ className, inset, ...props }, ref) => ( - -)) -ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName + +)); +ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName; const ContextMenuCheckboxItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, checked, ...props }, ref) => ( - - - - - - - {children} - -)) + + + + + + + {children} + +)); ContextMenuCheckboxItem.displayName = - ContextMenuPrimitive.CheckboxItem.displayName + ContextMenuPrimitive.CheckboxItem.displayName; const ContextMenuRadioItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - - - - - - - {children} - -)) -ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName + + + + + + + {children} + +)); +ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName; const ContextMenuLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + } >(({ className, inset, ...props }, ref) => ( - -)) -ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName + +)); +ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName; const ContextMenuSeparator = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - -)) -ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName + +)); +ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName; const ContextMenuShortcut = ({ - className, - ...props + className, + ...props }: React.HTMLAttributes) => { - return ( - - ) -} -ContextMenuShortcut.displayName = "ContextMenuShortcut" + return ( + + ); +}; +ContextMenuShortcut.displayName = "ContextMenuShortcut"; export { - ContextMenu, - ContextMenuTrigger, - ContextMenuContent, - ContextMenuItem, - ContextMenuCheckboxItem, - ContextMenuRadioItem, - ContextMenuLabel, - ContextMenuSeparator, - ContextMenuShortcut, - ContextMenuGroup, - ContextMenuPortal, - ContextMenuSub, - ContextMenuSubContent, - ContextMenuSubTrigger, - ContextMenuRadioGroup, -} + ContextMenu, + ContextMenuTrigger, + ContextMenuContent, + ContextMenuItem, + ContextMenuCheckboxItem, + ContextMenuRadioItem, + ContextMenuLabel, + ContextMenuSeparator, + ContextMenuShortcut, + ContextMenuGroup, + ContextMenuPortal, + ContextMenuSub, + ContextMenuSubContent, + ContextMenuSubTrigger, + ContextMenuRadioGroup, +}; diff --git a/Frontend/src/app/components/ui/label.tsx b/Frontend/src/app/components/ui/label.tsx index a992f60..dbb2d78 100644 --- a/Frontend/src/app/components/ui/label.tsx +++ b/Frontend/src/app/components/ui/label.tsx @@ -7,19 +7,19 @@ import * as React from "react"; import { cn } from "@/app/lib/utils"; const labelVariants = cva( - "text-sm font-medium text-zinc-300 leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" + "text-sm font-medium text-zinc-300 leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" ); const Label = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & - VariantProps + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps >(({ className, ...props }, ref) => ( - + )); Label.displayName = LabelPrimitive.Root.displayName; diff --git a/Frontend/src/app/components/ui/select.tsx b/Frontend/src/app/components/ui/select.tsx index abdae28..5329a24 100644 --- a/Frontend/src/app/components/ui/select.tsx +++ b/Frontend/src/app/components/ui/select.tsx @@ -1,160 +1,160 @@ -"use client" +"use client"; -import * as React from "react" -import * as SelectPrimitive from "@radix-ui/react-select" -import { Check, ChevronDown, ChevronUp } from "lucide-react" +import * as React from "react"; +import * as SelectPrimitive from "@radix-ui/react-select"; +import { Check, ChevronDown, ChevronUp } from "lucide-react"; -import { cn } from "@/app/lib/utils" +import { cn } from "@/app/lib/utils"; -const Select = SelectPrimitive.Root +const Select = SelectPrimitive.Root; -const SelectGroup = SelectPrimitive.Group +const SelectGroup = SelectPrimitive.Group; -const SelectValue = SelectPrimitive.Value +const SelectValue = SelectPrimitive.Value; const SelectTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - span]:line-clamp-1 transition-all transform-gpu", - className - )} - {...props} - > - {children} - - - - -)) -SelectTrigger.displayName = SelectPrimitive.Trigger.displayName + span]:line-clamp-1 transition-all transform-gpu", + className + )} + {...props} + > + {children} + + + + +)); +SelectTrigger.displayName = SelectPrimitive.Trigger.displayName; const SelectScrollUpButton = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - -)) -SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName + + + +)); +SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName; const SelectScrollDownButton = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - -)) + + + +)); SelectScrollDownButton.displayName = - SelectPrimitive.ScrollDownButton.displayName + SelectPrimitive.ScrollDownButton.displayName; const SelectContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, position = "popper", ...props }, ref) => ( - - - - - {children} - - - - -)) -SelectContent.displayName = SelectPrimitive.Content.displayName + + + + + {children} + + + + +)); +SelectContent.displayName = SelectPrimitive.Content.displayName; const SelectLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - -)) -SelectLabel.displayName = SelectPrimitive.Label.displayName + +)); +SelectLabel.displayName = SelectPrimitive.Label.displayName; const SelectItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - - - - - - + + + + + + - {children} - -)) -SelectItem.displayName = SelectPrimitive.Item.displayName + {children} + +)); +SelectItem.displayName = SelectPrimitive.Item.displayName; const SelectSeparator = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - -)) -SelectSeparator.displayName = SelectPrimitive.Separator.displayName + +)); +SelectSeparator.displayName = SelectPrimitive.Separator.displayName; export { - Select, - SelectGroup, - SelectValue, - SelectTrigger, - SelectContent, - SelectLabel, - SelectItem, - SelectSeparator, - SelectScrollUpButton, - SelectScrollDownButton, -} + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, +}; diff --git a/Frontend/src/app/components/ui/skeleton.tsx b/Frontend/src/app/components/ui/skeleton.tsx index cebdb00..e8cde28 100644 --- a/Frontend/src/app/components/ui/skeleton.tsx +++ b/Frontend/src/app/components/ui/skeleton.tsx @@ -1,15 +1,15 @@ -import { cn } from "@/app/lib/utils" +import { cn } from "@/app/lib/utils"; function Skeleton({ - className, - ...props + className, + ...props }: React.HTMLAttributes) { - return ( -
- ) + return ( +
+ ); } -export { Skeleton } +export { Skeleton }; diff --git a/Frontend/src/app/components/ui/sonner.tsx b/Frontend/src/app/components/ui/sonner.tsx index 452f4d9..d8dc1cc 100644 --- a/Frontend/src/app/components/ui/sonner.tsx +++ b/Frontend/src/app/components/ui/sonner.tsx @@ -1,31 +1,30 @@ -"use client" +"use client"; -import { useTheme } from "next-themes" -import { Toaster as Sonner } from "sonner" +import { useTheme } from "next-themes"; +import { Toaster as Sonner } from "sonner"; -type ToasterProps = React.ComponentProps +type ToasterProps = React.ComponentProps; const Toaster = ({ ...props }: ToasterProps) => { - const { theme = "system" } = useTheme() + const { theme = "system" } = useTheme(); - return ( - - ) -} + return ( + + ); +}; -export { Toaster } +export { Toaster }; diff --git a/Frontend/src/app/components/ui/toast.tsx b/Frontend/src/app/components/ui/toast.tsx index c7fb656..a32532a 100644 --- a/Frontend/src/app/components/ui/toast.tsx +++ b/Frontend/src/app/components/ui/toast.tsx @@ -1,122 +1,129 @@ -"use client" +"use client"; -import * as ToastPrimitives from "@radix-ui/react-toast" -import { cva, type VariantProps } from "class-variance-authority" -import { X } from "lucide-react" -import * as React from "react" +import * as ToastPrimitives from "@radix-ui/react-toast"; +import { cva, type VariantProps } from "class-variance-authority"; +import { X } from "lucide-react"; +import * as React from "react"; -import { cn } from "@/app/lib/utils" +import { cn } from "@/app/lib/utils"; -const ToastProvider = ToastPrimitives.Provider +const ToastProvider = ToastPrimitives.Provider; const ToastViewport = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - -)) -ToastViewport.displayName = ToastPrimitives.Viewport.displayName + +)); +ToastViewport.displayName = ToastPrimitives.Viewport.displayName; const toastVariants = cva( - "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", - { - variants: { - variant: { - default: "border bg-muted text-foreground", - destructive: - "destructive group border-destructive bg-destructive text-destructive-foreground", - }, - }, - defaultVariants: { - variant: "default", - }, - } -) + "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", + { + variants: { + variant: { + default: "border bg-muted text-foreground", + destructive: + "destructive group border-destructive bg-destructive text-destructive-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +); const Toast = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & - VariantProps + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps >(({ className, variant, ...props }, ref) => { - return ( - - ) -}) -Toast.displayName = ToastPrimitives.Root.displayName + return ( + + ); +}); +Toast.displayName = ToastPrimitives.Root.displayName; const ToastAction = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - -)) -ToastAction.displayName = ToastPrimitives.Action.displayName + +)); +ToastAction.displayName = ToastPrimitives.Action.displayName; const ToastClose = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - -)) -ToastClose.displayName = ToastPrimitives.Close.displayName + + + +)); +ToastClose.displayName = ToastPrimitives.Close.displayName; const ToastTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - -)) -ToastTitle.displayName = ToastPrimitives.Title.displayName + +)); +ToastTitle.displayName = ToastPrimitives.Title.displayName; const ToastDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - -)) -ToastDescription.displayName = ToastPrimitives.Description.displayName + +)); +ToastDescription.displayName = ToastPrimitives.Description.displayName; -type ToastProps = React.ComponentPropsWithoutRef +type ToastProps = React.ComponentPropsWithoutRef; -type ToastActionElement = React.ReactElement +type ToastActionElement = React.ReactElement; export { - Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, type ToastActionElement, type ToastProps -} - + Toast, + ToastAction, + ToastClose, + ToastDescription, + ToastProvider, + ToastTitle, + ToastViewport, + type ToastActionElement, + type ToastProps, +}; diff --git a/Frontend/src/app/components/ui/toaster.tsx b/Frontend/src/app/components/ui/toaster.tsx index a451808..dd88327 100644 --- a/Frontend/src/app/components/ui/toaster.tsx +++ b/Frontend/src/app/components/ui/toaster.tsx @@ -1,35 +1,43 @@ -"use client" +"use client"; import { - Toast, - ToastClose, - ToastDescription, - ToastProvider, - ToastTitle, - ToastViewport, -} from "@/app/components/ui/toast" -import { useToast } from "@/app/components/ui/use-toast" + Toast, + ToastClose, + ToastDescription, + ToastProvider, + ToastTitle, + ToastViewport, +} from "@/app/components/ui/toast"; +import { useToast } from "@/app/components/ui/use-toast"; export function Toaster() { - const { toasts } = useToast() + const { toasts } = useToast(); - return ( - - {toasts.map(function ({ id, title, description, action, ...props }) { - return ( - -
- {title && {title}} - {description && ( - {description} - )} -
- {action} - -
- ) - })} - -
- ) + return ( + + {toasts.map(function ({ + id, + title, + description, + action, + ...props + }) { + return ( + +
+ {title && {title}} + {description && ( + + {description} + + )} +
+ {action} + +
+ ); + })} + +
+ ); } diff --git a/Frontend/src/app/components/ui/tooltip.tsx b/Frontend/src/app/components/ui/tooltip.tsx index 1a6c803..7853f95 100644 --- a/Frontend/src/app/components/ui/tooltip.tsx +++ b/Frontend/src/app/components/ui/tooltip.tsx @@ -1,30 +1,30 @@ -"use client" +"use client"; -import * as React from "react" -import * as TooltipPrimitive from "@radix-ui/react-tooltip" +import * as React from "react"; +import * as TooltipPrimitive from "@radix-ui/react-tooltip"; -import { cn } from "@/app/lib/utils" +import { cn } from "@/app/lib/utils"; -const TooltipProvider = TooltipPrimitive.Provider +const TooltipProvider = TooltipPrimitive.Provider; -const Tooltip = TooltipPrimitive.Root +const Tooltip = TooltipPrimitive.Root; -const TooltipTrigger = TooltipPrimitive.Trigger +const TooltipTrigger = TooltipPrimitive.Trigger; const TooltipContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, sideOffset = 4, ...props }, ref) => ( - -)) -TooltipContent.displayName = TooltipPrimitive.Content.displayName + +)); +TooltipContent.displayName = TooltipPrimitive.Content.displayName; -export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }; diff --git a/Frontend/src/app/components/ui/use-toast.ts b/Frontend/src/app/components/ui/use-toast.ts index b21985b..63b356e 100644 --- a/Frontend/src/app/components/ui/use-toast.ts +++ b/Frontend/src/app/components/ui/use-toast.ts @@ -1,194 +1,192 @@ -"use client" +"use client"; // Inspired by react-hot-toast library -import * as React from "react" +import * as React from "react"; -import type { - ToastActionElement, - ToastProps, -} from "@/app/components/ui/toast" +import type { ToastActionElement, ToastProps } from "@/app/components/ui/toast"; -const TOAST_LIMIT = 1 -const TOAST_REMOVE_DELAY = 1000000 +const TOAST_LIMIT = 1; +const TOAST_REMOVE_DELAY = 1000000; type ToasterToast = ToastProps & { - id: string - title?: React.ReactNode - description?: React.ReactNode - action?: ToastActionElement -} + id: string; + title?: React.ReactNode; + description?: React.ReactNode; + action?: ToastActionElement; +}; const actionTypes = { - ADD_TOAST: "ADD_TOAST", - UPDATE_TOAST: "UPDATE_TOAST", - DISMISS_TOAST: "DISMISS_TOAST", - REMOVE_TOAST: "REMOVE_TOAST", -} as const + ADD_TOAST: "ADD_TOAST", + UPDATE_TOAST: "UPDATE_TOAST", + DISMISS_TOAST: "DISMISS_TOAST", + REMOVE_TOAST: "REMOVE_TOAST", +} as const; -let count = 0 +let count = 0; function genId() { - count = (count + 1) % Number.MAX_SAFE_INTEGER - return count.toString() + count = (count + 1) % Number.MAX_SAFE_INTEGER; + return count.toString(); } -type ActionType = typeof actionTypes +type ActionType = typeof actionTypes; type Action = - | { - type: ActionType["ADD_TOAST"] - toast: ToasterToast - } - | { - type: ActionType["UPDATE_TOAST"] - toast: Partial - } - | { - type: ActionType["DISMISS_TOAST"] - toastId?: ToasterToast["id"] - } - | { - type: ActionType["REMOVE_TOAST"] - toastId?: ToasterToast["id"] - } + | { + type: ActionType["ADD_TOAST"]; + toast: ToasterToast; + } + | { + type: ActionType["UPDATE_TOAST"]; + toast: Partial; + } + | { + type: ActionType["DISMISS_TOAST"]; + toastId?: ToasterToast["id"]; + } + | { + type: ActionType["REMOVE_TOAST"]; + toastId?: ToasterToast["id"]; + }; interface State { - toasts: ToasterToast[] + toasts: ToasterToast[]; } -const toastTimeouts = new Map>() +const toastTimeouts = new Map>(); const addToRemoveQueue = (toastId: string) => { - if (toastTimeouts.has(toastId)) { - return - } + if (toastTimeouts.has(toastId)) { + return; + } - const timeout = setTimeout(() => { - toastTimeouts.delete(toastId) - dispatch({ - type: "REMOVE_TOAST", - toastId: toastId, - }) - }, TOAST_REMOVE_DELAY) + const timeout = setTimeout(() => { + toastTimeouts.delete(toastId); + dispatch({ + type: "REMOVE_TOAST", + toastId: toastId, + }); + }, TOAST_REMOVE_DELAY); - toastTimeouts.set(toastId, timeout) -} + toastTimeouts.set(toastId, timeout); +}; export const reducer = (state: State, action: Action): State => { - switch (action.type) { - case "ADD_TOAST": - return { - ...state, - toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT), - } + switch (action.type) { + case "ADD_TOAST": + return { + ...state, + toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT), + }; - case "UPDATE_TOAST": - return { - ...state, - toasts: state.toasts.map((t) => - t.id === action.toast.id ? { ...t, ...action.toast } : t - ), - } + case "UPDATE_TOAST": + return { + ...state, + toasts: state.toasts.map((t) => + t.id === action.toast.id ? { ...t, ...action.toast } : t + ), + }; - case "DISMISS_TOAST": { - const { toastId } = action + case "DISMISS_TOAST": { + const { toastId } = action; - // ! Side effects ! - This could be extracted into a dismissToast() action, - // but I'll keep it here for simplicity - if (toastId) { - addToRemoveQueue(toastId) - } else { - state.toasts.forEach((toast) => { - addToRemoveQueue(toast.id) - }) - } + // ! Side effects ! - This could be extracted into a dismissToast() action, + // but I'll keep it here for simplicity + if (toastId) { + addToRemoveQueue(toastId); + } else { + state.toasts.forEach((toast) => { + addToRemoveQueue(toast.id); + }); + } - return { - ...state, - toasts: state.toasts.map((t) => - t.id === toastId || toastId === undefined - ? { - ...t, - open: false, - } - : t - ), - } - } - case "REMOVE_TOAST": - if (action.toastId === undefined) { - return { - ...state, - toasts: [], + return { + ...state, + toasts: state.toasts.map((t) => + t.id === toastId || toastId === undefined + ? { + ...t, + open: false, + } + : t + ), + }; } - } - return { - ...state, - toasts: state.toasts.filter((t) => t.id !== action.toastId), - } - } -} + case "REMOVE_TOAST": + if (action.toastId === undefined) { + return { + ...state, + toasts: [], + }; + } + return { + ...state, + toasts: state.toasts.filter((t) => t.id !== action.toastId), + }; + } +}; -const listeners: Array<(state: State) => void> = [] +const listeners: Array<(state: State) => void> = []; -let memoryState: State = { toasts: [] } +let memoryState: State = { toasts: [] }; function dispatch(action: Action) { - memoryState = reducer(memoryState, action) - listeners.forEach((listener) => { - listener(memoryState) - }) + memoryState = reducer(memoryState, action); + listeners.forEach((listener) => { + listener(memoryState); + }); } -type Toast = Omit +type Toast = Omit; function toast({ ...props }: Toast) { - const id = genId() + const id = genId(); + + const update = (props: ToasterToast) => + dispatch({ + type: "UPDATE_TOAST", + toast: { ...props, id }, + }); + const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id }); - const update = (props: ToasterToast) => dispatch({ - type: "UPDATE_TOAST", - toast: { ...props, id }, - }) - const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id }) + type: "ADD_TOAST", + toast: { + ...props, + id, + open: true, + onOpenChange: (open) => { + if (!open) dismiss(); + }, + }, + }); - dispatch({ - type: "ADD_TOAST", - toast: { - ...props, - id, - open: true, - onOpenChange: (open) => { - if (!open) dismiss() - }, - }, - }) - - return { - id: id, - dismiss, - update, - } + return { + id: id, + dismiss, + update, + }; } function useToast() { - const [state, setState] = React.useState(memoryState) + const [state, setState] = React.useState(memoryState); - React.useEffect(() => { - listeners.push(setState) - return () => { - const index = listeners.indexOf(setState) - if (index > -1) { - listeners.splice(index, 1) - } - } - }, [state]) + React.useEffect(() => { + listeners.push(setState); + return () => { + const index = listeners.indexOf(setState); + if (index > -1) { + listeners.splice(index, 1); + } + }; + }, [state]); - return { - ...state, - toast, - dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }), - } + return { + ...state, + toast, + dismiss: (toastId?: string) => + dispatch({ type: "DISMISS_TOAST", toastId }), + }; } -export { useToast, toast } +export { useToast, toast }; diff --git a/Frontend/src/app/config.ts b/Frontend/src/app/config.ts index c282611..2a4af07 100644 --- a/Frontend/src/app/config.ts +++ b/Frontend/src/app/config.ts @@ -2,4 +2,5 @@ * The configuration for this app. */ import config from "@/configJson"; + export default config; diff --git a/Frontend/src/app/layout.tsx b/Frontend/src/app/layout.tsx index 44ab237..c258a06 100644 --- a/Frontend/src/app/layout.tsx +++ b/Frontend/src/app/layout.tsx @@ -1,14 +1,15 @@ +import Footer from "@/components/footer"; import Navbar from "@/components/navbar"; -import { Toaster } from "@/components/ui/sonner" +import { Toaster } from "@/components/ui/sonner"; import { TooltipProvider } from "@/components/ui/tooltip"; import config from "@/config"; import { notoSans } from "@/font/fonts"; import { cn } from "@/lib/utils"; -import ThemeProvider from "@/provider/theme-provider"; import type { Metadata, Viewport } from "next"; import PlausibleProvider from "next-plausible"; import { ReactElement, ReactNode } from "react"; import "./globals.css"; +import ThemeProvider from "@/provider/theme-provider"; /** * Site metadata & viewport. @@ -44,7 +45,7 @@ const RootLayout = ({ {children} - {/*