From e0095ca8909044fc483dce25558d474267e849db Mon Sep 17 00:00:00 2001 From: dvelo <52332868+DeveloLongScript@users.noreply.github.com> Date: Sun, 16 Feb 2025 21:40:17 -0600 Subject: [PATCH] feat: progress (2/16) --- .../components/feat/navbar/menu-dropdown.tsx | 64 +++++++++++++++++++ .../www/src/components/feat/navbar/navbar.tsx | 34 ++++++++-- .../feat/server-list/server-card.tsx | 49 +++++++++++++- .../feat/server-list/server-list.tsx | 21 ++++-- apps/www/src/components/ui/dropdown-menu.tsx | 14 ++-- .../src/lib/hooks/use-infinite-scrolling.tsx | 38 +++++++++-- 6 files changed, 200 insertions(+), 20 deletions(-) create mode 100644 apps/www/src/components/feat/navbar/menu-dropdown.tsx diff --git a/apps/www/src/components/feat/navbar/menu-dropdown.tsx b/apps/www/src/components/feat/navbar/menu-dropdown.tsx new file mode 100644 index 0000000..2f7d083 --- /dev/null +++ b/apps/www/src/components/feat/navbar/menu-dropdown.tsx @@ -0,0 +1,64 @@ +import { + DropdownMenuItem, + DropdownMenuSeparator, +} from "@/components/ui/dropdown-menu"; +import { SignedIn, SignedOut, useClerk } from "@clerk/nextjs"; +import { LogIn, Settings, Ship, User, UserCog } from "lucide-react"; +import { useRouter } from "next/navigation"; + +export function MenuDropdown() { + const clerk = useClerk(); + const router = useRouter(); + + return ( + <> + Profile + + clerk.openSignIn()} + className="flex items-center gap-2" + > + + Login + + clerk.openSignUp()} + className="flex items-center gap-2" + > + + Sign up + + + router.push(process.env.NEXT_PUBLIC_CLERK_SWITCH_DOMAIN as string) + } + className="hover:block group hover:py-1" + > + + + Migrate your account + + + If you created your account before Jan. 29th 2025, you'll need to + migrate your account + + + + + clerk.openUserProfile()}> + + + User Settings + + + + App + + + + Settings + + + + ); +} diff --git a/apps/www/src/components/feat/navbar/navbar.tsx b/apps/www/src/components/feat/navbar/navbar.tsx index 3b9536e..65c3a71 100644 --- a/apps/www/src/components/feat/navbar/navbar.tsx +++ b/apps/www/src/components/feat/navbar/navbar.tsx @@ -1,5 +1,6 @@ "use client"; import { BrandingGenericIcon } from "@/components/feat/icons/branding-icons"; +import { Button } from "@/components/ui/button"; import { ContextMenu, ContextMenuContent, @@ -7,14 +8,19 @@ import { ContextMenuSeparator, ContextMenuTrigger, } from "@/components/ui/context-menu"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; import Github from "@/components/ui/github"; import { ALegacy } from "@/components/util/link"; -import { ModeToggle } from "@/components/util/mode-toggle"; import { version } from "@/config/version"; import { useScroll } from "@/lib/hooks/use-scroll"; import { cn } from "@/lib/utils"; -import { ServerCrash } from "lucide-react"; +import { Menu, ServerCrash } from "lucide-react"; import Link from "next/link"; +import { MenuDropdown } from "./menu-dropdown"; export function NavBar() { const showBorder = useScroll(40); @@ -56,11 +62,31 @@ export function NavBar() { + + + + Open GitHub Releases + + + - - + + + + + + + + + ); diff --git a/apps/www/src/components/feat/server-list/server-card.tsx b/apps/www/src/components/feat/server-list/server-card.tsx index 12d27d4..f4f33ca 100644 --- a/apps/www/src/components/feat/server-list/server-card.tsx +++ b/apps/www/src/components/feat/server-list/server-card.tsx @@ -1,14 +1,61 @@ import type { OnlineServer } from "@/lib/types/mh-server"; import IconDisplay from "../icons/minecraft-icon-display"; import { Material } from "@/components/ui/material"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; export default function ServerCard({ server }: { server: OnlineServer }) { return ( - {server.name} + {server.name} + + + + by {server.author || "Nobody"} + + + + + {server.author ? ( + + {server.name} is owned by{" "} + + + ) : ( + + This server doesn't have a recorded owner because the server owner + never linked their Minecraft account to their Minehut account. + + )} + + ); } + +function RankColoring({ rank, author }: { rank: string; author: string }) { + switch (rank.toLocaleLowerCase()) { + case "default": + return {author}; + case "vip": + return [VIP] {author}; + case "vip_plus": + return [VIP+] {author}; + case "pro": + return [PRO] {author}; + case "legend": + return [LEGEND] {author}; + case "patron": + return [PATRON] {author}; + case "mod": + return [MOD] {author}; + default: + return [STAFF] {author}; + } +} diff --git a/apps/www/src/components/feat/server-list/server-list.tsx b/apps/www/src/components/feat/server-list/server-list.tsx index ea6aec7..7d80d80 100644 --- a/apps/www/src/components/feat/server-list/server-list.tsx +++ b/apps/www/src/components/feat/server-list/server-list.tsx @@ -4,9 +4,13 @@ import { useServers } from "@/lib/hooks/use-servers"; import ServerCard from "./server-card"; import { Separator } from "@/components/ui/separator"; import { Statistics } from "./statistics"; +import InfiniteScroll from "react-infinite-scroll-component"; +import { useInfiniteScrolling } from "@/lib/hooks/use-infinite-scrolling"; export function ServerList() { const { servers, loading, serverCount, playerCount } = useServers(); + const { itemsLength, fetchMoreData, hasMoreData, data } = + useInfiniteScrolling(servers); if (loading) return ( @@ -29,11 +33,18 @@ export function ServerList() {

Servers

-
- {servers.map((c) => ( - - ))} -
+ Loading...} + > +
+ {data.map((c) => ( + + ))} +
+
); } diff --git a/apps/www/src/components/ui/dropdown-menu.tsx b/apps/www/src/components/ui/dropdown-menu.tsx index c522d38..251fe78 100644 --- a/apps/www/src/components/ui/dropdown-menu.tsx +++ b/apps/www/src/components/ui/dropdown-menu.tsx @@ -65,7 +65,7 @@ const DropdownMenuContent = React.forwardRef< (({ className, ...props }, ref) => ( + > +
{props.children}
+
+
)); DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; diff --git a/apps/www/src/lib/hooks/use-infinite-scrolling.tsx b/apps/www/src/lib/hooks/use-infinite-scrolling.tsx index 0890ed7..c011bd8 100644 --- a/apps/www/src/lib/hooks/use-infinite-scrolling.tsx +++ b/apps/www/src/lib/hooks/use-infinite-scrolling.tsx @@ -1,7 +1,33 @@ -import { OnlineServer } from "../types/mh-server"; +import { useEffect, useState } from "react"; +import type { OnlineServer } from "../types/mh-server"; -export function useInfiniteScrolling({ - servers, -}: { - servers: OnlineServer[]; -}) {} +const itemsPerScroll = 40; + +export function useInfiniteScrolling(servers: OnlineServer[]) { + const [currentOffset, setCurrentOffset] = useState(0); + const [data, setData] = useState([]); + const [hasMoreData, setHasMoreData] = useState(true); + + useEffect(() => { + // Start at the first `itemsPerScroll` servers (duh) + setData(servers.slice(0, itemsPerScroll)); + }, [servers]); + + return { + itemsLength: currentOffset + itemsPerScroll, + fetchMoreData: () => { + setCurrentOffset(currentOffset + itemsPerScroll); + const currentData = data; + const dataSlice = servers.slice( + currentOffset, + currentOffset + itemsPerScroll + ); + const newDataArray = [...currentData, ...dataSlice]; + + setData(newDataArray); + if (dataSlice.length !== itemsPerScroll) setHasMoreData(false); + }, + hasMoreData, + data, + }; +}