feat: 多语言
parent
5aa5435b90
commit
a80d3c7935
|
@ -1,6 +0,0 @@
|
|||
module.exports = {
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'zh-CN'],
|
||||
},
|
||||
}
|
|
@ -1,9 +1,6 @@
|
|||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'zh-CN'],
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
|
|
@ -12,12 +12,10 @@
|
|||
"@emotion/react": "^11.13.3",
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@mui/material": "^6.1.3",
|
||||
"i18next": "^23.15.2",
|
||||
"next": "14.2.15",
|
||||
"next-i18next": "^15.3.1",
|
||||
"next-intl": "^3.21.1",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-i18next": "^15.0.3"
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20",
|
||||
|
|
|
@ -20,6 +20,9 @@ importers:
|
|||
next:
|
||||
specifier: 14.2.15
|
||||
version: 14.2.15(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
next-intl:
|
||||
specifier: ^3.21.1
|
||||
version: 3.21.1(next@14.2.15(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||
react:
|
||||
specifier: ^18
|
||||
version: 18.3.1
|
||||
|
@ -175,6 +178,21 @@ packages:
|
|||
resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
||||
'@formatjs/ecma402-abstract@2.2.0':
|
||||
resolution: {integrity: sha512-IpM+ev1E4QLtstniOE29W1rqH9eTdx5hQdNL8pzrflMj/gogfaoONZqL83LUeQScHAvyMbpqP5C9MzNf+fFwhQ==}
|
||||
|
||||
'@formatjs/fast-memoize@2.2.1':
|
||||
resolution: {integrity: sha512-XS2RcOSyWxmUB7BUjj3mlPH0exsUzlf6QfhhijgI941WaJhVxXQ6mEWkdUFIdnKi3TuTYxRdelsgv3mjieIGIA==}
|
||||
|
||||
'@formatjs/icu-messageformat-parser@2.7.10':
|
||||
resolution: {integrity: sha512-wlQfqCZ7PURkUNL2+8VTEFavPovtADU/isSKLFvDbdFmV7QPZIYqFMkhklaDYgMyLSBJa/h2MVQ2aFvoEJhxgg==}
|
||||
|
||||
'@formatjs/icu-skeleton-parser@1.8.4':
|
||||
resolution: {integrity: sha512-LMQ1+Wk1QSzU4zpd5aSu7+w5oeYhupRwZnMQckLPRYhSjf2/8JWQ882BauY9NyHxs5igpuQIXZDgfkaH3PoATg==}
|
||||
|
||||
'@formatjs/intl-localematcher@0.5.5':
|
||||
resolution: {integrity: sha512-t5tOGMgZ/i5+ALl2/offNqAQq/lfUnKLEw0mXQI4N4bqpedhrSE+fyKLpwnd22sK0dif6AV+ufQcTsKShB9J1g==}
|
||||
|
||||
'@humanwhocodes/config-array@0.13.0':
|
||||
resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
|
@ -1066,6 +1084,9 @@ packages:
|
|||
resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
intl-messageformat@10.7.0:
|
||||
resolution: {integrity: sha512-2P06M9jFTqJnEQzE072VGPjbAx6ZG1YysgopAwc8ui0ajSjtwX1MeQ6bXFXIzKcNENJTizKkcJIcZ0zlpl1zSg==}
|
||||
|
||||
is-arguments@1.1.1:
|
||||
resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
@ -1313,6 +1334,16 @@ packages:
|
|||
natural-compare@1.4.0:
|
||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||
|
||||
negotiator@0.6.3:
|
||||
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
next-intl@3.21.1:
|
||||
resolution: {integrity: sha512-hQm4Wgq5i1lfOHAWmXBVl5d2/XAeddcjsrUmjotXEESzPSvW5j2t0Pr8AV8WorTILgqU748aXuenBhz5P78tdw==}
|
||||
peerDependencies:
|
||||
next: ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
|
||||
next@14.2.15:
|
||||
resolution: {integrity: sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==}
|
||||
engines: {node: '>=18.17.0'}
|
||||
|
@ -1786,6 +1817,11 @@ packages:
|
|||
uri-js@4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
|
||||
use-intl@3.21.1:
|
||||
resolution: {integrity: sha512-52kYgcydYkG9SX0ZZGt7W6WD2Va01hwe15bDgkXuaTdSxrF9fDu6hHTV5DxIuSmSSf/FEcBo/nodpw3ZhY31Lw==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
|
||||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
|
@ -2009,6 +2045,31 @@ snapshots:
|
|||
|
||||
'@eslint/js@8.57.1': {}
|
||||
|
||||
'@formatjs/ecma402-abstract@2.2.0':
|
||||
dependencies:
|
||||
'@formatjs/fast-memoize': 2.2.1
|
||||
'@formatjs/intl-localematcher': 0.5.5
|
||||
tslib: 2.7.0
|
||||
|
||||
'@formatjs/fast-memoize@2.2.1':
|
||||
dependencies:
|
||||
tslib: 2.7.0
|
||||
|
||||
'@formatjs/icu-messageformat-parser@2.7.10':
|
||||
dependencies:
|
||||
'@formatjs/ecma402-abstract': 2.2.0
|
||||
'@formatjs/icu-skeleton-parser': 1.8.4
|
||||
tslib: 2.7.0
|
||||
|
||||
'@formatjs/icu-skeleton-parser@1.8.4':
|
||||
dependencies:
|
||||
'@formatjs/ecma402-abstract': 2.2.0
|
||||
tslib: 2.7.0
|
||||
|
||||
'@formatjs/intl-localematcher@0.5.5':
|
||||
dependencies:
|
||||
tslib: 2.7.0
|
||||
|
||||
'@humanwhocodes/config-array@0.13.0':
|
||||
dependencies:
|
||||
'@humanwhocodes/object-schema': 2.0.3
|
||||
|
@ -3103,6 +3164,13 @@ snapshots:
|
|||
hasown: 2.0.2
|
||||
side-channel: 1.0.6
|
||||
|
||||
intl-messageformat@10.7.0:
|
||||
dependencies:
|
||||
'@formatjs/ecma402-abstract': 2.2.0
|
||||
'@formatjs/fast-memoize': 2.2.1
|
||||
'@formatjs/icu-messageformat-parser': 2.7.10
|
||||
tslib: 2.7.0
|
||||
|
||||
is-arguments@1.1.1:
|
||||
dependencies:
|
||||
call-bind: 1.0.7
|
||||
|
@ -3329,6 +3397,16 @@ snapshots:
|
|||
|
||||
natural-compare@1.4.0: {}
|
||||
|
||||
negotiator@0.6.3: {}
|
||||
|
||||
next-intl@3.21.1(next@14.2.15(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
'@formatjs/intl-localematcher': 0.5.5
|
||||
negotiator: 0.6.3
|
||||
next: 14.2.15(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react: 18.3.1
|
||||
use-intl: 3.21.1(react@18.3.1)
|
||||
|
||||
next@14.2.15(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
'@next/env': 14.2.15
|
||||
|
@ -3861,6 +3939,12 @@ snapshots:
|
|||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
use-intl@3.21.1(react@18.3.1):
|
||||
dependencies:
|
||||
'@formatjs/fast-memoize': 2.2.1
|
||||
intl-messageformat: 10.7.0
|
||||
react: 18.3.1
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
which-boxed-primitive@1.0.2:
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
Binary file not shown.
After Width: | Height: | Size: 550 B |
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"lan": "Chinese"
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"lan": "简体中文"
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import Image from "next/image";
|
||||
|
||||
|
||||
export default function Form() {
|
||||
return (
|
||||
<div className="w-full flex justify-center items-center gap-[22px]">
|
||||
<input
|
||||
type="text"
|
||||
placeholder='姓名'
|
||||
className="bg-[#F2F6FF] w-[280px] h-[66px] rounded-[30px] box-border
|
||||
border-solid border-[2px] border-[#F2F6FF] hover:border-[#4676ee]
|
||||
outline:none focus:outline-none placeholder:text-[#B0B0B0] placeholder:text-[20px]
|
||||
pl-[20px] text-[20px] text-[#B0B0B0]
|
||||
"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
placeholder='电话/微信'
|
||||
className="bg-[#F2F6FF] w-[280px] h-[66px] rounded-[30px] box-border
|
||||
border-solid border-[2px] border-[#F2F6FF] hover:border-[#4676ee]
|
||||
outline:none focus:outline-none placeholder:text-[#B0B0B0] placeholder:text-[20px]
|
||||
pl-[20px] text-[20px] text-[#B0B0B0]
|
||||
"
|
||||
/>
|
||||
<div
|
||||
className="rounded-[30px] w-[167px] h-[53px] flex items-center justify-between pl-[39px] pr-[42px] cursor-pointer"
|
||||
style={{background: 'linear-gradient(155deg, #A4D5FF 55%, #82B2FF 99%)'}}
|
||||
>
|
||||
<div className="text-[#fff] text-[24px] font-semibold">提交</div>
|
||||
<Image
|
||||
src="/home/submit_icon.png"
|
||||
width={26}
|
||||
height={22}
|
||||
alt=""
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
import Image from "next/image";
|
||||
import { getDictionary } from '@/dictionaries';
|
||||
import Form from "./components/form";
|
||||
import Header from "@/app/components/header";
|
||||
import Footer from "@/app/components/footer";
|
||||
|
||||
type CaseType = {
|
||||
img: string
|
||||
}
|
||||
export type PropsType = {
|
||||
params: {
|
||||
lang: string;
|
||||
};
|
||||
}
|
||||
export default async function Home (props: PropsType) {
|
||||
const lang = props.params.lang;
|
||||
const dict = await getDictionary(lang);
|
||||
const caseList: CaseType[] = [
|
||||
{ img: '/home/case_1.png' },
|
||||
{ img: '/home/case_2.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_1.png' },
|
||||
{ img: '/home/case_2.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_1.png' },
|
||||
{ img: '/home/case_2.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_1.png' },
|
||||
{ img: '/home/case_2.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
]
|
||||
return <>
|
||||
<div>
|
||||
<Header dict={dict} lang={lang} />
|
||||
<section id="home">
|
||||
<div className="w-full h-[770px] bg-[url('/home/img_header.png')] bg-right bg-no-repeat pt-[279px] pl-[172px]">
|
||||
<div
|
||||
className="text-[46px] leading-[62px] w-[368px] text-center"
|
||||
>
|
||||
<div
|
||||
className="font-black"
|
||||
style={{
|
||||
'background': 'linear-gradient(106deg, #8EC2EA 0%, #4174ED 93%)',
|
||||
'backgroundClip': 'text',
|
||||
'WebkitTextFillColor': 'transparent'
|
||||
}}>
|
||||
{dict.FocusingOnPlayableAds}
|
||||
</div>
|
||||
<div
|
||||
className="font-black"
|
||||
style={{
|
||||
'background': 'linear-gradient(106deg, #8EC2EA 0%, #4174ED 93%)',
|
||||
'backgroundClip': 'text',
|
||||
'WebkitTextFillColor': 'transparent'
|
||||
}}>
|
||||
{dict.goOverseas}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div className="w-full h-[428px] relative">
|
||||
<Image
|
||||
src="/home/img_bg2.png"
|
||||
width={745}
|
||||
height={428}
|
||||
alt=""
|
||||
|
||||
/>
|
||||
<div className="absolute w-[770px] text-[32px] top-[184px] right-[115px] text-[#333333] text-right font-semibold">
|
||||
{ dict.customized }
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-[403px] relative">
|
||||
<Image
|
||||
className="absolute right-[0]"
|
||||
src="/home/img_AB.png"
|
||||
width={787}
|
||||
height={403}
|
||||
alt=""
|
||||
|
||||
/>
|
||||
<div className="absolute w-[662px] text-[32px] top-[160px] left-[165px] text-[#333333] text-left font-semibold">
|
||||
{ dict.ABTesting}
|
||||
</div>
|
||||
<div className="absolute w-[680px] text-[32px] top-[204px] left-[165px] text-[#333333] text-left font-semibold">
|
||||
{ dict.iterateGameplay }
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-[392px] relative">
|
||||
<Image
|
||||
className="absolute"
|
||||
src="/home/img_mutilan.png"
|
||||
width={698}
|
||||
height={392}
|
||||
alt=""
|
||||
|
||||
/>
|
||||
<div className="absolute w-[520px] text-[32px] top-[197px] right-[115px] text-[#333333] text-right font-semibold">
|
||||
{ dict.multiLanguage }
|
||||
</div>
|
||||
<div className="absolute w-[510px] text-[32px] top-[242px] right-[115px] text-[#333333] text-right font-semibold">
|
||||
{ dict.breakingGeographical }
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-[317px] relative mt-[83px]">
|
||||
<Image
|
||||
className="absolute right-[0]"
|
||||
src="/home/img_Omnichannel.png"
|
||||
width={742}
|
||||
height={317}
|
||||
alt=""
|
||||
|
||||
/>
|
||||
<div className="absolute w-[680px] text-[32px] top-[124px] left-[165px] text-[#333333] text-left font-semibold">
|
||||
{ dict.allChannel }
|
||||
</div>
|
||||
<div className="absolute w-[680px] text-[32px] top-[169px] left-[165px] text-[#333333] text-left font-semibold">
|
||||
{ dict.expandInfluence }
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-[317px] relative mt-[83px]">
|
||||
<Image
|
||||
className="absolute"
|
||||
src="/home/img_Omnichannel.png"
|
||||
width={742}
|
||||
height={317}
|
||||
alt=""
|
||||
|
||||
/>
|
||||
<div className="absolute w-[610px] text-[32px] top-[100px] right-[115px] text-[#333333] text-right font-semibold">
|
||||
{ dict.lightweightDeployment }
|
||||
</div>
|
||||
<div className="absolute w-[600px] text-[32px] top-[145px] right-[115px] text-[#333333] text-right font-semibold">
|
||||
{ dict.simplifyProcess }
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section id="service">
|
||||
<div className="w-full flex flex-col justify-center items-center mt-[98px]">
|
||||
<div
|
||||
className="leading-[34px] text-[36px] font-black w-[150px] mb-[11px]"
|
||||
style={{
|
||||
background: 'linear-gradient(90deg, #93BBE6 0%, #4C76E4 100%)',
|
||||
backgroundClip: 'text',
|
||||
WebkitTextFillColor: 'transparent'
|
||||
}}
|
||||
>{ dict.caseGallery }</div>
|
||||
<div className="text-[19px] text-[#59676C]">{ dict.clickNow }</div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="case">
|
||||
<div className="w-full px-[40px] flex flex-wrap justify-center gap-[50px] mt-[34px] mb-[83px]">
|
||||
{
|
||||
caseList.map((item: CaseType, index: number) => {
|
||||
return <div key={'key'+index} className="cursor-pointer">
|
||||
<Image
|
||||
className="hover:scale-[1.17] hover:shadow-[0px_0px_20px_8px_#0988FF] rounded-[60px]
|
||||
transition ease-in-out duration-300"
|
||||
src={item.img}
|
||||
width={300}
|
||||
height={300}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
})
|
||||
}
|
||||
<div className="w-[300px] h-[300px] flex flex-col justify-center items-center text-[30px] text-[#3d3d3d] cursor-pointer">
|
||||
<div>{ dict.seeMore }</div>
|
||||
<div>{ dict.contactUs! }</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="contact">
|
||||
<div className="w-full flex flex-col justify-center items-center mt-[98px] mb-[59px]">
|
||||
<div
|
||||
className="leading-[34px] text-[36px] font-black w-[150px] mb-[11px]"
|
||||
style={{
|
||||
background: 'linear-gradient(90deg, #93BBE6 0%, #4C76E4 100%)',
|
||||
backgroundClip: 'text',
|
||||
WebkitTextFillColor: 'transparent'
|
||||
}}
|
||||
>{ dict.contactUs }</div>
|
||||
</div>
|
||||
<div className="w-full mb-[60px]">
|
||||
<Form />
|
||||
</div>
|
||||
<div className="w-full flex justify-center text-[19px] text-[#59676C] mb-[99px]">
|
||||
商务合作/求职:info@soyootech.com
|
||||
</div>
|
||||
</section>
|
||||
<div>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import Image from "next/image"
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer>
|
||||
<div className="flex items-start justify-between w-full px-[304px]">
|
||||
<div className=" w-[166px] flex flex-col items-center mb-[15px]">
|
||||
<Image
|
||||
className="mb-[16px]"
|
||||
src="/home/qrcode.png"
|
||||
width={151}
|
||||
height={151}
|
||||
alt=""
|
||||
/>
|
||||
<div className="text-[#888888] text-[15px]">添加微信,享受专属服务</div>
|
||||
</div>
|
||||
<div >
|
||||
<div className="text-[#AFB2B9] text-[17px] font-medium mb-[45px]">邮件联系</div>
|
||||
<div className="text-[#333333] text-[15px] ">info@soyootech.com</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-[#AFB2B9] text-[17px] font-medium mb-[45px]">帮助与支持</div>
|
||||
<div className="text-[#333333] text-[15px] mb-[23px]">产品中心</div>
|
||||
<div className="text-[#333333] text-[15px] ">产品中心</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-[#AFB2B9] text-[17px] font-medium mb-[45px]">法律与协议</div>
|
||||
<div className="text-[#333333] text-[15px] mb-[23px]">隐私条款</div>
|
||||
<div className="text-[#333333] text-[15px] ">用户协议</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-[15px] text-[#888888] text-center">
|
||||
Copyright © 2020-2024 All Rights Reserved.
|
||||
</div>
|
||||
<div className="text-[15px] text-[#888888] text-center mb-[20px]">
|
||||
京ICP备20028159号 版权所有
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
|
@ -1,24 +1,28 @@
|
|||
'use client'
|
||||
import Image from "next/image";
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
|
||||
type NavType = {
|
||||
name: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
function SplitButton() {
|
||||
// const { t } = useTranslation();
|
||||
const lagn = '简体中文'
|
||||
function SplitButton(props: {dict: Record<string, string>, lang: string}) {
|
||||
const { dict, lang } = props
|
||||
const [show, setShow] = useState(false)
|
||||
return <>
|
||||
<div className="relative">
|
||||
<div className="flex items-center w-[129px] h-[28px] bg-[#EEF1F6]
|
||||
border-[1px] border-[#eeeeee] rounded-[3px] px-[10px] mt-[18px]">
|
||||
border-[1px] border-[#eeeeee] rounded-[3px] px-[10px] mt-[18px] cursor-pointer"
|
||||
onClick={() => setShow(!show)}>
|
||||
<Image
|
||||
src="/common/earth.png"
|
||||
width={16.5}
|
||||
height={16.5}
|
||||
alt="logo"
|
||||
/>
|
||||
<div className="flex-1 text-[14px] text-[#333333] mx-[9px]">{ lagn }</div>
|
||||
<div className="flex-1 text-[14px] text-[#333333] mx-[9px]">{ dict?.lang }</div>
|
||||
<Image
|
||||
src="/common/arrow.png"
|
||||
width={10}
|
||||
|
@ -26,28 +30,39 @@ function SplitButton() {
|
|||
alt="logo"
|
||||
/>
|
||||
</div>
|
||||
{
|
||||
show && (
|
||||
<Link href={lang === 'en' ? '/zh/home' : '/en/home'}>
|
||||
<div className="absolute top-[30px] w-[129px] h-[28px] bg-[#EEF1F6] text-center">
|
||||
<div>{dict?.lang1}</div>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
export default function Header() {
|
||||
export default function Header(props: {dict: Record<string, string>, lang: string}) {
|
||||
const { dict, lang } = props
|
||||
const [activeTab, setActiveTab] = useState(dict.home)
|
||||
const navList: NavType[] = [
|
||||
{
|
||||
name: "首页",
|
||||
href: "/"
|
||||
name: dict.home,
|
||||
href: "#home"
|
||||
},
|
||||
{
|
||||
name: "服务内容",
|
||||
href: "/service"
|
||||
name: dict.services,
|
||||
href: "#service"
|
||||
},
|
||||
{
|
||||
name: "案例中心",
|
||||
href: "/case"
|
||||
name: dict.caseGallery,
|
||||
href: "#case"
|
||||
},
|
||||
{
|
||||
name: "联系我们",
|
||||
href: "/contact "
|
||||
name: dict.contactUs,
|
||||
href: "#contact "
|
||||
},
|
||||
]
|
||||
const pathname = '首页'
|
||||
return (<>
|
||||
<div className={"flex items-center px-[20px] h-[80px]"}>
|
||||
<Image
|
||||
|
@ -59,19 +74,21 @@ export default function Header() {
|
|||
<div className={"flex flex-1 items-end h-[80px] mx-[13px]"}>
|
||||
{
|
||||
navList.map((item: NavType) => (
|
||||
<div key={item.name} className="text-center cursor-pointer">
|
||||
<div className="my-[10px] w-[144px] text-[18px]">{ item.name }</div>
|
||||
{
|
||||
pathname === item.name ?
|
||||
<Image src="/common/tab_checked.png" width={144} height={8} alt="" /> :
|
||||
<div className="h-[8px]"></div>
|
||||
}
|
||||
</div>
|
||||
<Link href={item.href} key={item.name}>
|
||||
<div className="text-center cursor-pointer" onClick={() => setActiveTab(item.name)}>
|
||||
<div className="my-[10px] w-[144px] text-[18px]">{ item.name }</div>
|
||||
{
|
||||
activeTab === item.name ?
|
||||
<Image src="/common/tab_checked.png" width={144} height={8} alt="" /> :
|
||||
<div className="h-[8px]"></div>
|
||||
}
|
||||
</div>
|
||||
</Link>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<div className="">
|
||||
<SplitButton />
|
||||
<SplitButton dict={dict} lang={lang} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
@ -1,177 +0,0 @@
|
|||
import Image from "next/image";
|
||||
|
||||
type CaseType = {
|
||||
img: string
|
||||
}
|
||||
export default function Home () {
|
||||
const caseList: CaseType[] = [
|
||||
{ img: '/home/case_1.png' },
|
||||
{ img: '/home/case_2.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_1.png' },
|
||||
{ img: '/home/case_2.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_1.png' },
|
||||
{ img: '/home/case_2.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
{ img: '/home/case_1.png' },
|
||||
{ img: '/home/case_2.png' },
|
||||
{ img: '/home/case_3.png' },
|
||||
]
|
||||
return <>
|
||||
<div>
|
||||
<div className="w-full h-[770px] bg-[url('/home/img_header.png')] bg-right bg-no-repeat pt-[279px] pl-[172px]">
|
||||
<div
|
||||
className="text-[46px] leading-[62px] w-[368px] text-center"
|
||||
>
|
||||
<div
|
||||
className="font-black"
|
||||
style={{
|
||||
'background': 'linear-gradient(106deg, #8EC2EA 0%, #4174ED 93%)',
|
||||
'backgroundClip': 'text',
|
||||
'WebkitTextFillColor': 'transparent'
|
||||
}}>
|
||||
聚焦试玩广告
|
||||
</div>
|
||||
<div
|
||||
className="font-black"
|
||||
style={{
|
||||
'background': 'linear-gradient(106deg, #8EC2EA 0%, #4174ED 93%)',
|
||||
'backgroundClip': 'text',
|
||||
'WebkitTextFillColor': 'transparent'
|
||||
}}>
|
||||
全面助力游戏出海
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-[428px] relative">
|
||||
<Image
|
||||
src="/home/img_bg2.png"
|
||||
width={745}
|
||||
height={428}
|
||||
alt=""
|
||||
|
||||
/>
|
||||
<div className="absolute w-[770px] text-[32px] top-[184px] right-[115px] text-[#333333] text-right font-semibold">
|
||||
100%内容定制,根据项目需求量身打造试玩广告方案
|
||||
确保完全符合产品形象与市场定位
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-[403px] relative">
|
||||
<Image
|
||||
className="absolute right-[0]"
|
||||
src="/home/img_AB.png"
|
||||
width={787}
|
||||
height={403}
|
||||
alt=""
|
||||
|
||||
/>
|
||||
<div className="absolute w-[662px] text-[32px] top-[160px] left-[165px] text-[#333333] text-left font-semibold">
|
||||
支持 A/B 测试,通过优化素材内容
|
||||
</div>
|
||||
<div className="absolute w-[680px] text-[32px] top-[204px] left-[165px] text-[#333333] text-left font-semibold">
|
||||
迭代游戏玩法,全面提升提升转化率与用户体验
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-[392px] relative">
|
||||
<Image
|
||||
className="absolute"
|
||||
src="/home/img_mutilan.png"
|
||||
width={698}
|
||||
height={392}
|
||||
alt=""
|
||||
|
||||
/>
|
||||
<div className="absolute w-[520px] text-[32px] top-[197px] right-[115px] text-[#333333] text-right font-semibold">
|
||||
多语言支持,覆盖全球多种语言版本
|
||||
</div>
|
||||
<div className="absolute w-[510px] text-[32px] top-[242px] right-[115px] text-[#333333] text-right font-semibold">
|
||||
打破地域限制,实现国际化布局
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-[317px] relative mt-[83px]">
|
||||
<Image
|
||||
className="absolute right-[0]"
|
||||
src="/home/img_Omnichannel.png"
|
||||
width={742}
|
||||
height={317}
|
||||
alt=""
|
||||
|
||||
/>
|
||||
<div className="absolute w-[680px] text-[32px] top-[124px] left-[165px] text-[#333333] text-left font-semibold">
|
||||
全渠道适配,接入各大主流分发渠道
|
||||
</div>
|
||||
<div className="absolute w-[680px] text-[32px] top-[169px] left-[165px] text-[#333333] text-left font-semibold">
|
||||
让您的产品触达更多潜在用户,扩大品牌影响力
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-[317px] relative mt-[83px]">
|
||||
<Image
|
||||
className="absolute"
|
||||
src="/home/img_Omnichannel.png"
|
||||
width={742}
|
||||
height={317}
|
||||
alt=""
|
||||
|
||||
/>
|
||||
<div className="absolute w-[610px] text-[32px] top-[100px] right-[115px] text-[#333333] text-right font-semibold">
|
||||
轻量化部署,提供便捷的产品效果预览方案
|
||||
</div>
|
||||
<div className="absolute w-[600px] text-[32px] top-[145px] right-[115px] text-[#333333] text-right font-semibold">
|
||||
简化用户决策流程,方便追踪各阶段进度
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full flex flex-col justify-center items-center mt-[98px]">
|
||||
<div
|
||||
className="leading-[34px] text-[36px] font-black w-[150px] mb-[11px]"
|
||||
style={{
|
||||
background: 'linear-gradient(90deg, #93BBE6 0%, #4C76E4 100%)',
|
||||
backgroundClip: 'text',
|
||||
WebkitTextFillColor: 'transparent'
|
||||
}}
|
||||
>案例中心</div>
|
||||
<div className="text-[19px] text-[#59676C]">点击图标 立即体验</div>
|
||||
</div>
|
||||
<div className="w-full px-[40px] flex flex-wrap justify-center gap-[50px] mt-[34px] mb-[83px]">
|
||||
{
|
||||
caseList.map((item: CaseType) => {
|
||||
return <div key={item.img} className="cursor-pointer">
|
||||
<Image
|
||||
className="hover:scale-[1.17] hover:shadow-[0px_0px_20px_8px_#0988FF] rounded-[60px]
|
||||
transition ease-in-out duration-300"
|
||||
src={item.img}
|
||||
width={300}
|
||||
height={300}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
})
|
||||
}
|
||||
<div className="w-[300px] h-[300px] flex flex-col justify-center items-center text-[30px] text-[#3d3d3d] cursor-pointer">
|
||||
<div>想看更多?</div>
|
||||
<div>联系我们!</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div className="w-full flex flex-col justify-center items-center mt-[98px] mb-[59px]">
|
||||
<div
|
||||
className="leading-[34px] text-[36px] font-black w-[150px] mb-[11px]"
|
||||
style={{
|
||||
background: 'linear-gradient(90deg, #93BBE6 0%, #4C76E4 100%)',
|
||||
backgroundClip: 'text',
|
||||
WebkitTextFillColor: 'transparent'
|
||||
}}
|
||||
>联系我们</div>
|
||||
</div>
|
||||
<div className="w-full flex items-center justify-center">
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
|
@ -1,10 +1,7 @@
|
|||
import type { Metadata } from "next";
|
||||
import localFont from "next/font/local";
|
||||
import "./globals.css";
|
||||
import { appWithTranslation } from 'next-i18next'
|
||||
import Header from "./components/header";
|
||||
import { ReactElement, ReactNode } from "react";
|
||||
import { AppProps } from "next/app";
|
||||
|
||||
const geistSans = localFont({
|
||||
src: "./fonts/GeistVF.woff",
|
||||
|
@ -22,20 +19,15 @@ export const metadata: Metadata = {
|
|||
description: "Generated by create next app",
|
||||
};
|
||||
|
||||
interface LayoutProps extends AppProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
function RootLayout({ children, ...appProps }: LayoutProps): ReactElement {
|
||||
function RootLayout({ children }:{ children: ReactNode } ): ReactElement {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
<Header />
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
export default RootLayout
|
||||
// export default appWithTranslation(RootLayout)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"lang": "English",
|
||||
"lang1": "简体中文",
|
||||
"home": "Home",
|
||||
"services": "Services",
|
||||
"caseGallery": "Case gallery",
|
||||
"contactUs": "Contact Us",
|
||||
"FocusingOnPlayableAds": "Focusing on playable ads",
|
||||
"goOverseas": "comprehensively assisting the game to go overseas",
|
||||
"customized": "100% customized , tailored to the needs of the project to create a playable ad Ensure full compliance with product image and market positioning",
|
||||
"ABTesting": "Support A/B testing, by optimizing the material content",
|
||||
"iterateGameplay": "Iterate gameplay to improve conversion rate and user experience",
|
||||
"multiLanguage": "Multi-language support, covering the global multi-language version",
|
||||
"breakingGeographical": "Breaking geographical restrictions and realizing internationalized layout",
|
||||
"allChannel": "All-channel adaptation, access to major mainstream distribution channels",
|
||||
"expandInfluence": "Let your products reach more potential users and expand your brand influence",
|
||||
"lightweightDeployment": "Lightweight deployment, providing convenient product effect preview solutions",
|
||||
"simplifyProcess": "Simplify the user decision-making process, easy to track the progress of each stage",
|
||||
"clickNow": "Click on the icon to experience it now",
|
||||
"seeMore": "Want to see more?",
|
||||
"contactUs!": "Contact us!"
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
const dictionaries = {
|
||||
en: () => import('./en.json').then((module) => module.default),
|
||||
zh: () => import('./zh.json').then((module) => module.default),
|
||||
} as Record<string, () => Promise<Record<string, string>>>;
|
||||
|
||||
export const getDictionary = async (locale: string) => dictionaries[locale]();
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"lang": "简体中文",
|
||||
"lang1": "English",
|
||||
"home": "首页",
|
||||
"services": "服务内容",
|
||||
"caseGallery": "案例中心",
|
||||
"contactUs": "联系我们",
|
||||
"FocusingOnPlayableAds": "聚焦试玩广告",
|
||||
"goOverseas": "全面助力游戏出海",
|
||||
"customized": "100%内容定制,根据项目需求量身打造试玩广告方案 确保完全符合产品形象与市场定位",
|
||||
"ABTesting": "支持 A/B 测试,通过优化素材内容",
|
||||
"iterateGameplay": "迭代游戏玩法,全面提升提升转化率与用户体验",
|
||||
"multiLanguage": "多语言支持,覆盖全球多种语言版本",
|
||||
"breakingGeographical": "打破地域限制,实现国际化布局",
|
||||
"allChannel": "全渠道适配,接入各大主流分发渠道",
|
||||
"expandInfluence": "让您的产品触达更多潜在用户,扩大品牌影响力",
|
||||
"lightweightDeployment": "轻量化部署,提供便捷的产品效果预览方案",
|
||||
"simplifyProcess": "简化用户决策流程,方便追踪各阶段进度",
|
||||
"clickNow": "点击图标 立即体验",
|
||||
"seeMore": "想看更多?",
|
||||
"contactUs!": "联系我们!"
|
||||
}
|
Loading…
Reference in New Issue