产品和提取页面

This commit is contained in:
2025-03-14 12:40:51 +08:00
parent e1ca9bfff0
commit c0f367954d
30 changed files with 2449 additions and 280 deletions

View File

@@ -1,123 +0,0 @@
import Wrap from '@/components/wrap'
export type FooterProps = {}
export default function Footer(props: FooterProps) {
return (
<footer className="bg-gray-900 text-white overflow-hidden">
<Wrap className="flex flex-col px-4 py-8 lg:p-12">
<div className={`flex-auto overflow-hidden flex flex-wrap justify-between`}>
<div className="flex flex-col lg:items-center gap-2 lg:gap-6 max-lg:w-1/2">
<img src="/qrcode.svg" alt="logo" className="flex-none w-20 h-20 sm:w-44 sm:h-44 bg-gray-100"/>
<span className="text-sm font-light"></span>
</div>
<div className={`flex flex-col gap-2 lg:gap-4 max-lg:w-1/2`}>
<h3></h3>
<p className={`text-sm text-gray-500 font-light`}>大客户经理:张经理</p>
<p className={`text-sm text-gray-500 font-light`}>/微信:18751847847</p>
<p className={`text-sm text-gray-500 font-light`}>QQ号:800180559</p>
<h3 className={`hidden sm:block`}></h3>
<p className={`text-sm text-gray-500 font-light hidden sm:block`}></p>
<p className={`text-sm text-gray-500 font-light hidden sm:block`}></p>
</div>
<SiteNavList
title={`站点导航`}
items={[
{name: `产品订购`, href: `#`},
{name: `获取代理`, href: `#`},
{name: `帮助中心`, href: `#`},
{name: `企业服务`, href: `#`},
{name: `推广返利`, href: `#`},
]}
/>
<SiteNavList
title={`国内代理`}
items={[
{name: `短效代理`, href: `#`},
{name: `长效代理`, href: `#`},
{name: `固定IP代理`, href: `#`},
]}
/>
<SiteNavList
title={`全球代理`}
items={[
{name: `动态代理`, href: `#`},
{name: `静态代理`, href: `#`},
]}
/>
<SiteNavList
title={`使用案例`}
items={[
{name: `数据抓取`, href: `#`},
{name: `媒体矩阵`, href: `#`},
{name: `广告验证`, href: `#`},
{name: `价格监控`, href: `#`},
{name: `市场调研`, href: `#`},
{name: `金融数据`, href: `#`},
{name: `SEO优化`, href: `#`},
{name: `网站测试`, href: `#`},
]}
/>
<SiteNavList
title={`获取代理`}
items={[
{name: `API提取`, href: `#`},
{name: `代码示例`, href: `#`},
{name: `热门地区`, href: `#`},
]}
/>
<SiteNavList
title={`代理资讯`}
items={[
{name: `产品功能`, href: `#`},
{name: `使用教程`, href: `#`},
{name: `行业资讯`, href: `#`},
]}
/>
</div>
<div className={`flex-none mt-6 pt-6 border-t border-gray-300 flex flex-col items-center`}>
<p className={`text-sm font-light`}>
HTTP仅提供代理IP服务使HTTP从事任何违法犯罪行为HTTP不承担任何法律责任
<a href="#"></a>
</p>
<p className={`text-sm mt-3 font-light`}>
577404-405</p>
<p className={`text-sm mt-3 font-light`}>
B1-11111111
ICP备111111111号-1
11111111111111
</p>
</div>
</Wrap>
</footer>
)
}
function SiteNavList(props: {
title: string
items: {
name: string
href: string
}[]
}) {
return (
<div className={`max-lg:mt-4 w-full lg:w-auto`}>
<h3>{props.title}</h3>
<ul
className={[
`mt-1 flex flex-wrap gap-2 font-light`,
`lg:mt-4 lg:h-[184px] lg:flex-col lg:gap-4 lg:gap-x-6`,
].join(' ')}>
{props.items.map((item, index) => (
<li key={index}>
<a href={item.href} className={`text-sm text-gray-500`}>{item.name}</a>
</li>
))}
</ul>
</div>
)
}

