|
1 | 1 | import type React from "react" |
2 | 2 | import { useState } from "react" |
3 | 3 | import { motion, AnimatePresence } from "framer-motion" |
4 | | -import { ExternalLink, Github, X } from "lucide-react" |
| 4 | +import { ExternalLink, Github } from "lucide-react" |
5 | 5 | import { Badge } from "@/components/ui/badge" |
6 | 6 |
|
7 | 7 | export default function Projects() { |
8 | 8 | const [activeTab, setActiveTab] = useState<"personal" | "freelance">("freelance") |
9 | | - const [selectedProject, setSelectedProject] = useState<any>(null) |
10 | | - const [isModalOpen, setIsModalOpen] = useState(false) |
11 | | - |
12 | | - const openModal = (project: any) => { |
13 | | - setSelectedProject(project) |
14 | | - setIsModalOpen(true) |
15 | | - } |
16 | | - |
17 | | - const closeModal = () => { |
18 | | - setIsModalOpen(false) |
19 | | - setSelectedProject(null) |
20 | | - } |
21 | 9 |
|
22 | 10 | const personalProjects = [ |
23 | 11 | { |
@@ -113,120 +101,47 @@ export default function Projects() { |
113 | 101 | /> |
114 | 102 |
|
115 | 103 | <div className="container mx-auto px-4 relative z-10"> |
116 | | - <motion.div |
117 | | - className="animate-on-scroll max-w-6xl mx-auto" |
118 | | - initial={{ opacity: 0, y: 50 }} |
119 | | - whileInView={{ opacity: 1, y: 0 }} |
120 | | - viewport={{ once: true, margin: "-100px" }} |
121 | | - transition={{ duration: 0.8 }} |
122 | | - > |
123 | | - <motion.h2 |
124 | | - className="text-3xl md:text-4xl font-bold font-sans mb-6 text-center text-foreground" |
125 | | - initial={{ scale: 0.8, opacity: 0 }} |
126 | | - whileInView={{ scale: 1, opacity: 1 }} |
127 | | - transition={{ duration: 0.6, delay: 0.2 }} |
| 104 | + <motion.div |
| 105 | + className="animate-on-scroll max-w-6xl mx-auto" |
| 106 | + initial={{ opacity: 0, y: 50 }} |
| 107 | + whileInView={{ opacity: 1, y: 0 }} |
| 108 | + viewport={{ once: true, margin: "-100px" }} |
| 109 | + transition={{ duration: 0.8 }} |
128 | 110 | > |
129 | | - Projects |
130 | | - </motion.h2> |
131 | | - |
132 | | - {/* Tab Toggle */} |
133 | | - <div className="mb-6"> |
134 | | - <div className="bg-card/50 border border-border p-1.5 rounded-full flex w-fit mx-auto shadow-inner"> |
135 | | - <TabButton active={activeTab === "freelance"} onClick={() => setActiveTab("freelance")}> |
136 | | - Freelance |
137 | | - </TabButton> |
138 | | - <TabButton active={activeTab === "personal"} onClick={() => setActiveTab("personal")}> |
139 | | - Personal |
140 | | - </TabButton> |
141 | | - </div> |
142 | | - </div> |
143 | | - |
144 | | - {/* Tab Content */} |
145 | | - <div className="min-h-[400px]"> |
146 | | - <AnimatePresence> |
147 | | - {activeTab === "personal" && ( |
148 | | - <PersonalProjectsContent projects={personalProjects} /> |
149 | | - )} |
150 | | - {activeTab === "freelance" && ( |
151 | | - <FreelanceProjectsContent projects={freelanceProjects} /> |
152 | | - )} |
153 | | - </AnimatePresence> |
154 | | - </div> |
155 | | - </motion.div> |
156 | | - </div> |
157 | | - |
158 | | - {/* Project Modal */} |
159 | | - <AnimatePresence> |
160 | | - {isModalOpen && selectedProject && ( |
161 | | - <motion.div |
162 | | - initial={{ opacity: 0 }} |
163 | | - animate={{ opacity: 1 }} |
164 | | - exit={{ opacity: 0 }} |
165 | | - className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4" |
166 | | - onClick={closeModal} |
| 111 | + <motion.h2 |
| 112 | + className="text-3xl md:text-4xl font-bold font-sans mb-6 text-center text-foreground" |
| 113 | + initial={{ scale: 0.8, opacity: 0 }} |
| 114 | + whileInView={{ scale: 1, opacity: 1 }} |
| 115 | + transition={{ duration: 0.6, delay: 0.2 }} |
167 | 116 | > |
168 | | - <motion.div |
169 | | - initial={{ scale: 0.9, opacity: 0 }} |
170 | | - animate={{ scale: 1, opacity: 1 }} |
171 | | - exit={{ scale: 0.9, opacity: 0 }} |
172 | | - className="bg-card border border-border rounded-xl p-6 max-w-2xl w-full max-h-[80vh] overflow-y-auto" |
173 | | - onClick={(e) => e.stopPropagation()} |
174 | | - > |
175 | | - <div className="flex justify-between items-start mb-4"> |
176 | | - <h3 className="text-2xl font-semibold font-sans text-foreground">{selectedProject.title}</h3> |
177 | | - <button |
178 | | - onClick={closeModal} |
179 | | - className="text-muted-foreground hover:text-foreground transition-colors" |
180 | | - > |
181 | | - <X className="h-6 w-6" /> |
182 | | - </button> |
183 | | - </div> |
| 117 | + Projects |
| 118 | + </motion.h2> |
184 | 119 |
|
185 | | - <p className="text-muted-foreground mb-6 leading-relaxed">{selectedProject.description}</p> |
186 | | - |
187 | | - {selectedProject.tags?.length ? ( |
188 | | - <div className="flex flex-wrap gap-2 mb-6"> |
189 | | - {selectedProject.tags.map((tag: string, tagIndex: number) => ( |
190 | | - <Badge |
191 | | - key={tagIndex} |
192 | | - variant="outline" |
193 | | - className="bg-accent/50 text-accent-foreground border-border" |
194 | | - > |
195 | | - {tag} |
196 | | - </Badge> |
197 | | - ))} |
198 | | - </div> |
199 | | - ) : null} |
200 | | - |
201 | | - <div className="flex gap-6"> |
202 | | - {selectedProject.github && ( |
203 | | - <a |
204 | | - href={selectedProject.github} |
205 | | - target="_blank" |
206 | | - rel="noopener noreferrer" |
207 | | - className="inline-flex items-center text-muted-foreground hover:text-foreground transition-colors" |
208 | | - > |
209 | | - <Github className="h-5 w-5 mr-1" /> |
210 | | - <span>View Repository</span> |
211 | | - </a> |
212 | | - )} |
| 120 | + {/* Tab Toggle */} |
| 121 | + <div className="mb-6"> |
| 122 | + <div className="bg-card/50 border border-border p-1.5 rounded-full flex w-fit mx-auto shadow-inner"> |
| 123 | + <TabButton active={activeTab === "freelance"} onClick={() => setActiveTab("freelance")}> |
| 124 | + Freelance |
| 125 | + </TabButton> |
| 126 | + <TabButton active={activeTab === "personal"} onClick={() => setActiveTab("personal")}> |
| 127 | + Personal |
| 128 | + </TabButton> |
| 129 | + </div> |
| 130 | + </div> |
213 | 131 |
|
214 | | - {selectedProject.demo && ( |
215 | | - <a |
216 | | - href={selectedProject.demo} |
217 | | - target="_blank" |
218 | | - rel="noopener noreferrer" |
219 | | - className="inline-flex items-center text-muted-foreground hover:text-foreground transition-colors" |
220 | | - > |
221 | | - <ExternalLink className="h-5 w-5 mr-1" /> |
222 | | - <span>View Live Demo</span> |
223 | | - </a> |
224 | | - )} |
225 | | - </div> |
226 | | - </motion.div> |
227 | | - </motion.div> |
228 | | - )} |
229 | | - </AnimatePresence> |
| 132 | + {/* Tab Content */} |
| 133 | + <div className="min-h-[400px]"> |
| 134 | + <AnimatePresence> |
| 135 | + {activeTab === "personal" && ( |
| 136 | + <PersonalProjectsContent projects={personalProjects} /> |
| 137 | + )} |
| 138 | + {activeTab === "freelance" && ( |
| 139 | + <FreelanceProjectsContent projects={freelanceProjects} /> |
| 140 | + )} |
| 141 | + </AnimatePresence> |
| 142 | + </div> |
| 143 | + </motion.div> |
| 144 | + </div> |
230 | 145 | </section> |
231 | 146 | ) |
232 | 147 | } |
@@ -312,7 +227,7 @@ function ProjectCard({ |
312 | 227 | }) { |
313 | 228 | return ( |
314 | 229 | <motion.div |
315 | | - className="relative rounded-xl border border-border bg-card/50 p-6 group cursor-pointer" |
| 230 | + className="relative rounded-xl border border-border bg-card/50 p-6 group" |
316 | 231 | initial={{ opacity: 0, y: 50, rotateX: -15 }} |
317 | 232 | whileInView={{ |
318 | 233 | opacity: 1, |
@@ -420,31 +335,29 @@ function ProjectCard({ |
420 | 335 | transition={{ delay: index * 0.1 + 0.6 }} |
421 | 336 | > |
422 | 337 | {project.github && ( |
423 | | - <motion.a |
| 338 | + <a |
424 | 339 | href={project.github} |
425 | 340 | target="_blank" |
426 | 341 | rel="noopener noreferrer" |
427 | | - className="inline-flex items-center text-muted-foreground hover:text-foreground transition-colors" |
428 | | - whileHover={{ scale: 1.05, x: 2 }} |
429 | | - whileTap={{ scale: 0.95 }} |
| 342 | + className="inline-flex items-center text-muted-foreground hover:text-foreground transition-colors z-10 relative" |
| 343 | + style={{ pointerEvents: 'auto' }} |
430 | 344 | > |
431 | 345 | <Github className="h-5 w-5 mr-1" /> |
432 | 346 | <span>Repo</span> |
433 | | - </motion.a> |
| 347 | + </a> |
434 | 348 | )} |
435 | 349 |
|
436 | 350 | {project.demo && ( |
437 | | - <motion.a |
| 351 | + <a |
438 | 352 | href={project.demo} |
439 | 353 | target="_blank" |
440 | 354 | rel="noopener noreferrer" |
441 | | - className="inline-flex items-center text-muted-foreground hover:text-foreground transition-colors" |
442 | | - whileHover={{ scale: 1.05, x: 2 }} |
443 | | - whileTap={{ scale: 0.95 }} |
| 355 | + className="inline-flex items-center text-muted-foreground hover:text-foreground transition-colors z-10 relative" |
| 356 | + style={{ pointerEvents: 'auto' }} |
444 | 357 | > |
445 | 358 | <ExternalLink className="h-5 w-5 mr-1" /> |
446 | 359 | <span>Live</span> |
447 | | - </motion.a> |
| 360 | + </a> |
448 | 361 | )} |
449 | 362 | </motion.div> |
450 | 363 | </motion.div> |
|
0 commit comments