Skip to content

Commit 3fb0434

Browse files
committed
[ UPDATE ] Modify the UI for Projects
1 parent 2c0a46c commit 3fb0434

File tree

2 files changed

+36
-53
lines changed

2 files changed

+36
-53
lines changed

src/components/ProjectCard.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const ProjectCard = ({ project }) => {
55
const getTechColor = (tech) => techColors[tech] || "bg-white/20 text-white";
66

77
return (
8-
<div className="w-full flex-shrink-0 px-4">
8+
<div className="w-[360px] flex-shrink-0 px-4">
99
<Card className="h-[550px] overflow-hidden relative group">
1010
{/* Background Image */}
1111
<div className="absolute inset-0 w-full h-full">

src/components/Projects.jsx

Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
import { useState, useRef, useCallback } from "react";
1+
import { useState } from "react";
22
import ProjectCard from "./ProjectCard";
33

44
const Projects = () => {
5-
const [activeIndex, setActiveIndex] = useState(0);
6-
const sliderRef = useRef(null);
75

8-
const projects = [
6+
const projectsData = [
97
{
108
id: 1,
119
title: "Portfolio Website",
1210
description: "Personal portfolio website built with React + TailwindCSS.",
1311
image: "projects/portfolio.png",
1412
techStack: ["React", "TailwindCSS", "Vite", "Shadcn/ui"],
1513
status: "completed",
14+
category: "Full-Stack Application",
1615
link: "https://github.com/JjayFabor/portfolio"
1716
},
1817
{
@@ -22,6 +21,7 @@ const Projects = () => {
2221
image: "projects/lettuce-watch.png",
2322
techStack: ["Python", "Flask", "Machine Learning (ML)", "SQLite", "Arduino", "HTML", "CSS", "JavaScript"],
2423
status: "completed",
24+
category: "Full-Stack Application",
2525
link: "https://github.com/JjayFabor/LettuceRealTimeMonitoringSystem"
2626
},
2727
{
@@ -31,6 +31,7 @@ const Projects = () => {
3131
image: "projects/swiftbidder.png",
3232
techStack: ["Laravel", "PHP", "React", "InertiaJS", "TailwindCSS", "MySQL"],
3333
status: "ongoing",
34+
category: "Full-Stack Application",
3435
link: "https://github.com/JjayFabor/swift-bidder"
3536
},
3637
{
@@ -40,75 +41,57 @@ const Projects = () => {
4041
image: "projects/bridgeAI.png",
4142
techStack: ["Python", "GeminiAPI", "Flutter", "Dart", "Flask"],
4243
status: "ongoing",
44+
category: "Mobile Application",
4345
link: "https://github.com/JjayFabor/bridgeAI"
4446
},
4547
];
4648

47-
// Next slide function
48-
const nextSlide = useCallback(() => {
49-
setActiveIndex((prevIndex) => (prevIndex + 1) % projects.length);
50-
}, [projects.length]);
49+
const [selectedCategory, setSelectedCategory] = useState("All");
50+
const categories = ["All", ...new Set(projectsData.map((p) => p.category))];
5151

52-
// Previous slide function
53-
const prevSlide = () => {
54-
setActiveIndex((prevIndex) => (prevIndex - 1 + projects.length) % projects.length);
55-
};
52+
const filteredProjects = selectedCategory === "All"
53+
? projectsData
54+
: projectsData.filter((project) => project.category === selectedCategory);
5655

57-
const goToSlide = (index) => setActiveIndex(index);
5856

5957
return (
6058
<section id="projects" className="py-20">
6159
<div className="max-w-6xl mx-auto px-4">
6260
<h2 className="text-3xl font-bold mb-10 text-center">Projects</h2>
6361

64-
<div className="relative">
62+
<div className="flex justify-center gap-2 mb-10 flex-wrap">
63+
{categories.map((category) => (
6564
<button
66-
onClick={prevSlide}
67-
className="absolute left-0 top-1/2 transform -translate-y-1/2 z-10 bg-white/80 p-2 rounded-full shadow-md hover:bg-white transition-all"
68-
aria-label="Previous project"
65+
key={category}
66+
onClick={() => setSelectedCategory(category)}
67+
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors
68+
${selectedCategory === category
69+
? "bg-primary text-primary-foreground"
70+
: "bg-secondary text-secondary-foreground hover:bg-secondary/80"
71+
}`}
6972
>
70-
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
71-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 19l-7-7 7-7" />
72-
</svg>
73+
{category}
7374
</button>
74-
{/* Slider */}
75-
<div ref={sliderRef} className="overflow-hidden">
76-
<div
77-
className="flex transition-transform duration-500 ease-out"
78-
style={{ transform: `translateX(-${activeIndex * 100}%)` }}
79-
>
80-
{projects.map((project) => (
75+
))}
76+
</div>
77+
78+
{filteredProjects.length > 0 ? (
79+
<div className="overflow-x-auto pb-4">
80+
<div className="flex gap-6">
81+
{filteredProjects.map((project) => (
8182
<ProjectCard key={project.id} project={project} />
8283
))}
8384
</div>
8485
</div>
86+
) : (
87+
<p className="text-center text-gray-500">No projects found in this category.</p>
88+
)}
8589

86-
{/* Next Button */}
87-
<button
88-
onClick={nextSlide}
89-
className="absolute right-0 top-1/2 transform -translate-y-1/2 z-10 bg-white/80 p-2 rounded-full shadow-md hover:bg-white transition-all"
90-
aria-label="Next project"
91-
>
92-
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
93-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7" />
94-
</svg>
95-
</button>
96-
97-
98-
{/* Dots */}
99-
<div className="flex justify-center mt-8 space-x-2">
100-
{projects.map((_, index) => (
101-
<button
102-
key={index}
103-
onClick={() => goToSlide(index)}
104-
className={`w-3 h-3 rounded-full transition-all ${
105-
activeIndex === index ? "bg-blue-500 w-6" : "bg-gray-300"
106-
}`}
107-
aria-label={`Go to slide ${index + 1}`}
108-
/>
109-
))}
90+
{filteredProjects.length > 0 && (
91+
<div className="text-center mt-4 text-sm text-gray-500">
92+
<p>Swipe or scroll to view more projects &rarr;</p>
11093
</div>
111-
</div>
94+
)}
11295
</div>
11396
</section>
11497
);

0 commit comments

Comments
 (0)