76 lines
2.8 KiB
TypeScript
76 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
|
import type { EodDifficulty, EodStats } from "@/app/(frontend)/minigames/eod/actions";
|
|
import { isEodUnlocked } from "@/lib/minigames/custom/eod";
|
|
import { useRealtimePresence } from "@/hooks/useRealtimePresence";
|
|
import { useSidebar } from "@/components/ui/sidebar";
|
|
import { UnlockNotice } from "@/components/frontend/minigames/UnlockNotice";
|
|
import { UgcLinkButton } from "@/components/frontend/minigames/UgcLinkButton";
|
|
import { EodLeaderboard } from "./EodLeaderboard";
|
|
import { MinesweeperBoard } from "./MinesweeperBoard";
|
|
|
|
export function EodArena({
|
|
initialStats,
|
|
currentUserId,
|
|
}: {
|
|
initialStats: EodStats;
|
|
currentUserId: number | string;
|
|
}) {
|
|
const [refreshKey, setRefreshKey] = useState(0);
|
|
const [playing, setPlaying] = useState(false);
|
|
const [selectedDifficulty, setSelectedDifficulty] = useState<EodDifficulty>("training");
|
|
const { isMobile, setOpenMobile } = useSidebar();
|
|
const activeTeams = useRealtimePresence("eod", playing, true);
|
|
const onPhaseChange = useCallback((phase: "ready" | "playing" | "over") => {
|
|
setPlaying(phase === "playing");
|
|
}, []);
|
|
|
|
const customUnlocked = isEodUnlocked({
|
|
bestTrainingTime: initialStats.bestTrainingTime,
|
|
bestPerimeterTime: initialStats.bestPerimeterTime,
|
|
bestSupplyRoadTime: initialStats.bestSupplyRoadTime,
|
|
});
|
|
const clearedSectors = [
|
|
initialStats.bestTrainingTime,
|
|
initialStats.bestPerimeterTime,
|
|
].filter((time) => time > 0).length;
|
|
|
|
useEffect(() => {
|
|
if (playing && isMobile) setOpenMobile(false);
|
|
}, [isMobile, playing, setOpenMobile]);
|
|
|
|
return (
|
|
<div className="flex flex-col items-center gap-6">
|
|
{customUnlocked && (
|
|
<UgcLinkButton
|
|
href="/minigames/eod/custom"
|
|
title="UGC Minefields"
|
|
subtitle="Play, compete for, and create custom minefields you can share with other unit members! You can even earn XP for playing maps, and as an author, every payout on your map nets you some XP, too."
|
|
unlocked={customUnlocked}
|
|
className="max-w-5xl"
|
|
/>
|
|
)}
|
|
{!customUnlocked && (
|
|
<UnlockNotice
|
|
title="custom minefields"
|
|
requirement="you have cleared Training Pad and FOB Perimeter"
|
|
progress={`${clearedSectors} of 2 sectors cleared`}
|
|
/>
|
|
)}
|
|
<MinesweeperBoard
|
|
initialStats={initialStats}
|
|
onGameRecorded={() => setRefreshKey((key) => key + 1)}
|
|
onPhaseChange={onPhaseChange}
|
|
onDifficultyChange={setSelectedDifficulty}
|
|
/>
|
|
<EodLeaderboard
|
|
refreshKey={refreshKey}
|
|
currentUserId={currentUserId}
|
|
activeTeams={activeTeams}
|
|
difficulty={selectedDifficulty}
|
|
onDifficultyChange={setSelectedDifficulty}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|