feat: KB — hero-баннеры и цветные миниатюры статей

This commit is contained in:
wasrusgen 2026-05-29 01:10:08 +03:00
parent f87b026498
commit c350bb690d

View File

@ -3961,29 +3961,53 @@ function _openArticle(id){
document.getElementById('nav').innerHTML = navBar(); document.getElementById('nav').innerHTML = navBar();
} }
var _roomGrad = {
kitchen: ['#F97316','#EF4444'],
bedroom: ['#818CF8','#6366F1'],
living: ['#34D399','#059669'],
bathroom:['#22D3EE','#0891B2'],
hallway: ['#94A3B8','#475569'],
kids: ['#F472B6','#A855F7'],
office: ['#60A5FA','#2563EB'],
balcony: ['#86EFAC','#16A34A']
};
function screenArticle(){ function screenArticle(){
var allArticles = _KB.reduce(function(acc,r){ return acc.concat(r.articles.map(function(a){ return Object.assign({},a,{roomLabel:r.label,roomIcon:r.icon}); })); }, []); var allArticles = _KB.reduce(function(acc,r){ return acc.concat(r.articles.map(function(a){ return Object.assign({},a,{roomLabel:r.label,roomIcon:r.icon,roomId:r.id}); })); }, []);
var a = allArticles.find(function(x){ return x.id === window._kbArticle; }); var a = allArticles.find(function(x){ return x.id === window._kbArticle; });
if(!a) return '<div style="padding:32px;text-align:center;color:var(--muted)">Статья не найдена</div>'; if(!a) return '<div style="padding:32px;text-align:center;color:var(--muted)">Статья не найдена</div>';
var bk='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M15 18l-6-6 6-6"/></svg>'; var bk='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M15 18l-6-6 6-6"/></svg>';
var tagColor={'Материалы':'#3B82F6','Ткани':'#8B5CF6','Уход':'#10B981','Конструкции':'#F59E0B','Дизайн':'#EC4899','Безопасность':'#EF4444','Монтаж':'#0EA5E9','Клиентам':'#14B8A6','Автоматика':'#F97316'}[a.tag]||'#64748B'; var tagColor={'Материалы':'#3B82F6','Ткани':'#8B5CF6','Уход':'#10B981','Конструкции':'#F59E0B','Дизайн':'#EC4899','Безопасность':'#EF4444','Монтаж':'#0EA5E9','Клиентам':'#14B8A6','Автоматика':'#F97316'}[a.tag]||'#64748B';
// Рендер тела: переносы → параграфы, жирный текст **...** var grad = _roomGrad[a.roomId]||['#94A3B8','#475569'];
// Hero-баннер
var hero = '<div style="height:180px;background:linear-gradient(135deg,'+grad[0]+' 0%,'+grad[1]+' 100%);'
+'display:flex;align-items:center;justify-content:center;'
+'border-radius:0 0 24px 24px;margin:-0px -0px 20px;position:relative;overflow:hidden;flex-shrink:0">'
+'<div style="position:absolute;inset:0;background:repeating-linear-gradient(135deg,rgba(255,255,255,.06) 0,rgba(255,255,255,.06) 1px,transparent 1px,transparent 18px)"></div>'
+'<div style="position:absolute;right:-20px;bottom:-20px;width:140px;height:140px;border-radius:50%;background:rgba(255,255,255,.08)"></div>'
+'<div style="position:absolute;left:-30px;top:-30px;width:100px;height:100px;border-radius:50%;background:rgba(255,255,255,.06)"></div>'
+'<span style="font-size:80px;position:relative;filter:drop-shadow(0 6px 16px rgba(0,0,0,.25))">'+a.roomIcon+'</span>'
+'</div>';
// Рендер тела: переносы → параграфы
var bodyHtml = a.body.split('\n\n').map(function(para){ var bodyHtml = a.body.split('\n\n').map(function(para){
var p = para.replace(/\n/g,'<br>'); var p = para.replace(/\n/g,'<br>');
return '<p style="margin:0 0 14px;font-size:14px;line-height:1.7;color:var(--ink)">'+p+'</p>'; return '<p style="margin:0 0 14px;font-size:14px;line-height:1.7;color:var(--ink)">'+p+'</p>';
}).join(''); }).join('');
return '<div class="page">' return '<div class="page" style="overflow-y:auto">'
+'<div class="page-header"><button class="back-btn" onclick="window._kbArticle=null;_nav(\'manager_kb\')">'+bk+'</button><h2>📚 База знаний</h2></div>' +'<div style="position:relative">'
+'<div style="padding:16px 16px 32px">' + hero
// Шапка статьи +'<div style="position:absolute;top:12px;left:12px">'
+'<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px">' +'<button class="back-btn" onclick="window._kbArticle=null;_nav(\'manager_kb\')" style="background:rgba(255,255,255,.25);backdrop-filter:blur(8px);border:none;border-radius:50%;width:34px;height:34px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#fff">'+bk+'</button>'
+'<span style="font-size:20px">'+a.roomIcon+'</span>' +'</div>'
+'<span style="font-size:11px;color:var(--muted)">'+a.roomLabel+'</span>' +'</div>'
+'<span style="width:3px;height:3px;border-radius:50%;background:var(--muted);display:inline-block"></span>' +'<div style="padding:0 16px 32px">'
// Мета-строка
+'<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">'
+'<span style="font-size:10px;font-weight:700;padding:2px 8px;border-radius:20px;background:'+tagColor+'18;color:'+tagColor+'">'+a.tag+'</span>' +'<span style="font-size:10px;font-weight:700;padding:2px 8px;border-radius:20px;background:'+tagColor+'18;color:'+tagColor+'">'+a.tag+'</span>'
+'<span style="font-size:10px;color:var(--muted)">'+a.roomLabel+'</span>'
+'<span style="font-size:10px;color:var(--muted);margin-left:auto">👁 '+a.views.toLocaleString('ru')+'</span>' +'<span style="font-size:10px;color:var(--muted);margin-left:auto">👁 '+a.views.toLocaleString('ru')+'</span>'
+'</div>' +'</div>'
+'<h3 style="font-size:17px;font-weight:700;color:var(--ink);line-height:1.4;margin:0 0 16px">'+a.title+'</h3>' +'<h3 style="font-size:18px;font-weight:700;color:var(--ink);line-height:1.4;margin:0 0 16px">'+a.title+'</h3>'
+'<div style="height:1px;background:rgba(0,0,0,.07);margin-bottom:16px"></div>' +'<div style="height:1px;background:rgba(0,0,0,.07);margin-bottom:16px"></div>'
+ bodyHtml + bodyHtml
// Кнопка источника в Telegram // Кнопка источника в Telegram
@ -4001,7 +4025,7 @@ function screenKB(){
var room = _KB.find(function(r){return r.id===window._kbRoom;})||_KB[0]; var room = _KB.find(function(r){return r.id===window._kbRoom;})||_KB[0];
var search = window._kbSearch.toLowerCase().trim(); var search = window._kbSearch.toLowerCase().trim();
var articles= search var articles= search
? _KB.reduce(function(acc,r){return acc.concat(r.articles.map(function(a){return Object.assign({},a,{room:r.label,roomIcon:r.icon});}));}, []) ? _KB.reduce(function(acc,r){return acc.concat(r.articles.map(function(a){return Object.assign({},a,{room:r.label,roomIcon:r.icon,roomId:r.id});}));}, [])
.filter(function(a){return a.title.toLowerCase().indexOf(search)>=0||a.tag.toLowerCase().indexOf(search)>=0;}) .filter(function(a){return a.title.toLowerCase().indexOf(search)>=0||a.tag.toLowerCase().indexOf(search)>=0;})
: room.articles; : room.articles;
@ -4019,9 +4043,14 @@ function screenKB(){
'Материалы':'#3B82F6','Ткани':'#8B5CF6','Уход':'#10B981','Конструкции':'#F59E0B', 'Материалы':'#3B82F6','Ткани':'#8B5CF6','Уход':'#10B981','Конструкции':'#F59E0B',
'Дизайн':'#EC4899','Безопасность':'#EF4444','Монтаж':'#0EA5E9','Клиентам':'#14B8A6','Автоматика':'#F97316' 'Дизайн':'#EC4899','Безопасность':'#EF4444','Монтаж':'#0EA5E9','Клиентам':'#14B8A6','Автоматика':'#F97316'
}[a.tag]||'#64748B'; }[a.tag]||'#64748B';
var hasBody = !!a.body; var rid = a.roomId || room.id;
return '<div style="background:var(--card);margin:0 14px 8px;border-radius:14px;padding:13px 14px;display:flex;align-items:flex-start;gap:10px;cursor:pointer" onclick="_openArticle(\''+a.id+'\')">' var grad = _roomGrad[rid]||['#94A3B8','#475569'];
+'<div style="width:36px;height:36px;border-radius:10px;background:rgba(0,62,126,.07);display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:18px">'+(a.roomIcon||room.icon)+'</div>' var thumb = '<div style="width:52px;height:52px;border-radius:12px;flex-shrink:0;'
+'background:linear-gradient(135deg,'+grad[0]+','+grad[1]+');'
+'display:flex;align-items:center;justify-content:center;font-size:24px;'
+'box-shadow:0 2px 8px rgba(0,0,0,.12)">'+(a.roomIcon||room.icon)+'</div>';
return '<div style="background:var(--card);margin:0 14px 8px;border-radius:14px;padding:12px 14px;display:flex;align-items:flex-start;gap:12px;cursor:pointer" onclick="_openArticle(\''+a.id+'\')">'
+ thumb
+'<div style="flex:1;min-width:0">' +'<div style="flex:1;min-width:0">'
+'<div style="font-size:13px;font-weight:600;color:var(--ink);line-height:1.4;margin-bottom:5px">'+a.title+'</div>' +'<div style="font-size:13px;font-weight:600;color:var(--ink);line-height:1.4;margin-bottom:5px">'+a.title+'</div>'
+'<div style="display:flex;align-items:center;gap:8px">' +'<div style="display:flex;align-items:center;gap:8px">'
@ -4030,7 +4059,7 @@ function screenKB(){
+'<span style="font-size:10px;color:var(--muted);margin-left:auto">👁 '+a.views.toLocaleString('ru')+'</span>' +'<span style="font-size:10px;color:var(--muted);margin-left:auto">👁 '+a.views.toLocaleString('ru')+'</span>'
+'</div>' +'</div>'
+'</div>' +'</div>'
+'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" stroke-width="2.5" style="flex-shrink:0;margin-top:2px"><polyline points="9 18 15 12 9 6"/></svg>' +'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" stroke-width="2.5" style="flex-shrink:0;margin-top:4px"><polyline points="9 18 15 12 9 6"/></svg>'
+'</div>'; +'</div>';
}).join(''); }).join('');