feat(byt-ratt): sok bland ALLA recept vid byte
Byt-ratt-skarmen far ett sokfalt. Med sokning filtreras maltidstyp bort pa servern -> byt till vilken ratt som helst. Utan sokning visas breda forslag for slotten (view=swap).
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useState } from "react";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { Alert } from "react-native";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
@@ -8,13 +9,16 @@ import {
|
||||
Card,
|
||||
EmptyState,
|
||||
ErrorView,
|
||||
Input,
|
||||
LoadingView,
|
||||
Row,
|
||||
Screen,
|
||||
Small,
|
||||
Spacer,
|
||||
Tag,
|
||||
Title,
|
||||
} from "@/components/ui";
|
||||
import { spacing } from "@/lib/theme";
|
||||
|
||||
interface Rec {
|
||||
recipeId: string;
|
||||
@@ -32,13 +36,20 @@ export default function SwapMealScreen() {
|
||||
const mealType = String(params.mealType || "dinner");
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const [searchText, setSearchText] = useState("");
|
||||
const [submitted, setSubmitted] = useState("");
|
||||
|
||||
const query = useQuery({
|
||||
queryKey: ["swap-options", mealType],
|
||||
// view=swap: bredda urvalet – alla lämpliga rätter, inte bara det man har hemma.
|
||||
queryFn: () =>
|
||||
api<WhatToEatResponse>(
|
||||
`/v1/recommendations/what-to-eat?limit=20&view=swap&mealType=${mealType}`,
|
||||
),
|
||||
queryKey: ["swap-options", mealType, submitted],
|
||||
// Med sökning: byt till VILKEN rätt som helst (mealType filtreras då bort på
|
||||
// servern). Utan sökning: breda förslag för slotten (view=swap, låg täckningsvikt).
|
||||
queryFn: () => {
|
||||
const base = "/v1/recommendations/what-to-eat?limit=30&view=swap";
|
||||
const path = submitted
|
||||
? `${base}&search=${encodeURIComponent(submitted)}`
|
||||
: `${base}&mealType=${mealType}`;
|
||||
return api<WhatToEatResponse>(path);
|
||||
},
|
||||
});
|
||||
|
||||
const swap = useMutation({
|
||||
@@ -53,15 +64,35 @@ export default function SwapMealScreen() {
|
||||
});
|
||||
|
||||
const recs = query.data?.recommendations ?? [];
|
||||
const mealLabel = mealType === "lunch" ? "lunchen" : mealType === "breakfast" ? "frukosten" : "middagen";
|
||||
const mealLabel =
|
||||
mealType === "lunch" ? "lunchen" : mealType === "breakfast" ? "frukosten" : "middagen";
|
||||
|
||||
return (
|
||||
<Screen>
|
||||
<Title>Byt ut måltiden</Title>
|
||||
<Small>Välj en annan rätt för {mealLabel}:</Small>
|
||||
<Small>Välj en annan rätt för {mealLabel} – eller sök efter vilken rätt som helst.</Small>
|
||||
<Spacer size={spacing.sm} />
|
||||
<Input
|
||||
placeholder="Sök bland alla recept …"
|
||||
value={searchText}
|
||||
onChangeText={setSearchText}
|
||||
onSubmitEditing={() => setSubmitted(searchText.trim())}
|
||||
returnKeyType="search"
|
||||
autoCorrect={false}
|
||||
/>
|
||||
{submitted ? (
|
||||
<Small>
|
||||
Visar träffar för ”{submitted}”.{" "}
|
||||
<Small>Rensa sökrutan och sök på tomt för att se förslag igen.</Small>
|
||||
</Small>
|
||||
) : null}
|
||||
<Spacer size={spacing.xs} />
|
||||
|
||||
{query.isLoading && <LoadingView />}
|
||||
{query.isError && <ErrorView onRetry={() => void query.refetch()} />}
|
||||
{query.data && recs.length === 0 && <EmptyState text={t("wte.empty")} />}
|
||||
{query.data && recs.length === 0 && (
|
||||
<EmptyState text={submitted ? "Inga recept matchar sökningen." : t("wte.empty")} />
|
||||
)}
|
||||
{recs.map((rec) => (
|
||||
<Card key={rec.recipeId} onPress={() => swap.mutate(rec.recipeId)}>
|
||||
<Row style={{ justifyContent: "space-between", alignItems: "center" }}>
|
||||
|
||||
Reference in New Issue
Block a user