diff --git a/src/components/clerk/SignInForm.tsx b/src/components/clerk/SignInForm.tsx
new file mode 100644
index 0000000..b8c9cfb
--- /dev/null
+++ b/src/components/clerk/SignInForm.tsx
@@ -0,0 +1,311 @@
+/*
+ * MHSF, Minehut Server List
+ * All external content is rather licensed under the ECA Agreement
+ * located here: https://mhsf.app/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 * as Clerk from "@clerk/elements/common";
+import * as SignUp from "@clerk/elements/sign-up";
+import { Button } from "@/components/ui/button";
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card";
+import { Input } from "@/components/ui/input";
+import { Label } from "@/components/ui/label";
+import { cn } from "@/lib/utils";
+import { LoadingSpinner } from "../ui/loading-spinner";
+import Discord from "../ui/discord";
+import Github from "../ui/github";
+
+export default function SignUpPage() {
+ return (
+
+
+
+
+ }
+ >
+
+ {(isGlobalLoading) => (
+ <>
+ {isGlobalLoading && (
+
+
+
+ )}
+
+
+
+ Create your account
+
+ Welcome! Please fill in the details to get started.
+
+
+
+
+
+
+
+
+
+
+
+
+ Verify your email
+
+ Use the verification link sent to your email address
+
+
+
+
+
+
+ Email address
+
+
+ {
+ return (
+
+ {value}
+ {status === "cursor" && (
+
+
+
+ )}
+
+ );
+ }}
+ />
+
+
+
+ (
+
+ )}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+
+
+ );
+}
diff --git a/src/components/effects/gradient-banner.tsx b/src/components/effects/gradient-banner.tsx
new file mode 100644
index 0000000..d96bba8
--- /dev/null
+++ b/src/components/effects/gradient-banner.tsx
@@ -0,0 +1,73 @@
+/*
+ * MHSF, Minehut Server List
+ * All external content is rather licensed under the ECA Agreement
+ * located here: https://mhsf.app/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 React, { useEffect, useState } from "react";
+import { Gradient } from "stripe-gradient";
+
+export default function GradientBanner({
+ children,
+}: {
+ children?: React.ReactNode;
+}) {
+ const [gradientId, setGradientId] = useState("gradient-banner");
+
+ useEffect(() => {
+ setGradientId("gradient-banner");
+ const gradient = new Gradient();
+ gradient.initGradient("#" + gradientId);
+ }, [gradientId]);
+
+ return (
+
+ {" "}
+
+ {children}
+
+
+ );
+}
diff --git a/src/config/banner.tsx b/src/components/feat/AllBanners.tsx
similarity index 64%
rename from src/config/banner.tsx
rename to src/components/feat/AllBanners.tsx
index 1fcd32a..0c1ab01 100644
--- a/src/config/banner.tsx
+++ b/src/components/feat/AllBanners.tsx
@@ -1,7 +1,7 @@
/*
* 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
+ * located here: https://mhsf.app/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
@@ -28,26 +28,16 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-import { Button } from "@/components/ui/button";
-import Link from "next/link";
+"use client";
-/** used when there is a outage */
-export const banner = {
- isBanner:
- process.env.NEXT_PUBLIC_VERCEL_ENV !== "production"
- ? true
- : /** Set this to true when outage --->*/ false,
- bannerText:
- process.env.NEXT_PUBLIC_VERCEL_ENV !== "production" ? (
- <>
- Your not in production!{" "}
-
-
-
- >
- ) : (
- <>{/** Set this to an explanation! */}>
- ),
-};
+import { useBanners } from "@/lib/hooks/use-banners";
+
+export default function AllBanners() {
+ const { banners } = useBanners();
+
+ return (
+
+ );
+}
diff --git a/src/components/feat/BannerContainer.tsx b/src/components/feat/BannerContainer.tsx
new file mode 100644
index 0000000..11e3739
--- /dev/null
+++ b/src/components/feat/BannerContainer.tsx
@@ -0,0 +1,51 @@
+/*
+ * MHSF, Minehut Server List
+ * All external content is rather licensed under the ECA Agreement
+ * located here: https://mhsf.app/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 useTotalBannerSize from "@/lib/hooks/use-total-banner-size";
+
+export default function BannerContainer({
+ children,
+ className,
+ style,
+}: {
+ children: React.ReactNode;
+ className?: string;
+ style: (size: number) => React.CSSProperties;
+}) {
+ const { bannerSize } = useTotalBannerSize();
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/components/feat/LayoutPart.tsx b/src/components/feat/LayoutPart.tsx
new file mode 100644
index 0000000..1556782
--- /dev/null
+++ b/src/components/feat/LayoutPart.tsx
@@ -0,0 +1,55 @@
+"use client";
+
+import ClientFadeIn from "@/components/ClientFadeIn";
+import { BrandingGenericIcon } from "@/components/Icon";
+import TextFromPathname from "@/components/TextFromPathname";
+import TopBar from "@/components/clerk/Topbar";
+import {
+ Breadcrumb,
+ BreadcrumbList,
+ BreadcrumbPage,
+} from "@/components/ui/breadcrumb";
+import NextTopLoader from "@/lib/top-loader";
+import Link from "next/link";
+import BannerContainer from "@/components/feat/BannerContainer";
+import { Inter } from "next/font/google";
+
+const inter = Inter({ variable: "--font-inter", subsets: ["latin"] });
+export default function LayoutPart({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+ <>
+ ({
+ marginTop: `${2 * size}rem`,
+ })}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ({
+ paddingTop: `${2 * size}rem`,
+ })}
+ >
+
+ {children}
+
+ >
+ );
+}
diff --git a/src/components/feat/MainBanner.tsx b/src/components/feat/MainBanner.tsx
new file mode 100644
index 0000000..a2197eb
--- /dev/null
+++ b/src/components/feat/MainBanner.tsx
@@ -0,0 +1,50 @@
+/*
+ * MHSF, Minehut Server List
+ * All external content is rather licensed under the ECA Agreement
+ * located here: https://mhsf.app/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 default function MainBanner({
+ className,
+ size = 1,
+ children,
+}: {
+ className?: string;
+ size?: number;
+ children?: React.ReactNode;
+}) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/components/misc/AffilatePopup.tsx b/src/components/misc/AffilatePopup.tsx
new file mode 100644
index 0000000..c54e8c9
--- /dev/null
+++ b/src/components/misc/AffilatePopup.tsx
@@ -0,0 +1,29 @@
+/*
+ * MHSF, Minehut Server List
+ * All external content is rather licensed under the ECA Agreement
+ * located here: https://mhsf.app/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.
+ */
diff --git a/src/components/misc/KnockNotifications.tsx b/src/components/misc/KnockNotifications.tsx
new file mode 100644
index 0000000..8064358
--- /dev/null
+++ b/src/components/misc/KnockNotifications.tsx
@@ -0,0 +1,83 @@
+/*
+ * 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 { SignedIn } from "@clerk/clerk-react";
+import { useUser } from "@clerk/nextjs";
+import {
+ KnockProvider,
+ KnockFeedProvider,
+ NotificationIconButton,
+ NotificationFeedPopover,
+ NotificationCell,
+} from "@knocklabs/react";
+import { useRef, useState } from "react";
+
+import "@knocklabs/react/dist/index.css";
+import { Button } from "../ui/button";
+import { Bell } from "lucide-react";
+import { useTheme } from "next-themes";
+
+export default function KnockNotification() {
+ const [isVisible, setIsVisible] = useState(false);
+ const notifButtonRef = useRef(null);
+ const { user } = useUser();
+ const { resolvedTheme } = useTheme();
+
+ return (
+
+
+
+ <>
+
+ setIsVisible(false)}
+ />
+ >
+
+
+
+ );
+}
diff --git a/src/components/misc/ServerListNav.tsx b/src/components/misc/ServerListNav.tsx
new file mode 100644
index 0000000..2fcfba5
--- /dev/null
+++ b/src/components/misc/ServerListNav.tsx
@@ -0,0 +1,99 @@
+/*
+ * MHSF, Minehut Server List
+ * All external content is rather licensed under the ECA Agreement
+ * located here: https://mhsf.app/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 {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuTrigger,
+} from "../ui/dropdown-menu";
+import { Button } from "../ui/button";
+import { ChevronDown } from "lucide-react";
+
+export function ServerListNav() {
+ return (
+
diff --git a/src/components/ui/aspect-ratio.tsx b/src/components/ui/aspect-ratio.tsx
new file mode 100644
index 0000000..d6a5226
--- /dev/null
+++ b/src/components/ui/aspect-ratio.tsx
@@ -0,0 +1,7 @@
+"use client"
+
+import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"
+
+const AspectRatio = AspectRatioPrimitive.Root
+
+export { AspectRatio }
diff --git a/src/components/ui/discord.tsx b/src/components/ui/discord.tsx
new file mode 100644
index 0000000..5e039c0
--- /dev/null
+++ b/src/components/ui/discord.tsx
@@ -0,0 +1,17 @@
+import type { SVGProps } from "react";
+const Discord = (props: SVGProps) => (
+
+);
+export default Discord;
diff --git a/src/components/ui/github.tsx b/src/components/ui/github.tsx
new file mode 100644
index 0000000..704f108
--- /dev/null
+++ b/src/components/ui/github.tsx
@@ -0,0 +1,15 @@
+import type { SVGProps } from "react";
+const Github = (props: SVGProps) => (
+
+);
+export default Github;
diff --git a/src/config/banners.tsx b/src/config/banners.tsx
new file mode 100644
index 0000000..a096f10
--- /dev/null
+++ b/src/config/banners.tsx
@@ -0,0 +1,41 @@
+export const defaultBanners: {
+ bannerSpace: number;
+ bannerContent: React.ReactNode;
+}[] = [
+ // The sponsor banner ALWAYS has to be first.
+ // {
+ // bannerSpace: 2,
+ // bannerContent: (
+ //
+ // {" "}
+ //
+ // ??? — an official affiliate of MHSF{" "}
+ //
+ // Lorem ipsum odor amet, consectetuer adipiscing elit. — check it out
+ //
+ //
+ // ),
+ // },
+];
+
+export const bannerHooks: (() =>
+ | { bannerSpace: number; bannerContent: React.ReactNode }
+ | undefined)[] = [
+ () => {
+ // if (process.env.NEXT_PUBLIC_VERCEL_ENV !== "production")
+ // return {
+ // bannerSpace: 1,
+ // bannerContent: (
+ //
+ // Your not in production!{" "}
+ //
+ //
+ //
+ //
+ // ),
+ // };
+ return undefined;
+ },
+];
diff --git a/src/config/version.tsx b/src/config/version.tsx
index 77238eb..1ea92bc 100644
--- a/src/config/version.tsx
+++ b/src/config/version.tsx
@@ -65,7 +65,7 @@ export const changelog: { name: string; id: string; changelog: ReactNode }[] = [
features={[
"New MOTD engine that is over 3,000% faster, runs client-side, and doesn't need any requests to run.",
"Fixed issue where GitHub link was broken if you were signed-out",
- "",
+ "Adding snowfall finally (better late then ever)",
]}
title={
diff --git a/src/lib/api.ts b/src/lib/api.ts
index 7130a9d..49f4e8f 100644
--- a/src/lib/api.ts
+++ b/src/lib/api.ts
@@ -62,13 +62,17 @@ async function apiConstructor(
export async function getMOTDFromServer(
list: Array<{ server: string; motd: string }>,
): Promise> {
- const result = await fetch(connector("/motd", { version: 1 }), {
- body: JSON.stringify({ motd: list }),
- method: "POST",
- headers: {
- "Content-Type": "application/json",
+ const result = await fetch(
+ process.env.NEXT_PUBLIC_ALTERNATE_MOTD_ENDPOINT ??
+ connector("/motd", { version: 1 }),
+ {
+ body: JSON.stringify({ motd: list }),
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
},
- });
+ );
let json = await result.json();
return json.result;
diff --git a/src/lib/hooks/use-banners.tsx b/src/lib/hooks/use-banners.tsx
new file mode 100644
index 0000000..936ffc2
--- /dev/null
+++ b/src/lib/hooks/use-banners.tsx
@@ -0,0 +1,57 @@
+/*
+ * MHSF, Minehut Server List
+ * All external content is rather licensed under the ECA Agreement
+ * located here: https://mhsf.app/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 { bannerHooks, defaultBanners } from "@/config/banners";
+import { useEffect, useState } from "react";
+import { useIsMobile } from "./use-mobile";
+
+export function useBanners() {
+ const [banners, setBanners] = useState<
+ {
+ bannerSpace: number;
+ bannerContent: React.ReactNode;
+ }[]
+ >(defaultBanners);
+ const isOnMobile = useIsMobile();
+
+ useEffect(() => {
+ if (isOnMobile) {
+ setBanners([]);
+ return;
+ }
+ setBanners(defaultBanners);
+ bannerHooks.forEach((hook) => {
+ const run = hook();
+ if (run !== undefined) setBanners((oldBanners) => [...oldBanners, run]);
+ });
+ }, [isOnMobile]);
+
+ return { banners };
+}
diff --git a/src/lib/hooks/use-total-banner-size.tsx b/src/lib/hooks/use-total-banner-size.tsx
new file mode 100644
index 0000000..5ab3173
--- /dev/null
+++ b/src/lib/hooks/use-total-banner-size.tsx
@@ -0,0 +1,61 @@
+/*
+ * MHSF, Minehut Server List
+ * All external content is rather licensed under the ECA Agreement
+ * located here: https://mhsf.app/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 { bannerHooks, defaultBanners } from "@/config/banners";
+import { useEffect, useState } from "react";
+import { useIsMobile } from "./use-mobile";
+
+export default function useTotalBannerSize() {
+ const [bannerSize, setBannerSize] = useState(0);
+ const isOnMobile = useIsMobile();
+
+ useEffect(() => {
+ setBannerSize(0);
+ if (isOnMobile) return;
+ const allBanners = [];
+
+ // First push the default banners
+ allBanners.push(...defaultBanners);
+
+ // Then push the banner hooks
+ bannerHooks.forEach((hook) => {
+ allBanners.push(hook());
+ });
+
+ setBannerSize(
+ allBanners.reduce(
+ (acc, banner) => acc + (banner ?? { bannerSpace: 0 }).bannerSpace,
+ 0
+ ) ?? 0
+ );
+ }, [isOnMobile]);
+
+ return { bannerSize };
+}
diff --git a/src/lib/types/stripe-gradient.d.ts b/src/lib/types/stripe-gradient.d.ts
new file mode 100644
index 0000000..fcadc08
--- /dev/null
+++ b/src/lib/types/stripe-gradient.d.ts
@@ -0,0 +1,5 @@
+declare module "stripe-gradient" {
+ declare class Gradient {
+ initGradient(id: string): void;
+ };
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 5e7f4c8..fbc1388 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1178,6 +1178,13 @@
dependencies:
"@radix-ui/react-primitive" "2.0.0"
+"@radix-ui/react-aspect-ratio@^1.1.1":
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.1.tgz#95d7692e61bab5eb7fec91f241ea993899593313"
+ integrity sha512-kNU4FIpcFMBLkOUcgeIteH06/8JLBcYY6Le1iKenDGCYNYFX3TQqCZjzkOsz37h7r94/99GTb7YhEr98ZBJibw==
+ dependencies:
+ "@radix-ui/react-primitive" "2.0.1"
+
"@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"