var LAWS = [
{ id: 1, title: "Қазақстан Республикасының «Сыбайлас жемқорлыққа қарсы іс-қимыл туралы» Заңы", cat: "Заң", desc: "Сыбайлас жемқорлыққа қарсы іс-қимылдың негізгі қағидаттары, тыйымдар мен жауапкершілік." },
{ id: 2, title: "ҚР «Мемлекеттік қызмет туралы» Заңы", cat: "Заң", desc: "Мемлекеттік қызметшілердің этикасы мен шектеулері, мүдделер қақтығысын реттеу." },
{ id: 3, title: "«Жеке деректер және оларды қорғау туралы» Заң", cat: "Заң", desc: "Жеке деректерді жинау, өңдеу және сақтау талаптары." },
{ id: 4, title: "Қазақстан Республикасының Азаматтық кодексі (құпия ақпарат бөлімі)", cat: "Құқық", desc: "Коммерциялық құпия және құпия ақпарат режимі." },
{ id: 5, title: "«Ақпаратқа қол жеткізу туралы» Заң", cat: "Заң", desc: "Ақпаратқа қол жеткізу тәртібі және қызметтік ақпараттың құпиялылығы." },
{ id: 6, title: "Телеканалдың Ішкі еңбек тәртібі", cat: "Ішкі регламент", desc: "Еңбек тәртібі, қауіпсіздік және жұмыс орнындағы әдеп нормалары." },
{ id: 7, title: "Қаржылық бақылау жөніндегі нұсқаулық", cat: "Ішкі регламент", desc: "Қаржылық операцияларды бақылау, сыйлықтар мен төлемдерді декларациялау тәртібі." },
{ id: 8, title: "Ақпараттық қауіпсіздік саясаты", cat: "Ішкі регламент", desc: "Ақпараттық ресурстарды пайдалану, пароль және құпия сөздермен жұмыс ережелері." },
{ id: 9, title: "«Ақшаны жылыстатуға қарсы іс-қимыл туралы» Заң", cat: "Заң", desc: "Күдікті операциялар туралы хабарлау және қаржылық мониторинг талаптары." },
{ id: 10, title: "Комплаенс-бақылау жөніндегі ереже", cat: "Ішкі регламент", desc: "Комплаенс-тексерулер, өзін-өзі тексеру және есептілік тәртібі." }
];
var STRUCTURE = [
{ id: 1, name: "Айгүл Сейтова", role: "Бас директор", dept: "Әкімшілік", head: true, emoji: "👩💼" },
{ id: 2, name: "Ерлан Қасымов", role: "Директордың орынбасары", dept: "Әкімшілік", head: false, emoji: "👨💼" },
{ id: 3, name: "Асет Бисенов", role: "Комплаенс офицер", dept: "Комплаенс қызметі", head: false, emoji: "🛡️" },
{ id: 4, name: "Гүлназ Омарова", role: "Заңгер", dept: "Құқықтық департамент", head: false, emoji: "⚖️" },
{ id: 5, name: "Дәурен Нұрлан", role: "Бас бухгалтер", dept: "Қаржы департаменті", head: false, emoji: "💼" },
{ id: 6, name: "Майра Жұмабек", role: "HR директоры", dept: "Кадр департаменті", head: false, emoji: "🧑🏫" },
{ id: 7, name: "Бауыржан Серік", role: "IT директоры", dept: "IT департаменті", head: false, emoji: "💻" },
{ id: 8, name: "Ляззат Төлеген", role: "Бас редактор", dept: "Редакция", head: false, emoji: "📰" }
];
var VIDEOS = [
{ id: 1, title: "Комплаенс деген не?", category: "Кіріспе", duration: "4:32", desc: "Комплаенс ұғымы және телеканалдағы рөлі" },
{ id: 2, title: "Мүдделер қақтығысы: қалай анықтауға?", category: "Этика", duration: "3:45", desc: "Мүдделер қақтығысының белгілері мен шешімдері" },
{ id: 3, title: "Сыбайлас жемқорлыққа қарсы саясат", category: "Сыбайлас жемқорлық", duration: "5:18", desc: "Негізгі тыйымдар мен жауапкершілік" },
{ id: 4, title: "Сыйлықтар мен төлемдер: шегі қандай?", category: "Сыбайлас жемқорлық", duration: "3:20", desc: "Сыйлық қабылдау ережелері және декларациялау" },
{ id: 5, title: "Құпия ақпаратпен жұмыс", category: "Ақпарат", duration: "4:55", desc: "Құпия ақпаратты қорғау ережелері" },
{ id: 6, title: "Жеке деректерді қорғау", category: "Ақпарат", duration: "3:55", desc: "Жеке деректермен жұмыс істеу талаптары" },
{ id: 7, title: "Қысым мен кемсітушілік", category: "Этика", duration: "4:28", desc: "Жұмыс орнындағы әдеп және теңдік" },
{ id: 8, title: "Әлеуметтік желілердегі мінез-құлық", category: "Этика", duration: "3:38", desc: "Қызметкердің әлеуметтік желідегі әдебі" }
];
var QUESTIONS = [
{ q: "Сыйлықты декларациясыз қабылдауға болатын ең жоғары шекті мөлшері:", options: ["5 АЕК", "10 АЕК", "20 АЕК", "Кез келген"], correct: 0 },
{ q: "Мүдделер қақтығысы туындағанда не істеу керек?", options: ["Өзім шешемін", "Басшыға және комплаенс қызметіне хабарлау", "Елемеу", "Жұмыстан кету"], correct: 1 },
{ q: "Комплаенс-тестілеуден қаншалықты жиі өту керек?", options: ["3 жылда бір", "Қалауымша", "Жыл сайын", "Тек жұмысқа қабылданғанда"], correct: 2 },
{ q: "Серіктестерден ақшалай сыйлық қабылдауға бола ма?", options: ["10 000 теңгеге дейін", "Басшының рұқсатымен", "Кез келген мөлшерде тыйым салынады", "Болады, егер декларацияласа"], correct: 2 },
{ q: "5 АЕК-тен қымбат сыйлықпен не істеу керек?", options: ["Өзіме қалдыру", "Әріптестерге беру", "Декларациялап, ұйымға тапсыру", "Қайтару"], correct: 2 },
{ q: "Құпия ақпаратқа не жатады?", options: ["Тек қаржылық есептер", "Тек жеке деректер", "Қаржылық деректер, ЖД, коммерциялық құпия", "Тек келісімшарттар"], correct: 2 },
{ q: "Сырттай қоса атқару:", options: ["Толық тыйым салынады", "Шектеусіз рұқсат", "Басшының келісімімен рұқсат", "Тек демалыс күндері"], correct: 2 },
{ q: "Сыбайлас жемқорлық туралы хабарлау арналары:", options: ["Тек жеке басшыға", "Сенім телефоны, email, басшы", "Тек анонимді", "Хабарлауға болмайды"], correct: 1 },
{ q: "Сыбайлас жемқорлыққа қарсы оқыту міндетті:", options: ["Тек басшыларға", "Тек жаңа қызметкерлерге", "Барлық қызметкерлерге", "Тек бухгалтерияға"], correct: 2 },
{ q: "Комплаенс ережесін бұзу неге әкеледі?", options: ["Ауызша ескерту", "Тәртіптік жауапкершілік, жұмыстан босатуға дейін", "Ешқандай салдарға", "Тек айыппұлға"], correct: 1 }
];
var currentQuestion = 0;
var score = 0;
var testTaken = false;
var userName = "";
var userDept = "";
var mockResults = [
{ name: "Айгүл Сейтова", dept: "Әкімшілік", score: 10, total: 10, date: "2026-08-10" },
{ name: "Дәурен Нұрлан", dept: "Қаржы", score: 9, total: 10, date: "2026-08-10" },
{ name: "Майра Жұмабек", dept: "Кадр", score: 8, total: 10, date: "2026-08-09" },
{ name: "Бауыржан Серік", dept: "IT", score: 7, total: 10, date: "2026-08-09" },
{ name: "Ляззат Төлеген", dept: "Редакция", score: 6, total: 10, date: "2026-08-08" }
];
var results = [];
var resultsBackendReady = false;
function getResults() {
return resultsBackendReady ? results : mockResults;
}
function renderLaws() {
var query = (document.getElementById("law-search").value || "").toLowerCase();
var activeCat = document.querySelector(".chip.active");
var cat = activeCat ? activeCat.dataset.cat : "";
var list = document.getElementById("law-list");
var filtered = LAWS.filter(function (l) {
var matchQ = l.title.toLowerCase().indexOf(query) !== -1 || l.desc.toLowerCase().indexOf(query) !== -1;
var matchC = !cat || l.cat === cat;
return matchQ && matchC;
});
if (!filtered.length) {
list.innerHTML = '
Ештеңе табылмады
';
return;
}
list.innerHTML = filtered.map(function (l) {
return '' +
'
' + l.title + '
' +
'
' + l.cat + '' + l.id + '
' +
(l.desc ? '
' + l.desc + '
' : '') +
'
';
}).join("");
}
function renderLawChips() {
var cats = {};
LAWS.forEach(function (l) { cats[l.cat] = true; });
var chips = document.getElementById("law-chips");
chips.innerHTML = '' +
Object.keys(cats).map(function (c) {
return '';
}).join("");
chips.querySelectorAll(".chip").forEach(function (chip) {
chip.addEventListener("click", function () {
chips.querySelectorAll(".chip").forEach(function (c) { c.classList.remove("active"); });
chip.classList.add("active");
renderLaws();
});
});
}
function renderStructure() {
var grid = document.getElementById("structure-grid");
grid.innerHTML = STRUCTURE.map(function (s) {
return '' +
'
' + s.emoji + '
' +
'
' + s.name + '
' +
'
' + s.role + '
' +
'
' + s.dept + '
' +
(s.head ? '
👑 Басшылық
' : '') +
'
';
}).join("");
}
function renderVideos() {
var grid = document.getElementById("video-grid");
grid.innerHTML = VIDEOS.map(function (v) {
return '' +
'
' + v.desc + '
' +
'
' +
'
' + v.title + '
' +
'
' + v.category + '' + v.duration + '
' +
'
';
}).join("");
}
function openVideo(id) {
var v = VIDEOS.find(function (x) { return x.id === id; });
if (v) alert("🎬 «" + v.title + "»\n\nРеалды нұсқада мұнда видео ойнайды (файлды офицер жүктеген кезде).");
}
function initTest() {
currentQuestion = 0;
score = 0;
testTaken = false;
userName = document.getElementById("test-name").value.trim();
userDept = document.getElementById("test-dept").value.trim();
if (!userName || !userDept) {
alert("Аты-жөніңізді және бөлімді толтырыңыз");
return;
}
document.getElementById("test-start").style.display = "none";
document.getElementById("test-quiz").style.display = "block";
document.getElementById("test-result").style.display = "none";
showQuestion();
}
function showQuestion() {
var q = QUESTIONS[currentQuestion];
document.getElementById("q-current").textContent = currentQuestion + 1;
document.getElementById("q-total").textContent = QUESTIONS.length;
document.getElementById("question-text").textContent = q.q;
document.getElementById("test-feedback").textContent = "";
document.getElementById("test-options").innerHTML = q.options.map(function (opt, i) {
return '';
}).join("");
}
function answer(selectedIndex) {
if (testTaken) return;
testTaken = true;
var q = QUESTIONS[currentQuestion];
var options = document.querySelectorAll(".test-option");
var feedback = document.getElementById("test-feedback");
if (selectedIndex === q.correct) {
options[selectedIndex].classList.add("correct");
feedback.textContent = "✅ Дұрыс!";
feedback.style.color = "#48bb78";
score++;
} else {
options[selectedIndex].classList.add("wrong");
options[q.correct].classList.add("correct");
feedback.textContent = "❌ Қате";
feedback.style.color = "#f56565";
}
setTimeout(function () {
currentQuestion++;
if (currentQuestion < QUESTIONS.length) {
testTaken = false;
showQuestion();
} else {
finishTest();
}
}, 2000);
}
function finishTest() {
var percent = Math.round((score / QUESTIONS.length) * 100);
document.getElementById("test-quiz").style.display = "none";
document.getElementById("test-result").style.display = "block";
document.getElementById("result-score").textContent = score + " / " + QUESTIONS.length;
document.getElementById("result-percent").textContent = percent + "%";
var msg = percent >= 90
? "🎉 Тамаша! Сіз комплаенс саясатын жақсы білесіз."
: percent >= 70
? "👍 Жақсы нәтиже. Жеке тақырыптарды қайталау ұсынылады."
: "⚠️ Оқуды қайта өтіп, материалдарды зерделеуді ұсынамыз.";
document.getElementById("result-message").textContent = msg;
saveResult(userName, userDept, score, QUESTIONS.length);
}
function saveResult(name, dept, sc, total) {
var rec = { name: name, dept: dept, score: sc, total: total, date: new Date().toISOString().slice(0, 10) };
if (resultsBackendReady) {
fetch("/api/results", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(rec)
}).catch(function () {});
} else {
results.push(rec);
renderDashboard();
}
}
function renderStats() {
var rows = getResults();
var total = rows.length;
var passed = rows.filter(function (r) { return r.score / r.total >= 0.7; }).length;
var avg = total ? Math.round(rows.reduce(function (s, r) { return s + r.score / r.total * 100; }, 0) / total) : 0;
var stats = document.getElementById("stats-grid");
stats.innerHTML = [
{ icon: "👥", val: total, label: "Тест тапсырған" },
{ icon: "✅", val: passed, label: "70%+ нәтижемен" },
{ icon: "🎯", val: avg + "%", label: "Орташа нәтиже" },
{ icon: "📈", val: topPerformer(rows), label: "Үздік қызметкер" }
].map(function (s) {
return '' + s.icon + '' +
'' + s.val + '' + s.label + '
';
}).join("");
}
function topPerformer(rows) {
if (!rows.length) return "—";
var best = rows.reduce(function (a, b) { return (a.score / a.total) >= (b.score / b.total) ? a : b; });
return best.name;
}
function renderResultsTable() {
var query = (document.getElementById("dash-search").value || "").toLowerCase();
var rows = getResults().filter(function (r) {
return r.name.toLowerCase().indexOf(query) !== -1 || r.dept.toLowerCase().indexOf(query) !== -1;
}).slice().reverse();
var tbody = document.querySelector("#results-table tbody");
if (!rows.length) {
tbody.innerHTML = '| Нәтиже жоқ |
';
return;
}
tbody.innerHTML = rows.map(function (r) {
var pct = Math.round(r.score / r.total * 100);
var cls = pct >= 90 ? "score-good" : pct >= 70 ? "score-mid" : "score-low";
return '| ' + r.name + ' | ' + r.dept + ' | ' +
'' + pct + '% (' + r.score + '/' + r.total + ') | ' +
'' + r.date + ' |
';
}).join("");
}
function renderDashboard() {
renderStats();
renderResultsTable();
}
function exportCsv() {
var rows = getResults();
var head = ["Қызметкер", "Бөлім", "Нәтиже", "Дата"];
var body = rows.map(function (r) {
return [r.name, r.dept, r.score + "/" + r.total, r.date]
.map(function (v) { return '"' + String(v).replace(/"/g, '""') + '"'; }).join(";");
});
var csv = "\uFEFF" + [head.join(";"), ...body].join("\n");
var a = document.createElement("a");
a.href = URL.createObjectURL(new Blob([csv], { type: "text/csv" }));
a.download = "test_results.csv";
a.click();
}
function tryBackend() {
fetch("/api/results").then(function (r) { return r.json(); }).then(function (data) {
if (data && Array.isArray(data)) {
results = data;
resultsBackendReady = true;
renderDashboard();
}
}).catch(function () {});
}
document.getElementById("law-search").addEventListener("input", renderLaws);
document.getElementById("dash-search").addEventListener("input", renderResultsTable);
document.getElementById("export-btn").addEventListener("click", exportCsv);
document.getElementById("start-test-btn").addEventListener("click", initTest);
document.getElementById("restart-test-btn").addEventListener("click", function () {
document.getElementById("test-start").style.display = "block";
document.getElementById("test-result").style.display = "none";
});
document.getElementById("complaint-form").addEventListener("submit", function (e) {
e.preventDefault();
var form = e.target;
var data = {
category: form.category.value,
text: form.text.value
};
if (resultsBackendReady) {
fetch("/api/complaints", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
}).then(function () {
form.reset();
showFormSuccess();
}).catch(function () { form.reset(); showFormSuccess(); });
} else {
form.reset();
showFormSuccess();
}
});
function showFormSuccess() {
var note = document.querySelector(".form-note");
var old = note.textContent;
note.textContent = "✅ Өтініш жіберілді!";
setTimeout(function () { note.textContent = old; }, 4000);
}
document.getElementById("video-form").addEventListener("submit", function (e) {
e.preventDefault();
alert("📤 Бұл мүмкіндік сервер қосылғанда жұмыс істейді (Рецепт: видео жүктеу).");
});
document.querySelectorAll(".nav-link").forEach(function (link) {
link.addEventListener("click", function (e) {
e.preventDefault();
document.querySelectorAll(".nav-link").forEach(function (l) { l.classList.remove("active"); });
link.classList.add("active");
document.querySelector(link.getAttribute("href")).scrollIntoView({ behavior: "smooth" });
});
});
renderLawChips();
renderLaws();
renderStructure();
renderVideos();
renderDashboard();
tryBackend();