mhsf-dev/src/components/ServerCard.tsx

317 lines
11 KiB
TypeScript
Raw Normal View History

2024-07-23 18:49:21 -05:00
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuItem,
ContextMenuContent,
ContextMenuSeparator,
} from "@/components/ui/context-menu";
2024-08-15 23:24:15 -05:00
import toast, { LoaderIcon } from "react-hot-toast";
2024-07-23 18:49:21 -05:00
import {
CardHeader,
CardTitle,
CardDescription,
Card,
CardContent,
} from "./ui/card";
import IconDisplay from "./IconDisplay";
import { TagShower } from "./ServerList";
2024-08-22 23:44:00 -05:00
import {
ArrowRight,
ChartArea,
Copy,
EllipsisVertical,
Layers,
Star,
} from "lucide-react";
2024-07-23 18:49:21 -05:00
import { Button } from "./ui/button";
import {
Drawer,
DrawerContent,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
import { Tooltip } from "@radix-ui/react-tooltip";
import { TooltipContent, TooltipTrigger } from "./ui/tooltip";
2024-08-07 16:37:54 -05:00
import { useRouter } from "@/lib/useRouter";
2024-08-03 09:51:45 -05:00
import Link from "next/link";
2024-08-15 23:24:15 -05:00
import { useState } from "react";
import { favoriteServer, isFavorited } from "@/lib/api";
import { useUser } from "@clerk/nextjs";
import { useTheme } from "next-themes";
2024-08-22 23:44:00 -05:00
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card";
import useClipboard from "@/lib/useClipboard";
2024-07-23 18:49:21 -05:00
2024-08-15 23:24:15 -05:00
export default function ServerCard({ b, motd, mini, favs }: any) {
2024-08-07 16:37:54 -05:00
const router = useRouter();
2024-08-22 23:44:00 -05:00
const clipboard = useClipboard();
2024-08-15 23:24:15 -05:00
const [favoriteStar, setFavoriteStar] = useState(false);
const [favoriteLoading, setFavoriteLoading] = useState(true);
const { isSignedIn } = useUser();
const { resolvedTheme } = useTheme();
2024-07-23 18:49:21 -05:00
return (
2024-08-15 23:24:15 -05:00
<ContextMenu
onOpenChange={(open) => {
if (open && isSignedIn)
isFavorited(b.name).then((c) => {
setFavoriteStar(c);
setFavoriteLoading(false);
});
}}
>
2024-07-23 18:49:21 -05:00
<ContextMenuTrigger>
2024-07-23 22:07:54 -05:00
<Card
key={b.name}
2024-08-15 23:24:15 -05:00
className={
(!mini ? "min-h-[450px] max-h-[450px]" : "") +
" mb-4 flex items-start"
}
2024-07-23 22:07:54 -05:00
>
2024-07-23 18:49:21 -05:00
<CardHeader>
2024-08-08 18:02:46 -05:00
<CardTitle className="m-0">
2024-08-22 23:44:00 -05:00
<span>
<IconDisplay server={b} />
<HoverCard>
<HoverCardTrigger asChild>
<Link href={"/server/" + b.name}>
<Button
variant={"link"}
className="text-2xl px-0 pl-1 font-semibold"
>
{b.name}
</Button>
</Link>
</HoverCardTrigger>
<HoverCardContent className="w-80 font-normal tracking-normal">
<div className="flex justify-between space-x-4">
<div className="space-y-1">
<h4 className="text-sm font-semibold">{b.name}</h4>
<p className="text-sm">
{motd && (
<span
dangerouslySetInnerHTML={{ __html: motd }}
className="w-[30px] text-center break-all overflow-hidden"
/>
)}
</p>
<div className="flex items-center pt-2">
<span className="text-xs text-muted-foreground flex items-center">
<ArrowRight size={16} className="mr-2" />
Open Server Page
</span>
</div>
<div className="flex items-center pt-2">
<span className="text-xs text-muted-foreground flex items-center">
<ChartArea size={16} className="mr-2" />
Running on{" "}
{b.staticInfo.serverPlan == undefined
? "Free Plan"
: b.staticInfo.serverPlan}
</span>
</div>
</div>
</div>
</HoverCardContent>
</HoverCard>
</span>
2024-07-23 18:49:21 -05:00
<Drawer>
<DrawerTrigger>
<Button
size="icon"
2024-08-08 18:02:46 -05:00
className="w-[24px] h-[24px] ml-2 md:hidden"
2024-07-23 18:49:21 -05:00
variant="secondary"
>
<EllipsisVertical size={16} />
</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Actions</DrawerTitle>
</DrawerHeader>
<DrawerFooter>
<Button
variant="ghost"
onClick={() => {
2024-08-22 23:44:00 -05:00
clipboard.writeText(b.name + ".mshf.minehut.gg");
2024-07-23 18:49:21 -05:00
toast.success("Copied IP to clipboard");
}}
>
Copy server IP
2024-08-08 18:02:46 -05:00
<Copy size={18} className="ml-4" />
2024-07-23 18:49:21 -05:00
</Button>
<Button
variant="ghost"
onClick={() => {
2024-08-03 09:51:45 -05:00
router.push("/server/" + b.name);
2024-07-23 18:49:21 -05:00
}}
>
Open server page
</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
{b.author != undefined ? (
2024-08-22 23:44:00 -05:00
<div className="text-sm text-muted-foreground font-normal tracking-normal">
2024-07-23 18:49:21 -05:00
by {b.author}
</div>
) : (
<br />
)}
<TagShower server={b} />
</CardTitle>
2024-08-22 23:44:00 -05:00
<CardDescription className="float-left inline ">
2024-08-08 18:02:46 -05:00
<span className="flex items-center">
2024-07-23 18:49:21 -05:00
{b.playerData.playerCount == 0 ? (
<div
2024-08-08 18:02:46 -05:00
className="items-center border"
2024-07-23 18:49:21 -05:00
style={{
width: ".5rem",
height: ".5rem",
borderRadius: "9999px",
}}
/>
) : (
<div
2024-08-08 18:02:46 -05:00
className="items-center"
2024-07-23 18:49:21 -05:00
style={{
backgroundColor: "#0cce6b",
width: ".5rem",
height: ".5rem",
borderRadius: "9999px",
}}
/>
)}
2024-08-08 18:02:46 -05:00
<span className="pl-1">
2024-07-23 18:49:21 -05:00
{b.playerData.playerCount}{" "}
{b.playerData.playerCount == 1 ? "player" : "players"}{" "}
2024-08-15 23:24:15 -05:00
currently online {favs && <> {favs} favorited</>}
2024-07-23 18:49:21 -05:00
</span>
</span>
<ContextMenu>
<ContextMenuTrigger>
<>
<Button
size="icon"
variant="secondary"
2024-08-08 18:02:46 -05:00
className="min-w-[128px] max-w-[328px] h-[32px] mt-2 ml-2 max-md:hidden"
2024-07-23 18:49:21 -05:00
onClick={() => {
2024-08-22 23:44:00 -05:00
clipboard.writeText(b.name + ".mshf.minehut.gg");
2024-07-23 18:49:21 -05:00
toast.success("Copied IP to clipboard");
}}
>
<Copy size={18} />
<code className="ml-2">{b.name}</code>
</Button>
<Tooltip>
<TooltipTrigger>
2024-08-03 09:51:45 -05:00
<Link href={"/server/" + b.name}>
2024-08-07 16:37:54 -05:00
<Button
size="icon"
variant="secondary"
2024-08-08 18:02:46 -05:00
className="w-[32px] h-[32px] mt-2 ml-2 max-md:hidden"
2024-08-07 16:37:54 -05:00
>
<Layers size={18} />
</Button>
2024-08-03 09:51:45 -05:00
</Link>
2024-07-23 18:49:21 -05:00
</TooltipTrigger>
<TooltipContent>
2024-07-23 22:07:54 -05:00
Open up the server page to see more information about
the server
2024-07-23 18:49:21 -05:00
</TooltipContent>
</Tooltip>
</>
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem
onClick={() => {
2024-08-22 23:44:00 -05:00
clipboard.writeText(b.name + ".mshf.minehut.gg");
2024-07-23 18:49:21 -05:00
toast.success("Copied IP to clipboard");
}}
>
Copy server IP
2024-08-08 18:02:46 -05:00
<div className="RightSlot">
2024-07-23 18:49:21 -05:00
<Copy size={18} />
</div>
</ContextMenuItem>
<ContextMenuSeparator />
2024-08-03 09:51:45 -05:00
<Link href={"/server/" + b.name}>
2024-08-07 16:37:54 -05:00
<ContextMenuItem>Open server page</ContextMenuItem>
</Link>
2024-07-23 18:49:21 -05:00
</ContextMenuContent>
</ContextMenu>
</CardDescription>
<CardContent>
2024-08-15 23:24:15 -05:00
{motd && (
<span
dangerouslySetInnerHTML={{ __html: motd }}
className="w-[30px] text-center break-all overflow-hidden"
/>
)}
2024-07-23 18:49:21 -05:00
</CardContent>
</CardHeader>
</Card>
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem
onClick={() => {
2024-08-22 23:44:00 -05:00
clipboard.writeText(b.name + ".mshf.minehut.gg");
2024-07-23 18:49:21 -05:00
toast.success("Copied IP to clipboard");
}}
>
Copy server IP
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem
onClick={() => {
2024-08-03 09:51:45 -05:00
router.push("/server/" + b.name);
2024-07-23 18:49:21 -05:00
}}
>
Open server page
</ContextMenuItem>
2024-08-15 23:24:15 -05:00
<ContextMenuItem
onClick={() => {
router.push("/server/" + b.name + "/statistics");
}}
>
Open statistics page
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem
onClick={() => {
setFavoriteLoading(true);
favoriteServer(b.name).then(() => {
setFavoriteLoading(false);
setFavoriteStar(!favoriteStar);
});
}}
disabled={!isSignedIn || favoriteLoading}
>
{!favoriteLoading && (
<Star
size={16}
className="mr-2 text-white"
fill={
favoriteStar
? resolvedTheme == "dark"
? "white"
: "black"
: "transparent"
}
/>
)}{" "}
{favoriteLoading && <LoaderIcon className="mr-2" />}
{favoriteStar && isSignedIn ? "Unf" : "F"}avorite Server
</ContextMenuItem>
2024-07-23 18:49:21 -05:00
</ContextMenuContent>
</ContextMenu>
);
}