docs: report builder design spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
# Report Builder — Design Spec
|
||||
**Date:** 2026-04-28
|
||||
**Status:** Approved
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
A dedicated `/report` page (admin-only) where users configure a client-facing PDF report from scratch. The report is a professional business document — no app interface visible — downloadable as a `.pdf` file via `@react-pdf/renderer`.
|
||||
|
||||
---
|
||||
|
||||
## Page Structure
|
||||
|
||||
Two-column layout on desktop, stacked on mobile:
|
||||
- **Left panel (form):** all configuration fields, grouped into sections
|
||||
- **Right panel:** a static document preview mockup (not a live render — too expensive). Shows real text fields (title, client name, period) updating in real time, but charts and metrics are represented as grey placeholder shapes. Gives the user a sense of page structure and section order.
|
||||
- **Footer bar:** "Generate PDF" button (triggers download), estimated page count
|
||||
|
||||
The route is `/report`, protected the same way `/settings` is (admin only, via `userRole === 'admin'` check in `App.tsx`).
|
||||
|
||||
---
|
||||
|
||||
## Form Sections
|
||||
|
||||
### 1. Client Info
|
||||
| Field | Type | Notes |
|
||||
|---|---|---|
|
||||
| Report title | Text input | e.g. "Q1 2025 Visitor Performance" |
|
||||
| Prepared for (company) | Text input | Shown in report header |
|
||||
| Contact name | Text input | Optional — "Attention: …" line |
|
||||
| Client logo | File upload (PNG/JPG/SVG, max 2MB) | Base64-encoded, embedded in PDF header |
|
||||
| Accent color | Color picker | Defaults to HiHala blue `#2563eb`; used for section headers, borders |
|
||||
|
||||
### 2. Data Selection
|
||||
| Field | Type | Notes |
|
||||
|---|---|---|
|
||||
| Period start / end | Date inputs | Defaults to current month |
|
||||
| Museums | Multi-select (same component as dashboard) | Empty = all |
|
||||
| Channels | Multi-select | Empty = all |
|
||||
| VAT | Toggle: Excl / Incl | Defaults to Incl |
|
||||
| Include comparison | Checkbox | Adds previous-year column to metrics table |
|
||||
|
||||
### 3. Content Sections (toggleable)
|
||||
Each is a checkbox, all on by default:
|
||||
- Executive summary (3–4 sentences auto-generated from numbers)
|
||||
- Key metrics table (Revenue, Visitors, Tickets, Avg Rev/Visitor, optionally Pilgrim Capture Rate)
|
||||
- Revenue & visitor trend chart
|
||||
- Breakdown by museum
|
||||
- Breakdown by channel
|
||||
- Pilgrim capture rate section (only shown if toggle is on AND data exists)
|
||||
|
||||
### 4. Presentation
|
||||
| Field | Type | Notes |
|
||||
|---|---|---|
|
||||
| Language | Toggle: EN / AR | Controls all PDF text and direction |
|
||||
| Confidentiality footer | Select: Confidential / Internal / Public | Shown in page footer |
|
||||
| Page orientation | Toggle: Portrait / Landscape | Portrait default |
|
||||
|
||||
---
|
||||
|
||||
## PDF Document Design
|
||||
|
||||
Built with `@react-pdf/renderer`. All layout is code — no DOM capture, no html2canvas.
|
||||
|
||||
**Page 1 — Cover**
|
||||
- HiHala logo (top-left) + client logo (top-right)
|
||||
- Large report title
|
||||
- "Prepared for: [Company]" / "Attention: [Contact]"
|
||||
- Period label (e.g. "January – March 2025")
|
||||
- Generation date
|
||||
- Accent color bar at bottom
|
||||
|
||||
**Page 2+ — Content pages**
|
||||
- Shared header: small HiHala wordmark + report title + page number
|
||||
- Sections in the order the user toggled them on
|
||||
- Each section starts with a colored heading bar (accent color)
|
||||
- Confidentiality level in page footer
|
||||
|
||||
**Chart rendering:**
|
||||
Charts do not use the live Chart.js instances. Instead, `@react-pdf/renderer` draws simplified chart equivalents natively using SVG primitives (`<Svg>`, `<Rect>`, `<Path>`, `<Line>`) — no canvas capture needed. This produces crisp vector output at any print resolution.
|
||||
|
||||
Simplified charts to implement:
|
||||
- **Trend line chart:** SVG polyline over a grid
|
||||
- **Bar chart (museum/channel breakdown):** horizontal SVG bars with labels
|
||||
|
||||
**Executive summary generation:**
|
||||
Computed from the metrics — a template string filled with actual numbers. Example (EN):
|
||||
> "During [period], [selected museums] recorded [X] visitors and [Y SAR] in revenue, representing a [Z%] change versus the same period last year. The top-performing channel was [channel] with [N%] of total tickets."
|
||||
|
||||
The same template exists in Arabic (stored in the locale file alongside EN/AR strings already in the codebase). Falls back gracefully if comparison data is absent (omits the change sentence).
|
||||
|
||||
---
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
/report page
|
||||
→ user fills form
|
||||
→ clicks "Generate PDF"
|
||||
→ reads filtered data from already-loaded app state (passed as prop from App.tsx)
|
||||
OR re-fetches if needed (dataService.fetchData())
|
||||
→ applies period + museum + channel filters client-side
|
||||
→ computes metrics (reuses existing calculateMetrics())
|
||||
→ passes computed values to <ReportDocument /> (react-pdf component)
|
||||
→ pdf.download('hihala-report.pdf')
|
||||
```
|
||||
|
||||
No new API endpoints required. All computation is client-side using existing `dataService` functions.
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
src/
|
||||
components/
|
||||
Report/
|
||||
index.tsx — the /report page (form + preview layout)
|
||||
ReportForm.tsx — the left-panel form
|
||||
ReportPreview.tsx — the right-panel static mockup
|
||||
ReportDocument.tsx — the @react-pdf/renderer document
|
||||
reportCharts.tsx — SVG chart primitives for PDF
|
||||
reportHelpers.ts — executive summary generator, data filters
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Navigation
|
||||
|
||||
- Desktop nav: gear icon already links to `/settings`; add a "Report" link (document icon) next to it, admin-only
|
||||
- Mobile bottom nav: add Report icon between Comparison and Settings
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `@react-pdf/renderer` — PDF generation
|
||||
- No other new dependencies (reuses existing AltMultiSelect, form inputs, data service)
|
||||
|
||||
---
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- Scheduled / emailed reports
|
||||
- Saving report configurations
|
||||
- Non-admin users generating reports
|
||||
- Live chart preview in the right panel (static mockup only)
|
||||
Reference in New Issue
Block a user