|
| 1 | +import { motion } from 'framer-motion' |
| 2 | +import { useInView } from 'framer-motion' |
| 3 | +import { useRef } from 'react' |
| 4 | + |
| 5 | +const roadmapItems = [ |
| 6 | + // Completed |
| 7 | + { version: 'v0.1', title: 'Core Spawner', desc: 'spawn_claude, spawn_codex with IAC.md logging', status: 'completed' }, |
| 8 | + { version: 'v0.2', title: 'MCP Server', desc: 'Full MCP protocol, wait_for_agents, context handling', status: 'completed' }, |
| 9 | + { version: 'v0.3', title: 'Landing Page', desc: 'powerspawn.com with React + Tailwind', status: 'completed' }, |
| 10 | + { version: 'v0.4', title: 'Copilot Integration', desc: 'spawn_copilot with GPT, Claude, and Gemini models', status: 'completed' }, |
| 11 | + // Current |
| 12 | + { version: 'v0.5', title: 'VS Code MCP Testing', desc: 'Copilot + VS Code MCP configuration validation', status: 'current' }, |
| 13 | + // Upcoming |
| 14 | + { version: 'v0.6', title: 'MCP Registry', desc: 'Submit to official MCP server registry', status: 'upcoming' }, |
| 15 | + { version: 'v0.7', title: 'Test Suite', desc: 'Unit and integration tests with CI/CD', status: 'upcoming' }, |
| 16 | + { version: 'v1.0', title: 'Stable Release', desc: 'Production-ready with full documentation', status: 'upcoming' }, |
| 17 | +] |
| 18 | + |
| 19 | +export function Roadmap() { |
| 20 | + const ref = useRef(null) |
| 21 | + const isInView = useInView(ref, { once: true, margin: '-100px' }) |
| 22 | + |
| 23 | + return ( |
| 24 | + <section className="py-24 px-4" id="roadmap"> |
| 25 | + <div className="max-w-3xl mx-auto"> |
| 26 | + <motion.div |
| 27 | + ref={ref} |
| 28 | + initial={{ opacity: 0, y: 20 }} |
| 29 | + animate={isInView ? { opacity: 1, y: 0 } : {}} |
| 30 | + transition={{ duration: 0.5 }} |
| 31 | + className="text-center mb-12" |
| 32 | + > |
| 33 | + <h2 className="text-4xl font-bold text-white mb-4"> |
| 34 | + Roadmap |
| 35 | + </h2> |
| 36 | + <p className="text-xl text-gray-400"> |
| 37 | + From multi-agent spawner to production platform |
| 38 | + </p> |
| 39 | + </motion.div> |
| 40 | + |
| 41 | + {/* Timeline */} |
| 42 | + <div className="relative"> |
| 43 | + {/* Vertical line */} |
| 44 | + <div className="absolute left-6 top-0 bottom-0 w-0.5 bg-gray-700" /> |
| 45 | + |
| 46 | + <div className="space-y-6"> |
| 47 | + {roadmapItems.map((item, index) => ( |
| 48 | + <motion.div |
| 49 | + key={item.version} |
| 50 | + initial={{ opacity: 0, x: -20 }} |
| 51 | + animate={isInView ? { opacity: 1, x: 0 } : {}} |
| 52 | + transition={{ duration: 0.4, delay: 0.2 + index * 0.08 }} |
| 53 | + className={`relative pl-16 ${item.status === 'upcoming' ? 'opacity-50' : ''}`} |
| 54 | + > |
| 55 | + {/* Status indicator */} |
| 56 | + <div className={`absolute left-4 w-5 h-5 rounded-full border-2 flex items-center justify-center |
| 57 | + ${item.status === 'completed' ? 'bg-green-500 border-green-500' : ''} |
| 58 | + ${item.status === 'current' ? 'bg-orange-500 border-orange-500 animate-pulse' : ''} |
| 59 | + ${item.status === 'upcoming' ? 'bg-transparent border-gray-600' : ''} |
| 60 | + `}> |
| 61 | + {item.status === 'completed' && ( |
| 62 | + <svg className="w-3 h-3 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
| 63 | + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" /> |
| 64 | + </svg> |
| 65 | + )} |
| 66 | + </div> |
| 67 | + |
| 68 | + {/* Content */} |
| 69 | + <div className={`p-4 rounded-lg ${item.status === 'current' ? 'bg-orange-500/10 border border-orange-500/30' : ''}`}> |
| 70 | + <div className="flex items-center gap-3 mb-1"> |
| 71 | + <span className={`text-sm font-mono ${ |
| 72 | + item.status === 'completed' ? 'text-green-400' : |
| 73 | + item.status === 'current' ? 'text-orange-400' : |
| 74 | + 'text-gray-500' |
| 75 | + }`}> |
| 76 | + {item.version} |
| 77 | + </span> |
| 78 | + <span className={`font-semibold ${ |
| 79 | + item.status === 'current' ? 'text-orange-300' : 'text-white' |
| 80 | + }`}> |
| 81 | + {item.title} |
| 82 | + </span> |
| 83 | + </div> |
| 84 | + <p className="text-gray-400 text-sm"> |
| 85 | + {item.desc} |
| 86 | + </p> |
| 87 | + </div> |
| 88 | + </motion.div> |
| 89 | + ))} |
| 90 | + </div> |
| 91 | + </div> |
| 92 | + </div> |
| 93 | + </section> |
| 94 | + ) |
| 95 | +} |
0 commit comments