Improve MineGeo UI and application flows
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 2m37s

This commit is contained in:
2026-10-18 11:44:04 +05:00
parent ad73132f15
commit a7085e4e80
50 changed files with 4790 additions and 703 deletions

View File

@@ -9,6 +9,8 @@ import {
difficulties,
customDifficultySchema,
type DifficultyPreset,
type ScoringMode,
difficultyRuleDefaults,
} from "@/shared/protocol";
import { api } from "@/lib/client-api";
import { mergeDifficultyPresets } from "@/shared/difficulty-presets";
@@ -27,6 +29,13 @@ export function StartGame({
[difficultyName, setDifficultyName] = useState(""),
[difficultySeconds, setDifficultySeconds] = useState(90),
[difficultyZoom, setDifficultyZoom] = useState(true),
[difficultyRules, setDifficultyRules] = useState<{
pan: boolean;
compass: boolean;
coordinates: boolean;
mapZoom: boolean;
scoring: ScoringMode;
}>(difficultyRuleDefaults),
[savingDifficulty, setSavingDifficulty] = useState(false),
[mode, setMode] = useState<"solo" | "multiplayer">("solo"),
[playerLimit, setPlayerLimit] = useState(4),
@@ -67,6 +76,7 @@ export function StartGame({
name: difficultyName,
seconds: difficultySeconds,
zoom: difficultyZoom,
...difficultyRules,
});
if (!parsed.success) {
setError(parsed.error.issues[0].message);
@@ -85,6 +95,7 @@ export function StartGame({
setDifficultyName("");
setDifficultySeconds(90);
setDifficultyZoom(true);
setDifficultyRules(difficultyRuleDefaults);
setShowDifficultyForm(false);
} catch (failure) {
setError((failure as Error).message);
@@ -157,6 +168,18 @@ export function StartGame({
<ZoomIn size={13} />
{option.zoom ? t("Zoom allowed") : t("No zoom")}
</span>
{!(option.id in difficulties) && (
<span>
{t(
option.scoring === "strict"
? "Strict scoring"
: option.scoring === "gentle"
? "Gentle scoring"
: "Normal scoring",
)}{" "}
· {t(option.pan === false ? "Fixed view" : "Panning allowed")}
</span>
)}
</button>
))}
</div>
@@ -219,6 +242,52 @@ export function StartGame({
/>
{t("Allow zoom")}
</label>
{(
[
["pan", "Allow panorama panning"],
["compass", "Show north indicator"],
["coordinates", "Show guess coordinates"],
["mapZoom", "Allow guess-map zoom"],
] as const
).map(([key, label]) => (
<label className="difficulty-builder-zoom" key={key}>
<input
type="checkbox"
checked={difficultyRules[key]}
disabled={savingDifficulty || loading}
onChange={(event) =>
setDifficultyRules((previous) => ({
...previous,
[key]: event.target.checked,
}))
}
/>
{t(label)}
</label>
))}
<label htmlFor="custom-difficulty-scoring">
{t("Scoring strictness")}
</label>
<select
id="custom-difficulty-scoring"
value={difficultyRules.scoring}
disabled={savingDifficulty || loading}
onChange={(event) =>
setDifficultyRules((previous) => ({
...previous,
scoring: event.target.value as ScoringMode,
}))
}
>
<option value="normal">{t("Normal scoring")}</option>
<option value="strict">{t("Strict scoring")}</option>
<option value="gentle">{t("Gentle scoring")}</option>
</select>
<p className="muted">
{t(
"Strict scoring penalizes distance more; gentle scoring gives more credit for nearby guesses. Every game still has five rounds.",
)}
</p>
<button
className="button primary"
disabled={savingDifficulty || loading}