Files
Cibello-app/apps/mobile/src/app/saved-recipes.tsx
T

66 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from "react";
import { router } from "expo-router";
import { useQuery } from "@tanstack/react-query";
import { api } from "@/lib/api";
import { Card, EmptyState, ErrorView, Heading, Input, LoadingView, Screen, Small } from "@/components/ui";
import { spacing } from "@/lib/theme";
/** Dina sparade recept (favoriter) sökbar lista. Backend: GET /v1/recipes/favorites/mine. */
interface SavedRecipe {
id: string;
titleSv: string;
totalTimeMinutes: number | null;
nutritionPerPortion: { kcal?: number } | null;
}
interface FavoritesResponse {
recipes: SavedRecipe[];
}
export default function SavedRecipesScreen() {
const [query, setQuery] = useState("");
const favs = useQuery<FavoritesResponse>({
queryKey: ["favorites-mine"],
queryFn: () => api<FavoritesResponse>("/v1/recipes/favorites/mine"),
});
if (favs.isLoading) return <LoadingView />;
if (favs.isError) return <ErrorView onRetry={() => void favs.refetch()} />;
const all = favs.data?.recipes ?? [];
const q = query.trim().toLowerCase();
const filtered = q ? all.filter((r) => r.titleSv.toLowerCase().includes(q)) : all;
return (
<Screen style={{ gap: spacing.md }}>
<Input
placeholder="Sök bland dina sparade recept"
autoCapitalize="none"
value={query}
onChangeText={setQuery}
/>
{all.length === 0 ? (
<EmptyState text="Du har inga sparade recept än. Tryck på ☆ Spara på ett recept så hamnar det här." />
) : filtered.length === 0 ? (
<EmptyState text="Inga sparade recept matchar din sökning." />
) : (
filtered.map((r) => (
<Card key={r.id} onPress={() => router.push(`/recipe/${r.id}`)} style={{ gap: spacing.xs }}>
<Heading>{r.titleSv}</Heading>
<Small>
{[
r.totalTimeMinutes != null ? `${r.totalTimeMinutes} min` : null,
r.nutritionPerPortion?.kcal != null
? `${Math.round(r.nutritionPerPortion.kcal)} kcal`
: null,
]
.filter(Boolean)
.join(" · ")}
</Small>
</Card>
))
)}
</Screen>
);
}