Files
Epicure/apps/web/app/print/pantry/page.tsx
T
2026-07-01 11:10:37 +02:00

93 lines
3.3 KiB
TypeScript

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";
export default async function PantryPrintPage() {
const session = await auth.api.getSession({ headers: await headers() });
if (!session) return null;
const items = await db.query.pantryItems.findMany({
where: eq(pantryItems.userId, session.user.id),
orderBy: asc(pantryItems.rawName),
});
const now = new Date();
return (
<>
<style>{`
@media print {
body { margin: 0; }
.no-print { display: none !important; }
}
body {
font-family: system-ui, sans-serif;
color: #1a1a1a;
max-width: 680px;
margin: 40px auto;
padding: 0 24px;
font-size: 14px;
line-height: 1.6;
}
h1 { font-size: 1.8em; margin: 0 0 4px; }
.subtitle { color: #666; font-size: 0.9em; margin-bottom: 24px; }
table { width: 100%; border-collapse: collapse; }
th { text-align: left; font-size: 0.8em; text-transform: uppercase; letter-spacing: 0.06em; color: #888; padding: 4px 8px 4px 0; border-bottom: 1px solid #ccc; }
td { padding: 6px 8px 6px 0; border-bottom: 1px dotted #eee; font-size: 0.9em; vertical-align: top; }
tr:last-child td { border-bottom: none; }
.expiry-soon { color: #b45309; }
.expiry-expired { color: #dc2626; }
footer { margin-top: 40px; font-size: 0.75em; color: #aaa; text-align: center; }
.print-btn {
position: fixed; top: 16px; right: 16px; padding: 8px 16px;
background: #18181b; color: white; border: none; border-radius: 6px;
cursor: pointer; font-size: 13px;
}
.print-btn:hover { background: #3f3f46; }
`}</style>
<PrintTrigger />
<h1>Pantry</h1>
<p className="subtitle">{items.length} item{items.length !== 1 ? "s" : ""}</p>
{items.length === 0 ? (
<p style={{ color: "#888" }}>No items in pantry.</p>
) : (
<table>
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Expires</th>
</tr>
</thead>
<tbody>
{items.map((item) => {
const exp = item.expiresAt ? new Date(item.expiresAt) : null;
const daysLeft = exp ? Math.ceil((exp.getTime() - now.getTime()) / 86400000) : null;
const expiryClass = daysLeft === null ? "" : daysLeft < 0 ? "expiry-expired" : daysLeft <= 3 ? "expiry-soon" : "";
return (
<tr key={item.id}>
<td>{item.rawName}</td>
<td>{[item.quantity, item.unit].filter(Boolean).join(" ") || "—"}</td>
<td className={expiryClass}>
{exp
? daysLeft !== null && daysLeft < 0
? `Expired ${Math.abs(daysLeft)}d ago`
: exp.toLocaleDateString("en", { month: "short", day: "numeric", year: "numeric" })
: "—"}
</td>
</tr>
);
})}
</tbody>
</table>
)}
<footer>Printed from Epicure</footer>
</>
);
}