feat(plan): atgardspanel som bottenpanel (Modal) i stallet for Alert
Klick pa en maltid oppnar en egen panel: 'Jag lagade detta' (ratt dag), 'Byt ratt', 'Ta bort'. Ingen 'Avbryt' - tryck utanfor for att stanga. Kanns mer enterprise an systemets Alert-ruta.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { Alert, Pressable, Text, View } from "react-native";
|
import { Alert, Modal, Pressable, Text, View } from "react-native";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { api } from "@/lib/api";
|
import { api } from "@/lib/api";
|
||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
Card,
|
Card,
|
||||||
EmptyState,
|
EmptyState,
|
||||||
ErrorView,
|
ErrorView,
|
||||||
|
Heading,
|
||||||
LoadingView,
|
LoadingView,
|
||||||
Row,
|
Row,
|
||||||
Screen,
|
Screen,
|
||||||
@@ -67,6 +68,7 @@ export default function PlanScreen() {
|
|||||||
const locale = getLanguageTag();
|
const locale = getLanguageTag();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const [selectedKey, setSelectedKey] = useState<string>(() => toKey(new Date()));
|
const [selectedKey, setSelectedKey] = useState<string>(() => toKey(new Date()));
|
||||||
|
const [actionEntry, setActionEntry] = useState<WeekPlanEntry | null>(null);
|
||||||
const [generating, setGenerating] = useState(false);
|
const [generating, setGenerating] = useState(false);
|
||||||
const todayKey = toKey(new Date());
|
const todayKey = toKey(new Date());
|
||||||
|
|
||||||
@@ -175,31 +177,10 @@ export default function PlanScreen() {
|
|||||||
onError: onMutationError,
|
onError: onMutationError,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Öppnar en egen bottenpanel (Modal) i stället för Alert – ingen "Avbryt",
|
||||||
|
// tryck utanför för att stänga (känns mer enterprise).
|
||||||
const openActions = (entry: WeekPlanEntry) => {
|
const openActions = (entry: WeekPlanEntry) => {
|
||||||
if (!planId) return;
|
if (planId) setActionEntry(entry);
|
||||||
Alert.alert(entry.titleSv, undefined, [
|
|
||||||
// "Jag lagade detta" bara på rätt dag – inte för framtida måltider.
|
|
||||||
...(entry.date === todayKey
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
text: t("recipe.iCookedThis"),
|
|
||||||
onPress: () => patchEntry.mutate({ planId, entryId: entry.id, status: "cooked" }),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
{
|
|
||||||
text: "Byt rätt",
|
|
||||||
onPress: () =>
|
|
||||||
router.push(`/swap-meal/${entry.id}?planId=${planId}&mealType=${entry.mealType}`),
|
|
||||||
},
|
|
||||||
// Ersätter "Hoppa över": ta bort måltiden man inte lagat.
|
|
||||||
{
|
|
||||||
text: t("common.remove"),
|
|
||||||
style: "destructive" as const,
|
|
||||||
onPress: () => removeEntry.mutate({ planId, entryId: entry.id }),
|
|
||||||
},
|
|
||||||
{ text: t("common.cancel"), style: "cancel" as const },
|
|
||||||
]);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const monthLabel = cap(
|
const monthLabel = cap(
|
||||||
@@ -386,6 +367,70 @@ export default function PlanScreen() {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
{/* Åtgärdspanel för en måltid – tryck utanför för att stänga, ingen Avbryt. */}
|
||||||
|
<Modal
|
||||||
|
visible={actionEntry !== null}
|
||||||
|
transparent
|
||||||
|
animationType="fade"
|
||||||
|
onRequestClose={() => setActionEntry(null)}
|
||||||
|
>
|
||||||
|
<Pressable
|
||||||
|
onPress={() => setActionEntry(null)}
|
||||||
|
style={{ flex: 1, justifyContent: "flex-end", backgroundColor: "rgba(0,0,0,0.4)" }}
|
||||||
|
>
|
||||||
|
<Pressable
|
||||||
|
onPress={() => {}}
|
||||||
|
style={{
|
||||||
|
backgroundColor: colors.surface,
|
||||||
|
borderTopLeftRadius: radius.lg,
|
||||||
|
borderTopRightRadius: radius.lg,
|
||||||
|
padding: spacing.lg,
|
||||||
|
paddingBottom: spacing.xl,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{actionEntry ? (
|
||||||
|
<>
|
||||||
|
<Heading>{actionEntry.titleSv}</Heading>
|
||||||
|
{actionEntry.date === todayKey ? (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
label={t("recipe.iCookedThis")}
|
||||||
|
onPress={() => {
|
||||||
|
patchEntry.mutate({
|
||||||
|
planId: planId!,
|
||||||
|
entryId: actionEntry.id,
|
||||||
|
status: "cooked",
|
||||||
|
});
|
||||||
|
setActionEntry(null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Spacer size={spacing.xs} />
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
<Button
|
||||||
|
label="Byt rätt"
|
||||||
|
variant="secondary"
|
||||||
|
onPress={() => {
|
||||||
|
const e = actionEntry;
|
||||||
|
setActionEntry(null);
|
||||||
|
router.push(`/swap-meal/${e.id}?planId=${planId}&mealType=${e.mealType}`);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Spacer size={spacing.xs} />
|
||||||
|
<Button
|
||||||
|
label={t("common.remove")}
|
||||||
|
variant="danger"
|
||||||
|
onPress={() => {
|
||||||
|
removeEntry.mutate({ planId: planId!, entryId: actionEntry.id });
|
||||||
|
setActionEntry(null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</Pressable>
|
||||||
|
</Pressable>
|
||||||
|
</Modal>
|
||||||
</Screen>
|
</Screen>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user