a20a9de2d7
Allinea la dashboard alla rifinitura del mock (finezza bordi/colori/badge): - Card su border-border-light (slate-100) per il bordo sottile - KPI: valore verde su Incassato Reale, delta verde "+N questo mese" su Clienti Attivi (nuova metrica getDashboardStats.clientiNuoviMese) - Redditività: badge "Ottimo" con tint emerald soft (non brand primary) - Follow-up: righe come box bordati (no avatar), link "Apri →" primary - Forecast: selettore anno (pill interattiva) spostato nell'header della card, barre non-picco grigie (bg-border), rimosso il numero "mese prossimo" - Offerte Più Richieste: rimossa la pill totale nell'header Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
48 lines
1.8 KiB
TypeScript
48 lines
1.8 KiB
TypeScript
import type { OffersSoldBreakdown } from "@/lib/forecast-queries";
|
|
|
|
export function OffersSoldChart({ data }: { data: OffersSoldBreakdown }) {
|
|
const max = Math.max(...data.rows.map((r) => r.count), 1);
|
|
|
|
if (data.rows.length === 0) {
|
|
return (
|
|
<div className="bg-card rounded-xl border border-border-light shadow-card p-8 text-center">
|
|
<p className="text-sm text-muted-foreground italic">Nessuna offerta venduta finora.</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="bg-card rounded-xl border border-border-light shadow-card p-5 space-y-4">
|
|
<h3 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">
|
|
Offerte Più Richieste
|
|
</h3>
|
|
<div className="space-y-4">
|
|
{data.rows.map((row, i) => {
|
|
const pct = Math.round((row.count / max) * 100);
|
|
return (
|
|
<div key={`${row.offer_name}-${row.tier_letter ?? "—"}-${i}`}>
|
|
<div className="flex items-center justify-between mb-1 gap-2">
|
|
<span className="text-sm font-medium text-foreground truncate">
|
|
{row.offer_name}
|
|
{row.tier_letter && (
|
|
<span className="ml-2 inline-flex items-center rounded-full bg-primary/10 px-2 py-0.5 text-[11px] font-semibold text-primary">
|
|
Tier {row.tier_letter}
|
|
</span>
|
|
)}
|
|
</span>
|
|
<span className="text-sm font-mono text-muted-foreground shrink-0">{row.count}</span>
|
|
</div>
|
|
<div className="h-1.5 rounded-full bg-muted overflow-hidden">
|
|
<div
|
|
className="h-full rounded-full bg-primary transition-all"
|
|
style={{ width: `${pct}%` }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|