225 lines
10 KiB
HTML
225 lines
10 KiB
HTML
<!doctype html>
|
|
<html lang="kk">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Жол Ережелері - Тест</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body { font-family: -apple-system, "Segoe UI", Roboto, sans-serif; background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); min-height: 100vh; color: #fff; }
|
|
.container { max-width: 900px; margin: 0 auto; padding: 20px; }
|
|
header { text-align: center; padding: 40px 20px; }
|
|
header h1 { font-size: clamp(28px, 5vw, 42px); margin-bottom: 10px; background: linear-gradient(90deg, #00d9ff, #00ff88); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
|
|
header p { color: #a0a0b0; font-size: 18px; }
|
|
.stats { display: flex; gap: 15px; justify-content: center; flex-wrap: wrap; margin: 20px 0; }
|
|
.stat-card { background: rgba(255,255,255,0.1); backdrop-filter: blur(10px); border-radius: 12px; padding: 15px 25px; text-align: center; min-width: 140px; }
|
|
.stat-card .num { font-size: 28px; font-weight: bold; color: #00ff88; }
|
|
.stat-card .label { font-size: 14px; color: #a0a0b0; margin-top: 5px; }
|
|
.category-filter { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin: 20px 0; }
|
|
.cat-btn { padding: 10px 18px; border: 2px solid rgba(255,255,255,0.2); background: rgba(255,255,255,0.05); color: #fff; border-radius: 25px; cursor: pointer; font-size: 14px; transition: all 0.3s; }
|
|
.cat-btn:hover, .cat-btn.active { background: #00d9ff; border-color: #00d9ff; color: #1a1a2e; }
|
|
.question-card { background: rgba(255,255,255,0.08); backdrop-filter: blur(10px); border-radius: 16px; padding: 25px; margin: 20px 0; border: 1px solid rgba(255,255,255,0.1); }
|
|
.question-num { display: inline-block; background: #00d9ff; color: #1a1a2e; padding: 4px 12px; border-radius: 20px; font-weight: bold; font-size: 14px; margin-bottom: 12px; }
|
|
.question-text { font-size: 18px; line-height: 1.6; margin-bottom: 20px; }
|
|
.options { display: flex; flex-direction: column; gap: 10px; }
|
|
.option { padding: 15px 20px; background: rgba(255,255,255,0.05); border: 2px solid rgba(255,255,255,0.1); border-radius: 10px; cursor: pointer; transition: all 0.3s; font-size: 16px; }
|
|
.option:hover { background: rgba(0,217,255,0.1); border-color: #00d9ff; }
|
|
.option.correct { background: rgba(0,255,136,0.2); border-color: #00ff88; }
|
|
.option.wrong { background: rgba(255,82,82,0.2); border-color: #ff5252; }
|
|
.result-box { background: rgba(0,255,136,0.15); border: 2px solid #00ff88; border-radius: 12px; padding: 20px; margin-top: 20px; text-align: center; }
|
|
.result-box h3 { font-size: 24px; margin-bottom: 10px; }
|
|
.result-box .score { font-size: 42px; font-weight: bold; color: #00ff88; }
|
|
.explanation { background: rgba(255,193,7,0.1); border-left: 4px solid #ffc107; padding: 15px; margin-top: 15px; border-radius: 0 8px 8px 0; font-size: 15px; line-height: 1.6; }
|
|
.explanation strong { color: #ffc107; }
|
|
.controls { display: flex; gap: 10px; justify-content: center; margin: 30px 0; }
|
|
.btn { padding: 12px 30px; border: none; border-radius: 25px; cursor: pointer; font-size: 16px; font-weight: bold; transition: all 0.3s; }
|
|
.btn-primary { background: linear-gradient(90deg, #00d9ff, #00ff88); color: #1a1a2e; }
|
|
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 5px 20px rgba(0,217,255,0.4); }
|
|
.btn-secondary { background: rgba(255,255,255,0.1); color: #fff; border: 2px solid rgba(255,255,255,0.2); }
|
|
.btn-secondary:hover { background: rgba(255,255,255,0.2); }
|
|
.progress-bar { height: 6px; background: rgba(255,255,255,0.1); border-radius: 3px; overflow: hidden; margin: 20px 0; }
|
|
.progress-fill { height: 100%; background: linear-gradient(90deg, #00d9ff, #00ff88); transition: width 0.3s; }
|
|
.search-box { margin: 20px 0; text-align: center; }
|
|
.search-box input { width: 100%; max-width: 400px; padding: 12px 20px; border: 2px solid rgba(255,255,255,0.2); background: rgba(255,255,255,0.05); border-radius: 25px; color: #fff; font-size: 16px; }
|
|
.search-box input:focus { outline: none; border-color: #00d9ff; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<header>
|
|
<h1>🚦 Жол Қозғалысы Ережелері</h1>
|
|
<p>2025 жылғы айыппұлдар кестесі бойынша тест (80 сұрақ)</p>
|
|
</header>
|
|
|
|
<div class="stats">
|
|
<div class="stat-card">
|
|
<div class="num" id="totalQuestions">0</div>
|
|
<div class="label">Барлық сұрақ</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="num" id="answeredCount">0</div>
|
|
<div class="label">Жауап берілген</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="num" id="correctCount">0</div>
|
|
<div class="label">Дұрыс</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="num" id="scorePercent">0%</div>
|
|
<div class="label">Нәтиже</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="search-box">
|
|
<input type="text" id="searchInput" placeholder="🔍 Сұрақтарды іздеу...">
|
|
</div>
|
|
|
|
<div class="category-filter" id="categoryFilter"></div>
|
|
|
|
<div class="progress-bar">
|
|
<div class="progress-fill" id="progressBar" style="width: 0%"></div>
|
|
</div>
|
|
|
|
<div id="questionsContainer"></div>
|
|
|
|
<div class="controls">
|
|
<button class="btn btn-primary" onclick="checkAllAnswers()">✅ Жауаптарды тексеру</button>
|
|
<button class="btn btn-secondary" onclick="resetTest()">🔄 Қайта бастау</button>
|
|
</div>
|
|
|
|
<div class="result-box" id="resultBox" style="display: none;">
|
|
<h3>📊 Сіздің нәтижеңіз</h3>
|
|
<div class="score" id="finalScore"></div>
|
|
<p id="finalMessage"></p>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="questions.js"></script>
|
|
<script>
|
|
let currentCategory = "Барлығы";
|
|
let answered = {};
|
|
|
|
function getCategories() {
|
|
const cats = [...new Set(questions.map(q => q.category))];
|
|
return ["Барлығы", ...cats];
|
|
}
|
|
|
|
function renderCategories() {
|
|
const container = document.getElementById("categoryFilter");
|
|
const categories = getCategories();
|
|
container.innerHTML = categories.map(cat =>
|
|
'<button class="cat-btn ' + (cat === currentCategory ? "active" : "") + '" onclick="filterCategory(\'' + cat + '\')">' + cat + '</button>'
|
|
).join("");
|
|
}
|
|
|
|
function filterCategory(cat) {
|
|
currentCategory = cat;
|
|
renderCategories();
|
|
renderQuestions();
|
|
}
|
|
|
|
function renderQuestions() {
|
|
const container = document.getElementById("questionsContainer");
|
|
const filtered = currentCategory === "Барлығы"
|
|
? questions
|
|
: questions.filter(q => q.category === currentCategory);
|
|
|
|
document.getElementById("totalQuestions").textContent = filtered.length;
|
|
|
|
container.innerHTML = filtered.map((q, idx) => {
|
|
const realIdx = questions.indexOf(q);
|
|
const userAnswer = answered[realIdx];
|
|
let optionsHtml = q.options.map((opt, optIdx) => {
|
|
let className = "option";
|
|
if (userAnswer !== undefined) {
|
|
if (optIdx === q.correct) className += " correct";
|
|
else if (optIdx === userAnswer) className += " wrong";
|
|
}
|
|
return '<div class="' + className + '" onclick="selectAnswer(' + realIdx + ', ' + optIdx + ')">' + opt + '</div>';
|
|
}).join("");
|
|
|
|
let explanationHtml = "";
|
|
if (userAnswer !== undefined) {
|
|
explanationHtml = '<div class="explanation"><strong>Түсініктеме:</strong> ' + q.explanation + '</div>';
|
|
}
|
|
|
|
return '<div class="question-card">' +
|
|
'<span class="question-num">Сұрақ ' + (idx + 1) + '</span>' +
|
|
'<div class="question-text">' + q.question + '</div>' +
|
|
'<div class="options">' + optionsHtml + '</div>' +
|
|
explanationHtml +
|
|
'</div>';
|
|
}).join("");
|
|
|
|
updateStats();
|
|
}
|
|
|
|
function selectAnswer(qIdx, optIdx) {
|
|
if (answered[qIdx] !== undefined) return;
|
|
answered[qIdx] = optIdx;
|
|
renderQuestions();
|
|
}
|
|
|
|
function updateStats() {
|
|
const total = questions.length;
|
|
const answeredCount = Object.keys(answered).length;
|
|
const correctCount = Object.keys(answered).filter(k => answered[k] === questions[k].correct).length;
|
|
const percent = answeredCount > 0 ? Math.round((correctCount / answeredCount) * 100) : 0;
|
|
|
|
document.getElementById("answeredCount").textContent = answeredCount;
|
|
document.getElementById("correctCount").textContent = correctCount;
|
|
document.getElementById("scorePercent").textContent = percent + "%";
|
|
document.getElementById("progressBar").style.width = (answeredCount / total * 100) + "%";
|
|
}
|
|
|
|
function checkAllAnswers() {
|
|
const total = questions.length;
|
|
const answeredCount = Object.keys(answered).length;
|
|
|
|
if (answeredCount === 0) {
|
|
alert("Алдымен сұрақтарға жауап беріңіз!");
|
|
return;
|
|
}
|
|
|
|
const correctCount = Object.keys(answered).filter(k => answered[k] === questions[k].correct).length;
|
|
const percent = Math.round((correctCount / answeredCount) * 100);
|
|
|
|
document.getElementById("finalScore").textContent = correctCount + " / " + answeredCount + " (" + percent + "%)";
|
|
|
|
let message = "";
|
|
if (percent >= 90) message = "🎉 Керемет! Сіз жол ережелерін жақсы білесіз!";
|
|
else if (percent >= 70) message = "👍 Жақсы нәтиже! Бірақ әлі де қайталау керек.";
|
|
else if (percent >= 50) message = "😐 Орташа нәтиже. Ережелерді қайталаңыз.";
|
|
else message = "😓 Төмен нәтиже. Ережелерді мұқият оқып шығыңыз.";
|
|
|
|
document.getElementById("finalMessage").textContent = message;
|
|
document.getElementById("resultBox").style.display = "block";
|
|
|
|
renderQuestions();
|
|
}
|
|
|
|
function resetTest() {
|
|
answered = {};
|
|
currentCategory = "Барлығы";
|
|
document.getElementById("resultBox").style.display = "none";
|
|
renderCategories();
|
|
renderQuestions();
|
|
}
|
|
|
|
document.getElementById("searchInput").addEventListener("input", function(e) {
|
|
const term = e.target.value.toLowerCase();
|
|
const cards = document.querySelectorAll(".question-card");
|
|
cards.forEach((card, idx) => {
|
|
const q = questions[idx];
|
|
const match = q.question.toLowerCase().includes(term) ||
|
|
q.options.some(o => o.toLowerCase().includes(term));
|
|
card.style.display = match ? "block" : "none";
|
|
});
|
|
});
|
|
|
|
renderCategories();
|
|
renderQuestions();
|
|
</script>
|
|
</body>
|
|
</html>
|