From 197324188c51651254cbe273edbad9f9b916fda7 Mon Sep 17 00:00:00 2001 From: Millian Lamiaux Date: Tue, 17 Mar 2026 14:29:27 +0100 Subject: [PATCH] feat: update Home screen to use React Query with loading states - Replace static data with React Query hooks - Add loading skeletons for all data sections - Show shimmer effect while data is loading - Handle empty and error states gracefully --- app/(tabs)/index.tsx | 115 +++++++++++++++++++++----------------- src/shared/hooks/index.ts | 1 + 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 363d36f..5ac4998 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -12,18 +12,12 @@ import Ionicons from '@expo/vector-icons/Ionicons' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' -import { useHaptics } from '@/src/shared/hooks' +import { useHaptics, useFeaturedWorkouts, usePopularWorkouts, useCollections } from '@/src/shared/hooks' import { useUserStore, useActivityStore } from '@/src/shared/stores' -import { - getFeaturedWorkouts, - getPopularWorkouts, - COLLECTIONS, - WORKOUTS, -} from '@/src/shared/data' -import { useTranslatedWorkouts, useTranslatedCollections } 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 { WorkoutCardSkeleton, CollectionCardSkeleton, StatsCardSkeleton } from '@/src/shared/components/loading/Skeleton' import { useThemeColors, BRAND, GRADIENTS } from '@/src/shared/theme' import type { ThemeColors } from '@/src/shared/theme/types' @@ -69,10 +63,17 @@ export default function HomeScreen() { const [selectedCategory, setSelectedCategory] = useState('all') - const featured = getFeaturedWorkouts()[0] ?? WORKOUTS[0] - const popular = getPopularWorkouts(6) - const translatedPopular = useTranslatedWorkouts(popular) - const translatedCollections = useTranslatedCollections(COLLECTIONS) + // React Query hooks for live data + const { data: featuredWorkouts = [], isLoading: isLoadingFeatured } = useFeaturedWorkouts() + const { data: popularWorkouts = [], isLoading: isLoadingPopular } = usePopularWorkouts(6) + const { data: collections = [], isLoading: isLoadingCollections } = useCollections() + + const featured = featuredWorkouts[0] + + const filteredWorkouts = useMemo(() => { + if (selectedCategory === 'all') return popularWorkouts + return popularWorkouts.filter((w) => w.category === selectedCategory) + }, [popularWorkouts, selectedCategory]) const greeting = (() => { const hour = new Date().getHours() @@ -91,11 +92,6 @@ export default function HomeScreen() { router.push(`/collection/${id}`) } - const filteredWorkouts = useMemo(() => { - if (selectedCategory === 'all') return translatedPopular - return translatedPopular.filter((w) => w.category === selectedCategory) - }, [translatedPopular, selectedCategory]) - return ( - handleWorkoutPress(featured.id)} - /> + {isLoadingFeatured ? ( + + ) : featured ? ( + handleWorkoutPress(featured.id)} + /> + ) : null} {/* Category Filter */} @@ -176,34 +176,41 @@ export default function HomeScreen() { {/* Popular Workouts - Horizontal */} - {filteredWorkouts.length > 0 && ( - - - - {t('screens:home.popularThisWeek')} + + + + {t('screens:home.popularThisWeek')} + + + + {t('seeAll')} - - - {t('seeAll')} - - - - - {filteredWorkouts.map((workout) => ( + + + + {isLoadingPopular ? ( + // Loading skeletons + <> + + + + + ) : ( + filteredWorkouts.map((workout: any) => ( handleWorkoutPress(workout.id)} /> - ))} - - - )} + )) + )} + + {/* Collections Grid */} @@ -213,13 +220,21 @@ export default function HomeScreen() { - {translatedCollections.map((collection) => ( - handleCollectionPress(collection.id)} - /> - ))} + {isLoadingCollections ? ( + // Loading skeletons for collections + <> + + + + ) : ( + collections.map((collection) => ( + handleCollectionPress(collection.id)} + /> + )) + )} diff --git a/src/shared/hooks/index.ts b/src/shared/hooks/index.ts index 15ff2bb..3743de7 100644 --- a/src/shared/hooks/index.ts +++ b/src/shared/hooks/index.ts @@ -19,5 +19,6 @@ export { useCollection, usePrograms, useFeaturedWorkouts, + usePopularWorkouts, useWorkoutsByTrainer, } from './useSupabaseData'