/**
* TabataGo Profile Tab
* User info, subscription status, quick stats. Settings via form sheet.
*/
import { useMemo } from 'react'
import { View, Text, StyleSheet, ScrollView, Pressable } from 'react-native'
import { useRouter } from 'expo-router'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { useTranslation } from 'react-i18next'
import { Icon } from '@/src/shared/components/Icon'
import { useUserStore } from '@/src/shared/stores/userStore'
import { useProgressStore } from '@/src/shared/stores/progressStore'
import { usePurchases } from '@/src/shared/hooks'
import { useThemeColors } from '@/src/shared/theme'
import type { ThemeColors } from '@/src/shared/theme/types'
import { TYPOGRAPHY } from '@/src/shared/constants/typography'
import { SPACING, LAYOUT } from '@/src/shared/constants/spacing'
import { RADIUS } from '@/src/shared/constants/borderRadius'
import { GREEN, NAVY, TEXT, BORDER_COLORS } from '@/src/shared/constants/colors'
export default function ProfileScreen() {
const { t } = useTranslation()
const router = useRouter()
const insets = useSafeAreaInsets()
const colors = useThemeColors()
const styles = useMemo(() => createStyles(colors), [colors])
const profile = useUserStore(s => s.profile)
const { isPremium } = usePurchases()
const completedCount = useProgressStore(s => s.getCompletedCount())
const streak = useProgressStore(s => s.streak)
const weeklyCount = useProgressStore(s => s.getWeeklyCount())
const avatarLetter = profile.name?.[0]?.toUpperCase() || '?'
return (
{/* Avatar + name */}
{avatarLetter}
{profile.name || t('screens:profile.guest')}
{isPremium ? t('screens:settings.premium') : t('screens:settings.free')}
router.push('/settings')} hitSlop={8}>
{/* Stats row */}
{/* Upgrade banner (free users) */}
{!isPremium && (
router.push('/paywall')}
>
{t('screens:profile.upgradeTitle')}
{t('screens:profile.upgradeDescription')}
)}
{/* Settings link */}
router.push('/settings')}>
{t('screens:settings.title')}
)
}
function StatPill({ value, label, icon, color }: { value: number; label: string; icon: any; color: string }) {
return (
{value}
{label}
)
}
const pillStyles = StyleSheet.create({
pill: {
flex: 1,
alignItems: 'center',
paddingVertical: SPACING[3],
borderRadius: RADIUS.MD,
borderWidth: 1,
backgroundColor: NAVY[800],
borderColor: BORDER_COLORS.DIM,
gap: 4,
},
value: { ...TYPOGRAPHY.TITLE_2, color: TEXT.PRIMARY, fontVariant: ['tabular-nums'] },
label: { ...TYPOGRAPHY.CAPTION_2, color: TEXT.TERTIARY, textAlign: 'center' },
})
function createStyles(colors: ThemeColors) {
return StyleSheet.create({
container: { flex: 1, backgroundColor: colors.bg.base },
content: { paddingHorizontal: LAYOUT.SCREEN_PADDING },
profileHeader: {
flexDirection: 'row',
alignItems: 'center',
gap: SPACING[3],
marginBottom: SPACING[5],
},
avatar: {
width: 60,
height: 60,
borderRadius: 30,
backgroundColor: NAVY[700] ?? NAVY[800],
alignItems: 'center',
justifyContent: 'center',
borderWidth: 2,
borderColor: BORDER_COLORS.DIM,
},
avatarLetter: { ...TYPOGRAPHY.TITLE_1, color: TEXT.PRIMARY },
name: { ...TYPOGRAPHY.TITLE_2, color: TEXT.PRIMARY },
planBadge: {
alignSelf: 'flex-start',
marginTop: 4,
paddingHorizontal: SPACING[2],
paddingVertical: 2,
borderRadius: RADIUS.SM,
borderWidth: 1,
},
planText: { ...TYPOGRAPHY.CAPTION_2, fontWeight: '600' },
statsRow: { flexDirection: 'row', gap: SPACING[2], marginBottom: SPACING[5] },
upgradeBanner: {
flexDirection: 'row',
alignItems: 'center',
gap: SPACING[3],
padding: SPACING[4],
borderRadius: RADIUS.LG,
borderWidth: 1,
backgroundColor: colors.surface.default.backgroundColor,
marginBottom: SPACING[3],
borderCurve: 'continuous',
},
upgradeTitle: { ...TYPOGRAPHY.HEADLINE, color: TEXT.PRIMARY },
upgradeDesc: { ...TYPOGRAPHY.CAPTION_1, color: TEXT.SECONDARY, marginTop: 2 },
settingsRow: {
flexDirection: 'row',
alignItems: 'center',
gap: SPACING[3],
padding: SPACING[4],
borderRadius: RADIUS.LG,
borderWidth: 1,
borderColor: BORDER_COLORS.DIM,
backgroundColor: colors.surface.default.backgroundColor,
borderCurve: 'continuous',
},
settingsLabel: { ...TYPOGRAPHY.BODY, color: TEXT.PRIMARY, flex: 1 },
})
}