@qhr123/sa2kit 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +30 -0
  2. package/dist/auth/index.d.mts +104 -0
  3. package/dist/auth/index.d.ts +104 -0
  4. package/dist/auth/index.js +186 -0
  5. package/dist/auth/index.js.map +1 -0
  6. package/dist/auth/index.mjs +183 -0
  7. package/dist/auth/index.mjs.map +1 -0
  8. package/dist/chunk-TLXAIOXP.js +476 -0
  9. package/dist/chunk-TLXAIOXP.js.map +1 -0
  10. package/dist/chunk-WUTGV44D.mjs +466 -0
  11. package/dist/chunk-WUTGV44D.mjs.map +1 -0
  12. package/dist/config/index.d.mts +64 -0
  13. package/dist/config/index.d.ts +64 -0
  14. package/dist/config/index.js +136 -0
  15. package/dist/config/index.js.map +1 -0
  16. package/dist/config/index.mjs +128 -0
  17. package/dist/config/index.mjs.map +1 -0
  18. package/dist/i18n/index.d.mts +15 -3
  19. package/dist/i18n/index.d.ts +15 -3
  20. package/dist/i18n/index.js +3 -0
  21. package/dist/i18n/index.js.map +1 -1
  22. package/dist/i18n/index.mjs +1 -1
  23. package/dist/i18n/index.mjs.map +1 -1
  24. package/dist/index.d.mts +1 -3
  25. package/dist/index.d.ts +1 -3
  26. package/dist/index.js +29 -6
  27. package/dist/index.mjs +1 -2
  28. package/dist/storage/index.d.mts +162 -3
  29. package/dist/storage/index.d.ts +162 -3
  30. package/dist/storage/index.js +34 -2
  31. package/dist/storage/index.mjs +1 -1
  32. package/package.json +26 -8
  33. package/dist/chunk-3R73CUAY.js +0 -80
  34. package/dist/chunk-3R73CUAY.js.map +0 -1
  35. package/dist/chunk-4JTIYLS6.js +0 -88
  36. package/dist/chunk-4JTIYLS6.js.map +0 -1
  37. package/dist/chunk-C7VOMO3L.mjs +0 -77
  38. package/dist/chunk-C7VOMO3L.mjs.map +0 -1
  39. package/dist/chunk-M7CA3DTF.mjs +0 -86
  40. package/dist/chunk-M7CA3DTF.mjs.map +0 -1
  41. package/dist/hooks/index.d.mts +0 -30
  42. package/dist/hooks/index.d.ts +0 -30
  43. package/dist/hooks/index.js +0 -18
  44. package/dist/hooks/index.js.map +0 -1
  45. package/dist/hooks/index.mjs +0 -5
  46. package/dist/hooks/index.mjs.map +0 -1
  47. package/dist/types-BaZccpvk.d.mts +0 -48
  48. package/dist/types-BaZccpvk.d.ts +0 -48
package/README.md CHANGED
@@ -179,6 +179,36 @@ function MyComponent() {
179
179
  }
180
180
  ```
181
181
 
182
+ #### UI Components (Tailwind CSS)
183
+
184
+ ```typescript
185
+ import { LanguageSwitcher } from '@qhr123/sa2kit/i18n';
186
+
187
+ // Button group style (default)
188
+ <LanguageSwitcher variant="buttons" />
189
+
190
+ // Dropdown style
191
+ <LanguageSwitcher variant="dropdown" />
192
+
193
+ // Icon button with dropdown
194
+ <LanguageSwitcher variant="icon" />
195
+
196
+ // With custom className and callback
197
+ <LanguageSwitcher
198
+ variant="buttons"
199
+ className="my-custom-class"
200
+ onLanguageChange={(locale) => {
201
+ console.log('Language changed to:', locale);
202
+ }}
203
+ />
204
+ ```
205
+
206
+ **Requirements:**
207
+ - ✅ React >= 18.0.0
208
+ - ✅ Tailwind CSS configured in your project
209
+ - ✅ Next.js App Router compatible ('use client' included)
210
+ ```
211
+
182
212
  ### Analytics
183
213
 
