Skip to content

feat: add print/PDF export for character sheets and campaign party#77

Closed
lionel-lints wants to merge 1 commit into
igor47:mainfrom
lionel-lints:feat/character-print-export
Closed

feat: add print/PDF export for character sheets and campaign party#77
lionel-lints wants to merge 1 commit into
igor47:mainfrom
lionel-lints:feat/character-print-export

Conversation

@lionel-lints

Copy link
Copy Markdown
Contributor

Summary

  • Adds GET /characters/:id/print — a standalone, print-optimized character sheet accessible to both the character owner and any DM of a campaign containing the character
  • Adds GET /campaigns/:id/print — a DM-only route that prints all party characters back-to-back with a cover page listing the party
  • Adds Print button to the character sheet and Print All button (DM-only) to the campaign view, both opening in a new tab

How it works

Uses the browser's built-in print dialog (Ctrl+P → Save as PDF) — zero new runtime dependencies. The print route returns a standalone <html> document via c.html(), bypassing the app's jsxRenderer layout. It auto-triggers window.print() on load.

The character sheet uses a two-column grid layout:

  • Left (~40%): ability scores (3×2 grid with modifier + score circle), saving throws, skills with proficiency dots
  • Right (~60%): AC / Initiative / Speed, current & max HP, hit dice, attacks & weapons, equipment, coins
  • Page 2 (forced page break): traits & features in a 2-column flow, spells section (rendered only if the character has spells)

The visual style extends the app's existing aesthetic — clean bordered boxes, minimal typography — translated to print-optimized CSS with @page { size: letter portrait; margin: 0.5in; }. A screen preview mode wraps the sheet in a gray background so it looks like a real page at 8.5in width.

Bug fix: Bun.sql database URL parsing

Fixes a bug in src/db.ts where Bun.sql 1.3.1 silently ignores the database name in a PostgreSQL connection URL, connecting to the default postgres database instead of csheet_dev. Switched from the URL string form to the options object form (new SQL({ hostname, port, username, password, database })).

Test plan

  • Navigate to a character sheet and click Print — new tab opens with the print-optimized sheet, window.print() fires automatically
  • Verify two-column layout on page 1, traits/spells on page 2
  • Open browser print dialog (Cmd+P) and confirm the action bar is hidden in print preview
  • As a DM, navigate to a campaign and click Print All — all party character sheets render back-to-back with a cover page
  • Confirm non-DM members cannot access /campaigns/:id/print (redirected)
  • mise run test src/routes/character.test.ts — 44 tests pass
  • mise run test src/routes/campaigns.test.ts — 115 tests pass

🤖 Generated with Claude Code

Adds browser-native print-to-PDF export:
- GET /characters/:id/print — standalone multi-column character sheet (owner + DM)
- GET /campaigns/:id/print — DM-only full party export with cover page

The print layout uses a two-column grid (abilities/skills left, combat/HP/weapons/items right) with a second page for traits and spells. Zero new runtime dependencies — uses the browser's built-in print dialog.

Also fixes a Bun.sql 1.3.1 bug where a PostgreSQL connection URL was silently ignored in favor of the default 'postgres' database; switching to the options object form resolves the issue.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@igor47

igor47 commented May 26, 2026

Copy link
Copy Markdown
Owner

Fixes a bug in src/db.ts where Bun.sql 1.3.1 silently ignores the database name in a PostgreSQL connection URL, connecting to the default postgres database instead of csheet_dev. Switched from the URL string form to the options object form (new SQL({ hostname, port, username, password, database })).

i haven't been able to reproduce this -- any additional information about it?

@igor47

igor47 commented May 26, 2026

Copy link
Copy Markdown
Owner

Closing in favor of #78, which takes a different approach — generating PDFs server-side by filling MPMB's official D&D character record sheet template rather than rendering HTML and relying on the browser's print dialog. The HTML approach had hard layout issues in print mode (forced page breaks with whitespace, two-column grid not balancing) and created a parallel design system to maintain.

Thanks for the original work, @lionel-lints — your PR was the inspiration for #78. Your commit is preserved as the first commit on the new branch for credit.

@igor47 igor47 closed this May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants