diff --git a/miniapp/assets/podbor.config.js b/miniapp/assets/podbor.config.js index 63bcc54..e7a867f 100644 --- a/miniapp/assets/podbor.config.js +++ b/miniapp/assets/podbor.config.js @@ -19,19 +19,6 @@ const PODBOR_BUDGET_TIERS = [ { key: "budget", label: "Бюджет", hint: "только нужное" }, ]; -const PODBOR_FAMILY = [ - { key: "single", label: "1 взрослый" }, - { key: "couple", label: "Пара" }, - { key: "family", label: "Семья с детьми" }, - { key: "multigen", label: "2+ поколения" }, -]; - -const PODBOR_COOKING = [ - { key: "daily", label: "Ежедневно" }, - { key: "weekly", label: "3–5 раз в неделю" }, - { key: "rare", label: "По выходным или реже" }, -]; - const PODBOR_INFRA = { stove: [ { key: "induction", label: "Индукция / 380 В" }, @@ -40,19 +27,19 @@ const PODBOR_INFRA = { { key: "any", label: "Не знаю / любой" }, ], vent: [ - { key: "shaft", label: "Шахта вентиляции есть" }, - { key: "no_shaft", label: "Только рециркуляция" }, - { key: "unknown", label: "Не знаю" }, + { key: "yes", label: "Да — есть выводы в вентиляцию" }, + { key: "no", label: "Нет — рециркуляция с угольным фильтром" }, + { key: "unknown", label: "Не знаю — менеджер уточнит" }, ], }; -const PODBOR_TECHNIQUES = [ - { key: "bake", label: "Выпечка" }, - { key: "steam", label: "На пару" }, - { key: "grill", label: "Гриль" }, - { key: "wok", label: "Wok / стир-фрай" }, - { key: "low_t", label: "Низкотемпературное" }, - { key: "smart", label: "Умные режимы / Smart" }, +const PODBOR_PRIORITIES = [ + { key: "balance", label: "Цена / качество" }, + { key: "reviews", label: "Отзывы" }, + { key: "popular", label: "Популярность бренда" }, + { key: "design", label: "Дизайн и цвет" }, + { key: "tech", label: "Технологичность" }, + { key: "service", label: "Сервис и гарантия" }, ]; /* Бренды для каждой категории — для чипов с тирами. diff --git a/miniapp/assets/podbor.css b/miniapp/assets/podbor.css index 0110765..9449d84 100644 --- a/miniapp/assets/podbor.css +++ b/miniapp/assets/podbor.css @@ -258,6 +258,72 @@ text-align: right; color: var(--ink); } +/* ----- Price range (от — до по категориям) ----- */ +.price-list { display: flex; flex-direction: column; gap: var(--s3); } + +.price-row { + display: flex; + flex-direction: column; + gap: 6px; +} + +.price-label { + font-family: var(--font-ui); + font-size: 13.5px; + font-weight: 500; + color: var(--ink-2); +} + +.price-inputs { + display: flex; + align-items: center; + gap: 6px; + min-width: 0; +} + +.price-inputs input { + flex: 1; + min-width: 0; + width: 100%; + font-family: var(--font-mono); + font-size: 13px; + padding: 8px 10px; + text-align: center; + background: var(--paper); + border: 1px solid var(--line); + border-radius: var(--r-tag); + color: var(--ink); +} + +.price-inputs .dash { + font-family: var(--font-mono); + color: var(--muted); + flex-shrink: 0; +} + +.price-inputs .rub { + font-family: var(--font-mono); + font-size: 12px; + color: var(--muted); + flex-shrink: 0; + padding-left: 2px; +} + +.price-total { + margin-top: var(--s2); + padding-top: var(--s2); + border-top: 1px solid var(--line); + font-family: var(--font-mono); + font-size: 11px; + letter-spacing: 0.10em; + text-transform: uppercase; + color: var(--ink-2); + text-align: right; +} + +.price-total strong { font-family: var(--font-ui); font-size: 14px; color: var(--ink); font-weight: 600; } +.price-total.muted { color: var(--muted); } + /* ----- Option chips ----- */ .opt-list { display: flex; flex-wrap: wrap; gap: 6px; } @@ -283,49 +349,86 @@ } /* ----- Brand chips ----- */ -.tier-row { display: flex; flex-direction: column; gap: 6px; padding: 8px 0; border-top: 1px solid var(--line); } -.tier-row:first-child { border-top: none; padding-top: 0; } +/* Тиры (Premium/Middle/Budget) различаются цветом, без явных текстовых ярлыков. + Внутренне храним tier для аналитики «температуры» клиента. */ -.tier-label { - font-family: var(--font-mono); - font-size: 9.5px; - font-weight: 500; - letter-spacing: 0.14em; - text-transform: uppercase; - color: var(--muted); +.brand-chips { + display: flex; + flex-wrap: wrap; + gap: 6px; + padding: 6px 0; + border-top: 1px dashed var(--line); } -.brand-chips { display: flex; flex-wrap: wrap; gap: 6px; } +.brand-chips:first-of-type { + border-top: none; + padding-top: 0; +} .chip { font-family: var(--font-ui); font-size: 12.5px; font-weight: 500; - padding: 6px 10px; + padding: 6px 11px; border-radius: var(--r-tag); - border: 1px solid var(--line-strong); - background: var(--paper); - color: var(--muted); + border: 1px solid; cursor: pointer; transition: all 0.12s; position: relative; } -.chip.status-preferred { - background: var(--accent-2); +/* Базовый цвет покоя по тирам — без слов, только тёплый/холодный оттенок */ +.chip.tier-premium { + background: var(--paper); + color: var(--accent-2); /* walnut */ + border-color: rgba(107, 74, 43, 0.35); +} + +.chip.tier-middle { + background: var(--paper); + color: var(--ink-2); + border-color: var(--line-strong); +} + +.chip.tier-budget { + background: var(--paper); + color: var(--muted); + border-color: var(--line); +} + +/* Состояние preferred — заливка цветом тира */ +.chip.tier-premium.status-preferred { + background: var(--accent-2); /* walnut */ color: var(--paper); border-color: var(--accent-2); font-weight: 600; } +.chip.tier-middle.status-preferred { + background: var(--ink); + color: var(--paper); + border-color: var(--ink); + font-weight: 600; +} + +.chip.tier-budget.status-preferred { + background: var(--muted); + color: var(--paper); + border-color: var(--muted); + font-weight: 600; +} + .chip.status-preferred::before { content: "★ "; } +/* Состояние acceptable — обводка цветом тира, прозрачная заливка */ .chip.status-acceptable { background: var(--paper-2); - color: var(--ink); - border-color: var(--accent-2); } +.chip.tier-premium.status-acceptable { border-color: var(--accent-2); color: var(--accent-2); } +.chip.tier-middle.status-acceptable { border-color: var(--ink); color: var(--ink); } +.chip.tier-budget.status-acceptable { border-color: var(--muted); color: var(--ink-2); } + .chip.status-acceptable::before { content: "✓ "; } /* ----- Summary ----- */ diff --git a/miniapp/assets/podbor.js b/miniapp/assets/podbor.js index 2a9daa9..b325cf4 100644 --- a/miniapp/assets/podbor.js +++ b/miniapp/assets/podbor.js @@ -3,8 +3,8 @@ ============================================================ */ const Podbor = (function () { - const STORAGE_KEY = "zov-podbor-v1"; - const STEPS = ["intro", "categories", "context", "infra", "scenario", "brands", "summary"]; + const STORAGE_KEY = "zov-podbor-v2"; + const STEPS = ["intro", "categories", "pricing", "infra", "priorities", "brands", "summary"]; let state = loadState(); let root = null; @@ -23,13 +23,11 @@ const Podbor = (function () { client_name: "", client_phone: "", address: "", - budget_total: "", - categories: [], // ['fridge','hob',...] - niches: {}, // { fridge:{w,h,d}, hob:{w,d}, oven:{w,h,d}, dw:{w,h,d} } - budget_by_cat: {},// { fridge:80000, hob:50000, ... } + categories: [], // ['fridge','hob',...] + price_ranges: {}, // { fridge: { from: 50000, to: 120000 }, ... } infra: { stove: "", vent: "" }, - scenario: { family: "", cooking: "", techniques: [], guests: "" }, - brands: {}, // { fridge: {Bosch:'preferred', Liebherr:'preferred'}, ... } + priorities: [], // ['balance','reviews',...] + brands: {}, // { fridge: {Bosch:'preferred',...}, ... } notes: "", }; } @@ -72,9 +70,9 @@ const Podbor = (function () { switch (currentStep) { case "intro": screen.appendChild(renderIntro()); break; case "categories": screen.appendChild(renderCategories()); break; - case "context": screen.appendChild(renderContext()); break; + case "pricing": screen.appendChild(renderPricing()); break; case "infra": screen.appendChild(renderInfra()); break; - case "scenario": screen.appendChild(renderScenario()); break; + case "priorities": screen.appendChild(renderPriorities()); break; case "brands": screen.appendChild(renderBrands()); break; case "summary": screen.appendChild(renderSummary()); break; } @@ -107,7 +105,7 @@ const Podbor = (function () { const idx = STEPS.indexOf(currentStep); const total = STEPS.length; const pct = Math.round(((idx + 1) / total) * 100); - const labels = ["Старт", "Категории", "Контекст", "Инфра", "Сценарий", "Бренды", "Подбор"]; + const labels = ["Старт", "Категории", "Цена", "Инфра", "Приоритеты", "Бренды", "Подбор"]; return el(`
7 коротких шагов. Указываем категории, бюджет, инфраструктуру и предпочтения. Дальше AI сам соберёт предложение.
+7 коротких шагов. Категории, ценовой коридор, инфраструктура и предпочтения. AI соберёт предложение.
Если планируется встройка — укажите размеры ниш. Бюджет по категориям помогает AI распределить деньги.
- - ${niches ? ` -«От — До» по каждой категории. AI подберёт варианты, которые попадают в коридор и совокупно укладываются в общий бюджет клиента.
+Газ или электрика — главный вопрос для варочной. Шахта вентиляции — для вытяжки.
+Газ или электрика — определит тип варочной (индукция / стеклокерамика / газ). Подключение вытяжки — нужны ли выводы или угольный фильтр.
Семья с детьми готовит иначе, чем пара. AI учтёт это в подборе.
- +Бюджет уже задал коридор. Здесь — что AI должен использовать как тай-брейк, когда варианты примерно равны по цене.
Какие марки уважаете, какие — допустимы. AI сначала пробует preferred.
+Тап — ★ предпочтительно. Дабл — ✓ допустимо. Третий — снять. AI сначала пробует ★, потом ✓.
${blocks}Проверьте и отправьте — AI вернёт предложение в чат с ботом.