fix: demo首页
This commit is contained in:
parent
3e18012b1b
commit
84cd214dc5
@ -200,7 +200,7 @@ export default function Page() {
|
||||
{t('goToPayment')}
|
||||
</Button>
|
||||
<Button variant='outline'>
|
||||
<Link href='/'>{t('productList')}</Link>
|
||||
<Link href='/apps/user/public'>{t('productList')}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@ -1,11 +1,16 @@
|
||||
import { GlobalMap } from '@/components/main/global-map';
|
||||
/*import { GlobalMap } from '@/components/main/global-map';
|
||||
import { Hero } from '@/components/main/hero';
|
||||
import { ProductShowcase } from '@/components/main/product-showcase/index';
|
||||
import { Stats } from '@/components/main/stats';
|
||||
import { Stats } from '@/components/main/stats';*/
|
||||
import NewHeader from '@/components/Header/NewHeader';
|
||||
import { queryUserInfo } from '@/services/user/user';
|
||||
import { cookies } from 'next/headers';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
import FooterCopyright from '@/components/main/FooterCopyright';
|
||||
import FullScreenVideoBackground from '@/components/main/FullScreenVideoBackground';
|
||||
import HomeContent from '@/components/main/HomeContent';
|
||||
|
||||
export default async function Home() {
|
||||
const Authorization = (await cookies()).get('Authorization')?.value;
|
||||
|
||||
@ -26,11 +31,13 @@ export default async function Home() {
|
||||
}
|
||||
|
||||
return (
|
||||
<main className='container space-y-16'>
|
||||
<Hero />
|
||||
<Stats />
|
||||
<ProductShowcase />
|
||||
<GlobalMap />
|
||||
</main>
|
||||
<>
|
||||
<NewHeader />
|
||||
<FullScreenVideoBackground />
|
||||
<main className='fixed inset-0 z-10 flex items-center justify-center'>
|
||||
<HomeContent />
|
||||
</main>
|
||||
<FooterCopyright />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
51
apps/user/components/Header/NewHeader.tsx
Normal file
51
apps/user/components/Header/NewHeader.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
'use client';
|
||||
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { buttonVariants } from '@workspace/ui/components/button';
|
||||
import { cn } from '@workspace/ui/lib/utils';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Image from 'next/legacy/image';
|
||||
import Link from 'next/link';
|
||||
import LanguageSwitch from '../language-switch';
|
||||
// import ThemeSwitch from '../theme-switch';
|
||||
import { UserNav } from '../user-nav';
|
||||
import ImageLogo from './image.png';
|
||||
|
||||
export default function Header() {
|
||||
const t = useTranslations('common');
|
||||
|
||||
const { user } = useGlobalStore();
|
||||
const Logo = (
|
||||
<Link href='/' className='flex items-center gap-2 text-lg font-bold'>
|
||||
<Image src={ImageLogo} width={172} height={49} alt='logo' unoptimized />
|
||||
</Link>
|
||||
);
|
||||
return (
|
||||
<header className='fixed top-10 z-50 w-full'>
|
||||
<div className='container flex h-[73px] items-center justify-between rounded-[50px] bg-white pl-7 pr-1'>
|
||||
<nav className='flex-col gap-6 text-lg font-medium md:flex md:flex-row md:items-center md:gap-5 md:text-sm lg:gap-6'>
|
||||
{Logo}
|
||||
</nav>
|
||||
<div className='flex h-full flex-1 items-center justify-end gap-2 py-1'>
|
||||
<LanguageSwitch />
|
||||
{/*<ThemeSwitch />*/}
|
||||
<UserNav />
|
||||
{!user && (
|
||||
<Link
|
||||
href='/auth'
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
size: 'lg',
|
||||
variant: 'outline',
|
||||
}),
|
||||
'h-full rounded-[50px] border-2 border-[#0F2C53] bg-[#0F2C53] px-14 text-2xl font-bold text-white transition hover:bg-white hover:text-[#0F2C53]',
|
||||
)}
|
||||
>
|
||||
{t('login')}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
@ -5,9 +5,9 @@ import { buttonVariants } from '@workspace/ui/components/button';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Image from 'next/legacy/image';
|
||||
import Link from 'next/link';
|
||||
import LanguageSwitch from './language-switch';
|
||||
import ThemeSwitch from './theme-switch';
|
||||
import { UserNav } from './user-nav';
|
||||
import LanguageSwitch from '../language-switch';
|
||||
import ThemeSwitch from '../theme-switch';
|
||||
import { UserNav } from '../user-nav';
|
||||
|
||||
export default function Header() {
|
||||
const t = useTranslations('common');
|
||||
BIN
apps/user/components/Header/image.png
Normal file
BIN
apps/user/components/Header/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
@ -55,7 +55,7 @@ export default function LanguageSwitch() {
|
||||
<SelectTrigger className='hover:bg-accent hover:text-accent-foreground w-auto border-none bg-transparent p-2 shadow-none focus:ring-0 [&>svg]:hidden'>
|
||||
<SelectValue>
|
||||
<div className='flex items-center'>
|
||||
<Icon icon={`flagpack:${country?.alpha2.toLowerCase()}`} className='!size-5' />
|
||||
<Icon icon={`flagpack:${country?.alpha2.toLowerCase()}`} className='!size-7' />
|
||||
<span className='sr-only'>{languages[locale as keyof typeof languages]}</span>
|
||||
</div>
|
||||
</SelectValue>
|
||||
|
||||
27
apps/user/components/main/FooterCopyright.tsx
Normal file
27
apps/user/components/main/FooterCopyright.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
'use client';
|
||||
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function FooterCopyright() {
|
||||
const { common } = useGlobalStore();
|
||||
const { site } = common;
|
||||
const t = useTranslations('auth');
|
||||
|
||||
return (
|
||||
<footer className={'fixed bottom-6 z-50 w-full'}>
|
||||
<div className={'container pr-0 text-right'}>
|
||||
<strong className='text-foreground'>{site.site_name}</strong> © All rights reserved.
|
||||
<div>
|
||||
<Link href='/tos' className='underline'>
|
||||
{t('tos')}
|
||||
</Link>
|
||||
<Link href='/privacy-policy' className='ml-2 underline'>
|
||||
{t('privacyPolicy')}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
39
apps/user/components/main/FullScreenVideoBackground.tsx
Normal file
39
apps/user/components/main/FullScreenVideoBackground.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
'use client'; // 确保客户端渲染(如果在 App Router 中使用)
|
||||
|
||||
const FullScreenVideoBackground = ({}: {}) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
width: '100vw',
|
||||
height: '100vh',
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<video
|
||||
autoPlay
|
||||
muted
|
||||
loop
|
||||
playsInline
|
||||
style={{
|
||||
position: 'fixed',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
minWidth: '100%',
|
||||
minHeight: '100%',
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
zIndex: -1,
|
||||
}}
|
||||
>
|
||||
<source src={'/video.mp4'} type='video/mp4' /> {/* 传入本地视频路径,如 '/video.mp4' */}
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FullScreenVideoBackground;
|
||||
30
apps/user/components/main/HomeContent.tsx
Normal file
30
apps/user/components/main/HomeContent.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
|
||||
export default function HomeContent() {
|
||||
return (
|
||||
<div className='flex min-h-[calc(100vh-73px)] flex-col items-center justify-center pt-8'>
|
||||
{/* 大标题 */}
|
||||
<h1 className='mb-10 text-6xl font-extrabold leading-tight text-white'>
|
||||
连接
|
||||
<br />
|
||||
任何时间
|
||||
<br />
|
||||
任何地点
|
||||
</h1>
|
||||
{/* 副标题 */}
|
||||
<div className='mb-16 text-center text-sm font-bold leading-6 text-white'>
|
||||
<p>
|
||||
<span className='mr-2 text-xs text-white'>
|
||||
Airo<sup className='text-[8px]'>™</sup>Port
|
||||
</span>
|
||||
<span>提供极稳,极简,极速的网络服务</span>
|
||||
</p>
|
||||
<p>获取订阅地址,开始顶级的私密网络体验</p>
|
||||
</div>
|
||||
{/* 按钮 */}
|
||||
<Button className='mb-8 h-[64px] w-[219px] rounded-full border-2 border-white bg-white/10 text-2xl font-bold text-white transition hover:bg-white/20'>
|
||||
查看订阅套餐
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
63
apps/user/components/main/ShaderBackground.tsx
Normal file
63
apps/user/components/main/ShaderBackground.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
'use client';
|
||||
|
||||
import { ShaderGradient, ShaderGradientCanvas } from '@shadergradient/react';
|
||||
import React from 'react';
|
||||
|
||||
const ShaderBackground: React.FC<React.ComponentProps<'div'>> = ({ style, ...props }) => {
|
||||
return (
|
||||
<ShaderGradientCanvas
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
width: '100vw',
|
||||
height: '100vh',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
>
|
||||
{/*<ShaderGradient
|
||||
control="props" // 使用 props 模式,直接通过属性配置渐变参数
|
||||
animate="on" // 控制渐变是否动画化("on" 表示启用动画)
|
||||
axesHelper="on" // 是否显示坐标轴辅助线,用于调试("on" 表示显示)
|
||||
bgColor1="#ECEFF4" // 背景颜色 1,用于渐变的背景色调
|
||||
bgColor2="#ECEFF4" // 背景颜色 2,用于渐变的背景色调
|
||||
brightness={1} // 亮度级别,控制整体渐变的明亮程度
|
||||
cAzimuthAngle={1} // 相机方位角,控制相机围绕目标的水平旋转角度
|
||||
cDistance={6} // 相机距离,控制相机到目标的距离
|
||||
cPolarAngle={90} // 相机极角,控制相机围绕目标的垂直旋转角度
|
||||
cameraZoom={15} // 相机缩放级别,控制相机的放大倍数
|
||||
color1="#021033" // 渐变颜色 1,第一种主要颜色
|
||||
color2="#ECEFF4" // 渐变颜色 2,第二种主要颜色
|
||||
color3="#4E5C78" // 渐变颜色 3,第三种主要颜色
|
||||
envPreset="city" // 环境预设,设置背景环境贴图(如 "city" 表示城市环境)
|
||||
fov={45} // 视场角度(Field of View),控制相机视野宽度(度数)
|
||||
grain="off" // 颗粒效果,是否添加噪点("off" 表示关闭)
|
||||
lightType="3d" // 灯光类型,设置照明模式(如 "3d" 表示 3D 灯光)
|
||||
pixelDensity={1} // 像素密度,控制渲染质量(越高越清晰,但性能消耗更大)
|
||||
positionX={0} // X 轴位置,控制渐变网格的 X 坐标
|
||||
positionY={0} // Y 轴位置,控制渐变网格的 Y 坐标
|
||||
positionZ={5} // Z 轴位置,控制渐变网格的 Z 坐标
|
||||
reflection={1} // 反射强度,控制渐变的反射效果
|
||||
rotationX={0} // X 轴旋转,控制渐变网格的 X 轴旋转角度
|
||||
rotationY={0} // Y 轴旋转,控制渐变网格的 Y 轴旋转角度
|
||||
rotationZ={0} // Z 轴旋转,控制渐变网格的 Z 轴旋转角度
|
||||
shader="defaults" // 着色器类型,设置默认着色器("defaults" 表示默认着色器)
|
||||
type="waterPlane" // 网格类型,设置渐变的形状(如 "waterPlane" 表示水波平面)
|
||||
uAmplitude={0} // 统一变量:振幅,控制波形渐变的振幅(在 Framer 和 shadergradient.co 上重名为 Spiral)
|
||||
uDensity={2.8} // 统一变量:密度,控制渐变图案的密度
|
||||
uFrequency={5.5} // 统一变量:频率,控制渐变波形的频率
|
||||
uSpeed={0.1} // 统一变量:速度,控制渐变运动的速度
|
||||
uStrength={3.4} // 统一变量:强度,控制渐变效果的强度
|
||||
uTime={0.2} // 统一变量:时间,控制着色器动画的时间参数
|
||||
wireframe={false} // 线框模式,是否显示网格线框(false 表示关闭)
|
||||
/>*/}
|
||||
<ShaderGradient
|
||||
control='query'
|
||||
urlString={
|
||||
'https://www.shadergradient.co/customize?animate=on&axesHelper=on&bgColor1=%23ECEFF4&bgColor2=%23ECEFF4&brightness=1&cAzimuthAngle=0&cDistance=20&cPolarAngle=90&cameraZoom=1&color1=%23021033&color2=%23ECEFF4&color3=%234E5C78&destination=onCanvas&embedMode=off&envPreset=city&format=gif&fov=10&frameRate=10&grain=off&lightType=3d&pixelDensity=3&positionX=0&positionY=0&positionZ=5&range=enabled&rangeEnd=40&rangeStart=0&reflection=1&rotationX=0&rotationY=0&rotationZ=0&shader=defaults&type=waterPlane&uAmplitude=0&uDensity=2.8&uFrequency=5.5&uSpeed=0.3&uStrength=3.4&uTime=0.2&wireframe=false'
|
||||
}
|
||||
/>
|
||||
</ShaderGradientCanvas>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShaderBackground;
|
||||
@ -10,6 +10,9 @@
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-spring/three": "^10.0.1",
|
||||
"@react-three/fiber": "^9.2.0",
|
||||
"@shadergradient/react": "^2.1.2",
|
||||
"@stripe/react-stripe-js": "^3.4.0",
|
||||
"@stripe/stripe-js": "^6.0.0",
|
||||
"@tanstack/react-query": "^5.63.0",
|
||||
@ -32,6 +35,7 @@
|
||||
"react-dom": "^19.0.0",
|
||||
"react-turnstile": "^1.1.4",
|
||||
"rtl-detect": "^1.1.2",
|
||||
"three": "^0.178.0",
|
||||
"ua-parser-js": "^2.0.0",
|
||||
"universal-cookie": "^7.2.2",
|
||||
"zustand": "^5.0.3"
|
||||
|
||||
BIN
apps/user/public/video.mp4
Normal file
BIN
apps/user/public/video.mp4
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user