From 0cc8f036d65a8f1949fdabc744d81d8ac14ed05a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 19 Aug 2026 23:33:32 +0000 Subject: [PATCH] fix(inkopslista): visa den genererade listan (inte en gammal tom) POST aterananvander EN aktiv lista per veckoplan (staplar inte nya), GET sorterar nyaste forst, och appen navigerar med listId. Tidigare hamnade de genererade raderna i en lista skarmen inte visade -> tomt. --- apps/api/src/routes/shopping.ts | 47 +++++++++++++++++++++++++++----- apps/mobile/src/app/shopping.tsx | 7 ++++- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/apps/api/src/routes/shopping.ts b/apps/api/src/routes/shopping.ts index b050cab..a3db70b 100644 --- a/apps/api/src/routes/shopping.ts +++ b/apps/api/src/routes/shopping.ts @@ -101,7 +101,8 @@ export async function shoppingRoutes(app: FastifyInstance) { eq(schema.shoppingLists.householdId, householdId), eq(schema.shoppingLists.status, "active"), ), - ); + ) + .orderBy(desc(schema.shoppingLists.createdAt)); return { lists }; }); @@ -109,14 +110,46 @@ export async function shoppingRoutes(app: FastifyInstance) { const input = parse(createShoppingListInputSchema, req.body); const householdId = await requireActiveHousehold(app.db, req.userId); - const [list] = await app.db - .insert(schema.shoppingLists) - .values({ householdId, name: input.name, weekPlanId: input.weekPlanId ?? null }) - .returning(); - - // Generera från veckoplan: receptbehov − befintligt lager (spec §27) + // Generera från veckoplan: återanvänd EN aktiv lista per veckoplan så att + // "skapa inköpslista" inte staplar nya (tomma) listor. Utan detta pekade + // appen på en annan/äldre lista och den genererade listan såg tom ut. + let list; if (input.generateFromPlan && input.weekPlanId) { + const [existing] = await app.db + .select() + .from(schema.shoppingLists) + .where( + and( + eq(schema.shoppingLists.householdId, householdId), + eq(schema.shoppingLists.status, "active"), + eq(schema.shoppingLists.weekPlanId, input.weekPlanId), + ), + ) + .limit(1); + if (existing) { + list = existing; + // Rensa tidigare plan-rader så omgenerering inte dubblerar. + await app.db + .delete(schema.shoppingListItems) + .where( + and( + eq(schema.shoppingListItems.shoppingListId, existing.id), + eq(schema.shoppingListItems.origin, "plan"), + ), + ); + } else { + [list] = await app.db + .insert(schema.shoppingLists) + .values({ householdId, name: input.name, weekPlanId: input.weekPlanId }) + .returning(); + } + // Receptbehov − befintligt lager (spec §27) await generateItemsFromPlan(app, list!.id, input.weekPlanId, householdId, req.userId); + } else { + [list] = await app.db + .insert(schema.shoppingLists) + .values({ householdId, name: input.name, weekPlanId: input.weekPlanId ?? null }) + .returning(); } const items = await app.db diff --git a/apps/mobile/src/app/shopping.tsx b/apps/mobile/src/app/shopping.tsx index 94e335c..b2dd486 100644 --- a/apps/mobile/src/app/shopping.tsx +++ b/apps/mobile/src/app/shopping.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; import { Alert, Pressable, Text, View } from "react-native"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { useLocalSearchParams } from "expo-router"; import { api } from "@/lib/api"; import { t } from "@/lib/i18n"; import { formatMinor } from "@/lib/money"; @@ -61,6 +62,8 @@ const sectionLabel = (id: string): string => export default function ShoppingScreen() { const queryClient = useQueryClient(); const [newItem, setNewItem] = useState(""); + const params = useLocalSearchParams<{ listId?: string }>(); + const paramListId = typeof params.listId === "string" ? params.listId : undefined; const lists = useQuery({ queryKey: ["shopping-lists"], @@ -76,7 +79,9 @@ export default function ShoppingScreen() { return result.lists; }, }); - const listId = lists.data?.[0]?.id; + // Prioritera listId från navigering (t.ex. nygenererad från veckoplan), + // annars nyaste aktiva listan. + const listId = paramListId ?? lists.data?.[0]?.id; const list = useQuery({ queryKey: ["shopping-list", listId],