/
kkkatsuko
/
Blog
Обзор
Документация
Войти
/
kkkatsuko
/
Blog
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
task1806/index.html
641 строка
25 KB
kkkatsuko
Update: index.html
18 июн 2026, 19:56
Верифицирован
18 июн 2026, 19:56
08a4289
Код
Авторство
О чём код?
<!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: 'Segoe UI', Roboto, system-ui, sans-serif; background: linear-gradient(145deg, #f9e7f0 0%, #f5d6e4 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; } .app { max-width: 550px; width: 100%; background: #ffffffdd; backdrop-filter: blur(10px); border-radius: 40px; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15), 0 6px 12px rgba(0, 0, 0, 0.05); overflow: hidden; padding: 24px 20px 20px; transition: all 0.3s; } h1 { font-size: 26px; font-weight: 700; color: #4a2c3a; display: flex; align-items: center; gap: 10px; margin-bottom: 6px; } h1 small { font-size: 14px; font-weight: 400; color: #7a5a6a; margin-left: auto; } .subtitle { color: #6b4d5a; font-size: 15px; border-left: 4px solid #e89bb6; padding-left: 14px; margin-bottom: 20px; background: #fcecf3; border-radius: 0 12px 12px 0; line-height: 1.4; } .chat-box { background: #ffffff; border-radius: 28px; padding: 18px 16px 12px; box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.03); height: 380px; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; margin-bottom: 16px; border: 1px solid #f0dae6; } .chat-box::-webkit-scrollbar { width: 5px; } .chat-box::-webkit-scrollbar-thumb { background: #dbb6c9; border-radius: 10px; } .message { max-width: 85%; padding: 12px 16px; border-radius: 24px; line-height: 1.5; font-size: 15px; word-break: break-word; animation: fadeIn 0.25s ease-out; } .message.bot { background: #f2e3eb; color: #2d1f27; align-self: flex-start; border-bottom-left-radius: 6px; border-top-left-radius: 6px; } .message.user { background: #e89bb6; color: #fff; align-self: flex-end; border-bottom-right-radius: 6px; border-top-right-radius: 6px; } .message .age-badge { display: inline-block; background: #cfa1b6; color: #fff; font-size: 12px; padding: 2px 12px; border-radius: 20px; margin-right: 6px; font-weight: 600; } .message .doll-list { display: flex; flex-wrap: wrap; gap: 8px 12px; margin-top: 8px; } .message .doll-item { background: #ffffffb0; padding: 4px 14px; border-radius: 30px; font-size: 14px; color: #2d1f27; box-shadow: 0 1px 4px rgba(0,0,0,0.05); } .input-area { display: flex; gap: 10px; align-items: center; background: #fff; border-radius: 40px; padding: 4px 4px 4px 18px; border: 1px solid #ecdae5; transition: border 0.2s; } .input-area:focus-within { border-color: #d38aaa; } .input-area input { flex: 1; border: none; outline: none; padding: 12px 0; font-size: 16px; background: transparent; color: #2d1f27; } .input-area input::placeholder { color: #b392a3; } .input-area button { background: #e89bb6; border: none; color: #fff; padding: 10px 20px; border-radius: 40px; font-size: 16px; font-weight: 600; cursor: pointer; transition: background 0.2s, transform 0.1s; white-space: nowrap; } .input-area button:hover { background: #d47f9e; } .input-area button:active { transform: scale(0.96); } .action-row { display: flex; justify-content: flex-end; margin-top: 10px; gap: 12px; } .action-row button { background: transparent; border: none; color: #7a5a6a; font-size: 13px; cursor: pointer; text-decoration: underline dotted; padding: 6px 10px; border-radius: 20px; transition: background 0.2s; } .action-row button:hover { background: #f2e3eb; } /* Панель управления рекомендациями */ .admin-panel { margin-top: 16px; background: #faf0f5; border-radius: 28px; padding: 18px 16px; display: none; border: 1px solid #e3cbd8; } .admin-panel.open { display: block; } .admin-panel h3 { font-size: 16px; color: #4a2c3a; margin-bottom: 12px; display: flex; align-items: center; gap: 8px; } .admin-panel .group { background: #fff; border-radius: 16px; padding: 12px; margin-bottom: 12px; box-shadow: 0 2px 6px rgba(0,0,0,0.03); } .admin-panel .group-header { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; } .admin-panel .group-header input { padding: 6px 12px; border: 1px solid #dbb6c9; border-radius: 30px; font-size: 14px; flex: 1; min-width: 80px; } .admin-panel .group-header button { background: #dbb6c9; border: none; border-radius: 30px; padding: 6px 14px; color: #fff; font-weight: 600; cursor: pointer; font-size: 13px; transition: background 0.2s; } .admin-panel .group-header button:hover { background: #c69db3; } .admin-panel .group-header button.danger { background: #e8b4b4; } .admin-panel .group-header button.danger:hover { background: #d99a9a; } .admin-panel .doll-list-edit { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; align-items: center; } .admin-panel .doll-tag { background: #f2e3eb; padding: 4px 12px; border-radius: 30px; font-size: 13px; display: inline-flex; align-items: center; gap: 6px; } .admin-panel .doll-tag .remove { cursor: pointer; color: #a06f84; font-weight: 700; font-size: 16px; line-height: 1; } .admin-panel .add-doll-form { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; } .admin-panel .add-doll-form input { flex: 1; padding: 6px 12px; border: 1px solid #dbb6c9; border-radius: 30px; font-size: 14px; min-width: 80px; } .admin-panel .add-doll-form button { background: #e89bb6; border: none; border-radius: 30px; padding: 6px 16px; color: #fff; font-weight: 600; cursor: pointer; } .admin-panel .add-group-btn { background: #cfa1b6; border: none; border-radius: 30px; padding: 8px 20px; color: #fff; font-weight: 600; cursor: pointer; margin-top: 8px; width: 100%; } .footer-note { margin-top: 14px; font-size: 12px; color: #9b7d8a; text-align: center; border-top: 1px solid #eddae5; padding-top: 12px; } @keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } } /* адаптив */ @media (max-width: 500px) { .app { padding: 16px; } .chat-box { height: 300px; } .input-area input { font-size: 15px; } .input-area button { padding: 8px 16px; font-size: 15px; } } </style> </head> <body> <div class="app" id="app"> <h1> 🧸 Кукольный помощник <small>для родителей</small> </h1> <div class="subtitle"> 👶 Введите возраст ребёнка (число лет), и я подскажу, какие куклы ему подойдут. </div> <div class="chat-box" id="chatBox"> <div class="message bot"> Привет! 👋<br> Я помогу выбрать куклу для вашего малыша.<br> <strong>Напишите возраст (например, 4 или 7).</strong> </div> </div> <div class="input-area"> <input type="number" id="ageInput" placeholder="Возраст (лет)" min="0" max="99" step="1"> <button id="sendBtn">Спросить</button> </div> <div class="action-row"> <button id="toggleAdminBtn">⚙️ Настроить рекомендации</button> <button id="clearChatBtn">🗑️ Очистить чат</button> </div> <!-- Панель администратора (редактирование рекомендаций) --> <div class="admin-panel" id="adminPanel"> <h3>📋 Редактор рекомендаций</h3> <div id="groupsContainer"></div> <button class="add-group-btn" id="addGroupBtn">➕ Добавить возрастную группу</button> <div style="margin-top:12px; font-size:13px; color:#7a5a6a;"> * Изменения сохраняются в памяти. При обновлении страницы сбросятся. </div> </div> <div class="footer-note"> 💡 Названия кукол можно менять прямо в панели настроек </div> </div> <script> (function() { // ---------- БАЗА ДАННЫХ (рекомендации) ---------- // Вы можете отредактировать этот объект напрямую или через интерфейс. // Ключ — возрастная группа (например, "0-2"), значение — массив названий кукол. let recommendations = { "0-2": ["Пупс Кроха", "Пупс Карапуз", "Зайка Барбоскин"], "3-5": ["Малышка Соня", "Эля", "София", "Ася"], "6-8": ["Снежана", "Милана", "Эсна"], "9-12": ["Мирэя", "Куклы ЭТНО", "Куклы ПРОФИ"], "12+": ["Любая кукла фабрики "Весна""] }; // ---------- DOM-элементы ---------- const chatBox = document.getElementById('chatBox'); const ageInput = document.getElementById('ageInput'); const sendBtn = document.getElementById('sendBtn'); const toggleAdminBtn = document.getElementById('toggleAdminBtn'); const clearChatBtn = document.getElementById('clearChatBtn'); const adminPanel = document.getElementById('adminPanel'); const groupsContainer = document.getElementById('groupsContainer'); const addGroupBtn = document.getElementById('addGroupBtn'); // ---------- Вспомогательные функции ---------- function addMessage(text, isUser = false) { const div = document.createElement('div'); div.className = `message ${isUser ? 'user' : 'bot'}`; div.innerHTML = text; chatBox.appendChild(div); chatBox.scrollTop = chatBox.scrollHeight; } function getAgeGroup(age) { const keys = Object.keys(recommendations); // Сортируем группы по возрастанию нижней границы const sorted = keys.slice().sort((a, b) => { const aLow = parseInt(a.split('-')[0]); const bLow = parseInt(b.split('-')[0]); return aLow - bLow; }); for (let key of sorted) { const parts = key.split('-'); const low = parseInt(parts[0]); const high = parts.length > 1 ? parseInt(parts[1]) : Infinity; if (age >= low && age <= high) { return key; } } return null; } function handleAsk() { const raw = ageInput.value.trim(); if (raw === '') { addMessage('Пожалуйста, введите возраст.', false); return; } const age = parseInt(raw); if (isNaN(age) || age < 0 || age > 99) { addMessage('Введите число от 0 до 99.', false); return; } // Сообщение пользователя addMessage(`👶 Возраст: ${age} лет`, true); // Поиск группы const group = getAgeGroup(age); if (group) { const dolls = recommendations[group]; if (dolls && dolls.length > 0) { const dollListHtml = dolls.map(d => `<span class="doll-item">${d}</span>`).join(''); addMessage(` <span class="age-badge">${group} лет</span> <div class="doll-list">${dollListHtml}</div> <div style="margin-top:6px;font-size:13px;color:#5d3f4b;">Рекомендуем обратить внимание на эти куклы!</div> `, false); } else { addMessage(`Для возраста ${age} лет пока нет рекомендаций. Добавьте их в настройках.`, false); } } else { addMessage(`Не найдена группа для возраста ${age} лет. Проверьте настройки.`, false); } ageInput.value = ''; ageInput.focus(); } // ---------- Отрисовка панели администратора ---------- function renderAdmin() { groupsContainer.innerHTML = ''; const sortedGroups = Object.keys(recommendations).slice().sort((a, b) => { const aLow = parseInt(a.split('-')[0]); const bLow = parseInt(b.split('-')[0]); return aLow - bLow; }); sortedGroups.forEach(groupKey => { const dolls = recommendations[groupKey] || []; const groupDiv = document.createElement('div'); groupDiv.className = 'group'; groupDiv.dataset.group = groupKey; // Шапка группы const header = document.createElement('div'); header.className = 'group-header'; const inputGroup = document.createElement('input'); inputGroup.type = 'text'; inputGroup.value = groupKey; inputGroup.placeholder = 'Напр. 3-5'; inputGroup.spellcheck = false; const saveBtn = document.createElement('button'); saveBtn.textContent = 'Сохранить'; const deleteBtn = document.createElement('button'); deleteBtn.textContent = 'Удалить'; deleteBtn.className = 'danger'; header.appendChild(inputGroup); header.appendChild(saveBtn); header.appendChild(deleteBtn); groupDiv.appendChild(header); // Список кукол (редактируемые теги) const dollListDiv = document.createElement('div'); dollListDiv.className = 'doll-list-edit'; dolls.forEach(dollName => { const tag = document.createElement('span'); tag.className = 'doll-tag'; tag.innerHTML = `${dollName} <span class="remove" data-doll="${dollName}">×</span>`; dollListDiv.appendChild(tag); }); groupDiv.appendChild(dollListDiv); // Форма добавления куклы const addForm = document.createElement('div'); addForm.className = 'add-doll-form'; const inputDoll = document.createElement('input'); inputDoll.type = 'text'; inputDoll.placeholder = 'Название куклы'; const addDollBtn = document.createElement('button'); addDollBtn.textContent = 'Добавить'; addForm.appendChild(inputDoll); addForm.appendChild(addDollBtn); groupDiv.appendChild(addForm); // Обработчики // Сохранить группу (изменить ключ) saveBtn.addEventListener('click', function() { const newKey = inputGroup.value.trim(); if (newKey === '') { alert('Название группы не может быть пустым.'); return; } if (newKey !== groupKey && recommendations.hasOwnProperty(newKey)) { alert('Группа с таким названием уже существует.'); return; } // Обновляем объект const oldDolls = recommendations[groupKey]; delete recommendations[groupKey]; recommendations[newKey] = oldDolls; renderAdmin(); }); // Удалить группу deleteBtn.addEventListener('click', function() { if (confirm(`Удалить группу "${groupKey}" и все её куклы?`)) { delete recommendations[groupKey]; renderAdmin(); } }); // Удалить отдельную куклу (через делегирование) dollListDiv.addEventListener('click', function(e) { const target = e.target; if (target.classList.contains('remove')) { const dollName = target.dataset.doll; const group = this.closest('.group').dataset.group; if (recommendations[group]) { const idx = recommendations[group].indexOf(dollName); if (idx !== -1) { recommendations[group].splice(idx, 1); renderAdmin(); } } } }); // Добавить куклу addDollBtn.addEventListener('click', function() { const name = inputDoll.value.trim(); if (name === '') return; const group = this.closest('.group').dataset.group; if (!recommendations[group]) recommendations[group] = []; recommendations[group].push(name); renderAdmin(); }); // Enter на поле ввода inputDoll.addEventListener('keydown', function(e) { if (e.key === 'Enter') { addDollBtn.click(); } }); groupsContainer.appendChild(groupDiv); }); } // ---------- Добавление новой группы ---------- function addNewGroup() { const key = prompt('Введите название возрастной группы (например, "0-2" или "13-16"):'); if (key === null) return; const trimmed = key.trim(); if (trimmed === '') { alert('Название не может быть пустым.'); return; } if (recommendations.hasOwnProperty(trimmed)) { alert('Такая группа уже существует.'); return; } recommendations[trimmed] = []; renderAdmin(); } // ---------- Очистка чата ---------- function clearChat() { chatBox.innerHTML = ''; // Добавим приветственное сообщение const welcome = document.createElement('div'); welcome.className = 'message bot'; welcome.innerHTML = '👋 Чат очищен. Напишите возраст ребёнка, чтобы получить рекомендации.'; chatBox.appendChild(welcome); } // ---------- Инициализация интерфейса ---------- function init() { renderAdmin(); // Отправка по клику и Enter sendBtn.addEventListener('click', handleAsk); ageInput.addEventListener('keydown', function(e) { if (e.key === 'Enter') { handleAsk(); } }); // Панель администратора toggleAdminBtn.addEventListener('click', function() { adminPanel.classList.toggle('open'); if (adminPanel.classList.contains('open')) { toggleAdminBtn.textContent = '🔒 Закрыть настройки'; } else { toggleAdminBtn.textContent = '⚙️ Настроить рекомендации'; } }); clearChatBtn.addEventListener('click', clearChat); // Добавить группу addGroupBtn.addEventListener('click', addNewGroup); // Фокус на поле возраста при загрузке ageInput.focus(); // Сохраняем рекомендации в глобальную переменную для отладки (опционально) window.__recommendations = recommendations; } // Запуск init(); })(); </script> </body> </html>