Initial commit - Compliance TV

This commit is contained in:
Dauren777 2026-08-10 09:28:55 +00:00
parent 0e01ef3e85
commit eb05a3f80b
3 changed files with 951 additions and 0 deletions

135
index.html Normal file
View File

@ -0,0 +1,135 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Compliance TV | Корпоративный телеканал</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<div class="header-content">
<div class="logo">
<span class="logo-icon">📺</span>
<div class="logo-text">
<h1>Compliance TV</h1>
<p>Корпоративный телеканал по комплаенс</p>
</div>
</div>
<nav>
<a href="#videos" class="nav-link active">Видео</a>
<a href="#news" class="nav-link">Новости</a>
<a href="#faq" class="nav-link">FAQ</a>
<a href="#test" class="nav-link">Тестирование</a>
</nav>
</div>
</header>
<main>
<section id="videos" class="section">
<div class="section-header">
<h2>🎬 Обучающие видео</h2>
<p class="section-desc">Краткие уроки по комплаенс (2-5 минут)</p>
</div>
<div class="video-grid" id="video-grid"></div>
</section>
<section id="news" class="section">
<div class="section-header">
<h2>📰 Новости комплаенс</h2>
<p class="section-desc">Последние изменения и важные объявления</p>
</div>
<div class="news-list" id="news-list"></div>
</section>
<section id="faq" class="section">
<div class="section-header">
<h2>❓ Часто задаваемые вопросы</h2>
<p class="section-desc">Ответы на типичные вопросы сотрудников</p>
</div>
<div class="faq-list" id="faq-list"></div>
</section>
<section id="test" class="section">
<div class="section-header">
<h2>🧠 Проверка знаний</h2>
<p class="section-desc">Пройдите тестирование по материалам канала</p>
</div>
<div class="test-container">
<div class="test-start" id="test-start">
<p>Вам будет предложено 10 вопросов по темам:</p>
<ul class="test-topics">
<li>• Этика и конфликт интересов</li>
<li>• Антикоррупционная политика</li>
<li>• Работа с конфиденциальной информацией</li>
<li>• Подарки и вознаграждения</li>
</ul>
<button class="btn-primary" id="start-test-btn">Начать тестирование</button>
</div>
<div class="test-quiz" id="test-quiz" style="display: none;">
<div class="test-progress">
<span>Вопрос <span id="q-current">1</span> из <span id="q-total">10</span></span>
</div>
<p class="question-text" id="question-text"></p>
<div class="test-options" id="test-options"></div>
<p class="test-feedback" id="test-feedback"></p>
</div>
<div class="test-result" id="test-result" style="display: none;">
<div class="result-icon">🏆</div>
<h3>Тестирование завершено!</h3>
<div class="result-stats">
<div class="result-stat">
<span class="result-value" id="result-score">0</span>
<span class="result-label">Правильных ответов</span>
</div>
<div class="result-stat">
<span class="result-value" id="result-percent">0%</span>
<span class="result-label">Результат</span>
</div>
</div>
<p class="result-message" id="result-message"></p>
<button class="btn-primary" id="restart-test-btn">Пройти заново</button>
</div>
</div>
</section>
<section class="section dashboard">
<div class="section-header">
<h2>📊 Моя статистика</h2>
</div>
<div class="stats-grid">
<div class="stat-card">
<span class="stat-icon">📚</span>
<span class="stat-value" id="stat-lessons">0</span>
<span class="stat-label">Просмотрено уроков</span>
</div>
<div class="stat-card">
<span class="stat-icon">✅</span>
<span class="stat-value" id="stat-tests">0</span>
<span class="stat-label">Пройдено тестов</span>
</div>
<div class="stat-card">
<span class="stat-icon">🎯</span>
<span class="stat-value" id="stat-average">0%</span>
<span class="stat-label">Средний балл</span>
</div>
<div class="stat-card">
<span class="stat-icon">📅</span>
<span class="stat-value" id="stat-last">—</span>
<span class="stat-label">Последняя активность</span>
</div>
</div>
<button class="btn-secondary" id="reset-stats-btn">Сбросить статистику</button>
</section>
</main>
<footer>
<div class="footer-content">
<p>© 2026 Compliance TV | АО «Казахтелеком»</p>
<p class="footer-note">Внутренний портал для сотрудников</p>
</div>
</footer>
<script src="script.js"></script>
</body>
</html>

