UI bugfixes with boss

This commit is contained in:
Константин Лебединский
2026-04-30 19:53:49 +05:00
parent df6e770f90
commit b72b485fce
17 changed files with 469 additions and 250 deletions
+48 -31
View File
@@ -22,12 +22,6 @@
const btnFinish = document.getElementById('attempt-finish');
const resultEl = document.getElementById('attempt-result');
const hintModal = document.getElementById('hint-modal');
const hintVerdict = document.getElementById('hint-verdict');
const hintCorrect = document.getElementById('hint-correct');
const hintExplanation = document.getElementById('hint-explanation');
const hintCloseBtn = document.getElementById('hint-close-btn');
let playData = null;
const selections = {};
const checked = {};
@@ -65,6 +59,41 @@
return playData && playData.resultMode === 'immediate';
}
function formatAttemptMeta(d) {
const qs = d.questions || [];
const n = qs.length;
const tl = d.timeLimit;
const timestr = !tl || Number(tl) <= 0 ? 'без ограничения' : `${tl} мин`;
const res = d.resultMode === 'immediate' ? 'сразу' : 'в конце';
const hint = d.resultMode !== 'immediate'
? 'недоступны'
: (d.hintsEnabled ? 'вкл' : 'выкл');
const th = d.passingThreshold ?? 0;
return `Порог: ${th}% · Вопросов: ${n} · Время: ${timestr} · Результат: ${res} · Подсказки: ${hint}`;
}
function renderFeedbackPanel(data) {
const wrap = document.createElement('div');
wrap.className = 'attempt-feedback-panel';
const ok = data.isCorrect;
const verdict = document.createElement('p');
verdict.className = `attempt-feedback-verdict ${ok ? 'attempt-feedback-verdict--ok' : 'attempt-feedback-verdict--bad'}`;
verdict.textContent = ok ? 'Верно!' : 'Неверно.';
wrap.appendChild(verdict);
const correct = (data.correctOptionTexts || []).join('; ');
if (correct) {
const p = document.createElement('p');
p.className = 'attempt-feedback-correct';
p.textContent = `Правильный ответ: ${correct}`;
wrap.appendChild(p);
}
const exp = document.createElement('p');
exp.className = 'attempt-feedback-explanation';
exp.textContent = data.explanation || 'Объяснение недоступно.';
wrap.appendChild(exp);
return wrap;
}
function stepAnswered(q) {
const k = String(q.id);
if (isImmediate()) return !!checked[k];
@@ -151,6 +180,10 @@
}
card.appendChild(ul);
if (isChk && isImmediate() && playData.hintsEnabled) {
card.appendChild(renderFeedbackPanel(checked[qid]));
}
if (isImmediate() && !isChk) {
const wrap = document.createElement('div');
wrap.className = 'attempt-answer-actions';
@@ -204,29 +237,11 @@
if (!r.ok) throw new Error(data.error || 'Не удалось проверить ответ.');
checked[k] = data;
renderStep();
if (playData.hintsEnabled) {
showHint(data);
}
} catch (e) {
setErr(e.message);
}
}
function showHint(data) {
hintVerdict.textContent = data.isCorrect ? 'Верно!' : 'Неверно.';
hintVerdict.className = `attempt-hint-verdict ${data.isCorrect ? 'attempt-hint-verdict--ok' : 'attempt-hint-verdict--bad'}`;
const correct = (data.correctOptionTexts || []).join('; ');
hintCorrect.textContent = correct ? (`Правильный ответ: ${correct}`) : '';
hintExplanation.textContent = data.explanation || 'Объяснение недоступно.';
if (typeof hintModal.showModal === 'function') hintModal.showModal();
else hintModal.setAttribute('open', '');
}
hintCloseBtn.addEventListener('click', () => {
if (typeof hintModal.close === 'function') hintModal.close();
else hintModal.removeAttribute('open');
});
btnPrev.addEventListener('click', () => {
if (currentIdx <= 0) return;
currentIdx -= 1;
@@ -243,9 +258,14 @@
btnFinish.addEventListener('click', () => submit(false));
function startTimer(minutes) {
if (!minutes || minutes <= 0) return;
deadlineMs = Date.now() + minutes * 60 * 1000;
if (!timerEl) return;
timerEl.style.display = '';
if (!minutes || minutes <= 0) {
deadlineMs = null;
timerEl.textContent = 'без ограничения';
return;
}
deadlineMs = Date.now() + minutes * 60 * 1000;
const tick = () => {
const left = Math.max(0, deadlineMs - Date.now());
const m = Math.floor(left / 60000);
@@ -267,10 +287,7 @@
if (!r.ok) throw new Error(data.error || 'Не удалось открыть попытку.');
playData = data;
titleEl.textContent = data.testTitle || 'Прохождение теста';
const parts = [`Порог зачёта ${data.passingThreshold ?? 0}%`];
if (data.resultMode === 'immediate') parts.push('обратная связь после каждого ответа');
if (data.hintsEnabled) parts.push('с подсказками');
subEl.textContent = parts.join(' · ');
subEl.textContent = formatAttemptMeta(data);
if (!Array.isArray(data.questions) || !data.questions.length) {
setErr('В активной версии нет вопросов.');
btnNext.disabled = true;
@@ -279,7 +296,7 @@
}
currentIdx = 0;
renderStep();
if (data.timeLimit) startTimer(Number(data.timeLimit));
startTimer(Number(data.timeLimit));
} catch (e) {
setErr(e.message);
btnFinish.disabled = true;