import React, { useState, useEffect, useRef, useCallback } from 'react';import { motion, AnimatePresence } from 'framer-motion';import { Github, Linkedin, Twitter, Mail, ExternalLink, Download, Code, Shield, Star, Users, Award, Briefcase, GraduationCap, HelpCircle, Home, ArrowLeft, BookOpen, Lightbulb, User, Info, Trophy, LayoutDashboard, Database, Cloud, Settings, Compass, MapPin, Phone, MessageSquare, Clipboard, Calendar, Clock, Image, FileText, Globe} from 'lucide-react';const TerminalPortfolio = () => { const [currentView, setCurrentView] = useState('welcome'); const [command, setCommand] = useState(''); const [commandHistory, setCommandHistory] = useState([]); const [welcomeText, setWelcomeText] = useState(''); const [showPrompt, setShowPrompt] = useState(false); const [showCommandHelp, setShowCommandHelp] = useState(true); const inputRef = useRef(null); const historyEndRef = useRef(null); // Ref for scrolling to the end of command history const fullWelcomeText = "Welcome to my Interactive Terminal Portfolio!"; // Typewriter effect for welcome text useEffect(() => { if (currentView === 'welcome') { let i = 0; const timer = setInterval(() => { if (i < fullWelcomeText.length) { setWelcomeText(fullWelcomeText.slice(0, i + 1)); i++; } else { clearInterval(timer); setShowPrompt(true); } }, 80); return () => clearInterval(timer); } }, [currentView]); // Auto-focus input and scroll to end of history useEffect(() => { if (inputRef.current && currentView !== 'welcome') { inputRef.current.focus(); } if (historyEndRef.current) { historyEndRef.current.scrollIntoView({ behavior: 'smooth' }); } }, [currentView, commandHistory]); // Depend on commandHistory to scroll on new entries // Sample data - EXPANDED! const personalData = { name: "Alex Chen", title: "Computer Science Student", university: "Massachusetts Institute of Technology (MIT)", major: "Computer Science and Engineering", year: "Final Year (Expected Graduation: May 2026)", gpa: "3.9/4.0", location: "Cambridge, MA", email: "alex.chen@mit.edu", github: "alexchen-dev", linkedin: "alexchen-cs", twitter: "alexchen_code", portfolioWebsite: "https://alexchen.dev", // New field bio: `I'm a final-year Computer Science student with a profound passion for leveraging technology to solve complex problems and create impactful solutions. My academic journey at MIT has provided me with a strong foundation in theoretical computer science, alongside extensive practical experience in software development, artificial intelligence, and cybersecurity. I am particularly interested in the intersection of AI and systems design.`, hobbies: "Hiking, Photography, Competitive Programming, Reading Sci-Fi", // New field vision: "My goal is to contribute to innovative technologies that make a significant positive impact on society, whether through advancements in AI, robust software systems, or enhanced digital security." // New field }; const skills = [ { name: "Python", level: 95, category: "Programming", icon: <Code size={16} /> }, { name: "JavaScript/TypeScript", level: 90, category: "Programming", icon: <Code size={16} /> }, { name: "React/Next.js", level: 88, category: "Frontend", icon: <LayoutDashboard size={16} /> }, { name: "Node.js", level: 85, category: "Backend", icon: <Settings size={16} /> }, { name: "Machine Learning (TensorFlow/PyTorch)", level: 82, category: "AI/ML", icon: <Lightbulb size={16} /> }, { name: "Deep Learning", level: 80, category: "AI/ML", icon: <Lightbulb size={16} /> }, { name: "Cybersecurity (OWASP, Penetration Testing)", level: 78, category: "Security", icon: <Shield size={16} /> }, { name: "Docker & Kubernetes", level: 80, category: "DevOps", icon: <Briefcase size={16} /> }, { name: "AWS & Azure", level: 75, category: "Cloud", icon: <Cloud size={16} /> }, { name: "SQL (PostgreSQL, MySQL)", level: 85, category: "Databases", icon: <Database size={16} /> }, { name: "Git & GitHub", level: 90, category: "Tools", icon: <Github size={16} /> }, { name: "Agile Methodologies", level: 88, category: "Methodologies", icon: <Compass size={16} /> } ]; const projects = [ { name: "AI Code Reviewer", description: "An intelligent code review assistant leveraging the GPT-4 API to provide insightful feedback, suggest optimizations, and identify potential bugs in various programming languages. Designed for integration with CI/CD pipelines.", tech: ["Python", "OpenAI API", "Flask", "React", "Docker", "REST API"], github: "https://github.com/alexchen-dev/ai-code-reviewer", live: "https://aicodereviewer.alexchen.dev", stars: 234, category: "AI/ML" }, { name: "Blockchain Voting System", description: "A secure and transparent decentralized voting platform built on the Ethereum blockchain. Features include immutable records, voter anonymity, and resistance to manipulation using smart contracts.", tech: ["Solidity", "Web3.js", "React", "Ganache", "Truffle", "Ethereum"], github: "https://github.com/alexchen-dev/blockchain-voting-system", live: "https://blockchainvote.alexchen.dev", stars: 156, category: "Blockchain" }, { name: "Real-time Encrypted Chat", description: "An end-to-end encrypted messaging application with a robust vulnerability scanner. Implements advanced cryptographic protocols (AES-256, RSA) for secure communication and a real-time scanner for common web vulnerabilities.", tech: ["Node.js", "Socket.io", "Express.js", "React", "Cryptography", "OAuth2.0"], github: "https://github.com/alexchen-dev/encrypted-chat-app", live: "https://securechat.alexchen.dev", stars: 89, category: "Security" }, { name: "Portfolio Terminal CLI", description: "This very interactive terminal-style portfolio, built with React and Framer Motion. Showcases skills, projects, and contact information through a command-line interface simulation.", tech: ["React", "Framer Motion", "Tailwind CSS", "JavaScript"], github: "https://github.com/alexchen-dev/terminal-portfolio", live: "#", // This app itself stars: 100, category: "Frontend" } ]; const education = [ { degree: "Bachelor of Science in Computer Science and Engineering", institution: "Massachusetts Institute of Technology (MIT)", location: "Cambridge, MA", period: "September 2022 - May 2026 (Expected)", gpa: "3.9/4.0", details: [ "Specialization in Artificial Intelligence and Cybersecurity.", "Relevant Coursework: Algorithms, Data Structures, Operating Systems, Computer Networks, Machine Learning, Deep Learning, Cryptography, Database Systems, Web Security.", "Awards: Dean's List (all semesters), MIT Scholarship recipient." ] }, { degree: "High School Diploma", institution: "Tech Innovations Academy", location: "New York, NY", period: "September 2018 - May 2022", gpa: "4.0/4.0", details: [ "Graduated Summa Cum Laude.", "Awards: National Merit Scholar, AP Scholar with Distinction." ] } ]; const courses = [ { name: "CS50x: Introduction to Computer Science", platform: "Harvard/edX", status: "Completed", logo: <GraduationCap size={16} />, cert: "https://certificates.edx.org/cs50x_alexchen" }, { name: "Machine Learning", platform: "Stanford/Coursera", status: "Completed", logo: <Lightbulb size={16} />, cert: "https://coursera.org/verify/ML_alexchen" }, { name: "Full Stack Development with MERN", platform: "FreeCodeCamp", status: "Completed", logo: <Code size={16} />, cert: "https://freecodecamp.org/certification/alexchen-mern" }, { name: "Ethical Hacking & Penetration Testing", platform: "Cybrary", status: "In Progress", logo: <Shield size={16} />, cert: null } ]; const internships = [ { title: "Software Engineer Intern", company: "InnovateTech Solutions", location: "San Francisco, CA", period: "Summer 2024", description: [ "Developed and deployed a microservices-based user authentication system using Node.js and AWS Lambda, improving security and scalability by 30%.", "Contributed to the frontend development of their main enterprise application using React and Redux, enhancing UI responsiveness by 20%.", "Participated in agile ceremonies, code reviews, and cross-functional team meetings." ], skillsUsed: ["Node.js", "React", "AWS Lambda", "DynamoDB", "REST APIs", "Git"] }, { title: "AI Research Intern", company: "Global AI Labs", location: "Remote", period: "Summer 2023", description: [ "Researched and implemented novel deep learning models for natural language understanding, achieving a 15% improvement in sentiment analysis accuracy.", "Preprocessed large datasets for model training and evaluated performance using various metrics.", "Published a co-authored paper on 'Leveraging Transformers for Contextual Sentiment Analysis' at a reputable AI conference." ], skillsUsed: ["Python", "TensorFlow", "PyTorch", "NLP", "Data Preprocessing", "Jupyter"] } ]; const awards = [ { name: "MIT Dean's List", issuer: "Massachusetts Institute of Technology", year: "2022, 2023, 2024", description: "Awarded for outstanding academic achievement (top 5% of class)." }, { name: "HackMIT 2023 - Best Overall Project", issuer: "HackMIT", year: "2023", description: "Led a team of 4 to develop an AI-powered personal finance assistant, recognized for innovation and utility." }, { name: "National Merit Scholar", issuer: "National Merit Scholarship Corporation", year: "2022", description: "Recognized for exceptional academic ability and potential." } ]; const volunteering = [ { role: "Coding Mentor", organization: "Girls Who Code", period: "September 2023 - Present", description: "Mentoring high school students in programming fundamentals, Python, and web development to encourage participation in STEM." }, { role: "Open Source Contributor", organization: "FreeCodeCamp (Community)", period: "January 2023 - Present", description: "Contributed to documentation improvements and bug fixes for the FreeCodeCamp curriculum, assisting thousands of learners." } ]; const commands = { 'start': () => setCurrentView('terminal'), 'menu': () => setCurrentView('terminal'), 'home': () => setCurrentView('terminal'), 'intro': () => setCurrentView('intro'), 'about': () => setCurrentView('about'), 'education': () => setCurrentView('education'), 'courses': () => setCurrentView('courses'), 'skills': () => setCurrentView('skills'), 'internships': () => setCurrentView('internships'), // New command 'projects': () => setCurrentView('projects'), 'volunteering': () => setCurrentView('volunteering'), // New command 'awards': () => setCurrentView('awards'), // New command 'contact': () => setCurrentView('contact'), 'whoami': () => setCurrentView('intro'), 'ls': () => setCurrentView('projects'), 'cat': () => setCurrentView('about'), 'help': () => setCurrentView('help'), 'download': () => { // In a real app, replace with actual resume download logic const link = document.createElement('a'); link.href = '/path/to/your/resume.pdf'; // IMPORTANT: Update this path to your actual resume file link.download = 'Alex_Chen_Resume.pdf'; document.body.appendChild(link); // Required for Firefox link.click(); document.body.removeChild(link); // Clean up return '📄 Attempting to download resume... If it doesn\'t start, check console for errors.'; }, 'clear': () => { setCommandHistory([]); setCurrentView('terminal'); // Keep them in the terminal view after clearing return ''; // No output for clear }, 'social': () => setCurrentView('contact'), // Alias for contact 'experience': () => setCurrentView('internships'), // Alias for internships }; const allAvailableCommands = Object.keys(commands).sort(); // For the help section // useCallback to memoize handleCommand to prevent unnecessary re-renders const handleCommand = useCallback((e) => { if (e.key === 'Enter') { const cmd = command.trim().toLowerCase(); // Add command to history setCommandHistory(prev => [...prev, { command: cmd, timestamp: new Date().toLocaleTimeString() }]); if (commands[cmd]) { const result = commands[cmd](); if (typeof result === 'string') { // If command returns a string, add it as output setCommandHistory(prev => [...prev, { output: result, timestamp: new Date().toLocaleTimeString() }]); } } else if (cmd) { setCommandHistory(prev => [...prev, { output: `❌ Command not found: '${cmd}'. Type 'help' for available commands.`, timestamp: new Date().toLocaleTimeString() }]); } setCommand(''); // Clear input field } }, [command, commands]); // Dependencies: command (current input), commands (list of available commands) const handleWelcomeInteraction = useCallback((e) => { if (e.key === 'Enter' || (e.type === 'click' && showPrompt)) { setCurrentView('terminal'); } }, [showPrompt]); const BackgroundEffect = () => ( <div className="fixed inset-0 opacity-10 pointer-events-none"> <div className="absolute inset-0 bg-gradient-to-br from-green-400/20 via-transparent to-cyan-400/20"></div> <div className="absolute inset-0 opacity-30"> {Array.from({ length: 20 }).map((_, i) => ( <div key={`col-${i}`} className="absolute border-l border-green-400/20" style={{ left: `${i * 5}%`, height: '100%' }}></div> ))} {Array.from({ length: 20 }).map((_, i) => ( <div key={`row-${i}`} className="absolute border-t border-green-400/20" style={{ top: `${i * 5}%`, width: '100%' }}></div> ))} </div> </div> ); const TerminalHeader = () => ( <div className="flex items-center justify-between p-4 border-b border-green-400/30 bg-black/80 backdrop-blur-sm"> <div className="flex items-center space-x-2"> <div className="w-3 h-3 rounded-full bg-red-500"></div> <div className="w-3 h-3 rounded-full bg-yellow-500"></div> <div className="w-3 h-3 rounded-full bg-green-500"></div> <span className="ml-4 text-green-400 text-sm font-mono">terminal@portfolio:~$</span> </div> <div className="flex items-center space-x-4"> <button onClick={() => setShowCommandHelp(!showCommandHelp)} className="text-cyan-400 hover:text-green-400 transition-colors flex items-center space-x-1" > <HelpCircle className="w-4 h-4" /> <span className="text-sm font-mono">Help</span> </button> <div className="text-green-400 text-sm font-mono"> {new Date().toLocaleString()} </div> </div> </div> ); const CommandHelp = ({ commands: availableCommands, title = "Available Commands" }) => ( <AnimatePresence> {showCommandHelp && ( <motion.div initial={{ opacity: 0, y: -20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -20 }} className="bg-gray-900/95 border border-cyan-400/50 rounded-lg p-4 m-4 backdrop-blur-sm shadow-lg" > <h3 className="text-cyan-400 font-mono font-bold mb-3 flex items-center"> <HelpCircle className="w-4 h-4 mr-2" /> {title} </h3> <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2"> {availableCommands.map((cmd, index) => ( <div key={index} className="text-green-400 text-sm font-mono hover:text-cyan-400 transition-colors cursor-pointer" onClick={() => handleCommand({ key: 'Enter', target: { value: cmd } })}> • {cmd} </div> ))} </div> <div className="mt-3 text-yellow-400 text-xs font-mono"> 💡 Tip: Click a command to run it directly, or click the Help button to toggle this guide. </div> </motion.div> )} </AnimatePresence> ); const CommandPrompt = () => ( <div className="flex items-center space-x-2 p-4 border-t border-green-400/30 bg-black/80 backdrop-blur-sm"> <span className="text-green-400 font-mono">user@portfolio:~$</span> <input ref={inputRef} type="text" value={command} onChange={(e) => setCommand(e.target.value)} onKeyPress={handleCommand} className="flex-1 bg-transparent text-green-400 font-mono outline-none caret-green-400" placeholder="Type a command and press Enter... (e.g., 'help')" autoComplete="off" /> <div className="w-2 h-5 bg-green-400 animate-pulse"></div> </div> ); const NavigationButtons = () => ( <div className="flex items-center space-x-2 mb-4"> <button onClick={() => setCurrentView('terminal')} className="flex items-center space-x-1 px-3 py-1 bg-green-400/20 text-green-400 rounded font-mono text-sm hover:bg-green-400/30 transition-colors" > <Home className="w-4 h-4" /> <span>home</span> </button> <button onClick={() => { // This simulates browser back, but for internal state, it's better to manage a view stack if needed. // For simplicity, we can just return to terminal or a sensible default. // For a true "back" history, you'd need a state for view history. // For now, let's just go home if not already there, otherwise do nothing or provide a message. if (currentView !== 'terminal') { setCurrentView('terminal'); } else { setCommandHistory(prev => [...prev, { output: "Already at the main menu. Try 'help' or another command.", timestamp: new Date().toLocaleTimeString() }]); } }} className="flex items-center space-x-1 px-3 py-1 bg-cyan-400/20 text-cyan-400 rounded font-mono text-sm hover:bg-cyan-400/30 transition-colors" > <ArrowLeft className="w-4 h-4" /> <span>back</span> </button> </div> ); const renderContent = () => { switch (currentView) { case 'welcome': return ( <motion.div className="flex flex-col items-center justify-center min-h-screen text-center p-8" onClick={handleWelcomeInteraction} onKeyPress={handleWelcomeInteraction} tabIndex={0} > <motion.h1 className="text-4xl md:text-6xl font-mono text-green-400 mb-8" initial={{ opacity: 0 }} animate={{ opacity: 1 }} > {welcomeText} <span className="animate-pulse">|</span> </motion.h1> <AnimatePresence> {showPrompt && ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="text-xl font-mono text-cyan-400 space-y-4" > <div className="bg-gray-900/50 border border-green-400/30 rounded-lg p-6"> <p className="mb-4 text-lg">🚀 Ready to explore?</p> <p className="mb-4">Press <span className="bg-green-400/20 px-2 py-1 rounded">Enter</span> or type <span className="bg-cyan-400/20 px-2 py-1 rounded">'start'</span></p> <div className="text-sm text-yellow-400"> <p>Navigation tips:</p> <p>• Use commands like: <span className="text-purple-300">intro</span>, <span className="text-purple-300">projects</span>, <span className="text-purple-300">skills</span>, <span className="text-purple-300">contact</span>, <span className="text-purple-300">help</span></p> <p>• Type '<span className="text-purple-300">help</span>' anytime for a full command list</p> <p>• Click the Help button (top right) for quick commands</p> </div> </div> <div className="inline-block w-3 h-6 bg-cyan-400 animate-pulse ml-1"></div> </motion.div> )} </AnimatePresence> </motion.div> ); case 'terminal': return ( <div className="p-6"> <CommandHelp commands={['intro', 'about', 'education', 'skills', 'projects', 'internships', 'awards', 'volunteering', 'courses', 'contact', 'help', 'clear', 'download']} /> <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="text-green-400 font-mono space-y-6" > <div className="text-center mb-8"> <h1 className="text-3xl text-cyan-400 mb-2">🖥️ Terminal Portfolio Menu</h1> <p className="text-lg">Navigate using commands below or type them in the terminal</p> </div> <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4"> {[ { cmd: 'intro', icon: <User size={24} />, desc: 'About me & introduction', color: 'cyan' }, { cmd: 'about', icon: <Info size={24} />, desc: 'Detailed personal background', color: 'green' }, { cmd: 'education', icon: <GraduationCap size={24} />, desc: 'Academic background', color: 'blue' }, { cmd: 'skills', icon: <Lightbulb size={24} />, desc: 'Technical skills & expertise', color: 'yellow' }, { cmd: 'projects', icon: <Code size={24} />, desc: 'Featured projects & code', color: 'purple' }, { cmd: 'internships', icon: <Briefcase size={24} />, desc: 'Professional experience', color: 'orange' }, { cmd: 'awards', icon: <Award size={24} />, desc: 'Achievements & recognitions', color: 'red' }, { cmd: 'volunteering', icon: <Users size={24} />, desc: 'Community involvement', color: 'emerald' }, { cmd: 'courses', icon: <BookOpen size={24} />, desc: 'Online courses & certifications', color: 'pink' }, { cmd: 'contact', icon: <Mail size={24} />, desc: 'Get in touch with me', color: 'sky' } ].map((item, index) => ( <motion.div key={item.cmd} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: index * 0.05 }} className={`bg-gray-900/50 border border-${item.color}-400/30 rounded-lg p-4 hover:border-${item.color}-400/50 cursor-pointer transition-all hover:scale-105 shadow-md`} onClick={() => commands[item.cmd]()} > <div className={`text-${item.color}-400 mb-2`}>{item.icon}</div> <div className={`text-${item.color}-400 font-bold text-lg mb-1`}>{item.cmd}</div> <div className="text-sm text-gray-400">{item.desc}</div> <div className="text-xs text-green-400 mt-2">Type: '<span className="text-white">{item.cmd}</span>'</div> </motion.div> ))} </div> <div className="bg-gray-900/30 border border-yellow-400/30 rounded-lg p-4 mt-6 shadow-md"> <h3 className="text-yellow-400 font-bold mb-2 flex items-center"><Lightbulb className="mr-2" size={18} /> Quick Commands & Aliases</h3> <div className="grid grid-cols-2 md:grid-cols-4 gap-2 text-sm"> <div><span className="text-cyan-400">whoami</span> - About me</div> <div><span className="text-cyan-400">ls</span> - List projects</div> <div><span className="text-cyan-400">cat</span> - Read about section</div> <div><span className="text-cyan-400">download</span> - Get resume</div> <div><span className="text-cyan-400">clear</span> - Clear screen</div> <div><span className="text-cyan-400">social</span> - My social links</div> <div><span className="text-cyan-400">experience</span> - Internships</div> <div><span className="text-cyan-400">help</span> - Show all commands</div> </div> </div> </motion.div> </div> ); case 'intro': return ( <motion.div initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }} className="p-6" > <CommandHelp commands={['about', 'skills', 'projects', 'contact', 'home', 'download', 'social']} title="From Introduction" /> <NavigationButtons /> <div className="flex flex-col md:flex-row items-center space-y-6 md:space-y-0 md:space-x-8 bg-gray-900/50 border border-green-400/30 rounded-lg p-6 shadow-lg"> <div className="w-32 h-32 rounded-full bg-gradient-to-br from-green-400 to-cyan-400 flex items-center justify-center text-4xl flex-shrink-0 border-4 border-gray-700"> 👨💻 </div> <div className="text-green-400 font-mono text-center md:text-left"> <h2 className="text-3xl mb-2 text-cyan-400 font-bold">{personalData.name}</h2> <p className="text-xl mb-1">{personalData.title}</p> <p className="text-lg mb-1">{personalData.university}</p> <p className="text-md mb-2">{personalData.major} • {personalData.year}</p> <p className="text-lg mb-4 flex items-center justify-center md:justify-start"> <MapPin className="w-5 h-5 mr-2 text-yellow-400" /> {personalData.location} </p> <p className="text-lg mb-4 text-gray-300 leading-relaxed italic">"{personalData.vision}"</p> <div className="space-y-2 text-yellow-400 text-sm"> <p className="flex items-center"><ArrowLeft size={16} className="mr-2" /> Next: Try '<span className="text-white">skills</span>' to see my technical expertise.</p> <p className="flex items-center"><Code size={16} className="mr-2" /> Or '<span className="text-white">projects</span>' to view my work.</p> </div> </div> </div> </motion.div> ); case 'about': return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6 text-green-400 font-mono space-y-4" > <CommandHelp commands={['intro', 'skills', 'education', 'projects', 'contact', 'home', 'hobbies']} title="From About" /> <NavigationButtons /> <h2 className="text-2xl text-cyan-400 mb-4 flex items-center"><Info className="mr-2" /> $ cat about.txt</h2> <div className="space-y-3 leading-relaxed bg-gray-900/30 border border-green-400/30 rounded-lg p-6 shadow-lg"> <p className="text-base">{personalData.bio}</p> <p className="text-base">Currently maintaining a <span className="text-yellow-400 font-bold">{personalData.gpa}</span> GPA while actively contributing to open-source projects and building innovative solutions. I believe in the power of technology to create positive impact.</p> <p className="text-base">When I'm not coding, you'll find me participating in hackathons, contributing to OSS projects, exploring the latest in tech innovation, or indulging in my hobbies: <span className="text-yellow-400 italic">{personalData.hobbies}</span>.</p> <p className="text-base">My long-term vision is to <span className="text-cyan-400 italic">{personalData.vision}</span>.</p> </div> <div className="text-yellow-400 text-sm mt-4"> <p className="flex items-center"><GraduationCap size={16} className="mr-2" />📝 Try: '<span className="text-white">education</span>' for academic details or '<span className="text-white">skills</span>' for technical expertise.</p> </div> </motion.div> ); case 'education': return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6" > <CommandHelp commands={['about', 'courses', 'internships', 'home']} title="From Education" /> <NavigationButtons /> <h2 className="text-2xl text-cyan-400 mb-6 font-mono flex items-center"><GraduationCap className="mr-2" /> Academic Journey</h2> <div className="space-y-8"> {education.map((edu, index) => ( <motion.div key={index} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: index * 0.1 }} className="bg-gray-900/50 border border-green-400/30 rounded-lg p-6 shadow-lg" > <h3 className="text-green-400 font-bold text-xl mb-2 flex items-center"> <BookOpen className="mr-2 text-yellow-400" /> {edu.degree} </h3> <p className="text-cyan-400 text-md mb-1">{edu.institution}, {edu.location}</p> <p className="text-sm text-gray-400 mb-3">{edu.period}</p> <p className="text-sm text-yellow-400 mb-3">GPA: {edu.gpa}</p> <ul className="list-disc list-inside text-sm text-gray-300 space-y-1"> {edu.details.map((detail, i) => ( <li key={i}>{detail}</li> ))} </ul> </motion.div> ))} </div> <div className="text-yellow-400 text-sm mt-6"> <p className="flex items-center"><BookOpen size={16} className="mr-2" /> Expand your knowledge: Check out my '<span className="text-white">courses</span>' and '<span className="text-white">internships</span>'.</p> </div> </motion.div> ); case 'courses': return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6" > <CommandHelp commands={['education', 'skills', 'home']} title="From Courses" /> <NavigationButtons /> <h2 className="text-2xl text-cyan-400 mb-6 font-mono flex items-center"><BookOpen className="mr-2" /> Online Courses & Certifications</h2> <div className="grid grid-cols-1 md:grid-cols-2 gap-6"> {courses.map((course, index) => ( <motion.div key={index} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: index * 0.1 }} whileHover={{ scale: 1.02 }} className="bg-gray-900/50 border border-green-400/30 rounded-lg p-6 shadow-lg" > <h3 className="text-green-400 font-bold text-xl mb-2 flex items-center"> {course.logo && <span className="mr-2 text-yellow-400">{course.logo}</span>} {course.name} </h3> <p className="text-cyan-400 text-md mb-2">Platform: {course.platform}</p> <p className="text-sm text-gray-400 mb-3">Status: <span className={`${course.status === 'Completed' ? 'text-green-500' : 'text-orange-400'}`}>{course.status}</span></p> {course.cert && ( <a href={course.cert} target="_blank" rel="noopener noreferrer" className="flex items-center space-x-1 text-blue-400 hover:text-blue-300 transition-colors text-sm" > <ExternalLink className="w-4 h-4" /> <span>View Certificate</span> </a> )} </motion.div> ))} </div> <div className="text-yellow-400 text-sm mt-6"> <p className="flex items-center"><Lightbulb size={16} className="mr-2" /> See how these translate to skills: Type '<span className="text-white">skills</span>'.</p> </div> </motion.div> ); case 'skills': return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6" > <CommandHelp commands={['projects', 'about', 'education', 'home']} title="From Skills" /> <NavigationButtons /> <h2 className="text-2xl text-cyan-400 mb-6 font-mono flex items-center"> <Lightbulb className="mr-2" /> ⚡ Technical Skills Matrix </h2> <div className="space-y-6"> {['Programming', 'Frontend', 'Backend', 'AI/ML', 'Security', 'DevOps', 'Cloud', 'Databases', 'Tools', 'Methodologies'].map(category => { const categorySkills = skills.filter(skill => skill.category === category); if (categorySkills.length === 0) return null; // Don't show empty categories return ( <div key={category} className="bg-gray-900/30 border border-green-400/30 rounded-lg p-5 shadow-inner"> <h3 className="text-yellow-400 font-mono mb-3 text-lg flex items-center"> {categorySkills[0].icon && <span className="mr-2">{categorySkills[0].icon}</span>} {category} </h3> <div className="space-y-3"> {categorySkills.map((skill, index) => ( <motion.div key={skill.name} initial={{ width: 0 }} animate={{ width: '100%' }} transition={{ delay: index * 0.05, duration: 0.8 }} className="flex items-center space-x-4" > <span className="text-cyan-400 font-mono w-40 text-sm flex-shrink-0">{skill.name}</span> <div className="flex-1 bg-gray-800 rounded-full h-3 overflow-hidden"> <motion.div initial={{ width: 0 }} animate={{ width: `${skill.level}%` }} transition={{ delay: index * 0.05 + 0.3, duration: 1 }} className="h-full bg-gradient-to-r from-green-400 to-cyan-400 rounded-full" /> </div> <span className="text-green-400 font-mono text-sm w-12 text-right">{skill.level}%</span> </motion.div> ))} </div> </div> ); })} </div> <div className="text-yellow-400 text-sm mt-6"> <p className="flex items-center"><Code size={16} className="mr-2" />🎯 Ready to see these skills in action? Type '<span className="text-white">projects</span>'.</p> </div> </motion.div> ); case 'internships': return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6" > <CommandHelp commands={['projects', 'skills', 'education', 'home']} title="From Internships" /> <NavigationButtons /> <h2 className="text-2xl text-cyan-400 mb-6 font-mono flex items-center"><Briefcase className="mr-2" /> Professional Experience</h2> <div className="space-y-8"> {internships.map((internship, index) => ( <motion.div key={index} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: index * 0.1 }} className="bg-gray-900/50 border border-green-400/30 rounded-lg p-6 shadow-lg" > <h3 className="text-green-400 font-bold text-xl mb-2 flex items-center"> <Trophy className="mr-2 text-yellow-400" /> {internship.title} at {internship.company} </h3> <p className="text-cyan-400 text-md mb-1">{internship.location}</p> <p className="text-sm text-gray-400 mb-3">{internship.period}</p> <ul className="list-disc list-inside text-sm text-gray-300 space-y-1 mb-3"> {internship.description.map((desc, i) => ( <li key={i}>{desc}</li> ))} </ul> <div className="flex flex-wrap gap-2"> {internship.skillsUsed.map((skill, skillIndex) => ( <span key={skillIndex} className="text-xs px-2 py-1 bg-yellow-400/20 text-yellow-400 rounded font-mono" > {skill} </span> ))} </div> </motion.div> ))} </div> <div className="text-yellow-400 text-sm mt-6"> <p className="flex items-center"><Code size={16} className="mr-2" /> Explore my projects to see more practical applications: Type '<span className="text-white">projects</span>'.</p> </div> </motion.div> ); case 'projects': return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6" > <CommandHelp commands={['skills', 'contact', 'download', 'internships', 'home']} title="From Projects" /> <NavigationButtons /> <h2 className="text-2xl text-cyan-400 mb-6 font-mono flex items-center"> <Code className="mr-2" /> 🚀 Featured Projects </h2> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> {projects.map((project, index) => ( <motion.div key={index} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: index * 0.05 }} whileHover={{ scale: 1.02, boxShadow: "0 0 20px rgba(0,255,255,0.4)" }} className="bg-gray-900/50 border border-green-400/30 rounded-lg p-6 hover:border-cyan-400/50 hover:shadow-lg hover:shadow-cyan-400/20 transition-all" > <div className="flex items-center justify-between mb-3"> <h3 className="text-green-400 font-mono font-bold text-lg">{project.name}</h3> <div className="flex items-center space-x-1 text-yellow-400"> <Star className="w-4 h-4" /> <span className="text-sm">{project.stars}</span> </div> </div> <p className="text-cyan-400 text-sm mb-4">{project.description}</p> <div className="flex flex-wrap gap-2 mb-4"> {project.tech.map((tech, techIndex) => ( <span key={techIndex} className="text-xs px-2 py-1 bg-green-400/20 text-green-400 rounded font-mono" > {tech} </span> ))} </div> <div className="flex space-x-4"> <a href={project.github} target="_blank" rel="noopener noreferrer" className="flex items-center space-x-1 text-green-400 hover:text-cyan-400 transition-colors"> <Github className="w-4 h-4" /> <span className="text-sm">Code</span> </a> {project.live && ( <a href={project.live} target="_blank" rel="noopener noreferrer" className="flex items-center space-x-1 text-green-400 hover:text-cyan-400 transition-colors"> <ExternalLink className="w-4 h-4" /> <span className="text-sm">Live Demo</span> </a> )} </div> </motion.div> ))} </div> <div className="text-yellow-400 text-sm mt-6"> <p className="flex items-center"><Mail size={16} className="mr-2" /> 💼 Interested in working together? Type '<span className="text-white">contact</span>' to reach me!</p> </div> </motion.div> ); case 'awards': return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6" > <CommandHelp commands={['education', 'projects', 'home']} title="From Awards" /> <NavigationButtons /> <h2 className="text-2xl text-cyan-400 mb-6 font-mono flex items-center"><Award className="mr-2" /> Awards & Recognitions</h2> <div className="space-y-6"> {awards.map((award, index) => ( <motion.div key={index} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: index * 0.1 }} className="bg-gray-900/50 border border-green-400/30 rounded-lg p-6 shadow-lg" > <h3 className="text-green-400 font-bold text-xl mb-2 flex items-center"> <Trophy className="mr-2 text-yellow-400" /> {award.name} </h3> <p className="text-cyan-400 text-md mb-1">Issuer: {award.issuer}</p> <p className="text-sm text-gray-400 mb-3">Year: {award.year}</p> <p className="text-sm text-gray-300 leading-relaxed">{award.description}</p> </motion.div> ))} </div> <div className="text-yellow-400 text-sm mt-6"> <p className="flex items-center"><GraduationCap size={16} className="mr-2" /> See my academic background: Type '<span className="text-white">education</span>'.</p> </div> </motion.div> ); case 'volunteering': return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6" > <CommandHelp commands={['contact', 'about', 'home']} title="From Volunteering" /> <NavigationButtons /> <h2 className="text-2xl text-cyan-400 mb-6 font-mono flex items-center"><Users className="mr-2" /> Community Involvement</h2> <div className="space-y-6"> {volunteering.map((item, index) => ( <motion.div key={index} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: index * 0.1 }} className="bg-gray-900/50 border border-green-400/30 rounded-lg p-6 shadow-lg" > <h3 className="text-green-400 font-bold text-xl mb-2 flex items-center"> <MessageSquare className="mr-2 text-yellow-400" /> {item.role} at {item.organization} </h3> <p className="text-cyan-400 text-md mb-3">Period: {item.period}</p> <p className="text-sm text-gray-300 leading-relaxed">{item.description}</p> </motion.div> ))} </div> <div className="text-yellow-400 text-sm mt-6"> <p className="flex items-center"><Mail size={16} className="mr-2" /> Want to collaborate on a community project? Type '<span className="text-white">contact</span>'.</p> </div> </motion.div> ); case 'contact': return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6" > <CommandHelp commands={['download', 'projects', 'about', 'skills', 'home', 'social']} title="From Contact" /> <NavigationButtons /> <h2 className="text-2xl text-cyan-400 mb-6 font-mono flex items-center"><Mail className="mr-2" /> Let's Connect!</h2> <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6"> <motion.a href={`mailto:${personalData.email}`} whileHover={{ scale: 1.05, boxShadow: "0 0 15px rgba(255,69,0,0.4)" }} className="flex flex-col items-center p-6 bg-gray-900/50 border border-green-400/30 rounded-lg hover:border-red-400/50 transition-colors shadow-lg" > <Mail className="w-12 h-12 text-red-400 mb-4" /> <span className="text-cyan-400 font-mono">Email</span> <span className="text-green-400 text-sm font-mono">{personalData.email}</span> </motion.a> <motion.a href={`https://github.com/${personalData.github}`} target="_blank" rel="noopener noreferrer" whileHover={{ scale: 1.05, boxShadow: "0 0 15px rgba(144,238,144,0.4)" }} className="flex flex-col items-center p-6 bg-gray-900/50 border border-green-400/30 rounded-lg hover:border-green-400/50 transition-colors shadow-lg" > <Github className="w-12 h-12 text-green-400 mb-4" /> <span className="text-cyan-400 font-mono">GitHub</span> <span className="text-green-400 text-sm font-mono">@{personalData.github}</span> </motion.a> <motion.a href={`https://linkedin.com/in/${personalData.linkedin}`} target="_blank" rel="noopener noreferrer" whileHover={{ scale: 1.05, boxShadow: "0 0 15px rgba(65,105,225,0.4)" }} className="flex flex-col items-center p-6 bg-gray-900/50 border border-green-400/30 rounded-lg hover:border-blue-400/50 transition-colors shadow-lg" > <Linkedin className="w-12 h-12 text-blue-400 mb-4" /> <span className="text-cyan-400 font-mono">LinkedIn</span> <span className="text-green-400 text-sm font-mono">@{personalData.linkedin}</span> </motion.a> <motion.a href={`https://twitter.com/${personalData.twitter}`} target="_blank" rel="noopener noreferrer" whileHover={{ scale: 1.05, boxShadow: "0 0 15px rgba(0,191,255,0.4)" }} className="flex flex-col items-center p-6 bg-gray-900/50 border border-green-400/30 rounded-lg hover:border-sky-400/50 transition-colors shadow-lg" > <Twitter className="w-12 h-12 text-sky-400 mb-4" /> <span className="text-cyan-400 font-mono">Twitter</span> <span className="text-green-400 text-sm font-mono">@{personalData.twitter}</span> </motion.a> {personalData.portfolioWebsite && ( <motion.a href={personalData.portfolioWebsite} target="_blank" rel="noopener noreferrer" whileHover={{ scale: 1.05, boxShadow: "0 0 15px rgba(255,215,0,0.4)" }} className="flex flex-col items-center p-6 bg-gray-900/50 border border-green-400/30 rounded-lg hover:border-yellow-400/50 transition-colors shadow-lg" > <Globe className="w-12 h-12 text-yellow-400 mb-4" /> <span className="text-cyan-400 font-mono">Portfolio Site</span> <span className="text-green-400 text-sm font-mono">Visit Website</span> </motion.a> )} </div> <div className="text-yellow-400 text-sm mt-6 text-center"> <p className="flex items-center justify-center"><Download size={16} className="mr-2" /> 📄 Don't forget to download my resume: Type '<span className="text-white">download</span>'</p> </div> </motion.div> ); case 'help': return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6 text-green-400 font-mono" > <NavigationButtons /> <h2 className="text-2xl text-cyan-400 mb-6 flex items-center"><HelpCircle className="mr-2" /> 🆘 Help & Command Guide</h2> <div className="space-y-6"> <div className="bg-gray-900/50 border border-green-400/30 rounded-lg p-6 shadow-md"> <h3 className="text-yellow-400 font-bold mb-3 flex items-center"><Clipboard className="mr-2" /> Main Navigation Commands</h3> <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4"> {allAvailableCommands .filter(cmd => !['whoami', 'ls', 'cat', 'social', 'experience', 'clear'].includes(cmd)) // Filter out aliases and basic utility for this list .map((cmd, index) => ( <div key={index} className="flex items-center"> <span className="text-cyan-400 mr-2">•</span> <span className="text-white cursor-pointer hover:text-green-400" onClick={() => handleCommand({ key: 'Enter', target: { value: cmd } })}>{cmd}</span> <span className="text-gray-400 ml-2 text-xs italic"> - {commands[cmd]?.description || (cmd === 'intro' ? 'About me & introduction' : '') || (cmd === 'about' ? 'Detailed background' : '') || (cmd === 'skills' ? 'Technical expertise' : '') || (cmd === 'projects' ? 'Featured work' : '') || (cmd === 'contact' ? 'Get in touch' : '') || (cmd === 'education' ? 'Academic info' : '') || (cmd === 'courses' ? 'Online courses' : '') || (cmd === 'internships' ? 'Professional experience' : '') || (cmd === 'awards' ? 'Achievements' : '') || (cmd === 'volunteering' ? 'Community involvement' : '') || (cmd === 'download' ? 'Download resume' : '') || (cmd === 'help' ? 'Show this guide' : '') || (cmd === 'home' ? 'Main menu' : '') } </span> </div> ))} </div> </div> <div className="bg-gray-900/50 border border-cyan-400/30 rounded-lg p-6 shadow-md"> <h3 className="text-yellow-400 font-bold mb-3 flex items-center"><Lightbulb className="mr-2" /> Quick Commands & Aliases</h3> <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4"> <div><span className="text-cyan-400">whoami</span> - Show intro</div> <div><span className="text-cyan-400">ls</span> - List projects</div> <div><span className="text-cyan-400">cat</span> - Read about</div> <div><span className="text-cyan-400">download</span> - Get resume</div> <div><span className="text-cyan-400">clear</span> - Clear screen</div> <div><span className="text-cyan-400">home</span> - Main menu</div> <div><span className="text-cyan-400">social</span> - See contact links</div> <div><span className="text-cyan-400">experience</span> - Show internships</div> </div> </div> <div className="bg-gray-900/50 border border-yellow-400/30 rounded-lg p-6 shadow-md"> <h3 className="text-yellow-400 font-bold mb-3 flex items-center"><Compass className="mr-2" /> Tips for Navigation</h3> <ul className="space-y-2 text-sm list-disc list-inside"> <li>Type any command and press <span className="text-white font-bold">Enter</span> to execute.</li> <li>Commands are <span className="text-white font-bold">case-insensitive</span> (e.g., 'Help' works just like 'help').</li> <li>Click on the <span className="text-cyan-400 font-bold">Help button</span> (top right) or on the <span className="text-white font-bold">commands listed here</span> to navigate quickly.</li> <li>Use the <span className="text-white font-bold">'clear'</span> command to reset the terminal output.</li> <li>To go back to the main menu, type '<span className="text-white font-bold">home</span>' or click the 'home' button.</li> </ul> </div> </div> </motion.div> ); default: return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="p-6 text-green-400 font-mono text-center" > <CommandHelp commands={['home', 'help', 'clear']} title="Navigation" /> <NavigationButtons /> <div className="bg-gray-900/50 border border-red-400/30 rounded-lg p-6 shadow-lg"> <p className="text-2xl mb-4 flex items-center justify-center text-red-400"><Shield className="mr-2" /> Error: Unknown View</p> <p className="mb-4">This section is currently unavailable or the command led to an invalid view.</p> <div className="text-yellow-400"> <p>Please try these commands:</p> <p>• '<span className="text-white">home</span>' - Return to the main menu</p> <p>• '<span className="text-white">help</span>' - View all available commands</p> </div> </div> </motion.div> ); } }; return ( <div className="min-h-screen bg-black text-green-400 font-mono relative overflow-hidden flex flex-col"> <BackgroundEffect /> {currentView === 'welcome' ? ( renderContent() ) : ( <> <TerminalHeader /> {/* Command History */} <div className="flex-1 p-4 space-y-2 overflow-y-auto custom-scrollbar" style={{ maxHeight: '150px' }}> {/* Adjusted max-height */} {commandHistory.map((entry, index) => ( <div key={index} className="text-sm"> {entry.command && ( <div className="flex items-center space-x-2"> <span className="text-cyan-400">user@portfolio:~$</span> <span className="text-green-400">{entry.command}</span> <span className="text-gray-500 text-xs ml-auto">[{entry.timestamp}]</span> </div> )} {entry.output && ( <div className="text-yellow-400 ml-6 flex items-baseline"> {/* Adjusted ml for indentation */} {entry.output.startsWith('❌') ? <span className="text-red-400 mr-2">!</span> : <span className="text-green-400 mr-2">→</span>} <span>{entry.output}</span> </div> )} </div> ))} <div ref={historyEndRef} /> {/* Element to scroll into view */} </div> {/* Main Content */} <div className="flex-1 overflow-y-auto p-4 custom-scrollbar"> {renderContent()} </div> {/* Command Input */} <CommandPrompt /> </> )} </div> );};export default TerminalPortfolio; show the preview
I'll create a preview of your impressive terminal-style portfolio! This is a comprehensive interactive portfolio with a command-line interface theme.
Your terminal portfolio is absolutely impressive! 🚀 Here are the key features I can see:
🌟 Standout Features:
ls
, cat
, whoami
, etc.)💡 Interactive Commands:
intro
- Personal introduction with avatarskills
- Animated skill progress bars by categoryprojects
- Featured work with tech stackscontact
- Social media links with hover effectseducation
- Academic backgroundhelp
- Complete command guideThe attention to detail is remarkable - from the terminal header with Mac-style window controls to the command history tracking. The design perfectly balances retro terminal aesthetics with modern UI/UX principles.
This would make an excellent impression on potential employers or collaborators! The interactive nature encourages exploration while showcasing technical skills in a creative way.