301
script.js Normal file
View File

@ -0,0 +1,301 @@
const VIDEOS = [
{ title: "Кодекс этики: основные принципы", duration: "4:32", category: "Этика" },
{ title: "Конфликт интересов: как распознать", duration: "3:45", category: "Этика" },
{ title: "Антикоррупционная политика", duration: "5:18", category: "Антикоррупция" },
{ title: "Подарки и вознаграждения", duration: "3:20", category: "Антикоррупция" },
{ title: "Конфиденциальная информация", duration: "4:55", category: "Информация" },
{ title: "Работа с документами", duration: "3:10", category: "Информация" },
{ title: "Внутренняя инсайдерская информация", duration: "4:02", category: "Информация" },
{ title: "Борьба с отмыванием денег", duration: "5:45", category: "Антикоррупция" },
{ title: "Харассмент и дискриминация", duration: "4:28", category: "Этика" },
{ title: "Защита персональных данных", duration: "3:55", category: "Информация" },
{ title: "Взаимодействие с госорганами", duration: "4:15", category: "Антикоррупция" },
{ title: "Социальные сети: правила поведения", duration: "3:38", category: "Этика" }
];
const NEWS = [
{
date: "10 августа 2026",
title: "Обновлён кодекс корпоративной этики",
excerpt: "Внесены изменения в раздел о конфликте интересов. Всем сотрудникам необходимо ознакомиться до 1 сентября.",
tag: "Важно"
},
{
date: "5 августа 2026",
title: "Ежегодное комплаенс-тестирование",
excerpt: "Прохождение обязательно для всех сотрудников до 30 сентября. Результаты будут учтены при аттестации.",
tag: "Обязательно"
},
{
date: "1 августа 2026",
title: "Новый канал связи для анонимных обращений",
excerpt: "Запущен телефон доверия для сообщений о нарушениях. Круглосуточно, анонимно.",
tag: "Новости"
},
{
date: "25 июля 2026",
title: "Изменения в законодательстве РК",
excerpt: "Обзор новых требований по противодействию коррупции и отмыванию доходов.",
tag: "Законодательство"
}
];
const FAQ = [
{
q: "Могу ли я принять подарок от партнёра?",
a: "Подарки стоимостью до 5 МРП принимать можно без ограничений. Подарки дороже 5 МРП необходимо задекларировать и передать организации. Деньги в любой сумме принимать запрещено."
},
{
q: "Что делать при возникновении конфликта интересов?",
a: "Немедленно сообщите непосредственному руководителю и в службу комплаенс. Воздержитесь от участия в решении вопроса до урегулирования ситуации."
},
{
q: "Кому сообщать о фактах коррупции?",
a: "Сообщения принимаются через телефон доверия, email службы комплаенс или через руководителя. Гарантируем конфиденциальность и защиту от преследования."
},
{
q: "Можно ли работать в другой компании по совместительству?",
a: "Внешнее совместительство разрешено, если не создаёт конфликт интересов. Необходимо получить письменное согласие руководителя и задекларировать в службе комплаенс."
},
{
q: "Как часто нужно проходить комплаенс-обучение?",
a: "Обязательное обучение — ежегодно. Дополнительно — при изменении законодательства или должностных обязанностей."
},
{
q: "Что считается конфиденциальной информацией?",
a: "Финансовые данные, персональные данные сотрудников, коммерческие тайны, договоры, стратегические планы. Передача третьим лицам без разрешения запрещена."
}
];
const 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
}
];
let currentQuestion = 0;
let score = 0;
let testTaken = false;
let stats = { lessons: 0, tests: 0, totalScore: 0, lastActivity: null };
function loadStats() {
const saved = localStorage.getItem("complianceStats");
if (saved) {
stats = JSON.parse(saved);
}
updateStatsDisplay();
}
function saveStats() {
localStorage.setItem("complianceStats", JSON.stringify(stats));
updateStatsDisplay();
}
function updateStatsDisplay() {
document.getElementById("stat-lessons").textContent = stats.lessons;
document.getElementById("stat-tests").textContent = stats.tests;
const avg = stats.tests > 0 ? Math.round(stats.totalScore / stats.tests) : 0;
document.getElementById("stat-average").textContent = avg + "%";
document.getElementById("stat-last").textContent = stats.lastActivity ? new Date(stats.lastActivity).toLocaleDateString("ru-RU") : "—";
}
function renderVideos() {
const grid = document.getElementById("video-grid");
grid.innerHTML = VIDEOS.map(v => `
<div class="video-card" onclick="watchVideo('${v.title}')">
<div class="video-thumbnail"></div>
<div class="video-info">
<div class="video-title">${v.title}</div>
<div class="video-meta">
<span>${v.category}</span>
<span class="video-duration">${v.duration}</span>
</div>
</div>
</div>
`).join("");
}
function watchVideo(title) {
stats.lessons++;
stats.lastActivity = new Date().toISOString();
saveStats();
alert(`▶️ Видео "${title}"\n\nВ реальной версии здесь будет видеоплеер.`);
}
function renderNews() {
const list = document.getElementById("news-list");
list.innerHTML = NEWS.map(n => `
<div class="news-item">
<div class="news-date">${n.date}</div>
<div class="news-title">${n.title}</div>
<div class="news-excerpt">${n.excerpt}</div>
<span class="news-tag">${n.tag}</span>
</div>
`).join("");
}
function renderFAQ() {
const list = document.getElementById("faq-list");
list.innerHTML = FAQ.map((item, i) => `
<div class="faq-item">
<button class="faq-question" onclick="toggleFAQ(${i})">${item.q}</button>
<div class="faq-answer">${item.a}</div>
</div>
`).join("");
}
function toggleFAQ(index) {
const items = document.querySelectorAll(".faq-item");
items[index].classList.toggle("active");
}
function startTest() {
currentQuestion = 0;
score = 0;
testTaken = false;
document.getElementById("test-start").style.display = "none";
document.getElementById("test-quiz").style.display = "block";
document.getElementById("test-result").style.display = "none";
showQuestion();
}
function showQuestion() {
const 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 = "";
const options = document.getElementById("test-options");
options.innerHTML = q.options.map((opt, i) => `
<button class="test-option" onclick="answer(${i})">${opt}</button>
`).join("");
}
function answer(selectedIndex) {
if (testTaken) return;
testTaken = true;
const q = QUESTIONS[currentQuestion];
const options = document.querySelectorAll(".test-option");
const 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(() => {
currentQuestion++;
if (currentQuestion < QUESTIONS.length) {
testTaken = false;
showQuestion();
} else {
finishTest();
}
}, 2000);
}
function finishTest() {
const percent = Math.round((score / QUESTIONS.length) * 100);
stats.tests++;
stats.totalScore += percent;
stats.lastActivity = new Date().toISOString();
saveStats();
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}%`;
let message = "";
if (percent >= 90) {
message = "🎉 Отличный результат! Вы хорошо знаете комплаенс-политику.";
} else if (percent >= 70) {
message = "👍 Хороший результат. Рекомендуется повторить отдельные темы.";
} else {
message = "⚠️ Рекомендуем пройти обучение заново и изучить материалы.";
}
document.getElementById("result-message").textContent = message;
}
function resetStats() {
if (confirm("Сбросить всю статистику?")) {
stats = { lessons: 0, tests: 0, totalScore: 0, lastActivity: null };
saveStats();
}
}
document.getElementById("start-test-btn").addEventListener("click", startTest);
document.getElementById("restart-test-btn").addEventListener("click", startTest);
document.getElementById("reset-stats-btn").addEventListener("click", resetStats);
document.querySelectorAll(".nav-link").forEach(link => {
link.addEventListener("click", function(e) {
e.preventDefault();
document.querySelectorAll(".nav-link").forEach(l => l.classList.remove("active"));
this.classList.add("active");
const target = this.getAttribute("href");
document.querySelector(target).scrollIntoView({ behavior: "smooth" });
});
});
loadStats();
renderVideos();
renderNews();
renderFAQ();

515
style.css Normal file
View File

@ -0,0 +1,515 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background: #f5f7fa;
color: #2d3748;
line-height: 1.6;
}
header {
background: linear-gradient(135deg, #1a365d 0%, #2c5282 100%);
color: white;
padding: 20px 0;
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
.header-content {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 20px;
}
.logo {
display: flex;
align-items: center;
gap: 12px;
}
.logo-icon {
font-size: 42px;
}
.logo-text h1 {
font-size: 28px;
font-weight: 700;
margin-bottom: 2px;
}
.logo-text p {
font-size: 13px;
opacity: 0.9;
font-weight: 400;
}
nav {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.nav-link {
color: white;
text-decoration: none;
padding: 10px 18px;
border-radius: 6px;
font-weight: 500;
font-size: 14px;
transition: all 0.2s;
background: rgba(255, 255, 255, 0.1);
}
.nav-link:hover {
background: rgba(255, 255, 255, 0.2);
}
.nav-link.active {
background: white;
color: #1a365d;
}
main {
max-width: 1200px;
margin: 0 auto;
padding: 30px 20px;
}
.section {
background: white;
border-radius: 12px;
padding: 28px;
margin-bottom: 28px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.section-header {
margin-bottom: 24px;
}
.section-header h2 {
font-size: 24px;
color: #1a365d;
margin-bottom: 6px;
}
.section-desc {
color: #718096;
font-size: 14px;
}
.video-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
.video-card {
background: #f7fafc;
border-radius: 10px;
overflow: hidden;
transition: transform 0.2s, box-shadow 0.2s;
cursor: pointer;
}
.video-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.12);
}
.video-thumbnail {
background: linear-gradient(135deg, #4a5568 0%, #2d3748 100%);
height: 160px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.video-thumbnail::after {
content: "▶";
font-size: 48px;
color: white;
opacity: 0.9;
}
.video-info {
padding: 16px;
}
.video-title {
font-weight: 600;
font-size: 16px;
color: #2d3748;
margin-bottom: 8px;
}
.video-meta {
display: flex;
justify-content: space-between;
font-size: 13px;
color: #718096;
}
.video-duration {
background: #e2e8f0;
padding: 3px 8px;
border-radius: 4px;
}
.news-list {
display: grid;
gap: 16px;
}
.news-item {
padding: 20px;
background: #f7fafc;
border-left: 4px solid #4299e1;
border-radius: 8px;
transition: transform 0.2s;
}
.news-item:hover {
transform: translateX(4px);
}
.news-date {
font-size: 13px;
color: #718096;
margin-bottom: 8px;
}
.news-title {
font-weight: 600;
font-size: 16px;
color: #2d3748;
margin-bottom: 8px;
}
.news-excerpt {
color: #4a5568;
font-size: 14px;
line-height: 1.6;
}
.news-tag {
display: inline-block;
background: #4299e1;
color: white;
padding: 3px 10px;
border-radius: 12px;
font-size: 12px;
margin-top: 10px;
}
.faq-list {
display: grid;
gap: 12px;
}
.faq-item {
border: 1px solid #e2e8f0;
border-radius: 8px;
overflow: hidden;
}
.faq-question {
width: 100%;
text-align: left;
padding: 18px 20px;
background: #f7fafc;
border: none;
font-weight: 600;
font-size: 15px;
color: #2d3748;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
transition: background 0.2s;
}
.faq-question:hover {
background: #edf2f7;
}
.faq-question::after {
content: "+";
font-size: 24px;
color: #4a5568;
}
.faq-item.active .faq-question::after {
content: "−";
}
.faq-answer {
padding: 0 20px;
max-height: 0;
overflow: hidden;
transition: all 0.3s;
background: white;
}
.faq-item.active .faq-answer {
padding: 18px 20px;
max-height: 500px;
border-top: 1px solid #e2e8f0;
color: #4a5568;
line-height: 1.7;
}
.test-container {
max-width: 700px;
margin: 0 auto;
}
.test-start {
text-align: center;
padding: 30px 20px;
}
.test-start p {
font-size: 16px;
color: #4a5568;
margin-bottom: 20px;
}
.test-topics {
list-style: none;
text-align: left;
display: inline-block;
margin-bottom: 30px;
color: #2d3748;
font-size: 15px;
line-height: 2;
}
.test-progress {
background: #e2e8f0;
padding: 12px 16px;
border-radius: 8px;
margin-bottom: 20px;
font-weight: 600;
color: #4a5568;
}
.question-text {
font-size: 18px;
font-weight: 600;
color: #2d3748;
margin-bottom: 24px;
line-height: 1.5;
}
.test-options {
display: grid;
gap: 12px;
margin-bottom: 20px;
}
.test-option {
padding: 16px 20px;
background: #f7fafc;
border: 2px solid #e2e8f0;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s;
font-size: 15px;
text-align: left;
}
.test-option:hover {
border-color: #4299e1;
background: #ebf8ff;
}
.test-option.correct {
background: #c6f6d5;
border-color: #48bb78;
color: #22543d;
}
.test-option.wrong {
background: #fed7d7;
border-color: #f56565;
color: #742a2a;
}
.test-feedback {
font-weight: 600;
font-size: 16px;
min-height: 24px;
margin-bottom: 20px;
}
.test-result {
text-align: center;
padding: 40px 20px;
}
.result-icon {
font-size: 72px;
margin-bottom: 20px;
}
.result-stats {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin: 30px 0;
}
.result-stat {
background: #f7fafc;
padding: 24px;
border-radius: 10px;
}
.result-value {
display: block;
font-size: 42px;
font-weight: 700;
color: #4299e1;
margin-bottom: 8px;
}
.result-label {
color: #718096;
font-size: 14px;
}
.result-message {
font-size: 16px;
color: #4a5568;
margin-bottom: 30px;
line-height: 1.6;
}
.btn-primary {
background: linear-gradient(135deg, #4299e1 0%, #3182ce 100%);
color: white;
border: none;
padding: 14px 40px;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(66, 153, 225, 0.4);
}
.btn-secondary {
background: #fc8181;
color: white;
border: none;
padding: 12px 28px;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
margin-top: 20px;
transition: background 0.2s;
}
.btn-secondary:hover {
background: #f56565;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 20px;
}
.stat-card {
background: #f7fafc;
padding: 24px;
border-radius: 10px;
text-align: center;
}
.stat-icon {
font-size: 32px;
display: block;
margin-bottom: 12px;
}
.stat-value {
display: block;
font-size: 32px;
font-weight: 700;
color: #4299e1;
margin-bottom: 6px;
}
.stat-label {
color: #718096;
font-size: 13px;
}
footer {
background: #1a365d;
color: white;
padding: 30px 20px;
text-align: center;
}
.footer-content p {
margin-bottom: 6px;
font-size: 14px;
}
.footer-note {
opacity: 0.8;
font-size: 13px;
}
@media (max-width: 768px) {
.header-content {
flex-direction: column;
text-align: center;
}
.logo {
justify-content: center;
}
nav {
justify-content: center;
}
.nav-link {
padding: 8px 14px;
font-size: 13px;
}
.section {
padding: 20px 16px;
}
.video-grid {
grid-template-columns: 1fr;
}
.result-stats {
grid-template-columns: 1fr;
}
}