diff --git a/src/components/About.tsx b/src/components/About.tsx new file mode 100644 index 0000000..5e4cef2 --- /dev/null +++ b/src/components/About.tsx @@ -0,0 +1,168 @@ +import React, { useState, useEffect } from 'react'; +import { motion } from 'framer-motion'; +import { useInView } from 'react-intersection-observer'; + +const AnimatedCounter = ({ end, duration = 2, suffix = '' }: { end: number; duration?: number; suffix?: string }) => { + const [count, setCount] = useState(0); + const [ref, inView] = useInView({ triggerOnce: true }); + + useEffect(() => { + if (inView) { + let startTime = 0; + const startCount = 0; + const endCount = end; + + const animate = (currentTime: number) => { + if (startTime === 0) startTime = currentTime; + const progress = Math.min((currentTime - startTime) / (duration * 1000), 1); + const current = startCount + (endCount - startCount) * progress; + + setCount(Math.floor(current)); + + if (progress < 1) { + requestAnimationFrame(animate); + } + }; + + requestAnimationFrame(animate); + } + }, [inView, end, duration]); + + return ( + + {count}{suffix} + + ); +}; + +const About = () => { + const [ref, inView] = useInView({ + threshold: 0.3, + triggerOnce: true + }); + + const stats = [ + { number: 5, suffix: '+', label: 'Years Experience' }, + { number: 50, suffix: '+', label: 'Projects Completed' }, + { number: 20, suffix: '+', label: 'Technologies' }, + { number: 100, suffix: '%', label: 'Client Satisfaction' } + ]; + + return ( +
+
+ +

+ About Me +

+

+ Passionate developer with a love for creating innovative solutions +

+
+ +
+ {/* Profile Image */} + +
+ + AJ + + + {/* Floating particles */} +
+ {[...Array(6)].map((_, i) => ( + + ))} +
+
+
+ + {/* Content */} + +
+

+ I'm a passionate full-stack developer with over 5 years of experience creating + innovative web applications and digital experiences. My journey started with a + curiosity for how things work, which evolved into a love for crafting elegant + solutions to complex problems. +

+ +

+ I specialize in modern technologies like React, Node.js, and cloud platforms, + always staying up-to-date with the latest industry trends. When I'm not coding, + you'll find me exploring new technologies, contributing to open source, or + mentoring aspiring developers. +

+
+ + {/* Stats */} +
+ {stats.map((stat, index) => ( + +
+ +
+
{stat.label}
+
+ ))} +
+
+
+
+
+ ); +}; + +export default About; \ No newline at end of file diff --git a/src/components/Contact.tsx b/src/components/Contact.tsx new file mode 100644 index 0000000..c5b2c98 --- /dev/null +++ b/src/components/Contact.tsx @@ -0,0 +1,266 @@ +import React, { useState } from 'react'; +import { motion } from 'framer-motion'; +import { useInView } from 'react-intersection-observer'; +import { Mail, Phone, MapPin, Github, Linkedin, Twitter, Send } from 'lucide-react'; + +const FloatingLabel = ({ label, value, focused }: { label: string; value: string; focused: boolean }) => ( + + {label} + +); + +const Contact = () => { + const [ref, inView] = useInView({ + threshold: 0.3, + triggerOnce: true + }); + + const [formData, setFormData] = useState({ + name: '', + email: '', + subject: '', + message: '' + }); + + const [focusedField, setFocusedField] = useState(null); + const [isSubmitting, setIsSubmitting] = useState(false); + + const handleInputChange = (e: React.ChangeEvent) => { + setFormData(prev => ({ + ...prev, + [e.target.name]: e.target.value + })); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setIsSubmitting(true); + + // Simulate form submission + await new Promise(resolve => setTimeout(resolve, 2000)); + + console.log('Form submitted:', formData); + setIsSubmitting(false); + setFormData({ name: '', email: '', subject: '', message: '' }); + }; + + const socialLinks = [ + { icon: Github, href: 'https://github.com', label: 'GitHub', color: 'hover:text-gray-300' }, + { icon: Linkedin, href: 'https://linkedin.com', label: 'LinkedIn', color: 'hover:text-blue-400' }, + { icon: Twitter, href: 'https://twitter.com', label: 'Twitter', color: 'hover:text-cyan-400' }, + ]; + + const contactInfo = [ + { icon: Mail, label: 'alex@example.com', href: 'mailto:alex@example.com' }, + { icon: Phone, label: '+1 (555) 123-4567', href: 'tel:+15551234567' }, + { icon: MapPin, label: 'San Francisco, CA', href: '#' }, + ]; + + return ( +
+
+ +

+ Get In Touch +

+

+ Let's discuss your next project or just say hello +

+
+ +
+ {/* Contact Info */} + +
+

Let's Connect

+

+ I'm always interested in hearing about new opportunities and projects. + Whether you have a question or just want to say hi, I'll try my best to get back to you! +

+ +
+ {contactInfo.map((item, index) => ( + +
+ +
+ {item.label} +
+ ))} +
+
+ + {/* Social Links */} +
+

Follow Me

+
+ {socialLinks.map((social, index) => ( + + + + ))} +
+
+
+ + {/* Contact Form */} + +
+
+
+ setFocusedField('name')} + onBlur={() => setFocusedField(null)} + className="w-full px-4 py-4 bg-gray-800/50 backdrop-blur-sm border border-gray-700/50 rounded-lg text-white placeholder-transparent focus:border-blue-500 focus:outline-none transition-all duration-300" + placeholder="Your Name" + required + /> + +
+ +
+ setFocusedField('email')} + onBlur={() => setFocusedField(null)} + className="w-full px-4 py-4 bg-gray-800/50 backdrop-blur-sm border border-gray-700/50 rounded-lg text-white placeholder-transparent focus:border-blue-500 focus:outline-none transition-all duration-300" + placeholder="Your Email" + required + /> + +
+
+ +
+ setFocusedField('subject')} + onBlur={() => setFocusedField(null)} + className="w-full px-4 py-4 bg-gray-800/50 backdrop-blur-sm border border-gray-700/50 rounded-lg text-white placeholder-transparent focus:border-blue-500 focus:outline-none transition-all duration-300" + placeholder="Subject" + required + /> + +
+ +
+