4ff07915b8
Deploy Portfolio Selfmade / deploy (push) Successful in 31s
- Created HeroSection component for the landing page. - Implemented Navigation component with smooth scrolling to sections. - Added useNavigation hook to manage active section and scroll state. - Introduced useScrollToSection hook for smooth scrolling functionality. feat: add projects section with project cards - Developed ProjectCard component to display individual project details. - Created ProjectsSection component to showcase featured projects with filtering options. - Added sample project data for demonstration. feat: add skills section with skill cards - Implemented SkillCard component to display individual skills. - Created SkillsSection component to showcase skills with category filtering. - Added sample skills data for demonstration. style: update global styles and add custom scrollbar - Imported Urbanist font and set it as the default font. - Updated body background and text colors. - Customized scrollbar styles for better aesthetics. feat: add shared components and constants - Created AnimatedSection, Button, and Footer components for reusability. - Added COLORS and GRADIENT constants for consistent theming. - Updated index files for shared components and hooks. chore: update dependencies and configuration - Added framer-motion for animations. - Updated Tailwind CSS configuration for custom animations and colors. - Adjusted TypeScript configuration for better path resolution.
78 lines
2.8 KiB
TypeScript
78 lines
2.8 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { motion } from 'framer-motion';
|
|
import { skillsData } from '../data/skillsData';
|
|
import { SkillCard } from './SkillCard';
|
|
import AnimatedSection from '../../../shared/components/AnimatedSection';
|
|
|
|
type Category = 'All' | 'Frontend' | 'Backend' | 'Tools' | 'Design';
|
|
|
|
export const SkillsSection: React.FC = () => {
|
|
const [selectedCategory, setSelectedCategory] = useState<Category>('All');
|
|
|
|
const categories: Category[] = ['All', 'Frontend', 'Backend', 'Tools', 'Design'];
|
|
|
|
const filteredSkills = skillsData.filter(
|
|
(skill) => selectedCategory === 'All' || skill.category === selectedCategory
|
|
);
|
|
|
|
return (
|
|
<AnimatedSection id="skills" className="py-20 px-4 sm:px-6 lg:px-8">
|
|
<div className="max-w-7xl mx-auto">
|
|
{/* Section Header */}
|
|
<div className="text-center mb-16">
|
|
<motion.div
|
|
initial={{ opacity: 0, y: -20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.5 }}
|
|
className="inline-block px-4 py-2 rounded-full border border-green-500/50 bg-green-500/10 mb-6"
|
|
>
|
|
<span className="text-green-400 text-sm font-medium">My Expertise</span>
|
|
</motion.div>
|
|
|
|
<h2 className="text-4xl sm:text-5xl font-bold text-white mb-4">
|
|
Skills & Technologies
|
|
</h2>
|
|
<p className="text-gray-400 text-lg max-w-2xl mx-auto">
|
|
A comprehensive overview of my technical skills and proficiency levels
|
|
</p>
|
|
</div>
|
|
|
|
{/* Category Filter */}
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
className="flex flex-wrap justify-center gap-3 mb-12"
|
|
>
|
|
{categories.map((category) => (
|
|
<motion.button
|
|
key={category}
|
|
onClick={() => setSelectedCategory(category)}
|
|
whileHover={{ scale: 1.05 }}
|
|
whileTap={{ scale: 0.95 }}
|
|
className={`px-6 py-2 rounded-full font-medium transition-all duration-300 ${
|
|
selectedCategory === category
|
|
? 'bg-green-500 text-black'
|
|
: 'border border-green-500/30 text-gray-300 hover:border-green-500/60'
|
|
}`}
|
|
>
|
|
{category}
|
|
</motion.button>
|
|
))}
|
|
</motion.div>
|
|
|
|
{/* Skills Grid */}
|
|
<motion.div
|
|
layout
|
|
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"
|
|
>
|
|
{filteredSkills.map((skill, index: number) => (
|
|
<SkillCard key={skill.name} skill={skill} index={index} />
|
|
))}
|
|
</motion.div>
|
|
</div>
|
|
</AnimatedSection>
|
|
);
|
|
};
|