203 lines
9.7 KiB
TypeScript
203 lines
9.7 KiB
TypeScript
'use client';
|
||
|
||
import { useState, useEffect } from 'react';
|
||
|
||
interface Product {
|
||
name: string;
|
||
desc: string;
|
||
price: string;
|
||
features: string[];
|
||
badge?: string;
|
||
popular?: boolean;
|
||
}
|
||
|
||
interface ProductModalProps {
|
||
product: Product | null;
|
||
isOpen: boolean;
|
||
onClose: () => void;
|
||
contactText: string;
|
||
locale: string;
|
||
}
|
||
|
||
export default function ProductModal({ product, isOpen, onClose, contactText, locale }: ProductModalProps) {
|
||
const [isVisible, setIsVisible] = useState(false);
|
||
|
||
useEffect(() => {
|
||
if (isOpen) {
|
||
setIsVisible(true);
|
||
// 保存原始的overflow值
|
||
const originalOverflow = document.body.style.overflow;
|
||
document.body.style.overflow = 'hidden';
|
||
|
||
return () => {
|
||
// 恢复原始的overflow值
|
||
document.body.style.overflow = originalOverflow || 'unset';
|
||
};
|
||
} else {
|
||
// 延迟恢复overflow,允许动画完成
|
||
const timer = setTimeout(() => {
|
||
document.body.style.overflow = 'unset';
|
||
}, 300);
|
||
|
||
return () => {
|
||
clearTimeout(timer);
|
||
};
|
||
}
|
||
}, [isOpen]);
|
||
|
||
const handleClose = () => {
|
||
setIsVisible(false);
|
||
setTimeout(() => {
|
||
onClose();
|
||
}, 300);
|
||
};
|
||
|
||
if (!isOpen || !product) return null;
|
||
|
||
return (
|
||
<div className={`fixed inset-0 z-50 flex items-center justify-center p-4 transition-opacity duration-300 ${
|
||
isVisible ? 'opacity-100' : 'opacity-0'
|
||
}`}>
|
||
{/* 背景遮罩 */}
|
||
<div
|
||
className="absolute inset-0 bg-black bg-opacity-50 backdrop-blur-sm"
|
||
onClick={handleClose}
|
||
/>
|
||
|
||
{/* 模态框内容 */}
|
||
<div className={`relative bg-white rounded-2xl shadow-2xl max-w-2xl w-full max-h-[90vh] overflow-y-auto transform transition-all duration-300 ${
|
||
isVisible ? 'scale-100 translate-y-0' : 'scale-95 translate-y-4'
|
||
}`}>
|
||
{/* 关闭按钮 */}
|
||
<button
|
||
onClick={handleClose}
|
||
title="关闭"
|
||
aria-label="关闭产品详情"
|
||
className="absolute top-4 right-4 z-10 w-8 h-8 bg-gray-100 hover:bg-gray-200 rounded-full flex items-center justify-center transition-colors duration-200"
|
||
>
|
||
<svg className="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||
</svg>
|
||
</button>
|
||
|
||
{/* 产品标签 */}
|
||
<div className="absolute top-4 left-4 z-10 flex gap-2">
|
||
{product.badge && (
|
||
<span className="bg-blue-600 text-white text-xs font-semibold px-3 py-1 rounded-full shadow-lg">
|
||
{product.badge}
|
||
</span>
|
||
)}
|
||
{product.popular && (
|
||
<span className="bg-gradient-to-r from-orange-400 to-red-500 text-white text-xs font-bold px-3 py-1 rounded-full shadow-lg">
|
||
🔥 热门
|
||
</span>
|
||
)}
|
||
</div>
|
||
|
||
<div className="p-8 pt-16">
|
||
{/* 产品标题和价格 */}
|
||
<div className="mb-6">
|
||
<h2 className="text-3xl font-bold text-gray-900 mb-4">
|
||
{product.name}
|
||
</h2>
|
||
<div className="text-4xl font-bold text-blue-600 mb-4">
|
||
{product.price}
|
||
{product.price.includes('/月') && (
|
||
<span className="text-lg text-gray-500 ml-2 font-normal">
|
||
按月计费
|
||
</span>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* 产品描述 */}
|
||
<div className="mb-8">
|
||
<h3 className="text-lg font-semibold text-gray-900 mb-3">产品介绍</h3>
|
||
<p className="text-gray-700 leading-relaxed">
|
||
{product.desc}
|
||
</p>
|
||
</div>
|
||
|
||
{/* 功能特性 */}
|
||
<div className="mb-8">
|
||
<h3 className="text-lg font-semibold text-gray-900 mb-4">功能特性</h3>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||
{product.features.map((feature, index) => (
|
||
<div key={index} className="flex items-center">
|
||
<svg
|
||
className="w-5 h-5 text-green-500 mr-3 flex-shrink-0"
|
||
fill="currentColor"
|
||
viewBox="0 0 20 20"
|
||
>
|
||
<path
|
||
fillRule="evenodd"
|
||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||
clipRule="evenodd"
|
||
/>
|
||
</svg>
|
||
<span className="text-gray-700">{feature}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* 适用场景 */}
|
||
<div className="mb-8">
|
||
<h3 className="text-lg font-semibold text-gray-900 mb-3">适用场景</h3>
|
||
<div className="bg-blue-50 rounded-lg p-4">
|
||
<p className="text-blue-800 text-sm">
|
||
{getUseCases(product.name)}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 操作按钮 */}
|
||
<div className="flex flex-col sm:flex-row gap-4">
|
||
<a
|
||
href={locale === 'zh-CN' ? '/contact' : `/${locale}/contact`}
|
||
className={`flex-1 py-4 px-6 rounded-lg font-semibold text-center transition-all duration-300 ${
|
||
product.popular
|
||
? 'bg-gradient-to-r from-blue-600 to-purple-600 text-white hover:from-blue-700 hover:to-purple-700 shadow-lg'
|
||
: 'bg-blue-600 text-white hover:bg-blue-700'
|
||
}`}
|
||
>
|
||
{contactText}
|
||
</a>
|
||
<button
|
||
onClick={handleClose}
|
||
className="flex-1 py-4 px-6 border-2 border-gray-300 text-gray-700 rounded-lg font-semibold hover:bg-gray-50 transition-colors duration-300"
|
||
>
|
||
关闭
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
function getUseCases(productName: string): string {
|
||
const useCases: { [key: string]: string } = {
|
||
'轻量云服务器': '个人博客、小型企业官网、开发测试环境、学习实验、小型应用部署',
|
||
'EC2通用型服务器': 'Web应用、企业级应用、微服务架构、API服务、中等规模网站',
|
||
'EC2计算优化型': '科学计算、机器学习训练、高性能Web服务、数据分析、视频处理',
|
||
'站群服务器': 'SEO优化、多站点管理、内容分发、营销推广、大规模网站集群',
|
||
'高防服务器': '游戏服务器、金融应用、电商平台、直播平台、高价值业务系统',
|
||
'WAF Web防火墙': 'Web应用保护、API安全、电商网站、企业门户、在线服务平台',
|
||
'SSL证书服务': '网站HTTPS加密、API接口安全、移动应用、电商交易、数据传输保护',
|
||
'S3对象存储': '网站静态资源、数据备份归档、大数据分析、内容分发、移动应用存储',
|
||
'EBS块存储': '数据库存储、文件系统、企业应用、高IOPS应用、关键业务数据',
|
||
'EFS文件存储': '内容管理系统、Web服务、大数据分析、媒体处理、共享文件存储',
|
||
'RDS关系型数据库': '企业应用、电商系统、CRM系统、ERP系统、数据仓库',
|
||
'Redis缓存服务': '会话存储、实时排行榜、消息队列、计数器、高并发缓存',
|
||
'MongoDB文档数据库': '内容管理、物联网数据、实时分析、移动应用、社交平台',
|
||
'CDN内容分发': '网站加速、视频点播、游戏更新、软件下载、全球内容分发',
|
||
'负载均衡器': '高可用架构、流量分发、故障转移、弹性扩容、微服务架构',
|
||
'VPN专线服务': '企业组网、远程办公、数据中心互联、混合云架构、安全连接',
|
||
'机器学习平台': '模型训练、数据挖掘、预测分析、推荐系统、智能决策',
|
||
'图像识别API': '人脸识别、内容审核、智能相册、安防监控、医疗影像',
|
||
'语音识别API': '智能客服、语音助手、会议记录、语音翻译、语音控制'
|
||
};
|
||
|
||
return useCases[productName] || '适用于各种业务场景,具体请咨询我们的技术专家';
|
||
}
|