— курсив.\n"
+ " НЕ используй markdown (**текст**, *текст*, ## заголовки) — только HTML.\n"
+ " pros/cons/highlights — массивы строк с HTML внутри.\n\n"
+ "Структура ответа:\n"
"{\n"
' "summary": "2-3 предложения общего вывода: что подобрали, почему этот набор, на чём сэкономили / куда вложились",\n'
' "by_category": {\n'
diff --git a/miniapp/assets/podbor.css b/miniapp/assets/podbor.css
index 0e0978b..e89d848 100644
--- a/miniapp/assets/podbor.css
+++ b/miniapp/assets/podbor.css
@@ -10,7 +10,8 @@
margin-bottom: var(--s4);
}
-.podbor-back {
+.podbor-back,
+.podbor-home {
width: 28px;
height: 28px;
display: grid;
@@ -19,7 +20,11 @@
cursor: pointer;
}
-.podbor-back svg { width: 20px; height: 20px; }
+.podbor-back svg,
+.podbor-home svg { width: 20px; height: 20px; }
+
+.podbor-home { color: var(--muted); opacity: 0.7; transition: opacity .15s; }
+.podbor-home:hover { opacity: 1; }
.podbor-title {
font-family: var(--font-mono);
diff --git a/miniapp/assets/podbor.js b/miniapp/assets/podbor.js
index a2335a4..81bdc04 100644
--- a/miniapp/assets/podbor.js
+++ b/miniapp/assets/podbor.js
@@ -97,24 +97,31 @@ const Podbor = (function () {
/* ===================== Header & progress ===================== */
+ function _goHome() {
+ location.hash = "";
+ if (typeof routeByHash === "function") routeByHash();
+ }
+
function renderHeader() {
const h = el(`
`);
h.querySelector(".podbor-back").addEventListener("click", () => {
const idx = STEPS.indexOf(currentStep);
if (idx <= 0) {
- // Выход из подбора в главный экран кабинета — без перезагрузки (иначе сплэш мигает)
- location.hash = "";
- if (typeof routeByHash === "function") routeByHash();
+ _goHome();
} else {
go(STEPS[idx - 1]);
}
});
+ h.querySelector(".podbor-home").addEventListener("click", () => {
+ haptic && haptic("impact");
+ _goHome();
+ });
return h;
}
@@ -1277,6 +1284,17 @@ const Podbor = (function () {
`;
result.innerHTML = headSuccess;
+ // Кнопка "Вернуться в главное" сразу после успеха
+ const homeBtn = el(`
+
+
+
+ `);
+ homeBtn.querySelector("button").addEventListener("click", () => {
+ haptic && haptic("impact");
+ _goHome();
+ });
+ result.appendChild(homeBtn);
// Рендер отчёта (если AI вернул by_category)
if (data.ai) {
const reportNode = renderReport(data.ai, data.id || "");
@@ -1305,12 +1323,14 @@ const Podbor = (function () {
const wrap = el(``);
// Шапка
- wrap.appendChild(el(`
-
-
Отчёт · ${leadId.slice(0, 8)}
- ${summary ? `
${_esc(summary)}
` : ""}
-
- `));
+ const headNode = el(`Отчёт · ${leadId.slice(0, 8)}
`);
+ if (summary) {
+ const sumP = document.createElement("p");
+ sumP.className = "report-summary";
+ sumP.innerHTML = _ai(summary);
+ headNode.appendChild(sumP);
+ }
+ wrap.appendChild(headNode);
// Категории
for (const [catKey, catData] of Object.entries(byCat)) {
@@ -1327,9 +1347,12 @@ const Podbor = (function () {
${(catIcon && ICONS[catIcon]) || ""}
${_esc(catLabel)}
- ${catAnalysis ? `${_esc(catAnalysis)}
` : ""}
+ ${catAnalysis ? `` : ""}
`);
+ if (catAnalysis) {
+ catNode.querySelector(".report-cat-analysis").innerHTML = _ai(catAnalysis);
+ }
// Сравнение цен — основной блок, всегда вверху
const matrixNode = _renderPriceMatrix(models);
@@ -1513,25 +1536,25 @@ ${reportEl.outerHTML}
${_esc(m.model || "")}
${metaParts.length ? `${metaParts.join(" · ")}
` : ""}
${priceHtml}
- ${(m.highlights || []).length ? `✓ ${m.highlights.map(_esc).join(" · ")}
` : ""}
+ ${(m.highlights || []).length ? `✓ ${m.highlights.map(_ai).join(" · ")}
` : ""}
${(m.pros || []).length ? `
Плюсы
-
${m.pros.slice(0, 4).map(p => `- ${_esc(p)}
`).join("")}
+
${m.pros.slice(0, 4).map(p => `- ${_ai(p)}
`).join("")}
` : ""}
${(m.cons || []).length ? `
Минусы
-
${m.cons.slice(0, 3).map(c => `- ${_esc(c)}
`).join("")}
+
${m.cons.slice(0, 3).map(c => `- ${_ai(c)}
`).join("")}
` : ""}
${_renderSpecsBlock(m.specs || {})}
- ${m.reasoning ? `💡 ${_esc(m.reasoning)}
` : ""}
+ ${m.reasoning ? `💡 ${_ai(m.reasoning)}
` : ""}
${_renderUtilityLinks(m)}
@@ -1725,6 +1748,15 @@ ${reportEl.outerHTML}
.replace(/'/g, "'");
}
+ /* AI-generated text — trusted backend output, render as HTML.
+ Strip script/on* to be safe, but allow
. */
+ function _ai(s) {
+ if (s == null) return "";
+ return String(s)
+ .replace(/
-
+
@@ -39,7 +39,7 @@
-
+