test1 / templates /index.html
vydrking's picture
Upload 18 files
172ee17 verified
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ITMO Магистратура - Чат-бот</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.main-container {
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
margin: 20px auto;
max-width: 1200px;
}
.chat-container {
height: 400px;
overflow-y: auto;
border: 1px solid #dee2e6;
border-radius: 10px;
padding: 15px;
background: #f8f9fa;
}
.message {
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 15px;
max-width: 80%;
}
.user-message {
background: #007bff;
color: white;
margin-left: auto;
}
.bot-message {
background: #e9ecef;
color: #333;
}
.loading {
display: none;
text-align: center;
padding: 20px;
}
.spinner-border-sm {
width: 1rem;
height: 1rem;
}
.card {
border: none;
box-shadow: 0 5px 15px rgba(0,0,0,0.08);
border-radius: 15px;
}
.btn-primary {
background: linear-gradient(45deg, #667eea, #764ba2);
border: none;
border-radius: 25px;
padding: 10px 25px;
}
.btn-secondary {
background: linear-gradient(45deg, #6c757d, #495057);
border: none;
border-radius: 25px;
padding: 10px 25px;
}
.form-control, .form-select {
border-radius: 10px;
border: 2px solid #e9ecef;
}
.form-control:focus, .form-select:focus {
border-color: #667eea;
box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="main-container p-4">
<!-- Заголовок -->
<div class="text-center mb-4">
<h1 class="display-4 text-primary">
<i class="fas fa-robot"></i> ITMO Магистратура - Чат-бот
</h1>
<p class="lead text-muted">Задавайте вопросы о программах ИИ и AI Product, получайте персональные рекомендации по курсам</p>
<div class="row justify-content-center">
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<i class="fas fa-graduation-cap fa-2x text-primary"></i>
<h5 class="card-title">{{ courses_count }}</h5>
<p class="card-text">Курсов загружено</p>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Чат -->
<div class="col-lg-8">
<div class="card">
<div class="card-header bg-primary text-white">
<h5 class="mb-0"><i class="fas fa-comments"></i> Чат с ботом</h5>
</div>
<div class="card-body">
<div class="chat-container" id="chatContainer">
<div class="message bot-message">
<strong>Бот:</strong> Привет! Я помогу тебе узнать больше о магистерских программах ITMO. Задавай вопросы о курсах, программах и получай персональные рекомендации!
</div>
</div>
<div class="loading" id="loading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Загрузка...</span>
</div>
<p class="mt-2">Бот думает...</p>
</div>
<div class="input-group mt-3">
<input type="text" class="form-control" id="messageInput"
placeholder="Спрашивайте о дисциплинах, программах, учебных планах...">
<button class="btn btn-primary" type="button" id="sendBtn">
<i class="fas fa-paper-plane"></i> Отправить
</button>
<button class="btn btn-outline-secondary" type="button" id="clearBtn">
<i class="fas fa-trash"></i> Очистить
</button>
</div>
</div>
</div>
</div>
<!-- Рекомендации -->
<div class="col-lg-4">
<div class="card">
<div class="card-header bg-success text-white">
<h5 class="mb-0"><i class="fas fa-user-graduate"></i> Профиль для рекомендаций</h5>
</div>
<div class="card-body">
<form id="recommendationsForm">
<div class="mb-3">
<label class="form-label">Опыт программирования (0-5)</label>
<input type="range" class="form-range" id="programmingExp" min="0" max="5" value="2">
<div class="d-flex justify-content-between">
<small>Нет опыта</small>
<small>Эксперт</small>
</div>
</div>
<div class="mb-3">
<label class="form-label">Уровень математики (0-4)</label>
<input type="range" class="form-range" id="mathLevel" min="0" max="4" value="2">
<div class="d-flex justify-content-between">
<small>Базовый</small>
<small>Продвинутый</small>
</div>
</div>
<div class="mb-3">
<label class="form-label">Интересы</label>
<div class="row">
<div class="col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="ml" id="ml" checked>
<label class="form-check-label" for="ml">ML</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="dl" id="dl">
<label class="form-check-label" for="dl">DL</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="nlp" id="nlp">
<label class="form-check-label" for="nlp">NLP</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="cv" id="cv">
<label class="form-check-label" for="cv">CV</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="product" id="product">
<label class="form-check-label" for="product">Product</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="business" id="business">
<label class="form-check-label" for="business">Business</label>
</div>
</div>
<div class="col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="research" id="research">
<label class="form-check-label" for="research">Research</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="data" id="data">
<label class="form-check-label" for="data">Data</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="systems" id="systems">
<label class="form-check-label" for="systems">Systems</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="python" id="python">
<label class="form-check-label" for="python">Python</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="math" id="math">
<label class="form-check-label" for="math">Math</label>
</div>
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">Целевой семестр</label>
<select class="form-select" id="semester">
<option value="">Выберите семестр</option>
<option value="1">1 семестр</option>
<option value="2">2 семестр</option>
<option value="3">3 семестр</option>
<option value="4">4 семестр</option>
</select>
</div>
<button type="submit" class="btn btn-success w-100 mb-2">
<i class="fas fa-lightbulb"></i> Получить рекомендации
</button>
<button type="button" class="btn btn-secondary w-100" id="updateBtn">
<i class="fas fa-sync-alt"></i> Обновить данные
</button>
</form>
<div class="mt-3">
<textarea class="form-control" id="recommendationsOutput" rows="8"
placeholder="Здесь появятся рекомендации..." readonly></textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Функции для работы с чатом
function addMessage(message, isUser = false) {
const chatContainer = document.getElementById('chatContainer');
const messageDiv = document.createElement('div');
messageDiv.className = `message ${isUser ? 'user-message' : 'bot-message'}`;
messageDiv.innerHTML = `<strong>${isUser ? 'Вы:' : 'Бот:'}</strong> ${message}`;
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
function showLoading() {
document.getElementById('loading').style.display = 'block';
}
function hideLoading() {
document.getElementById('loading').style.display = 'none';
}
// Отправка сообщения
async function sendMessage() {
const input = document.getElementById('messageInput');
const message = input.value.trim();
if (!message) return;
addMessage(message, true);
input.value = '';
showLoading();
try {
const response = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ message: message })
});
const data = await response.json();
if (response.ok) {
addMessage(data.response);
} else {
addMessage(`Ошибка: ${data.error}`);
}
} catch (error) {
addMessage(`Ошибка соединения: ${error.message}`);
} finally {
hideLoading();
}
}
// Получение рекомендаций
async function getRecommendations() {
const programmingExp = document.getElementById('programmingExp').value;
const mathLevel = document.getElementById('mathLevel').value;
const semester = document.getElementById('semester').value;
if (!semester) {
alert('Пожалуйста, выберите семестр');
return;
}
const interests = [];
document.querySelectorAll('input[type="checkbox"]:checked').forEach(cb => {
interests.push(cb.value);
});
const output = document.getElementById('recommendationsOutput');
output.value = 'Генерируем рекомендации...';
try {
const response = await fetch('/api/recommendations', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
programming_exp: parseInt(programmingExp),
math_level: parseInt(mathLevel),
interests: interests,
semester: semester
})
});
const data = await response.json();
if (response.ok) {
output.value = data.response;
} else {
output.value = `Ошибка: ${data.error}`;
}
} catch (error) {
output.value = `Ошибка соединения: ${error.message}`;
}
}
// Обновление данных
async function updateData() {
const output = document.getElementById('recommendationsOutput');
output.value = 'Обновляем данные...';
try {
const response = await fetch('/api/update', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
});
const data = await response.json();
if (response.ok) {
output.value = data.message;
location.reload(); // Перезагружаем страницу для обновления счетчика
} else {
output.value = `Ошибка: ${data.error}`;
}
} catch (error) {
output.value = `Ошибка соединения: ${error.message}`;
}
}
// Очистка чата
function clearChat() {
const chatContainer = document.getElementById('chatContainer');
chatContainer.innerHTML = `
<div class="message bot-message">
<strong>Бот:</strong> Привет! Я помогу тебе узнать больше о магистерских программах ITMO. Задавай вопросы о курсах, программах и получай персональные рекомендации!
</div>
`;
}
// Обработчики событий
document.getElementById('sendBtn').addEventListener('click', sendMessage);
document.getElementById('messageInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
sendMessage();
}
});
document.getElementById('clearBtn').addEventListener('click', clearChat);
document.getElementById('recommendationsForm').addEventListener('submit', function(e) {
e.preventDefault();
getRecommendations();
});
document.getElementById('updateBtn').addEventListener('click', updateData);
</script>
</body>
</html>