pref: update index page

This commit is contained in:
thehrz 2024-08-16 23:32:19 +08:00
parent cac0d0d257
commit 804c597d0e
Signed by: thehrz
GPG Key ID: C84CBCE7D5F88855
13 changed files with 211 additions and 138 deletions

7
.dockerignore Normal file
View File

@ -0,0 +1,7 @@
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git

32
Dockerfile Normal file
View File

@ -0,0 +1,32 @@
FROM node:20-alpine as build-stage
WORKDIR /app
RUN corepack enable
COPY .npmrc package.json pnpm-lock.yaml ./
RUN --mount=type=cache,id=pnpm-store,target=/root/.pnpm-store \
pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
FROM node:20-alpine as production-stage
WORKDIR /srv/ipv6-test
ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=build-stage /app/public ./public
COPY --from=build-stage --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=build-stage --chown=nextjs:nodejs /app/.next/static ./.next/static
RUN chown nextjs:nodejs .next
USER nextjs
EXPOSE 3000
CMD ["nginx", "-g", "daemon off;"]

20
docker-compose.yml Normal file
View File

@ -0,0 +1,20 @@
version: "3.9"
networks:
traefik:
name: traefik
external: true
services:
ipv6-test:
build: .
container_name: ipv6-test
restart: always
labels:
- traefik.enable=true
- traefik.http.routers.ipv6-test.rule=Host(`ipv6.thehrz.net`)
- traefik.http.routers.ipv6-test.entrypoints=web,websecure
- traefik.http.routers.ipv6-test.tls.certresolver=letsencrypt
- traefik.http.services.ipv6-test.loadbalancer.server.port=3000
networks:
- traefik

View File

@ -1,4 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
const nextConfig = {
output: 'standalone',
}
export default nextConfig;

View File

@ -9,18 +9,20 @@
"lint": "next lint"
},
"dependencies": {
"next": "14.2.5",
"react": "^18",
"react-dom": "^18",
"next": "14.2.5"
"theme-change": "^2.5.0"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"daisyui": "^4.12.10",
"eslint": "^8",
"eslint-config-next": "14.2.5",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"eslint": "^8",
"eslint-config-next": "14.2.5"
"typescript": "^5"
}
}

View File

@ -17,6 +17,9 @@ importers:
react-dom:
specifier: ^18
version: 18.3.1(react@18.3.1)
theme-change:
specifier: ^2.5.0
version: 2.5.0
devDependencies:
'@types/node':
specifier: ^20
@ -27,6 +30,9 @@ importers:
'@types/react-dom':
specifier: ^18
version: 18.3.0
daisyui:
specifier: ^4.12.10
version: 4.12.10(postcss@8.4.41)
eslint:
specifier: ^8
version: 8.57.0
@ -396,6 +402,9 @@ packages:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
css-selector-tokenizer@0.8.0:
resolution: {integrity: sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==}
cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
@ -404,6 +413,14 @@ packages:
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
culori@3.3.0:
resolution: {integrity: sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
daisyui@4.12.10:
resolution: {integrity: sha512-jp1RAuzbHhGdXmn957Z2XsTZStXGHzFfF0FgIOZj3Wv9sH7OZgLfXTRZNfKVYxltGUOBsG1kbWAdF5SrqjebvA==}
engines: {node: '>=16.9.0'}
damerau-levenshtein@1.0.8:
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
@ -634,6 +651,9 @@ packages:
fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
fastparse@1.1.2:
resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==}
fastq@1.17.1:
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
@ -1404,6 +1424,9 @@ packages:
text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
theme-change@2.5.0:
resolution: {integrity: sha512-B/UdsgdHAGhSKHTAQnxg/etN0RaMDpehuJmZIjLMDVJ6DGIliRHGD6pODi1CXLQAN9GV0GSyB3G6yCuK05PkPQ==}
thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
@ -1883,10 +1906,26 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
css-selector-tokenizer@0.8.0:
dependencies:
cssesc: 3.0.0
fastparse: 1.1.2
cssesc@3.0.0: {}
csstype@3.1.3: {}
culori@3.3.0: {}
daisyui@4.12.10(postcss@8.4.41):
dependencies:
css-selector-tokenizer: 0.8.0
culori: 3.3.0
picocolors: 1.0.1
postcss-js: 4.0.1(postcss@8.4.41)
transitivePeerDependencies:
- postcss
damerau-levenshtein@1.0.8: {}
data-view-buffer@1.0.1:
@ -2091,7 +2130,7 @@ snapshots:
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0)
eslint-plugin-react: 7.35.0(eslint@8.57.0)
eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0)
@ -2115,7 +2154,7 @@ snapshots:
enhanced-resolve: 5.17.1
eslint: 8.57.0
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
fast-glob: 3.3.2
get-tsconfig: 4.7.6
is-core-module: 2.15.0
@ -2137,7 +2176,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
dependencies:
array-includes: 3.1.8
array.prototype.findlastindex: 1.2.5
@ -2292,6 +2331,8 @@ snapshots:
fast-levenshtein@2.0.6: {}
fastparse@1.1.2: {}
fastq@1.17.1:
dependencies:
reusify: 1.0.4
@ -3108,6 +3149,8 @@ snapshots:
text-table@0.2.0: {}
theme-change@2.5.0: {}
thenify-all@1.6.0:
dependencies:
thenify: 3.3.1

