/** * TabataFit Browse Screen - Premium Redesign * React Native UI with glassmorphism */ import { View, StyleSheet, ScrollView, Pressable, Dimensions, TextInput } from 'react-native' import { useRouter } from 'expo-router' import { useSafeAreaInsets } from 'react-native-safe-area-context' import { BlurView } from 'expo-blur' import Ionicons from '@expo/vector-icons/Ionicons' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { useHaptics } from '@/src/shared/hooks' import { COLLECTIONS, getFeaturedCollection, WORKOUTS, } from '@/src/shared/data' import { useTranslatedCollections, useTranslatedWorkouts } from '@/src/shared/data/useTranslatedData' import { StyledText } from '@/src/shared/components/StyledText' import { WorkoutCard } from '@/src/shared/components/WorkoutCard' import { CollectionCard } from '@/src/shared/components/CollectionCard' import { useThemeColors, BRAND } from '@/src/shared/theme' import type { ThemeColors } from '@/src/shared/theme/types' import { SPACING, LAYOUT } from '@/src/shared/constants/spacing' import { RADIUS } from '@/src/shared/constants/borderRadius' import type { WorkoutCategory } from '@/src/shared/types' const { width: SCREEN_WIDTH } = Dimensions.get('window') const FONTS = { LARGE_TITLE: 34, TITLE: 28, TITLE_2: 22, HEADLINE: 17, SUBHEADLINE: 15, CAPTION_1: 12, CAPTION_2: 11, } const CATEGORIES: { id: WorkoutCategory | 'all'; translationKey: string }[] = [ { id: 'all', translationKey: 'common:categories.all' }, { id: 'full-body', translationKey: 'common:categories.fullBody' }, { id: 'core', translationKey: 'common:categories.core' }, { id: 'upper-body', translationKey: 'common:categories.upperBody' }, { id: 'lower-body', translationKey: 'common:categories.lowerBody' }, { id: 'cardio', translationKey: 'common:categories.cardio' }, ] // ═══════════════════════════════════════════════════════════════════════════ // MAIN SCREEN // ═══════════════════════════════════════════════════════════════════════════ export default function BrowseScreen() { const { t } = useTranslation() const insets = useSafeAreaInsets() const router = useRouter() const haptics = useHaptics() const colors = useThemeColors() const styles = useMemo(() => createStyles(colors), [colors]) const [searchQuery, setSearchQuery] = useState('') const [selectedCategory, setSelectedCategory] = useState('all') const featuredCollection = getFeaturedCollection() const translatedCollections = useTranslatedCollections(COLLECTIONS) const translatedWorkouts = useTranslatedWorkouts(WORKOUTS) // Filter workouts based on search and category const filteredWorkouts = useMemo(() => { let filtered = translatedWorkouts if (searchQuery.trim()) { const query = searchQuery.toLowerCase() filtered = filtered.filter( (w) => w.title.toLowerCase().includes(query) || w.category.toLowerCase().includes(query) ) } if (selectedCategory !== 'all') { filtered = filtered.filter((w) => w.category === selectedCategory) } return filtered }, [translatedWorkouts, searchQuery, selectedCategory]) const handleWorkoutPress = (id: string) => { haptics.buttonTap() router.push(`/workout/${id}`) } const handleCollectionPress = (id: string) => { haptics.buttonTap() router.push(`/collection/${id}`) } return ( {/* Header */} {t('screens:browse.title')} {/* Search Bar */} {searchQuery.length > 0 && ( setSearchQuery('')} hitSlop={8} > )} {/* Category Filter Chips */} {CATEGORIES.map((cat) => ( { haptics.buttonTap() setSelectedCategory(cat.id) }} > {selectedCategory === cat.id && ( )} {t(cat.translationKey)} ))} {/* Featured Collection */} {featuredCollection && !searchQuery && selectedCategory === 'all' && ( {t('screens:browse.featured')} handleCollectionPress(featuredCollection.id)} /> )} {/* Collections Grid */} {!searchQuery && selectedCategory === 'all' && ( {t('screens:browse.collections')} {translatedCollections.map((collection) => ( handleCollectionPress(collection.id)} /> ))} )} {/* All Workouts Grid */} {searchQuery ? t('screens:browse.searchResults') || 'Results' : t('screens:browse.allWorkouts') || 'All Workouts'} {filteredWorkouts.length} {t('plurals.workout', { count: filteredWorkouts.length })} {filteredWorkouts.length > 0 ? ( {filteredWorkouts.map((workout) => ( handleWorkoutPress(workout.id)} /> ))} ) : ( {t('screens:browse.noResults') || 'No workouts found'} {t('screens:browse.tryDifferentSearch') || 'Try a different search or category'} )} ) } // ═══════════════════════════════════════════════════════════════════════════ // STYLES // ═══════════════════════════════════════════════════════════════════════════ function createStyles(colors: ThemeColors) { return StyleSheet.create({ container: { flex: 1, backgroundColor: colors.bg.base, }, scrollView: { flex: 1, }, scrollContent: { paddingHorizontal: LAYOUT.SCREEN_PADDING, }, // Header header: { marginBottom: SPACING[4], }, // Search Bar searchContainer: { flexDirection: 'row', alignItems: 'center', height: 48, borderRadius: RADIUS.LG, borderWidth: 1, borderColor: colors.border.glass, paddingHorizontal: SPACING[4], marginBottom: SPACING[4], overflow: 'hidden', }, searchInput: { flex: 1, marginLeft: SPACING[3], marginRight: SPACING[2], fontSize: FONTS.HEADLINE, color: colors.text.primary, height: '100%', }, // Categories categoriesContainer: { marginBottom: SPACING[6], }, categoriesScroll: { gap: SPACING[2], paddingRight: SPACING[4], }, categoryChip: { paddingHorizontal: SPACING[4], paddingVertical: SPACING[2], borderRadius: RADIUS.FULL, overflow: 'hidden', borderWidth: 1, borderColor: colors.border.glass, }, categoryChipActive: { borderColor: BRAND.PRIMARY, backgroundColor: `${BRAND.PRIMARY}30`, }, // Sections section: { marginBottom: SPACING[8], }, sectionHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: SPACING[4], }, // Collections collectionsGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACING[3], }, // Workouts Grid workoutsGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACING[3], }, // Empty State emptyState: { alignItems: 'center', justifyContent: 'center', paddingVertical: SPACING[12], }, }) }