233 lines
10 KiB
TypeScript
233 lines
10 KiB
TypeScript
|
|
// components/portfolio/PortfolioProjectDetails.tsx
|
||
|
|
import { motion } from "framer-motion";
|
||
|
|
import { Badge } from "@/components/ui/badge";
|
||
|
|
import {
|
||
|
|
Code,
|
||
|
|
ShoppingCart,
|
||
|
|
Calendar,
|
||
|
|
Users,
|
||
|
|
Smartphone
|
||
|
|
} from "lucide-react";
|
||
|
|
|
||
|
|
interface Technology {
|
||
|
|
name: string;
|
||
|
|
icon: React.ReactNode;
|
||
|
|
}
|
||
|
|
|
||
|
|
interface ProjectDetails {
|
||
|
|
technologies: Technology[];
|
||
|
|
industries: string[];
|
||
|
|
duration: string;
|
||
|
|
teamSize: string;
|
||
|
|
platforms: string[];
|
||
|
|
}
|
||
|
|
|
||
|
|
interface PortfolioProjectDetailsProps {
|
||
|
|
title?: string;
|
||
|
|
description?: string;
|
||
|
|
details: ProjectDetails;
|
||
|
|
achievements?: Array<{
|
||
|
|
label: string;
|
||
|
|
value: string;
|
||
|
|
description: string;
|
||
|
|
}>;
|
||
|
|
}
|
||
|
|
|
||
|
|
export const PortfolioProjectDetails = ({
|
||
|
|
title = "Project Details",
|
||
|
|
description = "Detailed overview of the project including technologies, timeline, and team composition.",
|
||
|
|
details,
|
||
|
|
achievements = []
|
||
|
|
}: PortfolioProjectDetailsProps) => {
|
||
|
|
return (
|
||
|
|
<section className="py-24 bg-card/30 relative overflow-hidden">
|
||
|
|
{/* Background Elements */}
|
||
|
|
<div className="absolute inset-0 bg-gradient-to-br from-accent/5 via-transparent to-green-500/5" />
|
||
|
|
<div className="absolute top-20 right-20 w-64 h-64 bg-accent/10 rounded-full blur-3xl opacity-20" />
|
||
|
|
<div className="absolute bottom-20 left-20 w-48 h-48 bg-green-500/10 rounded-full blur-3xl opacity-20" />
|
||
|
|
|
||
|
|
<div className="container mx-auto px-4 lg:px-6 relative z-10">
|
||
|
|
<div className="max-w-7xl mx-auto">
|
||
|
|
{/* Section Header */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, y: 30 }}
|
||
|
|
animate={{ opacity: 1, y: 0 }}
|
||
|
|
transition={{ duration: 0.8 }}
|
||
|
|
className="text-center mb-16"
|
||
|
|
>
|
||
|
|
<h2 className="text-3xl lg:text-5xl font-semibold text-foreground mb-6">
|
||
|
|
{title}
|
||
|
|
</h2>
|
||
|
|
<p className="text-xl text-muted-foreground max-w-3xl mx-auto">
|
||
|
|
{description}
|
||
|
|
</p>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Project Meta Information Grid */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, y: 30 }}
|
||
|
|
animate={{ opacity: 1, y: 0 }}
|
||
|
|
transition={{ duration: 0.8, delay: 0.2 }}
|
||
|
|
className="grid lg:grid-cols-2 gap-8 mb-20"
|
||
|
|
>
|
||
|
|
{/* Technologies & Industries Card */}
|
||
|
|
<div className="bg-background/40 backdrop-blur-xl rounded-2xl p-8 border border-border/30 hover:border-accent/20 transition-all duration-500 group">
|
||
|
|
<div className="space-y-8">
|
||
|
|
{/* Technologies */}
|
||
|
|
<div>
|
||
|
|
<div className="flex items-center gap-3 mb-6">
|
||
|
|
<div className="w-12 h-12 bg-accent/10 backdrop-blur-sm rounded-xl border border-accent/20 flex items-center justify-center group-hover:bg-accent/20 transition-all duration-300">
|
||
|
|
<Code className="w-6 h-6 text-accent" />
|
||
|
|
</div>
|
||
|
|
<h3 className="text-xl font-semibold text-foreground">Technologies</h3>
|
||
|
|
</div>
|
||
|
|
<div className="flex flex-wrap gap-3">
|
||
|
|
{details.technologies.map((tech) => (
|
||
|
|
<Badge
|
||
|
|
key={tech.name}
|
||
|
|
variant="outline"
|
||
|
|
className="text-base border-border/40 bg-background/30 hover:bg-accent/10 hover:border-accent/40 flex items-center gap-2 px-4 py-2 transition-all duration-300"
|
||
|
|
>
|
||
|
|
<span className="text-accent">{tech.icon}</span>
|
||
|
|
{tech.name}
|
||
|
|
</Badge>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Industries */}
|
||
|
|
<div>
|
||
|
|
<div className="flex items-center gap-3 mb-6">
|
||
|
|
<div className="w-12 h-12 bg-green-500/10 backdrop-blur-sm rounded-xl border border-green-500/20 flex items-center justify-center group-hover:bg-green-500/20 transition-all duration-300">
|
||
|
|
<ShoppingCart className="w-6 h-6 text-green-400" />
|
||
|
|
</div>
|
||
|
|
<h3 className="text-xl font-semibold text-foreground">Industries</h3>
|
||
|
|
</div>
|
||
|
|
<div className="flex flex-wrap gap-3">
|
||
|
|
{details.industries.map((industry) => (
|
||
|
|
<Badge
|
||
|
|
key={industry}
|
||
|
|
variant="secondary"
|
||
|
|
className="text-base bg-green-500/10 border-green-500/20 text-green-100 hover:bg-green-500/20 px-4 py-2 transition-all duration-300"
|
||
|
|
>
|
||
|
|
{industry}
|
||
|
|
</Badge>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Timeline & Team Card */}
|
||
|
|
<div className="bg-background/40 backdrop-blur-xl rounded-2xl p-8 border border-border/30 hover:border-blue-400/20 transition-all duration-500 group">
|
||
|
|
<div className="space-y-8">
|
||
|
|
{/* Duration */}
|
||
|
|
<div>
|
||
|
|
<div className="flex items-center gap-3 mb-6">
|
||
|
|
<div className="w-12 h-12 bg-blue-500/10 backdrop-blur-sm rounded-xl border border-blue-500/20 flex items-center justify-center group-hover:bg-blue-500/20 transition-all duration-300">
|
||
|
|
<Calendar className="w-6 h-6 text-blue-400" />
|
||
|
|
</div>
|
||
|
|
<h3 className="text-xl font-semibold text-foreground">Project Timeline</h3>
|
||
|
|
</div>
|
||
|
|
<p className="text-lg text-muted-foreground pl-15">{details.duration}</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Team */}
|
||
|
|
<div>
|
||
|
|
<div className="flex items-center gap-3 mb-6">
|
||
|
|
<div className="w-12 h-12 bg-purple-500/10 backdrop-blur-sm rounded-xl border border-purple-500/20 flex items-center justify-center group-hover:bg-purple-500/20 transition-all duration-300">
|
||
|
|
<Users className="w-6 h-6 text-purple-400" />
|
||
|
|
</div>
|
||
|
|
<h3 className="text-xl font-semibold text-foreground">Team Composition</h3>
|
||
|
|
</div>
|
||
|
|
<p className="text-lg text-muted-foreground pl-15">{details.teamSize}</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Platforms */}
|
||
|
|
<div>
|
||
|
|
<div className="flex items-center gap-3 mb-6">
|
||
|
|
<div className="w-12 h-12 bg-orange-500/10 backdrop-blur-sm rounded-xl border border-orange-500/20 flex items-center justify-center group-hover:bg-orange-500/20 transition-all duration-300">
|
||
|
|
<Smartphone className="w-6 h-6 text-orange-400" />
|
||
|
|
</div>
|
||
|
|
<h3 className="text-xl font-semibold text-foreground">Target Platforms</h3>
|
||
|
|
</div>
|
||
|
|
<div className="flex gap-3 pl-15">
|
||
|
|
{details.platforms.map((platform) => (
|
||
|
|
<Badge
|
||
|
|
key={platform}
|
||
|
|
variant="outline"
|
||
|
|
className="text-base border-orange-400/40 bg-orange-500/10 text-orange-100 hover:bg-orange-500/20 px-3 py-1"
|
||
|
|
>
|
||
|
|
{platform}
|
||
|
|
</Badge>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Key Achievements Section */}
|
||
|
|
{achievements.length > 0 && (
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, y: 30 }}
|
||
|
|
animate={{ opacity: 1, y: 0 }}
|
||
|
|
transition={{ duration: 0.8, delay: 0.4 }}
|
||
|
|
className="mb-16"
|
||
|
|
>
|
||
|
|
<div className="text-center mb-12">
|
||
|
|
<h2 className="text-3xl lg:text-4xl font-semibold text-foreground mb-6">
|
||
|
|
Key Impact & Results
|
||
|
|
</h2>
|
||
|
|
<p className="text-xl text-muted-foreground max-w-3xl mx-auto">
|
||
|
|
Measurable outcomes that demonstrate the project's success
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||
|
|
{achievements.map((achievement, index) => (
|
||
|
|
<motion.div
|
||
|
|
key={achievement.label}
|
||
|
|
initial={{ opacity: 0, y: 20 }}
|
||
|
|
animate={{ opacity: 1, y: 0 }}
|
||
|
|
transition={{ duration: 0.6, delay: 0.6 + index * 0.1 }}
|
||
|
|
whileHover={{
|
||
|
|
scale: 1.02,
|
||
|
|
y: -4,
|
||
|
|
transition: { duration: 0.3, ease: "easeOut" }
|
||
|
|
}}
|
||
|
|
className="bg-background/50 backdrop-blur-xl rounded-2xl p-8 border border-border/40 hover:border-accent/30 hover:bg-background/60 transition-all duration-500 group cursor-pointer relative overflow-hidden"
|
||
|
|
>
|
||
|
|
{/* Card Background Gradient */}
|
||
|
|
<div className="absolute inset-0 bg-gradient-to-br from-accent/5 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
||
|
|
|
||
|
|
{/* Content */}
|
||
|
|
<div className="relative z-10 text-center">
|
||
|
|
{/* Value */}
|
||
|
|
<div className="text-3xl lg:text-4xl font-bold text-accent mb-4 group-hover:text-accent transition-colors duration-300">
|
||
|
|
{achievement.value}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Label */}
|
||
|
|
<div className="text-xl font-semibold text-foreground mb-3 group-hover:text-foreground transition-colors duration-300">
|
||
|
|
{achievement.label}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Description */}
|
||
|
|
<div className="text-base text-muted-foreground leading-relaxed group-hover:text-muted-foreground transition-colors duration-300">
|
||
|
|
{achievement.description}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Hover Effect Line */}
|
||
|
|
<div className="absolute bottom-0 left-0 w-full h-1 bg-gradient-to-r from-accent to-accent/50 transform scale-x-0 group-hover:scale-x-100 transition-transform duration-500 origin-left" />
|
||
|
|
</motion.div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
);
|
||
|
|
};
|