diff --git a/client/components/roadmap/Timeline.tsx b/client/components/roadmap/Timeline.tsx new file mode 100644 index 00000000..20e187a1 --- /dev/null +++ b/client/components/roadmap/Timeline.tsx @@ -0,0 +1,111 @@ +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
+ )} +
+
+ ))} +
+
+
+
+ ); +}