Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 8m16s
119 lines
3.5 KiB
TypeScript
119 lines
3.5 KiB
TypeScript
import { getI18n } from "@/lib/i18n";
|
|
import "server-only";
|
|
import Link from "next/link";
|
|
import { Compass, ArrowUpRight, UserRound } from "lucide-react";
|
|
import { LanguageSwitcher } from "./LanguageSwitcher";
|
|
import { rawUser, admin, required } from "@/lib/supabase";
|
|
import { canReviewMaps, isAdministrator } from "@/shared/permissions";
|
|
import { Brand } from "./Brand";
|
|
import { SiteNav } from "./SiteNav";
|
|
import { ReportBugButton } from "./ReportBugButton";
|
|
import { ThemeToggle } from "./ThemeToggle";
|
|
import { CommunityLinks } from "./CommunityLinks";
|
|
import { forumUrl } from "@/lib/forum";
|
|
export async function Header() {
|
|
const { t } = await getI18n();
|
|
const account = await rawUser();
|
|
return (
|
|
<header className="site-header">
|
|
<div className="header-inner">
|
|
<Brand />
|
|
<SiteNav forumUrl={forumUrl()} />
|
|
<div className="header-actions">
|
|
<ThemeToggle />
|
|
<ReportBugButton />
|
|
<Link
|
|
href={account ? "/dashboard" : "/log-in"}
|
|
className="header-account"
|
|
aria-label={account ? t("My account") : t("Log in")}
|
|
>
|
|
<UserRound
|
|
size={18}
|
|
className="account-symbol"
|
|
aria-hidden="true"
|
|
/>
|
|
<span>{account ? t("My account") : t("Log in")}</span>{" "}
|
|
<ArrowUpRight
|
|
className="account-arrow"
|
|
size={15}
|
|
aria-hidden="true"
|
|
/>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|
|
export async function Footer() {
|
|
const { t } = await getI18n();
|
|
const forum = forumUrl();
|
|
const account = await rawUser();
|
|
const result = account
|
|
? await admin()
|
|
.from("profiles")
|
|
.select("role,account_status")
|
|
.eq("id", account.id)
|
|
.maybeSingle()
|
|
: null;
|
|
if (result?.error) required(result);
|
|
const role =
|
|
result?.data?.account_status === "active" ? result.data.role : undefined;
|
|
return (
|
|
<footer className="site-footer">
|
|
<div>
|
|
<Brand />
|
|
<p>{t("A familiar world. A whole new perspective.")}</p>
|
|
<CommunityLinks />
|
|
</div>
|
|
<div>
|
|
<ThemeToggle />
|
|
<LanguageSwitcher />
|
|
<Link href="/downloads">{t("Tools & downloads")}</Link>
|
|
<Link href="/docs">{t("Docs")}</Link>
|
|
<Link href="/changelogs">{t("Changelogs")}</Link>
|
|
{forum && (
|
|
<a href={forum} target="_blank" rel="noopener noreferrer">
|
|
{t("Forum")}
|
|
</a>
|
|
)}
|
|
<a
|
|
href="https://status.minegeo.site/"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
>
|
|
{t("Status")}
|
|
</a>
|
|
<Link href="/leaderboard">{t("Leaderboard")}</Link>
|
|
{canReviewMaps(role) && (
|
|
<Link href="/moderation">{t("Moderation Tools")}</Link>
|
|
)}
|
|
{isAdministrator(role) && <Link href="/admin">{t("Admin Tools")}</Link>}
|
|
</div>
|
|
<p className="disclaimer">
|
|
{t(
|
|
"An independent community project. Not affiliated with Mojang or Microsoft.",
|
|
)}
|
|
</p>
|
|
</footer>
|
|
);
|
|
}
|
|
export async function EmptyState({
|
|
title,
|
|
children,
|
|
}: {
|
|
title: string;
|
|
children: React.ReactNode;
|
|
}) {
|
|
const { t } = await getI18n();
|
|
return (
|
|
<div className="empty-state">
|
|
<Compass size={36} />
|
|
<h3>{t(title)}</h3>
|
|
<p>{children}</p>
|
|
<Link className="button primary" href="/downloads">
|
|
{t("Create the first map")} <ArrowUpRight size={16} />
|
|
</Link>
|
|
</div>
|
|
);
|
|
}
|