Files
hihala-dashboard/docs/superpowers/specs/2026-04-28-report-builder-design.md
T
fahed 64955f0f51 docs: report builder design spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 14:20:07 +03:00

5.5 KiB
Raw Blame History

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 (34 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)