|
1 | 1 | import { useState, useEffect } from 'react'; |
2 | 2 | import { motion, useInView } from 'framer-motion'; |
3 | 3 | import { useRef } from 'react'; |
4 | | -import { Star, GitFork, ExternalLink, Github, Loader } from 'lucide-react'; |
| 4 | +import { Star, GitFork, ExternalLink, Github, Loader, Rocket, AlertCircle } from 'lucide-react'; |
5 | 5 | import { fetchGitHubRepos } from '../utils/github'; |
6 | 6 |
|
| 7 | +// Manually defined featured full-stack project (private repo) |
| 8 | +const chronosDevTracker = { |
| 9 | + id: 'chronos-devtracker', |
| 10 | + name: 'Chronos DevTracker', |
| 11 | + description: 'Portfolio-ready full-stack project management application showcasing TypeScript across React (Vite) frontend and Express + Prisma backend with PostgreSQL, JWT auth, and automated E2E tests (Playwright).', |
| 12 | + demoUrl: 'https://ammarahmedl200961.github.io/chronos-devtracker-pm/', |
| 13 | + apiUrl: 'https://chronos-devtracker-pm.onrender.com/api', |
| 14 | + topics: ['TypeScript', 'React', 'Express', 'Prisma', 'PostgreSQL', 'Playwright'], |
| 15 | + isFullStack: true, |
| 16 | +}; |
| 17 | + |
7 | 18 | const Projects = () => { |
8 | 19 | const ref = useRef(null); |
9 | 20 | const isInView = useInView(ref, { once: true, margin: "-100px" }); |
@@ -95,6 +106,84 @@ const Projects = () => { |
95 | 106 | animate={isInView ? "visible" : "hidden"} |
96 | 107 | className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 place-items-stretch" |
97 | 108 | > |
| 109 | + {/* Chronos DevTracker - Featured Full-Stack Project Card */} |
| 110 | + <motion.div |
| 111 | + key={chronosDevTracker.id} |
| 112 | + variants={cardVariants} |
| 113 | + whileHover={{ |
| 114 | + scale: 1.03, |
| 115 | + y: -8 |
| 116 | + }} |
| 117 | + className="relative group w-full" |
| 118 | + > |
| 119 | + {/* Full-Stack badge */} |
| 120 | + <div className="absolute -top-3 -right-3 z-10"> |
| 121 | + <div className="px-3 py-1 bg-gradient-to-r from-neon-purple to-accent rounded-full text-xs font-bold text-white shadow-lg flex items-center gap-1"> |
| 122 | + <Rocket size={12} /> |
| 123 | + FULL-STACK |
| 124 | + </div> |
| 125 | + </div> |
| 126 | + |
| 127 | + {/* Card */} |
| 128 | + <div className="h-full bg-white/5 backdrop-blur-sm rounded-2xl p-6 border border-white/10 hover:border-neon-purple/50 transition-all duration-300 shadow-xl hover:shadow-[0_0_40px_rgba(183,148,246,0.2)] flex flex-col"> |
| 129 | + {/* Header with gradient accent */} |
| 130 | + <div className="h-2 w-full rounded-full bg-gradient-to-r from-neon-purple to-accent mb-6"></div> |
| 131 | + |
| 132 | + {/* Project Title */} |
| 133 | + <h3 className="text-2xl font-bold text-white mb-3 group-hover:text-neon-purple transition-colors"> |
| 134 | + {chronosDevTracker.name} |
| 135 | + </h3> |
| 136 | + |
| 137 | + {/* Description */} |
| 138 | + <p className="text-gray-400 mb-6 flex-grow"> |
| 139 | + {chronosDevTracker.description} |
| 140 | + </p> |
| 141 | + |
| 142 | + {/* Topics/Tags */} |
| 143 | + <div className="flex flex-wrap gap-2 mb-6"> |
| 144 | + {chronosDevTracker.topics.map((topic, idx) => ( |
| 145 | + <span |
| 146 | + key={idx} |
| 147 | + className="px-3 py-1 bg-neon-purple/20 border border-neon-purple/40 rounded-full text-xs text-neon-purple font-semibold" |
| 148 | + > |
| 149 | + {topic} |
| 150 | + </span> |
| 151 | + ))} |
| 152 | + </div> |
| 153 | + |
| 154 | + {/* API Notice */} |
| 155 | + <div className="mb-4 p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-lg"> |
| 156 | + <div className="flex items-start gap-2 text-xs text-yellow-400"> |
| 157 | + <AlertCircle size={14} className="mt-0.5 flex-shrink-0" /> |
| 158 | + <span> |
| 159 | + API hosted on Render may be sleeping.{' '} |
| 160 | + <a |
| 161 | + href={chronosDevTracker.apiUrl} |
| 162 | + target="_blank" |
| 163 | + rel="noopener noreferrer" |
| 164 | + className="underline hover:text-yellow-300 transition-colors" |
| 165 | + > |
| 166 | + Wake it up here |
| 167 | + </a> |
| 168 | + </span> |
| 169 | + </div> |
| 170 | + </div> |
| 171 | + |
| 172 | + {/* Links */} |
| 173 | + <div className="flex items-center justify-end pt-4 border-t border-white/10"> |
| 174 | + <a |
| 175 | + href={chronosDevTracker.demoUrl} |
| 176 | + target="_blank" |
| 177 | + rel="noopener noreferrer" |
| 178 | + className="inline-flex items-center gap-2 px-4 py-2 bg-gradient-to-r from-neon-purple to-accent rounded-lg text-white font-semibold text-sm hover:shadow-[0_0_20px_rgba(183,148,246,0.5)] transition-all duration-300 hover:scale-105" |
| 179 | + > |
| 180 | + <ExternalLink size={16} /> |
| 181 | + Live Demo |
| 182 | + </a> |
| 183 | + </div> |
| 184 | + </div> |
| 185 | + </motion.div> |
| 186 | + |
98 | 187 | {repos.map((repo, index) => { |
99 | 188 | const isFeatured = featuredProjects.includes(repo.name); |
100 | 189 | return ( |
|
0 commit comments