import { initI18n, onLangChange, getLang, t } from "./i18n"; interface Office { key: string; label_de: string; label_en: string; } interface PartnerUnit { id: string; name: string; office: string; } let offices: Office[] = []; let partnerUnits: PartnerUnit[] = []; async function seedDisplayName(): Promise { const input = document.getElementById("onb-display-name") as HTMLInputElement; if (!input || input.value) return; // /api/me returns 404 for users without a paliad.users row, but includes // the JWT email so we can pre-fill the display name from the local-part // (e.g. "m.flexsiebels" from "m.flexsiebels@hlc.com"). Best-effort. try { const resp = await fetch("/api/me"); if (resp.status !== 404) return; const body = await resp.json().catch(() => null); const email = body && typeof body.email === "string" ? body.email : ""; const localPart = email.split("@")[0] || ""; if (localPart) input.value = localPart; } catch { /* non-fatal */ } } async function loadOffices(): Promise { try { const resp = await fetch("/api/offices"); if (!resp.ok) return; offices = await resp.json(); } catch { offices = []; } renderOfficeOptions(); } async function loadPartnerUnits(): Promise { try { const resp = await fetch("/api/partner-units"); if (!resp.ok) return; partnerUnits = (await resp.json()) as PartnerUnit[]; } catch { partnerUnits = []; } renderPartnerUnitOptions(); } function renderPartnerUnitOptions(): void { const select = document.getElementById("onb-partner-unit") as HTMLSelectElement | null; if (!select) return; const previous = select.value; const unassignedLabel = t("onboarding.partner_unit.unassigned") || "(noch keine Zuordnung)"; const head = ``; select.innerHTML = head + partnerUnits .map((u) => ``) .join(""); // Preserve a previous selection across language toggles (which re-render // the head option). if (previous && partnerUnits.some((u) => u.id === previous)) { select.value = previous; } } function renderOfficeOptions(): void { const select = document.getElementById("onb-office") as HTMLSelectElement | null; if (!select) return; const isEN = getLang() === "en"; const previous = select.value; const placeholder = ``; select.innerHTML = placeholder + offices .map((o) => { const label = isEN ? o.label_en : o.label_de; return ``; }) .join(""); if (previous && offices.some((o) => o.key === previous)) { select.value = previous; } } function esc(s: string): string { const d = document.createElement("div"); d.textContent = s; return d.innerHTML; } function clearMessages(): void { document.querySelectorAll(".login-error, .login-success").forEach((el) => el.remove()); } function showMessage(msg: string, cls: "login-error" | "login-success"): void { clearMessages(); const div = document.createElement("div"); div.className = cls; div.textContent = msg; const heading = document.querySelector(".onboarding-lede"); if (heading) heading.after(div); } async function submitForm(e: Event): Promise { e.preventDefault(); clearMessages(); const form = document.getElementById("onboarding-form") as HTMLFormElement; const submitBtn = form.querySelector('button[type="submit"]')!; const data = new FormData(form); const displayName = (data.get("display_name") as string || "").trim(); const office = (data.get("office") as string || "").trim(); const jobTitle = (data.get("job_title") as string || "").trim(); const profession = (data.get("profession") as string || "").trim(); const partnerUnitID = (data.get("partner_unit_id") as string || "").trim(); if (!displayName) { showMessage(t("onboarding.error.display_name"), "login-error"); return; } if (!office) { showMessage(t("onboarding.error.office"), "login-error"); return; } if (!jobTitle) { showMessage(t("onboarding.error.job_title"), "login-error"); return; } const payload: Record = { display_name: displayName, office, job_title: jobTitle, profession, }; if (partnerUnitID) payload.partner_unit_id = partnerUnitID; submitBtn.disabled = true; try { const resp = await fetch("/api/onboarding", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); if (resp.ok) { window.location.href = "/dashboard"; return; } if (resp.status === 409) { // Row already exists — user is onboarded. Push them forward. window.location.href = "/dashboard"; return; } const body = await resp.json().catch(() => ({}) as { error?: string }); showMessage(body.error || t("onboarding.error.generic"), "login-error"); submitBtn.disabled = false; } catch { showMessage(t("onboarding.error.connection"), "login-error"); submitBtn.disabled = false; } } document.addEventListener("DOMContentLoaded", () => { initI18n(); seedDisplayName(); document.getElementById("onboarding-form")!.addEventListener("submit", submitForm); loadOffices(); loadPartnerUnits(); onLangChange(() => { renderOfficeOptions(); renderPartnerUnitOptions(); }); });