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,
},
});