"use client"; import { RiArrowRightLine as ArrowRight, RiCalendarCheckLine as CalendarPlus, RiCheckLine as Check, RiCloseLine as X } from "@remixicon/react"; import Link from "next/link"; import { useEffect, useRef, useState } from "react"; import { DAY_NAMES, mealLabel, slotKey, visibleMeals } from "@/app/lib/plan"; import { RECIPES_BY_ID } from "@/app/lib/recipes"; import { DEFAULT_STATE, sanitizeState } from "@/app/lib/sanitize"; import type { MealPlanState } from "@/app/types"; import { Button } from "@/components/base/buttons/button"; const STORAGE_KEY = "budget-meal-planner:v2"; function readPlan(): MealPlanState { try { const raw = window.localStorage.getItem(STORAGE_KEY); return raw ? sanitizeState(JSON.parse(raw)) : DEFAULT_STATE; } catch { return DEFAULT_STATE; } } export function AddToPlanControl({ recipeId, recipeTitle }: { recipeId: string; recipeTitle: string }) { const [open, setOpen] = useState(false); const [plan, setPlan] = useState(DEFAULT_STATE); const [addedLabel, setAddedLabel] = useState(null); const dialogRef = useRef(null); useEffect(() => { const dialog = dialogRef.current; if (!dialog) return; if (open && !dialog.open) dialog.showModal(); if (!open && dialog.open) dialog.close(); return () => { if (dialog.open) dialog.close(); }; }, [open]); function assignSlot(day: number, meal: number) { const latest = readPlan(); const key = slotKey(day, meal); const updated: MealPlanState = { ...latest, slots: { ...latest.slots, [key]: recipeId }, }; try { window.localStorage.setItem(STORAGE_KEY, JSON.stringify(updated)); setPlan(updated); setAddedLabel(`${DAY_NAMES[day]} ยท ${mealLabel(meal)}`); setOpen(false); } catch { // Blocked storage } } const meals = visibleMeals(plan.mealsPerDay); return (
{addedLabel && ( Added to {addedLabel} Open planner )} setOpen(false)} onClick={(e) => e.target === dialogRef.current && setOpen(false)} aria-labelledby="add-to-plan-title" className="m-0 mt-auto max-h-[85dvh] w-full max-w-none overflow-y-auto rounded-t-3xl border border-line bg-surface p-0 text-ink shadow-2xl sm:m-auto sm:max-w-lg sm:rounded-3xl" >

Assign slot

Add “{recipeTitle}”

{Array.from({ length: plan.daysCount }, (_, day) => (

{DAY_NAMES[day]}

{meals.map((meal) => { const key = slotKey(day, meal); const existingId = plan.slots[key]; const existingTitle = existingId ? RECIPES_BY_ID.get(existingId)?.title : null; const isSame = existingId === recipeId; return ( ); })}
))}
); }