Skip to main content

Projects

The Projects component creates a showcase section for displaying portfolio projects with interactive SpotlightCard effects, images, descriptions, and action buttons.

Overview

This component provides a clean, centered layout for featuring projects with images, descriptions, and links to live demos and source code. It’s designed to be easily expandable for multiple projects.

Props

The Projects component does not accept props. All project data is defined within the component.

Dependencies

import SpotlightCard from '../SpotlightCard/SpotLightCard';

Usage

import Projects from './components/ProjectsSection/Projects';

function App() {
  return (
    <main>
      <section id="projects">
        <Projects />
      </section>
    </main>
  );
}

Component Structure

function Projects() {
  return (
    <section className="flex flex-col items-center mt-28 px-16 text-[#ECECEC]">
      {/* Header */}
      <div className="flex flex-col items-center text-center mb-8">
        <p className="text-sm tracking-widest uppercase text-white/50 mb-2">PROJECTS</p>
        <h2 className="text-3xl font-bold text-white mb-4">Featured Work</h2>
        <hr className="w-1/4 border-2 border-[#3A3C41] rounded mb-4" />
        <p id="projects" className="text-[#C7C7C7] max-w-lg">
          A little showcase of my recent projects using modern frameworks and creative problem-solving.
        </p>
      </div>

      {/* Project Cards Grid */}
      <div className="flex justify-center p-8 w-full">
        {/* Individual project cards */}
      </div>
    </section>
  );
}

Features

Section Header

Includes:
  • Small uppercase label (“PROJECTS”)
  • Main heading (“Featured Work”)
  • Decorative divider line
  • Descriptive paragraph
  • Anchor ID for navigation

Project Card Structure

Each project card contains:
  • Project image/screenshot
  • Project title
  • Project description
  • Technology stack (mentioned in description)
  • Action buttons (Code & Preview)

Example Project Card

<SpotlightCard className="w-[320px]" spotlightColor="rgba(0, 229, 255, 0.2)">
  <div className="flex flex-col items-center gap-4 rounded-2xl p-6">
    <img src={Project1} alt="Music Store" className="w-full rounded-xl object-cover" />
    <div className="flex flex-col items-center gap-3 text-center">
      <h2 className="text-xl font-semibold text-white">Music Store</h2>
      <p className="text-[#C7C7C7] text-sm">
        Full stack music instrument store built with React, Tailwind and Supabase. 
        Features product catalog, brand filters, shopping cart and GSAP animations.
      </p>
      <div className="flex gap-3 py-7">
        <a href="https://github.com/JDiazRzo/MusicStore" target="_blank" rel="noopener noreferrer">
          <button className="bg-white/10 backdrop-blur-md text-white px-5 py-3 rounded-xl text-sm font-medium border border-white/20 hover:bg-white/20 hover:-translate-y-0.5 active:translate-y-0 transition-all duration-200 shadow-lg">
            Code
          </button>
        </a>
        <a href="https://music-store-xi-opal.vercel.app/" target="_blank" rel="noopener noreferrer">
          <button className="bg-white/10 backdrop-blur-md text-white px-5 py-3 rounded-xl text-sm font-medium border border-white/20 hover:bg-white/20 hover:-translate-y-0.5 active:translate-y-0 transition-all duration-200 shadow-lg">
            Preview
          </button>
        </a>
      </div>
    </div>
  </div>
</SpotlightCard>

Customization

Adding Multiple Projects

import Project1 from '/img/Project1.png';
import Project2 from '/img/Project2.png';
import Project3 from '/img/Project3.png';

function Projects() {
  const projects = [
    {
      image: Project1,
      title: "Music Store",
      description: "Full stack music instrument store built with React, Tailwind and Supabase.",
      codeUrl: "https://github.com/JDiazRzo/MusicStore",
      previewUrl: "https://music-store-xi-opal.vercel.app/"
    },
    {
      image: Project2,
      title: "Project 2",
      description: "Description of project 2...",
      codeUrl: "https://github.com/username/project2",
      previewUrl: "https://project2.vercel.app/"
    },
    // Add more projects...
  ];

  return (
    <section className="flex flex-col items-center mt-28 px-16 text-[#ECECEC]">
      {/* Header */}
      <div className="flex justify-center p-8 w-full">
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
          {projects.map((project, index) => (
            <SpotlightCard key={index} className="w-[320px]" spotlightColor="rgba(0, 229, 255, 0.2)">
              <div className="flex flex-col items-center gap-4 rounded-2xl p-6">
                <img src={project.image} alt={project.title} className="w-full rounded-xl object-cover" />
                <div className="flex flex-col items-center gap-3 text-center">
                  <h2 className="text-xl font-semibold text-white">{project.title}</h2>
                  <p className="text-[#C7C7C7] text-sm">{project.description}</p>
                  <div className="flex gap-3 py-7">
                    <a href={project.codeUrl} target="_blank" rel="noopener noreferrer">
                      <button className="bg-white/10 backdrop-blur-md text-white px-5 py-3 rounded-xl text-sm font-medium border border-white/20 hover:bg-white/20 hover:-translate-y-0.5 active:translate-y-0 transition-all duration-200 shadow-lg">
                        Code
                      </button>
                    </a>
                    <a href={project.previewUrl} target="_blank" rel="noopener noreferrer">
                      <button className="bg-white/10 backdrop-blur-md text-white px-5 py-3 rounded-xl text-sm font-medium border border-white/20 hover:bg-white/20 hover:-translate-y-0.5 active:translate-y-0 transition-all duration-200 shadow-lg">
                        Preview
                      </button>
                    </a>
                  </div>
                </div>
              </div>
            </SpotlightCard>
          ))}
        </div>
      </div>
    </section>
  );
}

