From 737d011c1be31189dc4939a3502f63cec1db9679 Mon Sep 17 00:00:00 2001 From: Arnaud Date: Thu, 2 Jul 2026 15:25:09 +0200 Subject: [PATCH] fix: translate remaining pantry UI (print button, manager, print page) pantry-page-header's Print button, the pantry-manager add/remove form (item name, qty, unit, expiry badges), and the print/pantry page (title, column headers, item count, empty state, footer) were all hardcoded English. Co-Authored-By: Claude Sonnet 5 --- apps/web/app/print/pantry/page.tsx | 18 ++++++++------- .../components/meal-plan/pantry-manager.tsx | 22 ++++++++++--------- .../components/pantry/pantry-page-header.tsx | 3 ++- apps/web/messages/en.json | 19 +++++++++++++++- apps/web/messages/fr.json | 19 +++++++++++++++- 5 files changed, 60 insertions(+), 21 deletions(-) diff --git a/apps/web/app/print/pantry/page.tsx b/apps/web/app/print/pantry/page.tsx index cb12172..30a745e 100644 --- a/apps/web/app/print/pantry/page.tsx +++ b/apps/web/app/print/pantry/page.tsx @@ -2,10 +2,12 @@ import { headers } from "next/headers"; import { auth } from "@/lib/auth/server"; import { db, pantryItems, eq, asc } from "@epicure/db"; import { PrintTrigger } from "@/components/recipe/print-trigger"; +import { getMessages, formatMessage } from "@/lib/i18n/server"; export default async function PantryPrintPage() { const session = await auth.api.getSession({ headers: await headers() }); if (!session) return null; + const m = getMessages((session.user as { locale?: string }).locale); const items = await db.query.pantryItems.findMany({ where: eq(pantryItems.userId, session.user.id), @@ -49,18 +51,18 @@ export default async function PantryPrintPage() { -

Pantry

-

{items.length} item{items.length !== 1 ? "s" : ""}

+

{m.pantry.title}

+

{formatMessage(items.length === 1 ? m.pantry.printItemCountSingular : m.pantry.printItemCountPlural, { count: items.length })}

{items.length === 0 ? ( -

No items in pantry.

+

{m.pantry.noItems}

) : ( - - - + + + @@ -75,7 +77,7 @@ export default async function PantryPrintPage() { @@ -86,7 +88,7 @@ export default async function PantryPrintPage() {
ItemQuantityExpires{m.pantry.colItem}{m.pantry.colQuantity}{m.pantry.colExpires}
{exp ? daysLeft !== null && daysLeft < 0 - ? `Expired ${Math.abs(daysLeft)}d ago` + ? formatMessage(m.pantry.expiredDaysAgo, { days: Math.abs(daysLeft) }) : exp.toLocaleDateString("en", { month: "short", day: "numeric", year: "numeric" }) : "—"}
)} -
Printed from Epicure
+
{m.print.footer}
); } diff --git a/apps/web/components/meal-plan/pantry-manager.tsx b/apps/web/components/meal-plan/pantry-manager.tsx index e74492a..1e75025 100644 --- a/apps/web/components/meal-plan/pantry-manager.tsx +++ b/apps/web/components/meal-plan/pantry-manager.tsx @@ -1,6 +1,7 @@ "use client"; import { useState } from "react"; +import { useTranslations } from "next-intl"; import { Plus, Trash2, AlertTriangle } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; @@ -20,6 +21,7 @@ function daysUntilExpiry(dateStr: string): number { } export function PantryManager({ initialItems }: { initialItems: PantryItem[] }) { + const t = useTranslations("pantry"); const [items, setItems] = useState(initialItems); const [name, setName] = useState(""); const [quantity, setQuantity] = useState(""); @@ -41,7 +43,7 @@ export function PantryManager({ initialItems }: { initialItems: PantryItem[] }) expiresAt: expiresAt ? new Date(expiresAt).toISOString() : undefined, }), }); - if (!res.ok) { toast.error("Failed to add"); return; } + if (!res.ok) { toast.error(t("addFailed")); return; } const { id } = await res.json() as { id: string }; setItems((prev) => [...prev, { id, rawName: name.trim(), quantity: quantity || null, unit: unit || null, expiresAt: expiresAt ? new Date(expiresAt).toISOString() : null }]); setName(""); setQuantity(""); setUnit(""); setExpiresAt(""); @@ -53,7 +55,7 @@ export function PantryManager({ initialItems }: { initialItems: PantryItem[] }) async function remove(id: string) { const res = await fetch(`/api/v1/pantry/${id}`, { method: "DELETE" }); if (res.ok) setItems((prev) => prev.filter((i) => i.id !== id)); - else toast.error("Failed to remove"); + else toast.error(t("removeFailed")); } const sorted = [...items].sort((a, b) => { @@ -67,18 +69,18 @@ export function PantryManager({ initialItems }: { initialItems: PantryItem[] })
{/* Add form */}
- setName(e.target.value)} placeholder="Item name" className="flex-1 min-w-[160px]" onKeyDown={(e) => e.key === "Enter" && add()} /> - setQuantity(e.target.value)} placeholder="Qty" className="w-20" /> - setUnit(e.target.value)} placeholder="Unit" className="w-20" /> + setName(e.target.value)} placeholder={t("itemNamePlaceholder")} className="flex-1 min-w-[160px]" onKeyDown={(e) => e.key === "Enter" && add()} /> + setQuantity(e.target.value)} placeholder={t("qtyPlaceholder")} className="w-20" /> + setUnit(e.target.value)} placeholder={t("unitPlaceholder")} className="w-20" /> setExpiresAt(e.target.value)} className="w-36" />
{/* Item list */} {items.length === 0 ? ( -

No pantry items yet.

+

{t("empty")}

) : (
{sorted.map((item) => { @@ -91,11 +93,11 @@ export function PantryManager({ initialItems }: { initialItems: PantryItem[] })
{item.rawName} {item.quantity && {item.quantity}{item.unit ? ` ${item.unit}` : ""}} - {expired && Expired} - {expiring && !expired && Expires in {days}d} + {expired && {t("expired")}} + {expiring && !expired && {t("expiresInDays", { days })}}
{item.expiresAt && !expired && !expiring && ( -

Expires {new Date(item.expiresAt).toLocaleDateString()}

+

{t("expiresOn", { date: new Date(item.expiresAt).toLocaleDateString() })}

)}