128 lines
4.4 KiB
TypeScript
128 lines
4.4 KiB
TypeScript
import React from "react";
|
|
import { motion } from "framer-motion";
|
|
import { CheckCircle } from "lucide-react";
|
|
|
|
interface Challenge {
|
|
icon: React.ReactNode;
|
|
title: string;
|
|
description: string;
|
|
}
|
|
|
|
interface Technology {
|
|
icon: React.ReactNode;
|
|
label: string;
|
|
}
|
|
|
|
interface Highlight {
|
|
text: string;
|
|
}
|
|
|
|
interface PortfolioChallengeSolutionProps {
|
|
challengesTitle?: string;
|
|
challenges: Challenge[];
|
|
solutionTitle?: string;
|
|
technologyStack: Technology[];
|
|
highlights: Highlight[];
|
|
}
|
|
|
|
const PortfolioChallengeSolution: React.FC<PortfolioChallengeSolutionProps> = ({
|
|
challengesTitle = "Challenges & Constraints",
|
|
challenges,
|
|
solutionTitle = "Solution Architecture",
|
|
technologyStack,
|
|
highlights,
|
|
}) => {
|
|
return (
|
|
<section className="py-24 bg-background">
|
|
<div className="container mx-auto px-4 lg:px-6">
|
|
<div className="max-w-6xl mx-auto">
|
|
<div className="grid lg:grid-cols-2 gap-20">
|
|
{/* Challenges */}
|
|
<motion.div
|
|
initial={{ opacity: 0, x: -30 }}
|
|
whileInView={{ opacity: 1, x: 0 }}
|
|
transition={{ duration: 0.8 }}
|
|
viewport={{ once: true }}
|
|
>
|
|
<h2 className="text-3xl lg:text-4xl font-semibold text-foreground mb-12">
|
|
{challengesTitle}
|
|
</h2>
|
|
<div className="space-y-6">
|
|
{challenges.map((challenge, index) => (
|
|
<motion.div
|
|
key={challenge.title}
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.6, delay: index * 0.1 }}
|
|
viewport={{ once: true }}
|
|
className="bg-background/50 rounded-xl p-6 border border-border/50 hover:border-accent/20 transition-colors duration-300"
|
|
>
|
|
<div className="flex items-start gap-4">
|
|
<div className="text-accent mt-1">{challenge.icon}</div>
|
|
<div>
|
|
<h3 className="text-lg font-semibold text-foreground mb-2">
|
|
{challenge.title}
|
|
</h3>
|
|
<p className="text-muted-foreground leading-relaxed">
|
|
{challenge.description}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</motion.div>
|
|
|
|
{/* Solution Architecture */}
|
|
<motion.div
|
|
initial={{ opacity: 0, x: 30 }}
|
|
whileInView={{ opacity: 1, x: 0 }}
|
|
transition={{ duration: 0.8 }}
|
|
viewport={{ once: true }}
|
|
>
|
|
<h2 className="text-3xl lg:text-4xl font-semibold text-foreground mb-12">
|
|
{solutionTitle}
|
|
</h2>
|
|
<div className="bg-background/50 rounded-2xl p-8 border border-border/50">
|
|
<div className="space-y-8">
|
|
<div>
|
|
<h3 className="text-xl font-semibold text-foreground mb-6">
|
|
Technology Stack
|
|
</h3>
|
|
<div className="space-y-4">
|
|
{technologyStack.map((tech, idx) => (
|
|
<div key={idx} className="flex items-center gap-3">
|
|
{tech.icon}
|
|
<span className="text-muted-foreground">{tech.label}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<h3 className="text-xl font-semibold text-foreground mb-6">
|
|
Key Highlights
|
|
</h3>
|
|
<div className="space-y-3">
|
|
{highlights.map((item, idx) => (
|
|
<div key={idx} className="flex items-start gap-3">
|
|
<CheckCircle className="w-4 h-4 text-accent mt-0.5 flex-shrink-0" />
|
|
<span className="text-muted-foreground text-base">
|
|
{item.text}
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default PortfolioChallengeSolution;
|