Files
clienthub/src/components/public/proposal/sections/TimelineSection.tsx
T
simone c803efe059 fix(preventivo): slide deck 100vh — nessuno scroll di pagina
- 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>
2026-06-20 18:08:40 +02:00

89 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { ProposalContent } from "@/lib/proposal/schema";
type Props = { timeline: ProposalContent["timeline"] };
const COLOR_MAP = {
cyan: { bg: "bg-cyan-400", text: "text-cyan-900" },
purple: { bg: "bg-violet-400", text: "text-violet-900" },
green: { bg: "bg-emerald-400",text: "text-emerald-900" },
};
export function TimelineSection({ timeline }: Props) {
const weeks = Array.from({ length: timeline.totalWeeks }, (_, i) => i + 1);
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">Timeline</p>
<h2 className="text-5xl font-light text-foreground mt-4">
{timeline.totalWeeks} settimane di <span className="text-primary">progressione.</span>
</h2>
</div>
<div className="space-y-4">
{/* Header settimane */}
<div className="grid gap-2" style={{ gridTemplateColumns: `140px repeat(${timeline.totalWeeks}, 1fr)` }}>
<div />
{weeks.map((w) => (
<div key={w} className="text-center text-xs font-mono text-muted-foreground">W{w}</div>
))}
</div>
{/* Righe fase */}
{timeline.phases.map((phase, i) => {
const colors = COLOR_MAP[phase.color];
return (
<div
key={i}
className="grid gap-2 items-center"
style={{ gridTemplateColumns: `140px repeat(${timeline.totalWeeks}, 1fr)` }}
>
<div className="text-xs text-muted-foreground font-mono truncate pr-2">
{i === 0 ? "OPZIONE A" : i === 1 ? "OPZIONE B" : "OPZIONE C"}
<br />
<span className="text-[10px] text-muted-foreground/60">
{phase.endWeek - phase.startWeek + 1} settimane
</span>
</div>
{weeks.map((w) => {
const active = w >= phase.startWeek && w <= phase.endWeek;
const isFirst = w === phase.startWeek;
const isLast = w === phase.endWeek;
return (
<div
key={w}
className={`h-10 ${active ? `${colors.bg} ${isFirst ? "rounded-l-md" : ""} ${isLast ? "rounded-r-md" : ""}` : ""} flex items-center ${isFirst ? "justify-start pl-3" : ""}`}
>
{isFirst && (
<span className={`text-xs font-medium ${colors.text} whitespace-nowrap`}>
{phase.label}
</span>
)}
</div>
);
})}
</div>
);
})}
</div>
{/* Legenda */}
<div className="flex items-center gap-6">
{timeline.phases.map((phase, i) => {
const colors = COLOR_MAP[phase.color];
return (
<div key={i} className="flex items-center gap-2">
<div className={`w-3 h-3 rounded-sm ${colors.bg}`} />
<span className="text-xs text-muted-foreground">{phase.label}</span>
</div>
);
})}
</div>
<p className="text-xs font-mono text-muted-foreground">
{timeline.disclaimer}
</p>
</div>
);
}