Skip to main content

figma-portfolio-nextjs

Build and customize a modern developer/designer portfolio with Next.js, TypeScript, and TailwindCSS featuring animated typing effects and responsive layouts.

Zur Installation springen

Quellinformationen

Repository
reason-machines/design-skills
Letzte Quellaktivität
18. Mai 2026 um 06:27
Erkannte Sprache von SKILL.md
Englisch
Sterne
4
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
figma-portfolio-nextjs
description
Build and customize a modern developer/designer portfolio with Next.js, TypeScript, and TailwindCSS featuring animated typing effects and responsive layouts.
triggers
["create a portfolio website","build a developer portfolio with nextjs","customize figma portfolio template","add projects to portfolio site","setup personal portfolio with tailwind","configure nextjs portfolio animations","deploy portfolio to vercel","modify portfolio hero section"]
# Figma Portfolio - Next.js Developer Portfolio > Skill by [ara.so](https://ara.so) — Design Skills collection. A personal portfolio template for developers and designers, built with Next.js 16, TypeScript, and TailwindCSS. Features a clean dark-themed UI with purple gradient accents, animated typing effects, responsive layouts, and sections to showcase projects, experience, and creative skills. ## Installation ```bash # Clone the repository git clone git@github.com:ibrahimmemonn/Figma_Portfolio.git # Navigate to project directory cd Figma_Portfolio/ # Install dependencies npm install # Run development server npm run dev ``` The development server starts at `http://localhost:3000`. ## Project Structure ``` Figma_Portfolio/ ├── app/ │ ├── page.tsx # Main landing page │ ├── layout.tsx # Root layout with font config │ └── globals.css # Global styles with Tailwind ├── components/ │ ├── Hero.tsx # Hero section with typing animation │ ├── Projects.tsx # Project showcase section │ ├── Experience.tsx # Experience timeline │ ├── Skills.tsx # Skills display │ └── Contact.tsx # Contact section ├── public/ │ ├── projects/ # Project images │ └── assets/ # Icons and media └── tailwind.config.ts # Tailwind configuration ``` ## Key Features & Configuration ### Font Configuration The portfolio uses Poppins font optimized with `next/font`: ```typescript // app/layout.tsx import { Poppins } from 'next/font/google'; const poppins = Poppins({ subsets: ['latin'], weight: ['300', '400', '500', '600', '700', '800', '900'], variable: '--font-poppins', }); export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en" className={poppins.variable}> <body>{children}</body> </html> ); } ``` ### Hero Section with Typing Animation ```typescript // components/Hero.tsx 'use client'; import { useState, useEffect } from 'react'; export default function Hero() { const [text, setText] = useState(''); const [isDeleting, setIsDeleting] = useState(false); const [loopNum, setLoopNum] = useState(0); const [typingSpeed, setTypingSpeed] = useState(150); const roles = ['Software Engineer', 'UI/UX Designer', 'Full Stack Developer']; useEffect(() => { const handleType = () => { const i = loopNum % roles.length; const fullText = roles[i]; setText( isDeleting ? fullText.substring(0, text.length - 1) : fullText.substring(0, text.length + 1) ); setTypingSpeed(isDeleting ? 50 : 150); if (!isDeleting && text === fullText) { setTimeout(() => setIsDeleting(true), 1000); } else if (isDeleting && text === '') { setIsDeleting(false); setLoopNum(loopNum + 1); } }; const timer = setTimeout(handleType, typingSpeed); return () => clearTimeout(timer); }, [text, isDeleting, loopNum, typingSpeed, roles]); return ( <section className="min-h-screen flex items-center justify-center px-4"> <div className="max-w-4xl mx-auto text-center"> <h1 className="text-5xl md:text-7xl font-bold mb-6"> Hi, I'm <span className="bg-gradient-to-r from-purple-400 to-pink-600 bg-clip-text text-transparent">Your Name</span> </h1> <h2 className="text-2xl md:text-4xl mb-8"> <span className="text-gray-400">{text}</span> <span className="animate-pulse">|</span> </h2> <p className="text-gray-300 text-lg max-w-2xl mx-auto"> Building digital experiences that combine aesthetic design with powerful functionality. </p> </div> </section> ); } ``` ### Adding Projects ```typescript // components/Projects.tsx interface Project { title: string; description: string; image: string; link: string; github?: string; tags: string[]; } const projects: Project[] = [ { title: 'E-Commerce Platform', description: 'Full-stack e-commerce solution with Next.js, Stripe, and MongoDB', image: '/projects/ecommerce.png', link: 'https://example.com', github: 'https://github.com/username/project', tags: ['Next.js', 'TypeScript', 'Stripe', 'MongoDB'], }, { title: 'Portfolio Dashboard', description: 'Analytics dashboard for tracking portfolio metrics', image: '/projects/dashboard.png', link: 'https://example.com', tags: ['React', 'Chart.js', 'TailwindCSS'], }, ]; export default function Projects() { return ( <section className="py-20 px-4"> <h2 className="text-4xl font-bold text-center mb-12"> Featured <span className="bg-gradient-to-r from-purple-400 to-pink-600 bg-clip-text text-transparent">Projects</span> </h2> <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-6xl mx-auto"> {projects.map((project, index) => ( <div key={index} className="bg-gray-800/50 rounded-lg overflow-hidden hover:transform hover:scale-105 transition-all duration-300"> <img src={project.image} alt={project.title} className="w-full h-48 object-cover" /> <div className="p-6"> <h3 className="text-xl font-semibold mb-2">{project.title}</h3> <p className="text-gray-400 mb-4">{project.description}</p> <div className="flex flex-wrap gap-2 mb-4"> {project.tags.map((tag, i) => ( <span key={i} className="px-3 py-1 bg-purple-500/20 text-purple-300 rounded-full text-sm"> {tag} </span> ))} </div> <div className="flex gap-4"> <a href={project.link} className="text-purple-400 hover:text-purple-300"> Live Demo → </a> {project.github && ( <a href={project.github} className="text-gray-400 hover:text-gray-300"> GitHub → </a> )} </div> </div> </div> ))} </div> </section> ); } ``` ### Customizing Theme Colors ```typescript // tailwind.config.ts import type { Config } from 'tailwindcss'; const config: Config = { content: [ './pages/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}', './app/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { extend: { colors: { primary: { 50: '#faf5ff', 100: '#f3e8ff', 500: '#a855f7', 600: '#9333ea', 700: '#7e22ce', }, }, backgroundImage: { 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', }, }, }, plugins: [], }; export default config; ``` ### Adding Analytics ```typescript // app/layout.tsx import { Analytics } from '@vercel/analytics/react'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body> {children} <Analytics /> </body> </html> ); } ``` ## Deployment ### Deploy to Vercel ```bash # Install Vercel CLI npm i -g vercel # Deploy vercel # Deploy to production vercel --prod ``` Or connect your GitHub repository to Vercel for automatic deployments on every push to `main`. ### Environment Variables ```bash # .env.local (not committed to git) NEXT_PUBLIC_SITE_URL=https://your-domain.com NEXT_PUBLIC_GA_ID=your-google-analytics-id ``` ## Common Customization Patterns ### Add a Contact Form ```typescript // components/Contact.tsx 'use client'; import { useState } from 'react'; export default function Contact() { const [formData, setFormData] = useState({ name: '', email: '', message: '', }); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); // Integrate with your preferred email service const response = await fetch('/api/contact', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData), }); if (response.ok) { alert('Message sent successfully!'); setFormData({ name: '', email: '', message: '' }); } }; return ( <section className="py-20 px-4"> <div className="max-w-2xl mx-auto"> <h2 className="text-4xl font-bold text-center mb-12">Get In Touch</h2> <form onSubmit={handleSubmit} className="space-y-6"> <input type="text" placeholder="Your Name" value={formData.name} onChange={(e) => setFormData({ ...formData, name: e.target.value })} className="w-full px-4 py-3 bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" required /> <input type="email" placeholder="Your Email" value={formData.email} onChange={(e) => setFormData({ ...formData, email: e.target.value })} className="w-full px-4 py-3 bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" required /> <textarea placeholder="Your Message" value={formData.message} onChange={(e) => setFormData({ ...formData, message: e.target.value })} rows={5} className="w-full px-4 py-3 bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" required /> <button type="submit" className="w-full py-3 bg-gradient-to-r from-purple-500 to-pink-600 rounded-lg font-semibold hover:opacity-90 transition-opacity" > Send Message </button> </form> </div> </section> ); } ``` ### Smooth Scroll Navigation ```typescript // components/Navigation.tsx export default function Navigation() { const scrollToSection = (id: string) => { const element = document.getElementById(id); element?.scrollIntoView({ behavior: 'smooth' }); }; return ( <nav className="fixed top-0 w-full bg-gray-900/80 backdrop-blur-sm z-50"> <div className="max-w-6xl mx-auto px-4 py-4 flex justify-between items-center"> <div className="text-xl font-bold">Portfolio</div> <div className="flex gap-6"> <button onClick={() => scrollToSection('projects')} className="hover:text-purple-400"> Projects </button> <button onClick={() => scrollToSection('experience')} className="hover:text-purple-400"> Experience </button> <button onClick={() => scrollToSection('contact')} className="hover:text-purple-400"> Contact </button> </div> </div>
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen