diff --git a/components/QRCodeModal.tsx b/components/QRCodeModal.tsx new file mode 100644 index 0000000..559b0f1 --- /dev/null +++ b/components/QRCodeModal.tsx @@ -0,0 +1,167 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import { X, Download, Share2, Copy, Check } from 'lucide-react'; + +interface QRCodeModalProps { + isOpen: boolean; + onClose: () => void; + url: string; + title?: string; +} + +export default function QRCodeModal({ + isOpen, + onClose, + url, + title = 'QR Код подписки', +}: QRCodeModalProps) { + const [copied, setCopied] = useState(false); + const [qrDataUrl, setQrDataUrl] = useState(''); + + useEffect(() => { + if (isOpen && url) { + // Generate QR code using qrcode library + import('qrcode').then((QRCode) => { + QRCode.toDataURL(url, { + 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); + }); + }); + } + }, [isOpen, url]); + + if (!isOpen) return null; + + const downloadQR = () => { + const a = document.createElement('a'); + a.href = qrDataUrl; + a.download = 'vpn-subscription-qr.png'; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + }; + + const shareQR = async () => { + if (!navigator.share) { + // Fallback: copy URL to clipboard + await copyUrl(); + return; + } + + try { + // Convert data URL to blob + const response = await fetch(qrDataUrl); + const blob = await response.blob(); + const file = new File([blob], 'vpn-qr-code.png', { type: 'image/png' }); + + await navigator.share({ + title: 'VPN Подписка', + text: 'QR код для подключения к VPN', + files: [file], + }); + } catch (err) { + console.error('Failed to share QR code:', err); + // Fallback to copying URL + await copyUrl(); + } + }; + + const copyUrl = async () => { + try { + await navigator.clipboard.writeText(url); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch (err) { + console.error('Failed to copy URL:', err); + } + }; + + return ( +
+
e.stopPropagation()} + > + {/* Header */} +
+

{title}

+ +
+ + {/* QR Code */} +
+ {qrDataUrl ? ( + QR Code + ) : ( +
+
+
+ )} +
+ + {/* Info text */} +

+ Отсканируйте QR код в приложении Umbrix для автоматического подключения +

+ + {/* Actions */} +
+ + +
+ + {/* Copy URL button */} + +
+
+ ); +} diff --git a/components/ReferralModal.tsx b/components/ReferralModal.tsx new file mode 100644 index 0000000..8f9ce6b --- /dev/null +++ b/components/ReferralModal.tsx @@ -0,0 +1,134 @@ +'use client'; + +import { X, Copy, Share2, Gift, Users, Award } from 'lucide-react'; + +interface ReferralModalProps { + isOpen: boolean; + onClose: () => void; + referralUrl: string; + onShare: () => void; + onCopy: () => void; +} + +export default function ReferralModal({ + isOpen, + onClose, + referralUrl, + onShare, + onCopy +}: ReferralModalProps) { + if (!isOpen) return null; + + return ( +
+ {/* Backdrop */} +
+ + {/* Modal */} +
e.stopPropagation()} + > + {/* Header */} +
+

+ + Пригласи друга +

+ +
+ + {/* Content */} +
+ {/* Условия программы */} +
+
+
+ +
+

Ты получишь:

+
    +
  • + + +7 дней бесплатно за каждого друга +
  • +
  • + + 10% скидка на продление при оплате +
  • +
  • + + За 5 друзей → 1 месяц в подарок +
  • +
+
+
+
+ +
+
+ +
+

Твой друг получит:

+
    +
  • + + 7 дней бесплатного триала +
  • +
  • + + -10% скидка на первую покупку +
  • +
+
+
+
+
+ + {/* Реферальная ссылка */} +
+ +
+ + {referralUrl} + +
+
+ + {/* Action buttons */} +
+ + + +
+ + {/* Info */} +
+ Бонусы начисляются после активации подписки приглашенным другом +
+
+
+
+ ); +}