docs: add implementation plan for page1 header restyle

This commit is contained in:
2026-03-20 16:39:26 +01:00
parent c72670edee
commit 3636676dbc

View File

@@ -0,0 +1,303 @@
# Page 1 Header Restyle & Label Fixes — Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Redesign l'header di pagina 1 (titolo centrato + box Tipologia/Data/Bid/Ask uniformi), rinominare colonne nelle tabelle Sottostanti ed Eventi, e fixare lo spazio nel footer branding.
**Architecture:** Modifiche localizzate a 3 file esistenti. Nessuna nuova classe o interfaccia. Le nuove costanti colore/brush vengono aggiunte a `PdfTheme.cs` seguendo il pattern `=>` già usato nel file. Il nuovo `DrawTitle` in `AnagraficaSectionRenderer` è una riscrittura completa del metodo esistente.
**Tech Stack:** C# / ASP.NET Core 8, Syncfusion PDF v33, Syncfusion.Drawing
---
## File map
| File | Modifica |
|------|----------|
| `CertReports.Syncfusion/Helpers/PdfTheme.cs` | Aggiungi 6 colori + 5 brush (stile `=>`) + fix footer offset (+2pt) |
| `CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs` | Riscrivi `DrawTitle`, aggiungi `DrawInfoBox`, rinomina headers sottostanti |
| `CertReports.Syncfusion/Services/Implementations/EventiSectionRenderer.cs` | Rinomina "Trigger CPN" → "Trigger Cedola" |
---
## Task 1: Nuovi colori e fix footer in PdfTheme.cs
**Files:**
- Modify: `CertReports.Syncfusion/Helpers/PdfTheme.cs`
- [ ] **Step 1: Aggiungi nuove costanti colore**
Inserisci dopo la riga `public static readonly Color TableAltRow = ...` (blocco colori, riga ~33):
```csharp
// Colori box header pagina 1
public static readonly Color AccentBlueDark = Color.FromArgb(255, 13, 71, 161); // #0D47A1
public static readonly Color BoxLightBlueBg = Color.FromArgb(255, 235, 242, 251); // #EBF2FB
public static readonly Color BoxGrayBg = Color.FromArgb(255, 245, 245, 245); // #F5F5F5
public static readonly Color BoxGrayAccent = Color.FromArgb(255, 136, 136, 136); // #888888
public static readonly Color BoxGrayLabel = Color.FromArgb(255, 102, 102, 102); // #666666
public static readonly Color BoxGrayValue = Color.FromArgb(255, 51, 51, 51); // #333333
```
- [ ] **Step 2: Aggiungi i brush corrispondenti — usa il pattern `=>` come il resto del file**
Inserisci dopo la riga `public static PdfPen AccentBluePen => ...` (blocco Brushes, riga ~86):
```csharp
public static PdfBrush AccentBlueDarkBrush => new PdfSolidBrush(AccentBlueDark);
public static PdfBrush BoxLightBlueBgBrush => new PdfSolidBrush(BoxLightBlueBg);
public static PdfBrush BoxGrayBgBrush => new PdfSolidBrush(BoxGrayBg);
public static PdfBrush BoxGrayAccentBrush => new PdfSolidBrush(BoxGrayAccent);
public static PdfBrush BoxGrayLabelBrush => new PdfSolidBrush(BoxGrayLabel);
public static PdfBrush BoxGrayValueBrush => new PdfSolidBrush(BoxGrayValue);
```
- [ ] **Step 3: Fix footer — cambia solo l'argomento `PointF` in `DrawTextWebLink` (riga ~203)**
```csharp
// PRIMA:
webLink.DrawTextWebLink(g, new PointF(prefixWidth, footerY));
// DOPO:
webLink.DrawTextWebLink(g, new PointF(prefixWidth + 2f, footerY));
```
> Il `DrawString` del testo prefisso (riga ~193) usa già `prefixWidth + 2f` come larghezza del `RectangleF` — questo fix allinea solo il punto di partenza del link.
- [ ] **Step 4: Build**
```bash
dotnet build CertReports.Syncfusion/CertReports.Syncfusion.csproj
```
Atteso: `Build succeeded` senza errori.
- [ ] **Step 5: Commit**
```bash
git add CertReports.Syncfusion/Helpers/PdfTheme.cs
git commit -m "feat: add box header colors/brushes and fix footer branding offset"
```
---
## Task 2: Riscrittura DrawTitle in AnagraficaSectionRenderer.cs
**Files:**
- Modify: `CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs`
Il metodo `DrawTitle` (righe 74-112) viene sostituito interamente. Si aggiunge il metodo privato `DrawInfoBox`.
**Layout:**
```
Scheda Prodotto XS1234567890 ← centrato, AccentBlue, SectionTitleFont
───────────────────────────────────────── ← AccentBluePen
[TIPOLOGIA / Cert. Bonus Cap] [DATA / 18/03] [BID / 98.50] [ASK / 99.20]
```
**Dimensioni box:**
- Altezza: `28f`; Gap: `6f`; Larghezza Data: `84f`, Bid: `70f`, Ask: `70f`
- `tipW` calcolato dinamicamente (vedi DrawTitle)
- Bordo sinistro accent: `4f`; Padding: `6f` sx, `4f` dx
- Label: `PdfTheme.Small` (6.5pt) a `y + 4f`
- Valore Bid/Ask/Data: `PdfTheme.Bold` (8pt bold) a `y + 14f`
- Valore Tipologia: `PdfTheme.Bold` (8pt bold) a `y + 14f` — testo più lungo, dimensione coerente con gli altri box
- [ ] **Step 1: Aggiungi il metodo `DrawInfoBox` alla classe (prima di `DrawCaratteristiche`)**
```csharp
private void DrawInfoBox(
PdfGraphics g,
float x, float y, float w, float boxH,
string label, string value,
PdfBrush bgBrush, PdfBrush accentBrush,
PdfBrush labelBrush, PdfBrush valueBrush,
PdfFont valueFont)
{
g.DrawRectangle(bgBrush, new RectangleF(x, y, w, boxH));
g.DrawRectangle(accentBrush, new RectangleF(x, y, 4f, boxH));
float innerX = x + 4f + 6f;
float innerW = w - 4f - 6f - 4f;
g.DrawString(label, PdfTheme.Small, labelBrush,
new RectangleF(innerX, y + 4f, innerW, 10f));
g.DrawString(value, valueFont, valueBrush,
new RectangleF(innerX, y + 14f, innerW, 14f));
}
```
> **Nota Syncfusion:** `RectangleF` non supporta named arguments — sempre forma posizionale `new RectangleF(x, y, w, h)`.
- [ ] **Step 2: Sostituisci il metodo `DrawTitle` (righe 74-112) con la nuova implementazione**
```csharp
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y)
{
// ── Titolo centrato ──────────────────────────────────────────
g.DrawString($"Scheda Prodotto {info.Isin}",
PdfTheme.SectionTitleFont,
new PdfSolidBrush(PdfTheme.AccentBlue),
new RectangleF(0, y, w, 20f),
new PdfStringFormat(PdfTextAlignment.Center));
y += 24f;
// Linea separatrice blu
g.DrawLine(PdfTheme.AccentBluePen, 0, y, w, y);
y += 8f;
// ── Riga box: Tipologia | Data | Bid | Ask ───────────────────
const float boxH = 28f;
const float gap = 6f;
const float dataW = 84f;
const float bidW = 70f;
const float askW = 70f;
bool showTip = !string.IsNullOrEmpty(info.Categoria);
bool showData = !string.IsNullOrEmpty(info.LastPriceDate);
bool showBidAsk = !string.IsNullOrEmpty(info.Bid) && !string.IsNullOrEmpty(info.Ask);
// Calcolo dinamico larghezza Tipologia in base ai box presenti
int nBoxes = (showTip ? 1 : 0) + (showData ? 1 : 0) + (showBidAsk ? 2 : 0);
float totalGaps = Math.Max(0, nBoxes - 1) * gap;
float fixedW = (showData ? dataW : 0f) + (showBidAsk ? bidW + askW : 0f);
float tipW = showTip ? (w - totalGaps - fixedW) : 0f;
float xCursor = 0f;
if (showTip)
{
DrawInfoBox(g, xCursor, y, tipW, boxH,
"TIPOLOGIA", info.Categoria,
PdfTheme.BoxLightBlueBgBrush, PdfTheme.AccentBlueBrush,
PdfTheme.AccentBlueBrush, PdfTheme.AccentBlueDarkBrush,
PdfTheme.Bold);
xCursor += tipW + gap;
}
if (showData)
{
DrawInfoBox(g, xCursor, y, dataW, boxH,
"DATA", info.LastPriceDate,
PdfTheme.BoxGrayBgBrush, PdfTheme.BoxGrayAccentBrush,
PdfTheme.BoxGrayLabelBrush, PdfTheme.BoxGrayValueBrush,
PdfTheme.Bold);
xCursor += dataW + gap;
}
if (showBidAsk)
{
DrawInfoBox(g, xCursor, y, bidW, boxH,
"BID", info.Bid,
PdfTheme.BoxLightBlueBgBrush, PdfTheme.AccentBlueBrush,
PdfTheme.AccentBlueBrush, PdfTheme.AccentBlueDarkBrush,
PdfTheme.Bold);
xCursor += bidW + gap;
DrawInfoBox(g, xCursor, y, askW, boxH,
"ASK", info.Ask,
PdfTheme.BoxLightBlueBgBrush, PdfTheme.AccentBlueBrush,
PdfTheme.AccentBlueBrush, PdfTheme.AccentBlueDarkBrush,
PdfTheme.Bold);
}
y += boxH + 10f;
return y;
}
```
- [ ] **Step 3: Build**
```bash
dotnet build CertReports.Syncfusion/CertReports.Syncfusion.csproj
```
Atteso: `Build succeeded`.
- [ ] **Step 4: Verifica visiva**
Avvia il progetto e apri nel browser:
```
https://localhost:{porta}/api/report/by-isin/{ISIN_VALIDO}
```
Controlla che la pagina 1 mostri: titolo centrato + linea + riga box con altezze uniformi.
Con `?branding=true` verifica che "Powered by Smart Roots" abbia lo spazio corretto tra "by" e il link.
- [ ] **Step 5: Commit**
```bash
git add CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs
git commit -m "feat: redesign page1 header - centered title, info boxes row (Tipologia/Data/Bid/Ask)"
```
---
## Task 3: Rinomina colonne tabella Sottostanti
**Files:**
- Modify: `CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs` (metodo `DrawSottostanti`, riga ~338)
- [ ] **Step 1: Aggiorna l'array `headers` in `DrawSottostanti`**
```csharp
// PRIMA:
string[] headers = { "Nome", "Strike", "Last", "% Perf.", "Barr.K",
"Buffer K", "Trig.CPN", "Buf.CPN", "Trig.AC" };
// DOPO:
string[] headers = { "Nome", "Strike", "Last", "% Perf.", "Barriera Capitale",
"Buffer Capitale", "Trigger Cedola", "Buffer Cedola", "Trig.AC" };
```
- [ ] **Step 2: Build**
```bash
dotnet build CertReports.Syncfusion/CertReports.Syncfusion.csproj
```
- [ ] **Step 3: Commit**
```bash
git add CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs
git commit -m "fix: rename sottostanti column headers (Barriera/Buffer/Trigger Cedola)"
```
---
## Task 4: Rinomina colonna tabella Eventi
**Files:**
- Modify: `CertReports.Syncfusion/Services/Implementations/EventiSectionRenderer.cs` (riga ~45)
- [ ] **Step 1: Aggiorna l'array `headers` in `EventiSectionRenderer.Render`**
```csharp
// PRIMA:
"Trigger CPN", "Cedola %", "Pagato", "Memoria",
// DOPO:
"Trigger Cedola", "Cedola %", "Pagato", "Memoria",
```
- [ ] **Step 2: Build**
```bash
dotnet build CertReports.Syncfusion/CertReports.Syncfusion.csproj
```
- [ ] **Step 3: Commit**
```bash
git add CertReports.Syncfusion/Services/Implementations/EventiSectionRenderer.cs
git commit -m "fix: rename eventi column Trigger CPN -> Trigger Cedola"
```
---
## Verifica finale
- [ ] Avvia il server: `dotnet run --project CertReports.Syncfusion`
- [ ] Apri report con un ISIN valido, verifica pagina 1:
- Titolo "Scheda Prodotto {ISIN}" centrato in blu
- Linea separatrice blu
- Box Tipologia / Data / Bid / Ask sulla stessa riga, stessa altezza (28pt)
- Box Tipologia si estende per occupare lo spazio residuo
- [ ] Verifica tabella Sottostanti: header con "Barriera Capitale", "Buffer Capitale", "Trigger Cedola", "Buffer Cedola"
- [ ] Verifica sezione Eventi: colonna "Trigger Cedola" (era "Trigger CPN")
- [ ] Verifica footer con `?branding=true`: "Powered by Smart Roots" con spazio visibile tra "by" e il link cliccabile