import React, { useState } from 'react'; import { View, Text, StyleSheet, ScrollView, useWindowDimensions, Platform, Alert, TouchableOpacity } from 'react-native'; import { BlurView } from 'expo-blur'; import { useRouter } from 'expo-router'; import { Ionicons } from '@expo/vector-icons'; import Constants from 'expo-constants'; import Animated, { FadeInDown } from 'react-native-reanimated'; import { LinearGradient } from 'expo-linear-gradient'; import { GradientBackground } from '../../components/ui'; import { Paywall } from '../../components/paywall'; import { CompactHeader } from '../../components/discovery'; import { MediaImage } from '../../components/MediaImage'; import { colors, featureColors, spacing, typography, radius } from '../../theme'; import { useAuthStore, useSubscriptionStore } from '../../store'; import { resetMatchesTutorial } from '../../lib/matchesTutorialSeen'; import { profileSettingsApi } from '../../lib/profileSettingsApi'; // Components import { SettingsSection, MenuItem, SubscriptionCard } from './components'; // Hooks import { useProfileSettings } from './hooks'; const MAX_CONTENT_WIDTH = 500; const ACCENT_GRADIENT = featureColors.profile.gradient as [string, string]; export function ProfileScreen() { const router = useRouter(); const { width } = useWindowDimensions(); const isWideScreen = width > MAX_CONTENT_WIDTH; const { user, partner, couple, fetchUser, isAnonymous } = useAuthStore(); const { subscription } = useSubscriptionStore(); const settings = useProfileSettings(); // Paywall state const [showPaywall, setShowPaywall] = useState(false); const [headerHeight, setHeaderHeight] = useState(130); // Derived state const isOwnSubscription = subscription.isProUser || user?.is_premium; const hasPremiumAccess = user?.is_premium || partner?.is_premium || subscription.isProUser; const formatExpirationDate = (date: Date | null | string) => { if (!date) return "Never"; const d = new Date(date); return d.toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric", }); }; // Version info const version = Constants.expoConfig?.version ?? '1.0.0'; const buildNumber = Platform.select({ ios: Constants.expoConfig?.ios?.buildNumber, android: Constants.expoConfig?.android?.versionCode?.toString(), default: undefined, }); const versionString = buildNumber ? `v${version} (${buildNumber})` : `v${version}`; return ( setHeaderHeight(e.nativeEvent.layout.height)} > {/* Compact Profile Preview */} router.push('/(app)/settings/profile')} activeOpacity={0.7} > {user?.avatar_url ? ( ) : ( {user?.name?.[0]?.toUpperCase() || "U"} )} {user?.name || "User"} {isAnonymous ? "Unsaved account" : (user?.email || "")} {/* Subscription CTA - prominent upsell */} setShowPaywall(true)} onManagePress={settings.handleManageSubscription} onRestorePress={settings.handleRestorePurchases} isRestoring={settings.isPurchasing} delay={200} /> {/* Settings Navigation */} router.push('/(app)/settings/profile')} /> router.push('/(app)/settings/notifications')} /> router.push('/(app)/settings/preferences')} /> {/* Relationship Section */} router.push('/(app)/settings/partner')} /> {/* Other Section */} {isAnonymous && ( <> router.push('/(app)/settings/save-account' as any)} /> )} router.push('/(app)/settings/support')} /> router.push('/(app)/settings/account')} /> {/* Debug Section - Dev only */} {__DEV__ && ( {}} showChevron={false} /> { if (!user?.id) return; await resetMatchesTutorial(user.id); Alert.alert("Success", "Matches tutorial has been reset."); }} /> { if (!user?.id) return; try { await profileSettingsApi.updateProfile({ onboarding_completed: false }); await fetchUser(); Alert.alert("Success", "Onboarding has been reset."); } catch (error) { Alert.alert("Error", "Failed to reset onboarding."); } }} /> )} {/* Version */} Sauci {versionString} setShowPaywall(false)} /> ); } const styles = StyleSheet.create({ container: { flex: 1, }, contentContainer: { paddingBottom: Platform.OS === 'ios' ? 100 : 80, }, contentContainerWide: { alignSelf: 'center', width: '100%', maxWidth: MAX_CONTENT_WIDTH, }, stickyHeader: { position: 'absolute', top: 0, left: 0, right: 0, zIndex: 10, overflow: 'hidden', }, stickyHeaderWide: { left: '50%', right: 'auto', width: MAX_CONTENT_WIDTH, transform: [{ translateX: -MAX_CONTENT_WIDTH / 2 }], }, // Profile Preview profilePreview: { marginHorizontal: spacing.lg, marginBottom: spacing.lg, backgroundColor: colors.backgroundLight, // Flat background borderRadius: radius.lg, borderWidth: 1, borderColor: colors.border, overflow: 'hidden', }, // ... avatarGradient: { width: 56, height: 56, borderRadius: 28, padding: 2, justifyContent: 'center', alignItems: 'center', // Removed shadow }, // ... versionBadge: { flexDirection: "row", alignItems: "center", backgroundColor: colors.backgroundLight, // Flat background paddingHorizontal: spacing.md, paddingVertical: spacing.sm, borderRadius: radius.full, gap: spacing.xs, borderWidth: 1, borderColor: colors.border, }, profilePreviewContent: { flexDirection: 'row', alignItems: 'center', padding: spacing.md, }, avatar: { width: '100%', height: '100%', borderRadius: 28, backgroundColor: colors.background, }, avatarInner: { width: '100%', height: '100%', borderRadius: 28, backgroundColor: colors.background, justifyContent: 'center', alignItems: 'center', }, avatarText: { ...typography.title2, fontSize: 24, color: colors.text, }, profileInfo: { flex: 1, marginLeft: spacing.md, }, userName: { ...typography.headline, color: colors.text, }, userEmail: { ...typography.caption1, color: colors.textSecondary, marginTop: 2, }, profileChevron: { padding: spacing.xs, }, divider: { height: 1, backgroundColor: colors.border, marginVertical: spacing.md, }, // Version Badge versionContainer: { alignItems: "center", marginTop: spacing.lg, }, version: { ...typography.caption1, color: colors.textTertiary, }, bottomSpacer: { height: spacing.lg, }, });