144 lines
5.6 KiB
TypeScript
144 lines
5.6 KiB
TypeScript
|
|
import { useRef } from 'react';
|
||
|
|
import { motion, useInView } from 'framer-motion';
|
||
|
|
import { ArrowRight, ExternalLink } from 'lucide-react';
|
||
|
|
import { Link } from 'react-router-dom';
|
||
|
|
import { Button } from '@/components/ui/button';
|
||
|
|
|
||
|
|
const projects = [
|
||
|
|
{
|
||
|
|
title: 'FinTech Dashboard',
|
||
|
|
category: 'Web Application',
|
||
|
|
image: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=600&h=400&fit=crop',
|
||
|
|
color: 'from-neon-blue/80',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: 'Health Tracker App',
|
||
|
|
category: 'Mobile App',
|
||
|
|
image: 'https://images.unsplash.com/photo-1576091160399-112ba8d25d1f?w=600&h=400&fit=crop',
|
||
|
|
color: 'from-neon-purple/80',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: 'AI Content Platform',
|
||
|
|
category: 'AI Solution',
|
||
|
|
image: 'https://images.unsplash.com/photo-1677442136019-21780ecad995?w=600&h=400&fit=crop',
|
||
|
|
color: 'from-neon-green/80',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: 'E-Commerce Suite',
|
||
|
|
category: 'Web Application',
|
||
|
|
image: 'https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?w=600&h=400&fit=crop',
|
||
|
|
color: 'from-neon-blue/80',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: 'Smart IoT Platform',
|
||
|
|
category: 'Cloud Solution',
|
||
|
|
image: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=600&h=400&fit=crop',
|
||
|
|
color: 'from-neon-purple/80',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: 'Learning Management',
|
||
|
|
category: 'Web Application',
|
||
|
|
image: 'https://images.unsplash.com/photo-1501504905252-473c47e087f8?w=600&h=400&fit=crop',
|
||
|
|
color: 'from-neon-green/80',
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
export default function ProjectsSection() {
|
||
|
|
const ref = useRef<HTMLElement>(null);
|
||
|
|
const isInView = useInView(ref, { once: true, margin: '-100px' });
|
||
|
|
|
||
|
|
return (
|
||
|
|
<section id="projects" ref={ref} className="py-24 relative overflow-hidden bg-secondary/30">
|
||
|
|
{/* Background pattern */}
|
||
|
|
<div className="absolute inset-0 opacity-5">
|
||
|
|
<div className="absolute inset-0" style={{
|
||
|
|
backgroundImage: `radial-gradient(circle at 1px 1px, currentColor 1px, transparent 0)`,
|
||
|
|
backgroundSize: '40px 40px',
|
||
|
|
}} />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="container mx-auto px-4 relative z-10">
|
||
|
|
{/* Section Header */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, y: 20 }}
|
||
|
|
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
||
|
|
transition={{ duration: 0.6 }}
|
||
|
|
className="text-center mb-16"
|
||
|
|
>
|
||
|
|
<span className="inline-block px-4 py-1.5 rounded-full glass text-sm font-medium text-primary mb-4">
|
||
|
|
Our Portfolio
|
||
|
|
</span>
|
||
|
|
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-4">
|
||
|
|
Our <span className="text-primary neon-text-glow">Projects</span>
|
||
|
|
</h2>
|
||
|
|
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
||
|
|
Explore our latest work and see how we've helped businesses
|
||
|
|
transform their digital presence.
|
||
|
|
</p>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Projects Grid */}
|
||
|
|
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6 mb-12">
|
||
|
|
{projects.map((project, index) => (
|
||
|
|
<motion.div
|
||
|
|
key={project.title}
|
||
|
|
initial={{ opacity: 0, y: 30 }}
|
||
|
|
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
||
|
|
transition={{ duration: 0.5, delay: index * 0.1 }}
|
||
|
|
whileHover={{ y: -8 }}
|
||
|
|
className="group relative rounded-2xl overflow-hidden cursor-pointer"
|
||
|
|
>
|
||
|
|
{/* Image */}
|
||
|
|
<div className="aspect-[4/3] overflow-hidden">
|
||
|
|
<img
|
||
|
|
src={project.image}
|
||
|
|
alt={project.title}
|
||
|
|
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Overlay */}
|
||
|
|
<div className={`absolute inset-0 bg-gradient-to-t ${project.color} to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300`} />
|
||
|
|
|
||
|
|
{/* Content */}
|
||
|
|
<div className="absolute inset-0 flex flex-col justify-end p-6">
|
||
|
|
<div className="transform translate-y-4 opacity-0 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300">
|
||
|
|
<span className="inline-block px-3 py-1 rounded-full bg-background/20 backdrop-blur-sm text-white text-xs font-medium mb-2">
|
||
|
|
{project.category}
|
||
|
|
</span>
|
||
|
|
<h3 className="text-xl font-bold text-white mb-2">{project.title}</h3>
|
||
|
|
<div className="flex items-center gap-2 text-white/80 text-sm">
|
||
|
|
<span>View Project</span>
|
||
|
|
<ExternalLink className="w-4 h-4" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Border glow effect */}
|
||
|
|
<div className="absolute inset-0 rounded-2xl border-2 border-transparent group-hover:border-primary/50 group-hover:neon-glow transition-all duration-300 pointer-events-none" />
|
||
|
|
</motion.div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* See All Button */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, y: 20 }}
|
||
|
|
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
||
|
|
transition={{ duration: 0.6, delay: 0.5 }}
|
||
|
|
className="text-center"
|
||
|
|
>
|
||
|
|
<Link to="/projects">
|
||
|
|
<Button
|
||
|
|
size="lg"
|
||
|
|
className="bg-primary text-primary-foreground font-semibold px-8 py-6 text-lg rounded-full neon-glow hover:neon-glow-strong transition-all group"
|
||
|
|
>
|
||
|
|
See All Projects
|
||
|
|
<ArrowRight className="ml-2 w-5 h-5 group-hover:translate-x-1 transition-transform" />
|
||
|
|
</Button>
|
||
|
|
</Link>
|
||
|
|
</motion.div>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
);
|
||
|
|
}
|