View File

@ -0,0 +1,5 @@
import { NextRequest, NextResponse } from "next/server"
export async function GET(request: NextRequest) {
return NextResponse.json(request.ip + "")
}

View File

@ -2,7 +2,7 @@
@tailwind components;
@tailwind utilities;
:root {
/* :root {
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
@ -30,4 +30,4 @@ body {
.text-balance {
text-wrap: balance;
}
}
} */

View File

@ -1,22 +1,30 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import type { Metadata } from "next"
import { Inter } from "next/font/google"
import "./globals.css"
import Nav from "@/components/Nav"
import Footer from "@/components/Footer"
const inter = Inter({ subsets: ["latin"] });
const inter = Inter({ subsets: ["latin"] })
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
title: "IPv6 测试",
description: "IPv6 测试",
}
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
children: React.ReactNode
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
<html lang='zh'>
<body className={inter.className}>
<main className='min-h-screen flex flex-col'>
<Nav />
{children}
<Footer />
</main>
</body>
</html>
);
)
}

View File

@ -1,113 +1,22 @@
import Image from "next/image";
"use client"
import Nav from "@/components/Nav"
import { useEffect } from "react"
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex">
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
Get started by editing&nbsp;
<code className="font-mono font-bold">src/app/page.tsx</code>
</p>
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:size-auto lg:bg-none">
<a
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
By{" "}
<Image
src="/vercel.svg"
alt="Vercel Logo"
className="dark:invert"
width={100}
height={24}
priority
/>
</a>
<div className="max-w-full flex justify-center m-auto">
<div className='hero-content text-center'>
<div className='max-w-md'>
<h1 className='text-5xl font-bold'>IPv6-test</h1>
<p className='py-6'>
IPv6测试服务
</p>
<button className='btn btn-primary'></button>
</div>
</div>
<div className="relative z-[-1] flex place-items-center before:absolute before:h-[300px] before:w-full before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-full after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 sm:before:w-[480px] sm:after:w-[240px] before:lg:h-[360px]">
<Image
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
src="/next.svg"
alt="Next.js Logo"
width={180}
height={37}
priority
/>
</div>
<div className="mb-32 grid text-center lg:mb-0 lg:w-full lg:max-w-5xl lg:grid-cols-4 lg:text-left">
<a
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
target="_blank"
rel="noopener noreferrer"
>
<h2 className="mb-3 text-2xl font-semibold">
Docs{" "}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className="m-0 max-w-[30ch] text-sm opacity-50">
Find in-depth information about Next.js features and API.
</p>
</a>
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
target="_blank"
rel="noopener noreferrer"
>
<h2 className="mb-3 text-2xl font-semibold">
Learn{" "}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className="m-0 max-w-[30ch] text-sm opacity-50">
Learn about Next.js in an interactive course with&nbsp;quizzes!
</p>
</a>
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
target="_blank"
rel="noopener noreferrer"
>
<h2 className="mb-3 text-2xl font-semibold">
Templates{" "}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className="m-0 max-w-[30ch] text-sm opacity-50">
Explore starter templates for Next.js.
</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
target="_blank"
rel="noopener noreferrer"
>
<h2 className="mb-3 text-2xl font-semibold">
Deploy{" "}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className="m-0 max-w-[30ch] text-balance text-sm opacity-50">
Instantly deploy your Next.js site to a shareable URL with Vercel.
</p>
</a>
</div>
</main>
);
</div>
)
}

12
src/components/Footer.tsx Normal file
View File

@ -0,0 +1,12 @@
export default function Footer() {
return (
<footer className='footer footer-center bg-base-300 text-base-content p-4'>
<aside>
<p>
Copyright © {new Date().getFullYear()} - All right reserved by ACME
Industries Ltd
</p>
</aside>
</footer>
)
}

29
src/components/Nav.tsx Normal file
View File

@ -0,0 +1,29 @@
export default function Nav() {
return (
<div className='navbar bg-base-200 px-5 border'>
<div className='flex-1'>
<a className='text-xl'>ipv6-test IPv6 </a>
</div>
<div className='flex-none'>
<ul className='menu menu-horizontal px-1'>
<li>
<a>Link</a>
</li>
<li>
<details>
<summary>Parent</summary>
<ul className='bg-base-100 rounded-t-none p-2'>
<li>
<a>Link 1</a>
</li>
<li>
<a>Link 2</a>
</li>
</ul>
</details>
</li>
</ul>
</div>
</div>
)
}

View File

@ -1,4 +1,5 @@
import type { Config } from "tailwindcss";
import type { Config } from "tailwindcss"
import daisyui from "daisyui"
const config: Config = {
content: [
@ -6,15 +7,18 @@ const config: Config = {
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
backgroundImage: {
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
"gradient-conic":
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
},
},
// theme: {
// extend: {
// backgroundImage: {
// "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
// "gradient-conic":
// "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
// },
// },
// },
plugins: [daisyui],
daisyui: {
themes: ["light"],
},
plugins: [],
};
export default config;