Compare commits

..

No commits in common. "697a5f2ed7d76cf944c055aa0fc6a0e91c30c816" and "0db9f5aba2d902ae56637cc530ba36c500c45225" have entirely different histories.

7 changed files with 78 additions and 127 deletions

@ -56,12 +56,6 @@ const nextConfig = {
webpack: (config) => { webpack: (config) => {
return config; return config;
}, },
eslint: {
ignoreDuringBuilds: true,
},
typescript: {
ignoreBuildErrors: true,
},
}; };
export default withContentlayer(nextConfig); export default withContentlayer(nextConfig);

@ -9367,10 +9367,4 @@ body {
--color-sidebar-border: var(--sidebar-border); --color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring); --color-sidebar-ring: var(--sidebar-ring);
--animate-aurora: aurora 8s ease-in-out infinite alternate; --animate-aurora: aurora 8s ease-in-out infinite alternate;
--animate-ripple: ripple var(--duration,2s) ease calc(var(--i, 0)*.2s) infinite;
@keyframes ripple {
0%, 100% {
transform: translate(-50%, -50%) scale(1);}
50% {
transform: translate(-50%, -50%) scale(0.9);}}
} }

@ -0,0 +1,42 @@
/*
* 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) 2025 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 { NotFoundComponent } from "@/components/util/not-found";
import type { Metadata } from "next";
export const metadata: Metadata = {
applicationName: "MHSF",
title: "Page not found · MHSF",
description: "Couldn't find the page that was requested.",
};
export default function NotFoundPage() {
return <NotFoundComponent />;
}

@ -8,8 +8,8 @@ import Image from "next/image"
export function Footer() { export function Footer() {
return ( return (
<footer className="w-full border-t mt-15"> <footer className="w-full border-t p-[20px] mt-15">
<div className="flex justify-between items-start p-[20px]"> <div className="flex justify-between items-start">
<span className="flex items-center gap-4 text-muted-foreground"> <span className="flex items-center gap-4 text-muted-foreground">
<Link href="Special:Root"> <Link href="Special:Root">
<BrandingGenericIcon className="max-w-[32px] max-h-[32px]" /> <BrandingGenericIcon className="max-w-[32px] max-h-[32px]" />
@ -82,8 +82,8 @@ export function Footer() {
</div> </div>
</div> </div>
<span className="block border-t border-neutral-500/20 bg-neutral-100 px-7 py-10 dark:border-neutral-700/50 dark:bg-neutral-900"> <span className="block mt-4">
<small className="text-[0.75rem]"> <small className="text-muted-foreground text-[0.75rem]">
MHSF is an open-source project licensed under the MIT license. MHSF is MHSF is an open-source project licensed under the MIT license. MHSF is
not officially affiliated with with Minehut, Super League Enterprise, not officially affiliated with with Minehut, Super League Enterprise,
or GamerSafer in any way. <br className="spacing-3" /> or GamerSafer in any way. <br className="spacing-3" />

@ -45,26 +45,17 @@ import { AnimatedList } from "./animated-list";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { ExampleChart } from "./example-chart"; import { ExampleChart } from "./example-chart";
import { Link } from "@/components/util/link"; import { Link } from "@/components/util/link";
import { type Avatar, AvatarCircles } from "./avatar-circles"; import {type Avatar, AvatarCircles } from "./avatar-circles";
import { Ripple } from "./ripple";
const getGitHubDetails = async () => { const getGitHubDetails = async () => {
const githubRepo = await ( const githubRepo = await (await fetch("https://api.github.com/repos/DeveloLongScript/mhsf")).json()
await fetch("https://api.github.com/repos/DeveloLongScript/mhsf") const githubStargazers = await (await fetch("https://api.github.com/repos/DeveloLongScript/mhsf/stargazers")).json()
).json();
const githubStargazers = await (
await fetch("https://api.github.com/repos/DeveloLongScript/mhsf/stargazers")
).json();
return { return {
stars: githubRepo.stargazers_count as number, stars: githubRepo.stargazers_count as number,
stargazers: ( stargazers: (githubStargazers as Array<{avatar_url: string, html_url: string}>).map((c) => {return {imageUrl: c.avatar_url, profileUrl: c.html_url}})
githubStargazers as Array<{ avatar_url: string; html_url: string }> }
).map((c) => { }
return { imageUrl: c.avatar_url, profileUrl: c.html_url };
}),
};
};
export default function HomePageComponent() { export default function HomePageComponent() {
const clerk = useClerk(); const clerk = useClerk();
@ -72,8 +63,8 @@ export default function HomePageComponent() {
const { isSignedIn } = useUser(); const { isSignedIn } = useUser();
const theme = useTheme(); const theme = useTheme();
const { resolvedTheme } = useTheme(); const { resolvedTheme } = useTheme();
const [stars, setStars] = useState(0); const [stars, setStars] = useState(0);
const [stargazers, setStargazers] = useState<Avatar[]>([]); const [stargazers, setStargazers] = useState<Avatar[]>([]);
const [gradientId, setGradientId] = useState("gradient-banner"); const [gradientId, setGradientId] = useState("gradient-banner");
useEffect(() => { useEffect(() => {
@ -82,12 +73,12 @@ export default function HomePageComponent() {
gradient.initGradient(`#${gradientId}`); gradient.initGradient(`#${gradientId}`);
}, [gradientId]); }, [gradientId]);
useEffect(() => { useEffect(() => {
getGitHubDetails().then((c) => { getGitHubDetails().then((c) => {
setStars(c.stars); setStars(c.stars);
setStargazers(c.stargazers); setStargazers(c.stargazers);
}); })
}, []); }, [])
return ( return (
<div className="lg:pt-10"> <div className="lg:pt-10">
@ -117,7 +108,8 @@ export default function HomePageComponent() {
<div className="absolute pointer-events-none inset-0 flex items-center justify-center dark:bg-[rgb(10,10,10)] bg-white [mask-image:radial-gradient(ellipse_at_center,transparent_20%,black)] " /> <div className="absolute pointer-events-none inset-0 flex items-center justify-center dark:bg-[rgb(10,10,10)] bg-white [mask-image:radial-gradient(ellipse_at_center,transparent_20%,black)] " />
<h1 className="bg-clip-text animate-fade-in -translate-y-4 bg-gradient-to-br from-black from-30% to-black/40 pb-6 text-5xl font-semibold tracking-tighter text-transparent opacity-0 [--animation-delay:200ms] sm:text-5xl md:text-6xl lg:text-7xl dark:from-white dark:to-white/40"> <h1 className="bg-clip-text animate-fade-in -translate-y-4 bg-gradient-to-br from-black from-30% to-black/40 pb-6 text-5xl font-semibold tracking-tighter text-transparent opacity-0 [--animation-delay:200ms] sm:text-5xl md:text-6xl lg:text-7xl dark:from-white dark:to-white/40">
The missing half of Minehut Meet MHSF, <br />
the modern server list
</h1> </h1>
<p className="animate-fade-in mb-12 -translate-y-4 text-balance text-lg tracking-tight text-neutral-400 opacity-0 [--animation-delay:400ms] md:text-xl "> <p className="animate-fade-in mb-12 -translate-y-4 text-balance text-lg tracking-tight text-neutral-400 opacity-0 [--animation-delay:400ms] md:text-xl ">
MHSF is the next generation Minehut server list wrapper, with <br /> MHSF is the next generation Minehut server list wrapper, with <br />
@ -225,13 +217,10 @@ export default function HomePageComponent() {
code: "2367", code: "2367",
}, },
]) ])
.reverse()
.flat() .flat()
.reverse()
.map((c) => ( .map((c) => (
<TypeScriptError <TypeScriptError name={c.name} code={c.code} key={c.code} />
name={c.name}
code={c.code}
/>
))} ))}
</AnimatedList> </AnimatedList>
@ -293,7 +282,7 @@ export default function HomePageComponent() {
For data hunters For data hunters
</Badge> </Badge>
</div> </div>
<section className="block mt-15 px-8 w-full text-center border-b"> <section className="md:flex mt-15 md:justify-center md:items-center px-8 w-full text-center border-b">
<span> <span>
<h1 className="animate-fade-in text-balance bg-gradient-to-br from-black from-30% to-black/40 bg-clip-text pb-6 text-2xl font-semibold leading-none tracking-tighter text-transparent opacity-0 [--animation-delay:200ms] sm:text-2xl md:text-3xl lg:text-4xl dark:from-white dark:to-white/40"> <h1 className="animate-fade-in text-balance bg-gradient-to-br from-black from-30% to-black/40 bg-clip-text pb-6 text-2xl font-semibold leading-none tracking-tighter text-transparent opacity-0 [--animation-delay:200ms] sm:text-2xl md:text-3xl lg:text-4xl dark:from-white dark:to-white/40">
Your data? <AuroraText>No problem.</AuroraText> Your data? <AuroraText>No problem.</AuroraText>
@ -305,13 +294,11 @@ export default function HomePageComponent() {
<br /> <br />
entries. entries.
</p> </p>
<ExampleChart />
<br />
</span> </span>
<div className="w-full">
<ExampleChart />
</div>
<br />
</section> </section>
<section className="md:flex relative overflow-hidden h-[500px] md:justify-center md:items-center px-8 w-full text-center border-b"> <section className="md:flex mt-15 md:justify-center md:items-center px-8 w-full text-center border-b">
<span> <span>
<h1 className="animate-fade-in text-balance bg-gradient-to-br from-black from-30% to-black/40 bg-clip-text pb-6 text-2xl font-semibold leading-none tracking-tighter text-transparent opacity-0 [--animation-delay:200ms] sm:text-2xl md:text-3xl lg:text-4xl dark:from-white dark:to-white/40"> <h1 className="animate-fade-in text-balance bg-gradient-to-br from-black from-30% to-black/40 bg-clip-text pb-6 text-2xl font-semibold leading-none tracking-tighter text-transparent opacity-0 [--animation-delay:200ms] sm:text-2xl md:text-3xl lg:text-4xl dark:from-white dark:to-white/40">
Don't trust us? <AuroraText>We're open-source.</AuroraText> Don't trust us? <AuroraText>We're open-source.</AuroraText>
@ -321,23 +308,16 @@ export default function HomePageComponent() {
completely open-source under the MIT License. completely open-source under the MIT License.
</p> </p>
<span className="flex items-center justify-center gap-2"> <span className="flex items-center justify-center gap-2">
<Link href="Special:GitHub"> <Link href="Special:GitHub">
<Button size="lg">Check it out!</Button> <Button>Check it out!</Button>
</Link> </Link>
<span className="flex items-center gap-2 border rounded-lg px-2 py-1"> <span className="flex items-center gap-2 border rounded-lg px-2 py-1">
<Star size={16} /> <Star size={16} />
<AvatarCircles numPeople={stars} avatarUrls={stargazers} /> <AvatarCircles numPeople={stars} avatarUrls={stargazers}/>
</span> </span>
</span> </span>
<br />
</span> </span>
<Ripple mainCircleSize={700}/>
</section> </section>
<div className="flex items-center justify-center border-b text-shadcn-primary/5 min-h-[50px] z-0">
<Badge className="animate-fade-in my-2 rounded-xl px-4 py-2 relative z-1 text-shadcn-primary">
For server <AuroraText>owners</AuroraText>
</Badge>
</div>
</section> </section>
</span> </span>
</div> </div>

@ -1,59 +0,0 @@
import React, { ComponentPropsWithoutRef, CSSProperties } from "react";
import { cn } from "@/lib/utils";
interface RippleProps extends ComponentPropsWithoutRef<"div"> {
mainCircleSize?: number;
mainCircleOpacity?: number;
numCircles?: number;
}
export const Ripple = React.memo(function Ripple({
mainCircleSize = 210,
mainCircleOpacity = 0.24,
numCircles = 8,
className,
...props
}: RippleProps) {
return (
<div
className={cn(
"pointer-events-none absolute inset-0 select-none [mask-image:linear-gradient(to_bottom,white,transparent)]",
className,
)}
{...props}
>
{Array.from({ length: numCircles }, (_, i) => {
const size = mainCircleSize + i * 70;
const opacity = mainCircleOpacity - i * 0.03;
const animationDelay = `${i * 0.06}s`;
const borderStyle = i === numCircles - 1 ? "dashed" : "solid";
const borderOpacity = 5 + i * 5;
return (
<div
key={i}
className={`absolute animate-ripple rounded-full border bg-foreground/25 shadow-xl`}
style={
{
"--i": i,
width: `${size}px`,
height: `${size}px`,
opacity,
animationDelay,
borderStyle,
borderWidth: "1px",
borderColor: `hsl(var(--foreground), ${borderOpacity / 100})`,
top: "50%",
left: "50%",
transform: "translate(-50%, -50%) scale(1)",
} as CSSProperties
}
/>
);
})}
</div>
);
});
Ripple.displayName = "Ripple";

@ -187,7 +187,7 @@ export function NavBar() {
</DropdownMenu> </DropdownMenu>
<SignedIn> <SignedIn>
<div <div
className="absolute right-0 z-10 h-full className="absolute right-0 -z-10 h-full
overflow-hidden w-full ml-auto" overflow-hidden w-full ml-auto"
style={{ borderRadius: "inherit" }} style={{ borderRadius: "inherit" }}
> >