mirror of
https://github.com/DeveloLongScript/MHSF.git
synced 2026-05-09 05:34:59 -05:00
feat: revamped documentation
This commit is contained in:
parent
dd9104f2f3
commit
3c1fd6cfc4
@ -11,12 +11,12 @@ The command-bar has many mods and is a great tool for power-users to use as its
|
||||
|
||||
## Triggering the command-bar
|
||||
|
||||
There are two ways to trigger the command bar, using `Ctrl+K` and `Ctrl+Shift+K`. Both put you in a command-bar, however when using `Ctrl+K`, you go into a general page with other settings.
|
||||
Using `Ctrl+Shift+K` opens a server viewer, and this may be faster then going through the general page.
|
||||
There are two ways to trigger the command bar, using `Ctrl+K` and <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>K</kbd>. Both put you in a command-bar, however when using `Ctrl+K`, you go into a general page with other settings.
|
||||
Using <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>K</kbd> opens a server viewer, and this may be faster then going through the general page.
|
||||
|
||||
## Functions using `Ctrl+K`
|
||||
## Functions using Ctrl+K
|
||||
|
||||
- **Servers** opens a server list, same as `Ctrl+Shift+K`
|
||||
- **Servers** opens a server list, same as <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>K</kbd>
|
||||
- **Sort Servers** allows you to go into a sorted server list quickly
|
||||
- **Links** shows links useful for MHSF
|
||||
- **Pick Random Server** picks a random server and shows the user what that server is, is similar to the one on [the server list](/)
|
||||
|
||||
@ -5,11 +5,11 @@ folder: "Guides"
|
||||
|
||||
# Owning a server
|
||||
|
||||
Owning a server is quite simple and allows you to [customize your server](/docs/guides/customization) your server and make it stand out from other servers. Before owning your server, make sure you agree to the [ECA](Docs:legal/external-content-agreement).
|
||||
Owning a server is quite simple and allows you to [customize your server](/docs/guides/customization) and make it stand out from other servers. Before owning your server, make sure you agree to the [ECA](Docs:legal/external-content-agreement).
|
||||
|
||||
## Linking
|
||||
|
||||
Find the server you would like to own (either by looking for it, or using the keyboard shortcut `Ctrl`+`Shift`+`K` and searching for it), and make sure your account has [already been linked with your Minecraft account](Docs:guides/linking). Go to the server, and hit the Customization tab. If the owner of the server, and the user your linked to match, you will gain access to the server.
|
||||
Find the server you would like to own (either by looking for it, or using the keyboard shortcut <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>K</kbd> and searching for it), and make sure your account has [already been linked with your Minecraft account](Docs:guides/linking). Go to the server, and hit the Customization tab. If the owner of the server, and the user your linked to match, you will gain access to the server.
|
||||
If they match, you should see a button named Click to own. Press that button, and you should automagically own the server. Congratulations!
|
||||
|
||||
## I can't link my server, because my server doesn't have a author
|
||||
|
||||
12
package.json
12
package.json
@ -19,6 +19,8 @@
|
||||
"@emotion/is-prop-valid": "^1.3.0",
|
||||
"@linear/sdk": "^31.0.0",
|
||||
"@monaco-editor/react": "^4.6.0",
|
||||
"@radix-ui/react-avatar": "^1.1.1",
|
||||
"@radix-ui/react-collapsible": "^1.1.1",
|
||||
"@radix-ui/react-hover-card": "^1.1.1",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-menubar": "^1.1.1",
|
||||
@ -35,7 +37,7 @@
|
||||
"inngest": "^3.21.2",
|
||||
"input-otp": "^1.2.4",
|
||||
"json-beautify": "^1.1.1",
|
||||
"lucide-react": "^0.416.0",
|
||||
"lucide-react": "^0.454.0",
|
||||
"minimessage-2-html": "1.6.0",
|
||||
"mongodb": "^6.8.0",
|
||||
"next": "14.2.10",
|
||||
@ -63,17 +65,17 @@
|
||||
"@hookform/resolvers": "^3.9.0",
|
||||
"@radix-ui/react-checkbox": "^1.1.1",
|
||||
"@radix-ui/react-context-menu": "^2.1.5",
|
||||
"@radix-ui/react-dialog": "^1.1.1",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||
"@radix-ui/react-dialog": "^1.1.2",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
||||
"@radix-ui/react-label": "^2.1.0",
|
||||
"@radix-ui/react-navigation-menu": "^1.1.4",
|
||||
"@radix-ui/react-popover": "^1.0.7",
|
||||
"@radix-ui/react-radio-group": "^1.2.0",
|
||||
"@radix-ui/react-scroll-area": "^1.1.0",
|
||||
"@radix-ui/react-separator": "^1.0.3",
|
||||
"@radix-ui/react-separator": "^1.1.0",
|
||||
"@radix-ui/react-slot": "^1.1.0",
|
||||
"@radix-ui/react-tabs": "^1.1.0",
|
||||
"@radix-ui/react-tooltip": "^1.0.7",
|
||||
"@radix-ui/react-tooltip": "^1.1.3",
|
||||
"@tailwindcss/typography": "^0.5.13",
|
||||
"@types/canvas-confetti": "^1.6.4",
|
||||
"@types/node": "^20",
|
||||
|
||||
129
src/app/(docs)/docs/[[...slug]]/page.tsx
Normal file
129
src/app/(docs)/docs/[[...slug]]/page.tsx
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* MHSF, Minehut Server List
|
||||
* All external content is rather licensed under the ECA Agreement
|
||||
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
|
||||
*
|
||||
* All code under MHSF is licensed under the MIT License
|
||||
* by open source contributors
|
||||
*
|
||||
* Copyright (c) 2024 dvelo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import TableOfContent from "@/components/docs/TOC";
|
||||
import { ALegacy } from "@/components/misc/Link";
|
||||
import { MDXElements } from "@/components/misc/MDXElements";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { allDocs } from "contentlayer/generated";
|
||||
import { useMDXComponent } from "next-contentlayer/hooks";
|
||||
import NextLink from "next/link";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
export const generateStaticParams = async () =>
|
||||
allDocs.map((post) => ({ slug: [post._raw.flattenedPath] }));
|
||||
|
||||
export const generateMetadata = ({
|
||||
params,
|
||||
}: {
|
||||
params: { slug: string[] };
|
||||
}) => {
|
||||
const post = allDocs.find(
|
||||
(post) => post._raw.flattenedPath === params.slug.join("/"),
|
||||
);
|
||||
if (!post) notFound();
|
||||
return { title: post.title + " | MHSF Docs", themeColor: "#000000" };
|
||||
};
|
||||
|
||||
const PostLayout = ({ params }: { params: { slug: string[] } }) => {
|
||||
const doc = allDocs.find(
|
||||
(post) => post._raw.flattenedPath === params.slug.join("/"),
|
||||
);
|
||||
|
||||
if (!doc) notFound();
|
||||
console.log(doc);
|
||||
const MDXContent = useMDXComponent(doc.body.code);
|
||||
|
||||
return (
|
||||
<main className="relative py-6 lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_300px]">
|
||||
<div className="mx-auto w-full min-w-0">
|
||||
<div className="pb-12 pt-8 prose dark:prose-invert">
|
||||
{doc.folder && <span>{doc.folder}</span>}{" "}
|
||||
{doc.lastUpdated && <span> - last updated {doc.lastUpdated}</span>}{" "}
|
||||
<MDXContent
|
||||
components={{
|
||||
Separator,
|
||||
a: (props) => <ALegacy {...props} />,
|
||||
...MDXElements,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{doc.toc && (
|
||||
<div className="hidden text-sm xl:block">
|
||||
<div className="sticky top-16 -mt-10 pt-4">
|
||||
<ScrollArea className="pb-10">
|
||||
<div className="sticky top-16 -mt-10 h-[calc(100vh-3.5rem)] py-12 space-y-2">
|
||||
<p className="font-medium">On This Page</p>
|
||||
{doc.toc.map(
|
||||
(c: { level: number; text: string; slug: string }) => (
|
||||
<TableOfContent toc={c} doc={doc} key={c.slug} />
|
||||
),
|
||||
)}
|
||||
<br />
|
||||
<div className="space-y-2">
|
||||
<p className="font-medium">Contribute</p>
|
||||
<ul className="m-0 list-none">
|
||||
<li className="mt-0 pt-2">
|
||||
<NextLink
|
||||
href={
|
||||
"https://github.com/DeveloLongScript/MHSF/edit/main/docs/" +
|
||||
doc._raw.flattenedPath +
|
||||
".mdx"
|
||||
}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors no-underline"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 438.549 438.549"
|
||||
fontSize={16}
|
||||
className="mr-2 size-4"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"
|
||||
/>
|
||||
</svg>
|
||||
Edit page on GitHub
|
||||
</NextLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
);
|
||||
};
|
||||
export default PostLayout;
|
||||
@ -28,47 +28,75 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
"use client";
|
||||
|
||||
import { Sidebar } from "@/components/docs/Sidebar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Drawer, DrawerContent, DrawerTrigger } from "@/components/ui/drawer";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import {
|
||||
SidebarInset,
|
||||
SidebarProvider,
|
||||
SidebarTrigger,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { version } from "@/config/version";
|
||||
import { HamburgerMenuIcon } from "@radix-ui/react-icons";
|
||||
import { GeistMono } from "geist/font/mono";
|
||||
import { GeistSans } from "geist/font/sans";
|
||||
import "../globals.css";
|
||||
import "../../themes.css";
|
||||
import { ThemeProvider } from "@/components/ThemeProvider";
|
||||
import { ClerkThemeProvider } from "@/components/clerk/ClerkThemeProvider";
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from "@/components/ui/breadcrumb";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import NextTopLoader from "@/lib/top-loader";
|
||||
import { useRouter } from "@/lib/useRouter";
|
||||
import { allDocs } from "contentlayer/generated";
|
||||
import { GetServerSideProps } from "next";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
interface Props {
|
||||
pathname: string;
|
||||
}
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
const pathname = usePathname();
|
||||
return (
|
||||
<div className="border-b pt-[40px]">
|
||||
<div className="container flex-1 items-start md:grid md:grid-cols-[220px_minmax(0,1fr)] md:gap-6 lg:grid-cols-[240px_minmax(0,1fr)] lg:gap-10">
|
||||
<aside className="fixed top-14 z-30 hidden h-[calc(100vh-3.5rem)] w-full shrink-0 md:sticky md:block">
|
||||
<ScrollArea className="h-full py-6 pr-6 lg:py-8">
|
||||
<div className="bg-muted w-full rounded justify-center p-4 flex items-center">
|
||||
MHSF Docs <small className="ml-2">Version {version}</small>
|
||||
</div>
|
||||
<br />
|
||||
<ClerkThemeProvider className="">
|
||||
<div className="theme-zinc">
|
||||
<NextTopLoader />
|
||||
<SidebarProvider>
|
||||
<Sidebar />
|
||||
</ScrollArea>
|
||||
</aside>
|
||||
<br className="md:hidden" />
|
||||
|
||||
<div className="bg-muted w-full rounded justify-center p-4 flex items-center md:hidden">
|
||||
MHSF Docs <small className="ml-2">Version {version}</small>
|
||||
<Drawer>
|
||||
<DrawerTrigger>
|
||||
<Button className="ml-2">
|
||||
<HamburgerMenuIcon />
|
||||
</Button>
|
||||
</DrawerTrigger>
|
||||
<DrawerContent className="p-4">
|
||||
<Sidebar />
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
</div>
|
||||
{children}
|
||||
<SidebarInset>
|
||||
<div className="fixed backdrop-blur w-full flex h-16 z-10 items-center gap-2 px-4 ">
|
||||
<SidebarTrigger />
|
||||
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||
{
|
||||
allDocs.find(
|
||||
(c) =>
|
||||
c._raw.flattenedPath ===
|
||||
pathname
|
||||
?.split("/")
|
||||
.splice(2, pathname?.split("/").length)
|
||||
.join("/"),
|
||||
)?.title
|
||||
}
|
||||
</div>
|
||||
<div className="px-[100px] pt-[50px]">{children}</div>
|
||||
</SidebarInset>
|
||||
</SidebarProvider>
|
||||
</div>
|
||||
</ClerkThemeProvider>
|
||||
);
|
||||
}
|
||||
@ -28,36 +28,36 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { GeistSans } from "geist/font/sans";
|
||||
import { SpeedInsights } from "@vercel/speed-insights/next";
|
||||
import { Analytics } from "@vercel/analytics/react";
|
||||
import "./globals.css";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { SpeedInsights } from "@vercel/speed-insights/next";
|
||||
import { GeistSans } from "geist/font/sans";
|
||||
import "../globals.css";
|
||||
import ClientFadeIn from "@/components/ClientFadeIn";
|
||||
import { CommandBarer } from "@/components/CommandBar";
|
||||
import { BrandingGenericIcon } from "@/components/Icon";
|
||||
import TextFromPathname from "@/components/TextFromPathname";
|
||||
import { ThemeProvider } from "@/components/ThemeProvider";
|
||||
import { ClerkThemeProvider } from "@/components/clerk/ClerkThemeProvider";
|
||||
import NextTopLoader from "@/lib/top-loader";
|
||||
import { banner } from "@/config/banner";
|
||||
import TopBar from "@/components/clerk/Topbar";
|
||||
import ThemedToaster from "@/components/misc/ThemedToaster";
|
||||
import UnofficalDialog from "@/components/misc/UnofficalDialog";
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
} from "@/components/ui/breadcrumb";
|
||||
import Link from "next/link";
|
||||
import TopBar from "@/components/clerk/Topbar";
|
||||
import TextFromPathname from "@/components/TextFromPathname";
|
||||
import { Inter as interFont } from "next/font/google";
|
||||
import { CommandBarer } from "@/components/CommandBar";
|
||||
import ThemedToaster from "@/components/misc/ThemedToaster";
|
||||
import UnofficalDialog from "@/components/misc/UnofficalDialog";
|
||||
import ClientFadeIn from "@/components/ClientFadeIn";
|
||||
import { BrandingGenericIcon } from "@/components/Icon";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { banner } from "@/config/banner";
|
||||
import NextTopLoader from "@/lib/top-loader";
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import { Inter as interFont } from "next/font/google";
|
||||
import Link from "next/link";
|
||||
|
||||
export const extraMetadata = {
|
||||
twitter: {
|
||||
images: [
|
||||
{
|
||||
url: "/public/imgs/icon-cf.png",
|
||||
url: "/imgs/icon-cf.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -65,7 +65,7 @@ export const extraMetadata = {
|
||||
openGraph: {
|
||||
images: [
|
||||
{
|
||||
url: "/public/imgs/icon-cf.png",
|
||||
url: "/imgs/icon-cf.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -38,7 +38,7 @@ export default function NotFound() {
|
||||
<br />
|
||||
<p>
|
||||
We couldn't find the page you were looking for.{" "}
|
||||
<Link href="/">Go home</Link>
|
||||
<Link href="/public">Go home</Link>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
@ -40,7 +40,7 @@ export const metadata: Metadata = {
|
||||
twitter: {
|
||||
images: [
|
||||
{
|
||||
url: "/public/imgs/icon-cf.png",
|
||||
url: "/imgs/icon-cf.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -48,7 +48,7 @@ export const metadata: Metadata = {
|
||||
openGraph: {
|
||||
images: [
|
||||
{
|
||||
url: "/public/imgs/icon-cf.png",
|
||||
url: "/imgs/icon-cf.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
155
src/app/(main)/server/[server]/page.tsx
Normal file
155
src/app/(main)/server/[server]/page.tsx
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* MHSF, Minehut Server List
|
||||
* All external content is rather licensed under the ECA Agreement
|
||||
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
|
||||
*
|
||||
* All code under MHSF is licensed under the MIT License
|
||||
* by open source contributors
|
||||
*
|
||||
* Copyright (c) 2024 dvelo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import AfterServerView from "@/components/AfterServerView";
|
||||
import Banner from "@/components/Banner";
|
||||
import ColorProvider from "@/components/ColorProvider";
|
||||
import ServerView from "@/components/ServerView";
|
||||
import TabServer from "@/components/misc/TabServer";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { CornerDownLeft } from "lucide-react";
|
||||
import type { Metadata, ResolvingMetadata } from "next";
|
||||
import Link from "next/link";
|
||||
|
||||
type Props = {
|
||||
params: { server: string };
|
||||
};
|
||||
|
||||
export async function generateMetadata(
|
||||
{ params }: Props,
|
||||
parent: ResolvingMetadata,
|
||||
): Promise<Metadata> {
|
||||
// read route params
|
||||
const { server } = params;
|
||||
const json = await (
|
||||
await fetch("https://api.minehut.com/server/" + server + "?byName=true")
|
||||
).json();
|
||||
|
||||
return {
|
||||
themeColor: "#000000",
|
||||
title:
|
||||
json.server == null
|
||||
? "Server doesn't exist | MHSF"
|
||||
: json.server.name +
|
||||
", " +
|
||||
(json.server.online
|
||||
? json.server.playerCount +
|
||||
(json.server.maxPlayers != 10
|
||||
? "/" + json.server.maxPlayers
|
||||
: "") +
|
||||
" online"
|
||||
: "Offline") +
|
||||
" | MHSF",
|
||||
description:
|
||||
json.server == null
|
||||
? `The server ${server} doesn't exist.`
|
||||
: `View ${server} on Minehut Server Finder!`,
|
||||
authors: json.server == null ? undefined : { name: json.server.owner },
|
||||
applicationName: "MHSF (Minehut Server Finder)",
|
||||
icons:
|
||||
json.server == null
|
||||
? undefined
|
||||
: "https://minehut-server-icons-live.s3.us-west-2.amazonaws.com/" +
|
||||
(json.server.icon == undefined ? "OAK_SIGN" : json.server.icon) +
|
||||
".png",
|
||||
twitter: {
|
||||
title:
|
||||
json.server == null
|
||||
? "Server doesn't exist | MHSF"
|
||||
: json.server.name +
|
||||
", " +
|
||||
(json.server.online
|
||||
? json.server.playerCount +
|
||||
(json.server.maxPlayers != 10
|
||||
? "/" + json.server.maxPlayers
|
||||
: "") +
|
||||
" online"
|
||||
: "Offline") +
|
||||
" | MHSF",
|
||||
description:
|
||||
json.server == null
|
||||
? `The server ${server} doesn't exist.`
|
||||
: `View ${server} on Minehut Server Finder!`,
|
||||
images: [
|
||||
{
|
||||
url:
|
||||
"https://minehut-server-icons-live.s3.us-west-2.amazonaws.com/" +
|
||||
json.server.icon +
|
||||
".png",
|
||||
},
|
||||
{
|
||||
url: "/public/imgs/icon-cf.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
openGraph: {
|
||||
type: "profile",
|
||||
siteName: "MHSF (Minehut Server Finder)",
|
||||
|
||||
images: [
|
||||
{
|
||||
url:
|
||||
"https://minehut-server-icons-live.s3.us-west-2.amazonaws.com/" +
|
||||
json.server.icon +
|
||||
".png",
|
||||
},
|
||||
{
|
||||
url: "/public/imgs/icon-cf.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function ServerPage({ params }: { params: { server: string } }) {
|
||||
return (
|
||||
<main>
|
||||
<ColorProvider server={params.server}>
|
||||
<div className={"pt-16"}>
|
||||
<Banner server={params.server} />
|
||||
<Link href="/">
|
||||
<Button variant="link" className="text-muted-foreground text-sm">
|
||||
<CornerDownLeft size={16} className="mr-2" /> Go back to the
|
||||
server list
|
||||
</Button>
|
||||
</Link>
|
||||
<TabServer server={params.server} tabDef="general" />
|
||||
<div className="pt-8">
|
||||
<ServerView server={params.server} />
|
||||
</div>
|
||||
<Separator />
|
||||
<br />
|
||||
<AfterServerView server={params.server} />
|
||||
</div>
|
||||
</ColorProvider>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
116
src/app/(main)/server/[server]/statistics/page.tsx
Normal file
116
src/app/(main)/server/[server]/statistics/page.tsx
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* MHSF, Minehut Server List
|
||||
* All external content is rather licensed under the ECA Agreement
|
||||
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
|
||||
*
|
||||
* All code under MHSF is licensed under the MIT License
|
||||
* by open source contributors
|
||||
*
|
||||
* Copyright (c) 2024 dvelo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Banner from "@/components/Banner";
|
||||
import ColorProvider from "@/components/ColorProvider";
|
||||
import { NewChart } from "@/components/NewChart";
|
||||
import ServerView from "@/components/ServerView";
|
||||
import TabServer from "@/components/misc/TabServer";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import type { Metadata, ResolvingMetadata } from "next";
|
||||
|
||||
type Props = {
|
||||
params: { server: string };
|
||||
};
|
||||
|
||||
export async function generateMetadata(
|
||||
{ params }: Props,
|
||||
parent: ResolvingMetadata,
|
||||
): Promise<Metadata> {
|
||||
// read route params
|
||||
const { server } = params;
|
||||
const json = await (
|
||||
await fetch("https://api.minehut.com/server/" + server + "?byName=true")
|
||||
).json();
|
||||
|
||||
return {
|
||||
title:
|
||||
json.server == null
|
||||
? "Server doesn't exist | MHSF"
|
||||
: json.server.name +
|
||||
", " +
|
||||
(json.server.online
|
||||
? json.server.playerCount +
|
||||
(json.server.maxPlayers != 10
|
||||
? "/" + json.server.maxPlayers
|
||||
: "") +
|
||||
" online"
|
||||
: "Offline") +
|
||||
" | MHSF",
|
||||
description:
|
||||
json.server == null
|
||||
? `The server ${server} doesn't exist.`
|
||||
: `View ${server} on Minehut Server Finder!`,
|
||||
authors: json.server == null ? undefined : { name: json.server.owner },
|
||||
applicationName: "MHSF (Minehut Server Finder)",
|
||||
icons:
|
||||
json.server == null
|
||||
? undefined
|
||||
: "https://mcapi.marveldc.me/item/" +
|
||||
(json.server.icon == undefined ? "OAK_SIGN" : json.server.icon) +
|
||||
"?width=64&height=64",
|
||||
openGraph: {
|
||||
type: "profile",
|
||||
siteName: "MHSF (Minehut Server Finder)",
|
||||
images: [
|
||||
{
|
||||
url:
|
||||
"https://mcapi.marveldc.me/item/" +
|
||||
json.server.icon +
|
||||
"?width=64&height=64",
|
||||
},
|
||||
{
|
||||
url: "/favicon.ico",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function ServerPage({ params }: { params: { server: string } }) {
|
||||
return (
|
||||
<main>
|
||||
<ColorProvider server={params.server}>
|
||||
<div className={"pt-16"}>
|
||||
<Banner server={params.server} />
|
||||
<TabServer server={params.server} tabDef="statistics" />
|
||||
<div className="pt-8">
|
||||
<ServerView server={params.server} />
|
||||
<Separator />
|
||||
<br />
|
||||
<div className="p-4 gap-4">
|
||||
<NewChart server={params.server} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ColorProvider>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* MHSF, Minehut Server List
|
||||
* All external content is rather licensed under the ECA Agreement
|
||||
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
|
||||
*
|
||||
* All code under MHSF is licensed under the MIT License
|
||||
* by open source contributors
|
||||
*
|
||||
* Copyright (c) 2024 dvelo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import TableOfContent from "@/components/docs/TOC";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { allDocs } from "contentlayer/generated";
|
||||
import { useMDXComponent } from "next-contentlayer/hooks";
|
||||
import NextLink from "next/link";
|
||||
import { notFound } from "next/navigation";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { ALegacy } from "@/components/misc/Link";
|
||||
import { MDXElements } from "@/components/misc/MDXElements";
|
||||
|
||||
export const generateStaticParams = async () =>
|
||||
allDocs.map((post) => ({ slug: [post._raw.flattenedPath] }));
|
||||
|
||||
export const generateMetadata = ({
|
||||
params,
|
||||
}: {
|
||||
params: { slug: string[] };
|
||||
}) => {
|
||||
const post = allDocs.find(
|
||||
(post) => post._raw.flattenedPath === params.slug.join("/")
|
||||
);
|
||||
if (!post) notFound();
|
||||
return { title: post.title + " | MHSF Docs", themeColor: "#000000" };
|
||||
};
|
||||
|
||||
const PostLayout = ({ params }: { params: { slug: string[] } }) => {
|
||||
const doc = allDocs.find(
|
||||
(post) => post._raw.flattenedPath === params.slug.join("/")
|
||||
);
|
||||
|
||||
if (!doc) notFound();
|
||||
console.log(doc);
|
||||
const MDXContent = useMDXComponent(doc.body.code);
|
||||
|
||||
return (
|
||||
<main className="relative py-6 lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_300px]">
|
||||
<div className="mx-auto w-full min-w-0">
|
||||
<div className="pb-12 pt-8 prose dark:prose-invert">
|
||||
{doc.folder && <span>{doc.folder}</span>}{" "}
|
||||
{doc.lastUpdated && <span> - last updated {doc.lastUpdated}</span>}{" "}
|
||||
<MDXContent
|
||||
components={{
|
||||
Separator,
|
||||
a: (props) => <ALegacy {...props} />,
|
||||
...MDXElements,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{doc.toc && (
|
||||
<div className="hidden text-sm xl:block">
|
||||
<div className="sticky top-16 -mt-10 pt-4">
|
||||
<ScrollArea className="pb-10">
|
||||
<div className="sticky top-16 -mt-10 h-[calc(100vh-3.5rem)] py-12 space-y-2">
|
||||
<p className="font-medium">On This Page</p>
|
||||
{doc.toc.map(
|
||||
(c: { level: number; text: string; slug: string }) => (
|
||||
<TableOfContent toc={c} doc={doc} key={c.slug} />
|
||||
)
|
||||
)}
|
||||
<br />
|
||||
<div className="space-y-2">
|
||||
<p className="font-medium">Contribute</p>
|
||||
<ul className="m-0 list-none">
|
||||
<li className="mt-0 pt-2">
|
||||
<NextLink
|
||||
href={
|
||||
"https://github.com/DeveloLongScript/MHSF/edit/main/docs/" +
|
||||
doc._raw.flattenedPath +
|
||||
".mdx"
|
||||
}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors no-underline"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 438.549 438.549"
|
||||
fontSize={16}
|
||||
className="mr-2 size-4"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"
|
||||
/>
|
||||
</svg>
|
||||
Edit page on GitHub
|
||||
</NextLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
);
|
||||
};
|
||||
export default PostLayout;
|
||||
@ -73,6 +73,15 @@
|
||||
--color-one: #37ecba;
|
||||
--color-two: #72afd3;
|
||||
--color-three: #ff2e63;
|
||||
--sidebar-background: 0 0% 98%;
|
||||
--sidebar-foreground: 240 5.3% 26.1%;
|
||||
--sidebar-primary: 240 5.9% 10%;
|
||||
--sidebar-primary-foreground: 0 0% 98%;
|
||||
--sidebar-mhsf: 240 1% 92%;
|
||||
--sidebar-accent: 240 4.8% 95.9%;
|
||||
--sidebar-accent-foreground: 240 5.9% 10%;
|
||||
--sidebar-border: 220 13% 91%;
|
||||
--sidebar-ring: 217.2 91.2% 59.8%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
@ -112,6 +121,15 @@
|
||||
--chart-3: 216 92% 60%;
|
||||
--chart-4: 210 98% 78%;
|
||||
--chart-5: 212 97% 87%;
|
||||
--sidebar-background: 240 5.9% 10%;
|
||||
--sidebar-foreground: 240 4.8% 95.9%;
|
||||
--sidebar-primary: 224.3 76.3% 48%;
|
||||
--sidebar-primary-foreground: 0 0% 100%;
|
||||
--sidebar-mhsf: 240 0% 13%;
|
||||
--sidebar-accent: 240 3.7% 15.9%;
|
||||
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
||||
--sidebar-border: 240 3.7% 15.9%;
|
||||
--sidebar-ring: 217.2 91.2% 59.8%;
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,11 +141,11 @@
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
@layer base {
|
||||
a {
|
||||
@apply underline text-blue-400;
|
||||
}
|
||||
}
|
||||
/*@layer base {*/
|
||||
/* a {*/
|
||||
/* @apply underline text-blue-400;*/
|
||||
/* }*/
|
||||
/*}*/
|
||||
|
||||
.backdrop-blur {
|
||||
-webkit-backdrop-filter: blur(8px) !important;
|
||||
|
||||
@ -1,152 +0,0 @@
|
||||
/*
|
||||
* MHSF, Minehut Server List
|
||||
* All external content is rather licensed under the ECA Agreement
|
||||
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
|
||||
*
|
||||
* All code under MHSF is licensed under the MIT License
|
||||
* by open source contributors
|
||||
*
|
||||
* Copyright (c) 2024 dvelo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import ServerView from "@/components/ServerView";
|
||||
import type { Metadata, ResolvingMetadata } from "next";
|
||||
import TabServer from "@/components/misc/TabServer";
|
||||
import ColorProvider from "@/components/ColorProvider";
|
||||
import AfterServerView from "@/components/AfterServerView";
|
||||
import Banner from "@/components/Banner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { CornerDownLeft } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
type Props = {
|
||||
params: { server: string };
|
||||
};
|
||||
|
||||
export async function generateMetadata(
|
||||
{ params }: Props,
|
||||
parent: ResolvingMetadata
|
||||
): Promise<Metadata> {
|
||||
// read route params
|
||||
const { server } = params;
|
||||
const json = await (
|
||||
await fetch("https://api.minehut.com/server/" + server + "?byName=true")
|
||||
).json();
|
||||
|
||||
return {
|
||||
themeColor: "#000000",
|
||||
title:
|
||||
json.server == null
|
||||
? "Server doesn't exist | MHSF"
|
||||
: json.server.name +
|
||||
", " +
|
||||
(json.server.online
|
||||
? json.server.playerCount +
|
||||
(json.server.maxPlayers != 10
|
||||
? "/" + json.server.maxPlayers
|
||||
: "") +
|
||||
" online"
|
||||
: "Offline") +
|
||||
" | MHSF",
|
||||
description:
|
||||
json.server == null
|
||||
? `The server ${server} doesn't exist.`
|
||||
: `View ${server} on Minehut Server Finder!`,
|
||||
authors: json.server == null ? undefined : { name: json.server.owner },
|
||||
applicationName: "MHSF (Minehut Server Finder)",
|
||||
icons:
|
||||
json.server == null
|
||||
? undefined
|
||||
: "https://minehut-server-icons-live.s3.us-west-2.amazonaws.com/" +
|
||||
(json.server.icon == undefined ? "OAK_SIGN" : json.server.icon) +
|
||||
".png",
|
||||
twitter: {
|
||||
title:
|
||||
json.server == null
|
||||
? "Server doesn't exist | MHSF"
|
||||
: json.server.name +
|
||||
", " +
|
||||
(json.server.online
|
||||
? json.server.playerCount +
|
||||
(json.server.maxPlayers != 10
|
||||
? "/" + json.server.maxPlayers
|
||||
: "") +
|
||||
" online"
|
||||
: "Offline") +
|
||||
" | MHSF",
|
||||
description:
|
||||
json.server == null
|
||||
? `The server ${server} doesn't exist.`
|
||||
: `View ${server} on Minehut Server Finder!`,
|
||||
images: [
|
||||
{
|
||||
url:
|
||||
"https://minehut-server-icons-live.s3.us-west-2.amazonaws.com/" +
|
||||
json.server.icon +
|
||||
".png",
|
||||
},
|
||||
{
|
||||
url: "/public/imgs/icon-cf.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
openGraph: {
|
||||
type: "profile",
|
||||
siteName: "MHSF (Minehut Server Finder)",
|
||||
|
||||
images: [
|
||||
{
|
||||
url:
|
||||
"https://minehut-server-icons-live.s3.us-west-2.amazonaws.com/" +
|
||||
json.server.icon +
|
||||
".png",
|
||||
},
|
||||
{
|
||||
url: "/public/imgs/icon-cf.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function ServerPage({ params }: { params: { server: string } }) {
|
||||
return (
|
||||
<main>
|
||||
<ColorProvider server={params.server}>
|
||||
<div className={"pt-16"}>
|
||||
<Banner server={params.server} />
|
||||
<Link href="/">
|
||||
<Button variant="link" className="text-muted-foreground text-sm">
|
||||
<CornerDownLeft size={16} className="mr-2" /> Go back to the
|
||||
server list
|
||||
</Button>
|
||||
</Link>
|
||||
<TabServer server={params.server} tabDef="general" />
|
||||
<div className="pt-8">
|
||||
<ServerView server={params.server} />
|
||||
</div>
|
||||
<AfterServerView server={params.server} />
|
||||
</div>
|
||||
</ColorProvider>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* MHSF, Minehut Server List
|
||||
* All external content is rather licensed under the ECA Agreement
|
||||
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
|
||||
*
|
||||
* All code under MHSF is licensed under the MIT License
|
||||
* by open source contributors
|
||||
*
|
||||
* Copyright (c) 2024 dvelo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import ServerView from "@/components/ServerView";
|
||||
import type { Metadata, ResolvingMetadata } from "next";
|
||||
import TabServer from "@/components/misc/TabServer";
|
||||
import { NewChart } from "@/components/NewChart";
|
||||
import ColorProvider from "@/components/ColorProvider";
|
||||
import Banner from "@/components/Banner";
|
||||
|
||||
type Props = {
|
||||
params: { server: string };
|
||||
};
|
||||
|
||||
export async function generateMetadata(
|
||||
{ params }: Props,
|
||||
parent: ResolvingMetadata
|
||||
): Promise<Metadata> {
|
||||
// read route params
|
||||
const { server } = params;
|
||||
const json = await (
|
||||
await fetch("https://api.minehut.com/server/" + server + "?byName=true")
|
||||
).json();
|
||||
|
||||
return {
|
||||
title:
|
||||
json.server == null
|
||||
? "Server doesn't exist | MHSF"
|
||||
: json.server.name +
|
||||
", " +
|
||||
(json.server.online
|
||||
? json.server.playerCount +
|
||||
(json.server.maxPlayers != 10
|
||||
? "/" + json.server.maxPlayers
|
||||
: "") +
|
||||
" online"
|
||||
: "Offline") +
|
||||
" | MHSF",
|
||||
description:
|
||||
json.server == null
|
||||
? `The server ${server} doesn't exist.`
|
||||
: `View ${server} on Minehut Server Finder!`,
|
||||
authors: json.server == null ? undefined : { name: json.server.owner },
|
||||
applicationName: "MHSF (Minehut Server Finder)",
|
||||
icons:
|
||||
json.server == null
|
||||
? undefined
|
||||
: "https://mcapi.marveldc.me/item/" +
|
||||
(json.server.icon == undefined ? "OAK_SIGN" : json.server.icon) +
|
||||
"?width=64&height=64",
|
||||
openGraph: {
|
||||
type: "profile",
|
||||
siteName: "MHSF (Minehut Server Finder)",
|
||||
images: [
|
||||
{
|
||||
url:
|
||||
"https://mcapi.marveldc.me/item/" +
|
||||
json.server.icon +
|
||||
"?width=64&height=64",
|
||||
},
|
||||
{
|
||||
url: "/favicon.ico",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function ServerPage({ params }: { params: { server: string } }) {
|
||||
return (
|
||||
<main>
|
||||
<ColorProvider server={params.server}>
|
||||
<div className={"pt-16"}>
|
||||
<Banner server={params.server} />
|
||||
<TabServer server={params.server} tabDef="statistics" />
|
||||
<div className="pt-8">
|
||||
<ServerView server={params.server} />
|
||||
<div className="p-4 gap-4">
|
||||
<NewChart server={params.server} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ColorProvider>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@ -30,7 +30,17 @@
|
||||
|
||||
"use client";
|
||||
import { getCommunityServerFavorites, getCustomization } from "@/lib/api";
|
||||
import { MHSF } from "@/lib/mhsf";
|
||||
import { ServerResponse } from "@/lib/types/mh-server";
|
||||
import { MinehutIcon, getMinehutIcons } from "@/lib/types/server-icon";
|
||||
import { Copy, Info } from "lucide-react";
|
||||
import { useTheme } from "next-themes";
|
||||
import { useEffect, useState } from "react";
|
||||
import FadeIn from "react-fade-in/lib/FadeIn";
|
||||
import toast, { CheckmarkIcon } from "react-hot-toast";
|
||||
import Markdown from "react-markdown";
|
||||
import AchievementList from "./feat/AchievementList";
|
||||
import { Button } from "./ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
@ -38,28 +48,20 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "./ui/card";
|
||||
import Markdown from "react-markdown";
|
||||
import { useTheme } from "next-themes";
|
||||
import FadeIn from "react-fade-in/lib/FadeIn";
|
||||
import { Button } from "./ui/button";
|
||||
import { ServerResponse } from "@/lib/types/mh-server";
|
||||
import { Copy, Info } from "lucide-react";
|
||||
import toast, { CheckmarkIcon } from "react-hot-toast";
|
||||
import { MHSF } from "@/lib/mhsf";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
|
||||
import AchievementList from "./feat/AchievementList";
|
||||
|
||||
export default function AfterServerView({ server }: { server: string }) {
|
||||
const [description, setDescription] = useState("");
|
||||
const [discord, setDiscord] = useState("");
|
||||
const [mhsf, setMHSF] = useState(new MHSF());
|
||||
const [icons, setIcons] = useState<MinehutIcon[]>();
|
||||
const { resolvedTheme } = useTheme();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [view, setView] = useState(
|
||||
description !== "" || discord !== "" ? "desc" : "extra"
|
||||
description !== "" || discord !== "" ? "desc" : "extra",
|
||||
);
|
||||
const [serverObject, setServerObject] = useState<ServerResponse | undefined>(
|
||||
undefined
|
||||
undefined,
|
||||
);
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
@ -72,9 +74,12 @@ export default function AfterServerView({ server }: { server: string }) {
|
||||
getCommunityServerFavorites(server).then((c) => {
|
||||
mhsf.setFavorites(c);
|
||||
});
|
||||
getMinehutIcons().then((i) => {
|
||||
setIcons(i);
|
||||
});
|
||||
}
|
||||
fetch("https://api.minehut.com/server/" + server + "?byName=true").then(
|
||||
(c) => c.json().then((n) => setServerObject(n.server))
|
||||
(c) => c.json().then((n) => setServerObject(n.server)),
|
||||
);
|
||||
setLoading(false);
|
||||
});
|
||||
@ -108,6 +113,12 @@ export default function AfterServerView({ server }: { server: string }) {
|
||||
>
|
||||
Achievements
|
||||
</Button>
|
||||
<Button
|
||||
variant={view == "icons" ? undefined : "ghost"}
|
||||
onClick={() => setView("icons")}
|
||||
>
|
||||
Purchased Icons
|
||||
</Button>
|
||||
</div>
|
||||
<div className="max-sm:hidden">
|
||||
<div className="grid">
|
||||
@ -131,6 +142,12 @@ export default function AfterServerView({ server }: { server: string }) {
|
||||
>
|
||||
Achievements
|
||||
</Button>
|
||||
<Button
|
||||
variant={view == "icons" ? undefined : "ghost"}
|
||||
onClick={() => setView("icons")}
|
||||
>
|
||||
Purchased Icons
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -317,11 +334,11 @@ export default function AfterServerView({ server }: { server: string }) {
|
||||
JSON.stringify({
|
||||
minehut: serverObject,
|
||||
mhsf: mhsf.getMHSF(),
|
||||
})
|
||||
}),
|
||||
);
|
||||
} catch {
|
||||
toast.error(
|
||||
"Clipboard is inaccessible. Cannot copy"
|
||||
"Clipboard is inaccessible. Cannot copy",
|
||||
);
|
||||
}
|
||||
toast.success(
|
||||
@ -334,7 +351,7 @@ export default function AfterServerView({ server }: { server: string }) {
|
||||
}).substring(0, 36)}
|
||||
...
|
||||
</code>
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
setTimeout(() => setCopied(false), 1000);
|
||||
}}
|
||||
@ -393,6 +410,20 @@ export default function AfterServerView({ server }: { server: string }) {
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
{view == "icons" && (
|
||||
<div>
|
||||
<p>
|
||||
Purchased Icons are icons that are under the server's
|
||||
ownership, they may or may not available at that certain
|
||||
moment either.
|
||||
</p>
|
||||
{serverObject?.purchased_icons.map((icon) => (
|
||||
<div key={icon}>
|
||||
{icons?.find((c) => c._id === icon)?.icon_name}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
@ -29,10 +29,11 @@
|
||||
*/
|
||||
|
||||
"use client";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { useState } from "react";
|
||||
import TabServer from "./misc/TabServer";
|
||||
import ServerCustomize from "./ServerCustomize";
|
||||
import Banner from "./Banner";
|
||||
import ServerCustomize from "./ServerCustomize";
|
||||
import TabServer from "./misc/TabServer";
|
||||
|
||||
export default function CustomizeRoot({
|
||||
params,
|
||||
@ -44,6 +45,7 @@ export default function CustomizeRoot({
|
||||
<div className={"pt-16 theme-" + color}>
|
||||
<Banner server={params.server} />
|
||||
<TabServer server={params.server} tabDef="customize" />
|
||||
<Separator />
|
||||
<br />
|
||||
<div className="pl-[40px] pr-[40px]">
|
||||
<ServerCustomize server={params.server} cs={color} setCS={setColor} />
|
||||
|
||||
@ -28,15 +28,15 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { useClerk } from "@clerk/nextjs";
|
||||
import { Cog, ExternalLink, KeyRound, Link, UserPen } from "lucide-react";
|
||||
import NextLink from "next/link";
|
||||
import { Button } from "./ui/button";
|
||||
import {
|
||||
ResizableHandle,
|
||||
ResizablePanel,
|
||||
ResizablePanelGroup,
|
||||
} from "./ui/resizable";
|
||||
import NextLink from "next/link";
|
||||
import { useClerk } from "@clerk/nextjs";
|
||||
|
||||
export function Sidebar({
|
||||
children,
|
||||
@ -54,7 +54,10 @@ export function Sidebar({
|
||||
>
|
||||
<ResizablePanel className="max-md:hidden min-w-[285px] max-w-[285px] w-[285px]">
|
||||
<div className="w-[300px] ml-[10px]">
|
||||
<NextLink href="/account/settings" className="text-inherit">
|
||||
<NextLink
|
||||
href="/src/app/(main)/account/settings"
|
||||
className="text-inherit"
|
||||
>
|
||||
<Button
|
||||
className="mb-[2px] w-[250px]"
|
||||
variant={curPage !== "/account/settings" ? "ghost" : "default"}
|
||||
@ -62,7 +65,10 @@ export function Sidebar({
|
||||
<Link size={16} className="mr-2" /> Linking
|
||||
</Button>
|
||||
</NextLink>
|
||||
<NextLink href="/account/settings/options" className="text-inherit">
|
||||
<NextLink
|
||||
href="/src/app/(main)/account/settings/options"
|
||||
className="text-inherit"
|
||||
>
|
||||
<Button
|
||||
className="mb-[2px] w-[250px] "
|
||||
variant={
|
||||
@ -93,7 +99,10 @@ export function Sidebar({
|
||||
<ResizableHandle className="max-md:hidden" />
|
||||
<ResizablePanel>
|
||||
<div className="md:hidden ml-2">
|
||||
<NextLink href="/account/settings" className="text-inherit">
|
||||
<NextLink
|
||||
href="/src/app/(main)/account/settings"
|
||||
className="text-inherit"
|
||||
>
|
||||
<Button
|
||||
className="mr-[2px]"
|
||||
variant={curPage !== "/account/settings" ? "ghost" : "default"}
|
||||
@ -101,7 +110,10 @@ export function Sidebar({
|
||||
<Link size={16} className="mr-2" /> Linking
|
||||
</Button>
|
||||
</NextLink>
|
||||
<NextLink href="/account/settings/options" className="text-inherit">
|
||||
<NextLink
|
||||
href="/src/app/(main)/account/settings/options"
|
||||
className="text-inherit"
|
||||
>
|
||||
<Button
|
||||
className="mr-[2px]"
|
||||
variant={
|
||||
|
||||
@ -28,32 +28,15 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { NewChart } from "@/components/NewChart";
|
||||
import { MiniJoinsChart } from "@/components/misc/MiniJoinsChart";
|
||||
import {
|
||||
ContextMenu,
|
||||
ContextMenuTrigger,
|
||||
ContextMenuItem,
|
||||
ContextMenuContent,
|
||||
ContextMenuItem,
|
||||
ContextMenuSeparator,
|
||||
ContextMenuTrigger,
|
||||
} from "@/components/ui/context-menu";
|
||||
import toast, { LoaderIcon } from "react-hot-toast";
|
||||
import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardDescription,
|
||||
Card,
|
||||
CardContent,
|
||||
} from "./ui/card";
|
||||
import IconDisplay from "./IconDisplay";
|
||||
import { TagShower } from "./ServerList";
|
||||
import {
|
||||
ArrowRight,
|
||||
ChartArea,
|
||||
Copy,
|
||||
EllipsisVertical,
|
||||
Layers,
|
||||
Star,
|
||||
} from "lucide-react";
|
||||
import { Button } from "./ui/button";
|
||||
import {
|
||||
Drawer,
|
||||
DrawerContent,
|
||||
@ -62,20 +45,39 @@ import {
|
||||
DrawerTitle,
|
||||
DrawerTrigger,
|
||||
} from "@/components/ui/drawer";
|
||||
import { Tooltip } from "@radix-ui/react-tooltip";
|
||||
import { TooltipContent, TooltipTrigger } from "./ui/tooltip";
|
||||
import { useRouter } from "@/lib/useRouter";
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
import { favoriteServer, isFavorited } from "@/lib/api";
|
||||
import { useUser } from "@clerk/nextjs";
|
||||
import { useTheme } from "next-themes";
|
||||
import {
|
||||
HoverCard,
|
||||
HoverCardContent,
|
||||
HoverCardTrigger,
|
||||
} from "@/components/ui/hover-card";
|
||||
import { favoriteServer, isFavorited } from "@/lib/api";
|
||||
import useClipboard from "@/lib/useClipboard";
|
||||
import { useRouter } from "@/lib/useRouter";
|
||||
import { useUser } from "@clerk/nextjs";
|
||||
import { Tooltip } from "@radix-ui/react-tooltip";
|
||||
import {
|
||||
ArrowRight,
|
||||
ChartArea,
|
||||
Copy,
|
||||
EllipsisVertical,
|
||||
Layers,
|
||||
Star,
|
||||
} from "lucide-react";
|
||||
import { useTheme } from "next-themes";
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
import toast, { LoaderIcon } from "react-hot-toast";
|
||||
import IconDisplay from "./IconDisplay";
|
||||
import { TagShower } from "./ServerList";
|
||||
import { Button } from "./ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "./ui/card";
|
||||
import { TooltipContent, TooltipTrigger } from "./ui/tooltip";
|
||||
|
||||
export default function ServerCard({ b, motd, mini, favs }: any) {
|
||||
const router = useRouter();
|
||||
@ -130,6 +132,13 @@ export default function ServerCard({ b, motd, mini, favs }: any) {
|
||||
/>
|
||||
)}
|
||||
</p>
|
||||
<br />
|
||||
<br />
|
||||
<strong className="text-sm font-semibold text-center">
|
||||
Joins Chart
|
||||
</strong>
|
||||
<MiniJoinsChart server={b.name} />
|
||||
|
||||
<div className="flex items-center pt-2">
|
||||
<span className="text-xs text-muted-foreground flex items-center">
|
||||
<ArrowRight size={16} className="mr-2" />
|
||||
@ -272,7 +281,7 @@ export default function ServerCard({ b, motd, mini, favs }: any) {
|
||||
</div>
|
||||
</ContextMenuItem>
|
||||
<ContextMenuSeparator />
|
||||
<Link href={"/server/" + b.name}>
|
||||
<Link href={"/src/app/(main)/server/" + b.name}>
|
||||
<ContextMenuItem>Open server page</ContextMenuItem>
|
||||
</Link>
|
||||
</ContextMenuContent>
|
||||
|
||||
@ -181,7 +181,7 @@ export default function ServerCustomize({
|
||||
Is this server in violation of the ECA?
|
||||
</div>
|
||||
Is this server in violation of the{" "}
|
||||
<Link href="/docs/legal/external-content-agreement">
|
||||
<Link href="/src/app/(main)/docs/legal/external-content-agreement">
|
||||
External Content Agreement (aka ECA)
|
||||
</Link>
|
||||
? You can report the server to remove the customizations from the
|
||||
@ -196,7 +196,7 @@ export default function ServerCustomize({
|
||||
<DialogDescription>
|
||||
This will send a notification to MHSF maintainers. This
|
||||
server must be in violation of the{" "}
|
||||
<Link href="/docs/legal/external-content-agreement">
|
||||
<Link href="/src/app/(main)/docs/legal/external-content-agreement">
|
||||
ECA
|
||||
</Link>{" "}
|
||||
to be a valid report. Typical response times include 1 hour
|
||||
@ -329,7 +329,7 @@ export default function ServerCustomize({
|
||||
Minehuts Terms of Service
|
||||
</Link>{" "}
|
||||
& the{" "}
|
||||
<Link href="/docs/legal/external-content-agreement">
|
||||
<Link href="/src/app/(main)/docs/legal/external-content-agreement">
|
||||
External Content Agreement
|
||||
</Link>
|
||||
.
|
||||
@ -436,7 +436,7 @@ export default function ServerCustomize({
|
||||
Imgurs Terms of Service
|
||||
</Link>{" "}
|
||||
& the{" "}
|
||||
<Link href="/docs/legal/external-content-agreement">
|
||||
<Link href="/src/app/(main)/docs/legal/external-content-agreement">
|
||||
External Content Agreement
|
||||
</Link>
|
||||
.
|
||||
@ -468,7 +468,7 @@ export default function ServerCustomize({
|
||||
Discords Terms of Service
|
||||
</Link>{" "}
|
||||
& the{" "}
|
||||
<Link href="/docs/legal/external-content-agreement">
|
||||
<Link href="/src/app/(main)/docs/legal/external-content-agreement">
|
||||
External Content Agreement
|
||||
</Link>
|
||||
.
|
||||
|
||||
@ -29,23 +29,8 @@
|
||||
*/
|
||||
|
||||
"use client";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { BorderBeam } from "@/components/effects/border-beam";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "./ui/badge";
|
||||
import ServersList from "@/lib/list";
|
||||
import {
|
||||
CircleUser,
|
||||
Network,
|
||||
Sun,
|
||||
Check,
|
||||
XIcon,
|
||||
Info,
|
||||
ArrowDownZA,
|
||||
LogIn,
|
||||
ImageIcon,
|
||||
} from "lucide-react";
|
||||
import Stat from "./Stat";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@ -54,23 +39,6 @@ import {
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import toast from "react-hot-toast";
|
||||
import { allTags, allCategories } from "@/config/tags";
|
||||
import IconDisplay from "./IconDisplay";
|
||||
import InfiniteScroll from "react-infinite-scroll-component";
|
||||
import { Spinner } from "./ui/spinner";
|
||||
import { CommandIcon } from "lucide-react";
|
||||
import { OnlineServer } from "@/lib/types/mh-server";
|
||||
import { useEffectOnce } from "@/lib/useEffectOnce";
|
||||
import ServerCard from "./ServerCard";
|
||||
import events from "@/lib/commandEvent";
|
||||
import { BorderBeam } from "@/components/effects/border-beam";
|
||||
import { useRouter } from "@/lib/useRouter";
|
||||
import {
|
||||
Menubar,
|
||||
MenubarCheckboxItem,
|
||||
@ -86,21 +54,53 @@ import {
|
||||
MenubarSubTrigger,
|
||||
MenubarTrigger,
|
||||
} from "@/components/ui/menubar";
|
||||
import ClientFadeIn from "./ClientFadeIn";
|
||||
import { Skeleton } from "./ui/skeleton";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { allCategories, allTags } from "@/config/tags";
|
||||
import events from "@/lib/commandEvent";
|
||||
import ServersList from "@/lib/list";
|
||||
import { OnlineServer } from "@/lib/types/mh-server";
|
||||
import useClipboard from "@/lib/useClipboard";
|
||||
import { SignedIn, SignedOut, useUser } from "@clerk/nextjs";
|
||||
import Link from "next/link";
|
||||
import SparklesText from "./effects/sparkles-text";
|
||||
import Particles from "./effects/particles";
|
||||
import { useTheme } from "next-themes";
|
||||
import { ChatBubbleIcon, InputIcon } from "@radix-ui/react-icons";
|
||||
import Marquee from "./effects/marquee";
|
||||
import { useEffectOnce } from "@/lib/useEffectOnce";
|
||||
import { useRouter } from "@/lib/useRouter";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
|
||||
import { SignedIn, SignedOut, useUser } from "@clerk/nextjs";
|
||||
import { ChatBubbleIcon, InputIcon } from "@radix-ui/react-icons";
|
||||
import {
|
||||
ArrowDownZA,
|
||||
Check,
|
||||
CircleUser,
|
||||
ImageIcon,
|
||||
Info,
|
||||
LogIn,
|
||||
Network,
|
||||
Sun,
|
||||
XIcon,
|
||||
} from "lucide-react";
|
||||
import { CommandIcon } from "lucide-react";
|
||||
import { useTheme } from "next-themes";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import InfiniteScroll from "react-infinite-scroll-component";
|
||||
import ClientFadeIn from "./ClientFadeIn";
|
||||
import IconDisplay from "./IconDisplay";
|
||||
import ServerCard from "./ServerCard";
|
||||
import Stat from "./Stat";
|
||||
import { SignInPopover } from "./clerk/SignInPopoverButton";
|
||||
import { BentoCard, BentoGrid } from "./effects/bento-grid";
|
||||
import Marquee from "./effects/marquee";
|
||||
import Particles from "./effects/particles";
|
||||
import SparklesText from "./effects/sparkles-text";
|
||||
import { pageFind } from "./misc/Link";
|
||||
import { Badge } from "./ui/badge";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
|
||||
import { Skeleton } from "./ui/skeleton";
|
||||
import { Spinner } from "./ui/spinner";
|
||||
|
||||
const features = [
|
||||
{
|
||||
@ -167,7 +167,7 @@ export default function ServerList() {
|
||||
Array<(server: OnlineServer) => Promise<boolean>>
|
||||
>([]);
|
||||
const [randomData, setRandomData] = useState<OnlineServer | undefined>(
|
||||
undefined
|
||||
undefined,
|
||||
);
|
||||
const { resolvedTheme } = useTheme();
|
||||
const [color, setColor] = useState("#ffffff");
|
||||
@ -258,7 +258,7 @@ export default function ServerList() {
|
||||
<div className="p-0 branding-hero">
|
||||
<>
|
||||
{(!isSignedIn || hero) && (
|
||||
<div className=" pb-[300px] relative mx-auto mt-20 max-w-7xl px-6 text-center md:px-8 ">
|
||||
<div className="pb-[300px] max-lg:pb-[1000px] max-md:pb-[1000px] relative mx-auto mt-20 max-w-7xl text-center md:px-8 ">
|
||||
<Particles
|
||||
className="absolute inset-0 -z-10 block"
|
||||
quantity={100}
|
||||
@ -349,7 +349,7 @@ export default function ServerList() {
|
||||
className={cn(
|
||||
"relative w-64 cursor-pointer overflow-hidden rounded-xl border no-underline " +
|
||||
"border-gray-950/[.1] bg-gray-950/[.01] hover:bg-gray-950/[.05] " +
|
||||
"dark:border-gray-50/[.1] dark:bg-gray-50/[.10] dark:hover:bg-gray-50/[.15]"
|
||||
"dark:border-gray-50/[.1] dark:bg-gray-50/[.10] dark:hover:bg-gray-50/[.15]",
|
||||
)}
|
||||
onClick={() =>
|
||||
router.push(pageFind(`Server:${server.name}`))
|
||||
@ -383,7 +383,7 @@ export default function ServerList() {
|
||||
className={cn(
|
||||
"relative w-64 cursor-pointer overflow-hidden rounded-xl border no-underline " +
|
||||
"border-gray-950/[.1] bg-gray-950/[.01] hover:bg-gray-950/[.05] " +
|
||||
"dark:border-gray-50/[.1] dark:bg-gray-50/[.10] dark:hover:bg-gray-50/[.15]"
|
||||
"dark:border-gray-50/[.1] dark:bg-gray-50/[.10] dark:hover:bg-gray-50/[.15]",
|
||||
)}
|
||||
onClick={() => router.push(`/server/${server.name}`)}
|
||||
>
|
||||
@ -566,7 +566,7 @@ export default function ServerList() {
|
||||
c.forEach(
|
||||
(b: { server: string; motd: string }) => {
|
||||
updatedSL[b.server] = b.motd;
|
||||
}
|
||||
},
|
||||
);
|
||||
setMotdList(updatedSL);
|
||||
setServers(serverList.currentServers);
|
||||
@ -582,7 +582,7 @@ export default function ServerList() {
|
||||
success: "Succesfully refreshed servers",
|
||||
loading: "Refreshing...",
|
||||
error: "Error while refreshing",
|
||||
}
|
||||
},
|
||||
);
|
||||
}}
|
||||
>
|
||||
@ -629,7 +629,7 @@ export default function ServerList() {
|
||||
c.forEach(
|
||||
(b: { server: string; motd: string }) => {
|
||||
updatedSL[b.server] = b.motd;
|
||||
}
|
||||
},
|
||||
);
|
||||
setMotdList(updatedSL);
|
||||
setServers(serverList.currentServers);
|
||||
@ -668,7 +668,7 @@ export default function ServerList() {
|
||||
c.forEach(
|
||||
(b: { server: string; motd: string }) => {
|
||||
updatedSL[b.server] = b.motd;
|
||||
}
|
||||
},
|
||||
);
|
||||
setMotdList(updatedSL);
|
||||
setServers(serverList.currentServers);
|
||||
@ -707,7 +707,7 @@ export default function ServerList() {
|
||||
c.forEach(
|
||||
(b: { server: string; motd: string }) => {
|
||||
updatedSL[b.server] = b.motd;
|
||||
}
|
||||
},
|
||||
);
|
||||
setMotdList(updatedSL);
|
||||
setServers(serverList.currentServers);
|
||||
@ -720,7 +720,7 @@ export default function ServerList() {
|
||||
error: "Error while changing filters",
|
||||
loading: "Changing filters...",
|
||||
success: "Changed filters!",
|
||||
}
|
||||
},
|
||||
);
|
||||
}}
|
||||
value={(() => {
|
||||
@ -804,7 +804,7 @@ export default function ServerList() {
|
||||
c.forEach(
|
||||
(b: { server: string; motd: string }) => {
|
||||
updatedSL[b.server] = b.motd;
|
||||
}
|
||||
},
|
||||
);
|
||||
setMotdList(updatedSL);
|
||||
setServers(serverList.currentServers);
|
||||
@ -901,7 +901,7 @@ export default function ServerList() {
|
||||
Change your preferences
|
||||
</Button>
|
||||
</span>,
|
||||
{ icon: "⚠️" }
|
||||
{ icon: "!" },
|
||||
);
|
||||
setIPR(v);
|
||||
}}
|
||||
@ -939,7 +939,7 @@ export default function ServerList() {
|
||||
Change your preferences
|
||||
</Button>
|
||||
</span>,
|
||||
{ icon: "⚠️" }
|
||||
{ icon: "!" },
|
||||
);
|
||||
setPadding(v);
|
||||
}}
|
||||
@ -1063,7 +1063,7 @@ export default function ServerList() {
|
||||
onClick={() => {
|
||||
setTextCopied(true);
|
||||
clipboard.writeText(
|
||||
randomData.name + ".mshf.minehut.gg"
|
||||
randomData.name + ".mshf.minehut.gg",
|
||||
);
|
||||
toast.success("Copied!");
|
||||
setTimeout(() => setTextCopied(false), 1000);
|
||||
|
||||
@ -30,17 +30,17 @@
|
||||
|
||||
"use client";
|
||||
import { ClerkProvider } from "@clerk/nextjs";
|
||||
import { useTheme } from "next-themes";
|
||||
import { dark } from "@clerk/themes";
|
||||
import { useTheme } from "next-themes";
|
||||
import { type ReactNode, useEffect, useState } from "react";
|
||||
import { ThemeProvider } from "../ThemeProvider";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function ClerkThemeProvider({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: JSX.Element;
|
||||
className: string;
|
||||
children: ReactNode | ReactNode[];
|
||||
className: string | undefined;
|
||||
}) {
|
||||
const [theme, setTheme] = useState<string | undefined>("");
|
||||
|
||||
|
||||
199
src/components/docs/NavUser.tsx
Normal file
199
src/components/docs/NavUser.tsx
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* MHSF, Minehut Server List
|
||||
* All external content is rather licensed under the ECA Agreement
|
||||
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
|
||||
*
|
||||
* All code under MHSF is licensed under the MIT License
|
||||
* by open source contributors
|
||||
*
|
||||
* Copyright (c) 2024 dvelo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
"use client";
|
||||
|
||||
import {
|
||||
BadgeCheck,
|
||||
Bell,
|
||||
ChevronsUpDown,
|
||||
Computer,
|
||||
CreditCard,
|
||||
LogIn,
|
||||
LogOut,
|
||||
Moon,
|
||||
SettingsIcon,
|
||||
Sparkles,
|
||||
Sun,
|
||||
} from "lucide-react";
|
||||
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuPortal,
|
||||
DropdownMenuRadioGroup,
|
||||
DropdownMenuRadioItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuSub,
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import {
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
useSidebar,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { useClerk, useUser } from "@clerk/nextjs";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
export function NavUser() {
|
||||
const { isMobile } = useSidebar();
|
||||
const { user, isSignedIn } = useUser();
|
||||
const clerk = useClerk();
|
||||
const { setTheme, theme } = useTheme();
|
||||
|
||||
return (
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<SidebarMenuButton
|
||||
size="lg"
|
||||
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||
>
|
||||
{isSignedIn && (
|
||||
<Avatar className="h-8 w-8 rounded-lg">
|
||||
<AvatarImage
|
||||
src={
|
||||
user?.imageUrl == undefined
|
||||
? "https://img.clerk.com/preview.png?size=144&seed=seed&initials=AD&isSquare=true&bgType=marble&bgColor=6c47ff&fgType=silhouette&fgColor=FFFFFF&type=user&w=48&q=75"
|
||||
: user?.imageUrl
|
||||
}
|
||||
alt={user?.username || "?"}
|
||||
/>
|
||||
<AvatarFallback className="rounded-lg">?</AvatarFallback>
|
||||
</Avatar>
|
||||
)}
|
||||
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-semibold">
|
||||
{isSignedIn ? user?.username : "Not logged in"}
|
||||
</span>
|
||||
<span className="truncate text-xs">
|
||||
{user?.primaryEmailAddress?.emailAddress}
|
||||
</span>
|
||||
</div>
|
||||
<ChevronsUpDown className="ml-auto size-4" />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
className="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg"
|
||||
side={isMobile ? "bottom" : "right"}
|
||||
align="end"
|
||||
sideOffset={4}
|
||||
>
|
||||
{isSignedIn && (
|
||||
<>
|
||||
<DropdownMenuLabel className="p-0 font-normal">
|
||||
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
||||
<Avatar className="h-8 w-8 rounded-lg">
|
||||
<AvatarImage
|
||||
src={
|
||||
user?.imageUrl == undefined
|
||||
? "https://img.clerk.com/preview.png?size=144&seed=seed&initials=AD&isSquare=true&bgType=marble&bgColor=6c47ff&fgType=silhouette&fgColor=FFFFFF&type=user&w=48&q=75"
|
||||
: user?.imageUrl
|
||||
}
|
||||
alt={user?.username || "?"}
|
||||
/>
|
||||
<AvatarFallback className="rounded-lg">?</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-semibold">
|
||||
{user?.username}
|
||||
</span>
|
||||
<span className="truncate text-xs">
|
||||
{user?.primaryEmailAddress?.emailAddress}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
)}
|
||||
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuRadioGroup
|
||||
onValueChange={(c) => setTheme(c)}
|
||||
value={theme}
|
||||
>
|
||||
<DropdownMenuRadioItem value="dark">
|
||||
<Moon /> Dark
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="light">
|
||||
<Sun /> Light
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="system">
|
||||
<Computer /> System
|
||||
</DropdownMenuRadioItem>
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuGroup>
|
||||
|
||||
{isSignedIn && (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem onSelect={() => clerk.openUserProfile()}>
|
||||
<SettingsIcon />
|
||||
Account Settings
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
className="text-red-500"
|
||||
onSelect={() => clerk.signOut()}
|
||||
>
|
||||
<LogOut />
|
||||
Log out
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
</>
|
||||
)}
|
||||
{!isSignedIn && (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem onSelect={() => clerk.openSignIn()}>
|
||||
<LogIn />
|
||||
Sign in
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
</>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
);
|
||||
}
|
||||
@ -1,134 +1,51 @@
|
||||
/*
|
||||
* MHSF, Minehut Server List
|
||||
* All external content is rather licensed under the ECA Agreement
|
||||
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
|
||||
*
|
||||
* All code under MHSF is licensed under the MIT License
|
||||
* by open source contributors
|
||||
*
|
||||
* Copyright (c) 2024 dvelo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
"use client";
|
||||
import { allFolders, Docs, DocsFolder } from "@/config/docs";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { Button } from "../ui/button";
|
||||
import { useState } from "react";
|
||||
import { ChevronRight } from "lucide-react";
|
||||
import { useRouter } from "@/lib/useRouter";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { NavUser } from "@/components/docs/NavUser";
|
||||
import { VersionSwitcher } from "@/components/docs/VersionSwitcher";
|
||||
import {
|
||||
Sidebar as ShadSidebar,
|
||||
SidebarContent,
|
||||
SidebarFooter,
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarGroupLabel,
|
||||
SidebarHeader,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
SidebarRail,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { allFolders } from "@/config/docs";
|
||||
|
||||
export function Sidebar() {
|
||||
return (
|
||||
<>
|
||||
{allFolders.map((docs) => (
|
||||
<Folder docs={docs} key={"url" in docs ? docs.title : docs.name} />
|
||||
<ShadSidebar>
|
||||
<SidebarHeader>
|
||||
<VersionSwitcher />
|
||||
</SidebarHeader>
|
||||
<SidebarContent>
|
||||
{/* We create a SidebarGroup for each parent. */}
|
||||
{allFolders.map((item) => (
|
||||
<SidebarGroup key={item.name}>
|
||||
<SidebarGroupLabel>{item.name}</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{item.docs.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.url}>{item.title}</a>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Folder({ docs }: { docs: any }) {
|
||||
const [folderOpen, setOpen] = useState(false);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<div key={"url" in docs ? docs.title : docs.name}>
|
||||
<Button
|
||||
size="sm"
|
||||
className="w-full font-normal tracking-normal mt-1"
|
||||
noJustify
|
||||
variant={
|
||||
"url" in docs
|
||||
? pathname === docs.url
|
||||
? "default"
|
||||
: "ghost"
|
||||
: "ghost"
|
||||
}
|
||||
onClick={() => {
|
||||
if ("docs" in docs) {
|
||||
setOpen(!folderOpen);
|
||||
} else {
|
||||
router.push(docs.url);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{"url" in docs ? docs.title : docs.name}
|
||||
<div className="flex items-center ml-auto text-muted-foreground">
|
||||
<AnimatePresence>
|
||||
{"docs" in docs && folderOpen && (
|
||||
<motion.div initial={{ rotate: 90 }} animate={{ rotate: 0 }}>
|
||||
<ChevronRight size={18} />
|
||||
</motion.div>
|
||||
)}
|
||||
{"docs" in docs && !folderOpen && (
|
||||
<motion.div initial={{ rotate: 0 }} animate={{ rotate: 90 }}>
|
||||
<ChevronRight size={18} />
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
</Button>
|
||||
<div className="ml-2">
|
||||
{folderOpen && <Subdocs docs={"docs" in docs ? docs.docs : []} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Subdocs({ docs }: { docs: (Docs | DocsFolder)[] }) {
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
return (
|
||||
<>
|
||||
{docs.map((doc) => {
|
||||
if ("docs" in doc) {
|
||||
return <Subdocs docs={doc.docs} key={doc.name} />;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
size="sm"
|
||||
className="w-full font-normal tracking-normal mt-1"
|
||||
noJustify
|
||||
onClick={() => {
|
||||
router.push(doc.url);
|
||||
}}
|
||||
key={doc.title}
|
||||
variant={
|
||||
"url" in doc
|
||||
? pathname == doc.url
|
||||
? "default"
|
||||
: "ghost"
|
||||
: "ghost"
|
||||
}
|
||||
>
|
||||
{doc.title}
|
||||
</Button>
|
||||
<br key={doc.url} />
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
))}
|
||||
</SidebarContent>
|
||||
<SidebarFooter>
|
||||
<NavUser />
|
||||
</SidebarFooter>
|
||||
<SidebarRail />
|
||||
</ShadSidebar>
|
||||
);
|
||||
}
|
||||
|
||||
@ -28,17 +28,17 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Button } from "../ui/button";
|
||||
import { Book, Calendar, Star, TerminalIcon } from "lucide-react";
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog";
|
||||
import { useState } from "react";
|
||||
import { Changelog, version } from "@/config/version";
|
||||
import { Changelog } from "@/components/changelog";
|
||||
import { changelog, version } from "@/config/version";
|
||||
import events from "@/lib/commandEvent";
|
||||
import { ScrollArea } from "../ui/scroll-area";
|
||||
import { useRouter } from "@/lib/useRouter";
|
||||
import { Book, Calendar, Star, TerminalIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Button } from "../ui/button";
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog";
|
||||
import { ScrollArea } from "../ui/scroll-area";
|
||||
|
||||
export default function InfoPopover() {
|
||||
const [changeLog, setChangelog] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
@ -51,19 +51,11 @@ export default function InfoPopover() {
|
||||
<small>* Licensed under the MIT License</small>
|
||||
</small>
|
||||
|
||||
<Button variant={"ghost"} onClick={() => setChangelog(true)}>
|
||||
<Changelog items={changelog}>
|
||||
<Button variant={"ghost"}>
|
||||
<Calendar size={18} className="mr-2" /> Changelog
|
||||
</Button>
|
||||
<Dialog open={changeLog} onOpenChange={setChangelog}>
|
||||
<DialogContent>
|
||||
<ScrollArea className="max-h-[500px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Changelog</DialogTitle>
|
||||
<Changelog />
|
||||
</DialogHeader>
|
||||
</ScrollArea>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</Changelog>
|
||||
|
||||
<Button
|
||||
variant={"ghost"}
|
||||
|
||||
111
src/components/misc/MiniJoinsChart.tsx
Normal file
111
src/components/misc/MiniJoinsChart.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* MHSF, Minehut Server List
|
||||
* All external content is rather licensed under the ECA Agreement
|
||||
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
|
||||
*
|
||||
* All code under MHSF is licensed under the MIT License
|
||||
* by open source contributors
|
||||
*
|
||||
* Copyright (c) 2024 dvelo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import {
|
||||
type ChartConfig,
|
||||
ChartContainer,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from "@/components/ui/chart";
|
||||
import { getShortTermData } from "@/lib/api";
|
||||
import { useEffectOnce } from "@/lib/useEffectOnce";
|
||||
import * as React from "react";
|
||||
import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts";
|
||||
|
||||
const chartConfig = {
|
||||
player_count: {
|
||||
label: "Joins",
|
||||
color: "hsl(var(--chart-1))",
|
||||
},
|
||||
} satisfies ChartConfig;
|
||||
|
||||
export function MiniJoinsChart({ server }: { server: string }) {
|
||||
const [chartData, setChartData] = React.useState<any>([]);
|
||||
const [loading, setLoading] = React.useState(true);
|
||||
|
||||
useEffectOnce(() => {
|
||||
getShortTermData(server, ["player_count", "date"]).then((result) => {
|
||||
setChartData(result.slice(-20));
|
||||
setLoading(false);
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="max-h-[160px] w-full">
|
||||
<ChartContainer config={chartConfig}>
|
||||
<LineChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<YAxis
|
||||
dataKey={"player_count"}
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => {
|
||||
return value;
|
||||
}}
|
||||
/>
|
||||
<XAxis
|
||||
dataKey="date"
|
||||
className="hidden"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
minTickGap={32}
|
||||
tickFormatter={(value) => {
|
||||
return new Date(value).toLocaleTimeString("en-US", {
|
||||
timeStyle: "short",
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<ChartTooltip
|
||||
content={
|
||||
<ChartTooltipContent
|
||||
className="w-[150px]"
|
||||
nameKey={"player_count"}
|
||||
indicator="line"
|
||||
labelFormatter={(value) => {
|
||||
return new Date(value).toLocaleTimeString("en-US", {
|
||||
timeStyle: "short",
|
||||
});
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Line
|
||||
dataKey={"player_count"}
|
||||
type="monotone"
|
||||
stroke={"var(--color-player_count)"}
|
||||
strokeWidth={2}
|
||||
dot={false}
|
||||
/>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -28,30 +28,30 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
"use client"
|
||||
"use client";
|
||||
|
||||
import * as React from "react"
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
|
||||
import { Check, ChevronRight, Circle } from "lucide-react"
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
||||
import { Check, ChevronRight, Circle } from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const DropdownMenu = DropdownMenuPrimitive.Root
|
||||
const DropdownMenu = DropdownMenuPrimitive.Root;
|
||||
|
||||
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
|
||||
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
||||
|
||||
const DropdownMenuGroup = DropdownMenuPrimitive.Group
|
||||
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
||||
|
||||
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
|
||||
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
||||
|
||||
const DropdownMenuSub = DropdownMenuPrimitive.Sub
|
||||
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
||||
|
||||
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
|
||||
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
||||
|
||||
const DropdownMenuSubTrigger = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
|
||||
inset?: boolean
|
||||
inset?: boolean;
|
||||
}
|
||||
>(({ className, inset, children, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
@ -59,16 +59,16 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
||||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
|
||||
inset && "pl-8",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronRight className="ml-auto h-4 w-4" />
|
||||
</DropdownMenuPrimitive.SubTrigger>
|
||||
))
|
||||
));
|
||||
DropdownMenuSubTrigger.displayName =
|
||||
DropdownMenuPrimitive.SubTrigger.displayName
|
||||
DropdownMenuPrimitive.SubTrigger.displayName;
|
||||
|
||||
const DropdownMenuSubContent = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
||||
@ -78,13 +78,13 @@ const DropdownMenuSubContent = React.forwardRef<
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
));
|
||||
DropdownMenuSubContent.displayName =
|
||||
DropdownMenuPrimitive.SubContent.displayName
|
||||
DropdownMenuPrimitive.SubContent.displayName;
|
||||
|
||||
const DropdownMenuContent = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
||||
@ -96,31 +96,31 @@ const DropdownMenuContent = React.forwardRef<
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</DropdownMenuPrimitive.Portal>
|
||||
))
|
||||
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
|
||||
));
|
||||
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
||||
|
||||
const DropdownMenuItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
||||
inset?: boolean
|
||||
inset?: boolean;
|
||||
}
|
||||
>(({ className, inset, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
inset && "pl-8",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
|
||||
));
|
||||
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
||||
|
||||
const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
||||
@ -130,7 +130,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
{...props}
|
||||
@ -142,9 +142,9 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
</span>
|
||||
{children}
|
||||
</DropdownMenuPrimitive.CheckboxItem>
|
||||
))
|
||||
));
|
||||
DropdownMenuCheckboxItem.displayName =
|
||||
DropdownMenuPrimitive.CheckboxItem.displayName
|
||||
DropdownMenuPrimitive.CheckboxItem.displayName;
|
||||
|
||||
const DropdownMenuRadioItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
||||
@ -153,8 +153,8 @@ const DropdownMenuRadioItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0 gap-3",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
@ -165,13 +165,13 @@ const DropdownMenuRadioItem = React.forwardRef<
|
||||
</span>
|
||||
{children}
|
||||
</DropdownMenuPrimitive.RadioItem>
|
||||
))
|
||||
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
|
||||
));
|
||||
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
||||
|
||||
const DropdownMenuLabel = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
||||
inset?: boolean
|
||||
inset?: boolean;
|
||||
}
|
||||
>(({ className, inset, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Label
|
||||
@ -179,12 +179,12 @@ const DropdownMenuLabel = React.forwardRef<
|
||||
className={cn(
|
||||
"px-2 py-1.5 text-sm font-semibold",
|
||||
inset && "pl-8",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
|
||||
));
|
||||
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
||||
|
||||
const DropdownMenuSeparator = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
||||
@ -195,8 +195,8 @@ const DropdownMenuSeparator = React.forwardRef<
|
||||
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
|
||||
));
|
||||
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
||||
|
||||
const DropdownMenuShortcut = ({
|
||||
className,
|
||||
@ -207,9 +207,9 @@ const DropdownMenuShortcut = ({
|
||||
className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
|
||||
);
|
||||
};
|
||||
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
||||
|
||||
export {
|
||||
DropdownMenu,
|
||||
@ -227,4 +227,4 @@ export {
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuRadioGroup,
|
||||
}
|
||||
};
|
||||
|
||||
@ -28,19 +28,20 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
export const allFolders: (DocsFolder | Docs)[] = [
|
||||
export const allFolders: DocsFolder[] = [
|
||||
{
|
||||
name: "General",
|
||||
docs: [
|
||||
{
|
||||
title: "Getting Started",
|
||||
url: "/docs/getting-started",
|
||||
},
|
||||
{
|
||||
title: "Server List",
|
||||
url: "/",
|
||||
},
|
||||
{
|
||||
title: "Reading",
|
||||
url: "/docs/reading",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Guides",
|
||||
docs: [
|
||||
|
||||
@ -278,7 +278,7 @@ export const allCategories: Array<{
|
||||
];
|
||||
|
||||
async function requestServer(s: OnlineServer): Promise<ServerResponse> {
|
||||
if (serverCache[s.name] == undefined) {
|
||||
if (serverCache[s.name] === undefined) {
|
||||
const re = await fetch(
|
||||
"https://api.minehut.com/server/" + s.name + "?byName=true",
|
||||
);
|
||||
|
||||
@ -29,149 +29,73 @@
|
||||
*/
|
||||
|
||||
"use client";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { Separator } from "../components/ui/separator";
|
||||
import { Button } from "../components/ui/button";
|
||||
import confetti from "canvas-confetti";
|
||||
|
||||
export const version = "1.3.2";
|
||||
import A from "@/components/misc/Link";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
const User = ({ user }: { user: string }) => (
|
||||
<span className="cursor-pointer bg-[rgba(255,165,0,0.25);] rounded p-[2.5px]">
|
||||
{user}
|
||||
</span>
|
||||
);
|
||||
const handleClick = () => {
|
||||
const duration = 5 * 1000;
|
||||
const animationEnd = Date.now() + duration;
|
||||
const defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: 0 };
|
||||
|
||||
const randomInRange = (min: number, max: number) =>
|
||||
Math.random() * (max - min) + min;
|
||||
|
||||
const interval = window.setInterval(() => {
|
||||
const timeLeft = animationEnd - Date.now();
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
return clearInterval(interval);
|
||||
}
|
||||
|
||||
const particleCount = 50 * (timeLeft / duration);
|
||||
confetti({
|
||||
...defaults,
|
||||
particleCount,
|
||||
zIndex: 60,
|
||||
origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 },
|
||||
});
|
||||
confetti({
|
||||
...defaults,
|
||||
particleCount,
|
||||
zIndex: 60,
|
||||
origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 },
|
||||
});
|
||||
}, 250);
|
||||
};
|
||||
export const Changelog = () => {
|
||||
const router = useRouter();
|
||||
const FeatureList = ({
|
||||
features,
|
||||
title,
|
||||
}: { features: (string | ReactNode)[]; title: ReactNode }) => {
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
Running on commit{" "}
|
||||
<code>
|
||||
<a
|
||||
href={`https://github.com/DeveloLongScript/mhsf/commit/${process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA}`}
|
||||
>
|
||||
{(
|
||||
process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA || "unknown"
|
||||
).substring(0, 7)}
|
||||
</a>{" "}
|
||||
{process.env.NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID != undefined &&
|
||||
process.env.NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID != "" && (
|
||||
<>
|
||||
{" "}
|
||||
| on PR{" "}
|
||||
<a
|
||||
href={`https://github.com/DeveloLongScript/MHSF/pull/${process.env.NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID}`}
|
||||
>
|
||||
{process.env.NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID}
|
||||
</a>{" "}
|
||||
by{" "}
|
||||
<a
|
||||
href={`https://github.com/${process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME}`}
|
||||
>
|
||||
{process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME}
|
||||
</a>
|
||||
</>
|
||||
)}{" "}
|
||||
{process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE != undefined &&
|
||||
`| ${process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE.substring(0, 24)}`}
|
||||
</code>
|
||||
</div>
|
||||
<div className="md:grid md:grid-cols-3 gap-1.5">
|
||||
<Button
|
||||
className="text-sm hover:h-[60px] animate-all group block max-md:w-full max-md:mt-2"
|
||||
onClick={() =>
|
||||
window.open("https://discord.com/invite/cCyEeUs", "_blank")
|
||||
<ul>
|
||||
{title}
|
||||
{features.map((feature, i) => (
|
||||
<li key={i}>• {feature}</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
export const version = "1.4.0";
|
||||
export const changelog: { name: string; id: string; changelog: ReactNode }[] = [
|
||||
{
|
||||
id: "amq4suhgcfwrb7y5j6",
|
||||
name: "v1.4.0",
|
||||
changelog: (
|
||||
<FeatureList
|
||||
features={[
|
||||
"Revamped documentation",
|
||||
"Revamped changelog UI",
|
||||
"New hover joins chart",
|
||||
]}
|
||||
title={
|
||||
<strong className="flex items-center">
|
||||
Version 1.4.0 (November 3rd 2024)
|
||||
</strong>
|
||||
}
|
||||
>
|
||||
<span className="group-hover:underline flex items-center">
|
||||
<Discord className="mr-2"/> Discord
|
||||
</span>
|
||||
<Marquee
|
||||
className="hidden group-hover:flex font-normal"
|
||||
style={{"--duration": "15s"}}
|
||||
>
|
||||
Join the offical Minehut Discord server! Talk to people that like
|
||||
MHSF too!
|
||||
</Marquee>
|
||||
</Button>
|
||||
<Button
|
||||
className="text-sm max-md:w-full max-md:mt-2 hover:h-[60px] animate-all group block "
|
||||
onClick={() =>
|
||||
window.open("https://github.com/DeveloLongScript/MHSF", "_blank")
|
||||
}
|
||||
>
|
||||
<span className="group-hover:underline flex items-center">
|
||||
<Github className="mr-2" fill={useDepTheme()}/> Star on GitHub
|
||||
</span>
|
||||
<Marquee
|
||||
className="hidden group-hover:flex font-normal"
|
||||
style={{"--duration": "10s"}}
|
||||
>
|
||||
Support the development of MHSF by starring it on GitHub!
|
||||
</Marquee>
|
||||
</Button>
|
||||
<Button
|
||||
className="text-sm max-md:w-full max-md:mt-2 hover:h-[60px] animate-all group block "
|
||||
onClick={() => window.open("/docs", "_blank")}
|
||||
>
|
||||
<span className="group-hover:underline flex items-center">
|
||||
<BookIcon className="mr-2" size={16}/> See the docs
|
||||
</span>
|
||||
<Marquee
|
||||
className="hidden group-hover:flex font-normal"
|
||||
style={{"--duration": "10s"}}
|
||||
>
|
||||
See more information about MHSF and how to use it
|
||||
</Marquee>
|
||||
</Button>
|
||||
</div>
|
||||
<br/>
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "jeh48p7w9bx2k3ad6f",
|
||||
name: "v1.3.2",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version 1.3.2 (October 4th 2024)
|
||||
</strong>
|
||||
<ul>
|
||||
<li>• Minor backend changes</li>
|
||||
<li>
|
||||
• Minor backend changes
|
||||
</li>
|
||||
<li>
|
||||
• <A alt="Please check on GitHub for statuses about this project.">Special:GitHub/releases/tag/1.3.2</A>
|
||||
•{" "}
|
||||
<A alt="Please check on GitHub for statuses about this project.">
|
||||
Special:GitHub/releases/tag/1.3.2
|
||||
</A>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "wvg9x5dbpj76sn4yrz",
|
||||
name: "v1.3.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version 1.3.0 (September 9th 2024)
|
||||
@ -188,7 +112,11 @@ export const Changelog = () => {
|
||||
<li>• Overhauled account preferences</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "v1.2.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version 1.2.0 (September 3rd 2024)
|
||||
@ -200,7 +128,12 @@ export const Changelog = () => {
|
||||
<li>• and alot more!</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "e482y9k5hvjt73urfx",
|
||||
},
|
||||
{
|
||||
name: "v1.1.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version 1.1.0 (August 24rd 2024)
|
||||
@ -211,27 +144,29 @@ export const Changelog = () => {
|
||||
<li>• New help guide</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "hfn9p243765x8bwurj",
|
||||
},
|
||||
{
|
||||
name: "v1.0.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version 1.0.0 (August 22nd 2024)
|
||||
</strong>
|
||||
<ul>
|
||||
<li>
|
||||
• 1.0!{" "}
|
||||
<Button className="h-[25px] w-[50px] ml-2" onClick={handleClick}>
|
||||
woah!
|
||||
</Button>
|
||||
</li>
|
||||
<li>• 1.0!</li>
|
||||
<li>• New hover card on server title hover</li>
|
||||
<li>• Moving to self-hosted cron jobs</li>
|
||||
<li>• Fixing some mobile issues</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
<Separator/>
|
||||
|
||||
<br/>
|
||||
),
|
||||
id: "a8w4xvjbg3s7ynehu6",
|
||||
},
|
||||
{
|
||||
name: "v0.10.7",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.10.7 (August 18th 2024)
|
||||
@ -240,7 +175,12 @@ export const Changelog = () => {
|
||||
<li>• New server information tab on server pages</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "asbt64h9fdyu8neqmp",
|
||||
},
|
||||
{
|
||||
name: "v0.10.2",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.10.2 (August 18th 2024)
|
||||
@ -250,7 +190,12 @@ export const Changelog = () => {
|
||||
<li>• Instead of using spinners, now we are using Skeletons</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "kct29adbp6zug5r3q8",
|
||||
},
|
||||
{
|
||||
name: "v0.10.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.10.0 (August 17th 2024)
|
||||
@ -264,15 +209,19 @@ export const Changelog = () => {
|
||||
</li>
|
||||
<li>• Improved MOTD engine</li>
|
||||
</ul>
|
||||
<br/>
|
||||
<br />
|
||||
<i>👀</i>
|
||||
{/** Ensure Tailwind pre-renders all grid column types */}
|
||||
<span className="grid-cols-6"/>
|
||||
<span className="grid-cols-5"/>
|
||||
<span className="grid-cols-4"/>
|
||||
<span className="grid-cols-6" />
|
||||
<span className="grid-cols-5" />
|
||||
<span className="grid-cols-4" />
|
||||
</div>
|
||||
<br/>
|
||||
<br/>
|
||||
),
|
||||
id: "ah6t7c8sfzyrkp3u52",
|
||||
},
|
||||
{
|
||||
name: "v0.9.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.9.0 (August 15th 2024)
|
||||
@ -282,16 +231,21 @@ export const Changelog = () => {
|
||||
<li>• Fixed right-click context menu on the server list</li>
|
||||
<li>• Fixed metadata bugs</li>
|
||||
</ul>
|
||||
<br/>
|
||||
<br />
|
||||
<i>
|
||||
Hey! Update on statistics. Recently, we have figured out the Minehut
|
||||
API is blocked to Vercel servers (atleast the <code>/servers</code>{" "}
|
||||
endpoint). I'm actively trying to find a loop-hole so that statistics
|
||||
works correctly. Thank you {":)"}
|
||||
</i>
|
||||
<br/>
|
||||
<br />
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "kjxnrfazc7hp9q4e82",
|
||||
},
|
||||
{
|
||||
name: "v0.8.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.8.0 (August 11th 2024)
|
||||
@ -301,7 +255,12 @@ export const Changelog = () => {
|
||||
<li>• Renaming "Short Term" to "Statistics"</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "f8rmhwzuxk3qyds542",
|
||||
},
|
||||
{
|
||||
name: "v0.7.2",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.7.2 (August 7th 2024)
|
||||
@ -312,7 +271,12 @@ export const Changelog = () => {
|
||||
<li>• Moved from Inngest to Vercel Cron</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "g2rhxfj6bu8wqk43n7",
|
||||
},
|
||||
{
|
||||
name: "v0.7.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.7.0 (August 7th 2024)
|
||||
@ -323,7 +287,12 @@ export const Changelog = () => {
|
||||
<li>• Lots of bugfixes</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "a5xb97jv3surwmqn62",
|
||||
},
|
||||
{
|
||||
name: "v0.6.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.6.0 (August 3rd 2024)
|
||||
@ -335,7 +304,12 @@ export const Changelog = () => {
|
||||
<li>• Lots of bugfixes</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "u83r5mkea9x4p2fjnb",
|
||||
},
|
||||
{
|
||||
name: "v0.4.5",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.4.5 (July 26th 2024):
|
||||
@ -345,7 +319,12 @@ export const Changelog = () => {
|
||||
<li>• Sorted API endpoints</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "vu3k2daqj4y68bnwsp",
|
||||
},
|
||||
{
|
||||
name: "v0.4.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.4 (July 25th 2024):
|
||||
@ -359,18 +338,28 @@ export const Changelog = () => {
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "psr9tx5jah74d32vq6",
|
||||
},
|
||||
{
|
||||
name: "v0.3.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.3 (July 23th 2024):
|
||||
</strong>
|
||||
<ul>
|
||||
<li>
|
||||
• Fixed minor bugs described by <User user="@Tarna"/>
|
||||
• Fixed minor bugs described by <User user="@Tarna" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
),
|
||||
id: "m2ngpd6fwtv7xh5zrk",
|
||||
},
|
||||
{
|
||||
name: "v0.2.0",
|
||||
changelog: (
|
||||
<div>
|
||||
<strong className="flex items-center">
|
||||
Version b-0.2 (July 23th 2024):
|
||||
@ -379,57 +368,7 @@ export const Changelog = () => {
|
||||
<li>• Inital release!</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
<div>
|
||||
<strong>All developers that helped out:</strong>
|
||||
<Link href="https://dvelo.vercel.app">
|
||||
<Image
|
||||
src="/imgs/badge1.gif"
|
||||
alt="cool badge"
|
||||
width={88}
|
||||
height={31}
|
||||
className="w-[88px] h-[31px]"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const Github = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
viewBox="0 0 256 250"
|
||||
width="1em"
|
||||
height="1em"
|
||||
fill="#24292f"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M128.001 0C57.317 0 0 57.307 0 128.001c0 56.554 36.676 104.535 87.535 121.46 6.397 1.185 8.746-2.777 8.746-6.158 0-3.052-.12-13.135-.174-23.83-35.61 7.742-43.124-15.103-43.124-15.103-5.823-14.795-14.213-18.73-14.213-18.73-11.613-7.944.876-7.78.876-7.78 12.853.902 19.621 13.19 19.621 13.19 11.417 19.568 29.945 13.911 37.249 10.64 1.149-8.272 4.466-13.92 8.127-17.116-28.431-3.236-58.318-14.212-58.318-63.258 0-13.975 5-25.394 13.188-34.358-1.329-3.224-5.71-16.242 1.24-33.874 0 0 10.749-3.44 35.21 13.121 10.21-2.836 21.16-4.258 32.038-4.307 10.878.049 21.837 1.47 32.066 4.307 24.431-16.56 35.165-13.12 35.165-13.12 6.967 17.63 2.584 30.65 1.255 33.873 8.207 8.964 13.173 20.383 13.173 34.358 0 49.163-29.944 59.988-58.447 63.157 4.591 3.972 8.682 11.762 8.682 23.704 0 17.126-.148 30.91-.148 35.126 0 3.407 2.304 7.398 8.792 6.14C219.37 232.5 256 184.537 256 128.002 256 57.307 198.691 0 128.001 0Zm-80.06 182.34c-.282.636-1.283.827-2.194.39-.929-.417-1.45-1.284-1.15-1.922.276-.655 1.279-.838 2.205-.399.93.418 1.46 1.293 1.139 1.931Zm6.296 5.618c-.61.566-1.804.303-2.614-.591-.837-.892-.994-2.086-.375-2.66.63-.566 1.787-.301 2.626.591.838.903 1 2.088.363 2.66Zm4.32 7.188c-.785.545-2.067.034-2.86-1.104-.784-1.138-.784-2.503.017-3.05.795-.547 2.058-.055 2.861 1.075.782 1.157.782 2.522-.019 3.08Zm7.304 8.325c-.701.774-2.196.566-3.29-.49-1.119-1.032-1.43-2.496-.726-3.27.71-.776 2.213-.558 3.315.49 1.11 1.03 1.45 2.505.701 3.27Zm9.442 2.81c-.31 1.003-1.75 1.459-3.199 1.033-1.448-.439-2.395-1.613-2.103-2.626.301-1.01 1.747-1.484 3.207-1.028 1.446.436 2.396 1.602 2.095 2.622Zm10.744 1.193c.036 1.055-1.193 1.93-2.715 1.95-1.53.034-2.769-.82-2.786-1.86 0-1.065 1.202-1.932 2.733-1.958 1.522-.03 2.768.818 2.768 1.868Zm10.555-.405c.182 1.03-.875 2.088-2.387 2.37-1.485.271-2.861-.365-3.05-1.386-.184-1.056.893-2.114 2.376-2.387 1.514-.263 2.868.356 3.061 1.403Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
import type { SVGProps } from "react";
|
||||
import Marquee from "@/components/effects/marquee";
|
||||
import { useRouter } from "@/lib/useRouter";
|
||||
import { BookIcon } from "lucide-react";
|
||||
import A from "@/components/misc/Link";
|
||||
import { useDepTheme } from "@/lib/getDependentTheming";
|
||||
const Discord = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
viewBox="0 0 256 199"
|
||||
width="1em"
|
||||
height="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M216.856 16.597A208.502 208.502 0 0 0 164.042 0c-2.275 4.113-4.933 9.645-6.766 14.046-19.692-2.961-39.203-2.961-58.533 0-1.832-4.4-4.55-9.933-6.846-14.046a207.809 207.809 0 0 0-52.855 16.638C5.618 67.147-3.443 116.4 1.087 164.956c22.169 16.555 43.653 26.612 64.775 33.193A161.094 161.094 0 0 0 79.735 175.3a136.413 136.413 0 0 1-21.846-10.632 108.636 108.636 0 0 0 5.356-4.237c42.122 19.702 87.89 19.702 129.51 0a131.66 131.66 0 0 0 5.355 4.237 136.07 136.07 0 0 1-21.886 10.653c4.006 8.02 8.638 15.67 13.873 22.848 21.142-6.58 42.646-16.637 64.815-33.213 5.316-56.288-9.08-105.09-38.056-148.36ZM85.474 135.095c-12.645 0-23.015-11.805-23.015-26.18s10.149-26.2 23.015-26.2c12.867 0 23.236 11.804 23.015 26.2.02 14.375-10.148 26.18-23.015 26.18Zm85.051 0c-12.645 0-23.014-11.805-23.014-26.18s10.148-26.2 23.014-26.2c12.867 0 23.236 11.804 23.015 26.2 0 14.375-10.148 26.18-23.015 26.18Z"
|
||||
fill="#5865F2"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
),
|
||||
id: "xsfw2rcnv7m3kuhpbq",
|
||||
},
|
||||
];
|
||||
|
||||
@ -30,10 +30,14 @@
|
||||
|
||||
import { LinearClient, LinearFetch, User } from "@linear/sdk";
|
||||
|
||||
export async function createReportIssue(server: string, reportDescription: string, userId: string) {
|
||||
export async function createReportIssue(
|
||||
server: string,
|
||||
reportDescription: string,
|
||||
userId: string,
|
||||
) {
|
||||
const linearClient = new LinearClient({
|
||||
apiKey: process.env.LINEAR
|
||||
})
|
||||
apiKey: process.env.LINEAR,
|
||||
});
|
||||
|
||||
const allTeams = await linearClient.teams();
|
||||
// Always grabs the first issue category.
|
||||
@ -41,7 +45,12 @@ export async function createReportIssue(server: string, reportDescription: strin
|
||||
|
||||
// Ensure there *actually* is a team there
|
||||
if (team.id) {
|
||||
await linearClient.createIssue({teamId: team.id, title: `Issue against server \`${server}\``, description: desc(userId, server, reportDescription), assigneeId: (await team.members()).nodes[0].id })
|
||||
await linearClient.createIssue({
|
||||
teamId: team.id,
|
||||
title: `Issue against server \`${server}\``,
|
||||
description: desc(userId, server, reportDescription),
|
||||
assigneeId: (await team.members()).nodes[0].id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,4 +65,4 @@ ${reason}
|
||||
|
||||
|
||||
*This was an automatically added issue by the report bot. Add the canceled status to remove the issue from the active issues, along with the labels Not Controllable & Spam for their respective values.*
|
||||
`
|
||||
`;
|
||||
|
||||
58
src/lib/types/server-icon.ts
Normal file
58
src/lib/types/server-icon.ts
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* MHSF, Minehut Server List
|
||||
* All external content is rather licensed under the ECA Agreement
|
||||
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
|
||||
*
|
||||
* All code under MHSF is licensed under the MIT License
|
||||
* by open source contributors
|
||||
*
|
||||
* Copyright (c) 2024 dvelo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
export async function getMinehutIcons(): Promise<MinehutIcon[] | undefined> {
|
||||
const icons = await fetch("https://api.minehut.com/servers/icons");
|
||||
console.log(icons);
|
||||
if (!icons.ok) return undefined;
|
||||
return await icons.json();
|
||||
}
|
||||
|
||||
export type MinehutIcon = {
|
||||
_id: string;
|
||||
display_name: string;
|
||||
icon_name: string;
|
||||
price: number;
|
||||
rank: string;
|
||||
available: boolean;
|
||||
disabled: boolean;
|
||||
created: number;
|
||||
last_updated: number;
|
||||
__v: number;
|
||||
salePrice: any;
|
||||
};
|
||||
|
||||
export const rarityIndex = {
|
||||
common: { bg: "#40464d", text: "#b7bfc5" },
|
||||
uncommon: { bg: "#184f02", text: "#61bf01" },
|
||||
rare: { bg: "#15448a", text: "#41afff" },
|
||||
epic: { bg: "#4c1a7b", text: "#ce59ff" },
|
||||
legendary: { bg: "#de6e0d", text: "#fce8cf" },
|
||||
};
|
||||
@ -41,126 +41,165 @@ const config = {
|
||||
prefix: "",
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
padding: "2rem",
|
||||
center: 'true',
|
||||
padding: '2rem',
|
||||
screens: {
|
||||
"2xl": "1400px",
|
||||
},
|
||||
'2xl': '1400px'
|
||||
}
|
||||
},
|
||||
extend: {
|
||||
colors: {
|
||||
border: "hsl(var(--border))",
|
||||
input: "hsl(var(--input))",
|
||||
ring: "hsl(var(--ring))",
|
||||
background: "hsl(var(--background))",
|
||||
foreground: "hsl(var(--foreground))",
|
||||
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))",
|
||||
DEFAULT: 'hsl(var(--primary))',
|
||||
foreground: 'hsl(var(--primary-foreground))'
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: "hsl(var(--secondary))",
|
||||
foreground: "hsl(var(--secondary-foreground))",
|
||||
DEFAULT: 'hsl(var(--secondary))',
|
||||
foreground: 'hsl(var(--secondary-foreground))'
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: "hsl(var(--destructive))",
|
||||
foreground: "hsl(var(--destructive-foreground))",
|
||||
DEFAULT: 'hsl(var(--destructive))',
|
||||
foreground: 'hsl(var(--destructive-foreground))'
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: "hsl(var(--muted))",
|
||||
foreground: "hsl(var(--muted-foreground))",
|
||||
DEFAULT: 'hsl(var(--muted))',
|
||||
foreground: 'hsl(var(--muted-foreground))'
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "hsl(var(--accent))",
|
||||
foreground: "hsl(var(--accent-foreground))",
|
||||
DEFAULT: 'hsl(var(--accent))',
|
||||
foreground: 'hsl(var(--accent-foreground))'
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: "hsl(var(--popover))",
|
||||
foreground: "hsl(var(--popover-foreground))",
|
||||
DEFAULT: 'hsl(var(--popover))',
|
||||
foreground: 'hsl(var(--popover-foreground))'
|
||||
},
|
||||
card: {
|
||||
DEFAULT: "hsl(var(--card))",
|
||||
foreground: "hsl(var(--card-foreground))",
|
||||
DEFAULT: 'hsl(var(--card))',
|
||||
foreground: 'hsl(var(--card-foreground))'
|
||||
},
|
||||
sidebar: {
|
||||
DEFAULT: 'hsl(var(--sidebar-background))',
|
||||
foreground: 'hsl(var(--sidebar-foreground))',
|
||||
primary: 'hsl(var(--sidebar-primary))',
|
||||
'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
|
||||
accent: 'hsl(var(--sidebar-accent))',
|
||||
'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
|
||||
border: 'hsl(var(--sidebar-border))',
|
||||
ring: 'hsl(var(--sidebar-ring))',
|
||||
mhsf: 'hsl(var(--sidebar-mhsf))'
|
||||
}
|
||||
},
|
||||
borderRadius: {
|
||||
lg: "var(--radius)",
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
lg: 'var(--radius)',
|
||||
md: 'calc(var(--radius) - 2px)',
|
||||
sm: 'calc(var(--radius) - 4px)'
|
||||
},
|
||||
keyframes: {
|
||||
'image-glow': {
|
||||
'0%': {
|
||||
'opacity': '0',
|
||||
'animation-timing-function': 'cubic-bezier(0.74, 0.25, 0.76, 1)',
|
||||
opacity: '0',
|
||||
'animation-timing-function': 'cubic-bezier(0.74, 0.25, 0.76, 1)'
|
||||
},
|
||||
'10%': {
|
||||
'opacity': '0.7',
|
||||
'animation-timing-function': 'cubic-bezier(0.12, 0.01, 0.08, 0.99)',
|
||||
opacity: '0.7',
|
||||
'animation-timing-function': 'cubic-bezier(0.12, 0.01, 0.08, 0.99)'
|
||||
},
|
||||
'100%': {
|
||||
opacity: '0.4',
|
||||
opacity: '0.4'
|
||||
}
|
||||
},
|
||||
'border-beam': {
|
||||
'100%': {
|
||||
'offset-distance': '100%'
|
||||
}
|
||||
},
|
||||
"border-beam": {
|
||||
"100%": {
|
||||
"offset-distance": "100%",
|
||||
'caret-blink': {
|
||||
'0%,70%,100%': {
|
||||
opacity: '1'
|
||||
},
|
||||
'20%,50%': {
|
||||
opacity: '0'
|
||||
}
|
||||
},
|
||||
"caret-blink": {
|
||||
"0%,70%,100%": { opacity: "1" },
|
||||
"20%,50%": { opacity: "0" },
|
||||
'accordion-down': {
|
||||
from: {
|
||||
height: '0'
|
||||
},
|
||||
|
||||
"accordion-down": {
|
||||
from: { height: "0" },
|
||||
to: { height: "var(--radix-accordion-content-height)" },
|
||||
to: {
|
||||
height: 'var(--radix-accordion-content-height)'
|
||||
}
|
||||
},
|
||||
"accordion-up": {
|
||||
from: { height: "var(--radix-accordion-content-height)" },
|
||||
to: { height: "0" },
|
||||
'accordion-up': {
|
||||
from: {
|
||||
height: 'var(--radix-accordion-content-height)'
|
||||
},
|
||||
|
||||
"fade-in": {
|
||||
from: { opacity: "0", transform: "translateY(-10px)" },
|
||||
to: { opacity: "1", transform: "none" },
|
||||
to: {
|
||||
height: '0'
|
||||
}
|
||||
},
|
||||
'fade-in': {
|
||||
from: {
|
||||
opacity: '0',
|
||||
transform: 'translateY(-10px)'
|
||||
},
|
||||
to: {
|
||||
opacity: '1',
|
||||
transform: 'none'
|
||||
}
|
||||
},
|
||||
marquee: {
|
||||
from: { transform: "translateX(0)" },
|
||||
to: { transform: "translateX(calc(-100% - var(--gap)))" },
|
||||
from: {
|
||||
transform: 'translateX(0)'
|
||||
},
|
||||
"marquee-vertical": {
|
||||
from: { transform: "translateY(0)" },
|
||||
to: { transform: "translateY(calc(-100% - var(--gap)))" },
|
||||
to: {
|
||||
transform: 'translateX(calc(-100% - var(--gap)))'
|
||||
}
|
||||
},
|
||||
"fade-up": {
|
||||
from: { opacity: "0", transform: "translateY(20px)" },
|
||||
to: { opacity: "1", transform: "none" },
|
||||
'marquee-vertical': {
|
||||
from: {
|
||||
transform: 'translateY(0)'
|
||||
},
|
||||
|
||||
'shimmer': {
|
||||
to: {
|
||||
transform: 'translateY(calc(-100% - var(--gap)))'
|
||||
}
|
||||
},
|
||||
'fade-up': {
|
||||
from: {
|
||||
opacity: '0',
|
||||
transform: 'translateY(20px)'
|
||||
},
|
||||
to: {
|
||||
opacity: '1',
|
||||
transform: 'none'
|
||||
}
|
||||
},
|
||||
shimmer: {
|
||||
'0%, 90%, 100%': {
|
||||
'background-position': 'calc(-100% - var(--shimmer-width)) 0',
|
||||
'background-position': 'calc(-100% - var(--shimmer-width)) 0'
|
||||
},
|
||||
'30%, 60%': {
|
||||
'background-position': 'calc(100% + var(--shimmer-width)) 0',
|
||||
},
|
||||
},
|
||||
'background-position': 'calc(100% + var(--shimmer-width)) 0'
|
||||
}
|
||||
}
|
||||
},
|
||||
animation: {
|
||||
marquee: "marquee var(--duration) linear infinite",
|
||||
"marquee-vertical": "marquee-vertical var(--duration) linear infinite",
|
||||
"accordion-down": "accordion-down 0.2s ease-out",
|
||||
"accordion-up": "accordion-up 0.2s ease-out",
|
||||
marquee: 'marquee var(--duration) linear infinite',
|
||||
'marquee-vertical': 'marquee-vertical var(--duration) linear infinite',
|
||||
'accordion-down': 'accordion-down 0.2s ease-out',
|
||||
'accordion-up': 'accordion-up 0.2s ease-out',
|
||||
'image-glow': 'image-glow 4100ms 600ms ease-out forwards',
|
||||
'shimmer': 'shimmer 8s infinite',
|
||||
"fade-in": "fade-in 1000ms var(--animation-delay, 0ms) ease forwards",
|
||||
"caret-blink": "caret-blink 1.25s ease-out infinite",
|
||||
"border-beam": "border-beam calc(var(--duration)*1s) infinite linear",
|
||||
|
||||
"fade-up": "fade-up 1000ms var(--animation-delay, 0ms) ease forwards",
|
||||
},
|
||||
},
|
||||
shimmer: 'shimmer 8s infinite',
|
||||
'fade-in': 'fade-in 1000ms var(--animation-delay, 0ms) ease forwards',
|
||||
'caret-blink': 'caret-blink 1.25s ease-out infinite',
|
||||
'border-beam': 'border-beam calc(var(--duration)*1s) infinite linear',
|
||||
'fade-up': 'fade-up 1000ms var(--animation-delay, 0ms) ease forwards'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [require("tailwindcss-animate"), require("@tailwindcss/typography")],
|
||||
} satisfies Config;
|
||||
|
||||
193
yarn.lock
193
yarn.lock
@ -1157,6 +1157,16 @@
|
||||
dependencies:
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
|
||||
"@radix-ui/react-avatar@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-avatar/-/react-avatar-1.1.1.tgz#5848d2ed5f34d18b36fc7e2d227c41fca8600ea1"
|
||||
integrity sha512-eoOtThOmxeoizxpX6RiEsQZ2wj5r4+zoeqAwO0cBaFQGjJwIH3dIX0OCxNrCyrrdxG+vBweMETh3VziQG7c1kw==
|
||||
dependencies:
|
||||
"@radix-ui/react-context" "1.1.1"
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||
|
||||
"@radix-ui/react-checkbox@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-1.1.1.tgz#a559c4303957d797acee99914480b755aa1f27d6"
|
||||
@ -1171,6 +1181,20 @@
|
||||
"@radix-ui/react-use-previous" "1.1.0"
|
||||
"@radix-ui/react-use-size" "1.1.0"
|
||||
|
||||
"@radix-ui/react-collapsible@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-collapsible/-/react-collapsible-1.1.1.tgz#1382cc9ec48f8b473c14f3779d317f0cdf6da5e9"
|
||||
integrity sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==
|
||||
dependencies:
|
||||
"@radix-ui/primitive" "1.1.0"
|
||||
"@radix-ui/react-compose-refs" "1.1.0"
|
||||
"@radix-ui/react-context" "1.1.1"
|
||||
"@radix-ui/react-id" "1.1.0"
|
||||
"@radix-ui/react-presence" "1.1.1"
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||
|
||||
"@radix-ui/react-collection@1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz"
|
||||
@ -1229,6 +1253,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.0.tgz#6df8d983546cfd1999c8512f3a8ad85a6e7fcee8"
|
||||
integrity sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==
|
||||
|
||||
"@radix-ui/react-context@1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.1.tgz#82074aa83a472353bb22e86f11bcbd1c61c4c71a"
|
||||
integrity sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==
|
||||
|
||||
"@radix-ui/react-dialog@1.0.5":
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300"
|
||||
@ -1250,7 +1279,7 @@
|
||||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "2.5.5"
|
||||
|
||||
"@radix-ui/react-dialog@^1.0.4", "@radix-ui/react-dialog@^1.1.1":
|
||||
"@radix-ui/react-dialog@^1.0.4":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz#4906507f7b4ad31e22d7dad69d9330c87c431d44"
|
||||
integrity sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==
|
||||
@ -1270,6 +1299,26 @@
|
||||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "2.5.7"
|
||||
|
||||
"@radix-ui/react-dialog@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.1.2.tgz#d9345575211d6f2d13e209e84aec9a8584b54d6c"
|
||||
integrity sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==
|
||||
dependencies:
|
||||
"@radix-ui/primitive" "1.1.0"
|
||||
"@radix-ui/react-compose-refs" "1.1.0"
|
||||
"@radix-ui/react-context" "1.1.1"
|
||||
"@radix-ui/react-dismissable-layer" "1.1.1"
|
||||
"@radix-ui/react-focus-guards" "1.1.1"
|
||||
"@radix-ui/react-focus-scope" "1.1.0"
|
||||
"@radix-ui/react-id" "1.1.0"
|
||||
"@radix-ui/react-portal" "1.1.2"
|
||||
"@radix-ui/react-presence" "1.1.1"
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
"@radix-ui/react-slot" "1.1.0"
|
||||
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "2.6.0"
|
||||
|
||||
"@radix-ui/react-direction@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz"
|
||||
@ -1305,16 +1354,27 @@
|
||||
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||
"@radix-ui/react-use-escape-keydown" "1.1.0"
|
||||
|
||||
"@radix-ui/react-dropdown-menu@^2.1.1":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz#3dc578488688250dbbe109d9ff2ca28a9bca27ec"
|
||||
integrity sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==
|
||||
"@radix-ui/react-dismissable-layer@1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz#cbdcb739c5403382bdde5f9243042ba643883396"
|
||||
integrity sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==
|
||||
dependencies:
|
||||
"@radix-ui/primitive" "1.1.0"
|
||||
"@radix-ui/react-compose-refs" "1.1.0"
|
||||
"@radix-ui/react-context" "1.1.0"
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||
"@radix-ui/react-use-escape-keydown" "1.1.0"
|
||||
|
||||
"@radix-ui/react-dropdown-menu@^2.1.2":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.2.tgz#acc49577130e3c875ef0133bd1e271ea3392d924"
|
||||
integrity sha512-GVZMR+eqK8/Kes0a36Qrv+i20bAPXSn8rCBTHx30w+3ECnR5o3xixAlqcVaYvLeyKUsm0aqyhWfmUcqufM8nYA==
|
||||
dependencies:
|
||||
"@radix-ui/primitive" "1.1.0"
|
||||
"@radix-ui/react-compose-refs" "1.1.0"
|
||||
"@radix-ui/react-context" "1.1.1"
|
||||
"@radix-ui/react-id" "1.1.0"
|
||||
"@radix-ui/react-menu" "2.1.1"
|
||||
"@radix-ui/react-menu" "2.1.2"
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||
|
||||
@ -1330,6 +1390,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz#8e9abb472a9a394f59a1b45f3dd26cfe3fc6da13"
|
||||
integrity sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==
|
||||
|
||||
"@radix-ui/react-focus-guards@1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz#8635edd346304f8b42cae86b05912b61aef27afe"
|
||||
integrity sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==
|
||||
|
||||
"@radix-ui/react-focus-scope@1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz"
|
||||
@ -1440,6 +1505,30 @@
|
||||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "2.5.7"
|
||||
|
||||
"@radix-ui/react-menu@2.1.2":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.1.2.tgz#91f6815845a4298dde775563ed2d80b7ad667899"
|
||||
integrity sha512-lZ0R4qR2Al6fZ4yCCZzu/ReTFrylHFxIqy7OezIpWF4bL0o9biKo0pFIvkaew3TyZ9Fy5gYVrR5zCGZBVbO1zg==
|
||||
dependencies:
|
||||
"@radix-ui/primitive" "1.1.0"
|
||||
"@radix-ui/react-collection" "1.1.0"
|
||||
"@radix-ui/react-compose-refs" "1.1.0"
|
||||
"@radix-ui/react-context" "1.1.1"
|
||||
"@radix-ui/react-direction" "1.1.0"
|
||||
"@radix-ui/react-dismissable-layer" "1.1.1"
|
||||
"@radix-ui/react-focus-guards" "1.1.1"
|
||||
"@radix-ui/react-focus-scope" "1.1.0"
|
||||
"@radix-ui/react-id" "1.1.0"
|
||||
"@radix-ui/react-popper" "1.2.0"
|
||||
"@radix-ui/react-portal" "1.1.2"
|
||||
"@radix-ui/react-presence" "1.1.1"
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
"@radix-ui/react-roving-focus" "1.1.0"
|
||||
"@radix-ui/react-slot" "1.1.0"
|
||||
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "2.6.0"
|
||||
|
||||
"@radix-ui/react-menubar@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-menubar/-/react-menubar-1.1.1.tgz#e126514cb1c46e0a4f9fba7d016e578cc4e41f22"
|
||||
@ -1548,6 +1637,14 @@
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||
|
||||
"@radix-ui/react-portal@1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.2.tgz#51eb46dae7505074b306ebcb985bf65cc547d74e"
|
||||
integrity sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==
|
||||
dependencies:
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||
|
||||
"@radix-ui/react-presence@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz"
|
||||
@ -1565,6 +1662,14 @@
|
||||
"@radix-ui/react-compose-refs" "1.1.0"
|
||||
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||
|
||||
"@radix-ui/react-presence@1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.1.tgz#98aba423dba5e0c687a782c0669dcd99de17f9b1"
|
||||
integrity sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==
|
||||
dependencies:
|
||||
"@radix-ui/react-compose-refs" "1.1.0"
|
||||
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||
|
||||
"@radix-ui/react-primitive@1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz"
|
||||
@ -1642,13 +1747,12 @@
|
||||
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||
|
||||
"@radix-ui/react-separator@^1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.0.3.tgz"
|
||||
integrity sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==
|
||||
"@radix-ui/react-separator@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.1.0.tgz#ee0f4d86003b0e3ea7bc6ccab01ea0adee32663e"
|
||||
integrity sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-primitive" "1.0.3"
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
|
||||
"@radix-ui/react-slot@1.0.2":
|
||||
version "1.0.2"
|
||||
@ -1692,24 +1796,23 @@
|
||||
"@radix-ui/react-roving-focus" "1.1.0"
|
||||
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||
|
||||
"@radix-ui/react-tooltip@^1.0.7":
|
||||
version "1.0.7"
|
||||
resolved "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz"
|
||||
integrity sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==
|
||||
"@radix-ui/react-tooltip@^1.1.3":
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.1.3.tgz#4250b14723f2d8477e7a3d0526c169f91d1f2f74"
|
||||
integrity sha512-Z4w1FIS0BqVFI2c1jZvb/uDVJijJjJ2ZMuPV81oVgTZ7g3BZxobplnMVvXtFWgtozdvYJ+MFWtwkM5S2HnAong==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/primitive" "1.0.1"
|
||||
"@radix-ui/react-compose-refs" "1.0.1"
|
||||
"@radix-ui/react-context" "1.0.1"
|
||||
"@radix-ui/react-dismissable-layer" "1.0.5"
|
||||
"@radix-ui/react-id" "1.0.1"
|
||||
"@radix-ui/react-popper" "1.1.3"
|
||||
"@radix-ui/react-portal" "1.0.4"
|
||||
"@radix-ui/react-presence" "1.0.1"
|
||||
"@radix-ui/react-primitive" "1.0.3"
|
||||
"@radix-ui/react-slot" "1.0.2"
|
||||
"@radix-ui/react-use-controllable-state" "1.0.1"
|
||||
"@radix-ui/react-visually-hidden" "1.0.3"
|
||||
"@radix-ui/primitive" "1.1.0"
|
||||
"@radix-ui/react-compose-refs" "1.1.0"
|
||||
"@radix-ui/react-context" "1.1.1"
|
||||
"@radix-ui/react-dismissable-layer" "1.1.1"
|
||||
"@radix-ui/react-id" "1.1.0"
|
||||
"@radix-ui/react-popper" "1.2.0"
|
||||
"@radix-ui/react-portal" "1.1.2"
|
||||
"@radix-ui/react-presence" "1.1.1"
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
"@radix-ui/react-slot" "1.1.0"
|
||||
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||
"@radix-ui/react-visually-hidden" "1.1.0"
|
||||
|
||||
"@radix-ui/react-use-callback-ref@1.0.1":
|
||||
version "1.0.1"
|
||||
@ -1815,6 +1918,13 @@
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-primitive" "1.0.3"
|
||||
|
||||
"@radix-ui/react-visually-hidden@1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz#ad47a8572580f7034b3807c8e6740cd41038a5a2"
|
||||
integrity sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==
|
||||
dependencies:
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
|
||||
"@radix-ui/rect@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz"
|
||||
@ -2809,7 +2919,7 @@ citty@^0.1.6:
|
||||
|
||||
class-variance-authority@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz"
|
||||
resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.0.tgz#1c3134d634d80271b1837452b06d821915954522"
|
||||
integrity sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==
|
||||
dependencies:
|
||||
clsx "2.0.0"
|
||||
@ -5010,10 +5120,10 @@ lru-cache@^10.2.0:
|
||||
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz"
|
||||
integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==
|
||||
|
||||
lucide-react@^0.416.0:
|
||||
version "0.416.0"
|
||||
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.416.0.tgz#657da248f9b862703d7d80aafb912e79ad886313"
|
||||
integrity sha512-wPWxTzdss1CTz2aqcNWNlbh4YSnH9neJWP3RaeXepxpLCTW+pmu7WcT/wxJe+Q7Y7DqGOxAqakJv0pIK3431Ag==
|
||||
lucide-react@^0.454.0:
|
||||
version "0.454.0"
|
||||
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.454.0.tgz#a81b9c482018720f07ead0503ae502d94d528444"
|
||||
integrity sha512-hw7zMDwykCLnEzgncEEjHeA6+45aeEzRYuKHuyRSOPkhko+J3ySGjGIzu+mmMfDFG1vazHepMaYFYHbTFAZAAQ==
|
||||
|
||||
luxon@~3.4.0:
|
||||
version "3.4.4"
|
||||
@ -6708,7 +6818,7 @@ react-markdown@^9.0.1:
|
||||
unist-util-visit "^5.0.0"
|
||||
vfile "^6.0.0"
|
||||
|
||||
react-remove-scroll-bar@^2.3.3, react-remove-scroll-bar@^2.3.4:
|
||||
react-remove-scroll-bar@^2.3.3, react-remove-scroll-bar@^2.3.4, react-remove-scroll-bar@^2.3.6:
|
||||
version "2.3.6"
|
||||
resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz"
|
||||
integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==
|
||||
@ -6738,6 +6848,17 @@ react-remove-scroll@2.5.7:
|
||||
use-callback-ref "^1.3.0"
|
||||
use-sidecar "^1.1.2"
|
||||
|
||||
react-remove-scroll@2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz#fb03a0845d7768a4f1519a99fdb84983b793dc07"
|
||||
integrity sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==
|
||||
dependencies:
|
||||
react-remove-scroll-bar "^2.3.6"
|
||||
react-style-singleton "^2.2.1"
|
||||
tslib "^2.1.0"
|
||||
use-callback-ref "^1.3.0"
|
||||
use-sidecar "^1.1.2"
|
||||
|
||||
react-resizable-panels@^2.0.23:
|
||||
version "2.0.23"
|
||||
resolved "https://registry.yarnpkg.com/react-resizable-panels/-/react-resizable-panels-2.0.23.tgz#7a4296f23028c32ffcbe8086aa918cd934e7e87f"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user