Files
MineGeo/components/Shell.tsx

107 lines
3.1 KiB
TypeScript

import { getI18n } from "@/lib/i18n";
import "server-only";
import Link from "next/link";
import { Compass, ArrowUpRight } 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"
>
{account ? t("My account") : t("Log in")} <ArrowUpRight size={15} />
</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>
{forum && (
<a href={forum} target="_blank" rel="noopener noreferrer">
{t("Forum")}
</a>
)}
<a
href="https://minegeo.instatus.com/"
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>
);
}