feat(eod): update difficulty selection in EOD components and bump version to 0.2.0
This commit is contained in:
parent
7a34c3901e
commit
d740d43800
4 changed files with 16 additions and 5 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "polaris-task-force",
|
"name": "polaris-task-force",
|
||||||
"version": "0.1.6",
|
"version": "0.2.0",
|
||||||
"description": "Web app for the Arma 3 unit Polaris Task Force. Uses Next.js for client- and server-side rendering, with a Postgres database and some other neat libraries.",
|
"description": "Web app for the Arma 3 unit Polaris Task Force. Uses Next.js for client- and server-side rendering, with a Postgres database and some other neat libraries.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import type { EodStats } from "@/app/(frontend)/eod/actions";
|
import type { EodDifficulty, EodStats } from "@/app/(frontend)/eod/actions";
|
||||||
import { useRealtimePresence } from "@/hooks/useRealtimePresence";
|
import { useRealtimePresence } from "@/hooks/useRealtimePresence";
|
||||||
import { EodLeaderboard } from "./EodLeaderboard";
|
import { EodLeaderboard } from "./EodLeaderboard";
|
||||||
import { MinesweeperBoard } from "./MinesweeperBoard";
|
import { MinesweeperBoard } from "./MinesweeperBoard";
|
||||||
|
|
@ -15,6 +15,7 @@ export function EodArena({
|
||||||
}) {
|
}) {
|
||||||
const [refreshKey, setRefreshKey] = useState(0);
|
const [refreshKey, setRefreshKey] = useState(0);
|
||||||
const [playing, setPlaying] = useState(false);
|
const [playing, setPlaying] = useState(false);
|
||||||
|
const [selectedDifficulty, setSelectedDifficulty] = useState<EodDifficulty>("training");
|
||||||
const activeTeams = useRealtimePresence("eod", playing, true);
|
const activeTeams = useRealtimePresence("eod", playing, true);
|
||||||
const onPhaseChange = useCallback((phase: "ready" | "playing" | "over") => {
|
const onPhaseChange = useCallback((phase: "ready" | "playing" | "over") => {
|
||||||
setPlaying(phase === "playing");
|
setPlaying(phase === "playing");
|
||||||
|
|
@ -26,11 +27,14 @@ export function EodArena({
|
||||||
initialStats={initialStats}
|
initialStats={initialStats}
|
||||||
onGameRecorded={() => setRefreshKey((key) => key + 1)}
|
onGameRecorded={() => setRefreshKey((key) => key + 1)}
|
||||||
onPhaseChange={onPhaseChange}
|
onPhaseChange={onPhaseChange}
|
||||||
|
onDifficultyChange={setSelectedDifficulty}
|
||||||
/>
|
/>
|
||||||
<EodLeaderboard
|
<EodLeaderboard
|
||||||
refreshKey={refreshKey}
|
refreshKey={refreshKey}
|
||||||
currentUserId={currentUserId}
|
currentUserId={currentUserId}
|
||||||
activeTeams={activeTeams}
|
activeTeams={activeTeams}
|
||||||
|
difficulty={selectedDifficulty}
|
||||||
|
onDifficultyChange={setSelectedDifficulty}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import {
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import type { EodDifficulty } from "@/app/(frontend)/eod/actions";
|
||||||
import type { PresenceParticipant } from "@/hooks/useRealtimePresence";
|
import type { PresenceParticipant } from "@/hooks/useRealtimePresence";
|
||||||
|
|
||||||
interface ApiUser {
|
interface ApiUser {
|
||||||
|
|
@ -58,6 +59,8 @@ interface EodLeaderboardProps {
|
||||||
refreshKey?: number;
|
refreshKey?: number;
|
||||||
currentUserId?: number | string;
|
currentUserId?: number | string;
|
||||||
activeTeams?: PresenceParticipant[];
|
activeTeams?: PresenceParticipant[];
|
||||||
|
difficulty: EodDifficulty;
|
||||||
|
onDifficultyChange: (difficulty: EodDifficulty) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function rankClass(index: number) {
|
function rankClass(index: number) {
|
||||||
|
|
@ -71,8 +74,9 @@ export function EodLeaderboard({
|
||||||
refreshKey = 0,
|
refreshKey = 0,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
activeTeams = [],
|
activeTeams = [],
|
||||||
|
difficulty,
|
||||||
|
onDifficultyChange,
|
||||||
}: EodLeaderboardProps) {
|
}: EodLeaderboardProps) {
|
||||||
const [difficulty, setDifficulty] = useState<"training" | "perimeter" | "supplyRoad">("training");
|
|
||||||
const [rows, setRows] = useState<LeaderboardRow[] | null>(null);
|
const [rows, setRows] = useState<LeaderboardRow[] | null>(null);
|
||||||
const [failed, setFailed] = useState(false);
|
const [failed, setFailed] = useState(false);
|
||||||
|
|
||||||
|
|
@ -146,7 +150,7 @@ export function EodLeaderboard({
|
||||||
<div className="ml-auto flex items-center gap-2 text-xs text-muted-foreground">
|
<div className="ml-auto flex items-center gap-2 text-xs text-muted-foreground">
|
||||||
<Select
|
<Select
|
||||||
value={difficulty}
|
value={difficulty}
|
||||||
onValueChange={(value) => setDifficulty(value as typeof difficulty)}
|
onValueChange={(value) => onDifficultyChange(value as EodDifficulty)}
|
||||||
>
|
>
|
||||||
<SelectTrigger aria-label="Leaderboard sector" className="h-8 w-[150px] text-xs">
|
<SelectTrigger aria-label="Leaderboard sector" className="h-8 w-[150px] text-xs">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
|
|
|
||||||
|
|
@ -174,10 +174,12 @@ export function MinesweeperBoard({
|
||||||
initialStats: serverStats,
|
initialStats: serverStats,
|
||||||
onGameRecorded,
|
onGameRecorded,
|
||||||
onPhaseChange,
|
onPhaseChange,
|
||||||
|
onDifficultyChange,
|
||||||
}: {
|
}: {
|
||||||
initialStats: EodStats;
|
initialStats: EodStats;
|
||||||
onGameRecorded: () => void;
|
onGameRecorded: () => void;
|
||||||
onPhaseChange: (phase: Phase) => void;
|
onPhaseChange: (phase: Phase) => void;
|
||||||
|
onDifficultyChange: (difficulty: EodDifficulty) => void;
|
||||||
}) {
|
}) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [difficulty, setDifficulty] = useState<GameMode>("training");
|
const [difficulty, setDifficulty] = useState<GameMode>("training");
|
||||||
|
|
@ -240,13 +242,14 @@ export function MinesweeperBoard({
|
||||||
if (submittingRef.current) return;
|
if (submittingRef.current) return;
|
||||||
const nextConfig = nextDifficulty === "custom" ? customConfig : DIFFICULTIES[nextDifficulty];
|
const nextConfig = nextDifficulty === "custom" ? customConfig : DIFFICULTIES[nextDifficulty];
|
||||||
setDifficulty(nextDifficulty);
|
setDifficulty(nextDifficulty);
|
||||||
|
if (nextDifficulty !== "custom") onDifficultyChange(nextDifficulty);
|
||||||
setBoard(emptyBoard(nextConfig.rows * nextConfig.cols));
|
setBoard(emptyBoard(nextConfig.rows * nextConfig.cols));
|
||||||
generatedRef.current = false;
|
generatedRef.current = false;
|
||||||
setSeconds(0);
|
setSeconds(0);
|
||||||
setLastRun(null);
|
setLastRun(null);
|
||||||
setPhaseSafe("ready");
|
setPhaseSafe("ready");
|
||||||
},
|
},
|
||||||
[customConfig, difficulty, setPhaseSafe],
|
[customConfig, difficulty, onDifficultyChange, setPhaseSafe],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue