Add player count fields with validation and labeled UX

This commit is contained in:
2026-01-29 01:53:24 +01:00
parent f713756ece
commit af84fc50d4
10 changed files with 415 additions and 32 deletions

View File

@@ -294,7 +294,7 @@ function setupHandlers() {
$("suggest-form").addEventListener("submit", async (e) => {
e.preventDefault();
const form = e.target;
const data = Object.fromEntries(new FormData(form).entries());
const data = normalizeSuggestionForm(new FormData(form));
if (!data.name) return toast("Name required", true);
if (data.screenshotUrl && !isValidImageUrl(data.screenshotUrl)) {
return toast("Screenshot URL must be http(s) and end with an image file.", true);
@@ -406,6 +406,7 @@ function buildCard(s, { showAuthor = false, allowDelete = false, allowEdit = fal
</div>
${s.genre ? `<p class="muted">${s.genre}</p>` : ""}
${s.description ? `<p>${s.description}</p>` : ""}
${(s.minPlayers || s.maxPlayers) ? `<p class="muted">Players: ${s.minPlayers ?? "?"}${s.maxPlayers ?? "?"}</p>` : ""}
</div>
`;
if (hasImage) {
@@ -470,7 +471,7 @@ function openEditModal(s) {
const form = overlay.querySelector("#edit-form");
form?.addEventListener("submit", async (e) => {
e.preventDefault();
const data = Object.fromEntries(new FormData(form).entries());
const data = normalizeSuggestionForm(new FormData(form));
if (data.screenshotUrl && !isValidImageUrl(data.screenshotUrl)) {
return toast("Screenshot URL must be http(s) and end with an image file.", true);
}
@@ -535,3 +536,22 @@ function isValidImageUrl(url) {
return false;
}
}
function normalizeSuggestionForm(formData) {
const obj = Object.fromEntries(formData.entries());
const parseNum = (v) => {
if (v === undefined || v === null || v === "") return null;
const n = Number(v);
return Number.isFinite(n) ? n : null;
};
return {
name: obj.name?.trim(),
genre: obj.genre?.trim() || null,
description: obj.description?.trim() || null,
screenshotUrl: obj.screenshotUrl?.trim() || null,
youtubeUrl: obj.youtubeUrl?.trim() || null,
gameUrl: obj.gameUrl?.trim() || null,
minPlayers: parseNum(obj.minPlayers),
maxPlayers: parseNum(obj.maxPlayers),
};
}