const state = { session: null, selectedQuestion: null, lastAnswer: null, }; const els = { sessionForm: document.querySelector("#session-form"), answerForm: document.querySelector("#answer-form"), answerText: document.querySelector("#answer-text"), answerButton: document.querySelector("#answer-button"), questions: document.querySelector("#questions"), feedback: document.querySelector("#feedback"), status: document.querySelector("#status-line"), error: document.querySelector("#error-line"), title: document.querySelector("#session-title"), }; els.sessionForm.addEventListener("submit", async (event) => { event.preventDefault(); clearError(); setStatus("Creating diagnostic session..."); const payload = { user_id: value("#user-id"), target_role: value("#target-role"), stack: value("#stack").split(",").map((item) => item.trim()).filter(Boolean), interview_timeline: value("#timeline"), }; try { const session = await request("/api/v1/diagnostic-sessions", { method: "POST", body: JSON.stringify(payload), }); state.session = session; state.selectedQuestion = session.questions[0] || null; state.lastAnswer = null; renderSession(); renderFeedback(); setStatus(`Session ${session.id} ready`); } catch (error) { showError(error.message); setStatus("Ready"); } }); els.answerForm.addEventListener("submit", async (event) => { event.preventDefault(); clearError(); if (!state.session || !state.selectedQuestion) return; setStatus("Submitting answer..."); els.answerButton.disabled = true; try { const answer = await request(`/api/v1/diagnostic-sessions/${state.session.id}/answers`, { method: "POST", body: JSON.stringify({ question_id: state.selectedQuestion.id, answer_text: els.answerText.value, }), }); state.lastAnswer = answer; renderFeedback(); setStatus(`Answer graded as ${answer.grade.overall}`); } catch (error) { showError(error.message); setStatus("Session ready"); } finally { els.answerButton.disabled = !state.selectedQuestion; } }); function renderSession() { if (!state.session) return; els.title.textContent = `${state.session.target_role} ยท ${state.session.questions.length} questions`; els.questions.className = "question-list"; els.questions.innerHTML = ""; state.session.questions.forEach((question) => { const button = document.createElement("button"); button.type = "button"; button.className = "question-button"; button.setAttribute("aria-pressed", String(state.selectedQuestion?.id === question.id)); button.innerHTML = `${question.id}${escapeHTML(question.prompt)}`; button.addEventListener("click", () => { state.selectedQuestion = question; els.answerText.value = ""; renderSession(); setStatus(`Selected ${question.id}`); }); els.questions.append(button); }); els.answerButton.disabled = !state.selectedQuestion; } function renderFeedback() { if (!state.lastAnswer) { els.feedback.className = "feedback empty-state"; els.feedback.textContent = "Submit an answer to see grade, evidence, and follow-up."; return; } const grade = state.lastAnswer.grade; els.feedback.className = "feedback"; els.feedback.innerHTML = `
${escapeHTML(grade.overall)}

${escapeHTML(grade.strengths?.[0] || "Answer was graded.")}

${scoreRows(grade.scores)} ${listBlock("Gaps", grade.gaps)} ${followUpBlock(grade.follow_up)} ${evidenceBlock(grade.evidence)} `; } function scoreRows(scores) { return Object.entries(scores || {}) .map(([label, score]) => `
${escapeHTML(label.replaceAll("_", " "))} ${score}/4
`) .join(""); } function listBlock(title, items = []) { if (!items.length) return ""; return `

${title}

`; } function followUpBlock(followUp) { if (!followUp?.needed) return ""; return `

Follow-up

${escapeHTML(followUp.question)}

`; } function evidenceBlock(evidence = []) { if (!evidence.length) return ""; return `

Evidence

`; } async function request(url, options = {}) { const response = await fetch(url, { headers: { "Content-Type": "application/json" }, ...options, }); const body = await response.json(); if (!response.ok) { throw new Error(body.error || `Request failed: ${response.status}`); } return body; } function value(selector) { return document.querySelector(selector).value.trim(); } function setStatus(message) { els.status.textContent = message; } function showError(message) { els.error.textContent = message; } function clearError() { els.error.textContent = ""; } function escapeHTML(value) { return String(value) .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); }