manual save(2025-12-29 00:16)
This commit is contained in:
@@ -1,14 +1,250 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'react-router-dom';
|
||||
import { motion } from 'framer-motion';
|
||||
import {
|
||||
Building2,
|
||||
Phone,
|
||||
Mail,
|
||||
MapPin,
|
||||
Clock,
|
||||
Wechat,
|
||||
Weibo,
|
||||
Linkedin,
|
||||
ArrowRight,
|
||||
} from 'lucide-react';
|
||||
import {
|
||||
COMPANY_INFO,
|
||||
FOOTER_LINKS,
|
||||
SOCIAL_MEDIA,
|
||||
} from '../../lib/constants';
|
||||
|
||||
/**
|
||||
* Footer 组件 - 企业官网页脚
|
||||
*/
|
||||
|
||||
// 动画变体配置
|
||||
const containerVariants = {
|
||||
hidden: { opacity: 0 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
transition: {
|
||||
staggerChildren: 0.1,
|
||||
delayChildren: 0.2,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const itemVariants = {
|
||||
hidden: { opacity: 0, y: 20 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.5 },
|
||||
},
|
||||
};
|
||||
|
||||
// 图标映射
|
||||
const iconMap: Record<string, React.ComponentType<{ size?: number; className?: string }>> = {
|
||||
Wechat,
|
||||
Weibo,
|
||||
Linkedin,
|
||||
};
|
||||
|
||||
/**
|
||||
* 联系方式项组件
|
||||
*/
|
||||
const ContactItem: React.FC<{
|
||||
icon: React.ComponentType<{ size?: number; className?: string }>;
|
||||
title: string;
|
||||
content: string;
|
||||
}> = ({ icon: Icon, title, content }) => (
|
||||
<div className="flex items-start gap-3">
|
||||
<Icon size={18} className="text-accent mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<p className="text-xs text-gray-400 mb-0.5">{title}</p>
|
||||
<p className="text-sm text-gray-200">{content}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
/**
|
||||
* 链接列组件
|
||||
*/
|
||||
const LinkColumn: React.FC<{
|
||||
title: string;
|
||||
links: Array<{ label: string; path: string }>;
|
||||
}> = ({ title, links }) => (
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-white uppercase tracking-wider mb-4">
|
||||
{title}
|
||||
</h3>
|
||||
<ul className="space-y-3">
|
||||
{links.map((link) => (
|
||||
<li key={link.path}>
|
||||
<Link
|
||||
to={link.path}
|
||||
className="flex items-center gap-2 text-sm text-gray-300 hover:text-accent transition-colors duration-200 group"
|
||||
>
|
||||
<ArrowRight
|
||||
size={14}
|
||||
className="opacity-0 -ml-4 group-hover:opacity-100 group-hover:ml-0 transition-all duration-200"
|
||||
/>
|
||||
<span className="group-hover:translate-x-1 transition-transform duration-200">
|
||||
{link.label}
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
||||
/**
|
||||
* Footer 组件
|
||||
*/
|
||||
export const Footer: React.FC = () => {
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
return (
|
||||
<footer className="bg-gray-50 border-t border-gray-200 py-8 mt-12">
|
||||
<div className="container mx-auto px-4 text-center text-gray-600">
|
||||
<p>Powered by TenantCMS</p>
|
||||
<p className="text-sm mt-2">
|
||||
Using X-Tenant-Slug for multi-tenant authentication
|
||||
</p>
|
||||
<footer className="bg-primary-dark text-white" role="contentinfo">
|
||||
{/* 主内容区域 */}
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 lg:py-16">
|
||||
<motion.div
|
||||
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-8 lg:gap-12"
|
||||
variants={containerVariants}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
{/* 企业信息 */}
|
||||
<motion.div className="lg:col-span-2 space-y-6" variants={itemVariants}>
|
||||
{/* Logo */}
|
||||
<Link to="/" className="flex items-center gap-3 group" aria-label="返回首页">
|
||||
<div className="flex items-center justify-center w-12 h-12 rounded-lg bg-accent text-primary-dark">
|
||||
<Building2 size={28} />
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-xl font-bold text-white group-hover:text-accent transition-colors">
|
||||
诚裕集团
|
||||
</span>
|
||||
<p className="text-xs text-gray-400">Chengyu Group</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* 企业简介 */}
|
||||
<p className="text-sm text-gray-300 leading-relaxed max-w-sm">
|
||||
{COMPANY_INFO.description}
|
||||
</p>
|
||||
|
||||
{/* 联系方式 */}
|
||||
<div className="space-y-3 pt-2">
|
||||
<ContactItem
|
||||
icon={MapPin}
|
||||
title="总部地址"
|
||||
content={COMPANY_INFO.headquarters}
|
||||
/>
|
||||
<ContactItem
|
||||
icon={Phone}
|
||||
title="服务热线"
|
||||
content={COMPANY_INFO.phone}
|
||||
/>
|
||||
<ContactItem
|
||||
icon={Mail}
|
||||
title="商务邮箱"
|
||||
content={COMPANY_INFO.email}
|
||||
/>
|
||||
<ContactItem
|
||||
icon={Clock}
|
||||
title="工作时间"
|
||||
content={COMPANY_INFO.workingHours}
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* 产品服务 */}
|
||||
<motion.div variants={itemVariants}>
|
||||
<LinkColumn title="产品服务" links={FOOTER_LINKS.products} />
|
||||
</motion.div>
|
||||
|
||||
{/* 公司信息 */}
|
||||
<motion.div variants={itemVariants}>
|
||||
<LinkColumn title="关于我们" links={FOOTER_LINKS.company} />
|
||||
</motion.div>
|
||||
|
||||
{/* 社交媒体 */}
|
||||
<motion.div variants={itemVariants}>
|
||||
<h3 className="text-sm font-semibold text-white uppercase tracking-wider mb-4">
|
||||
关注我们
|
||||
</h3>
|
||||
<p className="text-xs text-gray-400 mb-4">
|
||||
了解更多企业动态
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{SOCIAL_MEDIA.map((social) => {
|
||||
const Icon = iconMap[social.icon] || Wechat;
|
||||
return (
|
||||
<motion.a
|
||||
key={social.id}
|
||||
href={social.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-2 px-3 py-2 bg-white/10 rounded-lg text-sm text-gray-300 hover:bg-accent hover:text-primary-dark transition-all duration-200"
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
aria-label={social.label}
|
||||
>
|
||||
<Icon size={18} />
|
||||
<span className="hidden sm:inline">{social.label}</span>
|
||||
</motion.a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* 底部版权栏 */}
|
||||
<div className="border-t border-white/10">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
||||
<div className="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
{/* 版权信息 */}
|
||||
<motion.p
|
||||
className="text-sm text-gray-400"
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
© {currentYear} {COMPANY_INFO.fullName} 版权所有
|
||||
</motion.p>
|
||||
|
||||
{/* 备案和链接 */}
|
||||
<motion.div
|
||||
className="flex flex-wrap items-center justify-center gap-4 text-sm text-gray-400"
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: 0.1 }}
|
||||
>
|
||||
<span>京ICP备XXXXXXXX号</span>
|
||||
<span className="hidden sm:inline">|</span>
|
||||
<Link
|
||||
to="/privacy"
|
||||
className="hover:text-accent transition-colors duration-200"
|
||||
>
|
||||
隐私政策
|
||||
</Link>
|
||||
<span className="hidden sm:inline">|</span>
|
||||
<Link
|
||||
to="/terms"
|
||||
className="hover:text-accent transition-colors duration-200"
|
||||
>
|
||||
使用条款
|
||||
</Link>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
|
||||
Reference in New Issue
Block a user