View File

@@ -1,434 +0,0 @@
'use client'
import {ReactNode, useCallback, useEffect, useMemo, useState} from 'react'
import Link from 'next/link'
import Wrap from '@/components/wrap'
export type HeaderProps = {}
export default function Header(props: HeaderProps) {
// ======================
// 滚动条状态
// ======================
const [scroll, setScroll] = useState(false) // Changed to false for client-side rendering
const handleScroll = useCallback(() => {
setScroll(window.scrollY > 48)
}, [])
useEffect(() => {
// Initialize scroll state on client
setScroll(window.scrollY > 48)
window.addEventListener('scroll', handleScroll)
return () => {
window.removeEventListener('scroll', handleScroll)
}
}, [handleScroll])
// ======================
// 菜单状态
// ======================
const [menu, setMenu] = useState(false)
const [page, setPage] = useState(0)
const pages = useMemo(() => [
<ProductMenu key={`product`}/>,
<SolutionMenu key={`solution`}/>,
<HelpMenu key={`help`}/>,
], [])
// ======================
// 覆盖状态
// ======================
const [overlay, setOverlay] = useState(false)
useEffect(() => {
setOverlay(scroll || menu)
}, [menu, scroll])
// ======================
// 渲染组件
// ======================
const LinkItem = (props: {
text: string
href: string
}) => (
<li className={`group relative`}>
<Link
href={props.href}
className={[
`h-full px-4 flex items-center text-lg`,
`transition-colors duration-200 ease-in-out`,
`hover:text-blue-500`,
].join(' ')}
>
{props.text}
</Link>
<div className={[
`absolute bottom-0 w-full h-0.5 bg-transparent `,
`transition-colors duration-200`,
`group-hover:bg-blue-500`,
].join(' ')}>
</div>
</li>
)
const MenuItem = (props: {
text: string
page: number
}) => (
<li className={`group relative`}>
<button
onPointerEnter={() => {
setMenu(true)
setPage(props.page)
}}
onPointerLeave={() => {
setMenu(false)
}}
className={[
`h-full px-4 flex gap-3 items-center cursor-pointer text-lg`,
`transition-colors duration-200 ease-in-out`,
menu && page === props.page
? `text-blue-500`
: ``,
].join(' ')}
>
<span>{props.text}</span>
<img
src={`/header/down.svg`}
alt={`drop_menu`}
className={[
`transition-transform duration-200 ease-in-out`,
menu && page === props.page
? `rotate-180`
: ``,
].join(' ')}
/>
</button>
<div className={[
`absolute bottom-0 w-full h-0.5 bg-transparent pointer-events-none`,
`transition-colors duration-200`,
menu && page === props.page ? `bg-blue-500` : '',
].join(' ')}>
</div>
</li>
)
return (
<header className={[
`fixed top-0 w-full z-10`,
].join(' ')}>
<div className={[
``,
`transition-[background, shadow] duration-200 ease-in-out`,
menu
? `bg-[#fffe] backdrop-blur-sm`
: scroll
? `bg-[#fffe] backdrop-blur-sm shadow-lg`
: `bg-transparent shadow-none`,
].join(' ')}>
<Wrap className="h-20 max-md:h-16 flex justify-between">
<div className="flex justify-between gap-8">
{/* logo */}
<Link href="/" className={`flex items-center`}>
<img src={`/logo.svg`} alt={`logo`} className={`w-16 max-md:w-12 h-16 max-md:h-12 rounded-full bg-gray-100`}/>
</Link>
{/* 菜单 */}
<nav>
<ul className="h-full flex items-stretch max-lg:hidden">
<LinkItem text={`首页`} href={`/`}/>
<MenuItem text={`产品订购`} page={0}/>
<MenuItem text={`业务场景`} page={1}/>
<MenuItem text={`帮助中心`} page={2}/>
<LinkItem text={`企业服务`} href={`#`}/>
<LinkItem text={`推广返利`} href={`#`}/>
</ul>
</nav>
</div>
{/* 登录 */}
<div className={`flex items-center`}>
<a
href="#"
className={`w-24 h-12 flex items-center justify-center lg:text-lg font-medium`}
>
<span></span>
</a>
<a
href="#"
className={`w-20 lg:w-24 h-10 lg:h-12 bg-gradient-to-r from-blue-500 to-cyan-400 rounded-sm flex items-center justify-center lg:text-lg font-medium text-white`}
>
<span></span>
</a>
</div>
</Wrap>
</div>
{/* 下拉菜单 */}
<div
className={[
`shadow-lg`,
`overflow-hidden bg-[#fffe] backdrop-blur-sm`,
`transition-[opacity,padding,height] transition-discrete duration-200 ease-in-out`,
menu
? `delay-[0s,0s,0s] opacity-100 py-8 h-auto`
: `delay-[0s,0s,0.2s] opacity-0 py-0 h-0`,
].join(' ')}
onPointerEnter={() => setMenu(true)}
onPointerLeave={() => setMenu(false)}
>
{pages[page]}
</div>
</header>
)
}
function ProductMenu() {
// ====================
// Tab 选项
// ====================
type TabType = 'domestic' | 'oversea'
const [type, setType] = useState<TabType>('domestic')
const Tab = (props: {
type: TabType,
children: ReactNode
}) => {
return (
<li role="tab">
<button
className={[
`p-8 text-lg cursor-pointer border-r`,
type === props.type ? `bg-gradient-to-r from-transparent to-blue-200 border-blue-400` : `border-gray-200`,
].join(' ')}
onClick={() => setType(props.type)}
>
{props.children}
</button>
</li>
)
}
// ====================
// 渲染组件
// ====================
return (
<Wrap className="flex">
<ul role="tablist" className="w-48">
<Tab type="domestic"></Tab>
<Tab type="oversea"></Tab>
</ul>
<div className="flex-1">
{type === 'domestic'
? (
<section role="tabpanel" className="flex gap-16 mr-16">
<div className="w-64 flex flex-col gap-6">
<h3 className="font-bold mb-2 flex items-center gap-3">
<img src={`/prod.svg`} alt={`产品`} className={`w-10 h-=10`}/>
<span></span>
</h3>
<div className="flex flex-col gap-2">
<p className="flex gap-2">
<span>IP</span>
<span className="text-orange-500 text-xs text-light px-2 py-1 bg-orange-50 rounded-full">
45%
</span>
</p>
<p className="text-gray-400 text-sm">
300+
</p>
</div>
<div className="flex flex-col gap-2">
<p className="flex gap-2">
<span>IP</span>
<span className="text-orange-500 text-xs text-light px-2 py-1 bg-orange-50 rounded-full">
45%
</span>
</p>
<p className="text-gray-400 text-sm">
IPI资源覆盖全国
</p>
</div>
<div>
<p className="flex gap-2">
<span>IP</span>
<span className="text-orange-500 text-xs text-light px-2 py-1 bg-orange-50 rounded-full">
45%
</span>
</p>
</div>
</div>
<div className="w-64 flex flex-col gap-4">
<h3 className="font-bold mb-2 flex items-center gap-3">
<img src="/custom.svg" alt="定制" className="w-10 h-10"/>
<span></span>
</h3>
<div className="flex flex-col gap-2">
<p>//IP</p>
<p className="text-gray-400 text-sm">
1000
1 1 24
</p>
</div>
</div>
</section>
) : (
<section role="tabpanel">
</section>
)
}
</div>
<aside className="w-64">
<h3 className="flex gap-3 items-center mb-4">
<img src={`/anno.svg`} alt={`公告`} className={`w-10 h-10`}/>
<span></span>
</h3>
<div className="flex flex-col gap-2">
<p>线</p>
<p className="text-gray-400 text-sm">
1.使使
使
</p>
<p className="text-gray-400 text-sm">
2.使使
使
</p>
</div>
</aside>
</Wrap>
)
}
function SolutionMenu() {
const SolutionItem = (props: {
icon: string
title: string
desc: string
}) => {
return (
<div
className={[
`h-full p-4 flex gap-4 items-start rounded-md cursor-pointer`,
`transition-colors duration-200 hover:bg-blue-100`,
].join(' ')}
>
<img src={`/header/solution/${props.icon}.svg`} alt={props.title} className="w-10 h-10"/>
<div className="flex flex-col gap-1">
<h3 className="font-bold">{props.title}</h3>
<p className="text-gray-400 text-sm">{props.desc}</p>
</div>
</div>
)
}
return (
<Wrap className="grid grid-cols-4 auto-rows-fr gap-4">
<SolutionItem
icon="01"
title="数据抓取"
desc="高效采集和分析大量数据,助力企业获取大量情报"
/>
<SolutionItem
icon="02"
title="广告验证"
desc="确保广告点击和展示数据的真实性,帮助企业,提升广告效果"
/>
<SolutionItem
icon="03"
title="市场调查"
desc="收集全网行业数据,了解竞争对手动态"
/>
<SolutionItem
icon="04"
title="SEO优化"
desc="收集搜索引擎情报,提高网站在搜索引擎的排名"
/>
<SolutionItem
icon="05"
title="品牌保护"
desc="保护品牌商标打造,优质品牌形象,为企业获得更多用户"
/>
<SolutionItem
icon="06"
title="价格监控"
desc="利用优质代理IP实时监控行业价格信息提高市场竞争力"
/>
<SolutionItem
icon="07"
title="金融数据"
desc="快速获取金融市场实时数据,帮助投资者分析趋势,使其做出精准决策"
/>
<SolutionItem
icon="08"
title="网站测试"
desc="在不同环境下对网站进行性能和兼容的测试,让用户有高质量体验"
/>
</Wrap>
)
}
function HelpMenu() {
const Column = (props: {
icon: string,
title: string,
items: {
lead: string
href: string
}[]
}) => (
<div className="flex flex-col gap-4">
<h3 className="font-bold flex gap-3 items-center">
<img src={`/header/help/${props.icon}.svg`} alt={props.title} className="w-10 h-10"/>
<span>{props.title}</span>
</h3>
<ul className=" text-gray-500 text-sm flex flex-col items-end gap-2">
{props.items.map((item, index) => (
<li key={index}><Link href={item.href}>{item.lead}</Link></li>
))}
</ul>
</div>
)
return (
<Wrap className="w-full grid grid-cols-4 gap-4 justify-items-center">
<Column
icon="01"
title="提取IP"
items={[
{lead: '短效动态IP提取', href: '#'},
{lead: '长效静态IP提取', href: '#'},
]}
/>
<Column
icon="02"
title="使用教程"
items={[
{lead: '快速入手', href: '#'},
{lead: '代码下载', href: '#'},
{lead: 'API文档', href: '#'},
]}
/>
<Column
icon="03"
title="产品功能"
items={[
{lead: '常见问题', href: '#'},
{lead: '产品介绍', href: '#'},
{lead: '行业资讯', href: '#'},
]}
/>
<img src={`/header/help/banner.webp`} alt={`banner`} className={``}/>
</Wrap>
)
}