Customizing Section Header

<div className="flex flex-col items-center text-center mb-8">
  <p className="text-sm tracking-widest uppercase text-white/50 mb-2">
    [YOUR LABEL]
  </p>
  <h2 className="text-3xl font-bold text-white mb-4">
    [Your Heading]
  </h2>
  <hr className="w-1/4 border-2 border-[#3A3C41] rounded mb-4" />
  <p className="text-[#C7C7C7] max-w-lg">
    [Your description]
  </p>
</div>

Alternative Button Styles

{/* Solid Button */}
<button className="bg-blue-600 text-white px-5 py-3 rounded-xl text-sm font-medium hover:bg-blue-700 transition-all duration-200 shadow-lg">
  Code
</button>

{/* Outline Button */}
<button className="bg-transparent text-white px-5 py-3 rounded-xl text-sm font-medium border-2 border-white hover:bg-white hover:text-black transition-all duration-200">
  Code
</button>

{/* Gradient Button */}
<button className="bg-gradient-to-r from-purple-500 to-blue-500 text-white px-5 py-3 rounded-xl text-sm font-medium hover:opacity-90 transition-opacity duration-200 shadow-lg">
  Code
</button>

Grid Layout for Multiple Projects

<div className="flex justify-center p-8 w-full">
  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-7xl">
    {/* Project cards */}
  </div>
</div>

Responsive Design

Current Layout

  • Centered single column layout
  • Works on all screen sizes
  • Fixed card width (320px)

Responsive Grid Example

<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-8">
  {/* Cards adjust to grid */}
</div>

Styling Details

Section Spacing

className="flex flex-col items-center mt-28 px-16 text-[#ECECEC]"
  • mt-28: Top margin (112px)
  • px-16: Horizontal padding (64px)
  • Centered items
  • Light gray text color

Card Dimensions

className="w-[320px]"
  • Fixed width of 320px
  • Height adjusts to content
  • Internal padding of 24px (p-6)

Image Styling

className="w-full rounded-xl object-cover"
  • Full width within card
  • Rounded corners (12px)
  • Object-fit cover maintains aspect ratio

Button Hover Effects

className="hover:bg-white/20 hover:-translate-y-0.5 active:translate-y-0 transition-all duration-200"
  • Background lightens on hover
  • Subtle upward movement
  • Returns to position on click
  • Smooth 200ms transitions

Best Practices

Image Optimization

Optimize project images for web to improve loading performance:
# Recommended dimensions
- Width: 640px (2x the display size)
- Format: WebP or optimized PNG/JPG
- Compression: 80-85% quality

Descriptive Content

  1. Title: Clear, concise project name
  2. Description: Highlight key technologies and features
  3. Links: Ensure both GitHub and live demo work
  4. Alt Text: Descriptive alt text for images

Accessibility

{/* Proper link attributes */}
<a href="..." target="_blank" rel="noopener noreferrer">
  <button aria-label="View project code on GitHub">
    Code
  </button>
</a>

{/* Descriptive image alt */}
<img src={Project1} alt="Music Store project screenshot showing product catalog" />

File Structure

src/
├── components/
│   ├── ProjectsSection/
│   │   └── Projects.jsx
│   └── SpotlightCard/
│       └── SpotLightCard.jsx
└── public/
    └── img/
        ├── Project1.png
        ├── Project2.png
        └── Project3.png

Project Card Variations

With Technology Tags

<div className="flex flex-col items-center gap-3 text-center">
  <h2 className="text-xl font-semibold text-white">Project Title</h2>
  <p className="text-[#C7C7C7] text-sm">Project description...</p>
  
  {/* Technology tags */}
  <div className="flex flex-wrap gap-2 justify-center">
    <span className="px-2 py-1 bg-blue-500/20 text-blue-300 text-xs rounded-md">React</span>
    <span className="px-2 py-1 bg-green-500/20 text-green-300 text-xs rounded-md">Node.js</span>
    <span className="px-2 py-1 bg-purple-500/20 text-purple-300 text-xs rounded-md">MongoDB</span>
  </div>
  
  {/* Buttons */}
</div>

With Status Badge

<div className="relative">
  <span className="absolute top-2 right-2 px-3 py-1 bg-green-500 text-white text-xs font-semibold rounded-full">
    Live
  </span>
  <img src={Project1} alt="Project" className="w-full rounded-xl object-cover" />
</div>
Make sure all external links (GitHub repos and live demos) are accessible and working before deploying.

Build docs developers (and LLMs) love