import type { Metadata } from "next"; import { notFound } from "next/navigation"; import { headers } from "next/headers"; import Link from "next/link"; import { Globe } from "lucide-react"; import { auth } from "@/lib/auth/server"; import { db, mealPlans, eq, and } from "@epicure/db"; import { buttonVariants } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { getMessages, formatMessage } from "@/lib/i18n/server"; type Params = { params: Promise<{ id: string }> }; const DAY_ORDER = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"] as const; const MEAL_ORDER = ["breakfast", "lunch", "dinner", "snack"] as const; export async function generateMetadata({ params }: Params): Promise { const { id } = await params; const plan = await db.query.mealPlans.findFirst({ where: and(eq(mealPlans.id, id), eq(mealPlans.isPublic, true)), }); if (!plan) return {}; return { title: `Week of ${plan.weekStart}` }; } export default async function PublicMealPlanPage({ params }: Params) { const { id } = await params; const session = await auth.api.getSession({ headers: await headers() }).catch(() => null); const m = getMessages((session?.user as { locale?: string } | undefined)?.locale); const plan = await db.query.mealPlans.findFirst({ where: and(eq(mealPlans.id, id), eq(mealPlans.isPublic, true)), with: { entries: { with: { recipe: { columns: { id: true, title: true, visibility: true } } }, }, }, }); if (!plan) notFound(); const byDay = plan.entries.reduce>((acc, entry) => { (acc[entry.day] ??= []).push(entry); return acc; }, {}); return (
{m.mealPlan.publicLinkReadOnlyDescription} {!session && (
{m.publicRecipe.signUpFree} {m.publicRecipe.logIn}
)}

{formatMessage(m.mealPlan.weekOf, { date: plan.weekStart })}

{DAY_ORDER.filter((day) => byDay[day]?.length).map((day) => (

{m.mealPlan.days[day]}

    {[...byDay[day]!] .sort((a, b) => MEAL_ORDER.indexOf(a.mealType) - MEAL_ORDER.indexOf(b.mealType)) .map((entry) => (
  • {m.mealPlan.meals[entry.mealType]} {entry.recipe && (entry.recipe.visibility === "public" || entry.recipe.visibility === "unlisted") ? ( {entry.recipe.title} ) : ( {entry.recipe?.title ?? entry.note ?? "—"} )}
  • ))}
))} {plan.entries.length === 0 && (

{m.mealPlan.noEntriesPublic}

)}
{!session && (

{m.publicRecipe.wantToSaveDescription}

{m.publicRecipe.getStartedFree}
)}
); }