mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +00:00
@@ -1,4 +1,5 @@
|
|||||||
import { useState, useMemo, useEffect } from 'react'
|
import { useState, useMemo, useEffect } from 'react'
|
||||||
|
import { createPortal } from 'react-dom'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useQuery } from '@tanstack/react-query'
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import { subscriptionApi } from '../api/subscription'
|
import { subscriptionApi } from '../api/subscription'
|
||||||
@@ -133,7 +134,6 @@ export default function ConnectionModal({ onClose }: ConnectionModalProps) {
|
|||||||
const isMobileScreen = useIsMobile()
|
const isMobileScreen = useIsMobile()
|
||||||
const isMobile = isMobileScreen || isTelegramWebApp
|
const isMobile = isMobileScreen || isTelegramWebApp
|
||||||
|
|
||||||
const safeTop = isTelegramWebApp ? Math.max(safeAreaInset.top, contentSafeAreaInset.top) : 0
|
|
||||||
const safeBottom = isTelegramWebApp ? Math.max(safeAreaInset.bottom, contentSafeAreaInset.bottom) : 0
|
const safeBottom = isTelegramWebApp ? Math.max(safeAreaInset.bottom, contentSafeAreaInset.bottom) : 0
|
||||||
|
|
||||||
const { data: appConfig, isLoading, error } = useQuery<AppConfig>({
|
const { data: appConfig, isLoading, error } = useQuery<AppConfig>({
|
||||||
@@ -216,30 +216,36 @@ export default function ConnectionModal({ onClose }: ConnectionModalProps) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Mobile fullscreen wrapper - like React Native Modal with animationType="slide"
|
// Mobile fullscreen wrapper - like React Native Modal with animationType="slide"
|
||||||
const MobileWrapper = ({ children }: { children: React.ReactNode }) => (
|
// Use portal to render directly in body, avoiding transform/filter issues with fixed positioning
|
||||||
<>
|
const MobileWrapper = ({ children }: { children: React.ReactNode }) => {
|
||||||
{/* Backdrop */}
|
const content = (
|
||||||
<div className="fixed inset-0 z-[9998] bg-black/50 animate-fade-in" onClick={onClose} />
|
<>
|
||||||
{/* Modal - slides from bottom */}
|
{/* Backdrop */}
|
||||||
<div
|
<div className="fixed inset-0 z-[9998] bg-black/50 animate-fade-in" onClick={onClose} />
|
||||||
className="fixed inset-0 z-[9999] bg-dark-900 flex flex-col animate-slide-up"
|
{/* Modal - fullscreen overlay */}
|
||||||
style={{
|
<div
|
||||||
paddingTop: safeTop ? `${safeTop}px` : 'env(safe-area-inset-top, 0px)',
|
className="fixed inset-0 z-[9999] bg-dark-900 flex flex-col animate-slide-up"
|
||||||
paddingBottom: safeBottom ? `${safeBottom}px` : 'env(safe-area-inset-bottom, 0px)'
|
style={{
|
||||||
}}
|
paddingBottom: safeBottom ? `${safeBottom}px` : 'env(safe-area-inset-bottom, 0px)'
|
||||||
>
|
}}
|
||||||
{/* Close button */}
|
|
||||||
<button
|
|
||||||
onClick={onClose}
|
|
||||||
className="absolute top-4 right-4 z-10 p-2.5 rounded-full bg-dark-800/80 text-dark-200 active:bg-dark-700"
|
|
||||||
style={{ marginTop: safeTop ? `${safeTop}px` : 'env(safe-area-inset-top, 0px)' }}
|
|
||||||
>
|
>
|
||||||
<CloseIcon />
|
{/* Close button */}
|
||||||
</button>
|
<button
|
||||||
{children}
|
onClick={onClose}
|
||||||
</div>
|
className="absolute top-4 right-4 z-10 p-2.5 rounded-full bg-dark-800/80 text-dark-200 active:bg-dark-700"
|
||||||
</>
|
>
|
||||||
)
|
<CloseIcon />
|
||||||
|
</button>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
if (typeof document !== 'undefined') {
|
||||||
|
return createPortal(content, document.body)
|
||||||
|
}
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
const Wrapper = isMobile ? MobileWrapper : DesktopWrapper
|
const Wrapper = isMobile ? MobileWrapper : DesktopWrapper
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useState, useRef, useEffect } from 'react'
|
import { useState, useRef, useEffect } from 'react'
|
||||||
|
import { createPortal } from 'react-dom'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useMutation } from '@tanstack/react-query'
|
import { useMutation } from '@tanstack/react-query'
|
||||||
import { balanceApi } from '../api/balance'
|
import { balanceApi } from '../api/balance'
|
||||||
@@ -169,11 +170,10 @@ export default function TopUpModal({ method, onClose, initialAmountRubles }: Top
|
|||||||
return () => clearTimeout(timer)
|
return () => clearTimeout(timer)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
const modalContent = (
|
||||||
<div
|
<div
|
||||||
className="fixed inset-0 bg-black/70 z-[60] flex items-start justify-center p-4 pt-8 overflow-hidden"
|
className="fixed inset-0 bg-black/70 z-[60] flex items-start justify-center p-4 pt-4 overflow-hidden"
|
||||||
style={{
|
style={{
|
||||||
paddingTop: `max(2rem, calc(1rem + env(safe-area-inset-top, 0px)))`,
|
|
||||||
paddingBottom: `max(1rem, env(safe-area-inset-bottom, 0px))`,
|
paddingBottom: `max(1rem, env(safe-area-inset-bottom, 0px))`,
|
||||||
}}
|
}}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
@@ -279,4 +279,9 @@ export default function TopUpModal({ method, onClose, initialAmountRubles }: Top
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (typeof document !== 'undefined') {
|
||||||
|
return createPortal(modalContent, document.body)
|
||||||
|
}
|
||||||
|
return modalContent
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user