View File

@@ -1,227 +0,0 @@
import {ReactNode} from 'react'
import Link from 'next/link'
import Header from '@/app/(home)/header'
import Wrap from '@/components/wrap'
import Image from 'next/image'
import Footer from './footer'
export default function Home() {
return (
<div className={`overflow-auto flex flex-col items-stretch relative`}>
{/* 页头 */}
<Header/>
{/* 正文 */}
<main className={`flex flex-col gap-16 lg:gap-32 mb-16 lg:mb-32`}>
{/* banner */}
<section className={`w-full bg-[url('/banner.webp')] bg-cover bg-[center_right_40%]`}>
<Wrap className={`pt-64 pb-48 max-md:pt-32 max-md:pb-24`}>
<h1 className={`text-4xl font-medium`}></h1>
<p className={`mt-10 text-gray-500`}>IP代理服务</p>
<div className={`mt-24 max-md:mt-14 flex gap-8 max-md:flex-col`}>
<p className={`flex gap-4 items-center`}>
<Image src={`/check.svg`} alt={`checkbox`} width={24} height={24}/>
<span className={`lg:text-lg font-light`}>200+</span>
</p>
<p className={`flex gap-4 items-center`}>
<Image src={`/check.svg`} alt={`checkbox`} width={24} height={24}/>
<span className={`lg:text-lg font-light`}>300+</span>
</p>
<p className={`flex gap-4 items-center`}>
<Image src={`/check.svg`} alt={`checkbox`} width={24} height={24}/>
<span className={`lg:text-lg font-light`}>&</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-gradient-to-r from-blue-500 to-cyan-400 text-white text-xl lg:text-4xl font-medium`,
].join(' ')}>
</button>
</Wrap>
</section>
{/* 数据展示 */}
<Section title={`覆盖全国的IP资源及超大的带宽线路`}>
<ul className={`shadow-[0_0_20px_4px] shadow-blue-50 p-8 flex max-lg:flex-col`}>
<li className={`flex-1 flex flex-col items-center justify-center lg:border-r max-lg:mb-4 border-gray-200`}>
<p className={`text-xl`}>线</p>
<p className={`mt-9 max-lg:mt-2 text-5xl bg-gradient-to-t from-blue-500 to-cyan-400 bg-clip-text text-transparent font-bold pb-2 -mb-2`}>350+</p>
<div className={`lg:hidden w-24 border-b mt-4 border-gray-200`}></div>
</li>
<li className={`flex-1 flex flex-col items-center justify-center lg:border-r max-lg:mb-4 border-gray-200`}>
<p className={`text-xl`}>IP数量</p>
<p className={`mt-9 max-lg:mt-2 text-5xl bg-gradient-to-t from-blue-500 to-cyan-400 bg-clip-text text-transparent font-bold pb-2 -mb-2`}>1,350,129</p>
<div className={`lg:hidden w-24 border-b mt-4 border-gray-200`}></div>
</li>
<li className={`flex-1 flex flex-col items-center justify-center lg:border-r max-lg:mb-4 border-gray-200`}>
<p className={`text-xl`}></p>
<p className={`mt-9 max-lg:mt-2 text-5xl bg-gradient-to-t from-blue-500 to-cyan-400 bg-clip-text text-transparent font-bold pb-2 -mb-2`}>26,578</p>
<div className={`lg:hidden w-24 border-b mt-4 border-gray-200`}></div>
</li>
<li className={`flex-1 flex flex-col items-center justify-center`}>
<p className={`text-xl`}>IP可用率</p>
<p className={`mt-9 max-lg:mt-2 text-5xl bg-gradient-to-t from-blue-500 to-cyan-400 bg-clip-text text-transparent font-bold pb-2 -mb-2`}>99%</p>
</li>
</ul>
<img src={`/map.webp`} alt={`map`} className="w-[1200px]"/>
</Section>
{/* 优势 1 */}
<Section title={`HTTP安全合规的代理IP资源池`}>
<ul
className={[
`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8`,
].join(' ')}>
<Sec3Item
icon={`s1-1`} title={`短期动态IP池`} terms={[
{icon: `s1-check`, text: `IP时效3-30分钟(可定制)`},
{icon: `s1-check`, text: `支持高并发提取`},
]}/>
<Sec3Item
icon={`s1-2`} title={`长期静态IP池`} terms={[
{icon: `s1-check`, text: `IP覆盖全国各地`},
{icon: `s1-check`, text: `平均响应时长0.03s`},
]}/>
<Sec3Item
icon={`s1-3`} title={`固定IP池`} terms={[
{icon: `s1-check`, text: `稳定长输不掉线`},
{icon: `s1-check`, text: `全国热门静态IP线路`},
]}/>
<Sec3Item
icon={`s1-4`} title={`企业级定制池`} terms={[
{icon: `s1-check`, text: `可视化监控设计`},
{icon: `s1-check`, text: `技术团队现场支持`},
]}/>
</ul>
</Section>
{/* 优势 2 */}
<Section title={`HTTP 产品优势`}>
<div className={`flex gap-36`}>
<ul className={`flex-1 flex flex-col gap-6`}>
<Sec4Item icon={`s4-1-1`} title={`安全合规`} description={`国内三大运营商支持`}/>
<Sec4Item icon={`s4-1-2`} title={`稳定链接`} description={`IP纯净度高达99.9%`}/>
<Sec4Item icon={`s4-1-3`} title={`超匿名性`} description={`稳定传输,保护隐私安全`}/>
</ul>
<img src={`/s4-1-main.webp`} alt={`s2-1-main`} className={`w-0 flex-1 object-contain max-lg:hidden`}/>
</div>
<div className={`flex gap-36`}>
<img src={`/s4-2-main.webp`} alt={`s2-1-main`} className={`w-0 flex-1 object-contain max-lg:hidden`}/>
<ul className={`flex-1 flex flex-col gap-6`}>
<Sec4Item icon={`s4-2-1`} title={`API接口文档`} description={`与第三方软件轻松集成`}/>
<Sec4Item icon={`s4-2-2`} title={`多种编程语言代码`} description={`C语言、GO语言、Python...`}/>
<Sec4Item icon={`s4-2-3`} title={`双重认证方式`} description={`API提取+账密认证`}/>
</ul>
</div>
</Section>
{/* 行业资讯 */}
<Section title={`行业资讯`}>
<div className={`flex gap-8 max-md:gap-4`}>
<button className={`px-4 max-md:-mx-4`}>
<img src={`/next.svg`} alt={`prev`} className={`rotate-180`}/>
</button>
<div
className={[
`shadow-[4px_4px_20px_4px] shadow-blue-50 rounded-lg`,
`flex p-14 md:gap-14 max-md:flex-col max-md:p-4`,
].join(' ')}>
<img src="/s3-main.webp" alt="tumb" className={`w-2/3 md:flex-1 md:w-0 object-cover max-md:self-center`}/>
<div className={`flex-2 flex flex-col justify-between gap-4`}>
<h3 className={`flex justify-between`}>
<span className={`text-xl font-medium`}></span>
<sub className={`text-sm text-gray-500`}>2025-03-04</sub>
</h3>
<p className={`text-gray-400 md:leading-12`}>
...
</p>
<div className={`flex justify-end`}>
<a href="#" className={`text-sm text-gray-500 flex items-center gap-4`}>
<img src={`/next.svg`} alt={`more`} className={`h-4 fill-gray-400`}/>
</a>
</div>
</div>
</div>
<button className={`px-4 max-md:-mx-4`}>
<img src={`/next.svg`} alt={`prev`}/>
</button>
</div>
</Section>
</main>
{/* 页脚 */}
<Footer/>
</div>
)
}
function Section(props: {
title: string
children: ReactNode
}) {
return (
<section>
<div className={`max-w-[1232px] mx-auto px-4 flex flex-col items-stretch`}>
<h2 className={`text-center text-3xl font-medium mb-8 lg:mb-24`}>{props.title}</h2>
{props.children}
</div>
</section>
)
}
function Sec3Item(props: {
icon: string,
title: string,
terms: {
icon: string,
text: string,
}[]
}) {
return (
<li
className={[
`p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg`,
`max-md:items-center`,
].join(' ')}>
<img src={`/${props.icon}.webp`} alt={`s1-1`} aria-hidden className="w-44 h-44 object-cover"/>
<h3 className={`text-xl font-medium`}>{props.title}</h3>
<div className={`flex flex-col gap-3`}>
{props.terms.map((item, index) => {
return (
<p key={index} className={`text-sm text-gray-500 flex gap-3 items-center`}>
<img src={`/${item.icon}.svg`} alt={`check`} aria-hidden className={`w-5 h-5`}/>
<span>{item.text}</span>
</p>
)
})}
</div>
</li>
)
}
function Sec4Item(props: {
icon: string
title: string
description: string
}) {
return (
<li className={`flex gap-8 items-center p-4 lg:p-8 shadow-[4px_4px_20px_4px] shadow-blue-50 rounded-lg`}>
<img src={`/${props.icon}.webp`} alt={`s2-1-1`} aria-hidden className="w-24 h-24 object-contain"/>
<div className={`flex flex-col gap-3`}>
<h3 className={`text-xl font-medium`}>{props.title}</h3>
<p>{props.description}</p>
</div>
</li>
)
}