This commit is contained in:
zhu
2026-05-08 09:42:08 +08:00
parent 6348090dfe
commit c3d550513c
4 changed files with 63 additions and 23 deletions

View File

@@ -13,7 +13,8 @@
"lucide-react": "^1.14.0",
"next": "16.2.5",
"react": "19.2.4",
"react-dom": "19.2.4"
"react-dom": "19.2.4",
"zustand": "^5.0.13"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",

55
pnpm-lock.yaml generated
View File

@@ -14,6 +14,9 @@ importers:
classnames:
specifier: ^2.5.1
version: 2.5.1
lucide-react:
specifier: ^1.14.0
version: 1.14.0(react@19.2.4)
next:
specifier: 16.2.5
version: 16.2.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.99.0)
@@ -23,6 +26,9 @@ importers:
react-dom:
specifier: 19.2.4
version: 19.2.4(react@19.2.4)
zustand:
specifier: ^5.0.13
version: 5.0.13(@types/react@19.2.14)(react@19.2.4)
devDependencies:
'@tailwindcss/postcss':
specifier: ^4
@@ -39,9 +45,6 @@ importers:
sass:
specifier: ^1.99.0
version: 1.99.0
scss:
specifier: ^0.2.4
version: 0.2.4
tailwindcss:
specifier: ^4
version: 4.2.4
@@ -675,6 +678,11 @@ packages:
resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
engines: {node: '>= 12.0.0'}
lucide-react@1.14.0:
resolution: {integrity: sha512-+1mdWcfSJVUsaTIjN9zoezmUhfXo5l0vP7ekBMPo3jcS/aIkxHnXqAPsByszMZx/Y8oQBRJxJx5xg+RH3urzxA==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
@@ -719,10 +727,6 @@ packages:
node-addon-api@7.1.1:
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
ometa@0.2.2:
resolution: {integrity: sha512-LZuoK/yjU3FvrxPjUXUlZ1bavCfBPqauA7fsNdwi+AVhRdyk2IzgP3JRnevvjzQ6fKHdUw8YISshf53FmpHrng==}
engines: {node: '>= 0.2.0'}
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -763,10 +767,6 @@ packages:
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
scss@0.2.4:
resolution: {integrity: sha512-4u8V87F+Q/upVhUmhPnB4C1R11xojkRkWjExL2v0CX2EXTg18VrKd+9JWoeyCp2VEMdSpJsyAvVU+rVjogh51A==}
engines: {node: '>= 0.2.0'}
semver@7.7.4:
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
engines: {node: '>=10'}
@@ -811,6 +811,24 @@ packages:
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
zustand@5.0.13:
resolution: {integrity: sha512-efI2tVaVQPqtOh114loML/Z80Y4NP3yc+Ff0fYiZJPauNeWZeIp/bRFD7I9bfmCOYBh/PHxlglQ9+wvlwnPikQ==}
engines: {node: '>=12.20.0'}
peerDependencies:
'@types/react': '>=18.0.0'
immer: '>=9.0.6'
react: '>=18.0.0'
use-sync-external-store: '>=1.2.0'
peerDependenciesMeta:
'@types/react':
optional: true
immer:
optional: true
react:
optional: true
use-sync-external-store:
optional: true
snapshots:
'@alloc/quick-lru@5.2.0': {}
@@ -1276,6 +1294,10 @@ snapshots:
lightningcss-win32-arm64-msvc: 1.32.0
lightningcss-win32-x64-msvc: 1.32.0
lucide-react@1.14.0(react@19.2.4):
dependencies:
react: 19.2.4
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -1318,8 +1340,6 @@ snapshots:
node-addon-api@7.1.1:
optional: true
ometa@0.2.2: {}
picocolors@1.1.1: {}
picomatch@4.0.4:
@@ -1358,10 +1378,6 @@ snapshots:
scheduler@0.27.0: {}
scss@0.2.4:
dependencies:
ometa: 0.2.2
semver@7.7.4:
optional: true
@@ -1413,3 +1429,8 @@ snapshots:
typescript@5.9.3: {}
undici-types@6.21.0: {}
zustand@5.0.13(@types/react@19.2.14)(react@19.2.4):
optionalDependencies:
'@types/react': 19.2.14
react: 19.2.4

View File

@@ -9,11 +9,6 @@ import {PasswordToggle} from "../components/password-toggle";
import {getLoginNotice} from "./login-error";
import {validateSignup} from "../validate";
/** 登录表单提交参数。 */
interface LoginPayload {
email: string;
password: string;
}
/** 登录页入口,为依赖查询参数的表单提供 Suspense 边界。 */
export default function LoginPage() {

23
src/store/user.ts Normal file
View File

@@ -0,0 +1,23 @@
import {create} from "zustand";
import {persist, createJSONStorage} from "zustand/middleware";
type UserStore = {
token: string;
setToken: (token: string) => void;
clearToken: () => void;
}
const useUserStore = create<UserStore>()(
persist(
(set) => ({
token: "",
setToken: (token) => set({token}),
clearToken: () => set({token: ""}),
}),
{
name: "user-storage",
storage: createJSONStorage(() => localStorage),
}
)
);
export default useUserStore;