diff --git a/src/app/(inbox)/thread/[threadId]/page.tsx b/src/app/(inbox)/thread/[threadId]/page.tsx index 64bf97a..b64f978 100644 --- a/src/app/(inbox)/thread/[threadId]/page.tsx +++ b/src/app/(inbox)/thread/[threadId]/page.tsx @@ -1,5 +1,6 @@ import { getSession, getAccountId, getThreadEmails } from "@/lib/jmap"; import { notFound } from "next/navigation"; +import Link from "next/link"; import MobileBackButton from "@/components/MobileBackButton"; import EmailDetailView from "@/components/EmailDetailView"; import ThreadView from "@/components/ThreadView"; @@ -47,9 +48,18 @@ export default async function ThreadPage({ params }: Props) {
-

- {subject} -

+
+

+ {subject} +

+ + Print + +
diff --git a/src/app/globals.css b/src/app/globals.css index bf9ff95..254c6aa 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -8,3 +8,9 @@ :root { color-scheme: light dark; } + +@media print { + /* Allow content to expand to full height for printing */ + html, body { height: auto !important; overflow: visible !important; } + body > div, main { height: auto !important; overflow: visible !important; } +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index dcd9fea..8318432 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -32,7 +32,7 @@ export default async function RootLayout({ {/* Row: desktop sidebar + main content */}
{/* Sidebar — desktop only */} -
{/* Mobile bottom nav — hidden on desktop */} - +
); diff --git a/src/app/print/[id]/page.tsx b/src/app/print/[id]/page.tsx new file mode 100644 index 0000000..1d151eb --- /dev/null +++ b/src/app/print/[id]/page.tsx @@ -0,0 +1,67 @@ +import { getSession, getAccountId, getEmail } from "@/lib/jmap"; +import { formatAddressList, formatFullDate } from "@/lib/format"; +import { notFound } from "next/navigation"; +import PrintControls from "@/components/PrintControls"; +import { resolvePrintBody } from "@/lib/printHtml"; + +export const dynamic = "force-dynamic"; + +interface Props { + params: Promise<{ id: string }>; +} + +export default async function PrintPage({ params }: Props) { + const { id } = await params; + const session = await getSession(); + const accountId = getAccountId(session); + const email = await getEmail(session.apiUrl, accountId, id); + if (!email) return notFound(); + + const { bodyHtml, emailStyles, bodyType } = resolvePrintBody(email); + const subject = email.subject || "(no subject)"; + + return ( +
+ + +
+

+ {subject} +

+ +
+
From
+
{formatAddressList(email.from)}
+ {email.to && email.to.length > 0 && ( + <> +
To
+
{formatAddressList(email.to)}
+ + )} + {email.cc && email.cc.length > 0 && ( + <> +
Cc
+
{formatAddressList(email.cc)}
+ + )} +
Date
+
{formatFullDate(email.receivedAt)}
+
+ + {emailStyles &&