Skip to main content
Course/Module 9/Topic 3 of 4Intermediate

Portfolio Website

Create a professional portfolio website with animations, responsive design, and modern UI/UX

100 minBy Priygop TeamLast updated: Feb 2026

Portfolio Features

Example
// Portfolio website features
- Responsive design
- Smooth animations
- Project showcase
- Skills and experience
- Contact form
- Blog section
- Dark/light theme
- SEO optimization
- Performance optimization

// Portfolio structure
src/
├── components/
│   ├── layout/
│   │   ├── Header.js
│   │   ├── Footer.js
│   │   └── Navigation.js
│   ├── sections/
│   │   ├── Hero.js
│   │   ├── About.js
│   │   ├── Skills.js
│   │   ├── Projects.js
│   │   ├── Experience.js
│   │   ├── Contact.js
│   │   └── Blog.js
│   ├── ui/
│   │   ├── Button.js
│   │   ├── Card.js
│   │   ├── Modal.js
│   │   └── ThemeToggle.js
│   └── animations/
│       ├── FadeIn.js
│       ├── SlideIn.js
│       └── Parallax.js
├── pages/
│   ├── Home.js
│   ├── About.js
│   ├── Projects.js
│   ├── Blog.js
│   └── Contact.js
├── hooks/
│   ├── useScrollPosition.js
│   ├── useTheme.js
│   └── useIntersectionObserver.js
├── data/
│   ├── projects.js
│   ├── skills.js
│   ├── experience.js
│   └── blog-posts.js
└── styles/
    ├── globals.css
    ├── components.css
    └── animations.css

Modern UI Components

Example
// Modern portfolio components
import { motion } from 'framer-motion';
import { useState, useEffect } from 'react';

// Hero section with animations
function Hero() {
    const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });

    useEffect(() => {
        const handleMouseMove = (e) => {
            setMousePosition({ x: e.clientX, y: e.clientY });
        };

        window.addEventListener('mousemove', handleMouseMove);
        return () => window.removeEventListener('mousemove', handleMouseMove);
    }, []);

    return (
        <motion.section 
            className="hero"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ duration: 1 }}
        >
            <motion.div
                className="hero-content"
                initial={{ y: 100, opacity: 0 }}
                animate={{ y: 0, opacity: 1 }}
                transition={{ duration: 0.8, delay: 0.2 }}
            >
                <motion.h1
                    initial={{ scale: 0.8 }}
                    animate={{ scale: 1 }}
                    transition={{ duration: 0.5, delay: 0.5 }}
                >
                    Hi, I'm <span className="highlight">Your Name</span>
                </motion.h1>
                <motion.p
                    initial={{ y: 50, opacity: 0 }}
                    animate={{ y: 0, opacity: 1 }}
                    transition={{ duration: 0.8, delay: 0.7 }}
                >
                    Full-Stack Developer & UI/UX Designer
                </motion.p>
                <motion.div
                    className="hero-buttons"
                    initial={{ y: 50, opacity: 0 }}
                    animate={{ y: 0, opacity: 1 }}
                    transition={{ duration: 0.8, delay: 0.9 }}
                >
                    <Button variant="primary">View Projects</Button>
                    <Button variant="secondary">Contact Me</Button>
                </motion.div>
            </motion.div>
            
            <motion.div
                className="floating-elements"
                animate={{
                    x: mousePosition.x * 0.01,
                    y: mousePosition.y * 0.01,
                }}
                transition={{ type: "spring", stiffness: 50 }}
            >
                <div className="floating-shape shape-1"></div>
                <div className="floating-shape shape-2"></div>
                <div className="floating-shape shape-3"></div>
            </motion.div>
        </motion.section>
    );
}

