120 lines
3.9 KiB
TypeScript
120 lines
3.9 KiB
TypeScript
|
|
import React from "react";
|
||
|
|
import { motion } from "framer-motion";
|
||
|
|
|
||
|
|
interface LessonSectionProps {
|
||
|
|
title: string;
|
||
|
|
description: string;
|
||
|
|
workedTitle: string;
|
||
|
|
workedIcon: React.ReactNode;
|
||
|
|
workedColor: string;
|
||
|
|
workedLessons: string[];
|
||
|
|
improveTitle: string;
|
||
|
|
improveIcon: React.ReactNode;
|
||
|
|
improveColor: string;
|
||
|
|
improveLessons: string[];
|
||
|
|
}
|
||
|
|
|
||
|
|
const PortfolioLessonsSection: React.FC<LessonSectionProps> = ({
|
||
|
|
title,
|
||
|
|
description,
|
||
|
|
workedTitle,
|
||
|
|
workedIcon,
|
||
|
|
workedColor,
|
||
|
|
workedLessons,
|
||
|
|
improveTitle,
|
||
|
|
improveIcon,
|
||
|
|
improveColor,
|
||
|
|
improveLessons,
|
||
|
|
}) => {
|
||
|
|
return (
|
||
|
|
<section className="py-24 bg-card/30">
|
||
|
|
<div className="container mx-auto px-4 lg:px-6">
|
||
|
|
<div className="max-w-6xl mx-auto">
|
||
|
|
{/* Section Header */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, y: 30 }}
|
||
|
|
whileInView={{ opacity: 1, y: 0 }}
|
||
|
|
transition={{ duration: 0.8 }}
|
||
|
|
viewport={{ once: true }}
|
||
|
|
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>
|
||
|
|
|
||
|
|
{/* Lessons Grid */}
|
||
|
|
<div className="grid lg:grid-cols-2 gap-12">
|
||
|
|
{/* Worked Well */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, x: -30 }}
|
||
|
|
whileInView={{ opacity: 1, x: 0 }}
|
||
|
|
transition={{ duration: 0.8 }}
|
||
|
|
viewport={{ once: true }}
|
||
|
|
className={`rounded-2xl p-8 border`}
|
||
|
|
style={{
|
||
|
|
backgroundColor: `${workedColor}0D`, // light transparent bg
|
||
|
|
borderColor: `${workedColor}33`, // faint border
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<h3 className="text-2xl font-semibold text-foreground mb-8 flex items-center gap-3">
|
||
|
|
<span className="text-xl" style={{ color: workedColor }}>
|
||
|
|
{workedIcon}
|
||
|
|
</span>
|
||
|
|
{workedTitle}
|
||
|
|
</h3>
|
||
|
|
<div className="space-y-4">
|
||
|
|
{workedLessons.map((lesson, index) => (
|
||
|
|
<div key={index} className="flex items-start gap-3">
|
||
|
|
<div
|
||
|
|
className="w-2 h-2 rounded-full mt-2 flex-shrink-0"
|
||
|
|
style={{ backgroundColor: workedColor }}
|
||
|
|
/>
|
||
|
|
<span className="text-muted-foreground">{lesson}</span>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Areas for Improvement */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, x: 30 }}
|
||
|
|
whileInView={{ opacity: 1, x: 0 }}
|
||
|
|
transition={{ duration: 0.8 }}
|
||
|
|
viewport={{ once: true }}
|
||
|
|
className={`rounded-2xl p-8 border`}
|
||
|
|
style={{
|
||
|
|
backgroundColor: `${improveColor}0D`,
|
||
|
|
borderColor: `${improveColor}33`,
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<h3 className="text-2xl font-semibold text-foreground mb-8 flex items-center gap-3">
|
||
|
|
<span className="text-xl" style={{ color: improveColor }}>
|
||
|
|
{improveIcon}
|
||
|
|
</span>
|
||
|
|
{improveTitle}
|
||
|
|
</h3>
|
||
|
|
<div className="space-y-4">
|
||
|
|
{improveLessons.map((lesson, index) => (
|
||
|
|
<div key={index} className="flex items-start gap-3">
|
||
|
|
<div
|
||
|
|
className="w-2 h-2 rounded-full mt-2 flex-shrink-0"
|
||
|
|
style={{ backgroundColor: improveColor }}
|
||
|
|
/>
|
||
|
|
<span className="text-muted-foreground">{lesson}</span>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
export default PortfolioLessonsSection;
|