/
potogon
/
statbit
Обзор
Документация
Войти
/
potogon
/
statbit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
beck.html
612 строк
21 KB
Alex
add 2 tests
28 июл 2026, 18:20
28 июл 2026, 18:20
a100df7
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Опросник депрессии Бека</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f4f6f9; color: #222; line-height: 1.5; } .container { max-width: 800px; margin: 0 auto; padding: 20px; } header { background: #4a6fa5; color: #fff; padding: 20px; text-align: center; } header h1 { font-size: 1.4rem; } .back-link { display: inline-block; margin-bottom: 16px; color: #4a6fa5; text-decoration: none; font-size: 0.9rem; } .card { background: #fff; border-radius: 12px; padding: 20px; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); } .intro-text { background: #eaf2fb; border-left: 4px solid #4a6fa5; padding: 16px; border-radius: 8px; margin-bottom: 20px; font-size: 0.95rem; color: #2c3e50; } .form-group { margin-bottom: 14px; } .form-group label { display: block; margin-bottom: 6px; font-weight: 500; color: #333; } .form-group input, .form-group select { width: 100%; padding: 10px 12px; border: 1px solid #d0d7de; border-radius: 8px; font-size: 1rem; background: #fff; } .form-group input:focus, .form-group select:focus { outline: none; border-color: #4a6fa5; box-shadow: 0 0 0 3px rgba(74,111,165,0.15); } .question { background: #fff; border-radius: 12px; padding: 18px; margin-bottom: 14px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); } .question-title { font-weight: 600; margin-bottom: 12px; color: #2c3e50; font-size: 1rem; } .option { display: flex; align-items: flex-start; padding: 10px; margin-bottom: 6px; border-radius: 8px; cursor: pointer; transition: background 0.15s, border-color 0.15s; border: 1px solid transparent; user-select: none; } .option:hover { background: #f4f6f9; } .option.selected { background: #eaf2fb; border-color: #4a6fa5; } .option input { margin-right: 10px; margin-top: 3px; flex-shrink: 0; cursor: pointer; width: 18px; height: 18px; } .option label { cursor: pointer; flex: 1; font-size: 0.95rem; line-height: 1.4; } .extra-question { margin-top: 12px; padding: 12px; background: #fff8e1; border-radius: 8px; border-left: 3px solid #f1c40f; } .extra-question p { margin-bottom: 8px; font-weight: 500; } .extra-options { display: flex; gap: 16px; } .extra-options label { display: flex; align-items: center; cursor: pointer; font-size: 0.95rem; } .extra-options input { margin-right: 6px; cursor: pointer; } .btn { display: block; width: 100%; background: #4a6fa5; color: #fff; padding: 14px; border-radius: 10px; border: none; font-size: 1rem; font-weight: 500; cursor: pointer; margin-top: 20px; transition: background 0.15s; } .btn:hover:not(:disabled) { background: #3a5a8c; } .btn:disabled { background: #a0aec0; cursor: not-allowed; } .result-card { background: #fff; border-radius: 12px; padding: 24px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.06); } .result-score { font-size: 3rem; font-weight: 700; color: #4a6fa5; margin: 12px 0; } .result-status { font-size: 1.1rem; color: #555; margin-bottom: 20px; } .hidden { display: none; } .error-msg { color: #c0392b; background: #fdecea; padding: 10px 14px; border-radius: 8px; margin-bottom: 12px; font-size: 0.9rem; } @media (max-width: 600px) { .container { padding: 12px; } header h1 { font-size: 1.2rem; } .question, .card { padding: 14px; } } </style> </head> <body> <header> <h1>Опросник депрессии Бека (BDI)</h1> </header> <div class="container"> <a href="index.html" class="back-link">← Назад к списку тестов</a> <!-- Шаг 1: Ввод данных --> <div id="step-intro"> <div class="card"> <h2 style="margin-bottom:16px;color:#2c3e50;">Данные участника</h2> <div class="form-group"> <label for="fio">ФИО *</label> <input type="text" id="fio" required placeholder="Иванов Иван Иванович"> </div> <div class="form-group"> <label for="age">Возраст *</label> <input type="number" id="age" min="1" max="120" required placeholder="25"> </div> <div class="form-group"> <label for="gender">Пол *</label> <select id="gender" required> <option value="">— Выберите —</option> <option value="Мужской">Мужской</option> <option value="Женский">Женский</option> </select> </div> <button class="btn" id="startBtn">Начать тест</button> </div> </div> <!-- Шаг 2: Вопросы --> <div id="step-questions" class="hidden"></div> <!-- Шаг 3: Результат --> <div id="step-result" class="hidden"> <div class="result-card"> <h2>Спасибо за прохождение теста!</h2> <div class="result-score" id="totalScore">0</div> <div class="result-status" id="resultStatus">—</div> <a href="index.html" class="btn">Вернуться на главную</a> </div> </div> </div> <script src="config.js"></script> <script> // Данные теста (21 группа) const QUESTIONS = [ { group: 1, options: [ 'Я не чувствую себя несчастным.', 'Я чувствую себя несчастным.', 'Я всё время несчастен и не могу освободиться от этого чувства.', 'Я настолько несчастен и опечален, что не могу этого вынести.' ] }, { group: 2, options: [ 'Думая о будущем, я не чувствую себя особенно разочарованным.', 'Думая о будущем, я чувствую себя разочарованным.', 'Я чувствую, что мне нечего ждать в будущем.', 'Я чувствую, что будущее безнадёжно и ничто не изменится к лучшему.' ] }, { group: 3, options: [ 'Я не чувствую себя неудачником.', 'Я чувствую, что у меня было больше неудач, чем у большинства других людей.', 'Когда я оглядываюсь на прожитую жизнь, всё, что я вижу – это череда неудач.', 'Я чувствую себя полным неудачником.' ] }, { group: 4, options: [ 'Я получаю столько же удовольствия от жизни, как и раньше.', 'Я не получаю столько же удовольствия от жизни, как раньше.', 'Я не получаю настоящего удовлетворения от чего бы то ни было.', 'Я всем не доволен, и мне всё надоело.' ] }, { group: 5, options: [ 'Я не чувствую себя особенно виноватым.', 'Довольно часто я чувствую себя виноватым.', 'Почти всегда я чувствую себя виноватым.', 'Я чувствую себя виноватым всё время.' ] }, { group: 6, options: [ 'Я не чувствую, что меня за что-то наказывают.', 'Я чувствую, что могу быть наказан за что-то.', 'Я ожидаю, что меня накажут.', 'Я чувствую, что меня наказывают за что-то.' ] }, { group: 7, options: [ 'Я не испытываю разочарования в себе.', 'Я разочарован в себе.', 'Я внушаю себе отвращение.', 'Я ненавижу себя.' ] }, { group: 8, options: [ 'У меня нет чувства, что я в чём-то хуже других.', 'Я самокритичен и признаю свои слабости и ошибки.', 'Я всё время виню себя за свои ошибки.', 'Я виню себя за всё плохое, что происходит.' ] }, { group: 9, options: [ 'У меня нет мыслей о том, чтобы покончить с собой.', 'У меня есть мысли о том, чтобы покончить с собой, но я этого не сделаю.', 'Я хотел бы покончить жизнь самоубийством.', 'Я бы покончил с собой, если бы представился удобный случай.' ] }, { group: 10, options: [ 'Я плачу не чаще обычного.', 'Сейчас я плачу больше обычного.', 'Я теперь всё время плачу.', 'Раньше я ещё мог плакать, но теперь не смогу, даже если захочу.' ] }, { group: 11, options: [ 'Сейчас я не более раздражен, чем обычно.', 'Я раздражаюсь легче, чем раньше, даже по пустякам.', 'Сейчас я всё время раздражён.', 'Меня уже ничто не раздражает, потому что всё стало безразлично.' ] }, { group: 12, options: [ 'Я не потерял интереса к другим людям.', 'У меня меньше интереса к другим людям.', 'Я почти утратил интерес к другим людям.', 'Я потерял всякий интерес к другим людям.' ] }, { group: 13, options: [ 'Я способен принимать решения так же, как всегда.', 'Я откладываю принятие решений чаще, чем обычно.', 'Я испытываю больше трудностей в принятии решений, чем прежде.', 'Я больше не могу принимать каких-либо решений.' ] }, { group: 14, options: [ 'Я не чувствую, что выгляжу хуже, чем обычно.', 'Я обеспокоен тем, что выгляжу постаревшим и непривлекательным.', 'Я чувствую, что изменения, произошедшие в моей внешности, сделали меня непривлекательным.', 'Я уверен, что выгляжу безобразным.' ] }, { group: 15, options: [ 'Я могу работать так же, как раньше.', 'Мне надо приложить дополнительные усилия, чтобы начать что-то делать.', 'Я с большим трудом заставляю себя что-то делать.', 'Я вообще не могу работать.' ] }, { group: 16, options: [ 'Я могу спать также хорошо, как и раньше.', 'Я сплю не так хорошо как всегда.', 'Я просыпаюсь на 1 – 2 часа раньше, чем обычно, и с трудом могу заснуть снова.', 'Я практически вообще не сплю.' ] }, { group: 17, options: [ 'Я устаю не больше обычного.', 'Я устаю легче обычного.', 'Я устаю почти от всего того, что я делаю.', 'Я слишком устал, чтобы делать что бы то ни было.' ] }, { group: 18, options: [ 'Мой аппетит не хуже, чем обычно.', 'У меня сейчас не такой хороший аппетит, как был раньше.', 'Сейчас мой аппетит стал намного хуже.', 'Я вообще потерял аппетит.' ] }, { group: 19, options: [ 'Если я в последнее время и потерял в весе, то немного.', 'Я потерял в весе более 2 кг.', 'Я потерял в весе более 4 кг.', 'Я потерял в весе более 6 кг.' ], extra: { question: 'Я специально пытался не есть, чтобы потерять в весе.', options: ['Да', 'Нет'] } }, { group: 20, options: [ 'Я беспокоюсь о своём здоровье не больше, чем обычно.', 'Меня беспокоят такие проблемы, как различные боли, расстройства желудка, запоры.', 'Я настолько обеспокоен своим здоровьем, что мне даже трудно думать о чём-нибудь другом.', 'Я до такой степени обеспокоен своим здоровьем, что вообще ни о чём другом не могу думать.' ] }, { group: 21, options: [ 'Я не замечал каких-либо изменений в моих сексуальных интересах.', 'Я меньше чем обычно интересуюсь сексом.', 'Сейчас я намного меньше интересуюсь сексом.', 'Я совершенно утратил интерес к сексу.' ] } ]; // Состояние const state = { answers: {}, // { groupIndex: [выбранные баллы] } extraQ19: null // 'Да' | 'Нет' | null }; // DOM const stepIntro = document.getElementById('step-intro'); const stepQuestions = document.getElementById('step-questions'); const stepResult = document.getElementById('step-result'); const startBtn = document.getElementById('startBtn'); // Старт теста startBtn.addEventListener('click', () => { const fio = document.getElementById('fio').value.trim(); const age = document.getElementById('age').value.trim(); const gender = document.getElementById('gender').value; if (!fio || !age || !gender) { alert('Пожалуйста, заполните все поля.'); return; } if (isNaN(age) || age < 1 || age > 120) { alert('Введите корректный возраст.'); return; } state.fio = fio; state.age = age; state.gender = gender; renderQuestions(); stepIntro.classList.add('hidden'); stepQuestions.classList.remove('hidden'); window.scrollTo(0, 0); }); function renderQuestions() { let html = ` <div class="intro-text"> Вам предлагается ряд утверждений. Выберите одно утверждение в каждой группе, которое лучше всего (точнее всего) описывает Ваше состояние за прошедшую неделю, включая сегодняшний день. Вы можете выбрать несколько утверждений в группе, если они в равной мере хорошо описывают Ваше состояние. Прежде чем сделать выбор, внимательно прочтите все утверждения в каждой группе. </div> `; QUESTIONS.forEach((q, idx) => { html += `<div class="question" data-group="${idx}">`; html += `<div class="question-title">Группа ${q.group}</div>`; q.options.forEach((opt, optIdx) => { const points = optIdx; // 0,1,2,3 html += ` <div class="option" data-points="${points}"> <input type="checkbox" name="g${idx}" value="${points}"> <label>${escapeHtml(opt)}</label> </div> `; }); if (q.extra) { html += ` <div class="extra-question"> <p>${escapeHtml(q.extra.question)}</p> <div class="extra-options"> ${q.extra.options.map((o, i) => ` <label> <input type="radio" name="extra19" value="${o}"> ${o} </label> `).join('')} </div> </div> `; } html += `</div>`; }); html += `<button class="btn" id="submitBtn">Завершить тест</button>`; stepQuestions.innerHTML = html; // Обработчики выбора — клик на всю область .option document.querySelectorAll('.option').forEach(optEl => { const input = optEl.querySelector('input'); optEl.addEventListener('click', (e) => { // Если клик был прямо на input — ничего не делаем, он сам переключится if (e.target === input) { optEl.classList.toggle('selected', input.checked); updateAnswers(); return; } // Иначе переключаем чекбокс вручную input.checked = !input.checked; optEl.classList.toggle('selected', input.checked); updateAnswers(); }); }); document.querySelectorAll('input[name="extra19"]').forEach(r => { r.addEventListener('change', () => { state.extraQ19 = r.value; }); }); document.getElementById('submitBtn').addEventListener('click', submitTest); } function updateAnswers() { QUESTIONS.forEach((q, idx) => { const checked = document.querySelectorAll(`input[name="g${idx}"]:checked`); const points = Array.from(checked).map(c => parseInt(c.value)); state.answers[idx] = points; }); } async function submitTest() { updateAnswers(); // Проверка: хотя бы один вариант в каждой группе for (let i = 0; i < QUESTIONS.length; i++) { if (!state.answers[i] || state.answers[i].length === 0) { alert(`Пожалуйста, выберите хотя бы один вариант в группе ${i + 1}.`); const el = document.querySelector(`[data-group="${i}"]`); if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' }); return; } } if (state.extraQ19 === null) { alert('Пожалуйста, ответьте на дополнительный вопрос в группе 19.'); document.querySelector('.extra-question').scrollIntoView({ behavior: 'smooth', block: 'center' }); return; } // Подсчёт баллов const totalScore = Object.values(state.answers).reduce( (sum, arr) => sum + arr.reduce((a, b) => a + b, 0), 0 ); // Формирование строки ответов по группам (через запятую выбранные баллы) const answersByGroup = QUESTIONS.map((q, idx) => { return (state.answers[idx] || []).join(','); }); const payload = { fio: state.fio, age: state.age, gender: state.gender, answers: answersByGroup, extraQ19: state.extraQ19, totalScore: totalScore, testName: 'Опросник депрессии Бека' }; // Блокируем кнопку const btn = document.getElementById('submitBtn'); btn.disabled = true; btn.textContent = 'Отправка результатов…'; try { const res = await fetch(CONFIG.apiUrl, { method: 'POST', headers: { 'Content-Type': 'text/plain;charset=utf-8' }, body: JSON.stringify({ action: 'saveResult', payload }) }); const json = await res.json(); if (!json.ok) throw new Error(json.error || 'Ошибка сохранения'); } catch (err) { alert('Ошибка при сохранении: ' + err.message + '\nРезультаты не были отправлены.'); btn.disabled = false; btn.textContent = 'Завершить тест'; return; } // Показ результата document.getElementById('totalScore').textContent = totalScore; document.getElementById('resultStatus').textContent = interpretScore(totalScore); stepQuestions.classList.add('hidden'); stepResult.classList.remove('hidden'); window.scrollTo(0, 0); } function interpretScore(score) { if (score <= 9) return 'Минимальная депрессия (норма)'; if (score <= 18) return 'Лёгкая депрессия (субдепрессия)'; if (score <= 29) return 'Умеренная депрессия'; return 'Тяжёлая депрессия'; } function escapeHtml(s) { return String(s).replace(/[&<>"']/g, c => ({ '&':'&','<':'<','>':'>','"':'"',"'":''' }[c])); } </script> </body> </html>