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 { router, useLocalSearchParams } from "expo-router";
|
||||||
import { Alert } from "react-native";
|
import { Alert } from "react-native";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
@@ -8,13 +9,16 @@ import {
|
|||||||
Card,
|
Card,
|
||||||
EmptyState,
|
EmptyState,
|
||||||
ErrorView,
|
ErrorView,
|
||||||
|
Input,
|
||||||
LoadingView,
|
LoadingView,
|
||||||
Row,
|
Row,
|
||||||
Screen,
|
Screen,
|
||||||
Small,
|
Small,
|
||||||
|
Spacer,
|
||||||
Tag,
|
Tag,
|
||||||
Title,
|
Title,
|
||||||
} from "@/components/ui";
|
} from "@/components/ui";
|
||||||
|
import { spacing } from "@/lib/theme";
|
||||||
|
|
||||||
interface Rec {
|
interface Rec {
|
||||||
recipeId: string;
|
recipeId: string;
|
||||||
@@ -32,13 +36,20 @@ export default function SwapMealScreen() {
|
|||||||
const mealType = String(params.mealType || "dinner");
|
const mealType = String(params.mealType || "dinner");
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const [searchText, setSearchText] = useState("");
|
||||||
|
const [submitted, setSubmitted] = useState("");
|
||||||
|
|
||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
queryKey: ["swap-options", mealType],
|
queryKey: ["swap-options", mealType, submitted],
|
||||||
// view=swap: bredda urvalet – alla lämpliga rätter, inte bara det man har hemma.
|
// Med sökning: byt till VILKEN rätt som helst (mealType filtreras då bort på
|
||||||
queryFn: () =>
|
// servern). Utan sökning: breda förslag för slotten (view=swap, låg täckningsvikt).
|
||||||
api<WhatToEatResponse>(
|
queryFn: () => {
|
||||||
`/v1/recommendations/what-to-eat?limit=20&view=swap&mealType=${mealType}`,
|
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({
|
const swap = useMutation({
|
||||||
@@ -53,15 +64,35 @@ export default function SwapMealScreen() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const recs = query.data?.recommendations ?? [];
|
const recs = query.data?.recommendations ?? [];
|
||||||
const mealLabel = mealType === "lunch" ? "lunchen" : mealType === "breakfast" ? "frukosten" : "middagen";
|
const mealLabel =
|
||||||
|
mealType === "lunch" ? "lunchen" : mealType === "breakfast" ? "frukosten" : "middagen";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Screen>
|
<Screen>
|
||||||
<Title>Byt ut måltiden</Title>
|
<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.isLoading && <LoadingView />}
|
||||||
{query.isError && <ErrorView onRetry={() => void query.refetch()} />}
|
{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) => (
|
{recs.map((rec) => (
|
||||||
<Card key={rec.recipeId} onPress={() => swap.mutate(rec.recipeId)}>
|
<Card key={rec.recipeId} onPress={() => swap.mutate(rec.recipeId)}>
|
||||||
<Row style={{ justifyContent: "space-between", alignItems: "center" }}>
|
<Row style={{ justifyContent: "space-between", alignItems: "center" }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user