c803efe059
- ProposalDeck: outer div h-screen overflow-hidden, content wrapper h-full - Rimosso il div interno ridondante min-h-screen - useEffect blocca body overflow mentre la deck è aperta - Tutti i 20 componenti slide: min-h-screen → h-full Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
77 lines
2.9 KiB
TypeScript
77 lines
2.9 KiB
TypeScript
import type { AssembledProposal } from "@/lib/proposal/assemble";
|
||
|
||
type Props = { tiers: AssembledProposal["offer"]["tiers"] };
|
||
|
||
function formatEur(val: string | null | undefined): string {
|
||
if (!val) return "—";
|
||
const n = parseFloat(val);
|
||
return `€${n.toLocaleString("it-IT")}`;
|
||
}
|
||
|
||
export function PricingSection({ tiers }: Props) {
|
||
return (
|
||
<div className="h-full flex flex-col justify-center px-16 py-24 space-y-10">
|
||
<div>
|
||
<p className="text-xs font-mono tracking-widest text-muted-foreground uppercase">Le tre opzioni</p>
|
||
<h2 className="text-5xl font-light text-foreground mt-4">
|
||
Tre tappe, <span className="text-primary">un solo risultato.</span>
|
||
</h2>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-3 gap-6">
|
||
{tiers.map((tier, i) => {
|
||
const isHighlighted = i === 1; // tier B highlighted di default
|
||
const price = tier.publicPrice ?? tier.servicesTotal;
|
||
const durationLabel = `${tier.durationMonths} ${tier.durationMonths === 1 ? "mese" : "mesi"}`;
|
||
|
||
return (
|
||
<div
|
||
key={tier.id}
|
||
className={`rounded-xl p-8 space-y-6 border ${
|
||
isHighlighted
|
||
? "border-primary bg-primary/5"
|
||
: "border-border bg-white"
|
||
}`}
|
||
>
|
||
<div className="flex items-start justify-between">
|
||
<div>
|
||
<p className="text-xs font-mono tracking-widest text-muted-foreground uppercase">
|
||
Opzione {tier.tierLetter} / {durationLabel}
|
||
</p>
|
||
<h3 className="text-xl font-medium text-foreground mt-1">{tier.publicName}</h3>
|
||
</div>
|
||
<span className="text-xs font-mono bg-primary/10 text-primary px-2 py-1 rounded">
|
||
{tier.tierLetter}
|
||
</span>
|
||
</div>
|
||
|
||
<div className="space-y-1">
|
||
<p className="text-3xl font-light text-primary">{formatEur(price)}</p>
|
||
<p className="text-xs text-muted-foreground">
|
||
{tier.durationMonths > 1 ? `${tier.durationMonths} mesi` : "pagamento unico"}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Servizi inclusi */}
|
||
{tier.services.length > 0 && (
|
||
<ul className="space-y-1.5">
|
||
{tier.services.map((s) => (
|
||
<li key={s.id} className="flex items-start gap-2 text-sm text-foreground">
|
||
<span className="text-primary mt-0.5">–</span>
|
||
<span>{s.name}</span>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
)}
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
<p className="text-xs font-mono text-muted-foreground">
|
||
Le tre opzioni si compongono progressivamente. La C eredita tutto da B, che a sua volta eredita tutto da A.
|
||
</p>
|
||
</div>
|
||
);
|
||
}
|