style: 优化样式
This commit is contained in:
parent
b35c692998
commit
910bd2d4dc
@ -1,11 +1,24 @@
|
|||||||
'use client';
|
"use client";
|
||||||
import { signout } from '@/app/lib/actions';
|
import { signout } from "@/app/lib/actions/auth";
|
||||||
|
import { usePathname } from "next/navigation";
|
||||||
export default function SignoutButton() {
|
|
||||||
return <button onClick={async () => {
|
|
||||||
|
|
||||||
|
export default function SignoutButton({
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
className: string | undefined;
|
||||||
|
}) {
|
||||||
|
const pathname = usePathname();
|
||||||
|
if (pathname.match("/signin") || pathname.match("/signup")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className={className}
|
||||||
|
onClick={async () => {
|
||||||
await signout();
|
await signout();
|
||||||
}}>
|
}}
|
||||||
注销
|
>
|
||||||
|
注销
|
||||||
</button>
|
</button>
|
||||||
};
|
);
|
||||||
|
}
|
||||||
|
258
app/layout.tsx
258
app/layout.tsx
@ -1,6 +1,7 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Inter } from "next/font/google";
|
import { Inter } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
import SignoutButton from "./components/signout-button";
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
@ -16,7 +17,262 @@ export default function RootLayout({
|
|||||||
}>) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<html lang="zh_CN" data-theme="light">
|
<html lang="zh_CN" data-theme="light">
|
||||||
<body className={inter.className}>{children}</body>
|
<body className={inter.className}>
|
||||||
|
<header className="text-gray-600 body-font">
|
||||||
|
<div className="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center">
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="flex title-font font-medium items-center text-gray-900 mb-4 md:mb-0"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
className="w-10 h-10 text-white p-2 bg-indigo-500 rounded-full"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>
|
||||||
|
</svg>
|
||||||
|
<span className="ml-3 text-xl">音乐弹幕</span>
|
||||||
|
</a>
|
||||||
|
<nav className="md:ml-auto md:mr-auto flex flex-wrap items-center text-base justify-center">
|
||||||
|
<a href="#" className="mr-5 hover:text-gray-900">
|
||||||
|
First Link
|
||||||
|
</a>
|
||||||
|
<a href="#" className="mr-5 hover:text-gray-900">
|
||||||
|
Second Link
|
||||||
|
</a>
|
||||||
|
<a href="#" className="mr-5 hover:text-gray-900">
|
||||||
|
Third Link
|
||||||
|
</a>
|
||||||
|
<a href="#" className="mr-5 hover:text-gray-900">
|
||||||
|
Fourth Link
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<SignoutButton className="inline-flex items-center bg-gray-100 border-0 py-1 px-3 focus:outline-none hover:bg-gray-200 rounded text-base mt-4 md:mt-0" />
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main className="min-h-[50vh]">{children}</main>
|
||||||
|
<footer className="text-gray-600 body-font">
|
||||||
|
<div className="container px-5 py-24 mx-auto flex md:items-center lg:items-start md:flex-row md:flex-nowrap flex-wrap flex-col">
|
||||||
|
<div className="w-64 flex-shrink-0 md:mx-0 mx-auto text-center md:text-left">
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="flex title-font font-medium items-center md:justify-start justify-center text-gray-900"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
className="w-10 h-10 text-white p-2 bg-indigo-500 rounded-full"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>
|
||||||
|
</svg>
|
||||||
|
<span className="ml-3 text-xl">Tailblocks</span>
|
||||||
|
</a>
|
||||||
|
<p className="mt-2 text-sm text-gray-500">
|
||||||
|
Air plant banjo lyft occupy retro adaptogen indego
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex-grow flex flex-wrap md:pl-20 -mb-10 md:mt-0 mt-10 md:text-left text-center">
|
||||||
|
<div className="lg:w-1/4 md:w-1/2 w-full px-4">
|
||||||
|
<h2 className="title-font font-medium text-gray-900 tracking-widest text-sm mb-3">
|
||||||
|
CATEGORIES
|
||||||
|
</h2>
|
||||||
|
<nav className="list-none mb-10">
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
First Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Second Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Third Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Fourth Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div className="lg:w-1/4 md:w-1/2 w-full px-4">
|
||||||
|
<h2 className="title-font font-medium text-gray-900 tracking-widest text-sm mb-3">
|
||||||
|
CATEGORIES
|
||||||
|
</h2>
|
||||||
|
<nav className="list-none mb-10">
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
First Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Second Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Third Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Fourth Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div className="lg:w-1/4 md:w-1/2 w-full px-4">
|
||||||
|
<h2 className="title-font font-medium text-gray-900 tracking-widest text-sm mb-3">
|
||||||
|
CATEGORIES
|
||||||
|
</h2>
|
||||||
|
<nav className="list-none mb-10">
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
First Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Second Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Third Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Fourth Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div className="lg:w-1/4 md:w-1/2 w-full px-4">
|
||||||
|
<h2 className="title-font font-medium text-gray-900 tracking-widest text-sm mb-3">
|
||||||
|
CATEGORIES
|
||||||
|
</h2>
|
||||||
|
<nav className="list-none mb-10">
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
First Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Second Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Third Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" className="text-gray-600 hover:text-gray-800">
|
||||||
|
Fourth Link
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="bg-gray-100">
|
||||||
|
<div className="container mx-auto py-4 px-5 flex flex-wrap flex-col sm:flex-row">
|
||||||
|
<p className="text-gray-500 text-sm text-center sm:text-left">
|
||||||
|
© 2024 音乐弹幕 —
|
||||||
|
<a
|
||||||
|
href="https://github.com/sealday"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-gray-600 ml-1"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
@sealday
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<span className="inline-flex sm:ml-auto sm:mt-0 mt-2 justify-center sm:justify-start">
|
||||||
|
<a href="#" className="text-gray-500">
|
||||||
|
<svg
|
||||||
|
fill="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
className="w-5 h-5"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a href="#" className="ml-3 text-gray-500">
|
||||||
|
<svg
|
||||||
|
fill="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
className="w-5 h-5"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M23 3a10.9 10.9 0 01-3.14 1.53 4.48 4.48 0 00-7.86 3v1A10.66 10.66 0 013 4s-4 9 5 13a11.64 11.64 0 01-7 2c9 5 20 0 20-11.5a4.5 4.5 0 00-.08-.83A7.72 7.72 0 0023 3z"></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a href="#" className="ml-3 text-gray-500">
|
||||||
|
<svg
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
className="w-5 h-5"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<rect
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
x="2"
|
||||||
|
y="2"
|
||||||
|
rx="5"
|
||||||
|
ry="5"
|
||||||
|
></rect>
|
||||||
|
<path d="M16 11.37A4 4 0 1112.63 8 4 4 0 0116 11.37zm1.5-4.87h.01"></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a href="#" className="ml-3 text-gray-500">
|
||||||
|
<svg
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="0"
|
||||||
|
className="w-5 h-5"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke="none"
|
||||||
|
d="M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2z"
|
||||||
|
></path>
|
||||||
|
<circle cx="4" cy="4" r="2" stroke="none"></circle>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
'use server';
|
|
||||||
import { redirect } from 'next/navigation'
|
|
||||||
import { cookies } from 'next/headers'
|
|
||||||
|
|
||||||
const SIGNUP_URL = 'https://tachy.daoyoucloud.com/api/auth:signUp';
|
|
||||||
const SIGNIN_URL = 'https://tachy.daoyoucloud.com/api/auth:signIn';
|
|
||||||
const SIGNOUT_URL = 'https://tachy.daoyoucloud.com/api/auth:signOut'
|
|
||||||
|
|
||||||
|
|
||||||
export async function signout() {
|
|
||||||
const token = cookies().get('token');
|
|
||||||
const result = await fetch(SIGNOUT_URL, {
|
|
||||||
"headers": {
|
|
||||||
"authorization": "Bearer " + token?.value,
|
|
||||||
"cache-control": "no-cache",
|
|
||||||
"pragma": "no-cache",
|
|
||||||
"x-app": "danmu-sim",
|
|
||||||
"x-authenticator": "basic",
|
|
||||||
"x-locale": "zh-CN",
|
|
||||||
"x-timezone": "+08:00",
|
|
||||||
"x-with-acl-meta": "true",
|
|
||||||
},
|
|
||||||
"body": '',
|
|
||||||
"method": "POST"
|
|
||||||
});
|
|
||||||
cookies().delete('token');
|
|
||||||
redirect('/signin');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export async function signin(_currentState: unknown, formData: FormData) {
|
|
||||||
const result = await fetch(SIGNIN_URL, {
|
|
||||||
"headers": {
|
|
||||||
"cache-control": "no-cache",
|
|
||||||
"content-type": "application/json",
|
|
||||||
"pragma": "no-cache",
|
|
||||||
"x-app": "danmu-sim",
|
|
||||||
"x-authenticator": "basic",
|
|
||||||
"x-hostname": "tachy.daoyoucloud.com",
|
|
||||||
"x-locale": "zh-CN",
|
|
||||||
"x-timezone": "+08:00",
|
|
||||||
"x-with-acl-meta": "true",
|
|
||||||
},
|
|
||||||
"body": JSON.stringify(Object.fromEntries(formData)),
|
|
||||||
"method": "POST"
|
|
||||||
});
|
|
||||||
const res = await result.json();
|
|
||||||
if (res.errors) {
|
|
||||||
return res.errors[0].message;
|
|
||||||
}
|
|
||||||
cookies().set('token', res.data.token);
|
|
||||||
redirect('/');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function signup(_currentState: unknown, formData: FormData) {
|
|
||||||
const result = await fetch(SIGNUP_URL, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-App': 'danmu-sim',
|
|
||||||
"content-type": "application/json",
|
|
||||||
"x-authenticator": "basic",
|
|
||||||
"x-locale": "zh-CN",
|
|
||||||
"x-timezone": "+08:00",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(Object.fromEntries(formData))
|
|
||||||
})
|
|
||||||
const response = await result.json();
|
|
||||||
if (response.errors) {
|
|
||||||
return response.errors[0].message;
|
|
||||||
}
|
|
||||||
}
|
|
70
app/lib/actions/auth.ts
Normal file
70
app/lib/actions/auth.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
"use server";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
import { cookies } from "next/headers";
|
||||||
|
|
||||||
|
const SIGNUP_URL = "https://tachy.daoyoucloud.com/api/auth:signUp";
|
||||||
|
const SIGNIN_URL = "https://tachy.daoyoucloud.com/api/auth:signIn";
|
||||||
|
const SIGNOUT_URL = "https://tachy.daoyoucloud.com/api/auth:signOut";
|
||||||
|
|
||||||
|
export async function signout() {
|
||||||
|
const token = cookies().get("token");
|
||||||
|
const result = await fetch(SIGNOUT_URL, {
|
||||||
|
headers: {
|
||||||
|
authorization: "Bearer " + token?.value,
|
||||||
|
"cache-control": "no-cache",
|
||||||
|
pragma: "no-cache",
|
||||||
|
"x-app": "danmu-sim",
|
||||||
|
"x-authenticator": "basic",
|
||||||
|
"x-locale": "zh-CN",
|
||||||
|
"x-timezone": "+08:00",
|
||||||
|
"x-with-acl-meta": "true",
|
||||||
|
},
|
||||||
|
body: "",
|
||||||
|
method: "POST",
|
||||||
|
});
|
||||||
|
cookies().delete("token");
|
||||||
|
redirect("/signin");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function signin(_currentState: unknown, formData: FormData) {
|
||||||
|
const result = await fetch(SIGNIN_URL, {
|
||||||
|
headers: {
|
||||||
|
"cache-control": "no-cache",
|
||||||
|
"content-type": "application/json",
|
||||||
|
pragma: "no-cache",
|
||||||
|
"x-app": "danmu-sim",
|
||||||
|
"x-authenticator": "basic",
|
||||||
|
"x-hostname": "tachy.daoyoucloud.com",
|
||||||
|
"x-locale": "zh-CN",
|
||||||
|
"x-timezone": "+08:00",
|
||||||
|
"x-with-acl-meta": "true",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(Object.fromEntries(formData)),
|
||||||
|
method: "POST",
|
||||||
|
});
|
||||||
|
const res = await result.json();
|
||||||
|
if (res.errors) {
|
||||||
|
return res.errors[0].message;
|
||||||
|
}
|
||||||
|
cookies().set("token", res.data.token);
|
||||||
|
redirect("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function signup(_currentState: unknown, formData: FormData) {
|
||||||
|
const result = await fetch(SIGNUP_URL, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"X-App": "danmu-sim",
|
||||||
|
"content-type": "application/json",
|
||||||
|
"x-authenticator": "basic",
|
||||||
|
"x-locale": "zh-CN",
|
||||||
|
"x-timezone": "+08:00",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(Object.fromEntries(formData)),
|
||||||
|
});
|
||||||
|
const response = await result.json();
|
||||||
|
if (response.errors) {
|
||||||
|
return response.errors[0].message;
|
||||||
|
}
|
||||||
|
redirect("/signin");
|
||||||
|
}
|
1
app/music.svg
Normal file
1
app/music.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 204 KiB |
158
app/page.tsx
158
app/page.tsx
@ -1,124 +1,44 @@
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import SignoutButton from "@/app/components/signout-button";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import musicSvg from "@/app/music.svg";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return <main>
|
return (
|
||||||
<SignoutButton />
|
<section className="text-gray-600 body-font">
|
||||||
<Link className="btn" href="/music">弹幕测试</Link>
|
<div className="container mx-auto flex px-5 py-24 md:flex-row flex-col items-center">
|
||||||
</main>
|
<div className="lg:flex-grow md:w-1/2 lg:pr-24 md:pr-16 flex flex-col md:items-start md:text-left mb-16 md:mb-0 items-center text-center">
|
||||||
|
<h1 className="title-font sm:text-4xl text-3xl mb-4 font-medium text-gray-900">
|
||||||
|
Before they sold out
|
||||||
|
<br className="hidden lg:inline-block" />
|
||||||
|
readymade gluten
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="mb-8 leading-relaxed">
|
||||||
|
Copper mug try-hard pitchfork pour-over freegan heirloom neutra air
|
||||||
|
plant cold-pressed tacos poke beard tote bag. Heirloom echo park
|
||||||
|
mlkshk tote bag selvage hot chicken authentic tumeric truffaut
|
||||||
|
hexagon try-hard chambray.
|
||||||
|
</p>
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<Link
|
||||||
|
href="/music"
|
||||||
|
className="inline-flex text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
|
||||||
|
>
|
||||||
|
弹幕测试
|
||||||
|
</Link>
|
||||||
|
<button className="ml-4 inline-flex text-gray-700 bg-gray-100 border-0 py-2 px-6 focus:outline-none hover:bg-gray-200 rounded text-lg">
|
||||||
|
Button
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="lg:max-w-lg lg:w-full md:w-1/2 w-5/6">
|
||||||
|
<Image
|
||||||
|
className="object-cover object-center rounded"
|
||||||
|
alt="hero"
|
||||||
|
src={musicSvg}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// export default function Home() {
|
|
||||||
// return (
|
|
||||||
// <main className="flex min-h-screen flex-col items-center justify-between p-24">
|
|
||||||
// <SignoutButton />
|
|
||||||
// <Link className="btn" href="/music">弹幕测试</Link>
|
|
||||||
// <div className="z-10 max-w-5xl w-full 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
|
|
||||||
// <code className="font-mono font-bold">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:h-auto lg:w-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>
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// <div className="relative flex place-items-center before:absolute before:h-[300px] before:w-full sm:before:w-[480px] 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 sm:after:w-[240px] 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 before:lg:h-[360px] z-[-1]">
|
|
||||||
// <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:max-w-5xl lg:w-full lg:mb-0 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">
|
|
||||||
// ->
|
|
||||||
// </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">
|
|
||||||
// ->
|
|
||||||
// </span>
|
|
||||||
// </h2>
|
|
||||||
// <p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
|
||||||
// Learn about Next.js in an interactive course with 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">
|
|
||||||
// ->
|
|
||||||
// </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">
|
|
||||||
// ->
|
|
||||||
// </span>
|
|
||||||
// </h2>
|
|
||||||
// <p className={`m-0 max-w-[30ch] text-sm opacity-50 text-balance`}>
|
|
||||||
// Instantly deploy your Next.js site to a shareable URL with Vercel.
|
|
||||||
// </p>
|
|
||||||
// </a>
|
|
||||||
// </div>
|
|
||||||
// </main>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
@ -1,33 +1,89 @@
|
|||||||
'use client'
|
"use client";
|
||||||
|
|
||||||
import { signin } from '@/app/lib/actions'
|
import { signin } from "@/app/lib/actions/auth";
|
||||||
import { useFormState, useFormStatus } from 'react-dom'
|
import Link from "next/link";
|
||||||
|
import { useFormState, useFormStatus } from "react-dom";
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const [errorMessage, dispatch] = useFormState(signin, undefined)
|
const [errorMessage, dispatch] = useFormState(signin, undefined);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form action={dispatch}>
|
<section className="text-gray-600 body-font">
|
||||||
<input name="account" placeholder="Account" required />
|
<div className="container px-5 py-24 mx-auto flex flex-wrap items-center">
|
||||||
<input type="password" name="password" placeholder="Password" required />
|
<div className="lg:w-3/5 md:w-1/2 md:pr-16 lg:pr-0 pr-0">
|
||||||
<div>{errorMessage && <p>{errorMessage}</p>}</div>
|
<h1 className="title-font font-medium text-3xl text-gray-900">
|
||||||
<LoginButton />
|
Slow-carb next level shoindcgoitch ethical authentic, poko scenester
|
||||||
</form>
|
</h1>
|
||||||
)
|
<p className="leading-relaxed mt-4">
|
||||||
|
Poke slow-carb mixtape knausgaard, typewriter street art gentrify
|
||||||
|
hammock starladder roathse. Craies vegan tousled etsy austin.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
action={dispatch}
|
||||||
|
className="lg:w-2/6 md:w-1/2 bg-gray-100 rounded-lg p-8 flex flex-col md:ml-auto w-full mt-10 md:mt-0"
|
||||||
|
>
|
||||||
|
<h2 className="text-gray-900 text-lg font-medium title-font mb-5">
|
||||||
|
登录
|
||||||
|
</h2>
|
||||||
|
<div className="relative mb-4">
|
||||||
|
<label
|
||||||
|
htmlFor="account"
|
||||||
|
className="leading-7 text-sm text-gray-600"
|
||||||
|
>
|
||||||
|
账号
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="account"
|
||||||
|
className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
name="account"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative mb-4">
|
||||||
|
<label
|
||||||
|
htmlFor="password"
|
||||||
|
className="leading-7 text-sm text-gray-600"
|
||||||
|
>
|
||||||
|
密码
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="password"
|
||||||
|
className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
|
||||||
|
required
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<LoginButton className="text-white bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg" />
|
||||||
|
<Link href="/signup" className="btn btn-link">还没有账号?可以注册一个。</Link>
|
||||||
|
{errorMessage ? (
|
||||||
|
<p className="text-xs text-red-400 mt-3">{errorMessage}</p>
|
||||||
|
) : null}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function LoginButton() {
|
function LoginButton({ className }: { className: string | undefined }) {
|
||||||
const { pending } = useFormStatus()
|
const { pending } = useFormStatus();
|
||||||
|
|
||||||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
if (pending) {
|
if (pending) {
|
||||||
event.preventDefault()
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button aria-disabled={pending} type="submit" onClick={handleClick}>
|
<button
|
||||||
Login
|
className={className}
|
||||||
|
aria-disabled={pending}
|
||||||
|
type="submit"
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
登录
|
||||||
</button>
|
</button>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,125 @@
|
|||||||
'use client'
|
"use client";
|
||||||
|
|
||||||
import { signup } from '@/app/lib/actions'
|
import { signup } from "@/app/lib/actions/auth";
|
||||||
import { useFormState, useFormStatus } from 'react-dom'
|
import Link from "next/link";
|
||||||
|
import { useFormState, useFormStatus } from "react-dom";
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const [errorMessage, dispatch] = useFormState(signup, undefined)
|
const [errorMessage, dispatch] = useFormState(signup, undefined);
|
||||||
|
|
||||||
console.log(errorMessage, '=== in client');
|
return (
|
||||||
return (
|
<section className="text-gray-600 body-font">
|
||||||
<form action={dispatch}>
|
<div className="container px-5 py-24 mx-auto flex flex-wrap items-center">
|
||||||
<input name="username" required />
|
<div className="lg:w-3/5 md:w-1/2 md:pr-16 lg:pr-0 pr-0">
|
||||||
<input type="password" name="password" placeholder='密码' required />
|
<h1 className="title-font font-medium text-3xl text-gray-900">
|
||||||
<input type="password" name="confirm_password" placeholder='确认密码' required />
|
Slow-carb next level shoindcgoitch ethical authentic, poko scenester
|
||||||
<div>{errorMessage && <p>{errorMessage}</p>}</div>
|
</h1>
|
||||||
<LoginButton />
|
<p className="leading-relaxed mt-4">
|
||||||
|
Poke slow-carb mixtape knausgaard, typewriter street art gentrify
|
||||||
|
hammock starladder roathse. Craies vegan tousled etsy austin.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
action={dispatch}
|
||||||
|
className="lg:w-2/6 md:w-1/2 bg-gray-100 rounded-lg p-8 flex flex-col md:ml-auto w-full mt-10 md:mt-0"
|
||||||
|
>
|
||||||
|
<h2 className="text-gray-900 text-lg font-medium title-font mb-5">
|
||||||
|
注册
|
||||||
|
</h2>
|
||||||
|
<div className="relative mb-4">
|
||||||
|
<label
|
||||||
|
htmlFor="username"
|
||||||
|
className="leading-7 text-sm text-gray-600"
|
||||||
|
>
|
||||||
|
账号
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="username"
|
||||||
|
className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
name="username"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative mb-4">
|
||||||
|
<label
|
||||||
|
htmlFor="password"
|
||||||
|
className="leading-7 text-sm text-gray-600"
|
||||||
|
>
|
||||||
|
密码
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="password"
|
||||||
|
className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
|
||||||
|
required
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative mb-4">
|
||||||
|
<label
|
||||||
|
htmlFor="confirm_password"
|
||||||
|
className="leading-7 text-sm text-gray-600"
|
||||||
|
>
|
||||||
|
确认密码
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="confirm_password"
|
||||||
|
className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
|
||||||
|
required
|
||||||
|
type="password"
|
||||||
|
name="confirm_password"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<SignupButton className="text-white bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg" />
|
||||||
|
<Link href="/signin" className="btn btn-link">已经有账号?点此直接登录。</Link>
|
||||||
|
{errorMessage ? (
|
||||||
|
<p className="text-xs text-red-400 mt-3">{errorMessage}</p>
|
||||||
|
) : null}
|
||||||
</form>
|
</form>
|
||||||
)
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function LoginButton() {
|
|
||||||
const { pending } = useFormStatus()
|
|
||||||
|
|
||||||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
// export default function Page() {
|
||||||
if (pending) {
|
// const [errorMessage, dispatch] = useFormState(signup, undefined);
|
||||||
event.preventDefault()
|
|
||||||
}
|
// return (
|
||||||
|
// <form action={dispatch}>
|
||||||
|
// <input name="username" required />
|
||||||
|
// <input type="password" name="password" placeholder="密码" required />
|
||||||
|
// <input
|
||||||
|
// type="password"
|
||||||
|
// name="confirm_password"
|
||||||
|
// placeholder="确认密码"
|
||||||
|
// required
|
||||||
|
// />
|
||||||
|
// <div>{errorMessage && <p>{errorMessage}</p>}</div>
|
||||||
|
// <LoginButton />
|
||||||
|
// </form>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
function SignupButton({ className }: { className: string | undefined }) {
|
||||||
|
const { pending } = useFormStatus();
|
||||||
|
|
||||||
|
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
if (pending) {
|
||||||
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className={className}
|
||||||
|
aria-disabled={pending}
|
||||||
|
type="submit"
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
注册
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
|
||||||
<button aria-disabled={pending} type="submit" onClick={handleClick}>
|
|
||||||
Login {pending}
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
}
|
|
20
package.json
20
package.json
@ -11,21 +11,21 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"next": "14.1.4",
|
"next": "14.1.4",
|
||||||
"react": "^18",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18.2.0",
|
||||||
"react-use-websocket": "^4.8.1"
|
"react-use-websocket": "^4.8.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20",
|
"@types/node": "^20.12.4",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18.2.74",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18.2.24",
|
||||||
"autoprefixer": "^10.0.1",
|
"autoprefixer": "^10.4.19",
|
||||||
"daisyui": "^4.10.1",
|
"daisyui": "^4.10.1",
|
||||||
"eslint": "^8",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-next": "14.1.4",
|
"eslint-config-next": "14.1.4",
|
||||||
"postcss": "^8",
|
"postcss": "^8.4.38",
|
||||||
"tailwindcss": "^3.3.0",
|
"tailwindcss": "^3.4.3",
|
||||||
"typescript": "^5"
|
"typescript": "^5.4.4"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.15.5+sha256.4b4efa12490e5055d59b9b9fc9438b7d581a6b7af3b5675eb5c5f447cee1a589"
|
"packageManager": "pnpm@8.15.5+sha256.4b4efa12490e5055d59b9b9fc9438b7d581a6b7af3b5675eb5c5f447cee1a589"
|
||||||
}
|
}
|
@ -12,10 +12,10 @@ dependencies:
|
|||||||
specifier: 14.1.4
|
specifier: 14.1.4
|
||||||
version: 14.1.4(react-dom@18.2.0)(react@18.2.0)
|
version: 14.1.4(react-dom@18.2.0)(react@18.2.0)
|
||||||
react:
|
react:
|
||||||
specifier: ^18
|
specifier: ^18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
react-dom:
|
react-dom:
|
||||||
specifier: ^18
|
specifier: ^18.2.0
|
||||||
version: 18.2.0(react@18.2.0)
|
version: 18.2.0(react@18.2.0)
|
||||||
react-use-websocket:
|
react-use-websocket:
|
||||||
specifier: ^4.8.1
|
specifier: ^4.8.1
|
||||||
@ -23,34 +23,34 @@ dependencies:
|
|||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^20
|
specifier: ^20.12.4
|
||||||
version: 20.12.4
|
version: 20.12.4
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: ^18
|
specifier: ^18.2.74
|
||||||
version: 18.2.74
|
version: 18.2.74
|
||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
specifier: ^18
|
specifier: ^18.2.24
|
||||||
version: 18.2.24
|
version: 18.2.24
|
||||||
autoprefixer:
|
autoprefixer:
|
||||||
specifier: ^10.0.1
|
specifier: ^10.4.19
|
||||||
version: 10.4.19(postcss@8.4.38)
|
version: 10.4.19(postcss@8.4.38)
|
||||||
daisyui:
|
daisyui:
|
||||||
specifier: ^4.10.1
|
specifier: ^4.10.1
|
||||||
version: 4.10.1(postcss@8.4.38)
|
version: 4.10.1(postcss@8.4.38)
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^8
|
specifier: ^8.57.0
|
||||||
version: 8.57.0
|
version: 8.57.0
|
||||||
eslint-config-next:
|
eslint-config-next:
|
||||||
specifier: 14.1.4
|
specifier: 14.1.4
|
||||||
version: 14.1.4(eslint@8.57.0)(typescript@5.4.4)
|
version: 14.1.4(eslint@8.57.0)(typescript@5.4.4)
|
||||||
postcss:
|
postcss:
|
||||||
specifier: ^8
|
specifier: ^8.4.38
|
||||||
version: 8.4.38
|
version: 8.4.38
|
||||||
tailwindcss:
|
tailwindcss:
|
||||||
specifier: ^3.3.0
|
specifier: ^3.4.3
|
||||||
version: 3.4.3
|
version: 3.4.3
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5
|
specifier: ^5.4.4
|
||||||
version: 5.4.4
|
version: 5.4.4
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
@ -588,7 +588,7 @@ packages:
|
|||||||
postcss: ^8.1.0
|
postcss: ^8.1.0
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.23.0
|
browserslist: 4.23.0
|
||||||
caniuse-lite: 1.0.30001605
|
caniuse-lite: 1.0.30001606
|
||||||
fraction.js: 4.3.7
|
fraction.js: 4.3.7
|
||||||
normalize-range: 0.1.2
|
normalize-range: 0.1.2
|
||||||
picocolors: 1.0.0
|
picocolors: 1.0.0
|
||||||
@ -658,7 +658,7 @@ packages:
|
|||||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
caniuse-lite: 1.0.30001605
|
caniuse-lite: 1.0.30001606
|
||||||
electron-to-chromium: 1.4.728
|
electron-to-chromium: 1.4.728
|
||||||
node-releases: 2.0.14
|
node-releases: 2.0.14
|
||||||
update-browserslist-db: 1.0.13(browserslist@4.23.0)
|
update-browserslist-db: 1.0.13(browserslist@4.23.0)
|
||||||
@ -692,8 +692,8 @@ packages:
|
|||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/caniuse-lite@1.0.30001605:
|
/caniuse-lite@1.0.30001606:
|
||||||
resolution: {integrity: sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==}
|
resolution: {integrity: sha512-LPbwnW4vfpJId225pwjZJOgX1m9sGfbw/RKJvw/t0QhYOOaTXHvkjVGFGPpvwEzufrjvTlsULnVTxdy4/6cqkg==}
|
||||||
|
|
||||||
/chalk@4.1.2:
|
/chalk@4.1.2:
|
||||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||||
@ -2073,7 +2073,7 @@ packages:
|
|||||||
'@next/env': 14.1.4
|
'@next/env': 14.1.4
|
||||||
'@swc/helpers': 0.5.2
|
'@swc/helpers': 0.5.2
|
||||||
busboy: 1.6.0
|
busboy: 1.6.0
|
||||||
caniuse-lite: 1.0.30001605
|
caniuse-lite: 1.0.30001606
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
postcss: 8.4.31
|
postcss: 8.4.31
|
||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
|
Loading…
Reference in New Issue
Block a user