184
214
  ```typescript
@@ -0,0 +1,104 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * Auth 模块类型定义
5
+ */
6
+ /**
7
+ * 用户基础信息
8
+ */
9
+ interface User {
10
+ id: string;
11
+ email: string;
12
+ username: string;
13
+ [key: string]: any;
14
+ }
15
+ /**
16
+ * API 客户端基础接口
17
+ */
18
+ interface BaseApiClient {
19
+ isAuthenticated(): Promise<boolean>;
20
+ getCurrentUser(): Promise<{
21
+ success: boolean;
22
+ data?: User;
23
+ error?: string;
24
+ }>;
25
+ login(email: string, password: string): Promise<{
26
+ success: boolean;
27
+ data?: {
28
+ user: User;
29
+ };
30
+ error?: string;
31
+ }>;
32
+ register(email: string, password: string, username: string): Promise<{
33
+ success: boolean;
34
+ data?: {
35
+ user: User;
36
+ };
37
+ error?: string;
38
+ }>;
39
+ logout(): Promise<void>;
40
+ clearUserData(): Promise<void>;
41
+ }
42
+ /**
43
+ * 登录表单数据接口
44
+ */
45
+ interface LoginFormData {
46
+ email: string;
47
+ password: string;
48
+ }
49
+ /**
50
+ * 注册表单数据接口
51
+ */
52
+ interface RegisterFormData {
53
+ email: string;
54
+ password: string;
55
+ username: string;
56
+ }
57
+ /**
58
+ * 认证操作结果接口
59
+ */
60
+ interface AuthResult {
61
+ success: boolean;
62
+ error?: string;
63
+ }
64
+ /**
65
+ * useAuth Hook 返回值接口
66
+ */
67
+ interface UseAuthReturn {
68
+ user: User | null;
69
+ isLoggedIn: boolean;
70
+ loading: boolean;
71
+ checkingAuth: boolean;
72
+ error: string | null;
73
+ login: (email: string, password: string) => Promise<AuthResult>;
74
+ register: (email: string, password: string, username: string) => Promise<AuthResult>;
75
+ logout: () => Promise<void>;
76
+ refresh: () => Promise<void>;
77
+ clearError: () => void;
78
+ }
79
+
80
+ declare function useAuth(apiClient: BaseApiClient): UseAuthReturn;
81
+ /**
82
+ * 表单验证 Hook
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const { values, errors, handleChange, handleBlur, validate } = useAuthForm({
87
+ * email: '',
88
+ * password: ''
89
+ * })
90
+ * ```
91
+ */
92
+ declare function useAuthForm<T extends Record<string, any>>(initialValues: T): {
93
+ values: T;
94
+ errors: Partial<Record<keyof T, string>>;
95
+ touched: Partial<Record<keyof T, boolean>>;
96
+ handleChange: (field: keyof T, value: any) => void;
97
+ handleBlur: (field: keyof T) => void;
98
+ validate: (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => boolean;
99
+ reset: () => void;
100
+ setValues: React.Dispatch<React.SetStateAction<T>>;
101
+ setErrors: React.Dispatch<React.SetStateAction<Partial<Record<keyof T, string>>>>;
102
+ };
103
+
104
+ export { type AuthResult, type BaseApiClient, type LoginFormData, type RegisterFormData, type UseAuthReturn, type User, useAuth, useAuthForm };
@@ -0,0 +1,104 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * Auth 模块类型定义
5
+ */
6
+ /**
7
+ * 用户基础信息
8
+ */
9
+ interface User {
10
+ id: string;
11
+ email: string;
12
+ username: string;
13
+ [key: string]: any;
14
+ }
15
+ /**
16
+ * API 客户端基础接口
17
+ */
18
+ interface BaseApiClient {
19
+ isAuthenticated(): Promise<boolean>;
20
+ getCurrentUser(): Promise<{
21
+ success: boolean;
22
+ data?: User;
23
+ error?: string;
24
+ }>;
25
+ login(email: string, password: string): Promise<{
26
+ success: boolean;
27
+ data?: {
28
+ user: User;
29
+ };
30
+ error?: string;
31
+ }>;
32
+ register(email: string, password: string, username: string): Promise<{
33
+ success: boolean;
34
+ data?: {
35
+ user: User;
36
+ };
37
+ error?: string;
38
+ }>;
39
+ logout(): Promise<void>;
40
+ clearUserData(): Promise<void>;
41
+ }
42
+ /**
43
+ * 登录表单数据接口
44
+ */
45
+ interface LoginFormData {
46
+ email: string;
47
+ password: string;
48
+ }
49
+ /**
50
+ * 注册表单数据接口
51
+ */
52
+ interface RegisterFormData {
53
+ email: string;
54
+ password: string;
55
+ username: string;
56
+ }
57
+ /**
58
+ * 认证操作结果接口
59
+ */
60
+ interface AuthResult {
61
+ success: boolean;
62
+ error?: string;
63
+ }
64
+ /**
65
+ * useAuth Hook 返回值接口
66
+ */
67
+ interface UseAuthReturn {
68
+ user: User | null;
69
+ isLoggedIn: boolean;
70
+ loading: boolean;
71
+ checkingAuth: boolean;
72
+ error: string | null;
73
+ login: (email: string, password: string) => Promise<AuthResult>;
74
+ register: (email: string, password: string, username: string) => Promise<AuthResult>;
75
+ logout: () => Promise<void>;
76
+ refresh: () => Promise<void>;
77
+ clearError: () => void;
78
+ }
79
+
80
+ declare function useAuth(apiClient: BaseApiClient): UseAuthReturn;
81
+ /**
82
+ * 表单验证 Hook
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const { values, errors, handleChange, handleBlur, validate } = useAuthForm({
87
+ * email: '',
88
+ * password: ''
89
+ * })
90
+ * ```
91
+ */
92
+ declare function useAuthForm<T extends Record<string, any>>(initialValues: T): {
93
+ values: T;
94
+ errors: Partial<Record<keyof T, string>>;
95
+ touched: Partial<Record<keyof T, boolean>>;
96
+ handleChange: (field: keyof T, value: any) => void;
97
+ handleBlur: (field: keyof T) => void;
98
+ validate: (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => boolean;
99
+ reset: () => void;
100
+ setValues: React.Dispatch<React.SetStateAction<T>>;
101
+ setErrors: React.Dispatch<React.SetStateAction<Partial<Record<keyof T, string>>>>;
102
+ };
103
+
104
+ export { type AuthResult, type BaseApiClient, type LoginFormData, type RegisterFormData, type UseAuthReturn, type User, useAuth, useAuthForm };
@@ -0,0 +1,186 @@
1
+ 'use strict';
2
+
3
+ require('../chunk-DGUM43GV.js');
4
+ var react = require('react');
5
+
6
+ function useAuth(apiClient) {
7
+ const [user, setUser] = react.useState(null);
8
+ const [isLoggedIn, setIsLoggedIn] = react.useState(false);
9
+ const [loading, setLoading] = react.useState(false);
10
+ const [checkingAuth, setCheckingAuth] = react.useState(true);
11
+ const [error, setError] = react.useState(null);
12
+ const checkAuthStatus = react.useCallback(async () => {
13
+ try {
14
+ setCheckingAuth(true);
15
+ setError(null);
16
+ const isAuth = await apiClient.isAuthenticated();
17
+ if (isAuth) {
18
+ const response = await apiClient.getCurrentUser();
19
+ if (response.success && response.data) {
20
+ setUser(response.data);
21
+ setIsLoggedIn(true);
22
+ } else {
23
+ await apiClient.clearUserData();
24
+ setUser(null);
25
+ setIsLoggedIn(false);
26
+ }
27
+ } else {
28
+ setUser(null);
29
+ setIsLoggedIn(false);
30
+ }
31
+ } catch (err) {
32
+ console.error("\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25:", err);
33
+ setError(err instanceof Error ? err.message : "\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25");
34
+ setUser(null);
35
+ setIsLoggedIn(false);
36
+ } finally {
37
+ setCheckingAuth(false);
38
+ }
39
+ }, [apiClient]);
40
+ const login = react.useCallback(
41
+ async (email, password) => {
42
+ setLoading(true);
43
+ setError(null);
44
+ try {
45
+ const response = await apiClient.login(email, password);
46
+ if (response.success && response.data) {
47
+ setUser(response.data.user);
48
+ setIsLoggedIn(true);
49
+ return { success: true };
50
+ } else {
51
+ const errorMsg = response.error || "\u767B\u5F55\u5931\u8D25";
52
+ setError(errorMsg);
53
+ return { success: false, error: errorMsg };
54
+ }
55
+ } catch (err) {
56
+ const errorMsg = err instanceof Error ? err.message : "\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
57
+ setError(errorMsg);
58
+ return { success: false, error: errorMsg };
59
+ } finally {
60
+ setLoading(false);
61
+ }
62
+ },
63
+ [apiClient]
64
+ );
65
+ const register = react.useCallback(
66
+ async (email, password, username) => {
67
+ setLoading(true);
68
+ setError(null);
69
+ try {
70
+ const response = await apiClient.register(email, password, username);
71
+ if (response.success && response.data) {
72
+ setUser(response.data.user);
73
+ setIsLoggedIn(true);
74
+ return { success: true };
75
+ } else {
76
+ const errorMsg = response.error || "\u6CE8\u518C\u5931\u8D25";
77
+ setError(errorMsg);
78
+ return { success: false, error: errorMsg };
79
+ }
80
+ } catch (err) {
81
+ const errorMsg = err instanceof Error ? err.message : "\u6CE8\u518C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
82
+ setError(errorMsg);
83
+ return { success: false, error: errorMsg };
84
+ } finally {
85
+ setLoading(false);
86
+ }
87
+ },
88
+ [apiClient]
89
+ );
90
+ const logout = react.useCallback(async () => {
91
+ setLoading(true);
92
+ setError(null);
93
+ try {
94
+ await apiClient.logout();
95
+ setUser(null);
96
+ setIsLoggedIn(false);
97
+ } catch (err) {
98
+ console.error("\u767B\u51FA\u5931\u8D25:", err);
99
+ setError(err instanceof Error ? err.message : "\u767B\u51FA\u5931\u8D25");
100
+ setUser(null);
101
+ setIsLoggedIn(false);
102
+ } finally {
103
+ setLoading(false);
104
+ }
105
+ }, [apiClient]);
106
+ const clearError = react.useCallback(() => {
107
+ setError(null);
108
+ }, []);
109
+ react.useEffect(() => {
110
+ checkAuthStatus();
111
+ }, [checkAuthStatus]);
112
+ return {
113
+ // 状态
114
+ user,
115
+ isLoggedIn,
116
+ loading,
117
+ checkingAuth,
118
+ error,
119
+ // 操作方法
120
+ login,
121
+ register,
122
+ logout,
123
+ refresh: checkAuthStatus,
124
+ clearError
125
+ };
126
+ }
127
+ function useAuthForm(initialValues) {
128
+ const [values, setValues] = react.useState(initialValues);
129
+ const [errors, setErrors] = react.useState({});
130
+ const [touched, setTouched] = react.useState({});
131
+ const handleChange = react.useCallback(
132
+ (field, value) => {
133
+ setValues((prev) => ({ ...prev, [field]: value }));
134
+ if (errors[field]) {
135
+ setErrors((prev) => {
136
+ const newErrors = { ...prev };
137
+ delete newErrors[field];
138
+ return newErrors;
139
+ });
140
+ }
141
+ },
142
+ [errors]
143
+ );
144
+ const handleBlur = react.useCallback((field) => {
145
+ setTouched((prev) => ({ ...prev, [field]: true }));
146
+ }, []);
147
+ const validate = react.useCallback(
148
+ (validationRules) => {
149
+ const newErrors = {};
150
+ Object.keys(validationRules).forEach((key) => {
151
+ const field = key;
152
+ const rule = validationRules[field];
153
+ if (rule) {
154
+ const error = rule(values[field]);
155
+ if (error) {
156
+ newErrors[field] = error;
157
+ }
158
+ }
159
+ });
160
+ setErrors(newErrors);
161
+ return Object.keys(newErrors).length === 0;
162
+ },
163
+ [values]
164
+ );
165
+ const reset = react.useCallback(() => {
166
+ setValues(initialValues);
167
+ setErrors({});
168
+ setTouched({});
169
+ }, [initialValues]);
170
+ return {
171
+ values,
172
+ errors,
173
+ touched,
174
+ handleChange,
175
+ handleBlur,
176
+ validate,
177
+ reset,
178
+ setValues,
179
+ setErrors
180
+ };
181
+ }
182
+
183
+ exports.useAuth = useAuth;
184
+ exports.useAuthForm = useAuthForm;
185
+ //# sourceMappingURL=index.js.map
186
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/auth/hooks/useAuth.ts"],"names":["useState","useCallback","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport type { User, BaseApiClient, AuthResult, UseAuthReturn } from '../types';\n\nexport type { User, BaseApiClient, AuthResult, UseAuthReturn };\n\nexport function useAuth(apiClient: BaseApiClient): UseAuthReturn {\n const [user, setUser] = useState<User | null>(null);\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [loading, setLoading] = useState(false);\n const [checkingAuth, setCheckingAuth] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * 检查认证状态\n */\n const checkAuthStatus = useCallback(async () => {\n try {\n setCheckingAuth(true);\n setError(null);\n\n const isAuth = await apiClient.isAuthenticated();\n\n if (isAuth) {\n // 验证 token 并获取用户信息\n const response = await apiClient.getCurrentUser();\n\n if (response.success && response.data) {\n setUser(response.data);\n setIsLoggedIn(true);\n } else {\n // Token 无效,清除登录状态\n await apiClient.clearUserData();\n setUser(null);\n setIsLoggedIn(false);\n }\n } else {\n setUser(null);\n setIsLoggedIn(false);\n }\n } catch (err) {\n console.error('检查登录状态失败:', err);\n setError(err instanceof Error ? err.message : '检查登录状态失败');\n setUser(null);\n setIsLoggedIn(false);\n } finally {\n setCheckingAuth(false);\n }\n }, [apiClient]);\n\n /**\n * 用户登录\n */\n const login = useCallback(\n async (email: string, password: string): Promise<AuthResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await apiClient.login(email, password);\n\n if (response.success && response.data) {\n setUser(response.data.user);\n setIsLoggedIn(true);\n return { success: true };\n } else {\n const errorMsg = response.error || '登录失败';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '登录失败,请重试';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n } finally {\n setLoading(false);\n }\n },\n [apiClient]\n );\n\n /**\n * 用户注册\n */\n const register = useCallback(\n async (email: string, password: string, username: string): Promise<AuthResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await apiClient.register(email, password, username);\n\n if (response.success && response.data) {\n setUser(response.data.user);\n setIsLoggedIn(true);\n return { success: true };\n } else {\n const errorMsg = response.error || '注册失败';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '注册失败,请重试';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n } finally {\n setLoading(false);\n }\n },\n [apiClient]\n );\n\n /**\n * 用户登出\n */\n const logout = useCallback(async () => {\n setLoading(true);\n setError(null);\n\n try {\n await apiClient.logout();\n setUser(null);\n setIsLoggedIn(false);\n } catch (err) {\n console.error('登出失败:', err);\n setError(err instanceof Error ? err.message : '登出失败');\n // 即使登出失败,也清除本地状态\n setUser(null);\n setIsLoggedIn(false);\n } finally {\n setLoading(false);\n }\n }, [apiClient]);\n\n /**\n * 清除错误信息\n */\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n // 组件挂载时检查认证状态\n useEffect(() => {\n checkAuthStatus();\n }, [checkAuthStatus]);\n\n return {\n // 状态\n user,\n isLoggedIn,\n loading,\n checkingAuth,\n error,\n\n // 操作方法\n login,\n register,\n logout,\n refresh: checkAuthStatus,\n clearError,\n };\n}\n\n/**\n * 表单验证 Hook\n *\n * @example\n * ```typescript\n * const { values, errors, handleChange, handleBlur, validate } = useAuthForm({\n * email: '',\n * password: ''\n * })\n * ```\n */\nexport function useAuthForm<T extends Record<string, any>>(initialValues: T) {\n const [values, setValues] = useState<T>(initialValues);\n const [errors, setErrors] = useState<Partial<Record<keyof T, string>>>({});\n const [touched, setTouched] = useState<Partial<Record<keyof T, boolean>>>({});\n\n const handleChange = useCallback(\n (field: keyof T, value: any) => {\n setValues((prev: T) => ({ ...prev, [field]: value }));\n // 清除该字段的错误\n if (errors[field]) {\n setErrors((prev: Partial<Record<keyof T, string>>) => {\n const newErrors = { ...prev };\n delete newErrors[field];\n return newErrors;\n });\n }\n },\n [errors]\n );\n\n const handleBlur = useCallback((field: keyof T) => {\n setTouched((prev: Partial<Record<keyof T, boolean>>) => ({ ...prev, [field]: true }));\n }, []);\n\n const validate = useCallback(\n (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => {\n const newErrors: Partial<Record<keyof T, string>> = {};\n\n Object.keys(validationRules).forEach((key) => {\n const field = key as keyof T;\n const rule = validationRules[field];\n if (rule) {\n const error = rule(values[field]);\n if (error) {\n newErrors[field] = error;\n }\n }\n });\n\n setErrors(newErrors);\n return Object.keys(newErrors).length === 0;\n },\n [values]\n );\n\n const reset = useCallback(() => {\n setValues(initialValues);\n setErrors({});\n setTouched({});\n }, [initialValues]);\n\n return {\n values,\n errors,\n touched,\n handleChange,\n handleBlur,\n validate,\n reset,\n setValues,\n setErrors,\n };\n}\n\n"]}
@@ -0,0 +1,183 @@
1
+ import '../chunk-BJTO5JO5.mjs';
2
+ import { useState, useCallback, useEffect } from 'react';
3
+
4
+ function useAuth(apiClient) {
5
+ const [user, setUser] = useState(null);
6
+ const [isLoggedIn, setIsLoggedIn] = useState(false);
7
+ const [loading, setLoading] = useState(false);
8
+ const [checkingAuth, setCheckingAuth] = useState(true);
9
+ const [error, setError] = useState(null);
10
+ const checkAuthStatus = useCallback(async () => {
11
+ try {
12
+ setCheckingAuth(true);
13
+ setError(null);
14
+ const isAuth = await apiClient.isAuthenticated();
15
+ if (isAuth) {
16
+ const response = await apiClient.getCurrentUser();
17
+ if (response.success && response.data) {
18
+ setUser(response.data);
19
+ setIsLoggedIn(true);
20
+ } else {
21
+ await apiClient.clearUserData();
22
+ setUser(null);
23
+ setIsLoggedIn(false);
24
+ }
25
+ } else {
26
+ setUser(null);
27
+ setIsLoggedIn(false);
28
+ }
29
+ } catch (err) {
30
+ console.error("\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25:", err);
31
+ setError(err instanceof Error ? err.message : "\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25");
32
+ setUser(null);
33
+ setIsLoggedIn(false);
34
+ } finally {
35
+ setCheckingAuth(false);
36
+ }
37
+ }, [apiClient]);
38
+ const login = useCallback(
39
+ async (email, password) => {
40
+ setLoading(true);
41
+ setError(null);
42
+ try {
43
+ const response = await apiClient.login(email, password);
44
+ if (response.success && response.data) {
45
+ setUser(response.data.user);
46
+ setIsLoggedIn(true);
47
+ return { success: true };
48
+ } else {
49
+ const errorMsg = response.error || "\u767B\u5F55\u5931\u8D25";
50
+ setError(errorMsg);
51
+ return { success: false, error: errorMsg };
52
+ }
53
+ } catch (err) {
54
+ const errorMsg = err instanceof Error ? err.message : "\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
55
+ setError(errorMsg);
56
+ return { success: false, error: errorMsg };
57
+ } finally {
58
+ setLoading(false);
59
+ }
60
+ },
61
+ [apiClient]
62
+ );
63
+ const register = useCallback(
64
+ async (email, password, username) => {
65
+ setLoading(true);
66
+ setError(null);
67
+ try {
68
+ const response = await apiClient.register(email, password, username);
69
+ if (response.success && response.data) {
70
+ setUser(response.data.user);
71
+ setIsLoggedIn(true);
72
+ return { success: true };
73
+ } else {
74
+ const errorMsg = response.error || "\u6CE8\u518C\u5931\u8D25";
75
+ setError(errorMsg);
76
+ return { success: false, error: errorMsg };
77
+ }
78
+ } catch (err) {
79
+ const errorMsg = err instanceof Error ? err.message : "\u6CE8\u518C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
80
+ setError(errorMsg);
81
+ return { success: false, error: errorMsg };
82
+ } finally {
83
+ setLoading(false);
84
+ }
85
+ },
86
+ [apiClient]
87
+ );
88
+ const logout = useCallback(async () => {
89
+ setLoading(true);
90
+ setError(null);
91
+ try {
92
+ await apiClient.logout();
93
+ setUser(null);
94
+ setIsLoggedIn(false);
95
+ } catch (err) {
96
+ console.error("\u767B\u51FA\u5931\u8D25:", err);
97
+ setError(err instanceof Error ? err.message : "\u767B\u51FA\u5931\u8D25");
98
+ setUser(null);
99
+ setIsLoggedIn(false);
100
+ } finally {
101
+ setLoading(false);
102
+ }
103
+ }, [apiClient]);
104
+ const clearError = useCallback(() => {
105
+ setError(null);
106
+ }, []);
107
+ useEffect(() => {
108
+ checkAuthStatus();
109
+ }, [checkAuthStatus]);
110
+ return {
111
+ // 状态
112
+ user,
113
+ isLoggedIn,
114
+ loading,
115
+ checkingAuth,
116
+ error,
117
+ // 操作方法
118
+ login,
119
+ register,
120
+ logout,
121
+ refresh: checkAuthStatus,
122
+ clearError
123
+ };
124
+ }
125
+ function useAuthForm(initialValues) {
126
+ const [values, setValues] = useState(initialValues);
127
+ const [errors, setErrors] = useState({});
128
+ const [touched, setTouched] = useState({});
129
+ const handleChange = useCallback(
130
+ (field, value) => {
131
+ setValues((prev) => ({ ...prev, [field]: value }));
132
+ if (errors[field]) {
133
+ setErrors((prev) => {
134
+ const newErrors = { ...prev };
135
+ delete newErrors[field];
136
+ return newErrors;
137
+ });
138
+ }
139
+ },
140
+ [errors]
141
+ );
142
+ const handleBlur = useCallback((field) => {
143
+ setTouched((prev) => ({ ...prev, [field]: true }));
144
+ }, []);
145
+ const validate = useCallback(
146
+ (validationRules) => {
147
+ const newErrors = {};
148
+ Object.keys(validationRules).forEach((key) => {
149
+ const field = key;
150
+ const rule = validationRules[field];
151
+ if (rule) {
152
+ const error = rule(values[field]);
153
+ if (error) {
154
+ newErrors[field] = error;
155
+ }
156
+ }
157
+ });
158
+ setErrors(newErrors);
159
+ return Object.keys(newErrors).length === 0;
160
+ },
161
+ [values]
162
+ );
163
+ const reset = useCallback(() => {
164
+ setValues(initialValues);
165
+ setErrors({});
166
+ setTouched({});
167
+ }, [initialValues]);
168
+ return {
169
+ values,
170
+ errors,
171
+ touched,
172
+ handleChange,
173
+ handleBlur,
174
+ validate,
175
+ reset,
176
+ setValues,
177
+ setErrors
178
+ };
179
+ }
180
+
181
+ export { useAuth, useAuthForm };
182
+ //# sourceMappingURL=index.mjs.map
183
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/auth/hooks/useAuth.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport type { User, BaseApiClient, AuthResult, UseAuthReturn } from '../types';\n\nexport type { User, BaseApiClient, AuthResult, UseAuthReturn };\n\nexport function useAuth(apiClient: BaseApiClient): UseAuthReturn {\n const [user, setUser] = useState<User | null>(null);\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [loading, setLoading] = useState(false);\n const [checkingAuth, setCheckingAuth] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * 检查认证状态\n */\n const checkAuthStatus = useCallback(async () => {\n try {\n setCheckingAuth(true);\n setError(null);\n\n const isAuth = await apiClient.isAuthenticated();\n\n if (isAuth) {\n // 验证 token 并获取用户信息\n const response = await apiClient.getCurrentUser();\n\n if (response.success && response.data) {\n setUser(response.data);\n setIsLoggedIn(true);\n } else {\n // Token 无效,清除登录状态\n await apiClient.clearUserData();\n setUser(null);\n setIsLoggedIn(false);\n }\n } else {\n setUser(null);\n setIsLoggedIn(false);\n }\n } catch (err) {\n console.error('检查登录状态失败:', err);\n setError(err instanceof Error ? err.message : '检查登录状态失败');\n setUser(null);\n setIsLoggedIn(false);\n } finally {\n setCheckingAuth(false);\n }\n }, [apiClient]);\n\n /**\n * 用户登录\n */\n const login = useCallback(\n async (email: string, password: string): Promise<AuthResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await apiClient.login(email, password);\n\n if (response.success && response.data) {\n setUser(response.data.user);\n setIsLoggedIn(true);\n return { success: true };\n } else {\n const errorMsg = response.error || '登录失败';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '登录失败,请重试';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n } finally {\n setLoading(false);\n }\n },\n [apiClient]\n );\n\n /**\n * 用户注册\n */\n const register = useCallback(\n async (email: string, password: string, username: string): Promise<AuthResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await apiClient.register(email, password, username);\n\n if (response.success && response.data) {\n setUser(response.data.user);\n setIsLoggedIn(true);\n return { success: true };\n } else {\n const errorMsg = response.error || '注册失败';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '注册失败,请重试';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n } finally {\n setLoading(false);\n }\n },\n [apiClient]\n );\n\n /**\n * 用户登出\n */\n const logout = useCallback(async () => {\n setLoading(true);\n setError(null);\n\n try {\n await apiClient.logout();\n setUser(null);\n setIsLoggedIn(false);\n } catch (err) {\n console.error('登出失败:', err);\n setError(err instanceof Error ? err.message : '登出失败');\n // 即使登出失败,也清除本地状态\n setUser(null);\n setIsLoggedIn(false);\n } finally {\n setLoading(false);\n }\n }, [apiClient]);\n\n /**\n * 清除错误信息\n */\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n // 组件挂载时检查认证状态\n useEffect(() => {\n checkAuthStatus();\n }, [checkAuthStatus]);\n\n return {\n // 状态\n user,\n isLoggedIn,\n loading,\n checkingAuth,\n error,\n\n // 操作方法\n login,\n register,\n logout,\n refresh: checkAuthStatus,\n clearError,\n };\n}\n\n/**\n * 表单验证 Hook\n *\n * @example\n * ```typescript\n * const { values, errors, handleChange, handleBlur, validate } = useAuthForm({\n * email: '',\n * password: ''\n * })\n * ```\n */\nexport function useAuthForm<T extends Record<string, any>>(initialValues: T) {\n const [values, setValues] = useState<T>(initialValues);\n const [errors, setErrors] = useState<Partial<Record<keyof T, string>>>({});\n const [touched, setTouched] = useState<Partial<Record<keyof T, boolean>>>({});\n\n const handleChange = useCallback(\n (field: keyof T, value: any) => {\n setValues((prev: T) => ({ ...prev, [field]: value }));\n // 清除该字段的错误\n if (errors[field]) {\n setErrors((prev: Partial<Record<keyof T, string>>) => {\n const newErrors = { ...prev };\n delete newErrors[field];\n return newErrors;\n });\n }\n },\n [errors]\n );\n\n const handleBlur = useCallback((field: keyof T) => {\n setTouched((prev: Partial<Record<keyof T, boolean>>) => ({ ...prev, [field]: true }));\n }, []);\n\n const validate = useCallback(\n (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => {\n const newErrors: Partial<Record<keyof T, string>> = {};\n\n Object.keys(validationRules).forEach((key) => {\n const field = key as keyof T;\n const rule = validationRules[field];\n if (rule) {\n const error = rule(values[field]);\n if (error) {\n newErrors[field] = error;\n }\n }\n });\n\n setErrors(newErrors);\n return Object.keys(newErrors).length === 0;\n },\n [values]\n );\n\n const reset = useCallback(() => {\n setValues(initialValues);\n setErrors({});\n setTouched({});\n }, [initialValues]);\n\n return {\n values,\n errors,\n touched,\n handleChange,\n handleBlur,\n validate,\n reset,\n setValues,\n setErrors,\n };\n}\n\n"]}