添加i18n
This commit is contained in:
parent
ebe385a624
commit
cd40c603a1
@ -1,8 +1,11 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Playfair_Display, Noto_Serif_SC } from "next/font/google";
|
import { Playfair_Display, Noto_Serif_SC } from "next/font/google";
|
||||||
import "./globals.css";
|
import "../globals.css";
|
||||||
import Navbar from "@/components/Navbar";
|
import Navbar from "@/components/Navbar";
|
||||||
import Footer from "@/components/Footer";
|
import Footer from "@/components/Footer";
|
||||||
|
import {NextIntlClientProvider} from 'next-intl';
|
||||||
|
import {getMessages} from 'next-intl/server';
|
||||||
|
import {notFound} from 'next/navigation';
|
||||||
|
|
||||||
const playfairDisplay = Playfair_Display({
|
const playfairDisplay = Playfair_Display({
|
||||||
variable: "--font-serif",
|
variable: "--font-serif",
|
||||||
@ -22,21 +25,31 @@ export const metadata: Metadata = {
|
|||||||
description: "南京市肥鹅信息技术有限公司致力于为企业提供卓越的数字化解决方案,以创新技术驱动商业价值。",
|
description: "南京市肥鹅信息技术有限公司致力于为企业提供卓越的数字化解决方案,以创新技术驱动商业价值。",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default async function LocaleLayout({
|
||||||
children,
|
children,
|
||||||
}: Readonly<{
|
params
|
||||||
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}>) {
|
params: Promise<{locale: string}>;
|
||||||
|
}) {
|
||||||
|
const { locale } = await params;
|
||||||
|
if (!['en', 'zh', 'ja'].includes(locale)) {
|
||||||
|
notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = await getMessages();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="zh-CN">
|
<html lang={locale}>
|
||||||
<body
|
<body
|
||||||
className={`${playfairDisplay.variable} ${notoSerifSC.variable} antialiased selection:bg-feie-gold selection:text-white`}
|
className={`${playfairDisplay.variable} ${notoSerifSC.variable} antialiased selection:bg-feie-gold selection:text-white`}
|
||||||
>
|
>
|
||||||
<Navbar />
|
<NextIntlClientProvider messages={messages}>
|
||||||
{children}
|
<Navbar />
|
||||||
<Footer />
|
{children}
|
||||||
|
<Footer />
|
||||||
|
</NextIntlClientProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
87
bun.lock
87
bun.lock
@ -9,6 +9,7 @@
|
|||||||
"@react-three/fiber": "^9.4.2",
|
"@react-three/fiber": "^9.4.2",
|
||||||
"lucide-react": "^0.559.0",
|
"lucide-react": "^0.559.0",
|
||||||
"next": "16.0.8",
|
"next": "16.0.8",
|
||||||
|
"next-intl": "^4.6.1",
|
||||||
"prisma": "^6.0.0",
|
"prisma": "^6.0.0",
|
||||||
"react": "19.2.1",
|
"react": "19.2.1",
|
||||||
"react-dom": "19.2.1",
|
"react-dom": "19.2.1",
|
||||||
@ -90,6 +91,16 @@
|
|||||||
|
|
||||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
|
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
|
||||||
|
|
||||||
|
"@formatjs/ecma402-abstract": ["@formatjs/ecma402-abstract@2.3.6", "", { "dependencies": { "@formatjs/fast-memoize": "2.2.7", "@formatjs/intl-localematcher": "0.6.2", "decimal.js": "^10.4.3", "tslib": "^2.8.0" } }, "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw=="],
|
||||||
|
|
||||||
|
"@formatjs/fast-memoize": ["@formatjs/fast-memoize@2.2.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ=="],
|
||||||
|
|
||||||
|
"@formatjs/icu-messageformat-parser": ["@formatjs/icu-messageformat-parser@2.11.4", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "@formatjs/icu-skeleton-parser": "1.8.16", "tslib": "^2.8.0" } }, "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw=="],
|
||||||
|
|
||||||
|
"@formatjs/icu-skeleton-parser": ["@formatjs/icu-skeleton-parser@1.8.16", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "tslib": "^2.8.0" } }, "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ=="],
|
||||||
|
|
||||||
|
"@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.5.10", "", { "dependencies": { "tslib": "2" } }, "sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q=="],
|
||||||
|
|
||||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||||
|
|
||||||
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
||||||
@ -192,6 +203,34 @@
|
|||||||
|
|
||||||
"@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="],
|
"@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="],
|
||||||
|
|
||||||
|
"@parcel/watcher": ["@parcel/watcher@2.5.1", "", { "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", "micromatch": "^4.0.5", "node-addon-api": "^7.0.0" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.1", "@parcel/watcher-darwin-arm64": "2.5.1", "@parcel/watcher-darwin-x64": "2.5.1", "@parcel/watcher-freebsd-x64": "2.5.1", "@parcel/watcher-linux-arm-glibc": "2.5.1", "@parcel/watcher-linux-arm-musl": "2.5.1", "@parcel/watcher-linux-arm64-glibc": "2.5.1", "@parcel/watcher-linux-arm64-musl": "2.5.1", "@parcel/watcher-linux-x64-glibc": "2.5.1", "@parcel/watcher-linux-x64-musl": "2.5.1", "@parcel/watcher-win32-arm64": "2.5.1", "@parcel/watcher-win32-ia32": "2.5.1", "@parcel/watcher-win32-x64": "2.5.1" } }, "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.5.1", "", { "os": "android", "cpu": "arm64" }, "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-darwin-arm64": ["@parcel/watcher-darwin-arm64@2.5.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-darwin-x64": ["@parcel/watcher-darwin-x64@2.5.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-freebsd-x64": ["@parcel/watcher-freebsd-x64@2.5.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-linux-arm-glibc": ["@parcel/watcher-linux-arm-glibc@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-linux-arm-musl": ["@parcel/watcher-linux-arm-musl@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-linux-arm64-glibc": ["@parcel/watcher-linux-arm64-glibc@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-linux-arm64-musl": ["@parcel/watcher-linux-arm64-musl@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-linux-x64-glibc": ["@parcel/watcher-linux-x64-glibc@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-linux-x64-musl": ["@parcel/watcher-linux-x64-musl@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-win32-arm64": ["@parcel/watcher-win32-arm64@2.5.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-win32-ia32": ["@parcel/watcher-win32-ia32@2.5.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ=="],
|
||||||
|
|
||||||
|
"@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="],
|
||||||
|
|
||||||
"@prisma/client": ["@prisma/client@6.19.1", "", { "peerDependencies": { "prisma": "*", "typescript": ">=5.1.0" }, "optionalPeers": ["prisma", "typescript"] }, "sha512-4SXj4Oo6HyQkLUWT8Ke5R0PTAfVOKip5Roo+6+b2EDTkFg5be0FnBWiuRJc0BC0sRQIWGMLKW1XguhVfW/z3/A=="],
|
"@prisma/client": ["@prisma/client@6.19.1", "", { "peerDependencies": { "prisma": "*", "typescript": ">=5.1.0" }, "optionalPeers": ["prisma", "typescript"] }, "sha512-4SXj4Oo6HyQkLUWT8Ke5R0PTAfVOKip5Roo+6+b2EDTkFg5be0FnBWiuRJc0BC0sRQIWGMLKW1XguhVfW/z3/A=="],
|
||||||
|
|
||||||
"@prisma/config": ["@prisma/config@6.19.1", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.18.4", "empathic": "2.0.0" } }, "sha512-bUL/aYkGXLwxVGhJmQMtslLT7KPEfUqmRa919fKI4wQFX4bIFUKiY8Jmio/2waAjjPYrtuDHa7EsNCnJTXxiOw=="],
|
"@prisma/config": ["@prisma/config@6.19.1", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.18.4", "empathic": "2.0.0" } }, "sha512-bUL/aYkGXLwxVGhJmQMtslLT7KPEfUqmRa919fKI4wQFX4bIFUKiY8Jmio/2waAjjPYrtuDHa7EsNCnJTXxiOw=="],
|
||||||
@ -212,10 +251,38 @@
|
|||||||
|
|
||||||
"@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
|
"@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
|
||||||
|
|
||||||
|
"@schummar/icu-type-parser": ["@schummar/icu-type-parser@1.21.5", "", {}, "sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw=="],
|
||||||
|
|
||||||
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
|
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
|
||||||
|
|
||||||
|
"@swc/core": ["@swc/core@1.15.6", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.6", "@swc/core-darwin-x64": "1.15.6", "@swc/core-linux-arm-gnueabihf": "1.15.6", "@swc/core-linux-arm64-gnu": "1.15.6", "@swc/core-linux-arm64-musl": "1.15.6", "@swc/core-linux-x64-gnu": "1.15.6", "@swc/core-linux-x64-musl": "1.15.6", "@swc/core-win32-arm64-msvc": "1.15.6", "@swc/core-win32-ia32-msvc": "1.15.6", "@swc/core-win32-x64-msvc": "1.15.6" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-BpSCKSwE5DG4N4Um+ZZwvJzJ/4iyMVlzvhJQoR0wJSgccca9ES3+P/7SbPxTM/jtV9vE1llfLPphw+Y+MFhnZg=="],
|
||||||
|
|
||||||
|
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-8pv6W49H70/yxNAC0k+W/Ko3nJW2Za706C1a8q6XhT4JtMLyaYqb+KeoBfIOR8F7qNhMdMa7wdOY5DLPk5cPSg=="],
|
||||||
|
|
||||||
|
"@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.15.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-v4mDTwA+UdYEHKvzefc3VX/4a7QrRnAFZzNwL33PcLNUJhWbBg6ptcQpBDz/xWOjU6m+pC0IQfzcs16rkAFCHg=="],
|
||||||
|
|
||||||
|
"@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.15.6", "", { "os": "linux", "cpu": "arm" }, "sha512-OT8rIl24/mu4bgDPJT6FVcW+WF3ep9VTau69FspjeycNIa0U0est1ooHxxJyTcO8Qdv0Jy11oXHwtxslZ6KXcw=="],
|
||||||
|
|
||||||
|
"@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.15.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-RKdeG9HBecClhtNJpGyZCYwvGrjzxDzQxGaVOQa44DbNSlVgupj6LnqNSt0RCTy8HEjra1WTD8dCJ9AR++dznQ=="],
|
||||||
|
|
||||||
|
"@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.15.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-+llo+x7fRyyYd5qGfeYyHgDoZy7M9jKQKmYjTKTJ1BMoydeBoujUWtw+L3tOHyrzKBWOdmVhwdyK+Rx8DeOaGQ=="],
|
||||||
|
|
||||||
|
"@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.15.6", "", { "os": "linux", "cpu": "x64" }, "sha512-1Ufezv5CtJOZaIzYUVMWPORNXgY1MuBrU6LPIeACkdpIaY2wiyfvTiMF57yZ3/c6RQQAY5ZmgV44wCe4dhUFew=="],
|
||||||
|
|
||||||
|
"@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.15.6", "", { "os": "linux", "cpu": "x64" }, "sha512-hKhR3mAvLvp1bmSrM68DyW+p8vKoFospxtffCTdC0fUR+Y6GEmSMTh+KcQ5vcGptnS2VB6QhZx3oLdzoBs0R6g=="],
|
||||||
|
|
||||||
|
"@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.15.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-s3AMvEOxS+H4l2+bEYwKkfDBf34u1/i+t7OgflFCaZ9wSDA3f693bptPO3m1/DrMTq1iEztEV2MPbjMmQqOmBw=="],
|
||||||
|
|
||||||
|
"@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.15.6", "", { "os": "win32", "cpu": "ia32" }, "sha512-oD9REGtkA/kU+d9xBa0jddrn4BEIfWA7Jx+O+KD1Dhvgd23aYVWwR98kote6DbC/5nAbt201JnW73SkYHBm4pQ=="],
|
||||||
|
|
||||||
|
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.15.6", "", { "os": "win32", "cpu": "x64" }, "sha512-oJ17Ouy1BkoUM5R8HJF8nX8IbiDror8tjW9x/PUoUVmtxxVb42vpXrS6xGDpH0mXx8K1wVVS6DOgH83uwKEBUQ=="],
|
||||||
|
|
||||||
|
"@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
|
||||||
|
|
||||||
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
||||||
|
|
||||||
|
"@swc/types": ["@swc/types@0.1.25", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g=="],
|
||||||
|
|
||||||
"@tailwindcss/node": ["@tailwindcss/node@4.1.17", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.17" } }, "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg=="],
|
"@tailwindcss/node": ["@tailwindcss/node@4.1.17", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.17" } }, "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.17", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.17", "@tailwindcss/oxide-darwin-arm64": "4.1.17", "@tailwindcss/oxide-darwin-x64": "4.1.17", "@tailwindcss/oxide-freebsd-x64": "4.1.17", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", "@tailwindcss/oxide-linux-x64-musl": "4.1.17", "@tailwindcss/oxide-wasm32-wasi": "4.1.17", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA=="],
|
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.17", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.17", "@tailwindcss/oxide-darwin-arm64": "4.1.17", "@tailwindcss/oxide-darwin-x64": "4.1.17", "@tailwindcss/oxide-freebsd-x64": "4.1.17", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", "@tailwindcss/oxide-linux-x64-musl": "4.1.17", "@tailwindcss/oxide-wasm32-wasi": "4.1.17", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA=="],
|
||||||
@ -442,6 +509,8 @@
|
|||||||
|
|
||||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||||
|
|
||||||
|
"decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="],
|
||||||
|
|
||||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||||
|
|
||||||
"deepmerge-ts": ["deepmerge-ts@7.1.5", "", {}, "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw=="],
|
"deepmerge-ts": ["deepmerge-ts@7.1.5", "", {}, "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw=="],
|
||||||
@ -622,6 +691,8 @@
|
|||||||
|
|
||||||
"internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
|
"internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
|
||||||
|
|
||||||
|
"intl-messageformat": ["intl-messageformat@10.7.18", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "@formatjs/fast-memoize": "2.2.7", "@formatjs/icu-messageformat-parser": "2.11.4", "tslib": "^2.8.0" } }, "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g=="],
|
||||||
|
|
||||||
"is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="],
|
"is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="],
|
||||||
|
|
||||||
"is-async-function": ["is-async-function@2.1.1", "", { "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ=="],
|
"is-async-function": ["is-async-function@2.1.1", "", { "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ=="],
|
||||||
@ -772,8 +843,16 @@
|
|||||||
|
|
||||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||||
|
|
||||||
|
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
||||||
|
|
||||||
"next": ["next@16.0.8", "", { "dependencies": { "@next/env": "16.0.8", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.0.8", "@next/swc-darwin-x64": "16.0.8", "@next/swc-linux-arm64-gnu": "16.0.8", "@next/swc-linux-arm64-musl": "16.0.8", "@next/swc-linux-x64-gnu": "16.0.8", "@next/swc-linux-x64-musl": "16.0.8", "@next/swc-win32-arm64-msvc": "16.0.8", "@next/swc-win32-x64-msvc": "16.0.8", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-LmcZzG04JuzNXi48s5P+TnJBsTGPJunViNKV/iE4uM6kstjTQsQhvsAv+xF6MJxU2Pr26tl15eVbp0jQnsv6/g=="],
|
"next": ["next@16.0.8", "", { "dependencies": { "@next/env": "16.0.8", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.0.8", "@next/swc-darwin-x64": "16.0.8", "@next/swc-linux-arm64-gnu": "16.0.8", "@next/swc-linux-arm64-musl": "16.0.8", "@next/swc-linux-x64-gnu": "16.0.8", "@next/swc-linux-x64-musl": "16.0.8", "@next/swc-win32-arm64-msvc": "16.0.8", "@next/swc-win32-x64-msvc": "16.0.8", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-LmcZzG04JuzNXi48s5P+TnJBsTGPJunViNKV/iE4uM6kstjTQsQhvsAv+xF6MJxU2Pr26tl15eVbp0jQnsv6/g=="],
|
||||||
|
|
||||||
|
"next-intl": ["next-intl@4.6.1", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.5.4", "@parcel/watcher": "^2.4.1", "@swc/core": "^1.15.2", "negotiator": "^1.0.0", "next-intl-swc-plugin-extractor": "^4.6.1", "po-parser": "^2.0.0", "use-intl": "^4.6.1" }, "peerDependencies": { "next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0", "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-KlWgWtKLBPUsTPgxqwyjws1wCMD2QKxLlVjeeGj53DC1JWfKmBShKOrhIP0NznZrRQ0GleeoDUeHSETmyyIFeA=="],
|
||||||
|
|
||||||
|
"next-intl-swc-plugin-extractor": ["next-intl-swc-plugin-extractor@4.6.1", "", {}, "sha512-+HHNeVERfSvuPDF7LYVn3pxst5Rf7EYdUTw7C7WIrYhcLaKiZ1b9oSRkTQddAN3mifDMCfHqO4kAQ/pcKiBl3A=="],
|
||||||
|
|
||||||
|
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
||||||
|
|
||||||
"node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="],
|
"node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="],
|
||||||
|
|
||||||
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
|
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
|
||||||
@ -824,6 +903,8 @@
|
|||||||
|
|
||||||
"pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="],
|
"pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="],
|
||||||
|
|
||||||
|
"po-parser": ["po-parser@2.0.0", "", {}, "sha512-SZvoKi3PoI/hHa2V9je9CW7Xgxl4dvO74cvaa6tWShIHT51FkPxje6pt0gTJznJrU67ix91nDaQp2hUxkOYhKA=="],
|
||||||
|
|
||||||
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
||||||
|
|
||||||
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||||
@ -992,6 +1073,8 @@
|
|||||||
|
|
||||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||||
|
|
||||||
|
"use-intl": ["use-intl@4.6.1", "", { "dependencies": { "@formatjs/fast-memoize": "^2.2.0", "@schummar/icu-type-parser": "1.21.5", "intl-messageformat": "^10.5.14" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0" } }, "sha512-mUIj6QvJZ7Rk33mLDxRziz1YiBBAnIji8YW4TXXMdYHtaPEbVucrXD3iKQGAqJhbVn0VnjrEtIKYO1B18mfSJw=="],
|
||||||
|
|
||||||
"use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
|
"use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
|
||||||
|
|
||||||
"utility-types": ["utility-types@3.11.0", "", {}, "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw=="],
|
"utility-types": ["utility-types@3.11.0", "", {}, "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw=="],
|
||||||
@ -1028,6 +1111,10 @@
|
|||||||
|
|
||||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||||
|
|
||||||
|
"@formatjs/ecma402-abstract/@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.6.2", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA=="],
|
||||||
|
|
||||||
|
"@parcel/watcher/detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
const About: React.FC = () => {
|
const About: React.FC = () => {
|
||||||
|
const t = useTranslations('About');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section id="about" className="py-24 bg-feie-cream relative">
|
<section id="about" className="py-24 bg-feie-cream relative">
|
||||||
<div className="container mx-auto px-6">
|
<div className="container mx-auto px-6">
|
||||||
@ -23,32 +26,32 @@ const About: React.FC = () => {
|
|||||||
|
|
||||||
{/* Text Content */}
|
{/* Text Content */}
|
||||||
<div className="w-full md:w-1/2 space-y-8">
|
<div className="w-full md:w-1/2 space-y-8">
|
||||||
<h2 className="text-sm font-bold tracking-widest text-feie-gold uppercase mb-2">关于我们 • About Us</h2>
|
<h2 className="text-sm font-bold tracking-widest text-feie-gold uppercase mb-2">{t('title')} • {t('subtitle')}</h2>
|
||||||
<h3 className="text-4xl md:text-5xl font-serif text-feie-dark leading-tight">
|
<h3 className="text-4xl md:text-5xl font-serif text-feie-dark leading-tight">
|
||||||
专注技术沉淀 <br />
|
{t('heading')} <br />
|
||||||
<span className="italic text-gray-500">成就卓越品质</span>
|
<span className="italic text-gray-500">{t('subheading')}</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div className="space-y-6 text-gray-600 font-light leading-relaxed">
|
<div className="space-y-6 text-gray-600 font-light leading-relaxed">
|
||||||
<p>
|
<p>
|
||||||
南京市肥鹅信息技术有限公司坐落于历史悠久的六朝古都——南京。我们是一家专注于前沿信息技术研发与应用的高新技术企业。
|
{t('p1')}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
自成立以来,我们始终秉承"技术驱动、服务至上"的理念,深耕软件开发、系统集成及数字化转型咨询领域。我们拥有一支经验丰富、富有创造力的技术团队,致力于通过代码改变世界,用智慧连接未来。
|
{t('p2')}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
在溧水区这片充满活力的创新热土上,我们正以稳健的步伐,为各行各业的客户提供量身定制的IT解决方案,助力企业在数字经济浪潮中乘风破浪。
|
{t('p3')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="pt-4 grid grid-cols-2 gap-8">
|
<div className="pt-4 grid grid-cols-2 gap-8">
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-3xl font-serif text-feie-gold">100+</h4>
|
<h4 className="text-3xl font-serif text-feie-gold">100+</h4>
|
||||||
<p className="text-sm text-gray-500 uppercase tracking-wider mt-1">成功案例</p>
|
<p className="text-sm text-gray-500 uppercase tracking-wider mt-1">{t('stats.cases')}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-3xl font-serif text-feie-gold">24/7</h4>
|
<h4 className="text-3xl font-serif text-feie-gold">24/7</h4>
|
||||||
<p className="text-sm text-gray-500 uppercase tracking-wider mt-1">技术支持</p>
|
<p className="text-sm text-gray-500 uppercase tracking-wider mt-1">{t('stats.support')}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { MapPin, Phone, Mail } from 'lucide-react';
|
import { MapPin, Phone, Mail } from 'lucide-react';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
interface FormData {
|
interface FormData {
|
||||||
name: string;
|
name: string;
|
||||||
@ -18,6 +19,7 @@ interface FormErrors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Contact: React.FC = () => {
|
const Contact: React.FC = () => {
|
||||||
|
const t = useTranslations('Contact');
|
||||||
const [formData, setFormData] = useState<FormData>({
|
const [formData, setFormData] = useState<FormData>({
|
||||||
name: '',
|
name: '',
|
||||||
phone: '',
|
phone: '',
|
||||||
@ -33,25 +35,25 @@ const Contact: React.FC = () => {
|
|||||||
const newErrors: FormErrors = {};
|
const newErrors: FormErrors = {};
|
||||||
|
|
||||||
if (!formData.name.trim()) {
|
if (!formData.name.trim()) {
|
||||||
newErrors.name = '请输入姓名';
|
newErrors.name = t('form.errors.nameRequired');
|
||||||
}
|
}
|
||||||
|
|
||||||
const phoneRegex = /^1[3-9]\d{9}$/;
|
const phoneRegex = /^1[3-9]\d{9}$/;
|
||||||
if (!formData.phone.trim()) {
|
if (!formData.phone.trim()) {
|
||||||
newErrors.phone = '请输入电话';
|
newErrors.phone = t('form.errors.phoneRequired');
|
||||||
} else if (!phoneRegex.test(formData.phone)) {
|
} else if (!phoneRegex.test(formData.phone)) {
|
||||||
newErrors.phone = '请输入正确的手机号';
|
newErrors.phone = t('form.errors.phoneInvalid');
|
||||||
}
|
}
|
||||||
|
|
||||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
if (!formData.email.trim()) {
|
if (!formData.email.trim()) {
|
||||||
newErrors.email = '请输入邮箱';
|
newErrors.email = t('form.errors.emailRequired');
|
||||||
} else if (!emailRegex.test(formData.email)) {
|
} else if (!emailRegex.test(formData.email)) {
|
||||||
newErrors.email = '请输入正确的邮箱地址';
|
newErrors.email = t('form.errors.emailInvalid');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!formData.description.trim()) {
|
if (!formData.description.trim()) {
|
||||||
newErrors.description = '请描述您的需求';
|
newErrors.description = t('form.errors.descRequired');
|
||||||
}
|
}
|
||||||
|
|
||||||
setErrors(newErrors);
|
setErrors(newErrors);
|
||||||
@ -91,7 +93,7 @@ const Contact: React.FC = () => {
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
setSubmitStatus({
|
setSubmitStatus({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
message: data.message || '留言提交成功,我们会尽快与您联系!'
|
message: data.message || t('form.success')
|
||||||
});
|
});
|
||||||
// 清空表单
|
// 清空表单
|
||||||
setFormData({
|
setFormData({
|
||||||
@ -129,9 +131,9 @@ const Contact: React.FC = () => {
|
|||||||
|
|
||||||
<div className="space-y-8">
|
<div className="space-y-8">
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-sm font-bold tracking-widest text-feie-gold uppercase mb-3">联系方式 • Contact</h2>
|
<h2 className="text-sm font-bold tracking-widest text-feie-gold uppercase mb-3">{t('title')} • {t('subtitle')}</h2>
|
||||||
<h3 className="text-4xl md:text-5xl font-serif leading-tight">
|
<h3 className="text-4xl md:text-5xl font-serif leading-tight">
|
||||||
期待与您的合作 <br/>
|
{t('heading')} <br/>
|
||||||
<span className="text-feie-white/50">共创价值</span>
|
<span className="text-feie-white/50">共创价值</span>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
@ -146,8 +148,8 @@ const Contact: React.FC = () => {
|
|||||||
<MapPin className="w-6 h-6 text-feie-gold" />
|
<MapPin className="w-6 h-6 text-feie-gold" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-400 uppercase tracking-wider mb-1">注册地址</p>
|
<p className="text-sm text-gray-400 uppercase tracking-wider mb-1">{t('info.address')}</p>
|
||||||
<p className="text-xl font-serif">江苏省南京市溧水区永阳街道中大街81号8幢1630室</p>
|
<p className="text-xl font-serif">{t('info.addressValue')}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -156,7 +158,7 @@ const Contact: React.FC = () => {
|
|||||||
<Phone className="w-6 h-6 text-feie-gold" />
|
<Phone className="w-6 h-6 text-feie-gold" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-400 uppercase tracking-wider mb-1">联系电话</p>
|
<p className="text-sm text-gray-400 uppercase tracking-wider mb-1">{t('info.phone')}</p>
|
||||||
<p className="text-xl font-serif">19844561014</p>
|
<p className="text-xl font-serif">19844561014</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -166,7 +168,7 @@ const Contact: React.FC = () => {
|
|||||||
<Mail className="w-6 h-6 text-feie-gold" />
|
<Mail className="w-6 h-6 text-feie-gold" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-400 uppercase tracking-wider mb-1">电子邮箱</p>
|
<p className="text-sm text-gray-400 uppercase tracking-wider mb-1">{t('info.email')}</p>
|
||||||
<a href="mailto:feie9454@gmail.com" className="text-xl font-serif hover:text-feie-gold transition-colors">
|
<a href="mailto:feie9454@gmail.com" className="text-xl font-serif hover:text-feie-gold transition-colors">
|
||||||
feie9454@gmail.com
|
feie9454@gmail.com
|
||||||
</a>
|
</a>
|
||||||
@ -192,7 +194,7 @@ const Contact: React.FC = () => {
|
|||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
|
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
|
||||||
姓名 <span className="text-red-500">*</span>
|
{t('form.name')} <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@ -202,13 +204,13 @@ const Contact: React.FC = () => {
|
|||||||
className={`w-full bg-white border-b-2 p-3 focus:border-feie-gold outline-none transition-colors ${
|
className={`w-full bg-white border-b-2 p-3 focus:border-feie-gold outline-none transition-colors ${
|
||||||
errors.name ? 'border-red-500' : 'border-gray-200'
|
errors.name ? 'border-red-500' : 'border-gray-200'
|
||||||
}`}
|
}`}
|
||||||
placeholder="您的姓名"
|
placeholder={t('form.name')}
|
||||||
/>
|
/>
|
||||||
{errors.name && <p className="text-red-500 text-sm mt-1">{errors.name}</p>}
|
{errors.name && <p className="text-red-500 text-sm mt-1">{errors.name}</p>}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
|
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
|
||||||
电话 <span className="text-red-500">*</span>
|
{t('form.phone')} <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="tel"
|
type="tel"
|
||||||
@ -218,14 +220,14 @@ const Contact: React.FC = () => {
|
|||||||
className={`w-full bg-white border-b-2 p-3 focus:border-feie-gold outline-none transition-colors ${
|
className={`w-full bg-white border-b-2 p-3 focus:border-feie-gold outline-none transition-colors ${
|
||||||
errors.phone ? 'border-red-500' : 'border-gray-200'
|
errors.phone ? 'border-red-500' : 'border-gray-200'
|
||||||
}`}
|
}`}
|
||||||
placeholder="联系电话"
|
placeholder={t('form.phone')}
|
||||||
/>
|
/>
|
||||||
{errors.phone && <p className="text-red-500 text-sm mt-1">{errors.phone}</p>}
|
{errors.phone && <p className="text-red-500 text-sm mt-1">{errors.phone}</p>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
|
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
|
||||||
邮箱 <span className="text-red-500">*</span>
|
{t('form.email')} <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
@ -241,7 +243,7 @@ const Contact: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
|
<label className="block text-sm font-bold uppercase tracking-wider text-gray-500 mb-2">
|
||||||
需求描述 <span className="text-red-500">*</span>
|
{t('form.description')} <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
rows={4}
|
rows={4}
|
||||||
@ -251,7 +253,7 @@ const Contact: React.FC = () => {
|
|||||||
className={`w-full bg-white border-b-2 p-3 focus:border-feie-gold outline-none transition-colors resize-none ${
|
className={`w-full bg-white border-b-2 p-3 focus:border-feie-gold outline-none transition-colors resize-none ${
|
||||||
errors.description ? 'border-red-500' : 'border-gray-200'
|
errors.description ? 'border-red-500' : 'border-gray-200'
|
||||||
}`}
|
}`}
|
||||||
placeholder="请简要描述您的需求..."
|
placeholder={t('form.description')}
|
||||||
></textarea>
|
></textarea>
|
||||||
{errors.description && <p className="text-red-500 text-sm mt-1">{errors.description}</p>}
|
{errors.description && <p className="text-red-500 text-sm mt-1">{errors.description}</p>}
|
||||||
</div>
|
</div>
|
||||||
@ -264,7 +266,7 @@ const Contact: React.FC = () => {
|
|||||||
: 'bg-feie-dark text-feie-white hover:bg-feie-gold'
|
: 'bg-feie-dark text-feie-white hover:bg-feie-gold'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{isSubmitting ? '发送中...' : '发送信息'}
|
{isSubmitting ? t('form.submitting') : t('form.submit')}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,17 +1,20 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
const Footer: React.FC = () => {
|
const Footer: React.FC = () => {
|
||||||
|
const t = useTranslations('Footer');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className="bg-feie-dark text-feie-white border-t border-white/10 py-12">
|
<footer className="bg-feie-dark text-feie-white border-t border-white/10 py-12">
|
||||||
<div className="container mx-auto px-6 flex flex-col md:flex-row justify-between items-center gap-6">
|
<div className="container mx-auto px-6 flex flex-col md:flex-row justify-between items-center gap-6">
|
||||||
<div className="text-center md:text-left">
|
<div className="text-center md:text-left">
|
||||||
<h5 className="font-serif text-xl font-bold mb-2">南京市肥鹅信息技术有限公司</h5>
|
<h5 className="font-serif text-xl font-bold mb-2">{t('company')}</h5>
|
||||||
<p className="text-gray-500 text-sm">© {new Date().getFullYear()} Nanjing Feie Information Technology Co., Ltd. All rights reserved.</p>
|
<p className="text-gray-500 text-sm">{t('rights', {year: new Date().getFullYear()})}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex gap-6 text-sm text-gray-400">
|
<div className="flex gap-6 text-sm text-gray-400">
|
||||||
<a href="#" className="hover:text-feie-gold transition-colors">隐私政策</a>
|
<a href="#" className="hover:text-feie-gold transition-colors">{t('privacy')}</a>
|
||||||
<a href="#" className="hover:text-feie-gold transition-colors">服务条款</a>
|
<a href="#" className="hover:text-feie-gold transition-colors">{t('terms')}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import React, { useRef, useMemo } from 'react';
|
|||||||
import { Canvas, useFrame } from '@react-three/fiber';
|
import { Canvas, useFrame } from '@react-three/fiber';
|
||||||
import { Float, Stars } from '@react-three/drei';
|
import { Float, Stars } from '@react-three/drei';
|
||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
// ------------------- Three.js Components -------------------
|
// ------------------- Three.js Components -------------------
|
||||||
|
|
||||||
@ -103,6 +104,9 @@ const Scene = () => {
|
|||||||
// ------------------- Main Component -------------------
|
// ------------------- Main Component -------------------
|
||||||
|
|
||||||
const Hero: React.FC = () => {
|
const Hero: React.FC = () => {
|
||||||
|
const t = useTranslations('Hero');
|
||||||
|
const tNav = useTranslations('Navbar');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section id="hero" className="relative w-full h-screen bg-feie-dark overflow-hidden">
|
<section id="hero" className="relative w-full h-screen bg-feie-dark overflow-hidden">
|
||||||
{/* 3D Canvas Layer */}
|
{/* 3D Canvas Layer */}
|
||||||
@ -122,24 +126,24 @@ const Hero: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-5xl md:text-7xl font-serif text-feie-white leading-tight">
|
<h1 className="text-5xl md:text-7xl font-serif text-feie-white leading-tight">
|
||||||
数字化未来的 <br />
|
{t('title')} <br />
|
||||||
<span className="text-feie-gold italic">构建者</span>
|
<span className="text-feie-gold italic">{t('subtitle')}</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-feie-white/70 text-lg md:text-xl font-light max-w-md leading-relaxed">
|
<p className="text-feie-white/70 text-lg md:text-xl font-light max-w-md leading-relaxed">
|
||||||
南京市肥鹅信息技术有限公司致力于为企业提供卓越的数字化解决方案,以创新技术驱动商业价值。
|
{t('description')}
|
||||||
</p>
|
</p>
|
||||||
<div className="pt-8 flex gap-4">
|
<div className="pt-8 flex gap-4">
|
||||||
<a
|
<a
|
||||||
href="#services"
|
href="#services"
|
||||||
className="px-8 py-3 bg-feie-gold text-feie-white font-serif hover:bg-yellow-600 transition-colors duration-300 rounded-sm"
|
className="px-8 py-3 bg-feie-gold text-feie-white font-serif hover:bg-yellow-600 transition-colors duration-300 rounded-sm"
|
||||||
>
|
>
|
||||||
探索服务
|
{t('cta')}
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="#contact"
|
href="#contact"
|
||||||
className="px-8 py-3 border border-feie-white text-feie-white font-serif hover:bg-feie-white hover:text-feie-dark transition-colors duration-300 rounded-sm"
|
className="px-8 py-3 border border-feie-white text-feie-white font-serif hover:bg-feie-white hover:text-feie-dark transition-colors duration-300 rounded-sm"
|
||||||
>
|
>
|
||||||
联系我们
|
{tNav('contact')}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,18 +1,34 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useTransition } from 'react';
|
||||||
import { Menu, X } from 'lucide-react';
|
import { Menu, X, Globe } from 'lucide-react';
|
||||||
|
import { useTranslations, useLocale } from 'next-intl';
|
||||||
const navItems = [
|
import { usePathname, useRouter } from '@/i18n/routing';
|
||||||
{ label: '首页', href: '#hero' },
|
|
||||||
{ label: '关于我们', href: '#about' },
|
|
||||||
{ label: '核心业务', href: '#services' },
|
|
||||||
{ label: '联系方式', href: '#contact' },
|
|
||||||
];
|
|
||||||
|
|
||||||
const Navbar: React.FC = () => {
|
const Navbar: React.FC = () => {
|
||||||
|
const t = useTranslations('Navbar');
|
||||||
|
const locale = useLocale();
|
||||||
|
const router = useRouter();
|
||||||
|
const pathname = usePathname();
|
||||||
|
const [isPending, startTransition] = useTransition();
|
||||||
|
|
||||||
const [isScrolled, setIsScrolled] = useState(false);
|
const [isScrolled, setIsScrolled] = useState(false);
|
||||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||||
|
const [isLangMenuOpen, setIsLangMenuOpen] = useState(false);
|
||||||
|
|
||||||
|
const navItems = [
|
||||||
|
{ label: t('home'), href: '#hero' },
|
||||||
|
{ label: t('about'), href: '#about' },
|
||||||
|
{ label: t('services'), href: '#services' },
|
||||||
|
{ label: t('contact'), href: '#contact' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const onSelectChange = (nextLocale: string) => {
|
||||||
|
startTransition(() => {
|
||||||
|
router.replace(pathname, {locale: nextLocale});
|
||||||
|
});
|
||||||
|
setIsLangMenuOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
@ -63,29 +79,61 @@ const Navbar: React.FC = () => {
|
|||||||
{item.label}
|
{item.label}
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
<a
|
|
||||||
href="#contact"
|
{/* Language Switcher */}
|
||||||
className={`px-5 py-2 border font-serif text-sm transition-all duration-300 ${
|
<div className="relative">
|
||||||
isScrolled
|
<button
|
||||||
? 'border-feie-dark text-feie-dark hover:bg-feie-dark hover:text-feie-white'
|
onClick={() => setIsLangMenuOpen(!isLangMenuOpen)}
|
||||||
: 'border-feie-white text-feie-white hover:bg-feie-white hover:text-feie-dark'
|
className={`flex items-center gap-1 font-serif text-sm tracking-widest uppercase hover:text-feie-gold transition-colors duration-300 ${
|
||||||
}`}
|
isScrolled ? 'text-feie-dark' : 'text-feie-white/90'
|
||||||
>
|
}`}
|
||||||
合作咨询
|
>
|
||||||
</a>
|
<Globe size={16} />
|
||||||
|
<span>{locale.toUpperCase()}</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{isLangMenuOpen && (
|
||||||
|
<div className="absolute top-full right-0 mt-2 w-24 bg-white rounded-md shadow-lg py-1 z-50">
|
||||||
|
{['zh', 'en', 'ja'].map((l) => (
|
||||||
|
<button
|
||||||
|
key={l}
|
||||||
|
onClick={() => onSelectChange(l)}
|
||||||
|
className={`block w-full text-left px-4 py-2 text-sm hover:bg-gray-100 ${locale === l ? 'text-feie-gold font-bold' : 'text-gray-700'}`}
|
||||||
|
>
|
||||||
|
{l === 'zh' ? '中文' : l === 'en' ? 'English' : '日本語'}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile Toggle */}
|
{/* Mobile Toggle */}
|
||||||
<button
|
<div className="md:hidden flex items-center gap-4">
|
||||||
className="md:hidden focus:outline-none"
|
{/* Mobile Language Switcher */}
|
||||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
<button
|
||||||
>
|
onClick={() => {
|
||||||
{isMobileMenuOpen ? (
|
const nextLocale = locale === 'zh' ? 'en' : locale === 'en' ? 'ja' : 'zh';
|
||||||
<X className={isScrolled || isMobileMenuOpen ? 'text-feie-dark' : 'text-feie-white'} />
|
onSelectChange(nextLocale);
|
||||||
) : (
|
}}
|
||||||
<Menu className={isScrolled || isMobileMenuOpen ? 'text-feie-dark' : 'text-feie-white'} />
|
className={`flex items-center gap-1 font-serif text-sm tracking-widest uppercase ${
|
||||||
)}
|
isScrolled || isMobileMenuOpen ? 'text-feie-dark' : 'text-feie-white'
|
||||||
</button>
|
}`}
|
||||||
|
>
|
||||||
|
{locale.toUpperCase()}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="focus:outline-none"
|
||||||
|
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||||
|
>
|
||||||
|
{isMobileMenuOpen ? (
|
||||||
|
<X className={isScrolled || isMobileMenuOpen ? 'text-feie-dark' : 'text-feie-white'} />
|
||||||
|
) : (
|
||||||
|
<Menu className={isScrolled || isMobileMenuOpen ? 'text-feie-dark' : 'text-feie-white'} />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile Menu */}
|
{/* Mobile Menu */}
|
||||||
|
|||||||
@ -1,48 +1,51 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Monitor, Server, Code, Database, Globe, Shield } from 'lucide-react';
|
import { Monitor, Server, Code, Database, Globe, Shield } from 'lucide-react';
|
||||||
import { ServiceItem } from '../types';
|
import { ServiceItem } from '../types';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
const services: ServiceItem[] = [
|
|
||||||
{
|
|
||||||
title: '定制软件开发',
|
|
||||||
description: '根据企业独特需求,打造专属的Web应用、移动端APP及桌面软件,优化业务流程。',
|
|
||||||
icon: Code,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '企业数字化转型',
|
|
||||||
description: '提供全方位的数字化咨询与落地实施方案,助力传统企业实现智能化升级。',
|
|
||||||
icon: Monitor,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '系统集成服务',
|
|
||||||
description: '打破信息孤岛,实现异构系统间的数据互通与功能协同,提升整体运营效率。',
|
|
||||||
icon: Server,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '大数据分析',
|
|
||||||
description: '挖掘数据价值,提供可视化报表与智能决策支持,让数据成为企业的核心资产。',
|
|
||||||
icon: Database,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '云服务与部署',
|
|
||||||
description: '提供安全可靠的云端架构设计、迁移及运维服务,保障业务的高可用性。',
|
|
||||||
icon: Globe,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '信息安全保障',
|
|
||||||
description: '构建多层次的安全防护体系,保护企业核心数据资产不受威胁。',
|
|
||||||
icon: Shield,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const Services: React.FC = () => {
|
const Services: React.FC = () => {
|
||||||
|
const t = useTranslations('Services');
|
||||||
|
|
||||||
|
const services: ServiceItem[] = [
|
||||||
|
{
|
||||||
|
title: t('items.customDev.title'),
|
||||||
|
description: t('items.customDev.desc'),
|
||||||
|
icon: Code,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('items.digitalTrans.title'),
|
||||||
|
description: t('items.digitalTrans.desc'),
|
||||||
|
icon: Monitor,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('items.systemIntegration.title'),
|
||||||
|
description: t('items.systemIntegration.desc'),
|
||||||
|
icon: Server,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('items.bigData.title'),
|
||||||
|
description: t('items.bigData.desc'),
|
||||||
|
icon: Database,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('items.cloudService.title'),
|
||||||
|
description: t('items.cloudService.desc'),
|
||||||
|
icon: Globe,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('items.security.title'),
|
||||||
|
description: t('items.security.desc'),
|
||||||
|
icon: Shield,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section id="services" className="py-24 bg-white">
|
<section id="services" className="py-24 bg-white">
|
||||||
<div className="container mx-auto px-6">
|
<div className="container mx-auto px-6">
|
||||||
<div className="text-center max-w-3xl mx-auto mb-16">
|
<div className="text-center max-w-3xl mx-auto mb-16">
|
||||||
<h2 className="text-sm font-bold tracking-widest text-feie-gold uppercase mb-3">核心业务 • Services</h2>
|
<h2 className="text-sm font-bold tracking-widest text-feie-gold uppercase mb-3">{t('title')} • {t('subtitle')}</h2>
|
||||||
<h3 className="text-3xl md:text-4xl font-serif text-feie-dark mb-6">
|
<h3 className="text-3xl md:text-4xl font-serif text-feie-dark mb-6">
|
||||||
全方位技术解决方案
|
{t('heading')}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="w-16 h-1 bg-feie-dark mx-auto"></div>
|
<div className="w-16 h-1 bg-feie-dark mx-auto"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
16
i18n/request.ts
Normal file
16
i18n/request.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import {getRequestConfig} from 'next-intl/server';
|
||||||
|
|
||||||
|
export default getRequestConfig(async ({requestLocale}) => {
|
||||||
|
// This typically corresponds to the `[locale]` segment
|
||||||
|
let locale = await requestLocale;
|
||||||
|
|
||||||
|
// Ensure that a valid locale is used
|
||||||
|
if (!locale || !['en', 'zh', 'ja'].includes(locale)) {
|
||||||
|
locale = 'zh';
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
locale,
|
||||||
|
messages: (await import(`../messages/${locale}.json`)).default
|
||||||
|
};
|
||||||
|
});
|
||||||
15
i18n/routing.ts
Normal file
15
i18n/routing.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import {defineRouting} from 'next-intl/routing';
|
||||||
|
import {createNavigation} from 'next-intl/navigation';
|
||||||
|
|
||||||
|
export const routing = defineRouting({
|
||||||
|
// A list of all locales that are supported
|
||||||
|
locales: ['en', 'zh', 'ja'],
|
||||||
|
|
||||||
|
// Used when no locale matches
|
||||||
|
defaultLocale: 'zh'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Lightweight wrappers around Next.js' navigation APIs
|
||||||
|
// that will consider the routing configuration
|
||||||
|
export const {Link, redirect, usePathname, useRouter, getPathname} =
|
||||||
|
createNavigation(routing);
|
||||||
92
messages/en.json
Normal file
92
messages/en.json
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
"Navbar": {
|
||||||
|
"home": "Home",
|
||||||
|
"about": "About Us",
|
||||||
|
"services": "Services",
|
||||||
|
"contact": "Contact"
|
||||||
|
},
|
||||||
|
"Hero": {
|
||||||
|
"title": "Digital Future",
|
||||||
|
"subtitle": "Innovation Leads Change",
|
||||||
|
"description": "We are committed to providing excellent digital solutions for enterprises, driving business value with innovative technology.",
|
||||||
|
"cta": "Learn More"
|
||||||
|
},
|
||||||
|
"About": {
|
||||||
|
"title": "About Us",
|
||||||
|
"subtitle": "About Us",
|
||||||
|
"heading": "Focus on Technology",
|
||||||
|
"subheading": "Achieve Excellence",
|
||||||
|
"p1": "Nanjing Feie Information Technology Co., Ltd. is located in Nanjing, the ancient capital of the Six Dynasties. We are a high-tech enterprise focusing on the R&D and application of cutting-edge information technology.",
|
||||||
|
"p2": "Since our establishment, we have always adhered to the concept of \"Technology Driven, Service First\", deeply cultivating in the fields of software development, system integration, and digital transformation consulting. We have an experienced and creative technical team dedicated to changing the world through code and connecting the future with wisdom.",
|
||||||
|
"p3": "In the vibrant innovation hot land of Lishui District, we are providing customized IT solutions for customers in various industries with steady steps, helping enterprises ride the wind and waves in the digital economy.",
|
||||||
|
"stats": {
|
||||||
|
"cases": "Successful Cases",
|
||||||
|
"support": "Tech Support"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Services": {
|
||||||
|
"title": "Core Services",
|
||||||
|
"subtitle": "Services",
|
||||||
|
"heading": "Comprehensive Tech Solutions",
|
||||||
|
"items": {
|
||||||
|
"customDev": {
|
||||||
|
"title": "Custom Software Development",
|
||||||
|
"desc": "Build exclusive Web applications, mobile APPs, and desktop software according to unique enterprise needs to optimize business processes."
|
||||||
|
},
|
||||||
|
"digitalTrans": {
|
||||||
|
"title": "Digital Transformation",
|
||||||
|
"desc": "Provide comprehensive digital consulting and implementation plans to help traditional enterprises achieve intelligent upgrades."
|
||||||
|
},
|
||||||
|
"systemIntegration": {
|
||||||
|
"title": "System Integration",
|
||||||
|
"desc": "Break information silos, achieve data interoperability and functional synergy between heterogeneous systems, and improve overall operational efficiency."
|
||||||
|
},
|
||||||
|
"bigData": {
|
||||||
|
"title": "Big Data Analysis",
|
||||||
|
"desc": "Mine data value, provide visual reports and intelligent decision support, making data a core asset of the enterprise."
|
||||||
|
},
|
||||||
|
"cloudService": {
|
||||||
|
"title": "Cloud Services & Deployment",
|
||||||
|
"desc": "Provide safe and reliable cloud architecture design, migration, and operation and maintenance services to ensure high availability of business."
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"title": "Information Security",
|
||||||
|
"desc": "Build a multi-level security protection system to protect enterprise core data assets from threats."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Contact": {
|
||||||
|
"title": "Contact Us",
|
||||||
|
"subtitle": "Contact Us",
|
||||||
|
"heading": "Start Your Digital Journey",
|
||||||
|
"form": {
|
||||||
|
"name": "Name",
|
||||||
|
"phone": "Phone",
|
||||||
|
"email": "Email",
|
||||||
|
"description": "Description",
|
||||||
|
"submit": "Submit",
|
||||||
|
"submitting": "Submitting...",
|
||||||
|
"success": "Message submitted successfully, we will contact you soon!",
|
||||||
|
"errors": {
|
||||||
|
"nameRequired": "Please enter your name",
|
||||||
|
"phoneRequired": "Please enter your phone number",
|
||||||
|
"phoneInvalid": "Please enter a valid phone number",
|
||||||
|
"emailRequired": "Please enter your email",
|
||||||
|
"emailInvalid": "Please enter a valid email address",
|
||||||
|
"descRequired": "Please describe your needs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"address": "Registered Address",
|
||||||
|
"addressValue": "Room 1630, Building 8, No. 81 Zhongda Street, Yongyang Subdistrict, Lishui District, Nanjing, Jiangsu Province",
|
||||||
|
"phone": "Phone",
|
||||||
|
"email": "Email"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Footer": {
|
||||||
|
"company": "Nanjing Feie Information Technology Co., Ltd.",
|
||||||
|
"rights": "© {year} Nanjing Feie Information Technology Co., Ltd. All rights reserved.",
|
||||||
|
"privacy": "Privacy Policy",
|
||||||
|
"terms": "Terms of Service"
|
||||||
|
}
|
||||||
|
}
|
||||||
92
messages/ja.json
Normal file
92
messages/ja.json
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
"Navbar": {
|
||||||
|
"home": "ホーム",
|
||||||
|
"about": "私たちについて",
|
||||||
|
"services": "サービス",
|
||||||
|
"contact": "お問い合わせ"
|
||||||
|
},
|
||||||
|
"Hero": {
|
||||||
|
"title": "デジタルが未来を拓く",
|
||||||
|
"subtitle": "革新が変革を導く",
|
||||||
|
"description": "私たちは、革新的な技術でビジネス価値を創造し、企業に卓越したデジタルソリューションを提供することに尽力しています。",
|
||||||
|
"cta": "詳細を見る"
|
||||||
|
},
|
||||||
|
"About": {
|
||||||
|
"title": "私たちについて",
|
||||||
|
"subtitle": "About Us",
|
||||||
|
"heading": "技術へのこだわり",
|
||||||
|
"subheading": "卓越した品質の追求",
|
||||||
|
"p1": "南京市肥鹅信息技术有限公司は、歴史ある六朝の古都、南京に位置しています。最先端の情報技術の研究開発と応用に注力するハイテク企業です。",
|
||||||
|
"p2": "設立以来、「技術主導、サービス第一」の理念を掲げ、ソフトウェア開発、システムインテグレーション、デジタルトランスフォーメーションコンサルティングの分野で深く活動してきました。経験豊富で創造的な技術チームを擁し、コードで世界を変え、知恵で未来をつなぐことに尽力しています。",
|
||||||
|
"p3": "活気あふれる溧水区のイノベーションの地で、私たちは着実な歩みで、各業界のお客様にカスタマイズされたITソリューションを提供し、デジタル経済の波に乗る企業を支援しています。",
|
||||||
|
"stats": {
|
||||||
|
"cases": "成功事例",
|
||||||
|
"support": "技術サポート"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Services": {
|
||||||
|
"title": "コアサービス",
|
||||||
|
"subtitle": "Services",
|
||||||
|
"heading": "包括的な技術ソリューション",
|
||||||
|
"items": {
|
||||||
|
"customDev": {
|
||||||
|
"title": "カスタムソフトウェア開発",
|
||||||
|
"desc": "企業の独自のニーズに合わせて、専用のWebアプリケーション、モバイルアプリ、デスクトップソフトウェアを構築し、業務プロセスを最適化します。"
|
||||||
|
},
|
||||||
|
"digitalTrans": {
|
||||||
|
"title": "企業のデジタルトランスフォーメーション",
|
||||||
|
"desc": "包括的なデジタルコンサルティングと実装計画を提供し、伝統的な企業のインテリジェントなアップグレードを支援します。"
|
||||||
|
},
|
||||||
|
"systemIntegration": {
|
||||||
|
"title": "システムインテグレーション",
|
||||||
|
"desc": "情報の孤立を打破し、異種システム間のデータ相互運用性と機能的相乗効果を実現し、全体的な運用効率を向上させます。"
|
||||||
|
},
|
||||||
|
"bigData": {
|
||||||
|
"title": "ビッグデータ分析",
|
||||||
|
"desc": "データの価値を掘り起こし、視覚的なレポートとインテリジェントな意思決定サポートを提供し、データを企業のコア資産にします。"
|
||||||
|
},
|
||||||
|
"cloudService": {
|
||||||
|
"title": "クラウドサービスと展開",
|
||||||
|
"desc": "安全で信頼性の高いクラウドアーキテクチャの設計、移行、運用保守サービスを提供し、ビジネスの高可用性を保証します。"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"title": "情報セキュリティ保証",
|
||||||
|
"desc": "多層的なセキュリティ保護システムを構築し、企業のコアデータ資産を脅威から保護します。"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Contact": {
|
||||||
|
"title": "お問い合わせ",
|
||||||
|
"subtitle": "Contact Us",
|
||||||
|
"heading": "デジタルの旅を始めましょう",
|
||||||
|
"form": {
|
||||||
|
"name": "お名前",
|
||||||
|
"phone": "電話番号",
|
||||||
|
"email": "メールアドレス",
|
||||||
|
"description": "ご要望",
|
||||||
|
"submit": "送信",
|
||||||
|
"submitting": "送信中...",
|
||||||
|
"success": "メッセージが送信されました。すぐにご連絡いたします!",
|
||||||
|
"errors": {
|
||||||
|
"nameRequired": "お名前を入力してください",
|
||||||
|
"phoneRequired": "電話番号を入力してください",
|
||||||
|
"phoneInvalid": "有効な電話番号を入力してください",
|
||||||
|
"emailRequired": "メールアドレスを入力してください",
|
||||||
|
"emailInvalid": "有効なメールアドレスを入力してください",
|
||||||
|
"descRequired": "ご要望を入力してください"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"address": "登録住所",
|
||||||
|
"addressValue": "江蘇省南京市溧水区永陽街道中大街81号8棟1630室",
|
||||||
|
"phone": "電話番号",
|
||||||
|
"email": "メールアドレス"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Footer": {
|
||||||
|
"company": "南京市肥鹅信息技术有限公司",
|
||||||
|
"rights": "© {year} Nanjing Feie Information Technology Co., Ltd. All rights reserved.",
|
||||||
|
"privacy": "プライバシーポリシー",
|
||||||
|
"terms": "利用規約"
|
||||||
|
}
|
||||||
|
}
|
||||||
92
messages/zh.json
Normal file
92
messages/zh.json
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
"Navbar": {
|
||||||
|
"home": "首页",
|
||||||
|
"about": "关于我们",
|
||||||
|
"services": "核心业务",
|
||||||
|
"contact": "联系方式"
|
||||||
|
},
|
||||||
|
"Hero": {
|
||||||
|
"title": "数字驱动未来",
|
||||||
|
"subtitle": "创新引领变革",
|
||||||
|
"description": "我们致力于为企业提供卓越的数字化解决方案,以创新技术驱动商业价值。",
|
||||||
|
"cta": "了解更多"
|
||||||
|
},
|
||||||
|
"About": {
|
||||||
|
"title": "关于我们",
|
||||||
|
"subtitle": "About Us",
|
||||||
|
"heading": "专注技术沉淀",
|
||||||
|
"subheading": "成就卓越品质",
|
||||||
|
"p1": "南京市肥鹅信息技术有限公司坐落于历史悠久的六朝古都——南京。我们是一家专注于前沿信息技术研发与应用的高新技术企业。",
|
||||||
|
"p2": "自成立以来,我们始终秉承\"技术驱动、服务至上\"的理念,深耕软件开发、系统集成及数字化转型咨询领域。我们拥有一支经验丰富、富有创造力的技术团队,致力于通过代码改变世界,用智慧连接未来。",
|
||||||
|
"p3": "在溧水区这片充满活力的创新热土上,我们正以稳健的步伐,为各行各业的客户提供量身定制的IT解决方案,助力企业在数字经济浪潮中乘风破浪。",
|
||||||
|
"stats": {
|
||||||
|
"cases": "成功案例",
|
||||||
|
"support": "技术支持"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Services": {
|
||||||
|
"title": "核心业务",
|
||||||
|
"subtitle": "Services",
|
||||||
|
"heading": "全方位技术解决方案",
|
||||||
|
"items": {
|
||||||
|
"customDev": {
|
||||||
|
"title": "定制软件开发",
|
||||||
|
"desc": "根据企业独特需求,打造专属的Web应用、移动端APP及桌面软件,优化业务流程。"
|
||||||
|
},
|
||||||
|
"digitalTrans": {
|
||||||
|
"title": "企业数字化转型",
|
||||||
|
"desc": "提供全方位的数字化咨询与落地实施方案,助力传统企业实现智能化升级。"
|
||||||
|
},
|
||||||
|
"systemIntegration": {
|
||||||
|
"title": "系统集成服务",
|
||||||
|
"desc": "打破信息孤岛,实现异构系统间的数据互通与功能协同,提升整体运营效率。"
|
||||||
|
},
|
||||||
|
"bigData": {
|
||||||
|
"title": "大数据分析",
|
||||||
|
"desc": "挖掘数据价值,提供可视化报表与智能决策支持,让数据成为企业的核心资产。"
|
||||||
|
},
|
||||||
|
"cloudService": {
|
||||||
|
"title": "云服务与部署",
|
||||||
|
"desc": "提供安全可靠的云端架构设计、迁移及运维服务,保障业务的高可用性。"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"title": "信息安全保障",
|
||||||
|
"desc": "构建多层次的安全防护体系,保护企业核心数据资产不受威胁。"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Contact": {
|
||||||
|
"title": "联系我们",
|
||||||
|
"subtitle": "Contact Us",
|
||||||
|
"heading": "开启您的数字化之旅",
|
||||||
|
"form": {
|
||||||
|
"name": "姓名",
|
||||||
|
"phone": "电话",
|
||||||
|
"email": "邮箱",
|
||||||
|
"description": "需求描述",
|
||||||
|
"submit": "提交留言",
|
||||||
|
"submitting": "提交中...",
|
||||||
|
"success": "留言提交成功,我们会尽快与您联系!",
|
||||||
|
"errors": {
|
||||||
|
"nameRequired": "请输入姓名",
|
||||||
|
"phoneRequired": "请输入电话",
|
||||||
|
"phoneInvalid": "请输入正确的手机号",
|
||||||
|
"emailRequired": "请输入邮箱",
|
||||||
|
"emailInvalid": "请输入正确的邮箱地址",
|
||||||
|
"descRequired": "请描述您的需求"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"address": "注册地址",
|
||||||
|
"addressValue": "江苏省南京市溧水区永阳街道中大街81号8幢1630室",
|
||||||
|
"phone": "联系电话",
|
||||||
|
"email": "电子邮箱"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Footer": {
|
||||||
|
"company": "南京市肥鹅信息技术有限公司",
|
||||||
|
"rights": "© {year} Nanjing Feie Information Technology Co., Ltd. All rights reserved.",
|
||||||
|
"privacy": "隐私政策",
|
||||||
|
"terms": "服务条款"
|
||||||
|
}
|
||||||
|
}
|
||||||
11
middleware.ts
Normal file
11
middleware.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import createMiddleware from 'next-intl/middleware';
|
||||||
|
import {routing} from './i18n/routing';
|
||||||
|
|
||||||
|
export default createMiddleware(routing);
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
// Match all pathnames except for
|
||||||
|
// - … if they start with `/api`, `/_next` or `/_vercel`
|
||||||
|
// - … the ones containing a dot (e.g. `favicon.ico`)
|
||||||
|
matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
|
||||||
|
};
|
||||||
@ -1,7 +1,10 @@
|
|||||||
import type { NextConfig } from "next";
|
import type { NextConfig } from "next";
|
||||||
|
import createNextIntlPlugin from 'next-intl/plugin';
|
||||||
|
|
||||||
|
const withNextIntl = createNextIntlPlugin('./i18n/request.ts');
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
/* config options here */
|
/* config options here */
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default withNextIntl(nextConfig);
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
"@react-three/fiber": "^9.4.2",
|
"@react-three/fiber": "^9.4.2",
|
||||||
"lucide-react": "^0.559.0",
|
"lucide-react": "^0.559.0",
|
||||||
"next": "16.0.8",
|
"next": "16.0.8",
|
||||||
|
"next-intl": "^4.6.1",
|
||||||
"prisma": "^6.0.0",
|
"prisma": "^6.0.0",
|
||||||
"react": "19.2.1",
|
"react": "19.2.1",
|
||||||
"react-dom": "19.2.1",
|
"react-dom": "19.2.1",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user