import { useMemo, useRef } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { CheckCircle2, Circle, Rocket, Target, Flame, Sparkles, } from "lucide-react"; export type RoadmapPhase = "now" | "month1" | "month2" | "month3"; export interface TimelineEvent { id: string; title: string; phase: RoadmapPhase; xp: number; claimed?: boolean; } export default function Timeline({ events, onSelectPhase, onToggleClaim, }: { events: TimelineEvent[]; onSelectPhase?: (p: RoadmapPhase) => void; onToggleClaim?: (id: string) => void; }) { const containerRef = useRef(null); const phases: RoadmapPhase[] = ["now", "month1", "month2", "month3"]; const iconFor: Record = { now: Target, month1: Flame, month2: Rocket, month3: Sparkles, }; const grouped = useMemo(() => { const map: Record = { now: [], month1: [], month2: [], month3: [], }; for (const e of events) map[e.phase].push(e); return map; }, [events]); const scrollToPhase = (p: RoadmapPhase) => { const el = containerRef.current?.querySelector( `[data-phase="${p}"]`, ); if (el) el.scrollIntoView({ behavior: "smooth", inline: "center", block: "nearest", }); onSelectPhase?.(p); }; return (
{phases.map((p) => { const Icon = iconFor[p]; const label = p === "now" ? "Now" : p === "month1" ? "Month 1" : p === "month2" ? "Month 2" : "Month 3"; return ( ); })}
Interactive timeline
{phases.map((p, idx) => (
{/* Phase header */}
{(() => { const Icon = iconFor[p]; return ; })()} {p === "now" ? "Now" : p === "month1" ? "Month 1" : p === "month2" ? "Month 2" : "Month 3"}
{/* Events for phase */}
{grouped[p].map((e) => ( ))} {grouped[p].length === 0 && (
No quests yet
)}
))}
); }