feat(mobile): MIKRO WEEK-3 interaktiv planera veckan-ruta (dagar x måltider)
This commit is contained in:
@@ -80,10 +80,15 @@ export default function PlanScreen() {
|
|||||||
const mondayKey = toKey(monday);
|
const mondayKey = toKey(monday);
|
||||||
const weekDays = useMemo(() => Array.from({ length: 7 }, (_, i) => addDays(monday, i)), [monday]);
|
const weekDays = useMemo(() => Array.from({ length: 7 }, (_, i) => addDays(monday, i)), [monday]);
|
||||||
// Vardag: middag. Helg (lör/sön): lunch + middag. Realistisk förifylld default.
|
// Vardag: middag. Helg (lör/sön): lunch + middag. Realistisk förifylld default.
|
||||||
const mealSlots = useMemo(
|
const [mealSlots, setMealSlots] = useState<string[][]>(() =>
|
||||||
() => weekDays.map((d) => (d.getDay() === 0 || d.getDay() === 6 ? ["lunch", "dinner"] : ["dinner"])),
|
weekDays.map((d) => (d.getDay() === 0 || d.getDay() === 6 ? ["lunch", "dinner"] : ["dinner"])),
|
||||||
[weekDays],
|
|
||||||
);
|
);
|
||||||
|
const toggleSlot = (dayIdx: number, meal: string) =>
|
||||||
|
setMealSlots((prev) =>
|
||||||
|
prev.map((meals, i) =>
|
||||||
|
i !== dayIdx ? meals : meals.includes(meal) ? meals.filter((m) => m !== meal) : [...meals, meal],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
queryKey: ["week-plan", mondayKey],
|
queryKey: ["week-plan", mondayKey],
|
||||||
@@ -313,11 +318,39 @@ export default function PlanScreen() {
|
|||||||
<>
|
<>
|
||||||
<EmptyState text={t("plan.emptyDay")} />
|
<EmptyState text={t("plan.emptyDay")} />
|
||||||
{(plan === null || !hasEntries) && (
|
{(plan === null || !hasEntries) && (
|
||||||
<Button
|
<>
|
||||||
label={t("plan.generate")}
|
<Small>Planera veckan – välj måltider per dag:</Small>
|
||||||
onPress={() => generate.mutate()}
|
{weekDays.map((d, i) => (
|
||||||
loading={generate.isPending}
|
<Row
|
||||||
/>
|
key={toKey(d)}
|
||||||
|
style={{ justifyContent: "space-between", alignItems: "center", marginVertical: 2 }}
|
||||||
|
>
|
||||||
|
<Small>
|
||||||
|
{cap(new Intl.DateTimeFormat(locale, { weekday: "short", day: "numeric" }).format(d))}
|
||||||
|
</Small>
|
||||||
|
<Row>
|
||||||
|
{(["breakfast", "lunch", "dinner"] as const).map((meal) => (
|
||||||
|
<Pressable
|
||||||
|
key={meal}
|
||||||
|
onPress={() => toggleSlot(i, meal)}
|
||||||
|
style={{ marginLeft: spacing.xs }}
|
||||||
|
>
|
||||||
|
<Tag
|
||||||
|
label={mealTypeLabel(meal)}
|
||||||
|
tone={mealSlots[i]?.includes(meal) ? "accent" : "neutral"}
|
||||||
|
/>
|
||||||
|
</Pressable>
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
</Row>
|
||||||
|
))}
|
||||||
|
<Spacer size={spacing.xs} />
|
||||||
|
<Button
|
||||||
|
label={t("plan.generate")}
|
||||||
|
onPress={() => generate.mutate()}
|
||||||
|
loading={generate.isPending}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user