developer-portfolios/app/components/Footer.tsx
2025-04-11 02:05:41 +01:00

174 lines
5.7 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import { motion } from "framer-motion";
import { ArrowUpIcon } from "lucide-react";
interface FooterProps {
socialLinks: {
name: string;
url: string;
icon: any;
}[];
}
const Footer: React.FC<FooterProps> = ({ socialLinks }) => {
const [showScrollTop, setShowScrollTop] = useState(false);
useEffect(() => {
const handleScroll = () => {
setShowScrollTop(window.scrollY > 500);
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
const scrollToTop = () => {
window.scrollTo({
top: 0,
behavior: "smooth",
});
};
const navItems = [
{ id: "home", label: "Home" },
{ id: "about", label: "About" },
{ id: "skills", label: "Skills" },
{ id: "projects", label: "Projects" },
{ id: "education", label: "Education" },
{ id: "contact", label: "Contact" },
];
const scrollToSection = (sectionId: string) => {
const element = document.getElementById(sectionId);
if (element) {
window.scrollTo({
top: element.offsetTop - 80,
behavior: "smooth",
});
}
};
return (
<footer className="bg-white dark:bg-gray-900 py-12 px-6 md:px-12">
<div className="container mx-auto max-w-6xl">
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
{/* Logo and Description */}
<div className="col-span-1 md:col-span-2">
<a
href="#home"
className="flex items-center gap-2 mb-4"
onClick={(e) => {
e.preventDefault();
scrollToSection("home");
}}
>
<div className="flex items-center">
<img src="./ucefLogo.png" alt="Logo" className="h-14 w-14" />
<span className="text-2xl font-bold gradient-text bg-clip-text text-transparent bg-gradient-to-r from-primary to-secondary">
Youssef Sahih
</span>
</div>
</a>
<p className="text-gray-600 dark:text-gray-400 mt-4 mb-6 max-w-md">
A passionate software developer with expertise in both low-level
programming and web development technologies.
</p>
<div className="flex space-x-3">
{socialLinks.map((link, index) => (
<motion.a
key={index}
href={link.url}
target="_blank"
rel="noopener noreferrer"
className="text-gray-600 dark:text-gray-400 hover:text-primary dark:hover:text-primary-light transition-colors"
whileHover={{ y: -3 }}
whileTap={{ scale: 0.95 }}
>
<link.icon className="w-5 h-5" />
</motion.a>
))}
</div>
</div>
{/* Quick Links */}
<div className="col-span-1">
<h3 className="text-lg font-semibold mb-4 text-gray-800 dark:text-white">
Quick Links
</h3>
<ul className="space-y-2">
{navItems.map((item) => (
<li key={item.id}>
<a
href={`#${item.id}`}
className="text-gray-600 dark:text-gray-400 hover:text-primary dark:hover:text-primary-light transition-colors"
onClick={(e) => {
e.preventDefault();
scrollToSection(item.id);
}}
>
{item.label}
</a>
</li>
))}
</ul>
</div>
{/* Contact Info */}
<div className="col-span-1">
<h3 className="text-lg font-semibold mb-4 text-gray-800 dark:text-white">
Contact
</h3>
<ul className="space-y-2">
<li>
<a
href="mailto:ucefsahih@gmail.com"
className="text-gray-600 dark:text-gray-400 hover:text-primary dark:hover:text-primary-light transition-colors"
>
ucefsahih@gmail.com
</a>
</li>
<li>
<a
href="tel:+212708978739"
className="text-gray-600 dark:text-gray-400 hover:text-primary dark:hover:text-primary-light transition-colors"
>
+212 708 978 739
</a>
</li>
<li className="text-gray-600 dark:text-gray-400">Morocco</li>
</ul>
</div>
</div>
<div className="mt-12 pt-6 border-t border-gray-200 dark:border-gray-800 flex flex-col md:flex-row justify-between items-center">
<p className="text-gray-600 dark:text-gray-400 text-sm">
&copy; {new Date().getFullYear()} Youssef Sahih. All rights
reserved.
</p>
<p className="text-gray-600 dark:text-gray-400 text-sm mt-2 md:mt-0">
Designed & Built with <span className="text-red-500"></span> by
Youssef Sahih
</p>
</div>
</div>
{/* Scroll to top button */}
<motion.button
className={`fixed bottom-6 right-6 p-3 rounded-full bg-primary text-white shadow-lg ${
showScrollTop ? "opacity-100" : "opacity-0 pointer-events-none"
} transition-opacity duration-300`}
onClick={scrollToTop}
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
aria-label="Scroll to top"
>
<ArrowUpIcon className="w-5 h-5" />
</motion.button>
</footer>
);
};
export default Footer;