240 lines
7.5 KiB
TypeScript
240 lines
7.5 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
ArrowRightOutlined,
|
|
BulbOutlined,
|
|
EnvironmentOutlined,
|
|
FacebookOutlined,
|
|
InstagramOutlined,
|
|
LinkedinOutlined,
|
|
MailOutlined,
|
|
PhoneOutlined,
|
|
TeamOutlined,
|
|
TrophyOutlined,
|
|
TwitterOutlined
|
|
} from '@ant-design/icons';
|
|
import { Typography } from 'antd';
|
|
import { motion } from 'framer-motion';
|
|
import React, { useEffect, useState } from 'react';
|
|
import styles from './Footer.module.css';
|
|
|
|
const { Paragraph } = Typography;
|
|
|
|
const Footer: React.FC = () => {
|
|
const [expandedSections, setExpandedSections] = useState<{ [key: string]: boolean }>({});
|
|
const [isMobile, setIsMobile] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const checkMobile = () => {
|
|
setIsMobile(window.innerWidth <= 768);
|
|
};
|
|
|
|
checkMobile();
|
|
window.addEventListener('resize', checkMobile);
|
|
|
|
return () => window.removeEventListener('resize', checkMobile);
|
|
}, []);
|
|
|
|
const containerVariants = {
|
|
hidden: { opacity: 0 },
|
|
visible: {
|
|
opacity: 1,
|
|
transition: {
|
|
staggerChildren: 0.1
|
|
}
|
|
}
|
|
};
|
|
|
|
const itemVariants = {
|
|
hidden: { y: 20, opacity: 0 },
|
|
visible: {
|
|
y: 0,
|
|
opacity: 1,
|
|
transition: { duration: 0.5 }
|
|
}
|
|
};
|
|
|
|
const toggleSection = (sectionKey: string) => {
|
|
if (isMobile) {
|
|
setExpandedSections(prev => ({
|
|
...prev,
|
|
[sectionKey]: !prev[sectionKey]
|
|
}));
|
|
}
|
|
};
|
|
|
|
const footerSections = [
|
|
{
|
|
key: 'company',
|
|
title: 'Company',
|
|
icon: <TeamOutlined className={styles.footerColumnIcon} />,
|
|
links: [
|
|
{ href: '/about', text: 'About Us' },
|
|
{ href: '/services', text: 'Our Services' },
|
|
{ href: '/projects', text: 'Portfolio' },
|
|
{ href: '/contact', text: 'Contact Us' }
|
|
]
|
|
},
|
|
{
|
|
key: 'services',
|
|
title: 'Services',
|
|
icon: <BulbOutlined className={styles.footerColumnIcon} />,
|
|
links: [
|
|
{ href: '/services#webdev', text: 'Web Development' },
|
|
{ href: '/services#mobile', text: 'Mobile Apps' },
|
|
{ href: '/services#ai', text: 'AI Solutions' },
|
|
{ href: '/services#cloud', text: 'Cloud Services' }
|
|
]
|
|
},
|
|
{
|
|
key: 'resources',
|
|
title: 'Resources',
|
|
icon: <TrophyOutlined className={styles.footerColumnIcon} />,
|
|
links: [
|
|
{ href: '/blog', text: 'Blog & Insights' },
|
|
{ href: '/case-studies', text: 'Case Studies' },
|
|
{ href: '/whitepapers', text: 'Whitepapers' },
|
|
{ href: '/webinars', text: 'Webinars' }
|
|
]
|
|
},
|
|
{
|
|
key: 'contact',
|
|
title: 'Contact Info',
|
|
icon: <MailOutlined className={styles.footerColumnIcon} />,
|
|
links: [
|
|
{ href: 'mailto:info@techmaster.com', text: 'info@techmaster.com' },
|
|
{ href: 'tel:+15551234567', text: '+1 (555) 123-4567' },
|
|
{ href: '#', text: 'San Francisco, CA' },
|
|
{ href: '/support', text: '24/7 Support' }
|
|
]
|
|
}
|
|
];
|
|
|
|
const getLinkIcon = (href: string) => {
|
|
if (href.startsWith('mailto:')) return <MailOutlined className={styles.footerLinkIcon} />;
|
|
if (href.startsWith('tel:')) return <PhoneOutlined className={styles.footerLinkIcon} />;
|
|
if (href.includes('support')) return <ArrowRightOutlined className={styles.footerLinkIcon} />;
|
|
if (href.includes('San Francisco')) return <EnvironmentOutlined className={styles.footerLinkIcon} />;
|
|
return <ArrowRightOutlined className={styles.footerLinkIcon} />;
|
|
};
|
|
|
|
return (
|
|
<footer className={styles.footer}>
|
|
<div className={styles.footerBackground}>
|
|
<div className={styles.footerOrb1}></div>
|
|
<div className={styles.footerOrb2}></div>
|
|
</div>
|
|
|
|
<div className={styles.footerContainer}>
|
|
<motion.div
|
|
variants={containerVariants}
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={{ once: true }}
|
|
className={styles.footerContent}
|
|
>
|
|
{footerSections.map((section) => (
|
|
<motion.div
|
|
key={section.key}
|
|
variants={itemVariants}
|
|
className={`${styles.footerColumn} ${isMobile ? styles.mobileFooterColumn : ''}`}
|
|
>
|
|
<div
|
|
className={`${styles.footerColumnTitle} ${isMobile && expandedSections[section.key] ? styles.expanded : ''}`}
|
|
onClick={() => toggleSection(section.key)}
|
|
role={isMobile ? 'button' : undefined}
|
|
tabIndex={isMobile ? 0 : undefined}
|
|
onKeyDown={(e) => {
|
|
if (isMobile && (e.key === 'Enter' || e.key === ' ')) {
|
|
e.preventDefault();
|
|
toggleSection(section.key);
|
|
}
|
|
}}
|
|
>
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
{section.icon}
|
|
{section.title}
|
|
</div>
|
|
</div>
|
|
<ul className={`${styles.footerLinks} ${isMobile && expandedSections[section.key] ? styles.expanded : ''}`}>
|
|
{section.links.map((link, index) => (
|
|
<li key={index} className={styles.footerLink}>
|
|
<a
|
|
href={link.href}
|
|
onClick={(e) => {
|
|
// Prevent navigation if it's a placeholder link
|
|
if (link.href === '#') {
|
|
e.preventDefault();
|
|
}
|
|
}}
|
|
>
|
|
{getLinkIcon(link.href)}
|
|
{link.text}
|
|
</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</motion.div>
|
|
))}
|
|
</motion.div>
|
|
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.6, delay: 0.3 }}
|
|
viewport={{ once: true }}
|
|
className={styles.footerBottom}
|
|
>
|
|
<Paragraph className={styles.footerBottomText}>
|
|
Ready to transform your business? Let's discuss your next project.
|
|
</Paragraph>
|
|
|
|
<div className={styles.socialLinks}>
|
|
<a
|
|
href="#"
|
|
className={styles.socialLink}
|
|
onClick={(e) => e.preventDefault()}
|
|
aria-label="Facebook"
|
|
>
|
|
<FacebookOutlined />
|
|
</a>
|
|
<a
|
|
href="#"
|
|
className={styles.socialLink}
|
|
onClick={(e) => e.preventDefault()}
|
|
aria-label="Twitter"
|
|
>
|
|
<TwitterOutlined />
|
|
</a>
|
|
<a
|
|
href="#"
|
|
className={styles.socialLink}
|
|
onClick={(e) => e.preventDefault()}
|
|
aria-label="LinkedIn"
|
|
>
|
|
<LinkedinOutlined />
|
|
</a>
|
|
<a
|
|
href="#"
|
|
className={styles.socialLink}
|
|
onClick={(e) => e.preventDefault()}
|
|
aria-label="Instagram"
|
|
>
|
|
<InstagramOutlined />
|
|
</a>
|
|
</div>
|
|
|
|
<div className={styles.copyright}>
|
|
<span>© 2024 Tech Master. All rights reserved.</span>
|
|
<div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap', justifyContent: 'center' }}>
|
|
<a href="/privacy" onClick={(e) => e.preventDefault()}>Privacy Policy</a>
|
|
<a href="/terms" onClick={(e) => e.preventDefault()}>Terms of Service</a>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</footer>
|
|
);
|
|
};
|
|
|
|
export default Footer;
|