// Setup Wizard - пошаговая настройка после создания подписки 'use client'; import { useState, useEffect } from 'react'; import { X, ChevronLeft, Laptop, Smartphone, Check, Copy, QrCode } from 'lucide-react'; interface SetupWizardProps { isOpen: boolean; onClose: () => void; subscriptionUrl: string; username: string; planType: 'trial' | 'basic' | 'extended' | 'premium'; expiryDate?: string; } type Step = 'device' | 'app-check' | 'location' | 'final'; type DeviceType = 'desktop' | 'mobile' | null; type MobileOS = 'android' | 'ios' | null; export default function SetupWizard({ isOpen, onClose, subscriptionUrl, username, planType, expiryDate }: SetupWizardProps) { const [step, setStep] = useState('device'); const [deviceType, setDeviceType] = useState(null); const [mobileOS, setMobileOS] = useState(null); const [hasApp, setHasApp] = useState(null); const [selectedLocations, setSelectedLocations] = useState([]); const [copied, setCopied] = useState(false); const [showQR, setShowQR] = useState(false); const [qrDataUrl, setQrDataUrl] = useState(''); // Генерация QR кода при открытии финального шага useEffect(() => { if (step === 'final' && subscriptionUrl && !qrDataUrl) { import('qrcode').then((QRCode) => { QRCode.toDataURL(subscriptionUrl, { width: 300, margin: 2, color: { dark: '#000000', light: '#FFFFFF', }, errorCorrectionLevel: 'H', }) .then((dataUrl) => { setQrDataUrl(dataUrl); }) .catch((err) => { console.error('Failed to generate QR code:', err); }); }); } }, [step, subscriptionUrl, qrDataUrl]); // Локации для выбора (для тарифа "Расширенный") const locations = [ { id: 'nl', name: '🇳🇱 Нидерланды', ping: '15ms' }, { id: 'de', name: '🇩🇪 Германия', ping: '20ms' }, { id: 'us', name: '🇺🇸 США', ping: '120ms' }, { id: 'sg', name: '🇸🇬 Сингапур', ping: '180ms' }, { id: 'jp', name: '🇯🇵 Япония', ping: '160ms' }, { id: 'uk', name: '🇬🇧 Великобритания', ping: '35ms' }, ]; const needsLocationSelection = planType === 'extended'; const maxLocations = planType === 'extended' ? 3 : 1; const handleCopy = async () => { await navigator.clipboard.writeText(subscriptionUrl); setCopied(true); setTimeout(() => setCopied(false), 2000); }; const handleDeviceSelect = (type: DeviceType) => { setDeviceType(type); if (type === 'desktop') { setStep('app-check'); } else { setStep('app-check'); } }; const handleAppCheck = (installed: boolean) => { setHasApp(installed); if (needsLocationSelection) { setStep('location'); } else { setStep('final'); } }; const handleLocationToggle = (locationId: string) => { if (selectedLocations.includes(locationId)) { setSelectedLocations(selectedLocations.filter(id => id !== locationId)); } else if (selectedLocations.length < maxLocations) { setSelectedLocations([...selectedLocations, locationId]); } }; const canProceedFromLocation = selectedLocations.length === maxLocations; const getProgressSteps = () => { const steps = ['device', 'app-check']; if (needsLocationSelection) steps.push('location'); steps.push('final'); return steps; }; const currentStepIndex = getProgressSteps().indexOf(step); const totalSteps = getProgressSteps().length; if (!isOpen) return null; return (
{/* Header */}

{step === 'device' && '🎉 Подписка создана!'} {step === 'app-check' && deviceType === 'desktop' && '💻 Настройка'} {step === 'app-check' && deviceType === 'mobile' && '📱 Настройка'} {step === 'location' && '🌍 Выбор локаций'} {step === 'final' && '✨ Всё готово!'}

{/* Progress bar */}
{Array.from({ length: totalSteps }).map((_, i) => (
))}
{/* Content */}
{/* Step 1: Device Selection */} {step === 'device' && (

{expiryDate ? `Действует до ${expiryDate}` : 'Осталось 2 шага до подключения'}

Какое у вас устройство?

)} {/* Step 2: App Check */} {step === 'app-check' && deviceType === 'desktop' && (

У вас установлен Umbrix?

{hasApp === false && (

Скачайте Umbrix:

)}
)} {step === 'app-check' && deviceType === 'mobile' && (

Какая у вас система?

{mobileOS && (

У вас уже установлено приложение?

{hasApp === false && (

Рекомендуем:

{mobileOS === 'android' ? (
• V2RayNG
• Hiddify
• v2rayTun
) : (
• Shadowrocket (AppStore)
• Hiddify (AppStore)
)}
)}
)}
)} {/* Step 3: Location Selection (только для extended тарифа) */} {step === 'location' && (

Выберите {maxLocations} локации

Выбрано: {selectedLocations.length} из {maxLocations}

{locations.map((location) => { const isSelected = selectedLocations.includes(location.id); const canSelect = selectedLocations.length < maxLocations; return ( ); })}
)} {/* Step 4: Final - Show Link/QR */} {step === 'final' && (
🎉

{deviceType === 'desktop' ? 'Скопируйте ссылку и вставьте в Umbrix' : 'Отсканируйте QR код или скопируйте ссылку'}

{deviceType === 'mobile' && ( )} {showQR && qrDataUrl && (
QR код подписки
{subscriptionUrl}
)}
)}
); }