Add MineGeo gameplay systems and interface

This commit is contained in:
2026-10-10 10:27:47 +05:00
parent bf01d9801d
commit 9af71c85c2
47 changed files with 9954 additions and 93 deletions

View File

@@ -10,6 +10,8 @@ import { reportCategories } from "@/shared/moderation";
import type { Appeal } from "./MapAppeal";
import { ModeratorSettings } from "./ModeratorSettings";
import { ModeratorPrefixes } from "./ModeratorPrefixes";
import { isAdministrator, type StaffRole } from "@/shared/permissions";
import { DiscordIntegration } from "./DiscordIntegration";
type ReviewMap = {
id: string;
name: string;
@@ -45,7 +47,8 @@ export function Moderation() {
[reasons, setReasons] = useState<Record<string, string>>({});
const [preview, setPreview] = useState<string | null>(null),
[loading, setLoading] = useState(true);
const [authorized, setAuthorized] = useState(false);
const [role, setRole] = useState<StaffRole | null>(null);
const administrator = isAdministrator(role ?? undefined);
const [reportPreview, setReportPreview] = useState<{
id: string;
panorama: string | null;
@@ -53,17 +56,21 @@ export function Moderation() {
async function load() {
try {
const d = await api<{
role: StaffRole;
maps: ReviewMap[];
reports: typeof reports;
appeals: Appeal[];
}>("moderation");
setMaps(d.maps);
setAuthorized(true);
setRole(d.role);
setReports(d.reports);
setAppeals(d.appeals);
setError("");
} catch (e) {
setAuthorized(false);
setRole(null);
setMaps([]);
setReports([]);
setAppeals([]);
setError((e as Error).message);
} finally {
setLoading(false);
@@ -114,8 +121,16 @@ export function Moderation() {
}
return (
<>
{authorized && <ModeratorSettings />}
{authorized && <ModeratorPrefixes />}
{administrator && <ModeratorSettings />}
{administrator && <ModeratorPrefixes />}
{administrator && <DiscordIntegration />}
{role === "moderator" && (
<p className="muted">
{t(
"Moderators can inspect and review pending maps and updates. Other controls require Admin permission.",
)}
</p>
)}
{error && (
<p role="alert" className="error-message">
{t(error)}
@@ -185,7 +200,7 @@ export function Moderation() {
</button>
</>
) : null}
{m.state === "published" && (
{administrator && m.state === "published" && (
<button
className="button"
disabled={busy}
@@ -197,7 +212,7 @@ export function Moderation() {
</div>
</article>
))}
{reports.length > 0 && (
{administrator && reports.length > 0 && (
<section className="token-box">
<h2>{t("Community reports")}</h2>
<p className="muted">
@@ -284,7 +299,7 @@ export function Moderation() {
))}
</section>
)}
{appeals.length > 0 && (
{administrator && appeals.length > 0 && (
<section className="token-box">
<h2>{t("Map ban appeals")}</h2>
{appeals.map((a) => (