fix: offer name in client detail, retainer forecast, LTV with offers, offers-sold chart
- Client detail offers: show offer macro name ("Mantenimento") instead of tier letter
- Forecast: retainers project the monthly fee across every month from start_date
(no longer capped by duration_months); una_tantum unchanged
- Clients list LTV: per project max(accepted_total, sum of assigned offers) so a
retainer with unset quote still counts
- Dashboard: new "Offerte vendute" chart (count by offer + tier)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
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-white rounded-xl border border-[#e5e7eb] p-8 text-center">
|
||||
<p className="text-sm text-[#71717a] italic">Nessuna offerta venduta finora.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-xl border border-[#e5e7eb] p-6 space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 className="text-sm font-bold text-[#1a1a1a]">Offerte vendute</h3>
|
||||
<span className="inline-flex items-center justify-center min-w-[24px] h-6 px-2 rounded-full bg-[#1A463C] text-white text-xs font-bold">
|
||||
{data.total}
|
||||
</span>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
{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-[#1a1a1a] truncate">
|
||||
{row.offer_name}
|
||||
{row.tier_letter && (
|
||||
<span className="ml-2 inline-flex items-center rounded-full bg-[#1A463C]/10 px-2 py-0.5 text-[11px] font-semibold text-[#1A463C]">
|
||||
Tier {row.tier_letter}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
<span className="text-sm tabular-nums text-[#71717a] shrink-0">{row.count}</span>
|
||||
</div>
|
||||
<div className="h-2 rounded-full bg-[#f4f4f5] overflow-hidden">
|
||||
<div
|
||||
className="h-full rounded-full bg-[#1A463C] transition-all"
|
||||
style={{ width: `${pct}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user