/* eslint-disable react/display-name */ import { Image, Pressable, Text, View, StyleSheet } from 'react-native' import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view' import { SafeAreaView } from 'react-native-safe-area-context' import React from 'reactn' import { responsiveHeight } from '../actions/responsiveSizes.js' import { subBadges } from '../assets' import BaseHeader from '../components/BaseHeader' import CreditAmount from '../components/CreditAmount' import ConnectBtn from '../components/ConnectBtn.js' import GradientButton from '../components/GradientButton' import CoinPackModal from '../components/modal/CoinPackModal' import NavigateHeader from '../components/NavigateHeader' import ShareBtn from '../components/ShareBtn/ShareBtn' import { isWeb } from '../hooks/useLayoutType.js' import { useUserData } from '../providers/UserDataProvider' import { Routes } from '../navigation' import { navigate } from '../navigation/NavigationService' import { gutters, Palette } from '../styles' import { FONT_FAMILY } from '../styles/Fonts' import { subscribeCoinPackModal } from '../utils/coinPackModal' import { BlurView } from 'expo-blur' export default ({ children, topStickyContent = null, bottomStickyContent = null, title = '', rightComponent = null, containerType = 'SAFE_AREA_VIEW', headerType = 'BASE', containerStyle = {}, headerStyle = {}, contentContainerStyle = {}, scrollEnabled = false, onBackPressed = null, backgroundImg = null, headerTitleStyle = {}, hideBackButton = false, width = undefined, maxWidth = 1200, shareBtn = false, connect = false, blurIntensity = 0, backgroundColor = '#000', backgroundContent = null, coinBadgeContainerStyle = null, showCoin = true, showReturnHome = false, onReturnHome = null, }) => { const { currentUID = null, currentUserData = null } = useUserData?.() || {} const coinBalance = React.useMemo(() => { const value = currentUserData?.coins if (typeof value === 'number' && Number.isFinite(value)) { return value } if (typeof value === 'string') { const parsed = Number(value) if (Number.isFinite(parsed)) { return parsed } } return 0 }, [currentUserData?.coins]) const showCoinBadge = isWeb && !!currentUID && showCoin const showReturnHomeButton = isWeb && showReturnHome const coinBadgeContainerVisible = showCoinBadge || showReturnHomeButton const [isCoinModalVisible, setCoinModalVisible] = React.useState(false) const subscriptionBadgeSource = React.useMemo(() => { const allowedLevels = new Set(['starter', 'pro', 'premium']) const pickLevel = (value) => { if (typeof value !== 'string') { return null } const normalized = value.trim().toLowerCase() return normalized && allowedLevels.has(normalized) ? normalized : null } const nestedSubscription = currentUserData?.subscription && typeof currentUserData.subscription === 'object' ? currentUserData.subscription : null const stripeMetadata = currentUserData?.stripeSubscription && typeof currentUserData.stripeSubscription === 'object' && typeof currentUserData.stripeSubscription.metadata === 'object' ? currentUserData.stripeSubscription.metadata : null const directCandidates = [ pickLevel(currentUserData?.premiumLevel), pickLevel(currentUserData?.subscriptionLevel), pickLevel(currentUserData?.subscriptionPlan), pickLevel(currentUserData?.subscriptionPack), ] const nestedCandidates = nestedSubscription ? ['level', 'plan', 'pack', 'type'].map((key) => pickLevel(nestedSubscription?.[key])) : [] const metadataCandidates = stripeMetadata ? ['level', 'subscriptionLevel', 'subscription_level', 'pack', 'Pack'].map((key) => pickLevel(stripeMetadata?.[key]) ) : [] const resolvedLevel = [...directCandidates, ...nestedCandidates, ...metadataCandidates].find( Boolean ) return resolvedLevel ? subBadges[resolvedLevel] || null : null }, [currentUserData]) const handleCoinPress = React.useCallback(() => { if (!showCoinBadge) return navigate(Routes.Payments, { pack: 'packs' }) }, [showCoinBadge]) const handleCloseCoinModal = React.useCallback(() => { setCoinModalVisible(false) }, []) const handleReturnHomePress = React.useCallback(() => { if (typeof onReturnHome === 'function') { onReturnHome() return } navigate(Routes.LandingPage) }, [onReturnHome]) React.useEffect(() => { if (!showCoinBadge && isCoinModalVisible) { setCoinModalVisible(false) } }, [showCoinBadge, isCoinModalVisible]) React.useEffect(() => { if (!showCoinBadge) { return undefined } const unsubscribe = subscribeCoinPackModal(() => { setCoinModalVisible(true) }) return unsubscribe }, [showCoinBadge]) const PageContainer = containerType === 'SAFE_AREA_VIEW' ? SafeAreaView : View const ContentContainer = scrollEnabled ? KeyboardAwareScrollView : View const computedWidth = width ?? (isWeb ? '60%' : '100%') const shareButtonElement = (() => { if (!shareBtn) return null if (typeof React?.isValidElement === 'function') { if (React.isValidElement(shareBtn)) { return shareBtn } } if (typeof shareBtn === 'object' && !Array.isArray(shareBtn)) { return } return })() const resolvedContainerStyle = React.useMemo( () => StyleSheet.flatten(containerStyle) || {}, [containerStyle] ) const resolvedHeaderStyle = React.useMemo( () => StyleSheet.flatten(headerStyle) || {}, [headerStyle] ) const resolvedContentContainerStyle = React.useMemo( () => StyleSheet.flatten(contentContainerStyle) || {}, [contentContainerStyle] ) return ( {backgroundImg ? ( ) : null} {backgroundContent} {coinBadgeContainerVisible ? ( {showCoinBadge ? ( {subscriptionBadgeSource ? ( navigate(Routes.ManageSubscription)} accessibilityRole="button" style={styles.subscriptionBadge} > ) : null} ) : null} {showReturnHomeButton ? ( // {"Retour à l'accueil"} ) : null} ) : null} {headerType !== 'NONE' ? ( headerType === 'BASE' ? ( ) : ( ) ) : null} {topStickyContent?.()} {children} {bottomStickyContent?.()} {(shareButtonElement || connect) && isWeb && ( {shareButtonElement} {connect && } )} ) } const styles = StyleSheet.create({ coinBadgeContainer: { position: 'absolute', top: gutters, left: gutters, alignItems: 'flex-start', gap: 10, zIndex: 20, }, coinRow: { flexDirection: 'row', alignItems: 'center', gap: 6, }, coinButton: { paddingHorizontal: 14, paddingVertical: 8, borderRadius: 20, backgroundColor: 'rgba(12, 14, 18, 0.72)', borderWidth: 1, borderColor: 'rgba(255, 255, 255, 0.1)', flexDirection: 'row', alignItems: 'center', gap: 8, }, subscriptionBadge: { paddingVertical: 4, }, returnHomeButton: { width: 220, alignSelf: 'flex-start', }, })