e.stopPropagation()}
diff --git a/src/components/TopUpModal.tsx b/src/components/TopUpModal.tsx
index 8618c65..ffe11a6 100644
--- a/src/components/TopUpModal.tsx
+++ b/src/components/TopUpModal.tsx
@@ -37,6 +37,36 @@ const CloseIcon = () => (
)
+const WalletIcon = () => (
+
+)
+
+const StarIcon = () => (
+
+)
+
+const CardIcon = () => (
+
+)
+
+const CryptoIcon = () => (
+
+)
+
+const SparklesIcon = () => (
+
+)
+
interface TopUpModalProps {
method: PaymentMethod
onClose: () => void
@@ -56,6 +86,14 @@ function useIsMobile() {
return isMobile
}
+// Get method icon based on method type
+const getMethodIcon = (methodId: string) => {
+ const id = methodId.toLowerCase()
+ if (id.includes('stars')) return
+ if (id.includes('crypto') || id.includes('ton') || id.includes('usdt')) return
+ return
+}
+
export default function TopUpModal({ method, onClose, initialAmountRubles }: TopUpModalProps) {
const { t } = useTranslation()
const { formatAmount, currencySymbol, convertAmount, convertToRub, targetCurrency } = useCurrency()
@@ -79,6 +117,7 @@ export default function TopUpModal({ method, onClose, initialAmountRubles }: Top
method.options && method.options.length > 0 ? method.options[0].id : null
)
const popupRef = useRef
(null)
+ const [isInputFocused, setIsInputFocused] = useState(false)
const handleClose = useCallback(() => {
onClose()
@@ -107,7 +146,7 @@ export default function TopUpModal({ method, onClose, initialAmountRubles }: Top
}
}, [webApp, handleClose])
- // Scroll lock - simple version without position:fixed
+ // Scroll lock
useEffect(() => {
const scrollY = window.scrollY
const preventScroll = (e: TouchEvent) => {
@@ -194,7 +233,6 @@ export default function TopUpModal({ method, onClose, initialAmountRubles }: Top
}
const amountKopeks = Math.round(amountRubles * 100)
- // IMPORTANT: Pre-open window on PC to avoid popup blockers
if (!isTelegramMiniApp) {
try { popupRef.current = window.open('', '_blank') } catch { popupRef.current = null }
}
@@ -217,104 +255,88 @@ export default function TopUpModal({ method, onClose, initialAmountRubles }: Top
return () => clearTimeout(timer)
}, [isMobileScreen])
- // Mobile bottom sheet
- const MobileModal = () => (
- <>
-
- e.stopPropagation()}
- >
- {/* Handle */}
-
- {/* Header */}
-
- {methodName}
-
-
- {/* Content */}
-
- {renderContent()}
-
-
- >
- )
-
- // Desktop centered modal
- const DesktopModal = () => (
-
-
e.stopPropagation()}
- >
- {/* Header */}
-
- {methodName}
-
-
- {/* Content */}
-
- {renderContent()}
-
-
-
- )
+ // Calculate display amount for preview
+ const displayAmount = amount && parseFloat(amount) > 0 ? parseFloat(amount) : 0
const renderContent = () => (
- <>
- {/* Payment options */}
+
+ {/* Header icon and method */}
+
+
+
+ {getMethodIcon(method.id)}
+
+
+
+
{methodName}
+
+ {formatAmount(minRubles, 0)} – {formatAmount(maxRubles, 0)} {currencySymbol}
+
+
+
+
+ {/* Payment options (if any) */}
{hasOptions && method.options && (
-
- {method.options.map((opt) => (
-
- ))}
+
+
+
+ {method.options.map((opt) => (
+
+ ))}
+
)}
- {/* Amount input */}
-
-
setAmount(e.target.value)}
- onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); handleSubmit() } }}
- placeholder={`${formatAmount(minRubles, 0)} – ${formatAmount(maxRubles, 0)}`}
- className="w-full h-12 px-4 pr-12 text-lg font-semibold bg-dark-800 border border-dark-700 rounded-xl text-dark-100 placeholder:text-dark-500 focus:outline-none focus:border-accent-500 transition-colors"
- style={{ fontSize: '18px' }}
- autoComplete="off"
- />
-
- {currencySymbol}
-
+ {/* Amount input - modern design */}
+
+
+
+ setAmount(e.target.value)}
+ onFocus={() => setIsInputFocused(true)}
+ onBlur={() => setIsInputFocused(false)}
+ onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); handleSubmit() } }}
+ placeholder="0"
+ className="w-full h-16 px-5 pr-16 text-2xl font-bold bg-transparent text-dark-100 placeholder:text-dark-600 focus:outline-none"
+ style={{ fontSize: '24px' }}
+ autoComplete="off"
+ />
+
+ {currencySymbol}
+
+
- {/* Quick amounts */}
+ {/* Quick amount buttons */}
{quickAmounts.length > 0 && (
{quickAmounts.map((a) => {
@@ -325,10 +347,10 @@ export default function TopUpModal({ method, onClose, initialAmountRubles }: Top
key={a}
type="button"
onClick={() => { setAmount(val); inputRef.current?.blur() }}
- className={`flex-1 py-2.5 rounded-xl text-sm font-semibold transition-all ${
+ className={`flex-1 py-3 rounded-xl text-sm font-bold transition-all duration-200 ${
isSelected
- ? 'bg-accent-500/15 text-accent-400 ring-1 ring-accent-500/30'
- : 'bg-dark-800 text-dark-300 hover:bg-dark-700'
+ ? 'bg-accent-500/20 text-accent-400 ring-1 ring-accent-500/40'
+ : 'bg-dark-800/50 text-dark-400 hover:bg-dark-800 hover:text-dark-300 border border-dark-700/30'
}`}
>
{formatAmount(a, 0)}
@@ -338,32 +360,129 @@ export default function TopUpModal({ method, onClose, initialAmountRubles }: Top
)}
- {/* Error */}
+ {/* Error message */}
{error && (
-
{error}
+
)}
- {/* Submit */}
+ {/* Submit button */}
+
+ )
+
+ // Mobile bottom sheet
+ const MobileModal = () => (
+ <>
+ {/* Backdrop */}
+
+ {/* Bottom sheet */}
+
e.stopPropagation()}
+ >
+ {/* Handle bar */}
+
+
+ {/* Header */}
+
+
+
+ {t('balance.topUp')}
+
+
+
+
+ {/* Divider */}
+
+
+ {/* Content */}
+
+ {renderContent()}
+
+
>
)
+ // Desktop centered modal
+ const DesktopModal = () => (
+
+
e.stopPropagation()}
+ >
+ {/* Header */}
+
+
+
+
+
+
{t('balance.topUp')}
+
+
+
+
+ {/* Content */}
+
+ {renderContent()}
+
+
+
+ )
+
const content = isMobileScreen ?
:
if (typeof document !== 'undefined') {