fix(podbor): HTML format + sticky header + home button at report bottom

- _ai(): markdown→HTML fallback (**, *, _, `) when no HTML tags found
- podbor-header: position:sticky so back/home always visible while scrolling
- renderReport(): footer with "← Главное меню" + "+ Новый подбор" buttons

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
wasrusgen 2026-05-19 09:26:07 +03:00
parent 3e7ae7764a
commit 12dec17ed1
3 changed files with 44 additions and 4 deletions

View File

@ -8,6 +8,11 @@
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: var(--s4); margin-bottom: var(--s4);
position: sticky;
top: 0;
z-index: 100;
background: var(--bg);
padding: 8px 0 4px;
} }
.podbor-back, .podbor-back,

View File

@ -1410,6 +1410,29 @@ const Podbor = (function () {
exportNode.querySelector("#exportPrint").addEventListener("click", () => _exportReportPrint(wrap, leadId)); exportNode.querySelector("#exportPrint").addEventListener("click", () => _exportReportPrint(wrap, leadId));
wrap.appendChild(exportNode); wrap.appendChild(exportNode);
// Кнопка «Домой» в самом конце отчёта — без скролла вверх
const footerNav = el(`
<div style="margin:16px 0 24px;display:flex;gap:10px;">
<button class="btn-secondary" style="flex:1;" id="reportNewPodbor"> Новый подбор</button>
<button class="btn-primary" style="flex:1;" id="reportGoHome"> Главное меню</button>
</div>
`);
footerNav.querySelector("#reportGoHome").addEventListener("click", () => {
haptic && haptic("impact");
_goHome();
});
footerNav.querySelector("#reportNewPodbor").addEventListener("click", () => {
haptic && haptic("impact");
// Сбрасываем state и начинаем заново
state = defaultState();
saveState();
currentStep = "intro";
detailView = "menu";
render();
window.scrollTo({ top: 0, behavior: "smooth" });
});
wrap.appendChild(footerNav);
return wrap; return wrap;
} }
@ -1842,12 +1865,24 @@ ${reportEl.outerHTML}
} }
/* AI-generated text trusted backend output, render as HTML. /* AI-generated text trusted backend output, render as HTML.
Strip script/on* to be safe, but allow <b><em><ul><li><br>. */ Strip script/on* to be safe, but allow <b><em><ul><li><br>.
Markdown fallback: если GigaChat всё же вернул ** или *, конвертируем. */
function _ai(s) { function _ai(s) {
if (s == null) return ""; if (s == null) return "";
return String(s) let t = String(s)
.replace(/<script[\s\S]*?<\/script>/gi, "") .replace(/<script[\s\S]*?<\/script>/gi, "")
.replace(/\son\w+\s*=/gi, " data-stripped="); .replace(/\son\w+\s*=/gi, " data-stripped=");
// Markdown → HTML только если нет HTML-тегов (GigaChat иногда игнорирует инструкцию)
if (!/<[a-zA-Z]/.test(t)) {
t = t
.replace(/\*\*\*(.+?)\*\*\*/g, "<b><em>$1</em></b>") // ***bold-italic***
.replace(/\*\*(.+?)\*\*/g, "<b>$1</b>") // **bold**
.replace(/\*([^*\n]+?)\*/g, "<em>$1</em>") // *italic*
.replace(/_([^_\n]+?)_/g, "<em>$1</em>") // _italic_
.replace(/`([^`]+?)`/g, "<code>$1</code>") // `code`
.replace(/\n/g, "<br>"); // newlines
}
return t;
} }
/* ===================== Helpers ===================== */ /* ===================== Helpers ===================== */

View File

@ -13,7 +13,7 @@
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700&family=Inter:wght@400;500;600;700;800&family=Geist:wght@400;500;600&family=Manrope:wght@400;500;600;700&family=Newsreader:ital,wght@0,400..600;1,400..600&family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500&family=Cormorant+Garamond:ital,wght@1,400;1,500;1,600&family=Caveat:wght@500;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700&family=Inter:wght@400;500;600;700;800&family=Geist:wght@400;500;600&family=Manrope:wght@400;500;600;700&family=Newsreader:ital,wght@0,400..600;1,400..600&family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500&family=Cormorant+Garamond:ital,wght@1,400;1,500;1,600&family=Caveat:wght@500;700&display=swap">
<script src="https://telegram.org/js/telegram-web-app.js"></script> <script src="https://telegram.org/js/telegram-web-app.js"></script>
<link rel="stylesheet" href="assets/styles.css?v=20260518o"> <link rel="stylesheet" href="assets/styles.css?v=20260518o">
<link rel="stylesheet" href="assets/podbor.css?v=20260519a"> <link rel="stylesheet" href="assets/podbor.css?v=20260519c">
</head> </head>
<body> <body>
<!-- Splash — лого @wasrusgen1 + опилки (16) + вращающийся диск --> <!-- Splash — лого @wasrusgen1 + опилки (16) + вращающийся диск -->
@ -39,7 +39,7 @@
<script src="assets/icons.js?v=20260516h"></script> <script src="assets/icons.js?v=20260516h"></script>
<script src="assets/podbor.config.js?v=20260516h"></script> <script src="assets/podbor.config.js?v=20260516h"></script>
<script src="assets/podbor.picts.js?v=20260516h"></script> <script src="assets/podbor.picts.js?v=20260516h"></script>
<script src="assets/podbor.js?v=20260519b"></script> <script src="assets/podbor.js?v=20260519c"></script>
<script src="assets/clients.js?v=20260518e"></script> <script src="assets/clients.js?v=20260518e"></script>
<script src="assets/zamer-picts.js?v=20260516h"></script> <script src="assets/zamer-picts.js?v=20260516h"></script>
<script src="assets/measurements.js?v=20260518f"></script> <script src="assets/measurements.js?v=20260518f"></script>