首页页面
51
README.md
@@ -1,36 +1,23 @@
|
||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||
## 功能布局
|
||||
|
||||
## Getting Started
|
||||
### 首页
|
||||
|
||||
First, run the development server:
|
||||
- 页头
|
||||
- LOGO
|
||||
- 菜单
|
||||
- 登录/注册
|
||||
- 正文
|
||||
- 优势介绍
|
||||
- 数据展示
|
||||
- 产品推荐
|
||||
- 客户案例
|
||||
- 合作伙伴
|
||||
- 新闻动态
|
||||
- 页脚
|
||||
- 关于我们
|
||||
- 网站地图
|
||||
- 备案/版权信息
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
### 后台
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||
### 授权
|
||||
|
||||
@@ -11,6 +11,12 @@ const compat = new FlatCompat({
|
||||
|
||||
const eslintConfig = [
|
||||
...compat.extends("next/core-web-vitals", "next/typescript"),
|
||||
{
|
||||
rules: {
|
||||
'@typescript-eslint/no-empty-object-type': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default eslintConfig;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"dev": "next dev -H 0.0.0.0 --turbopack",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
@@ -14,6 +14,8 @@
|
||||
"next": "15.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/eslint-plugin-next": "^15.2.1",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"typescript": "^5",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
|
||||
30
pnpm-lock.yaml
generated
@@ -21,6 +21,9 @@ importers:
|
||||
'@eslint/eslintrc':
|
||||
specifier: ^3
|
||||
version: 3.3.0
|
||||
'@next/eslint-plugin-next':
|
||||
specifier: ^15.2.1
|
||||
version: 15.2.1
|
||||
'@tailwindcss/postcss':
|
||||
specifier: ^4
|
||||
version: 4.0.9
|
||||
@@ -39,6 +42,9 @@ importers:
|
||||
eslint-config-next:
|
||||
specifier: 15.2.1
|
||||
version: 15.2.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.8.2)
|
||||
eslint-plugin-react-hooks:
|
||||
specifier: ^5.2.0
|
||||
version: 5.2.0(eslint@9.21.0(jiti@2.4.2))
|
||||
tailwindcss:
|
||||
specifier: ^4
|
||||
version: 4.0.9
|
||||
@@ -135,67 +141,79 @@ packages:
|
||||
resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.0.5':
|
||||
resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.0.4':
|
||||
resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.0.4':
|
||||
resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
||||
resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
||||
resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linux-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-arm@0.33.5':
|
||||
resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-s390x@0.33.5':
|
||||
resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-x64@0.33.5':
|
||||
resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.33.5':
|
||||
resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-wasm32@0.33.5':
|
||||
resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
|
||||
@@ -237,24 +255,28 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@next/swc-linux-arm64-musl@15.2.1':
|
||||
resolution: {integrity: sha512-3v0pF/adKZkBWfUffmB/ROa+QcNTrnmYG4/SS+r52HPwAK479XcWoES2I+7F7lcbqc7mTeVXrIvb4h6rR/iDKg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@next/swc-linux-x64-gnu@15.2.1':
|
||||
resolution: {integrity: sha512-RbsVq2iB6KFJRZ2cHrU67jLVLKeuOIhnQB05ygu5fCNgg8oTewxweJE8XlLV+Ii6Y6u4EHwETdUiRNXIAfpBww==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@next/swc-linux-x64-musl@15.2.1':
|
||||
resolution: {integrity: sha512-QHsMLAyAIu6/fWjHmkN/F78EFPKmhQlyX5C8pRIS2RwVA7z+t9cTb0IaYWC3EHLOTjsU7MNQW+n2xGXr11QPpg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@next/swc-win32-arm64-msvc@15.2.1':
|
||||
resolution: {integrity: sha512-Gk42XZXo1cE89i3hPLa/9KZ8OuupTjkDmhLaMKFohjf9brOeZVEa3BQy1J9s9TWUqPhgAEbwv6B2+ciGfe54Vw==}
|
||||
@@ -334,24 +356,28 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tailwindcss/oxide-linux-arm64-musl@4.0.9':
|
||||
resolution: {integrity: sha512-3eMjyTC6HBxh9nRgOHzrc96PYh1/jWOwHZ3Kk0JN0Kl25BJ80Lj9HEvvwVDNTgPg154LdICwuFLuhfgH9DULmg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-gnu@4.0.9':
|
||||
resolution: {integrity: sha512-v0D8WqI/c3WpWH1kq/HP0J899ATLdGZmENa2/emmNjubT0sWtEke9W9+wXeEoACuGAhF9i3PO5MeyditpDCiWQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-musl@4.0.9':
|
||||
resolution: {integrity: sha512-Kvp0TCkfeXyeehqLJr7otsc4hd/BUPfcIGrQiwsTVCfaMfjQZCG7DjI+9/QqPZha8YapLA9UoIcUILRYO7NE1Q==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tailwindcss/oxide-win32-arm64-msvc@4.0.9':
|
||||
resolution: {integrity: sha512-m3+60T/7YvWekajNq/eexjhV8z10rswcz4BC9bioJ7YaN+7K8W2AmLmG0B79H14m6UHE571qB0XsPus4n0QVgQ==}
|
||||
@@ -1128,24 +1154,28 @@ packages:
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.29.1:
|
||||
resolution: {integrity: sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.29.1:
|
||||
resolution: {integrity: sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-musl@1.29.1:
|
||||
resolution: {integrity: sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.29.1:
|
||||
resolution: {integrity: sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==}
|
||||
|
||||
BIN
public/banner.webp
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
4
public/check.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="24" height="24" rx="2" fill="#2470F9"/>
|
||||
<path d="M9.42868 17.6575C9.15888 17.6491 8.90283 17.5364 8.71438 17.3432L4.45011 13.1003C4.25501 12.898 4.146 12.6278 4.146 12.3467C4.146 12.0656 4.25501 11.7955 4.45011 11.5932C4.54836 11.4942 4.66521 11.4157 4.79393 11.3622C4.92265 11.3086 5.06069 11.281 5.20011 11.281C5.33952 11.281 5.47757 11.3086 5.60628 11.3622C5.735 11.4157 5.85185 11.4942 5.95011 11.5932L9.42868 15.0932L18.3144 7.31458C18.4115 7.21501 18.5276 7.13588 18.6558 7.08186C18.784 7.02783 18.9217 7 19.0608 7C19.1999 7 19.3376 7.02783 19.4658 7.08186C19.594 7.13588 19.7101 7.21501 19.8072 7.31458C19.9061 7.41284 19.9846 7.52969 20.0382 7.65841C20.0918 7.78712 20.1194 7.92517 20.1194 8.06458C20.1194 8.204 20.0918 8.34204 20.0382 8.47076C19.9846 8.59948 19.9061 8.71633 19.8072 8.81458L10.1787 17.3432C9.98014 17.5431 9.71043 17.6561 9.42868 17.6575Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 997 B |
BIN
public/earth.webp
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
@@ -1 +0,0 @@
|
||||
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 391 B |
@@ -1 +0,0 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
BIN
public/map.webp
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
@@ -1 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||
<svg width="44" height="78" viewBox="0 0 44 78" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Vector" d="M42.1191 35.139C43.2285 36.231 44.2588 37.7129 43.9418 39.117C44.1795 40.521 43.07 41.847 42.1191 42.939L7.6472 76.713C5.90387 78.429 3.05096 78.429 1.30753 76.713C-0.435894 74.997 -0.435796 72.189 1.30753 70.4731L34.1153 39.039L1.30763 7.52691C-0.435794 5.81098 -0.435794 3.00291 1.30763 1.28699C3.05106 -0.42894 5.90387 -0.429039 7.6472 1.28699L42.1191 35.139Z" fill="#E3E3E3"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 505 B |
BIN
public/s1-1.webp
Normal file
|
After Width: | Height: | Size: 186 KiB |
BIN
public/s1-2.webp
Normal file
|
After Width: | Height: | Size: 169 KiB |
BIN
public/s1-3.webp
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
public/s1-4.webp
Normal file
|
After Width: | Height: | Size: 142 KiB |
10
public/s1-check.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="已勾选32 12" clip-path="url(#clip0_77_98)">
|
||||
<path id="Vector" d="M3.46154 0H14.5385C15.4565 0 16.337 0.364697 16.9861 1.01386C17.6353 1.66303 18 2.54348 18 3.46154V14.5385C18 15.4565 17.6353 16.337 16.9861 16.9861C16.337 17.6353 15.4565 18 14.5385 18H3.46154C2.54348 18 1.66303 17.6353 1.01386 16.9861C0.364697 16.337 0 15.4565 0 14.5385L0 3.46154C0 2.54348 0.364697 1.66303 1.01386 1.01386C1.66303 0.364697 2.54348 0 3.46154 0ZM3.46154 1.38462C2.9107 1.38462 2.38243 1.60343 1.99293 1.99293C1.60343 2.38243 1.38462 2.9107 1.38462 3.46154V14.5385C1.38462 14.8112 1.43834 15.0813 1.54271 15.3333C1.64709 15.5852 1.80007 15.8142 1.99293 16.0071C2.18579 16.1999 2.41475 16.3529 2.66673 16.4573C2.91872 16.5617 3.18879 16.6154 3.46154 16.6154H14.5385C14.8112 16.6154 15.0813 16.5617 15.3333 16.4573C15.5852 16.3529 15.8142 16.1999 16.0071 16.0071C16.1999 15.8142 16.3529 15.5852 16.4573 15.3333C16.5617 15.0813 16.6154 14.8112 16.6154 14.5385V3.46154C16.6154 3.18879 16.5617 2.91872 16.4573 2.66673C16.3529 2.41475 16.1999 2.18579 16.0071 1.99293C15.8142 1.80007 15.5852 1.64709 15.3333 1.54271C15.0813 1.43834 14.8112 1.38462 14.5385 1.38462H3.46154ZM13.743 5.92338C13.8041 5.98151 13.8531 6.0511 13.8873 6.12818C13.9214 6.20526 13.9401 6.28831 13.9421 6.3726C13.9442 6.45689 13.9296 6.54076 13.8993 6.61941C13.8689 6.69806 13.8233 6.76996 13.7652 6.831L8.50085 12.3348C8.49877 12.3376 8.49392 12.339 8.48977 12.3432L8.48285 12.3528C8.44477 12.3902 8.39977 12.4096 8.35615 12.4359C8.32846 12.4512 8.307 12.474 8.27862 12.4858C8.20213 12.5178 8.12007 12.5345 8.03714 12.5347C7.95421 12.5349 7.87205 12.5188 7.79538 12.4872C7.77323 12.4782 7.75523 12.4588 7.73308 12.447C7.68462 12.4214 7.63477 12.3972 7.59185 12.357C7.58838 12.3542 7.587 12.3494 7.58285 12.3452C7.57938 12.3432 7.57592 12.3418 7.57315 12.339L4.92162 9.58638C4.86293 9.5258 4.81679 9.45421 4.78585 9.37574C4.75491 9.29727 4.73978 9.21346 4.74132 9.12912C4.74287 9.04479 4.76106 8.96159 4.79485 8.8843C4.82864 8.80702 4.87737 8.73717 4.93823 8.67877C4.99877 8.62 5.07035 8.57379 5.14882 8.5428C5.2273 8.5118 5.31113 8.49664 5.3955 8.49819C5.47986 8.49973 5.56308 8.51795 5.64037 8.5518C5.71766 8.58564 5.78749 8.63444 5.84585 8.69538L8.03354 10.9648L12.834 5.94415C12.8923 5.88305 12.9621 5.83404 13.0393 5.79992C13.1166 5.7658 13.1998 5.74724 13.2842 5.74532C13.3686 5.74339 13.4526 5.75812 13.5313 5.78868C13.6101 5.81923 13.682 5.86501 13.743 5.92338Z" fill="#FF6B00"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_77_98">
|
||||
<rect width="18" height="18" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
BIN
public/s2-1-1.webp
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
public/s2-1-2.webp
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
public/s2-1-3.webp
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
public/s2-1-main.webp
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
public/s2-2-1.webp
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
public/s2-2-2.webp
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
public/s2-2-3.webp
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
public/s2-2-main.webp
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/s3-main.webp
Normal file
|
After Width: | Height: | Size: 540 KiB |
@@ -1 +0,0 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 128 B |
@@ -1 +0,0 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
||||
|
Before Width: | Height: | Size: 385 B |
243
src/app/(admin)/dashboard/page.tsx
Normal file
@@ -0,0 +1,243 @@
|
||||
import {ReactNode} from 'react'
|
||||
|
||||
export type DashboardPageProps = {
|
||||
|
||||
}
|
||||
|
||||
export default function DashboardPage(props: DashboardPageProps) {
|
||||
return (
|
||||
<div className="flex gap-6">
|
||||
|
||||
{/* 左侧主要内容区域 */}
|
||||
<div className="flex-1">
|
||||
|
||||
{/* 页面标题 */}
|
||||
<div className="mb-8 bg-gradient-to-r from-blue-50 to-indigo-50 p-6 rounded-xl border border-blue-100">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="p-3 bg-blue-600 rounded-lg">
|
||||
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-gray-900">IP资源监控中心</h1>
|
||||
<p className="mt-2 text-gray-600">实时监控IP资源使用情况和系统性能指标</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 数据卡片网格 */}
|
||||
<div className="grid grid-cols-3 gap-4 mb-6">
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow transition-shadow">
|
||||
<div className="flex items-center">
|
||||
<div className="p-3 bg-blue-100 rounded-lg">
|
||||
<svg className="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="ml-4">
|
||||
<h2 className="text-sm font-medium text-gray-600">活跃IP数</h2>
|
||||
<p className="text-2xl font-semibold text-gray-900">8,721</p>
|
||||
<p className="text-sm text-green-600">↑12% 较上月</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow transition-shadow">
|
||||
<div className="flex items-center">
|
||||
<div className="p-3 bg-green-100 rounded-lg">
|
||||
<svg className="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="ml-4">
|
||||
<h2 className="text-sm font-medium text-gray-600">IP可用率</h2>
|
||||
<p className="text-2xl font-semibold text-gray-900">99.9%</p>
|
||||
<p className="text-sm text-green-600">符合SLA标准</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow transition-shadow">
|
||||
<div className="flex items-center">
|
||||
<div className="p-3 bg-purple-100 rounded-lg">
|
||||
<svg className="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="ml-4">
|
||||
<h2 className="text-sm font-medium text-gray-600">平均响应时间</h2>
|
||||
<p className="text-2xl font-semibold text-gray-900">47ms</p>
|
||||
<p className="text-sm text-green-600">优于行业标准</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 监控指标区域 */}
|
||||
<div className="grid grid-cols-2 gap-4 mb-6">
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow transition-shadow">
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-4">带宽使用趋势</h3>
|
||||
<div className="h-64 bg-gray-50 rounded-lg flex items-center justify-center">
|
||||
带宽使用量图表
|
||||
</div>
|
||||
<div className="mt-4 grid grid-cols-3 gap-4 text-center text-sm">
|
||||
<div>
|
||||
<p className="text-gray-600">当前带宽</p>
|
||||
<p className="font-semibold">1.2 Gbps</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-gray-600">峰值带宽</p>
|
||||
<p className="font-semibold">2.5 Gbps</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-gray-600">平均带宽</p>
|
||||
<p className="font-semibold">800 Mbps</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow transition-shadow">
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-4">IP地理分布</h3>
|
||||
<div className="h-64 bg-gray-50 rounded-lg flex items-center justify-center">
|
||||
地理分布热力图
|
||||
</div>
|
||||
<div className="mt-4 grid grid-cols-3 gap-4 text-center text-sm">
|
||||
<div>
|
||||
<p className="text-gray-600">亚太地区</p>
|
||||
<p className="font-semibold">45%</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-gray-600">欧美地区</p>
|
||||
<p className="font-semibold">35%</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-gray-600">其他地区</p>
|
||||
<p className="font-semibold">20%</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 告警信息 */}
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow transition-shadow">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h3 className="text-lg font-medium text-gray-900">系统告警</h3>
|
||||
<span className="text-sm text-blue-600 cursor-pointer hover:text-blue-700">查看全部</span>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center p-4 bg-red-50 rounded-lg">
|
||||
<div className="p-2 bg-red-100 rounded-lg mr-4">
|
||||
<svg className="w-5 h-5 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-sm font-medium text-red-900">带宽使用率超过阈值</h4>
|
||||
<p className="text-xs text-red-600 mt-1">5分钟前</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center p-4 bg-yellow-50 rounded-lg">
|
||||
<div className="p-2 bg-yellow-100 rounded-lg mr-4">
|
||||
<svg className="w-5 h-5 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-sm font-medium text-yellow-900">IP资源池使用率达到80%</h4>
|
||||
<p className="text-xs text-yellow-600 mt-1">20分钟前</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右侧边栏 */}
|
||||
<div className="w-80 space-y-6">
|
||||
{/* 用户信息卡片 */}
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow transition-shadow">
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="relative">
|
||||
<div className="w-14 h-14 bg-gradient-to-br from-blue-500 to-blue-600 rounded-lg flex items-center justify-center">
|
||||
<span className="text-xl font-bold text-white">A</span>
|
||||
</div>
|
||||
<div className="absolute -bottom-1 -right-1 w-4 h-4 bg-green-500 rounded-full border-2 border-white"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-gray-900">管理员</h4>
|
||||
<p className="text-sm text-gray-600">admin@example.com</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-6 pt-4 border-t border-gray-100">
|
||||
<div className="grid grid-cols-2 gap-4 text-center">
|
||||
<div className="bg-blue-50 p-3 rounded-lg">
|
||||
<p className="text-sm font-medium text-gray-600">在线时长</p>
|
||||
<p className="text-lg font-semibold text-blue-600">4.5h</p>
|
||||
</div>
|
||||
<div className="bg-green-50 p-3 rounded-lg">
|
||||
<p className="text-sm font-medium text-gray-600">处理工单</p>
|
||||
<p className="text-lg font-semibold text-green-600">12</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 快捷操作 */}
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow transition-shadow">
|
||||
<h3 className="text-lg font-semibold text-gray-900 mb-4">快捷操作</h3>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<button className="flex items-center justify-center space-x-2 bg-blue-50 text-blue-700 p-3 rounded-lg hover:bg-blue-100 transition-colors">
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
||||
</svg>
|
||||
<span>新增用户</span>
|
||||
</button>
|
||||
<button className="flex items-center justify-center space-x-2 bg-purple-50 text-purple-700 p-3 rounded-lg hover:bg-purple-100 transition-colors">
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
|
||||
</svg>
|
||||
<span>工单管理</span>
|
||||
</button>
|
||||
<button className="flex items-center justify-center space-x-2 bg-green-50 text-green-700 p-3 rounded-lg hover:bg-green-100 transition-colors">
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||
</svg>
|
||||
<span>数据报表</span>
|
||||
</button>
|
||||
<button className="flex items-center justify-center space-x-2 bg-orange-50 text-orange-700 p-3 rounded-lg hover:bg-orange-100 transition-colors">
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
<span>系统设置</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 系统公告 */}
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow transition-shadow">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h3 className="text-lg font-semibold text-gray-900">系统公告</h3>
|
||||
<span className="text-sm text-blue-600 hover:text-blue-700 cursor-pointer">全部</span>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start space-x-3">
|
||||
<div className="w-2 h-2 mt-2 bg-red-500 rounded-full"></div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-900">系统将于本周日凌晨2点进行例行维护升级</p>
|
||||
<p className="text-xs text-gray-500 mt-1">2024-01-20 10:00</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start space-x-3">
|
||||
<div className="w-2 h-2 mt-2 bg-blue-500 rounded-full"></div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-900">IP资源管理系统V2.0版本更新说明</p>
|
||||
<p className="text-xs text-gray-500 mt-1">2024-01-18 15:30</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
198
src/app/(admin)/layout.tsx
Normal file
@@ -0,0 +1,198 @@
|
||||
import Link from 'next/link'
|
||||
import {ReactNode} from 'react'
|
||||
|
||||
export type AdminLayoutProps = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export default function AdminLayout(props: AdminLayoutProps) {
|
||||
return (
|
||||
<div className="min-w-[1200px] overflow-auto bg-gray-50 flex">
|
||||
|
||||
{/* 左侧导航栏 */}
|
||||
<aside className="w-64 h-screen overflow-y-auto bg-white border-r border-gray-200">
|
||||
{/* Logo区域 */}
|
||||
<div className="h-16 flex items-center px-6">
|
||||
<svg className="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||
</svg>
|
||||
<h1 className="ml-3 text-xl font-bold text-gray-900">管理系统</h1>
|
||||
</div>
|
||||
|
||||
{/* 导航菜单 */}
|
||||
<nav className="mt-4 px-4">
|
||||
<div className="space-y-6">
|
||||
{/* 概览 */}
|
||||
<div>
|
||||
<div className="px-3 mb-2 text-xs font-medium text-gray-500 uppercase tracking-wider">概览</div>
|
||||
<Link
|
||||
href="/dashboard"
|
||||
className="flex items-center px-3 py-2 text-sm font-medium text-blue-600 bg-blue-50 rounded-md">
|
||||
<svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
|
||||
</svg>
|
||||
仪表盘
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* 用户管理 */}
|
||||
<div>
|
||||
<div className="px-3 mb-2 text-xs font-medium text-gray-500 uppercase tracking-wider">用户管理</div>
|
||||
<div className="space-y-1">
|
||||
<a
|
||||
href="/users"
|
||||
className="flex items-center px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50">
|
||||
<svg className="w-5 h-5 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/>
|
||||
</svg>
|
||||
用户列表
|
||||
</a>
|
||||
<a
|
||||
href="/users/roles"
|
||||
className="flex items-center px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50">
|
||||
<svg className="w-5 h-5 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/>
|
||||
</svg>
|
||||
角色权限
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 订单管理 */}
|
||||
<div>
|
||||
<div className="px-3 mb-2 text-xs font-medium text-gray-500 uppercase tracking-wider">订单管理</div>
|
||||
<div className="space-y-1">
|
||||
<a
|
||||
href="/orders"
|
||||
className="flex items-center px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50">
|
||||
<svg className="w-5 h-5 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
|
||||
</svg>
|
||||
订单列表
|
||||
</a>
|
||||
<a
|
||||
href="/orders/refunds"
|
||||
className="flex items-center px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50">
|
||||
<svg className="w-5 h-5 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M16 15v-1a4 4 0 00-4-4H8m0 0l3 3m-3-3l3-3m9 14V5a2 2 0 00-2-2H6a2 2 0 00-2 2v16l4-2 4 2 4-2 4 2z"/>
|
||||
</svg>
|
||||
退款管理
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 系统设置 */}
|
||||
<div>
|
||||
<div className="px-3 mb-2 text-xs font-medium text-gray-500 uppercase tracking-wider">系统设置</div>
|
||||
<a
|
||||
href="/settings"
|
||||
className="flex items-center px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50">
|
||||
<svg className="w-5 h-5 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
||||
<path
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
</svg>
|
||||
基本设置
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
{/* 右侧主内容区 */}
|
||||
<div className="flex-1 h-screen flex flex-col">
|
||||
|
||||
{/* 顶部导航栏 */}
|
||||
<header className="h-16 bg-white border-b border-gray-200 px-6 flex items-center justify-between">
|
||||
|
||||
{/* 面包屑导航 */}
|
||||
<div className="flex items-center">
|
||||
<a href="/dashboard" className="text-gray-600 hover:text-blue-600">首页</a>
|
||||
<svg className="w-4 h-4 mx-2 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7"/>
|
||||
</svg>
|
||||
<span className="text-gray-400">当前页面</span>
|
||||
</div>
|
||||
|
||||
{/* 右侧工具栏 */}
|
||||
<div className="flex items-center space-x-3">
|
||||
{/* 搜索框 */}
|
||||
<div className="w-56">
|
||||
<div className="relative">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="搜索..."
|
||||
className="w-full h-10 pl-10 pr-4 text-sm bg-gray-50 border border-gray-200 rounded-lg focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500"
|
||||
/>
|
||||
<svg
|
||||
className="w-5 h-5 text-gray-400 absolute left-3 top-2.5" fill="none" stroke="currentColor"
|
||||
viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 全屏切换 */}
|
||||
<button
|
||||
className="p-2 text-gray-500 hover:text-gray-600 hover:bg-gray-100 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{/* 通知 */}
|
||||
<button
|
||||
className="relative p-2 text-gray-500 hover:text-gray-600 hover:bg-gray-100 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
|
||||
</svg>
|
||||
<span className="absolute top-2 right-2 w-2 h-2 bg-red-500 rounded-full"></span>
|
||||
</button>
|
||||
|
||||
{/* 用户菜单 */}
|
||||
<div className="relative">
|
||||
<button
|
||||
className="flex items-center space-x-3 p-1.5 rounded-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
<img
|
||||
src="/images/avatar.jpg"
|
||||
alt="用户头像"
|
||||
className="w-9 h-9 rounded-full object-cover border-2 border-gray-200"
|
||||
/>
|
||||
<div className="text-left">
|
||||
<div className="font-medium text-gray-800">管理员</div>
|
||||
<div className="text-gray-500 text-xs">超级管理员</div>
|
||||
</div>
|
||||
<svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* 主内容区域 */}
|
||||
<main className={`flex-1 overflow-auto p-6`}>
|
||||
{props.children}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
102
src/app/(auth)/login/page.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import {ReactNode} from 'react'
|
||||
|
||||
export type LoginPageProps = {}
|
||||
|
||||
export default function LoginPage(props: LoginPageProps) {
|
||||
return (
|
||||
|
||||
<div className="flex h-screen w-screen">
|
||||
{/* 左侧背景图 */}
|
||||
<div className="relative flex-1 hidden lg:block">
|
||||
<img
|
||||
src="/images/login-bg.jpg"
|
||||
alt="登录背景"
|
||||
className="object-cover w-full h-full"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-black/30">
|
||||
<div className="flex items-center justify-center h-full">
|
||||
<h1 className="text-4xl font-bold text-white">
|
||||
欢迎回来
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右侧登录表单 */}
|
||||
<div className="w-[600px] flex items-center justify-center p-8">
|
||||
<div className="w-full space-y-8">
|
||||
<div className="text-center">
|
||||
<h2 className="text-3xl font-bold text-gray-900">
|
||||
登录您的账户
|
||||
</h2>
|
||||
<p className="mt-2 text-sm text-gray-600">
|
||||
或者{' '}
|
||||
<a href="#" className="font-medium text-blue-600 hover:text-blue-500">
|
||||
开始14天免费试用
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form className="mt-8 space-y-6">
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
|
||||
邮箱地址
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
required
|
||||
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
|
||||
密码
|
||||
</label>
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
autoComplete="current-password"
|
||||
required
|
||||
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<input
|
||||
id="remember-me"
|
||||
name="remember-me"
|
||||
type="checkbox"
|
||||
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
|
||||
/>
|
||||
<label htmlFor="remember-me" className="ml-2 block text-sm text-gray-900">
|
||||
记住我
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="text-sm">
|
||||
<a href="#" className="font-medium text-blue-600 hover:text-blue-500">
|
||||
忘记密码?
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
>
|
||||
登录
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
106
src/app/(home)/footer.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import Wrap from '@/components/wrap'
|
||||
|
||||
export type FooterProps = {}
|
||||
|
||||
export default function Footer(props: FooterProps) {
|
||||
return (
|
||||
<footer className="h-[500px] bg-gray-900 p-12 text-white overflow-hidden">
|
||||
<Wrap className="flex flex-col">
|
||||
<div className={`flex-auto overflow-hidden flex justify-between`}>
|
||||
<div className="flex">
|
||||
<div className="flex flex-col items-center">
|
||||
<img src="/logo.svg" alt="logo" className="w-44 h-44 bg-gray-100"/>
|
||||
<span className="text-sm font-light mt-6">关注我们查看更多资讯</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className={`flex flex-col gap-4`}>
|
||||
<h3>商务合作</h3>
|
||||
<p className={`text-sm text-gray-400 font-light`}>大客户经理:张经理</p>
|
||||
<p className={`text-sm text-gray-400 font-light`}>电话/微信:18751847847</p>
|
||||
<p className={`text-sm text-gray-400 font-light`}>QQ号:800180559</p>
|
||||
<h3>服务保障</h3>
|
||||
<p className={`text-sm text-gray-400 font-light`}>售前服务</p>
|
||||
<p className={`text-sm text-gray-400 font-light`}>技术支持</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>站点导航</h3>
|
||||
<ul className={`mt-4 flex flex-col gap-4 font-light`}>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>产品订购</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>获取代理</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>帮助中心</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>企业服务</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>推广返利</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>国内代理</h3>
|
||||
<ul className={`mt-4 flex flex-col gap-4 font-light`}>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>短效代理</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>长效代理</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>固定IP代理</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>全球代理</h3>
|
||||
<ul className={`mt-4 flex flex-col gap-4 font-light`}>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>动态代理</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>静态代理</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>使用案例</h3>
|
||||
<ul className={`mt-4 h-[184px] flex flex-col flex-wrap gap-4 gap-x-6 font-light`}>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>数据抓取</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>媒体矩阵</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>广告验证</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>价格监控</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>市场调研</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>金融数据</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>SEO优化</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>网站测试</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>获取代理</h3>
|
||||
<ul className={`mt-4 flex flex-col gap-4 font-light`}>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>API提取</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>代码示例</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>热门地区</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>代理资讯</h3>
|
||||
<ul className={`mt-4 flex flex-col gap-4 font-light`}>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>产品功能</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>使用教程</a></li>
|
||||
<li><a href="#" className={`text-sm text-gray-400`}>行业资讯</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={`flex-none mt-6 pt-6 border-t border-gray-300 flex flex-col items-center`}>
|
||||
<p className={`text-sm font-light`}>
|
||||
声明:啊啊HTTP仅提供代理IP服务;严禁用户使用啊啊HTTP从事任何违法犯罪行为,产生的相关责任用户自负,对此啊啊HTTP不承担任何法律责任。
|
||||
<a href="#">自律公约</a>
|
||||
</p>
|
||||
<p className={`text-sm mt-3 font-light`}>
|
||||
南京啊啊啊啊科技有限公司 版权所有网站地图
|
||||
地址:啊啊啊啊啊啊啊啊啊大街57号楚翘城7幢404-405室</p>
|
||||
<p className={`text-sm mt-3 font-light`}>
|
||||
电信业务经营许可证:B1-11111111
|
||||
苏ICP备111111111号-1
|
||||
苏公网安备11111111111111号
|
||||
</p>
|
||||
</div>
|
||||
</Wrap>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
101
src/app/(home)/header.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
'use client'
|
||||
import {ReactNode, useEffect, useState} from 'react'
|
||||
import Link from 'next/link'
|
||||
import Wrap from '@/components/wrap'
|
||||
|
||||
export type HeaderProps = {}
|
||||
|
||||
export default function Header(props: HeaderProps) {
|
||||
const [isScrolled, setIsScrolled] = useState(window.scrollY > 0)
|
||||
|
||||
const handleScroll = () => {
|
||||
setIsScrolled(window.scrollY > 0)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<header
|
||||
className={[
|
||||
`w-full h-24 fixed top-0 shadow-lg`,
|
||||
`transition-shadow duration-200 ${isScrolled ? 'bg-white' : 'bg-transparent shadow-transparent'}`,
|
||||
].join(' ')}>
|
||||
<Wrap className="flex items-center justify-between">
|
||||
{/* 菜单 */}
|
||||
<div className="flex items-center justify-between gap-8">
|
||||
{/* logo */}
|
||||
<Link href="/">
|
||||
<img alt={`logo`} className={`w-16 h-16 rounded-full bg-gray-100`}/>
|
||||
</Link>
|
||||
|
||||
{/* 菜单 */}
|
||||
<nav className={`flex items-center`}>
|
||||
<ul className="flex items-center gap-4 text-xl">
|
||||
<NavItemTop>
|
||||
<Link href={`/`}>首页</Link>
|
||||
</NavItemTop>
|
||||
<NavItemTop>
|
||||
<button>产品订购</button>
|
||||
<SvgDown/>
|
||||
</NavItemTop>
|
||||
<NavItemTop>
|
||||
<button>业务场景</button>
|
||||
<SvgDown/>
|
||||
</NavItemTop>
|
||||
<NavItemTop>
|
||||
<button>帮助中心</button>
|
||||
<SvgDown/>
|
||||
</NavItemTop>
|
||||
<NavItemTop>
|
||||
<Link href={`#`}>企业服务</Link>
|
||||
</NavItemTop>
|
||||
<NavItemTop>
|
||||
<Link href={`#`}>推广返利</Link>
|
||||
</NavItemTop>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{/* 登录 */}
|
||||
<div className={`flex items-center`}>
|
||||
<a
|
||||
href="#"
|
||||
className={`w-24 h-12 flex items-center justify-center text-xl font-medium`}>
|
||||
<span>登录</span>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className={`w-24 h-12 bg-gradient-to-r from-blue-500 to-cyan-400 rounded-sm flex items-center justify-center text-xl font-medium text-white`}>
|
||||
<span>注册</span>
|
||||
</a>
|
||||
</div>
|
||||
</Wrap>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
||||
type NavItemTopProps = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
function NavItemTop(props: NavItemTopProps) {
|
||||
return (
|
||||
<li className={`flex items-center text-xl px-2`}>
|
||||
{props.children}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
function SvgDown() {
|
||||
return (
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M6 9L12 15L18 9" stroke="currentColor" strokeWidth="2" strokeLinecap="round"
|
||||
strokeLinejoin="round"/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
240
src/app/(home)/page.tsx
Normal file
@@ -0,0 +1,240 @@
|
||||
import {ReactNode} from 'react'
|
||||
import Link from 'next/link'
|
||||
import Header from '@/app/(home)/header'
|
||||
import Wrap from '@/components/wrap'
|
||||
import Image from 'next/image'
|
||||
import Footer from './footer'
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className={`overflow-auto flex flex-col items-stretch relative`}>
|
||||
{/* 页头 */}
|
||||
<Header/>
|
||||
|
||||
{/* 正文 */}
|
||||
<main>
|
||||
|
||||
{/* banner */}
|
||||
<section className={`w-full h-[800px] bg-[url('/banner.webp')] bg-cover`}>
|
||||
<Wrap className={`overflow-hidden`}>
|
||||
<h1 className={`mt-64 text-4xl font-medium`}>安全,稳定,快速,合规的代理服务器</h1>
|
||||
<p className={`mt-10 text-gray-400`}>遍布全国的代理服务器节点为用户提供智能可靠的IP代理服务</p>
|
||||
|
||||
<div className={`mt-24 flex gap-8`}>
|
||||
<p className={`flex gap-4 items-center`}>
|
||||
<Image src={`/check.svg`} alt={`checkbox`} width={24} height={24}/>
|
||||
<span className={`text-xl font-light`}>全国200+城市节点</span>
|
||||
</p>
|
||||
<p className={`flex gap-4 items-center`}>
|
||||
<Image src={`/check.svg`} alt={`checkbox`} width={24} height={24}/>
|
||||
<span className={`text-xl font-light`}>300+城市级精准定位</span>
|
||||
</p>
|
||||
<p className={`flex gap-4 items-center`}>
|
||||
<Image src={`/check.svg`} alt={`checkbox`} width={24} height={24}/>
|
||||
<span className={`text-xl font-light`}>低延迟&高并发提取</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button className={`mt-32 w-96 h-24 bg-gradient-to-r from-blue-500 to-cyan-400 rounded-lg shadow-lg text-white text-4xl font-medium`}>
|
||||
免费试用
|
||||
</button>
|
||||
</Wrap>
|
||||
</section>
|
||||
|
||||
{/* 数据展示 */}
|
||||
<section className={`my-36`}>
|
||||
<Wrap className={`flex flex-col items-center`}>
|
||||
<h2 className={`text-3xl font-medium`}>覆盖全国的IP资源及超大的带宽线路</h2>
|
||||
<ul className={`w-full h-48 shadow-[0_0_20px_4px] shadow-blue-50 mt-24 flex`}>
|
||||
<li className={`flex-1 flex flex-col items-center justify-center`}>
|
||||
<p className={`text-xl`}>全国城市线路数量</p>
|
||||
<p className={`mt-9 text-5xl bg-gradient-to-t from-blue-500 to-cyan-400 bg-clip-text text-transparent font-bold pb-2 -mb-2`}>350+</p>
|
||||
</li>
|
||||
<li className={`flex-1 flex flex-col items-center justify-center`}>
|
||||
<p className={`text-xl`}>每日更新IP数量</p>
|
||||
<p className={`mt-9 text-5xl bg-gradient-to-t from-blue-500 to-cyan-400 bg-clip-text text-transparent font-bold pb-2 -mb-2`}>1,350,129</p>
|
||||
</li>
|
||||
<li className={`flex-1 flex flex-col items-center justify-center`}>
|
||||
<p className={`text-xl`}>用户量</p>
|
||||
<p className={`mt-9 text-5xl bg-gradient-to-t from-blue-500 to-cyan-400 bg-clip-text text-transparent font-bold pb-2 -mb-2`}>26,578</p>
|
||||
</li>
|
||||
<li className={`flex-1 flex flex-col items-center justify-center`}>
|
||||
<p className={`text-xl`}>IP可用率</p>
|
||||
<p className={`mt-9 text-5xl bg-gradient-to-t from-blue-500 to-cyan-400 bg-clip-text text-transparent font-bold pb-2 -mb-2`}>99%</p>
|
||||
</li>
|
||||
</ul>
|
||||
<img src={`/map.webp`} alt={`map`} className="w-[1200px]"/>
|
||||
</Wrap>
|
||||
</section>
|
||||
|
||||
{/* 优势 1 */}
|
||||
<section>
|
||||
<Wrap>
|
||||
<h2 className={`text-3xl font-medium text-center`}>HTTP安全合规的代理IP资源池</h2>
|
||||
<ul className={`mt-28 pt-16 pb-16 flex justify-between bg-[url('/earth.webp')] bg-cover`}>
|
||||
<li className={`p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg`}>
|
||||
<img src={`/s1-1.webp`} alt={`s1-1`} aria-hidden className="w-44 h-44 object-cover"/>
|
||||
<h3 className={`text-xl font-medium`}>短期动态IP池</h3>
|
||||
<div className={`flex flex-col gap-3`}>
|
||||
<p className={`text-sm text-gray-400 flex gap-3 items-center`}>
|
||||
<img src={`/s1-check.svg`} alt={`check`} aria-hidden className={`w-5 h-5`}/>
|
||||
<span>IP时效3-30分钟(可定制)</span>
|
||||
</p>
|
||||
<p className={`text-sm text-gray-400 flex gap-3 items-center`}>
|
||||
<img src={`/s1-check.svg`} alt={`check`} aria-hidden className={`w-5 h-5`}/>
|
||||
<span>支持高并发提取</span>
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li className={`p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg`}>
|
||||
<img src={`/s1-2.webp`} alt={`s1-1`} aria-hidden className="w-44 h-44 object-cover"/>
|
||||
<h3 className={`text-xl font-medium`}>长期静态IP池</h3>
|
||||
<div className={`flex flex-col gap-3`}>
|
||||
<p className={`text-sm text-gray-400 flex gap-3 items-center`}>
|
||||
<img src={`/s1-check.svg`} alt={`check`} aria-hidden className={`w-5 h-5`}/>
|
||||
<span>IP覆盖全国各地</span>
|
||||
</p>
|
||||
<p className={`text-sm text-gray-400 flex gap-3 items-center`}>
|
||||
<img src={`/s1-check.svg`} alt={`check`} aria-hidden className={`w-5 h-5`}/>
|
||||
<span>平均响应时长:0.03s</span>
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li className={`p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg`}>
|
||||
<img src={`/s1-3.webp`} alt={`s1-1`} aria-hidden className="w-44 h-44 object-cover"/>
|
||||
<h3 className={`text-xl font-medium`}>固定IP池</h3>
|
||||
<div className={`flex flex-col gap-3`}>
|
||||
<p className={`text-sm text-gray-400 flex gap-3 items-center`}>
|
||||
<img src={`/s1-check.svg`} alt={`check`} aria-hidden className={`w-5 h-5`}/>
|
||||
<span>稳定长输不掉线</span>
|
||||
</p>
|
||||
<p className={`text-sm text-gray-400 flex gap-3 items-center`}>
|
||||
<img src={`/s1-check.svg`} alt={`check`} aria-hidden className={`w-5 h-5`}/>
|
||||
<span>全国热门静态IP线路</span>
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li className={`p-8 flex flex-col gap-5 shadow-[4px_4px_20px_4px] shadow-blue-50 bg-white rounded-lg`}>
|
||||
<img src={`/s1-4.webp`} alt={`s1-1`} aria-hidden className="w-44 h-44 object-cover"/>
|
||||
<h3 className={`text-xl font-medium`}>企业级定制池</h3>
|
||||
<div className={`flex flex-col gap-3`}>
|
||||
<p className={`text-sm text-gray-400 flex gap-3 items-center`}>
|
||||
<img src={`/s1-check.svg`} alt={`check`} aria-hidden className={`w-5 h-5`}/>
|
||||
<span>可视化监控设计</span>
|
||||
</p>
|
||||
<p className={`text-sm text-gray-400 flex gap-3 items-center`}>
|
||||
<img src={`/s1-check.svg`} alt={`check`} aria-hidden className={`w-5 h-5`}/>
|
||||
<span>技术团队现场支持</span>
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</Wrap>
|
||||
</section>
|
||||
|
||||
{/* 优势 2 */}
|
||||
<section className={`mt-28 flex flex-col gap-24`}>
|
||||
<Wrap>
|
||||
<h2 className={`text-3xl text-center font-medium`}>HTTP 产品优势</h2>
|
||||
|
||||
<div className={`mt-24 flex gap-36`}>
|
||||
<ul className={`flex-auto flex flex-col gap-6`}>
|
||||
<li className={`flex gap-14 items-center pl-20 h-48 shadow-[4px_4px_20px_4px] shadow-blue-50 rounded-lg`}>
|
||||
<img src={`/s2-1-1.webp`} alt={`s2-1-1`} aria-hidden className="w-24 h-24 object-contain"/>
|
||||
<div className={`flex flex-col gap-3`}>
|
||||
<h3 className={`text-xl font-medium`}>安全合规</h3>
|
||||
<p>国内三大运营商支持</p>
|
||||
</div>
|
||||
</li>
|
||||
<li className={`flex gap-14 items-center pl-20 h-48 shadow-[4px_4px_20px_4px] shadow-blue-50 rounded-lg`}>
|
||||
<img src={`/s2-1-2.webp`} alt={`s2-1-1`} aria-hidden className="w-24 h-24 object-contain"/>
|
||||
<div className={`flex flex-col gap-3`}>
|
||||
<h3 className={`text-xl font-medium`}>稳定链接</h3>
|
||||
<p>IP纯净度高达99.9%</p>
|
||||
</div>
|
||||
</li>
|
||||
<li className={`flex gap-14 items-center pl-20 h-48 shadow-[4px_4px_20px_4px] shadow-blue-50 rounded-lg`}>
|
||||
<img src={`/s2-1-3.webp`} alt={`s2-1-1`} aria-hidden className="w-24 h-24 object-contain"/>
|
||||
<div className={`flex flex-col gap-3`}>
|
||||
<h3 className={`text-xl font-medium`}>超匿名性</h3>
|
||||
<p>稳定传输,保护隐私安全</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<img src={`/s2-2-main.webp`} alt={`s2-1-main`} className={`w-[600px] h-[600px] object-contain flex-none`}/>
|
||||
</div>
|
||||
|
||||
<div className={`flex gap-36 mt-24`}>
|
||||
<img src={`/s2-2-main.webp`} alt={`s2-1-main`} className={`w-[600px] h-[600px] object-contain`}/>
|
||||
<ul className={`flex-auto flex flex-col gap-6`}>
|
||||
<li className={`flex gap-14 items-center pl-20 h-48 shadow-[4px_4px_20px_4px] shadow-blue-50 rounded-lg`}>
|
||||
<img src={`/s2-2-1.webp`} alt={`s2-1-1`} aria-hidden className="w-24 h-24 object-cover"/>
|
||||
<div className={`flex flex-col gap-3`}>
|
||||
<h3 className={`text-xl font-medium`}>API接口文档</h3>
|
||||
<p>与第三方软件轻松集成</p>
|
||||
</div>
|
||||
</li>
|
||||
<li className={`flex gap-14 items-center pl-20 h-48 shadow-[4px_4px_20px_4px] shadow-blue-50 rounded-lg`}>
|
||||
<img src={`/s2-2-2.webp`} alt={`s2-1-1`} aria-hidden className="w-24 h-24 object-cover"/>
|
||||
<div className={`flex flex-col gap-3`}>
|
||||
<h3 className={`text-xl font-medium`}>多种编程语言代码</h3>
|
||||
<p>C语言、GO语言、Python...</p>
|
||||
</div>
|
||||
</li>
|
||||
<li className={`flex gap-14 items-center pl-20 h-48 shadow-[4px_4px_20px_4px] shadow-blue-50 rounded-lg`}>
|
||||
<img src={`/s2-2-3.webp`} alt={`s2-1-1`} aria-hidden className="w-24 h-24 object-cover"/>
|
||||
<div className={`flex flex-col gap-3`}>
|
||||
<h3 className={`text-xl font-medium`}>双重认证方式</h3>
|
||||
<p>API提取+账密认证</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Wrap>
|
||||
</section>
|
||||
|
||||
{/* 行业资讯 */}
|
||||
<section className={`mt-44 mb-32 flex flex-col`}>
|
||||
<Wrap>
|
||||
|
||||
<h2 className={`text-center text-3xl font-medium`}>行业资讯</h2>
|
||||
|
||||
<div className={`mt-24 flex gap-20`}>
|
||||
<button className={`px-4`}>
|
||||
<img src={`/next.svg`} alt={`prev`} className={`rotate-180`}/>
|
||||
</button>
|
||||
|
||||
<div className={`flex p-14 gap-14 shadow-[4px_4px_20px_4px] shadow-blue-50 rounded-lg]`}>
|
||||
<img src="/s3-main.webp" alt="tumb" className={`flex-none w-[350px] h-[270px] object-cover`}/>
|
||||
<div className={`flex flex-col justify-between`}>
|
||||
<h3 className={`flex justify-between`}>
|
||||
<span className={`text-xl font-medium`}>我是标题</span>
|
||||
<sub className={`text-sm text-gray-400`}>2025-03-04</sub>
|
||||
</h3>
|
||||
<p className={`text-gray-400 leading-12`}>
|
||||
我是内容我是内容我是内容我是内容我是内容我是容我是内容我是内容内容我是内容我是内容我是内我是内容我是内容我是内容我是内容我是内容...
|
||||
</p>
|
||||
<div className={`flex justify-end`}>
|
||||
<a href="#" className={`text-sm text-gray-400 flex items-center gap-5`}>
|
||||
更多详情
|
||||
<img src={`/next.svg`} alt={`more`} className={`h-4 fill-gray-400`}/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button className={`px-4`}>
|
||||
<img src={`/next.svg`} alt={`prev`} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
</Wrap>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
{/* 页脚 */}
|
||||
<Footer/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
BIN
src/app/SourceHanSansSC-VF.otf.woff2
Normal file
@@ -1,26 +1,5 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
color: hsl(0, 0%, 20%);
|
||||
}
|
||||
|
||||
@@ -1,34 +1,25 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import {ReactNode} from 'react'
|
||||
import {Metadata} from 'next'
|
||||
import './globals.css'
|
||||
import localFont from 'next/font/local'
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
const font = localFont({src: './SourceHanSansSC-VF.otf.woff2'})
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
};
|
||||
title: 'Create Next App',
|
||||
description: 'Generated by create next app',
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
children: ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
<html lang="zh-Cn">
|
||||
<body className={font.className}>
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
101
src/app/page.tsx
@@ -1,101 +0,0 @@
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
|
||||
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
|
||||
<Image
|
||||
className="dark:invert"
|
||||
src="/next.svg"
|
||||
alt="Next.js logo"
|
||||
width={180}
|
||||
height={38}
|
||||
priority
|
||||
/>
|
||||
<ol className="list-inside list-decimal text-sm text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
|
||||
<li className="mb-2">
|
||||
Get started by editing{" "}
|
||||
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-semibold">
|
||||
src/app/page.tsx
|
||||
</code>
|
||||
.
|
||||
</li>
|
||||
<li>Save and see your changes instantly.</li>
|
||||
</ol>
|
||||
|
||||
<div className="flex gap-4 items-center flex-col sm:flex-row">
|
||||
<a
|
||||
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5"
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
className="dark:invert"
|
||||
src="/vercel.svg"
|
||||
alt="Vercel logomark"
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
Deploy now
|
||||
</a>
|
||||
<a
|
||||
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:min-w-44"
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Read our docs
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
<footer className="row-start-3 flex gap-6 flex-wrap items-center justify-center">
|
||||
<a
|
||||
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
aria-hidden
|
||||
src="/file.svg"
|
||||
alt="File icon"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
Learn
|
||||
</a>
|
||||
<a
|
||||
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
aria-hidden
|
||||
src="/window.svg"
|
||||
alt="Window icon"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
Examples
|
||||
</a>
|
||||
<a
|
||||
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
aria-hidden
|
||||
src="/globe.svg"
|
||||
alt="Globe icon"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
Go to nextjs.org →
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
14
src/components/wrap.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import {ReactNode} from 'react'
|
||||
|
||||
export type WrapProps = {
|
||||
children: ReactNode
|
||||
className?: string
|
||||
}
|
||||
|
||||
export default function Wrap(props: WrapProps) {
|
||||
return (
|
||||
<div className={`w-[1200px] h-full mx-auto ${props.className}`}>
|
||||
{props.children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||