Files
web/src/components/scene-page.tsx

301 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import {ReactNode} from 'react'
import Image, {StaticImageData} from 'next/image'
import {useRouter} from 'next/navigation'
import {Button} from '@/components/ui/button'
import {merge} from '@/lib/utils'
import HomePage from '@/components/home/page'
import Wrap from '@/components/wrap'
import check_main from '@/assets/check-main.svg'
import check_accent from '@/assets/check-accent.svg'
// 后2个区块的固定图片
import advantageImg1 from '@/assets/scene/advantage-1.webp'
import advantageImg2 from '@/assets/scene/advantage-2.webp'
import advantageImg3 from '@/assets/scene/advantage-3.webp'
import advantageImg4 from '@/assets/scene/advantage-4.webp'
import advantageImg5 from '@/assets/scene/advantage-5.webp'
import advantageImg6 from '@/assets/scene/advantage-6.webp'
import solutionDiagram from '@/assets/scene/solution-diagram.webp'
// 类型定义
export type ScenePageConfig = {
breadcrumb: {
label: string
href: string
}
banner: {
title: string
description: string
backgroundImage: StaticImageData
features: [string, string, string]
}
value: {
title: string
cards: [
{
icon: StaticImageData
title: string
description: string
},
{
icon: StaticImageData
title: string
description: string
},
{
icon: StaticImageData
title: string
description: string
},
]
}
solution: {
title: string
image: StaticImageData
paragraphs: string[]
}
}
export default function ScenePage(props: ScenePageConfig) {
const router = useRouter()
return (
<HomePage path={[
{label: '业务场景'},
props.breadcrumb,
]}>
<Wrap className="flex flex-col gap-16 lg:gap-32 mb-16 lg:mb-32">
{/* 1. Banner 区 - 可定制 */}
<section className="flex-none basis-40 relative flex flex-col gap-4 justify-center">
<Image
src={props.banner.backgroundImage}
alt="背景图"
className="absolute inset-0 w-full h-full object-cover rounded-lg"
priority
/>
<div className="relative pt-30 pb-48 max-md:pt-32 max-md:pb-24 min-h-[500px]">
<div className="relative max-lg:pl-8 lg:pl-20 lg:w-1/2 max-lg:w-full flex-1">
<h1 className="text-4xl max-md:text-3xl">{props.banner.title}</h1>
<p className="mt-10 text-gray-500 max-md:text-sm">
{props.banner.description}
</p>
<div className="mt-24 max-md:mt-14 flex gap-8 max-md:flex-col">
{props.banner.features.map((feature, i) => (
<p key={i} className="flex gap-4 items-center">
<Image src={check_main} alt="checkbox" width={24} height={24}/>
<span className="lg:text-md">{feature}</span>
</p>
))}
</div>
<Button
className={[
`mt-32 max-md:mt-20 w-96 max-md:w-full h-16 md:h-24 rounded-lg shadow-lg`,
`bg-linear-to-r from-blue-500 to-cyan-400 text-white text-xl lg:text-4xl hover:from-blue-600 hover:to-cyan-500`,
].join(' ')}
onClick={() => router.push('/product?type=short')}
>
</Button>
</div>
</div>
</section>
{/* 2. 场景价值区 - 可定制 */}
<Section title={props.value.title}>
<ul className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{props.value.cards.map((card, i) => (
<li key={i} className="p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg max-md:items-center">
<Image
src={card.icon}
alt={card.title}
className="w-44 h-44 object-cover"
/>
<h3 className="text-xl">{card.title}</h3>
<p className="text-sm text-gray-500">
{card.description}
</p>
</li>
))}
</ul>
</Section>
{/* 3. 解决方案介绍区 - 可定制 */}
<Section>
<div className="flex gap-8 max-lg:flex-col">
<Image
src={props.solution.image}
alt={props.solution.title}
className="w-0 flex-1 lg:max-w-[50%] object-cover rounded-lg"
/>
<div className="flex-1 flex flex-col gap-6 justify-center">
<h2 className="text-2xl font-medium">{props.solution.title}</h2>
{props.solution.paragraphs.map((paragraph, i) => (
<p key={i} className="text-gray-500 leading-relaxed">
{paragraph}
</p>
))}
</div>
</div>
</Section>
{/* 4. 产品核心优势区 - 固定内容 */}
<Section title="产品核心优势">
<ul className={merge('grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8')}>
<li className={merge('p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg max-md:items-center')}>
<Image
src={advantageImg1}
alt="稳健可靠"
className="w-44 h-44 object-cover"
/>
<h3 className="text-xl"></h3>
<div className="flex flex-col gap-3">
<p className="text-sm text-gray-500">
//IP都经过技术团队的严格筛选和验证
</p>
</div>
</li>
<li className={merge('p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg max-md:items-center')}>
<Image
src={advantageImg2}
alt="资源积累"
className="w-44 h-44 object-cover"
/>
<h3 className="text-xl"></h3>
<div className="flex flex-col gap-3">
<p className="text-sm text-gray-500">
3000+
</p>
</div>
</li>
<li className={merge('p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg max-md:items-center')}>
<Image
src={advantageImg3}
alt="稳定连接"
className="w-44 h-44 object-cover"
/>
<h3 className="text-xl"></h3>
<div className="flex flex-col gap-3">
<p className="text-sm text-gray-500">
IP的纯净度高达99.8%IP的影响
</p>
</div>
</li>
<li className={merge('p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg max-md:items-center')}>
<Image
src={advantageImg4}
alt="超匿名性"
className="w-44 h-44 object-cover"
/>
<h3 className="text-xl"></h3>
<div className="flex flex-col gap-3">
<p className="text-sm text-gray-500">
IP地址
</p>
</div>
</li>
</ul>
<ul className="flex mt-8 gap-8 max-md:flex-col">
<li className={merge('flex-1 p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg max-md:items-center')}>
<Image
src={advantageImg5}
alt="可视化管理"
className="w-44 h-44 object-cover"
/>
<h3 className="text-xl"></h3>
<div className="flex flex-col gap-3">
<p className="text-sm text-gray-500">
IP使用情况
</p>
</div>
</li>
<li className={merge('flex-1 p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg max-md:items-center')}>
<Image
src={advantageImg6}
alt="灵活定价"
className="w-44 h-44 object-cover"
/>
<h3 className="text-xl"></h3>
<div className="flex flex-col gap-3">
<p className="text-sm text-gray-500">
</p>
</div>
</li>
</ul>
</Section>
{/* 5. 定制方案区 - 固定内容 */}
<Section>
<div className="flex gap-8 max-md:flex-col max-md:gap-4">
<div className={merge('shadow-[4px_4px_20px_4px] shadow-blue-50 flex-1 p-4 flex justify-center items-center bg-gray-50 rounded-lg')}>
<Image
src={solutionDiagram}
alt="代理解决方案示意图"
className="w-full h-auto object-contain max-h-64"
/>
</div>
<div className="flex-1 flex flex-col gap-6">
<div>
<h2 className="text-2xl font-medium"></h2>
<p className="text-gray-500 mt-2">
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div className="flex gap-2 items-center">
<Image src={check_accent} alt="特性" width={20} height={20}/>
<span className="text-sm">IP时效3-30()</span>
</div>
<div className="flex gap-2 items-center">
<Image src={check_accent} alt="特性" width={20} height={20}/>
<span className="text-sm">IP覆盖全国各地</span>
</div>
<div className="flex gap-2 items-center">
<Image src={check_accent} alt="特性" width={20} height={20}/>
<span className="text-sm">线</span>
</div>
<div className="flex gap-2 items-center">
<Image src={check_accent} alt="特性" width={20} height={20}/>
<span className="text-sm"></span>
</div>
<div className="flex gap-2 items-center">
<Image src={check_accent} alt="特性" width={20} height={20}/>
<span className="text-sm">0.03s</span>
</div>
<div className="flex gap-2 items-center">
<Image src={check_accent} alt="特性" width={20} height={20}/>
<span className="text-sm">IP线路</span>
</div>
</div>
<Button
className="bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-md w-fit"
onClick={() => router.push('/custom')}
>
</Button>
</div>
</div>
</Section>
</Wrap>
</HomePage>
)
}
function Section(props: {
title?: string
children: ReactNode
}) {
return (
<section>
<div className="max-w-[1232px] mx-auto px-4 flex flex-col items-stretch">
{props.title && <h2 className="text-center text-3xl mb-8 lg:mb-24">{props.title}</h2>}
{props.children}
</div>
</section>
)
}