/** * TabataGo Home Screen * Mascot + 3 stat pills + 3 body zone cards + settings button. */ 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 { Mascot } from '@/src/shared/components/Mascot' import { useUserStore } from '@/src/shared/stores/userStore' import { useProgressStore } from '@/src/shared/stores/progressStore' import { BODY_ZONE_META, type BodyZone } from '@/src/shared/types/workoutProgram' import { TYPOGRAPHY } from '@/src/shared/constants/typography' import { SPACING } from '@/src/shared/constants/spacing' import { RADIUS } from '@/src/shared/constants/borderRadius' import { TEXT, NAVY, GREEN, BORDER_COLORS } from '@/src/shared/constants/colors' import { withOpacity } from '@/src/shared/utils/color' const BODY_ZONES: BodyZone[] = ['upper-body', 'lower-body', 'full-body'] export default function HomeScreen() { const router = useRouter() const insets = useSafeAreaInsets() const { t } = useTranslation() const firstName = useUserStore(s => s.profile.name) const streak = useProgressStore(s => s.streak.current) const weeklyCount = useProgressStore(s => s.getWeeklyCount()) const completedCount = useProgressStore(s => s.getCompletedCount()) const nameSuffix = firstName ? `, ${firstName}` : '' const mascotMessage = streak > 0 ? t('screens:home.mascotStreak', { count: streak, name: nameSuffix }) : t('screens:home.mascotReady', { name: nameSuffix }) return ( {/* Header with settings */} TabataGo router.push('/settings')} style={styles.iconBtn} hitSlop={8}> {/* Mascot */} {/* Stats pills */} {/* Body zone cards */} {t('screens:zone.chooseYourFocus')} {BODY_ZONES.map(zone => ( router.push(`/zone/${zone}`)} /> ))} ) } function StatPill({ value, label, icon, color, }: { value: number label: string icon: any color: string }) { return ( {value} {label} ) } function ZoneCard({ zone, onPress }: { zone: BodyZone; onPress: () => void }) { const meta = BODY_ZONE_META[zone] const { t } = useTranslation() return ( [ styles.zoneCard, { borderColor: withOpacity(meta.color, 0.3) }, pressed && { opacity: 0.85, transform: [{ scale: 0.98 }] }, ]} > {/* Colored top strip with large icon */} {/* Content area */} {meta.label} {t(meta.descKey)} {/* Bottom row: level badge + chevron */} {t('screens:home.zoneLevels')} ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: NAVY[900] }, content: { paddingHorizontal: SPACING[5] }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: SPACING[4], }, brand: { ...TYPOGRAPHY.TITLE_1, color: TEXT.PRIMARY, letterSpacing: -0.5 }, iconBtn: { width: 40, height: 40, borderRadius: 20, alignItems: 'center', justifyContent: 'center', backgroundColor: NAVY[800], borderWidth: 1, borderColor: BORDER_COLORS.DIM, }, mascotWrap: { alignItems: 'center', marginVertical: SPACING[4] }, statsRow: { flexDirection: 'row', gap: SPACING[2], marginBottom: SPACING[6] }, pill: { flex: 1, alignItems: 'center', paddingVertical: SPACING[3], paddingHorizontal: SPACING[2], borderRadius: RADIUS.MD, borderWidth: 1, backgroundColor: NAVY[800], gap: 4, }, pillValue: { ...TYPOGRAPHY.TITLE_2, color: TEXT.PRIMARY, fontVariant: ['tabular-nums'] }, pillLabel: { ...TYPOGRAPHY.CAPTION_2, color: TEXT.TERTIARY, textAlign: 'center' }, sectionTitle: { ...TYPOGRAPHY.HEADLINE, color: TEXT.PRIMARY, marginBottom: SPACING[3] }, zoneList: { gap: SPACING[4] }, zoneCard: { borderRadius: RADIUS.XL, borderWidth: 1, backgroundColor: NAVY[800], overflow: 'hidden' as const, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.3)', }, zoneTopStrip: { alignItems: 'center' as const, justifyContent: 'center' as const, paddingVertical: SPACING[5], }, zoneIconCircle: { width: 72, height: 72, borderRadius: 36, alignItems: 'center' as const, justifyContent: 'center' as const, }, zoneContent: { padding: SPACING[4], gap: SPACING[2], }, zoneTitle: { ...TYPOGRAPHY.TITLE_2, color: TEXT.PRIMARY }, zoneDesc: { ...TYPOGRAPHY.SUBHEADLINE, color: TEXT.SECONDARY, lineHeight: 20 }, zoneFooter: { flexDirection: 'row' as const, alignItems: 'center' as const, justifyContent: 'space-between' as const, marginTop: SPACING[1], }, zoneBadge: { paddingHorizontal: SPACING[3], paddingVertical: SPACING[1], borderRadius: RADIUS.SM, }, zoneBadgeText: { ...TYPOGRAPHY.CAPTION_1, fontWeight: '600' as const }, })