mirror of
https://github.com/DeveloLongScript/MHSF.git
synced 2026-05-09 08:55:00 -05:00
Compare commits
2 Commits
0db9f5aba2
...
697a5f2ed7
| Author | SHA1 | Date | |
|---|---|---|---|
| 697a5f2ed7 | |||
| 65dd761da8 |
@ -56,6 +56,12 @@ 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,4 +9367,10 @@ 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);}}
|
||||||
}
|
}
|
||||||
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 p-[20px] mt-15">
|
<footer className="w-full border-t mt-15">
|
||||||
<div className="flex justify-between items-start">
|
<div className="flex justify-between items-start p-[20px]">
|
||||||
<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 mt-4">
|
<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">
|
||||||
<small className="text-muted-foreground text-[0.75rem]">
|
<small className="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" />
|
||||||
|
|||||||
@ -46,16 +46,25 @@ 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 (await fetch("https://api.github.com/repos/DeveloLongScript/mhsf")).json()
|
const githubRepo = await (
|
||||||
const githubStargazers = await (await fetch("https://api.github.com/repos/DeveloLongScript/mhsf/stargazers")).json()
|
await fetch("https://api.github.com/repos/DeveloLongScript/mhsf")
|
||||||
|
).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: (githubStargazers as Array<{avatar_url: string, html_url: string}>).map((c) => {return {imageUrl: c.avatar_url, profileUrl: c.html_url}})
|
stargazers: (
|
||||||
}
|
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();
|
||||||
@ -77,8 +86,8 @@ export default function HomePageComponent() {
|
|||||||
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">
|
||||||
@ -108,8 +117,7 @@ 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">
|
||||||
Meet MHSF, <br />
|
The missing half of Minehut
|
||||||
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 />
|
||||||
@ -217,10 +225,13 @@ export default function HomePageComponent() {
|
|||||||
code: "2367",
|
code: "2367",
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.flat()
|
|
||||||
.reverse()
|
.reverse()
|
||||||
|
.flat()
|
||||||
.map((c) => (
|
.map((c) => (
|
||||||
<TypeScriptError name={c.name} code={c.code} key={c.code} />
|
<TypeScriptError
|
||||||
|
name={c.name}
|
||||||
|
code={c.code}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</AnimatedList>
|
</AnimatedList>
|
||||||
|
|
||||||
@ -282,7 +293,7 @@ export default function HomePageComponent() {
|
|||||||
For data hunters
|
For data hunters
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
<section className="md:flex mt-15 md:justify-center md:items-center px-8 w-full text-center border-b">
|
<section className="block mt-15 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>
|
||||||
@ -294,11 +305,13 @@ 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 mt-15 md:justify-center md:items-center px-8 w-full text-center border-b">
|
<section className="md:flex relative overflow-hidden h-[500px] 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>
|
||||||
@ -309,15 +322,22 @@ export default function HomePageComponent() {
|
|||||||
</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>Check it out!</Button>
|
<Button size="lg">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>
|
||||||
|
|||||||
59
apps/www/src/components/feat/home-page/ripple.tsx
Normal file
59
apps/www/src/components/feat/home-page/ripple.tsx
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
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" }}
|
||||||
>
|
>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user