// Project showcase with filters
function Projects() {
    const [filter, setFilter] = useState('all');
    const [projects, setProjects] = useState([]);

    const categories = ['all', 'web', 'mobile', 'design', 'other'];

    const filteredProjects = projects.filter(project => 
        filter === 'all' || project.category === filter
    );

    return (
        <section className="projects">
            <motion.h2
                initial={{ opacity: 0, y: 50 }}
                whileInView={{ opacity: 1, y: 0 }}
                transition={{ duration: 0.6 }}
            >
                My Projects
            </motion.h2>
            
            <div className="filter-buttons">
                {categories.map(category => (
                    <motion.button
                        key={category}
                        onClick={() => setFilter(category)}
                        className={`filter-btn ${filter === category ? 'active' : ''}`}
                        whileHover={{ scale: 1.05 }}
                        whileTap={{ scale: 0.95 }}
                    >
                        {category.charAt(0).toUpperCase() + category.slice(1)}
                    </motion.button>
                ))}
            </div>
            
            <motion.div 
                className="projects-grid"
                layout
            >
                {filteredProjects.map((project, index) => (
                    <motion.div
                        key={project.id}
                        layout
                        initial={{ opacity: 0, scale: 0.8 }}
                        animate={{ opacity: 1, scale: 1 }}
                        exit={{ opacity: 0, scale: 0.8 }}
                        transition={{ duration: 0.3, delay: index * 0.1 }}
                        whileHover={{ y: -10 }}
                    >
                        <ProjectCard project={project} />
                    </motion.div>
                ))}
            </motion.div>
        </section>
    );
}

// Project card component
function ProjectCard({ project }) {
    const [isHovered, setIsHovered] = useState(false);

    return (
        <motion.div
            className="project-card"
            onHoverStart={() => setIsHovered(true)}
            onHoverEnd={() => setIsHovered(false)}
            whileHover={{ scale: 1.02 }}
        >
            <div className="project-image">
                <img src={project.image} alt={project.title} />
                <motion.div
                    className="project-overlay"
                    initial={{ opacity: 0 }}
                    animate={{ opacity: isHovered ? 1 : 0 }}
                    transition={{ duration: 0.3 }}
                >
                    <div className="project-links">
                        <a href={project.liveUrl} target="_blank" rel="noopener">
                            Live Demo
                        </a>
                        <a href={project.githubUrl} target="_blank" rel="noopener">
                            GitHub
                        </a>
                    </div>
                </motion.div>
            </div>
            <div className="project-content">
                <h3>{project.title}</h3>
                <p>{project.description}</p>
                <div className="project-tech">
                    {project.technologies.map(tech => (
                        <span key={tech} className="tech-tag">{tech}</span>
                    ))}
                </div>
            </div>
        </motion.div>
    );
}

// Skills section with progress bars
function Skills() {
    const skills = [
        { name: 'React', level: 90 },
        { name: 'JavaScript', level: 85 },
        { name: 'Node.js', level: 80 },
        { name: 'Python', level: 75 },
        { name: 'CSS/SASS', level: 88 },
        { name: 'TypeScript', level: 70 },
    ];

    return (
        <section className="skills">
            <motion.h2
                initial={{ opacity: 0, y: 50 }}
                whileInView={{ opacity: 1, y: 0 }}
                transition={{ duration: 0.6 }}
            >
                Skills & Technologies
            </motion.h2>
            
            <div className="skills-grid">
                {skills.map((skill, index) => (
                    <motion.div
                        key={skill.name}
                        className="skill-item"
                        initial={{ opacity: 0, x: -50 }}
                        whileInView={{ opacity: 1, x: 0 }}
                        transition={{ duration: 0.6, delay: index * 0.1 }}
                    >
                        <div className="skill-header">
                            <h3>{skill.name}</h3>
                            <span>{skill.level}%</span>
                        </div>
                        <div className="skill-bar">
                            <motion.div
                                className="skill-progress"
                                initial={{ width: 0 }}
                                whileInView={{ width: `${skill.level}%` }}
                                transition={{ duration: 1, delay: 0.2 }}
                            />
                        </div>
                    </motion.div>
                ))}
            </div>
        </section>
    );
}

Additional Resources

Recommended Reading

  • React Project Best Practices
  • Deployment Strategies Guide
  • Performance Optimization Tips

Online Resources

  • Real-World React Projects
  • Portfolio Building Guide
  • React Deployment Tutorial
Chat on WhatsApp
Priygop - Leading Professional Development Platform | Expert Courses & Interview Prep