/* global React */ const { useState: useStateQ, useEffect: useEffectQ, useMemo: useMemoQ } = React; /* questions strictly per brief — Email removed from channel options */ const QUESTIONS = [ { id: "experience", title: "Есть ли у вас опыт инвестирования?", options: [ "Да, есть опыт", "Частично", "Нет, только знакомлюсь", "Пока просто интересуюсь", ], }, { id: "long_term", title: "Интересуют ли вас долгосрочные решения?", options: [ "Да, рассматриваю долгосрочно", "Скорее да", "Скорее нет", "Пока не определился(ась)", ], }, { id: "consult", title: "Рассматриваете ли вы консультацию?", options: [ "Да, хотелось бы получить", "Возможно, нужна дополнительная информация", "Сначала хочу прочитать материалы", "Не сейчас", ], }, { id: "channel", title: "Как вам удобнее получить информацию?", options: [ "Звонок", "Telegram", "WhatsApp", ], }, ]; const CHANNEL_INDEX = QUESTIONS.findIndex(q => q.id === "channel"); /* phone mask: +7 (XXX) XXX-XX-XX */ function formatPhoneQ(raw) { const digits = raw.replace(/\D/g, "").slice(0, 11); let d = digits; if (d.length > 0) { if (d[0] === "8") d = "7" + d.slice(1); if (d[0] !== "7") d = "7" + d; d = d.slice(0, 11); } if (d.length === 0) return ""; let out = "+7"; if (d.length > 1) out += " (" + d.slice(1, 4); if (d.length >= 4) out += ") " + d.slice(4, 7); if (d.length >= 7) out += "-" + d.slice(7, 9); if (d.length >= 9) out += "-" + d.slice(9, 11); return out; } /* "@username" or "+7 phone" — Telegram-flexible */ function formatTelegramQ(raw) { const trimmed = raw.trim(); if (trimmed.startsWith("@")) { return "@" + trimmed.slice(1).replace(/[^A-Za-z0-9_]/g, "").slice(0, 32); } if (/^[A-Za-z]/.test(trimmed)) { return "@" + trimmed.replace(/[^A-Za-z0-9_]/g, "").slice(0, 32); } return formatPhoneQ(raw); } /* validation per channel */ function validateContact(channel, value) { const v = (value || "").trim(); if (!v) return "Укажите контакт"; if (channel === 1) { if (v.startsWith("@")) { if (v.length < 6) return "Минимум 5 символов после @"; return null; } if (v.replace(/\D/g, "").length < 11) return "Введите @username или номер полностью"; return null; } if (v.replace(/\D/g, "").length < 11) return "Введите номер полностью"; return null; } function QuizOverlay({ onClose, onOpenPrivacy }) { // 0..3 = questions, 4 = form const [step, setStep] = useStateQ(0); const [answers, setAnswers] = useStateQ({}); const [name, setName] = useStateQ(""); const [contact, setContact] = useStateQ(""); const [err, setErr] = useStateQ({}); const [submitting, setSubmitting] = useStateQ(false); const totalSteps = QUESTIONS.length + 1; // 4 q + form const progress = step >= totalSteps ? 100 : Math.round((step / totalSteps) * 100); const currentQ = step < QUESTIONS.length ? QUESTIONS[step] : null; const currentAnswer = currentQ ? answers[currentQ.id] : null; // selected channel index (0=call, 1=telegram, 2=whatsapp); default = call const channel = answers["channel"] ?? 0; const channelMeta = useMemoQ(() => { if (channel === 1) { return { label: "Telegram", sub: "@username или номер телефона", placeholder: "@username или +7 (___) ___-__-__", inputMode: "text", autocomplete: "off", formatter: formatTelegramQ, }; } if (channel === 2) { return { label: "WhatsApp", sub: "Номер для сообщения в WhatsApp", placeholder: "+7 (___) ___-__-__", inputMode: "tel", autocomplete: "tel", formatter: formatPhoneQ, }; } return { label: "Телефон", sub: "Для звонка в рабочее время", placeholder: "+7 (___) ___-__-__", inputMode: "tel", autocomplete: "tel", formatter: formatPhoneQ, }; }, [channel]); // reset contact value if user goes back and picks another channel useEffectQ(() => { setContact(""); setErr(e => ({ ...e, contact: undefined })); }, [channel]); useEffectQ(() => { function onKey(e) { if (e.key === "Escape") onClose(); if (e.key === "Enter" && currentQ && currentAnswer != null) next(); } window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }); function pick(qid, idx) { setAnswers(a => ({ ...a, [qid]: idx })); setTimeout(() => setStep(s => Math.min(s + 1, totalSteps)), 260); } function next() { if (step < totalSteps) setStep(s => s + 1); } function back() { setStep(s => Math.max(0, s - 1)); } function validate() { const e = {}; if (!name.trim() || name.trim().length < 2) e.name = "Укажите имя"; const cErr = validateContact(channel, contact); if (cErr) e.contact = cErr; setErr(e); return Object.keys(e).length === 0; } function submit() { if (!validate()) return; setSubmitting(true); // Классическая HTML-форма (WAF-friendly): собираем скрытую