import React, { useState, useEffect } from 'react';
import { ChevronLeft, ChevronRight, Lock, ArrowRight, CheckCircle2, ShieldCheck, Sparkles, AlertCircle, Clock, CheckSquare, Square } from 'lucide-react';
// ─── Helper Icons (For Results Page) ──────────────────────────────────────────
const LockIcon = () => (
);
const ClockIcon = () => (
);
const StarIcon = () => (
);
// ─── Animated Ring (For Results Page) ────────────────────────────────────────
const ScoreRing = ({ score }) => {
const [animated, setAnimated] = useState(0);
useEffect(() => {
const t = setTimeout(() => setAnimated(score), 300);
return () => clearTimeout(t);
}, [score]);
const r = 62, circ = 2 * Math.PI * r;
const offset = circ - (animated / 100) * circ;
const color = score >= 60 ? "#2563eb" : "#16a34a"; // Blue or Green
return (
);
};
// ─── Metric Bar (For Results Page) ───────────────────────────────────────────
const MetricBar = ({ label, current, target, boost, delay = 0, locked = false }) => {
const [w, setW] = useState(0);
useEffect(() => {
if (locked) return;
const t = setTimeout(() => setW(current), 400 + delay);
return () => clearTimeout(t);
}, [current, delay, locked]);
const gap = target - current;
if (locked) {
return (
);
}
return (
↑ +{boost} баллов с правильной стратегией
);
};
// ─── Timeline Item (For Results Page) ────────────────────────────────────────
const TimelineItem = ({ number, title, desc }) => (
);
// ─── Countdown Hook ──────────────────────────────────────────────────────────
const useCountdown = (start = 239) => { // Defaults to 4 minutes
const [s, setS] = useState(start);
useEffect(() => {
if (s <= 0) return;
const id = setInterval(() => setS(x => x - 1), 1000);
return () => clearInterval(id);
}, [s]);
const m = String(Math.floor(s / 60)).padStart(2, "0");
const sec = String(s % 60).padStart(2, "0");
return { m, sec, urgent: s < 60 };
};
// ─── Ticker String ───────────────────────────────────────────────────────────
const TICKER = "🎓 Алина забронировала слот · 🏆 Марк прошел тест · ✅ Диана забронировала слот · 🎯 Иван — Yonsei University · 🌟 Соня — HKUST · 💼 Артур забронировал слот · ";
// --- DATA & CONFIG ---
const funnelSteps = [
{
id: 1,
type: 'question',
title: 'Выберите ваш профиль',
options: [
{ id: 'q1_1', text: 'Я студент', subtext: 'Хочу поступить в топовый вуз', emoji: '🧑🎓', score: null },
{ id: 'q1_2', text: 'Я родитель', subtext: 'Хочу обеспечить ребенку лучшее будущее', emoji: '👨👩👧', score: null },
]
},
{
id: 'about',
type: 'about',
title: '"Более 2,400"',
subtitle: 'учеников поступили в топ-вузы с impact admissions'
},
{
id: 'grade',
type: 'question',
title: 'В каком классе сейчас учитесь (вы или ваш ребенок)?',
options: [
{ id: 'gr_1', text: '8 класс или младше', subtext: 'Есть масса времени на сильный профиль', emoji: '🌱', score: null },
{ id: 'gr_2', text: '9 - 10 класс', subtext: 'Идеальное время для старта подготовки', emoji: '⏳', score: null },
{ id: 'gr_3', text: '11 класс', subtext: 'Нужна экстренная стратегия и подача заявок', emoji: '🔥', score: null },
{ id: 'gr_4', text: 'Уже закончил(а) школу / Учусь в университете', subtext: 'Планирую перевод (Transfer) или магистратуру', emoji: '🎓', score: null },
]
},
{
id: 2,
type: 'question',
title: 'О каких университетах вы мечтаете?',
options: [
{ id: 'q2_1', text: 'Самые элитные в мире', subtext: 'Лига Плюща, Стэнфорд, MIT, Оксбридж', emoji: '🏛️', score: null },
{ id: 'q2_2', text: 'Очень престижные, Топ-50', subtext: 'Например, NYU, UCLA, UCL (Лондон)', emoji: '🌟', score: null },
{ id: 'q2_3', text: 'Топ-100 мира или хорошая Европа', subtext: 'Главное — сильный диплом и гранты', emoji: '🌍', score: null },
{ id: 'q2_4', text: 'Пока не знаю', subtext: 'Хочу понять, куда реально поступить', emoji: '🤔', score: null },
]
},
{
id: 'fears',
type: 'multi',
title: 'Что сейчас пугает больше всего?',
subtitle: 'Можно выбрать несколько вариантов',
options: [
{ id: 'f1', text: 'Огромная конкуренция среди отличников', emoji: '😰' },
{ id: 'f2', text: 'Нет выдающихся достижений вне школы', emoji: '📉' },
{ id: 'f3', text: 'Страх не потянуть обучение финансово', emoji: '💸' },
{ id: 'f4', text: 'Непонятно, с чего вообще начать', emoji: '🤷' },
{ id: 'f5', text: 'Сложности с написанием эссе', emoji: '✍️' },
]
},
{
id: 'insight1',
type: 'insight',
emoji: '📊',
title: 'В Топ-вузы поступают только 4-7% кандидатов.',
subtitle: 'Но среди тех, кто использует стратегию "impact admissions", шансы получить заветный оффер (и стипендию!) вырастают до 38%.'
},
{
id: 3,
type: 'question',
title: 'Как обстоят дела с оценками в школе?',
options: [
{ id: 'q3_1', text: 'Круглый отличник', subtext: 'Беру самые сложные предметы (AP/IB/A-level/Физмат)', emoji: '📚', score: { category: 'academic', value: 85 } },
{ id: 'q3_2', text: 'В основном 4 и 5', subtext: 'Хорошая успеваемость, но программа обычная', emoji: '📈', score: { category: 'academic', value: 65 } },
{ id: 'q3_3', text: 'Оценки средние', subtext: 'Но есть пара любимых предметов, где я силен', emoji: '⚖️', score: { category: 'academic', value: 45 } },
{ id: 'q3_4', text: 'Оценки ниже среднего', subtext: 'Придется перекрывать их крутыми баллами SAT/IELTS', emoji: '⚠️', score: { category: 'academic', value: 30 } },
]
},
{
id: 'load1',
type: 'loading',
duration: 4000,
phases: [
'Оцениваем текущую успеваемость...',
'Сравниваем с проходными баллами Топ-10...',
'Вычисляем стартовый потенциал...'
]
},
{
id: 4,
type: 'question',
title: 'Чем вы занимаетесь после уроков?',
options: [
{ id: 'q4_1', text: 'Развиваю 1-2 серьезных проекта', subtext: 'Например: свой бизнес, стартап, победы на олимпиадах', emoji: '🏆', score: { category: 'extraDepth', value: 85 } },
{ id: 'q4_2', text: 'Хожу на много разных кружков', subtext: 'Интересов много, но грандиозных успехов пока нет', emoji: '🎨', score: { category: 'extraDepth', value: 55 } },
{ id: 'q4_3', text: 'Спорт, музыка или танцы', subtext: 'Занимаюсь для себя или на школьном уровне', emoji: '⚽', score: { category: 'extraDepth', value: 35 } },
{ id: 'q4_4', text: 'Ничем серьезным', subtext: 'Все время уходит только на уроки и репетиторов', emoji: '📝', score: { category: 'extraDepth', value: 20 } },
]
},
{
id: 5,
type: 'question',
title: 'Приносят ли ваши проекты реальную пользу другим людям (impact)?',
options: [
{ id: 'q5_1', text: 'Да, масштаб огромный', subtext: 'Влияние на уровне страны или мира (НГО, публикации)', emoji: '🌎', score: { category: 'extraImpact', value: 90 } },
{ id: 'q5_2', text: 'Да, на уровне города', subtext: 'Организую волонтерство, управляю сообществом', emoji: '🏙️', score: { category: 'extraImpact', value: 65 } },
{ id: 'q5_3', text: 'Да, но только в школе', subtext: 'Президент школьного клуба, помогаю учителям', emoji: '🏫', score: { category: 'extraImpact', value: 40 } },
{ id: 'q5_4', text: 'Пока нет', subtext: 'Я делаю проекты только для себя', emoji: '🌱', score: { category: 'extraImpact', value: 20 } },
]
},
{
id: 'compare1',
type: 'compare',
title: 'Приемная комиссия ищет "Спайк" (уникальную изюминку), а не просто хороших учеников.',
subtitle: 'Начните применять стратегию сегодня, и ваш профиль кардинально изменится:'
},
{
id: 6,
type: 'question',
title: 'Престижные университеты ищут студентов с "искренней жаждой знаний". Что из этого про вас?',
options: [
{ id: 'q6_1', text: 'Постоянно изучаю то, чего нет в школе', subtext: 'Делаю свои исследования, читаю научные статьи', emoji: '🧠', score: { category: 'vitality', value: 90 } },
{ id: 'q6_2', text: 'Углубляюсь в любимые предметы', subtext: 'Смотрю лекции на YouTube, читаю доп. литературу', emoji: '📖', score: { category: 'vitality', value: 65 } },
{ id: 'q6_3', text: 'Просто хорошо делаю домашку', subtext: 'Выполняю всё, что задают, но не более того', emoji: '✅', score: { category: 'vitality', value: 40 } },
{ id: 'q6_4', text: 'Учусь только ради поступления', subtext: 'Оценки — это просто средство достижения цели', emoji: '🎯', score: { category: 'vitality', value: 20 } },
]
},
{
id: 'load2',
type: 'loading',
duration: 4500,
phases: [
'Оцениваем уровень лидерства...',
'Проверяем критерий "Жажда знаний"...',
'Формируем индивидуальный план поступления...'
]
},
{
id: 'lead_capture',
type: 'capture'
},
{
id: 'results',
type: 'results'
}
];
const loadingTestimonials = [
{ text: "Сэкономили месяцы стресса. Поняли, какой Hook нужен для Стэнфорда.", author: "Артур (РК)", stars: "★★★★★" },
{ text: "Благодаря этой стратегии я получил оффер от плющей с грантом $70k.", author: "Алишер (KZ)", stars: "★★★★★" },
{ text: "Оказывается, мой GPA был не главной проблемой. Переделали позиционирование!", author: "Динара (UZ)", stars: "★★★★★" },
];
export default function App() {
const [currentStepIndex, setCurrentStepIndex] = useState(0);
const [answers, setAnswers] = useState({});
const [scores, setScores] = useState({ academic: 0, extraDepth: 0, extraImpact: 0, vitality: 0 });
const [isTransitioning, setIsTransitioning] = useState(false);
const [formData, setFormData] = useState({ name: '', contact: '' });
const currentStep = funnelSteps[currentStepIndex];
const questionSteps = funnelSteps.filter(s => ['question', 'multi', 'capture'].includes(s.type));
const currentQIndex = questionSteps.findIndex(s => s.id === currentStep.id);
const progressPercent = currentStep.type === 'results'
? 100
: currentQIndex >= 0
? Math.max(10, Math.round(((currentQIndex) / questionSteps.length) * 100))
: Math.max(10, Math.round(((currentStepIndex) / funnelSteps.length) * 100));
const handleNextStep = () => {
setIsTransitioning(true);
setTimeout(() => {
setCurrentStepIndex(prev => prev + 1);
setIsTransitioning(false);
}, 300);
};
const handlePrevStep = () => {
if (currentStepIndex === 0) return;
let prevIndex = currentStepIndex - 1;
while (prevIndex > 0 && funnelSteps[prevIndex].type === 'loading') {
prevIndex--;
}
setIsTransitioning(true);
setTimeout(() => {
setCurrentStepIndex(prevIndex);
setIsTransitioning(false);
}, 300);
};
const handleOptionSelect = (option) => {
setAnswers(prev => ({ ...prev, [currentStep.id]: option.id }));
if (option.score) {
setScores(prev => ({ ...prev, [option.score.category]: option.score.value }));
}
handleNextStep();
};
useEffect(() => {
const style = document.createElement('style');
style.innerHTML = `
@keyframes ticker {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
.animate-ticker {
animation: ticker 25s linear infinite;
}
`;
document.head.appendChild(style);
return () => document.head.removeChild(style);
}, []);
const TopBar = () => (
{currentStepIndex > 0 && currentStep.type !== 'results' && currentStep.type !== 'loading' ? (
) :
}
impact admissions
{currentStep.type !== 'results' && currentStep.type !== 'loading' && (
)}
);
const QuestionScreen = () => (
{currentStepIndex === 0 && (
Тест из 7 вопросов • 2 минуты
Оцените шансы на поступление в ТОП-10 вузов по Стэнфордской методологии за 2 минуты
)}
{currentStepIndex !== 0 && (
{currentStep.title}
)}
{currentStep.options.map((option) => (
currentStepIndex === 0 ? (
handleOptionSelect(option)}
className="w-full flex flex-col rounded-[20px] border-[2.5px] border-blue-600 bg-blue-600 overflow-hidden transition-all duration-200 hover:shadow-lg active:scale-[0.98] text-left group p-0"
>
) : (
handleOptionSelect(option)}
className="w-full text-left p-4 rounded-2xl border-2 border-gray-100 bg-white hover:border-blue-500 hover:bg-blue-50 transition-all duration-200 shadow-sm hover:shadow-md flex items-center group active:scale-[0.98]"
> {option.emoji}
{option.text}
{option.subtext &&
{option.subtext}
}
)
))}
);
const AboutScreen = () => (
{currentStep.title} {currentStep.subtitle}
{/* Floating Tooltip Pointer */}
Более 16 000 000 $ сэкономлено на обучении, 92% учеников получили гранты, и 514 вузов по всему миру приняли наших студентов.
Продолжить
);
const MultiScreen = () => {
const [selected, setSelected] = useState(answers[currentStep.id] || []);
const toggleOpt = (id) => setSelected(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]);
const handleContinue = () => { setAnswers(prev => ({ ...prev, [currentStep.id]: selected })); handleNextStep(); };
return (
{currentStep.title} {currentStep.subtitle}
{currentStep.options.map((option) => {
const isSelected = selected.includes(option.id);
return (
toggleOpt(option.id)}
className={`w-full text-left p-4 rounded-2xl border-2 transition-all duration-200 flex items-center group active:scale-[0.98] ${isSelected ? 'border-blue-600 bg-blue-50 shadow-sm' : 'border-gray-100 bg-white hover:border-blue-300 hover:bg-slate-50'}`}
> {isSelected ? : }
{option.emoji}
{option.text}
)
})}
Продолжить {selected.length > 0 && }
);
};
const LoadingScreen = () => {
const [percent, setPercent] = useState(0);
const [phaseIndex, setPhaseIndex] = useState(0);
const [testIndex, setTestIndex] = useState(0);
useEffect(() => {
const intervalTime = currentStep.duration / 100;
const phaseTime = currentStep.duration / currentStep.phases.length;
const testTime = currentStep.duration / loadingTestimonials.length;
const pTimer = setInterval(() => setPercent(prev => { if (prev >= 100) { clearInterval(pTimer); return 100; } return prev + 1; }), intervalTime);
const phTimer = setInterval(() => setPhaseIndex(prev => Math.min(prev + 1, currentStep.phases.length - 1)), phaseTime);
const tTimer = setInterval(() => setTestIndex(prev => Math.min(prev + 1, loadingTestimonials.length - 1)), testTime);
const nextTimer = setTimeout(() => handleNextStep(), currentStep.duration + 300);
return () => { clearInterval(pTimer); clearInterval(phTimer); clearInterval(tTimer); clearTimeout(nextTimer); };
}, [currentStepIndex]);
return (
{percent}%
{currentStep.phases[phaseIndex]}
{loadingTestimonials[testIndex].stars}
"{loadingTestimonials[testIndex].text}"
{loadingTestimonials[testIndex].author}
);
};
const InsightScreen = () => {
return (
📊
В Топ-вузы поступают только 4-7% кандидатов. Но среди тех, кто использует стратегию "Impact Admissions", шансы получить заветный оффер (и стипендию!) вырастают до 38%.
Продолжить
);
};
const CompareScreen = () => {
const isParent = answers[1] === 'q1_2';
return (
Приемная комиссия ищет "Спайк" (уникальную изюминку), а не просто хороших учеников. Начните применять стратегию сегодня, и ваш профиль кардинально изменится:
{isParent ? 'Обычный ребенок' : 'Обычный отличник'} Фокус только на GPA и SAT Много рандомных кружков Стандартные эссе
{isParent ? 'impact-кандидат' : 'impact scholar'} Четкое позиционирование (Spike) Проекты с реальным impact Доказанная жажда знаний Продолжить
);
};
const CaptureScreen = () => (
Оценка завершена! Данные успешно проанализированы по 3 метрикам Стэнфорда.
Куда отправить финальный отчет? 🎓 Узнайте свои сильные стороны, слабые места и получите пошаговый план подготовки.
Ваши данные надежно защищены
);
const ResultsScreen = () => {
const { m, sec, urgent } = useCountdown(239); // 4 Minutes
const [booked, setBooked] = useState(false);
const [showModal, setShowModal] = useState(false);
const goalMapping = {
'q2_1': { text: 'Топ-10 США / Плющи', targetScore: 94 },
'q2_2': { text: 'Топ-50 США / UK', targetScore: 84 },
'q2_3': { text: 'Топ-100 мира / Европа', targetScore: 72 },
'q2_4': { text: 'выбранный престижный вуз', targetScore: 78 }
};
const userGoal = goalMapping[answers[2]] || goalMapping['q2_2'];
const gradeMapping = {
'gr_1': '8 класс или младше',
'gr_2': '9 - 10 класс',
'gr_3': '11 класс (Срочно)',
'gr_4': 'Студент / Перевод'
};
const userGrade = gradeMapping[answers['grade']] || 'Не указан';
// Advanced dynamic timeline based on grade input
const timelineMapping = {
'gr_1': 'Сейчас идеальное время, чтобы значительно улучшить профиль за 3+ года до подачи документов.',
'gr_2': 'Сейчас идеальное время, чтобы значительно улучшить профиль за 1-2 года до подачи документов.',
'gr_3': 'Нужно экстренно подготовиться к ранним дедлайнам (Ноябрь 2026 - Январь 2027).',
'gr_4': 'Время подготовиться к ближайшим дедлайнам (Весна 2027).'
};
const userTimeline = timelineMapping[answers['grade']] || 'Пора начинать подготовку.';
const fearsMapping = {
'f1': 'Высокая конкуренция',
'f2': 'Слабые проекты',
'f3': 'Поиск финансирования',
'f4': 'С чего начать',
'f5': 'Написание эссе'
};
const userFearsList = (answers['fears'] || []).map(f => fearsMapping[f]).filter(Boolean);
const userFears = userFearsList.length > 0 ? userFearsList.join(', ') : 'Не указано';
const calcScore = (val) => Math.max(35, val || 45);
const finalAcademic = calcScore(scores.academic);
const finalExtra = Math.round((calcScore(scores.extraDepth) + calcScore(scores.extraImpact)) / 2);
const finalVitality = calcScore(scores.vitality);
const initialScore = Math.round((finalAcademic + finalExtra + finalVitality) / 3);
const acBoost = Math.max(4, Math.floor((98 - finalAcademic) * 0.3));
const ecBoost = Math.max(10, Math.floor((98 - finalExtra) * 0.7));
const ivBoost = Math.max(8, Math.floor((98 - finalVitality) * 0.6));
const potentialScore = Math.min(99, Math.round(((finalAcademic + acBoost) + (finalExtra + ecBoost) + (finalVitality + ivBoost)) / 3));
const chanceMultiplier = initialScore >= 75 ? "в 2.5 раза" : initialScore >= 55 ? "в 4 раза" : "в 6 раз";
const firstName = formData.name ? formData.name.split(' ')[0] : 'Кандидат';
return (
{/* ── STICKY TOP BAR ── */}
{urgent && ● }
{urgent ? "Сгорает через" : "Ваш слот"}
{m}:{sec}
setShowModal(true)}
style={{ background: "#000", color: "white", border: "none", borderRadius: 10, padding: "10px 14px", fontSize: 11, fontWeight: 900, cursor: "pointer", letterSpacing: 0.3 }}
>
ПОЛУЧИТЬ ПЛАН
{/* ── HERO CARD ── */}
{/* subtle blue glow top-right */}
Оценка профиля
Привет, {firstName} 👋
{/* stat chips */}
Потенциал
{potentialScore}/100
Рост шансов
{chanceMultiplier}
{/* strategy banner with dynamic timeline */}
🚀 С правильной стратегией вы сможете поступить в {userGoal.text} . {userTimeline}
{/* ── PROFILE SUMMARY (WHITE) ── */}
Исходные данные ⏳ Текущий класс
{userGrade}
🎯 Главные барьеры
{userFears}
{/* ── METRICS (WHITE) ── */}
Где вы теряете баллы? 3 из 7 критериев · остальные заблокированы
{/* locked rows with gradient fade (No button, only lock icon) */}
{/* ── TIMELINE & CTA (BLACK) ── */}
Дорожная карта поступления
{/* Visual Roadmap */}
{/* Blurred items to create mystery/FOMO */}
{/* CTA Overlay block */}
Получить полный план
Узнайте свои красные флаги, список подходящих вузов и получите персональный Roadmap на бесплатной диагностике.
{/* countdown */}
{urgent ? "⚡ Слот почти сгорел!" : "Бесплатный слот сгорит через"}
{m}:{sec}
{/* CTA button (with crossed out price inside) */}
setShowModal(true)}
style={{ width: "100%", background: "#2563eb", color: "white", border: "none", borderRadius: 18, padding: "16px 20px", cursor: "pointer", position: "relative", overflow: "hidden", marginBottom: 8, boxShadow: "0 6px 24px rgba(37,99,235,0.35)", display: "flex", flexDirection: "column", alignItems: "center" }}
>
ПОЛУЧИТЬ ПЛАН $49 $0 Сегодня
и детальный анализ профиля
$49 $0 · сегодня бесплатно
{/* ── EXPERT BLOCK ── */}
Бесплатный разбор с экспертом impact admissions
Более 23,000 семей прошли консультацию и более 2,500 студентов успешно поступили за рубеж. На разборе мы сделаем полную диагностику профиля и отдадим вам ее бесплатно.
setShowModal(true)} style={{ width: "100%", background: "#f3f4f6", color: "#000", border: "1px solid #e5e7eb", borderRadius: 14, padding: "14px 20px", cursor: "pointer", fontSize: 14, fontWeight: 900, letterSpacing: 0.3 }}>
Записаться к эксперту →
{/* ── SOCIAL PROOF (WHITE) ── */}
{[...Array(5)].map((_,i) => )}
2,400+ поступивших студентов
{[
{ name: "Алина М.", school: "USC + $30K scholarship", flag: "🇺🇸" },
{ name: "Марк К.", school: "UCLA Early Decision", flag: "🎓" },
{ name: "Диана С.", school: "Northeastern Merit Aid", flag: "✅" },
].map(({ name, school, flag }) => (
))}
{/* ── TICKER ── */}
{/* ── MODAL (WHITE) ── */}
{showModal && (
{booked ? (
🎉
Вы записаны! Проверьте почту — мы пришлём детали в течение 2 часов.
{ setShowModal(false); setBooked(false); }} style={{ marginTop: 24, background: "#000", color: "white", border: "none", borderRadius: 14, padding: "14px 32px", fontWeight: 900, cursor: "pointer", fontSize: 15 }}>Готово
) : (
<>
setShowModal(false)} style={{ float: "right", background: "none", border: "none", color: "#9ca3af", fontSize: 22, cursor: "pointer" }}>✕ Запишитесь на разбор Эксперт изучит ваш профиль и даст конкретный план действий.
{[["Ваше имя", "Имя Фамилия", "text"], ["Email", "you@email.com", "email"]].map(([label, ph, type]) => (
{label}
))}
setBooked(true)} style={{ width: "100%", background: "#2563eb", color: "white", border: "none", borderRadius: 14, padding: "16px", fontSize: 15, fontWeight: 900, cursor: "pointer", marginTop: 8, boxShadow: "0 4px 16px rgba(37,99,235,0.3)" }}>
Забронировать бесплатно →