import React, { useState, useEffect } from 'react';
import { Sparkles, Calculator, Briefcase, ChefHat, ArrowRight, CheckCircle2, Copy, GraduationCap, Loader2 } from 'lucide-react';
const App = () => {
const [step, setStep] = useState('intro'); // intro, loading, calculator, result
// State for calculator inputs
const [cityTier, setCityTier] = useState('medium');
const [experience, setExperience] = useState('family');
const [currentSalary, setCurrentSalary] = useState(45000);
const [workHours, setWorkHours] = useState(40);
const [bakingHours, setBakingHours] = useState(5);
const [targetGoal, setTargetGoal] = useState('phone');
// Logo error state
const [logoError, setLogoError] = useState(false);
// Loading state
const [loadingText, setLoadingText] = useState('');
// Constants
const cityMultipliers = {
small: { check: 1200, label: 'Небольшой' },
medium: { check: 1800, label: 'Средний' },
large: { check: 2500, label: 'Мегаполис' },
};
const goals = {
phone: { name: 'Новый iPhone', cost: 120000, emoji: '????' },
travel: { name: 'Отпуск на море', cost: 150000, emoji: '????️' },
debt: { name: 'Закрыть кредитку', cost: 50000, emoji: '????' },
repair: { name: 'Ремонт', cost: 80000, emoji: '????️' },
};
const experienceLevels = [
{ id: 'beginner', label: 'Только учусь' },
{ id: 'family', label: 'Готовлю для семьи и друзей' },
{ id: 'sales', label: 'Есть опыт продаж' },
];
// Calculations
const [results, setResults] = useState(null);
const startCalculation = () => {
setStep('loading');
const messages = [
"Анализируем спрос в твоем городе...",
"Считаем себестоимость продуктов...",
"Подбираем идеальное меню...",
"Формируем стратегию продаж..."
];
let i = 0;
setLoadingText(messages[0]);
const interval = setInterval(() => {
i++;
if (i < messages.length) {
setLoadingText(messages[i]);
} else {
clearInterval(interval);
performCalculation();
}
}, 600); // 600ms per message
};
const performCalculation = () => {
const avgCheck = cityMultipliers[cityTier].check;
const profitPerOrder = avgCheck * 0.5;
const ordersPerWeekPossible = Math.floor(bakingHours / 1.5);
const weeklyProfit = ordersPerWeekPossible * profitPerOrder;
const monthlyProfit = weeklyProfit * 4;
const mainJobHourly = currentSalary / (workHours * 4);
const sweetHourly = bakingHours > 0 ? weeklyProfit / bakingHours : 0;
const selectedGoal = goals[targetGoal];
const monthsToGoal = monthlyProfit > 0 ? (selectedGoal.cost / monthlyProfit).toFixed(1) : '∞';
const boxCount = Math.ceil(ordersPerWeekPossible * 0.6);
const cakeCount = Math.floor(ordersPerWeekPossible * 0.4);
setResults({
monthlyProfit,
ordersPerWeek: ordersPerWeekPossible,
mainJobHourly: Math.round(mainJobHourly),
sweetHourly: Math.round(sweetHourly),
monthsToGoal,
goalName: selectedGoal.name,
goalEmoji: selectedGoal.emoji,
avgCheck,
productMix: {
boxes: boxCount,
cakes: cakeCount
}
});
setStep('result');
};
// Action script generator
const [showScript, setShowScript] = useState(false);
const [copied, setCopied] = useState(false);
const copyScript = () => {
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
return (
{/* Background */}
{/* Header */}
Сладкий Бизнес
Калькулятор твоей свободы
{/* Content Body */}
{step === 'intro' && (
{/* Logo with Fallback */}
{!logoError ? (
setLogoError(true)}
className="max-h-full max-w-full object-contain drop-shadow-md hover:scale-105 transition-transform"
/>
) : (
????
)}
Преврати десерты в деньги
Узнай, сколько наборов конфет нужно продать, чтобы уволиться с нелюбимой работы или закрыть кредит.
setStep('calculator')}
className="w-full py-4 bg-gray-900 text-white rounded-xl font-bold text-lg hover:bg-gray-800 transition-all transform hover:scale-[1.02] shadow-lg flex items-center justify-center gap-2"
>
Начать расчет
)}
{step === 'calculator' && (
{/* Question 1: City */}
Твой город
{[
{ id: 'small', label: 'Малый' },
{ id: 'medium', label: 'Средний' },
{ id: 'large', label: 'Крупный' },
].map((city) => (
setCityTier(city.id)}
className={`p-2 rounded-xl text-xs sm:text-sm border-2 transition-all ${
cityTier === city.id
? 'border-pink-500 bg-pink-50 text-pink-700 font-bold'
: 'border-gray-200 text-gray-500 hover:border-pink-200'
}`}
> {city.label}
))}
{/* Question 1.5: Experience */}
Опыт в десертах setExperience(e.target.value)}
className="w-full p-3 pl-10 border border-gray-300 rounded-xl bg-white focus:ring-2 focus:ring-pink-300 outline-none appearance-none"
>
{experienceLevels.map((level) => (
{level.label}
))}
{/* Question 2: Job */}
{/* Question 3: Baking Time */}
{/* Question 4: Goal */}
На что копим? setTargetGoal(e.target.value)}
className="w-full p-3 border border-gray-300 rounded-xl bg-white focus:ring-2 focus:ring-pink-300 outline-none"
>
{Object.entries(goals).map(([key, val]) => (
{val.emoji} {val.name}
))}
Рассчитать стратегию
)}
{step === 'loading' && (
)}
{step === 'result' && results && (
{/* Header Result */}
Твой потенциал за {bakingHours} часов в неделю:
{results.monthlyProfit.toLocaleString('ru-RU')} ₽
{/* Plan Card */}
ТВОЙ ПЛАН ПРОДАЖ
Чтобы заработать эти деньги, тебе нужно продавать в неделю:
???? Наборы конфет
~{results.avgCheck}₽ / шт
x{results.productMix.boxes}
{results.productMix.cakes > 0 && (
???? Бенто-торты
~{(results.avgCheck * 1.2).toFixed(0)}₽ / шт
x{results.productMix.cakes}
)}
{/* Action Script */}
setShowScript(!showScript)}>
Найти клиента прямо сейчас?
Текст для первой продажи
{showScript && (
"Друзья! ????♀️ Я сейчас учусь делать самые полезные конфеты в мире. Ищу 3 человек, кто хочет попробовать мои новые трюфели без сахара по себестоимости! ???? Всего {results.avgCheck * 0.7}₽ за коробочку. Пишите в личку, забронирую!"
{ e.stopPropagation(); copyScript(); }}
className="absolute bottom-2 right-2 p-1.5 bg-white text-indigo-900 rounded hover:bg-indigo-50 transition-colors"
>
{copied ? : }
)}
{/* Final Upsell */}
)}
);
};
export default App;