Add CSV file upload and auto-delimiter detection for pilot import

Allows uploading a CSV file directly instead of only pasting text, and
auto-detects comma vs semicolon separators to support more locales.
This commit is contained in:
Jan Meinl
2026-08-19 15:32:26 +02:00
parent 4b5f0eb326
commit 65bb2b351f
10 changed files with 97 additions and 16 deletions
+19 -1
View File
@@ -953,15 +953,33 @@
function openImportModal() {
const backdrop = el("div", { class: "modal-backdrop",
onclick: (e) => { if (e.target === backdrop) backdrop.remove(); } });
let selectedFile = null;
const fileNameSpan = el("span", { class: "muted small", style: { marginLeft: "0.5rem" } }, "");
const fileInput = el("input", { type: "file", accept: ".csv,text/csv", style: { display: "none" },
onchange: (e) => {
selectedFile = e.target.files[0] || null;
fileNameSpan.textContent = selectedFile ? selectedFile.name : "";
},
});
const textarea = el("textarea", { placeholder: t("csv_paste"), style: { width: "100%", minHeight: "180px" } });
backdrop.appendChild(el("div", { class: "modal" },
el("h3", null, t("import_csv")),
el("p", { class: "muted small", style: { marginBottom: "0.5rem" } }, t("csv_separator_hint")),
el("div", { style: { marginBottom: "0.75rem", display: "flex", alignItems: "center" } },
fileInput,
el("button", { onclick: () => fileInput.click() }, t("upload_file")),
fileNameSpan,
),
textarea,
el("div", { class: "row", style: { justifyContent: "flex-end", marginTop: "1rem" } },
el("button", { onclick: () => backdrop.remove() }, t("cancel")),
el("button", { class: "primary", onclick: async () => {
try {
await API.importPilots(competitionId, textarea.value);
const data = selectedFile || textarea.value;
if (!data || (typeof data === "string" && !data.trim())) {
alert(t("csv_empty")); return;
}
await API.importPilots(competitionId, data);
await loadPilots();
backdrop.remove();
render();