110 lines
4.7 KiB
TypeScript
110 lines
4.7 KiB
TypeScript
import React from 'react';
|
|
import { ExternalLink, Github } from 'lucide-react';
|
|
|
|
const Portfolio: React.FC = () => {
|
|
const projects = [
|
|
{
|
|
title: 'E-Commerce Platform',
|
|
description: 'A full-stack e-commerce solution with React, Node.js, and Stripe integration.',
|
|
image: 'https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80',
|
|
tags: ['React', 'Node.js', 'MongoDB', 'Stripe'],
|
|
liveUrl: '#',
|
|
githubUrl: '#'
|
|
},
|
|
{
|
|
title: 'Task Management App',
|
|
description: 'A collaborative project management tool with real-time updates and team features.',
|
|
image: 'https://images.unsplash.com/photo-1611224923853-80b023f02d71?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80',
|
|
tags: ['Vue.js', 'Firebase', 'Tailwind CSS'],
|
|
liveUrl: '#',
|
|
githubUrl: '#'
|
|
},
|
|
{
|
|
title: 'Weather Dashboard',
|
|
description: 'A responsive weather application with location-based forecasts and data visualization.',
|
|
image: 'https://images.unsplash.com/photo-1504608524841-42fe6f032b4b?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80',
|
|
tags: ['React', 'TypeScript', 'Chart.js', 'API'],
|
|
liveUrl: '#',
|
|
githubUrl: '#'
|
|
}
|
|
];
|
|
|
|
return (
|
|
<section className="py-20 bg-background">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div className="text-center">
|
|
<h2 className="text-3xl font-bold text-text sm:text-4xl">
|
|
Featured Projects
|
|
</h2>
|
|
<p className="mt-4 text-lg text-lines max-w-2xl mx-auto">
|
|
A showcase of my recent work and creative solutions
|
|
</p>
|
|
</div>
|
|
|
|
<div className="mt-16 grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-3">
|
|
{projects.map((project, index) => (
|
|
<div
|
|
key={project.title}
|
|
className="bg-background-light rounded-xl shadow-lg overflow-hidden hover:shadow-xl transition-all duration-300 transform hover:-translate-y-2 group border border-lines"
|
|
>
|
|
<div className="relative overflow-hidden">
|
|
<img
|
|
className="w-full h-48 object-cover group-hover:scale-110 transition-transform duration-300"
|
|
src={project.image}
|
|
alt={project.title}
|
|
loading="lazy"
|
|
/>
|
|
<div className="absolute inset-0 bg-gradient-to-t from-background/80 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
<div className="absolute top-4 right-4 flex space-x-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
|
<a
|
|
href={project.liveUrl}
|
|
className="p-2 bg-boxes rounded-full hover:bg-other transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-lines focus:ring-offset-2"
|
|
aria-label={`View ${project.title} live`}
|
|
>
|
|
<ExternalLink className="h-4 w-4 text-text" />
|
|
</a>
|
|
<a
|
|
href={project.githubUrl}
|
|
className="p-2 bg-boxes rounded-full hover:bg-other transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-lines focus:ring-offset-2"
|
|
aria-label={`View ${project.title} source code`}
|
|
>
|
|
<Github className="h-4 w-4 text-text" />
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div className="p-6">
|
|
<h3 className="text-xl font-semibold text-text mb-2">
|
|
{project.title}
|
|
</h3>
|
|
<p className="text-lines mb-4">
|
|
{project.description}
|
|
</p>
|
|
<div className="flex flex-wrap gap-2">
|
|
{project.tags.map((tag) => (
|
|
<span
|
|
key={tag}
|
|
className="px-3 py-1 text-xs font-medium bg-boxes text-other rounded-full"
|
|
>
|
|
{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="text-center mt-12">
|
|
<a
|
|
href="/portfolio"
|
|
className="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-lg text-background bg-other hover:bg-lines focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-other transition-all duration-200 transform hover:scale-105"
|
|
>
|
|
View All Projects
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default Portfolio; |