import { Stack, useLocalSearchParams, router } from 'expo-router'; import { useMemo, useState } from 'react'; import { ActivityIndicator, FlatList, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native'; import { useQuery } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { fetchRecipes } from '@/src/api/recipes.api'; import { EmptyState, RecipeCard } from '@/src/components/RecipeCard'; import { ErrorView } from '@/src/components/ErrorView'; import { Screen } from '@/src/components/Screen'; import { useAppearance } from '@/src/context/AppearanceContext'; import { categoryLabel, parseCategoryParam } from '@/src/utils/recipe'; import { nextSort, sortBy, sortIndicator, type SortDirection } from '@/src/utils/sort'; type RecipeSortColumn = 'name' | 'calories' | 'prepTime'; const RECIPE_SORT_COLUMNS: { id: RecipeSortColumn; labelKey: string }[] = [ { id: 'name', labelKey: 'manage.recipeName' }, { id: 'calories', labelKey: 'recipes.calories' }, { id: 'prepTime', labelKey: 'manage.prepTimeMin' }, ]; export default function CategoryScreen() { const { category: categoryParam } = useLocalSearchParams<{ category: string }>(); const category = parseCategoryParam(categoryParam ?? ''); const { t } = useTranslation(); const { colors } = useAppearance(); const [recipeSort, setRecipeSort] = useState<{ column: RecipeSortColumn; direction: SortDirection }>({ column: 'name', direction: 'asc', }); const recipesQuery = useQuery({ queryKey: ['recipes', 'category', category], queryFn: () => fetchRecipes({ category: category! }), enabled: category != null, }); const title = category != null ? categoryLabel(category, t) : t('categories.unknown'); const sortedRecipes = useMemo(() => { const list = recipesQuery.data ?? []; const { column, direction } = recipeSort; return sortBy(list, direction, (recipe) => { switch (column) { case 'name': return recipe.name; case 'calories': return recipe.calories; case 'prepTime': return recipe.prepTimeMinutes; } }); }, [recipesQuery.data, recipeSort]); if (category == null) { return ( ); } return ( <> {(recipesQuery.data?.length ?? 0) > 0 ? ( {RECIPE_SORT_COLUMNS.map(({ id, labelKey }) => ( setRecipeSort((current) => nextSort(current, id))} /> ))} ) : null} {recipesQuery.isLoading ? ( ) : recipesQuery.isError ? ( recipesQuery.refetch()} /> ) : ( String(item.id)} contentContainerStyle={styles.list} ListEmptyComponent={ } renderItem={({ item }) => ( router.push(`/(main)/recipe/${item.id}`)} /> )} /> )} ); } function SortChip({ label, active, onPress }: { label: string; active: boolean; onPress: () => void }) { const { colors } = useAppearance(); return ( {label} ); } const styles = StyleSheet.create({ sortRow: { gap: 8, paddingBottom: 8, }, sortChip: { borderWidth: 1, borderRadius: 999, paddingHorizontal: 12, paddingVertical: 6, }, list: { gap: 10, paddingBottom: 24, flexGrow: 1, }, loading: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingVertical: 40, }, });