From 19005c28a759d66b2ca5476d155339dbdbdebc54 Mon Sep 17 00:00:00 2001 From: WASRUSGEN Date: Tue, 26 May 2026 09:22:01 +0300 Subject: [PATCH] Add custom request: voice/text input + localStorage analytics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "Нужен другой формат?" toggle after 4 deliverable cards - Textarea + Web Speech API microphone button (ru-RU) - On submit: Elena confirms, logs to zashita_custom_delivs in localStorage - Stats pill shows logged custom requests for analysis --- mockup.html | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/mockup.html b/mockup.html index 9dae532..2bc2944 100644 --- a/mockup.html +++ b/mockup.html @@ -129,6 +129,19 @@ body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-hei .ctype-note{display:block;font-size:13px;color:var(--mut);line-height:1.5;margin-bottom:6px;padding:8px 10px;background:var(--surf);border-radius:8px;border-left:3px solid var(--bg)} .sample-link{display:inline-block;margin-top:7px;font-size:11px;font-weight:600;color:var(--bg);text-decoration:none;border:1px solid rgba(159,18,57,.3);border-radius:5px;padding:2px 9px;transition:background .15s} .sample-link:hover{background:var(--tint)} +/* ── свой запрос ── */ +.custom-req-row{margin:14px 0 0 51px} +.custom-req-toggle{background:none;border:1.5px dashed var(--line);border-radius:11px;padding:9px 14px;font-size:13px;color:var(--mut);cursor:pointer;font-family:inherit;transition:all .15s;width:100%;max-width:520px;text-align:left} +.custom-req-toggle:hover{border-color:var(--bg);color:var(--bg);background:var(--tint)} +.custom-req-area{margin-top:4px} +.custom-input-block{margin:0 0 12px 51px;max-width:520px} +.custom-input-block textarea{width:100%;border:1.5px solid var(--line);border-radius:11px;padding:11px 13px;font-size:14px;font-family:inherit;color:var(--ink);resize:none;background:var(--card);transition:border .15s;line-height:1.5} +.custom-input-block textarea:focus{outline:none;border-color:var(--bg)} +.custom-input-btns{display:flex;gap:8px;margin-top:8px;align-items:stretch} +.custom-voice-btn{background:var(--surf);border:1.5px solid var(--line);border-radius:11px;width:46px;height:46px;font-size:20px;cursor:pointer;flex-shrink:0;transition:all .15s;display:flex;align-items:center;justify-content:center} +.custom-voice-btn:hover{border-color:var(--bg);background:var(--tint)} +.custom-voice-btn.recording{background:#fee2e2;border-color:#ef4444;animation:crpulse 1s infinite} +@keyframes crpulse{0%,100%{box-shadow:0 0 0 0 rgba(239,68,68,.3)}50%{box-shadow:0 0 0 6px rgba(239,68,68,0)}} /* ── план после выбора ── */ .plan-what{background:var(--surf);border-radius:12px;padding:14px 16px;margin:16px 0;max-width:600px} .plan-what-title{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:1.2px;color:var(--mut);margin-bottom:10px} @@ -399,6 +412,28 @@ body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-hei Рекомендуем + + +
+ +
+ @@ -979,7 +1014,93 @@ function toast(msg){ _toastT=setTimeout(()=>el.classList.remove('show'),2600); } function go(id){document.querySelectorAll('.screen').forEach(s=>s.classList.toggle('on',s.id===id));window.scrollTo(0,0);} +/* ── СВОЙ ЗАПРОС ── */ +let _customOpen = false; +let _voiceRec = null; + +function toggleCustomReq() { + _customOpen = !_customOpen; + const area = document.getElementById('custom-req-area'); + const btn = document.getElementById('custom-req-btn'); + area.style.display = _customOpen ? 'block' : 'none'; + btn.textContent = _customOpen ? '✕ Закрыть' : '✏️ Нужен другой формат? Опишите задачу →'; + if (_customOpen) { + area.scrollIntoView({ behavior: 'smooth' }); + setTimeout(() => document.getElementById('custom-text').focus(), 350); + } +} + +function toggleVoice() { + const SR = window.SpeechRecognition || window.webkitSpeechRecognition; + const btn = document.getElementById('custom-voice-btn'); + if (!SR) { btn.title='Не поддерживается — введите текстом'; btn.style.opacity='.4'; return; } + if (_voiceRec) { _voiceRec.stop(); return; } + _voiceRec = new SR(); + _voiceRec.lang = 'ru-RU'; + _voiceRec.continuous = true; + _voiceRec.interimResults = true; + const ta = document.getElementById('custom-text'); + const base = ta.value; + _voiceRec.onresult = e => { + let t = ''; + for (let i = e.resultIndex; i < e.results.length; i++) t += e.results[i][0].transcript; + ta.value = (base ? base + ' ' : '') + t; + }; + _voiceRec.onerror = _voiceRec.onend = () => { + _voiceRec = null; + btn.classList.remove('recording'); + btn.innerHTML = '🎤'; + }; + _voiceRec.start(); + btn.classList.add('recording'); + btn.innerHTML = '⏹'; +} + +function submitCustomReq() { + const text = (document.getElementById('custom-text').value || '').trim(); + if (!text) { document.getElementById('custom-text').focus(); return; } + if (_voiceRec) { _voiceRec.stop(); } + // Сохраняем в localStorage для анализа + const key = 'zashita_custom_delivs'; + const arr = JSON.parse(localStorage.getItem(key) || '[]'); + arr.push({ + ts: new Date().toISOString(), + ctype: (document.getElementById('el-scan-type') || {}).textContent || '', + text: text + }); + localStorage.setItem(key, JSON.stringify(arr)); + renderCustomStats(); + // Скрываем форму, показываем подтверждение + document.querySelector('.custom-input-block').style.display = 'none'; + document.getElementById('custom-req-btn').style.display = 'none'; + const short = text.length > 90 ? text.slice(0, 90) + '…' : text; + document.getElementById('custom-confirm-text').innerHTML = + `Записала! Передам юристу:
«${short}»

Свяжемся с вами в течение 24 часов. Обычно — быстрее 🙂`; + const conf = document.getElementById('custom-confirm'); + conf.style.display = 'flex'; + conf.scrollIntoView({ behavior: 'smooth' }); +} + +function renderCustomStats() { + const arr = JSON.parse(localStorage.getItem('zashita_custom_delivs') || '[]'); + let el = document.getElementById('custom-stats-pill'); + if (!arr.length) { if (el) el.style.display = 'none'; return; } + if (!el) { + el = document.createElement('div'); el.id = 'custom-stats-pill'; + el.className = 'stats-pill'; el.style.bottom = '52px'; + el.title = 'Нажать — очистить'; + el.onclick = () => { localStorage.removeItem('zashita_custom_delivs'); renderCustomStats(); }; + document.body.appendChild(el); + } + el.style.display = 'block'; + el.innerHTML = `Свои запросы (${arr.length})
` + + arr.slice(-3).map(r => + `· ${(r.ctype||'').trim().slice(0,20)} — ${(r.text||'').slice(0,38)}` + ).join('
'); +} + window.addEventListener('DOMContentLoaded', renderStats); +window.addEventListener('DOMContentLoaded', renderCustomStats); function tab(name){ document.querySelectorAll('.tabpane').forEach(p=>p.classList.toggle('on',p.id==='p-'+name)); document.querySelectorAll('.side a').forEach(a=>a.classList.remove('on'));