sa2kit 1.0.0 → 1.0.2

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 (99) hide show
  1. package/dist/UniversalFileService-CEZRJ87g.d.mts +727 -0
  2. package/dist/UniversalFileService-CEZRJ87g.d.ts +727 -0
  3. package/dist/api/index.d.mts +248 -0
  4. package/dist/api/index.d.ts +248 -0
  5. package/dist/api/index.js +294 -0
  6. package/dist/api/index.js.map +1 -0
  7. package/dist/api/index.mjs +290 -0
  8. package/dist/api/index.mjs.map +1 -0
  9. package/dist/auth/client/index.d.mts +52 -3
  10. package/dist/auth/client/index.d.ts +52 -3
  11. package/dist/auth/components/index.d.mts +149 -4
  12. package/dist/auth/components/index.d.ts +149 -4
  13. package/dist/auth/components/index.js +243 -9
  14. package/dist/auth/components/index.js.map +1 -1
  15. package/dist/auth/components/index.mjs +237 -4
  16. package/dist/auth/components/index.mjs.map +1 -1
  17. package/dist/auth/hooks/index.d.mts +31 -2
  18. package/dist/auth/hooks/index.d.ts +31 -2
  19. package/dist/auth/index.d.mts +5 -5
  20. package/dist/auth/index.d.ts +5 -5
  21. package/dist/auth/index.js +49 -17
  22. package/dist/auth/index.mjs +1 -1
  23. package/dist/auth/routes/index.d.mts +103 -5
  24. package/dist/auth/routes/index.d.ts +103 -5
  25. package/dist/auth/routes/index.js +37 -5
  26. package/dist/auth/routes/index.mjs +1 -1
  27. package/dist/chunk-42IJ7HEI.js +573 -0
  28. package/dist/chunk-42IJ7HEI.js.map +1 -0
  29. package/dist/chunk-7XLFSPDG.mjs +31 -0
  30. package/dist/chunk-7XLFSPDG.mjs.map +1 -0
  31. package/dist/chunk-GCVOKQZP.js +36 -0
  32. package/dist/chunk-GCVOKQZP.js.map +1 -0
  33. package/dist/chunk-IBLB7ARJ.mjs +560 -0
  34. package/dist/chunk-IBLB7ARJ.mjs.map +1 -0
  35. package/dist/{chunk-6FNUWAIV.js → chunk-LX4XX6W7.js} +54 -8
  36. package/dist/chunk-LX4XX6W7.js.map +1 -0
  37. package/dist/{chunk-HXFFYNIF.mjs → chunk-T5OZHYVM.mjs} +54 -8
  38. package/dist/chunk-T5OZHYVM.mjs.map +1 -0
  39. package/dist/config/server/index.d.mts +1533 -0
  40. package/dist/config/server/index.d.ts +1533 -0
  41. package/dist/config/server/index.js +1177 -0
  42. package/dist/config/server/index.js.map +1 -0
  43. package/dist/config/server/index.mjs +1138 -0
  44. package/dist/config/server/index.mjs.map +1 -0
  45. package/dist/i18n/index.d.mts +2 -1
  46. package/dist/i18n/index.d.ts +2 -1
  47. package/dist/i18n/index.js +125 -61
  48. package/dist/i18n/index.js.map +1 -1
  49. package/dist/i18n/index.mjs +126 -62
  50. package/dist/i18n/index.mjs.map +1 -1
  51. package/dist/index.js +6 -6
  52. package/dist/index.mjs +1 -1
  53. package/dist/mmd/index.d.mts +346 -0
  54. package/dist/mmd/index.d.ts +346 -0
  55. package/dist/mmd/index.js +1535 -0
  56. package/dist/mmd/index.js.map +1 -0
  57. package/dist/mmd/index.mjs +1503 -0
  58. package/dist/mmd/index.mjs.map +1 -0
  59. package/dist/storage/index.d.mts +1 -0
  60. package/dist/storage/index.d.ts +1 -0
  61. package/dist/storage/index.js +9 -9
  62. package/dist/storage/index.mjs +1 -1
  63. package/dist/{index-8VoHap_4.d.mts → types-CroexXnI.d.ts} +38 -44
  64. package/dist/{index-8VoHap_4.d.ts → types-DmsXCWvm.d.mts} +38 -44
  65. package/dist/{types-DAxQ1MeY.d.ts → types-Dt0oqeFM.d.mts} +1 -1
  66. package/dist/{types-DT8LVCvE.d.mts → types-zK6kDzDQ.d.ts} +1 -1
  67. package/dist/universalExport/index.js +17 -32
  68. package/dist/universalExport/index.js.map +1 -1
  69. package/dist/universalExport/index.mjs +2 -29
  70. package/dist/universalExport/index.mjs.map +1 -1
  71. package/dist/universalExport/server/index.d.mts +849 -8
  72. package/dist/universalExport/server/index.d.ts +849 -8
  73. package/dist/universalExport/server/index.js +1382 -2
  74. package/dist/universalExport/server/index.js.map +1 -1
  75. package/dist/universalExport/server/index.mjs +1355 -3
  76. package/dist/universalExport/server/index.mjs.map +1 -1
  77. package/dist/universalFile/index.d.mts +54 -3
  78. package/dist/universalFile/index.d.ts +54 -3
  79. package/dist/universalFile/index.js +272 -0
  80. package/dist/universalFile/index.js.map +1 -1
  81. package/dist/universalFile/index.mjs +267 -1
  82. package/dist/universalFile/index.mjs.map +1 -1
  83. package/dist/universalFile/server/index.d.mts +2541 -469
  84. package/dist/universalFile/server/index.d.ts +2541 -469
  85. package/dist/universalFile/server/index.js +830 -64
  86. package/dist/universalFile/server/index.js.map +1 -1
  87. package/dist/universalFile/server/index.mjs +803 -66
  88. package/dist/universalFile/server/index.mjs.map +1 -1
  89. package/package.json +47 -23
  90. package/dist/chunk-6FNUWAIV.js.map +0 -1
  91. package/dist/chunk-APY57REU.js +0 -300
  92. package/dist/chunk-APY57REU.js.map +0 -1
  93. package/dist/chunk-C64RY2OW.mjs +0 -295
  94. package/dist/chunk-C64RY2OW.mjs.map +0 -1
  95. package/dist/chunk-HXFFYNIF.mjs.map +0 -1
  96. package/dist/types-CoGG1rNV.d.mts +0 -258
  97. package/dist/types-CoGG1rNV.d.ts +0 -258
  98. package/dist/types-DW9qar-w.d.mts +0 -52
  99. package/dist/types-DW9qar-w.d.ts +0 -52
@@ -1,6 +1,6 @@
1
1
  import { useAuth } from '../../chunk-KGRQNEIR.mjs';
2
2
  import '../../chunk-BJTO5JO5.mjs';
3
- import React, { useState } from 'react';
3
+ import React3, { useState, useEffect } from 'react';
4
4
 
5
5
  function LoginForm({ apiClient, onSuccess, onError, children }) {
6
6
  const { login, loading, error: authError, clearError } = useAuth(apiClient);
@@ -30,7 +30,7 @@ function LoginForm({ apiClient, onSuccess, onError, children }) {
30
30
  handlePasswordChange: setPassword,
31
31
  handleSubmit
32
32
  };
33
- return /* @__PURE__ */ React.createElement(React.Fragment, null, children(state));
33
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, children(state));
34
34
  }
35
35
  function RegisterForm({
36
36
  apiClient,
@@ -78,9 +78,242 @@ function RegisterForm({
78
78
  handleUsernameChange: setUsername,
79
79
  handleSubmit
80
80
  };
81
- return /* @__PURE__ */ React.createElement(React.Fragment, null, children(state));
81
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, children(state));
82
+ }
83
+ var DefaultContainer = ({ children }) => /* @__PURE__ */ React3.createElement("div", { className: "min-h-screen bg-gradient-to-br from-indigo-100 via-purple-50 to-pink-100 flex items-center justify-center px-4 py-12 relative overflow-hidden" }, /* @__PURE__ */ React3.createElement("div", { className: "absolute inset-0 overflow-hidden pointer-events-none" }, /* @__PURE__ */ React3.createElement(
84
+ "div",
85
+ {
86
+ className: "absolute -top-40 -right-40 w-80 h-80 bg-purple-300 rounded-full mix-blend-multiply filter blur-xl opacity-70",
87
+ style: {
88
+ animation: "blob 7s infinite"
89
+ }
90
+ }
91
+ ), /* @__PURE__ */ React3.createElement(
92
+ "div",
93
+ {
94
+ className: "absolute -bottom-40 -left-40 w-80 h-80 bg-indigo-300 rounded-full mix-blend-multiply filter blur-xl opacity-70",
95
+ style: {
96
+ animation: "blob 7s infinite",
97
+ animationDelay: "2s"
98
+ }
99
+ }
100
+ ), /* @__PURE__ */ React3.createElement(
101
+ "div",
102
+ {
103
+ className: "absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-80 h-80 bg-pink-300 rounded-full mix-blend-multiply filter blur-xl opacity-70",
104
+ style: {
105
+ animation: "blob 7s infinite",
106
+ animationDelay: "4s"
107
+ }
108
+ }
109
+ )), /* @__PURE__ */ React3.createElement("div", { className: "relative z-10" }, children), /* @__PURE__ */ React3.createElement("style", { dangerouslySetInnerHTML: { __html: `
110
+ @keyframes blob {
111
+ 0%, 100% { transform: translate(0, 0) scale(1); }
112
+ 25% { transform: translate(20px, -50px) scale(1.1); }
113
+ 50% { transform: translate(-20px, 20px) scale(0.9); }
114
+ 75% { transform: translate(50px, 50px) scale(1.05); }
115
+ }
116
+ ` } }));
117
+ var DefaultCard = ({ children }) => /* @__PURE__ */ React3.createElement("div", { className: "w-full max-w-md bg-white/95 backdrop-blur-xl rounded-2xl shadow-2xl border border-white/20 overflow-hidden" }, children);
118
+ var DefaultInput = (props) => /* @__PURE__ */ React3.createElement(
119
+ "input",
120
+ {
121
+ ...props,
122
+ className: "w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all duration-200 placeholder-gray-400 text-gray-900 hover:border-gray-300"
123
+ }
124
+ );
125
+ var DefaultButton = ({ children, disabled, type, ...props }) => /* @__PURE__ */ React3.createElement(
126
+ "button",
127
+ {
128
+ type: type || "button",
129
+ disabled,
130
+ ...props,
131
+ className: `w-full bg-gradient-to-r from-blue-50 to-indigo-50 border-2 border-dashed border-blue-300 text-blue-700 hover:from-blue-100 hover:to-indigo-100 hover:border-blue-400 px-4 py-2.5 rounded-xl text-sm font-medium transition-all duration-200 transform hover:scale-105 active:scale-95 ${disabled ? "opacity-60 cursor-not-allowed hover:scale-100 hover:shadow-none" : "block"}
132
+ }`,
133
+ style: {
134
+ backgroundSize: "200% 100%",
135
+ backgroundPosition: disabled ? "0% 0%" : "0% 0%",
136
+ display: "block"
137
+ },
138
+ onMouseEnter: (e) => {
139
+ if (!disabled) {
140
+ e.currentTarget.style.backgroundPosition = "100% 0%";
141
+ }
142
+ },
143
+ onMouseLeave: (e) => {
144
+ if (!disabled) {
145
+ e.currentTarget.style.backgroundPosition = "0% 0%";
146
+ }
147
+ }
148
+ },
149
+ children
150
+ );
151
+ var DefaultAlert = ({ children }) => /* @__PURE__ */ React3.createElement("div", { className: "bg-red-50 border-l-4 border-red-500 text-red-700 px-4 py-3 rounded-lg relative flex items-start space-x-3 shadow-sm" }, /* @__PURE__ */ React3.createElement("svg", { className: "w-5 h-5 text-red-500 mt-0.5 flex-shrink-0", fill: "currentColor", viewBox: "0 0 20 20" }, /* @__PURE__ */ React3.createElement("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z", clipRule: "evenodd" })), /* @__PURE__ */ React3.createElement("div", { className: "flex-1 text-sm" }, children));
152
+ var DefaultBadge = ({
153
+ children,
154
+ variant,
155
+ className = ""
156
+ }) => /* @__PURE__ */ React3.createElement(
157
+ "span",
158
+ {
159
+ className: `inline-flex items-center px-3 py-1.5 rounded-full text-xs font-semibold shadow-sm ${variant === "dev" ? "bg-gradient-to-r from-orange-400 to-amber-500 text-white border-0" : "bg-gray-100 text-gray-700 border border-gray-200"} ${className}`
160
+ },
161
+ children
162
+ );
163
+ function AdminLoginPage(props) {
164
+ const {
165
+ apiClient,
166
+ onLoginSuccess,
167
+ onLoginError,
168
+ checkPermission,
169
+ permissionDeniedMessage = "\u8BBF\u95EE\u88AB\u62D2\u7EDD\uFF1A\u9700\u8981\u7BA1\u7406\u5458\u6743\u9650",
170
+ devConfig,
171
+ texts = {},
172
+ analytics,
173
+ components,
174
+ classNames = {}
175
+ } = props;
176
+ const Container = components?.Container || DefaultContainer;
177
+ const Card = components?.Card || DefaultCard;
178
+ const Input = components?.Input || DefaultInput;
179
+ const Button = components?.Button || DefaultButton;
180
+ const Alert = components?.Alert || DefaultAlert;
181
+ components?.Badge || DefaultBadge;
182
+ const t = {
183
+ appName: texts.appName || "LyricNote",
184
+ appDescription: texts.appDescription || "\u667A\u80FD\u6B4C\u8BCD\u7BA1\u7406\u5E73\u53F0",
185
+ pageTitle: texts.pageTitle || "\u7BA1\u7406\u5458\u767B\u5F55",
186
+ pageSubtitle: texts.pageSubtitle || "\u8BF7\u4F7F\u7528\u7BA1\u7406\u5458\u8D26\u6237\u767B\u5F55\u7CFB\u7EDF",
187
+ emailLabel: texts.emailLabel || "\u7BA1\u7406\u5458\u90AE\u7BB1",
188
+ emailPlaceholder: texts.emailPlaceholder || "admin@example.com",
189
+ passwordLabel: texts.passwordLabel || "\u5BC6\u7801",
190
+ passwordPlaceholder: texts.passwordPlaceholder || "\u8BF7\u8F93\u5165\u5BC6\u7801",
191
+ loginButton: texts.loginButton || "\u767B\u5F55\u7BA1\u7406\u540E\u53F0",
192
+ loggingInButton: texts.loggingInButton || "\u767B\u5F55\u4E2D...",
193
+ fillTestAccount: texts.fillTestAccount || "\u586B\u5145\u6D4B\u8BD5\u8D26\u6237",
194
+ copyCredentials: texts.copyCredentials || "\u590D\u5236",
195
+ devModeLabel: texts.devModeLabel || "\u5F00\u53D1\u73AF\u5883",
196
+ testAccountInfo: texts.testAccountInfo || "\u6D4B\u8BD5\u8D26\u6237\u5DF2\u586B\u5145\uFF0C\u53EF\u76F4\u63A5\u767B\u5F55",
197
+ testAccountFilled: texts.testAccountFilled || "\u5DF2\u81EA\u52A8\u586B\u5145\u6D4B\u8BD5\u8D26\u6237\u4FE1\u606F",
198
+ footer: texts.footer || "\u4EC5\u9650\u7BA1\u7406\u5458\u8BBF\u95EE \u2022 \u7CFB\u7EDF\u5B89\u5168\u4FDD\u62A4"
199
+ };
200
+ const [email, setEmail] = useState("");
201
+ const [password, setPassword] = useState("");
202
+ const [showPassword, setShowPassword] = useState(false);
203
+ const [autoFilled, setAutoFilled] = useState(false);
204
+ const [localError, setLocalError] = useState("");
205
+ const isDevelopment = devConfig?.enabled ?? (typeof window !== "undefined" && (process.env.NODE_ENV === "development" || window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1"));
206
+ const testEmail = devConfig?.testEmail || "admin@example.com";
207
+ const testPassword = devConfig?.testPassword || "admin123";
208
+ const autoFillDelay = devConfig?.autoFillDelay || 2e3;
209
+ const { user, isLoggedIn, loading, error: authError, login, clearError } = useAuth(apiClient);
210
+ const error = authError || localError;
211
+ useEffect(() => {
212
+ if (typeof window !== "undefined" && analytics?.trackPageView) {
213
+ analytics.trackPageView({
214
+ pageName: "admin_login_page",
215
+ pageUrl: window.location.pathname
216
+ });
217
+ }
218
+ }, [analytics]);
219
+ useEffect(() => {
220
+ if (isDevelopment && !email && !password) {
221
+ const timer = setTimeout(() => {
222
+ if (!email && !password) {
223
+ setEmail(testEmail);
224
+ setPassword(testPassword);
225
+ setAutoFilled(true);
226
+ }
227
+ }, autoFillDelay);
228
+ return () => clearTimeout(timer);
229
+ }
230
+ return;
231
+ }, [isDevelopment, email, password, testEmail, testPassword, autoFillDelay]);
232
+ useEffect(() => {
233
+ if (user && isLoggedIn) {
234
+ if (checkPermission && !checkPermission(user)) {
235
+ setLocalError(permissionDeniedMessage);
236
+ analytics?.trackPermissionDenied?.(user);
237
+ return;
238
+ }
239
+ analytics?.trackLoginSuccess?.(user);
240
+ analytics?.setUser?.({
241
+ userId: user.id,
242
+ email: user.email,
243
+ role: user.role
244
+ });
245
+ onLoginSuccess?.(user);
246
+ }
247
+ }, [user, isLoggedIn, checkPermission, permissionDeniedMessage, analytics, onLoginSuccess]);
248
+ const handleSubmit = async (e) => {
249
+ e.preventDefault();
250
+ setLocalError("");
251
+ clearError();
252
+ try {
253
+ const result = await login(email, password);
254
+ if (!result.success) {
255
+ const errorMsg = result.error || "\u767B\u5F55\u5931\u8D25";
256
+ setLocalError(errorMsg);
257
+ analytics?.trackLoginFailed?.(errorMsg, email);
258
+ onLoginError?.(errorMsg);
259
+ }
260
+ } catch (err) {
261
+ const errorMsg = "\u767B\u5F55\u5931\u8D25\uFF1A\u7F51\u7EDC\u9519\u8BEF\u6216\u670D\u52A1\u5668\u9519\u8BEF";
262
+ setLocalError(errorMsg);
263
+ analytics?.trackLoginFailed?.(errorMsg, email);
264
+ onLoginError?.(errorMsg);
265
+ }
266
+ };
267
+ const fillTestAccount = () => {
268
+ setEmail(testEmail);
269
+ setPassword(testPassword);
270
+ setLocalError("");
271
+ setAutoFilled(true);
272
+ };
273
+ return /* @__PURE__ */ React3.createElement(Container, null, /* @__PURE__ */ React3.createElement("div", { className: "w-full max-w-md" }, /* @__PURE__ */ React3.createElement(Card, null, /* @__PURE__ */ React3.createElement("div", { className: "p-8" }, /* @__PURE__ */ React3.createElement("div", { className: "pb-8" }, /* @__PURE__ */ React3.createElement("h2", { className: "text-2xl font-bold text-center text-gray-800" }, t.pageTitle)), /* @__PURE__ */ React3.createElement("form", { onSubmit: handleSubmit, className: "space-y-5" }, error && /* @__PURE__ */ React3.createElement(Alert, null, error), /* @__PURE__ */ React3.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React3.createElement("label", { htmlFor: "email", className: "text-sm font-semibold text-gray-700 block" }, t.emailLabel), /* @__PURE__ */ React3.createElement(
274
+ Input,
275
+ {
276
+ id: "email",
277
+ type: "email",
278
+ value: email,
279
+ onChange: (e) => setEmail(e.target.value),
280
+ placeholder: t.emailPlaceholder,
281
+ required: true,
282
+ disabled: loading
283
+ }
284
+ )), /* @__PURE__ */ React3.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React3.createElement("label", { htmlFor: "password", className: "text-sm font-semibold text-gray-700 block" }, t.passwordLabel), /* @__PURE__ */ React3.createElement("div", { className: "relative" }, /* @__PURE__ */ React3.createElement(
285
+ Input,
286
+ {
287
+ id: "password",
288
+ type: showPassword ? "text" : "password",
289
+ value: password,
290
+ onChange: (e) => setPassword(e.target.value),
291
+ placeholder: t.passwordPlaceholder,
292
+ required: true,
293
+ disabled: loading
294
+ }
295
+ ), /* @__PURE__ */ React3.createElement(
296
+ "button",
297
+ {
298
+ type: "button",
299
+ onClick: () => setShowPassword(!showPassword),
300
+ className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600 transition-colors p-1",
301
+ disabled: loading,
302
+ title: showPassword ? "\u9690\u85CF\u5BC6\u7801" : "\u663E\u793A\u5BC6\u7801"
303
+ },
304
+ showPassword ? /* @__PURE__ */ React3.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React3.createElement("path", { fillRule: "evenodd", d: "M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z", clipRule: "evenodd" }), /* @__PURE__ */ React3.createElement("path", { d: "M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z" })) : /* @__PURE__ */ React3.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React3.createElement("path", { d: "M10 12a2 2 0 100-4 2 2 0 000 4z" }), /* @__PURE__ */ React3.createElement("path", { fillRule: "evenodd", d: "M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z", clipRule: "evenodd" }))
305
+ ))), isDevelopment && /* @__PURE__ */ React3.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React3.createElement(
306
+ "button",
307
+ {
308
+ type: "button",
309
+ onClick: fillTestAccount,
310
+ className: "w-full bg-gradient-to-r from-blue-50 to-indigo-50 border-2 border-dashed border-blue-300 text-blue-700 hover:from-blue-100 hover:to-indigo-100 hover:border-blue-400 px-4 py-2.5 rounded-xl text-sm font-medium transition-all duration-200 transform hover:scale-105 active:scale-95",
311
+ disabled: loading
312
+ },
313
+ t.fillTestAccount
314
+ )), /* @__PURE__ */ React3.createElement("div", { className: "pt-3" }, /* @__PURE__ */ React3.createElement(Button, { type: "submit", disabled: loading }, loading ? t.loggingInButton : t.loginButton)))))));
82
315
  }
83
316
 
84
- export { LoginForm, RegisterForm };
317
+ export { AdminLoginPage, LoginForm, RegisterForm };
85
318
  //# sourceMappingURL=index.mjs.map
86
319
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/auth/components/LoginForm.tsx","../../../src/auth/components/RegisterForm.tsx"],"names":["useState","React"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Auth Components - LoginForm (Headless)\n * 无样式的登录表单组件\n */\n\nimport React, { useState } from 'react';\nimport { useAuth } from '../hooks';\nimport type { HeadlessLoginFormProps, LoginFormState } from './types';\n\n/**\n * Headless 登录表单组件\n *\n * 提供登录逻辑但不包含任何 UI 样式,\n * 使用 render props 模式让用户完全控制 UI\n *\n * @example\n * ```tsx\n * <LoginForm apiClient={apiClient}>\n * {({ email, password, loading, error, handleEmailChange, handlePasswordChange, handleSubmit }) => (\n * <form onSubmit={handleSubmit}>\n * <input\n * value={email}\n * onChange={(e) => handleEmailChange(e.target.value)}\n * />\n * <input\n * type=\"password\"\n * value={password}\n * onChange={(e) => handlePasswordChange(e.target.value)}\n * />\n * {error && <div>{error}</div>}\n * <button disabled={loading}>\n * {loading ? '登录中...' : '登录'}\n * </button>\n * </form>\n * )}\n * </LoginForm>\n * ```\n */\nexport function LoginForm({ apiClient, onSuccess, onError, children }: HeadlessLoginFormProps) {\n const { login, loading, error: authError, clearError } = useAuth(apiClient);\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n\n const handleSubmit = async (e?: React.FormEvent) => {\n if (e) {\n e.preventDefault();\n }\n\n clearError();\n\n const result = await login(email, password);\n\n if (result.success) {\n // 登录成功后 user 会自动更新到 state\n const currentUser = apiClient.getUser();\n if (currentUser) {\n onSuccess?.(currentUser);\n }\n } else {\n onError?.(result.error || '登录失败');\n }\n };\n\n const state: LoginFormState = {\n email,\n password,\n loading,\n error: authError,\n handleEmailChange: setEmail,\n handlePasswordChange: setPassword,\n handleSubmit,\n };\n\n return <>{children(state)}</>;\n}\n\n","/**\n * Auth Components - RegisterForm (Headless)\n * 无样式的注册表单组件\n */\n\nimport React, { useState } from 'react';\nimport { useAuth } from '../hooks';\nimport type { HeadlessRegisterFormProps, RegisterFormState } from './types';\n\n/**\n * Headless 注册表单组件\n *\n * 提供注册逻辑但不包含任何 UI 样式,\n * 使用 render props 模式让用户完全控制 UI\n *\n * @example\n * ```tsx\n * <RegisterForm apiClient={apiClient}>\n * {({ email, password, username, loading, error, handleEmailChange, handlePasswordChange, handleUsernameChange, handleSubmit }) => (\n * <form onSubmit={handleSubmit}>\n * <input\n * value={email}\n * onChange={(e) => handleEmailChange(e.target.value)}\n * />\n * <input\n * value={username}\n * onChange={(e) => handleUsernameChange(e.target.value)}\n * />\n * <input\n * type=\"password\"\n * value={password}\n * onChange={(e) => handlePasswordChange(e.target.value)}\n * />\n * {error && <div>{error}</div>}\n * <button disabled={loading}>\n * {loading ? '注册中...' : '注册'}\n * </button>\n * </form>\n * )}\n * </RegisterForm>\n * ```\n */\nexport function RegisterForm({\n apiClient,\n onSuccess,\n onError,\n children,\n}: HeadlessRegisterFormProps) {\n const { register, loading, error: authError, clearError } = useAuth(apiClient);\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [username, setUsername] = useState('');\n\n const handleSubmit = async (e?: React.FormEvent) => {\n if (e) {\n e.preventDefault();\n }\n\n clearError();\n\n // 基础验证\n if (!email || !password || !username) {\n const errorMsg = '请填写所有字段';\n onError?.(errorMsg);\n return;\n }\n\n if (password.length < 6) {\n const errorMsg = '密码长度至少为 6 位';\n onError?.(errorMsg);\n return;\n }\n\n const result = await register(email, password, username);\n\n if (result.success) {\n // 注册成功后 user 会自动更新到 state\n const currentUser = apiClient.getUser();\n if (currentUser) {\n onSuccess?.(currentUser);\n }\n } else {\n onError?.(result.error || '注册失败');\n }\n };\n\n const state: RegisterFormState = {\n email,\n password,\n username,\n loading,\n error: authError,\n handleEmailChange: setEmail,\n handlePasswordChange: setPassword,\n handleUsernameChange: setUsername,\n handleSubmit,\n };\n\n return <>{children(state)}</>;\n}\n\n"]}
1
+ {"version":3,"sources":["../../../src/auth/components/LoginForm.tsx","../../../src/auth/components/RegisterForm.tsx","../../../src/auth/components/AdminLoginPage.tsx"],"names":["React","useState"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Auth Components - LoginForm (Headless)\n * 无样式的登录表单组件\n */\n\nimport React, { useState } from 'react';\nimport { useAuth } from '../hooks';\nimport type { HeadlessLoginFormProps, LoginFormState } from './types';\n\n/**\n * Headless 登录表单组件\n *\n * 提供登录逻辑但不包含任何 UI 样式,\n * 使用 render props 模式让用户完全控制 UI\n *\n * @example\n * ```tsx\n * <LoginForm apiClient={apiClient}>\n * {({ email, password, loading, error, handleEmailChange, handlePasswordChange, handleSubmit }) => (\n * <form onSubmit={handleSubmit}>\n * <input\n * value={email}\n * onChange={(e) => handleEmailChange(e.target.value)}\n * />\n * <input\n * type=\"password\"\n * value={password}\n * onChange={(e) => handlePasswordChange(e.target.value)}\n * />\n * {error && <div>{error}</div>}\n * <button disabled={loading}>\n * {loading ? '登录中...' : '登录'}\n * </button>\n * </form>\n * )}\n * </LoginForm>\n * ```\n */\nexport function LoginForm({ apiClient, onSuccess, onError, children }: HeadlessLoginFormProps) {\n const { login, loading, error: authError, clearError } = useAuth(apiClient);\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n\n const handleSubmit = async (e?: React.FormEvent) => {\n if (e) {\n e.preventDefault();\n }\n\n clearError();\n\n const result = await login(email, password);\n\n if (result.success) {\n // 登录成功后 user 会自动更新到 state\n const currentUser = apiClient.getUser();\n if (currentUser) {\n onSuccess?.(currentUser);\n }\n } else {\n onError?.(result.error || '登录失败');\n }\n };\n\n const state: LoginFormState = {\n email,\n password,\n loading,\n error: authError,\n handleEmailChange: setEmail,\n handlePasswordChange: setPassword,\n handleSubmit,\n };\n\n return <>{children(state)}</>;\n}\n\n","/**\n * Auth Components - RegisterForm (Headless)\n * 无样式的注册表单组件\n */\n\nimport React, { useState } from 'react';\nimport { useAuth } from '../hooks';\nimport type { HeadlessRegisterFormProps, RegisterFormState } from './types';\n\n/**\n * Headless 注册表单组件\n *\n * 提供注册逻辑但不包含任何 UI 样式,\n * 使用 render props 模式让用户完全控制 UI\n *\n * @example\n * ```tsx\n * <RegisterForm apiClient={apiClient}>\n * {({ email, password, username, loading, error, handleEmailChange, handlePasswordChange, handleUsernameChange, handleSubmit }) => (\n * <form onSubmit={handleSubmit}>\n * <input\n * value={email}\n * onChange={(e) => handleEmailChange(e.target.value)}\n * />\n * <input\n * value={username}\n * onChange={(e) => handleUsernameChange(e.target.value)}\n * />\n * <input\n * type=\"password\"\n * value={password}\n * onChange={(e) => handlePasswordChange(e.target.value)}\n * />\n * {error && <div>{error}</div>}\n * <button disabled={loading}>\n * {loading ? '注册中...' : '注册'}\n * </button>\n * </form>\n * )}\n * </RegisterForm>\n * ```\n */\nexport function RegisterForm({\n apiClient,\n onSuccess,\n onError,\n children,\n}: HeadlessRegisterFormProps) {\n const { register, loading, error: authError, clearError } = useAuth(apiClient);\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [username, setUsername] = useState('');\n\n const handleSubmit = async (e?: React.FormEvent) => {\n if (e) {\n e.preventDefault();\n }\n\n clearError();\n\n // 基础验证\n if (!email || !password || !username) {\n const errorMsg = '请填写所有字段';\n onError?.(errorMsg);\n return;\n }\n\n if (password.length < 6) {\n const errorMsg = '密码长度至少为 6 位';\n onError?.(errorMsg);\n return;\n }\n\n const result = await register(email, password, username);\n\n if (result.success) {\n // 注册成功后 user 会自动更新到 state\n const currentUser = apiClient.getUser();\n if (currentUser) {\n onSuccess?.(currentUser);\n }\n } else {\n onError?.(result.error || '注册失败');\n }\n };\n\n const state: RegisterFormState = {\n email,\n password,\n username,\n loading,\n error: authError,\n handleEmailChange: setEmail,\n handlePasswordChange: setPassword,\n handleUsernameChange: setUsername,\n handleSubmit,\n };\n\n return <>{children(state)}</>;\n}\n\n","/**\n * Admin Login Page Component\n * 完整的管理后台登录页面组件\n *\n * 功能:\n * - 邮箱密码登录\n * - 开发环境测试账户自动填充\n * - Analytics 埋点集成\n * - 角色权限检查\n * - 响应式设计\n */\n\nimport React, { useState, useEffect } from 'react';\nimport { useAuth } from '../hooks';\nimport type { BaseApiClient } from '../client/base-api-client';\nimport type { User } from '../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AdminLoginPageProps {\n /**\n * API 客户端实例\n */\n apiClient: BaseApiClient;\n\n /**\n * 登录成功后的回调\n */\n onLoginSuccess?: (user: User) => void;\n\n /**\n * 登录失败的回调\n */\n onLoginError?: (error: string) => void;\n\n /**\n * 权限检查函数(可选)\n * 返回 true 表示有权限,false 表示无权限\n */\n checkPermission?: (user: User) => boolean;\n\n /**\n * 权限不足时的错误消息\n */\n permissionDeniedMessage?: string;\n\n /**\n * 开发环境配置\n */\n devConfig?: {\n /**\n * 是否启用开发模式功能(自动填充等)\n */\n enabled?: boolean;\n\n /**\n * 测试账户邮箱\n */\n testEmail?: string;\n\n /**\n * 测试账户密码\n */\n testPassword?: string;\n\n /**\n * 自动填充延迟(毫秒)\n */\n autoFillDelay?: number;\n };\n\n /**\n * 页面文本配置\n */\n texts?: {\n appName?: string;\n appDescription?: string;\n pageTitle?: string;\n pageSubtitle?: string;\n emailLabel?: string;\n emailPlaceholder?: string;\n passwordLabel?: string;\n passwordPlaceholder?: string;\n loginButton?: string;\n loggingInButton?: string;\n fillTestAccount?: string;\n copyCredentials?: string;\n devModeLabel?: string;\n testAccountInfo?: string;\n testAccountFilled?: string;\n footer?: string;\n };\n\n /**\n * Analytics 集成(可选)\n */\n analytics?: {\n /**\n * 页面访问埋点\n */\n trackPageView?: (data: Record<string, any>) => void;\n\n /**\n * 登录成功埋点\n */\n trackLoginSuccess?: (user: User) => void;\n\n /**\n * 登录失败埋点\n */\n trackLoginFailed?: (error: string, email: string) => void;\n\n /**\n * 权限拒绝埋点\n */\n trackPermissionDenied?: (user: User) => void;\n\n /**\n * 设置用户信息\n */\n setUser?: (user: { userId: string; email: string; role: string }) => void;\n };\n\n /**\n * UI 组件(可选,用于自定义样式)\n */\n components?: {\n Container?: React.ComponentType<{ children: React.ReactNode }>;\n Card?: React.ComponentType<{ children: React.ReactNode }>;\n Input?: React.ComponentType<any>;\n Button?: React.ComponentType<any>;\n Alert?: React.ComponentType<{ children: React.ReactNode }>;\n Badge?: React.ComponentType<{ children: React.ReactNode; variant?: string }>;\n };\n\n /**\n * className 配置(用于 Tailwind CSS)\n */\n classNames?: {\n container?: string;\n card?: string;\n header?: string;\n form?: string;\n input?: string;\n button?: string;\n alert?: string;\n };\n}\n\n// ============================================================================\n// Default Components (Tailwind CSS based) - Modern & Beautiful Design\n// ============================================================================\n\nconst DefaultContainer: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <div className=\"min-h-screen bg-gradient-to-br from-indigo-100 via-purple-50 to-pink-100 flex items-center justify-center px-4 py-12 relative overflow-hidden\">\n {/* Animated background elements */}\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <div\n className=\"absolute -top-40 -right-40 w-80 h-80 bg-purple-300 rounded-full mix-blend-multiply filter blur-xl opacity-70\"\n style={{\n animation: 'blob 7s infinite',\n }}\n ></div>\n <div\n className=\"absolute -bottom-40 -left-40 w-80 h-80 bg-indigo-300 rounded-full mix-blend-multiply filter blur-xl opacity-70\"\n style={{\n animation: 'blob 7s infinite',\n animationDelay: '2s',\n }}\n ></div>\n <div\n className=\"absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-80 h-80 bg-pink-300 rounded-full mix-blend-multiply filter blur-xl opacity-70\"\n style={{\n animation: 'blob 7s infinite',\n animationDelay: '4s',\n }}\n ></div>\n </div>\n <div className=\"relative z-10\">\n {children}\n </div>\n <style dangerouslySetInnerHTML={{__html: `\n @keyframes blob {\n 0%, 100% { transform: translate(0, 0) scale(1); }\n 25% { transform: translate(20px, -50px) scale(1.1); }\n 50% { transform: translate(-20px, 20px) scale(0.9); }\n 75% { transform: translate(50px, 50px) scale(1.05); }\n }\n `}} />\n </div>\n);\n\nconst DefaultCard: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <div className=\"w-full max-w-md bg-white/95 backdrop-blur-xl rounded-2xl shadow-2xl border border-white/20 overflow-hidden\">\n {children}\n </div>\n);\n\nconst DefaultInput: React.FC<any> = (props) => (\n <input\n {...props}\n className=\"w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all duration-200 placeholder-gray-400 text-gray-900 hover:border-gray-300\"\n />\n);\n\nconst DefaultButton: React.FC<any> = ({ children, disabled, type, ...props }) => (\n <button\n type={type || 'button'}\n disabled={disabled}\n {...props}\n className={`w-full bg-gradient-to-r from-blue-50 to-indigo-50 border-2 border-dashed border-blue-300 text-blue-700 hover:from-blue-100 hover:to-indigo-100 hover:border-blue-400 px-4 py-2.5 rounded-xl text-sm font-medium transition-all duration-200 transform hover:scale-105 active:scale-95 ${\n disabled ? 'opacity-60 cursor-not-allowed hover:scale-100 hover:shadow-none' : 'block'}\n }`}\n style={{\n backgroundSize: '200% 100%',\n backgroundPosition: disabled ? '0% 0%' : '0% 0%',\n display: 'block',\n }}\n onMouseEnter={(e) => {\n if (!disabled) {\n e.currentTarget.style.backgroundPosition = '100% 0%';\n }\n }}\n onMouseLeave={(e) => {\n if (!disabled) {\n e.currentTarget.style.backgroundPosition = '0% 0%';\n }\n }}\n >\n {children}\n </button>\n);\n\nconst DefaultAlert: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <div className=\"bg-red-50 border-l-4 border-red-500 text-red-700 px-4 py-3 rounded-lg relative flex items-start space-x-3 shadow-sm\">\n <svg className=\"w-5 h-5 text-red-500 mt-0.5 flex-shrink-0\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clipRule=\"evenodd\"/>\n </svg>\n <div className=\"flex-1 text-sm\">{children}</div>\n </div>\n);\n\nconst DefaultBadge: React.FC<{ children: React.ReactNode; variant?: string; className?: string }> = ({\n children,\n variant,\n className = '',\n}) => (\n <span\n className={`inline-flex items-center px-3 py-1.5 rounded-full text-xs font-semibold shadow-sm ${\n variant === 'dev'\n ? 'bg-gradient-to-r from-orange-400 to-amber-500 text-white border-0'\n : 'bg-gray-100 text-gray-700 border border-gray-200'\n } ${className}`}\n >\n {children}\n </span>\n);\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport function AdminLoginPage(props: AdminLoginPageProps) {\n const {\n apiClient,\n onLoginSuccess,\n onLoginError,\n checkPermission,\n permissionDeniedMessage = '访问被拒绝:需要管理员权限',\n devConfig,\n texts = {},\n analytics,\n components,\n classNames = {},\n } = props;\n\n // Use custom or default components\n const Container = components?.Container || DefaultContainer;\n const Card = components?.Card || DefaultCard;\n const Input = components?.Input || DefaultInput;\n const Button = components?.Button || DefaultButton;\n const Alert = components?.Alert || DefaultAlert;\n const Badge = components?.Badge || DefaultBadge;\n\n // Default texts\n const t = {\n appName: texts.appName || 'LyricNote',\n appDescription: texts.appDescription || '智能歌词管理平台',\n pageTitle: texts.pageTitle || '管理员登录',\n pageSubtitle: texts.pageSubtitle || '请使用管理员账户登录系统',\n emailLabel: texts.emailLabel || '管理员邮箱',\n emailPlaceholder: texts.emailPlaceholder || 'admin@example.com',\n passwordLabel: texts.passwordLabel || '密码',\n passwordPlaceholder: texts.passwordPlaceholder || '请输入密码',\n loginButton: texts.loginButton || '登录管理后台',\n loggingInButton: texts.loggingInButton || '登录中...',\n fillTestAccount: texts.fillTestAccount || '填充测试账户',\n copyCredentials: texts.copyCredentials || '复制',\n devModeLabel: texts.devModeLabel || '开发环境',\n testAccountInfo: texts.testAccountInfo || '测试账户已填充,可直接登录',\n testAccountFilled: texts.testAccountFilled || '已自动填充测试账户信息',\n footer: texts.footer || '仅限管理员访问 • 系统安全保护',\n };\n\n // State\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [showPassword, setShowPassword] = useState(false);\n const [autoFilled, setAutoFilled] = useState(false);\n const [localError, setLocalError] = useState('');\n\n // Check if development mode\n const isDevelopment =\n devConfig?.enabled ??\n (typeof window !== 'undefined' &&\n (process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1'));\n\n // Test account config\n const testEmail = devConfig?.testEmail || 'admin@example.com';\n const testPassword = devConfig?.testPassword || 'admin123';\n const autoFillDelay = devConfig?.autoFillDelay || 2000;\n\n // Use auth hook\n const { user, isLoggedIn, loading, error: authError, login, clearError } = useAuth(apiClient as any);\n\n const error = authError || localError;\n\n // Track page view\n useEffect(() => {\n if (typeof window !== 'undefined' && analytics?.trackPageView) {\n analytics.trackPageView({\n pageName: 'admin_login_page',\n pageUrl: window.location.pathname,\n });\n }\n }, [analytics]);\n\n // Auto-fill test account in development\n useEffect(() => {\n if (isDevelopment && !email && !password) {\n const timer = setTimeout(() => {\n if (!email && !password) {\n setEmail(testEmail);\n setPassword(testPassword);\n setAutoFilled(true);\n }\n }, autoFillDelay);\n\n return () => clearTimeout(timer);\n }\n return; // Explicit return for all code paths\n }, [isDevelopment, email, password, testEmail, testPassword, autoFillDelay]);\n\n // Check permission after login\n useEffect(() => {\n if (user && isLoggedIn) {\n // Check permission if provided\n if (checkPermission && !checkPermission(user)) {\n setLocalError(permissionDeniedMessage);\n analytics?.trackPermissionDenied?.(user);\n return;\n }\n\n // Track login success\n analytics?.trackLoginSuccess?.(user);\n analytics?.setUser?.({\n userId: user.id,\n email: user.email,\n role: user.role,\n });\n\n // Call success callback\n onLoginSuccess?.(user);\n }\n }, [user, isLoggedIn, checkPermission, permissionDeniedMessage, analytics, onLoginSuccess]);\n\n // Handle login submit\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setLocalError('');\n clearError();\n\n try {\n const result = await login(email, password);\n\n if (!result.success) {\n const errorMsg = result.error || '登录失败';\n setLocalError(errorMsg);\n analytics?.trackLoginFailed?.(errorMsg, email);\n onLoginError?.(errorMsg);\n }\n } catch (err) {\n const errorMsg = '登录失败:网络错误或服务器错误';\n setLocalError(errorMsg);\n analytics?.trackLoginFailed?.(errorMsg, email);\n onLoginError?.(errorMsg);\n }\n };\n\n // Fill test account\n const fillTestAccount = () => {\n setEmail(testEmail);\n setPassword(testPassword);\n setLocalError('');\n setAutoFilled(true);\n };\n\n // Copy test credentials\n const copyTestCredentials = async () => {\n const credentials = `邮箱: ${testEmail}\\n密码: ${testPassword}`;\n try {\n await navigator.clipboard.writeText(credentials);\n } catch (err) {\n console.warn('复制失败,请手动复制');\n }\n };\n\n return (\n <Container>\n <div className=\"w-full max-w-md\">\n {/* Login Form Card */}\n <Card>\n <div className=\"p-8\">\n {/* Title */}\n <div className=\"pb-8\">\n <h2 className=\"text-2xl font-bold text-center text-gray-800\">{t.pageTitle}</h2>\n </div>\n\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n {/* Error Alert */}\n {error && <Alert>{error}</Alert>}\n\n {/* Email Input */}\n <div className=\"space-y-2\">\n <label htmlFor=\"email\" className=\"text-sm font-semibold text-gray-700 block\">\n {t.emailLabel}\n </label>\n <Input\n id=\"email\"\n type=\"email\"\n value={email}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setEmail(e.target.value)}\n placeholder={t.emailPlaceholder}\n required\n disabled={loading}\n />\n </div>\n\n {/* Password Input */}\n <div className=\"space-y-2\">\n <label htmlFor=\"password\" className=\"text-sm font-semibold text-gray-700 block\">\n {t.passwordLabel}\n </label>\n <div className=\"relative\">\n <Input\n id=\"password\"\n type={showPassword ? 'text' : 'password'}\n value={password}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setPassword(e.target.value)\n }\n placeholder={t.passwordPlaceholder}\n required\n disabled={loading}\n />\n <button\n type=\"button\"\n onClick={() => setShowPassword(!showPassword)}\n className=\"absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600 transition-colors p-1\"\n disabled={loading}\n title={showPassword ? '隐藏密码' : '显示密码'}\n >\n {showPassword ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fillRule=\"evenodd\" d=\"M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z\" clipRule=\"evenodd\" />\n <path d=\"M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z\" />\n </svg>\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M10 12a2 2 0 100-4 2 2 0 000 4z\" />\n <path fillRule=\"evenodd\" d=\"M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z\" clipRule=\"evenodd\" />\n </svg>\n )}\n </button>\n </div>\n </div>\n\n {/* Dev Mode: Test Account Button */}\n {isDevelopment && (\n <div className=\"pt-2\">\n <button\n type=\"button\"\n onClick={fillTestAccount}\n className=\"w-full bg-gradient-to-r from-blue-50 to-indigo-50 border-2 border-dashed border-blue-300 text-blue-700 hover:from-blue-100 hover:to-indigo-100 hover:border-blue-400 px-4 py-2.5 rounded-xl text-sm font-medium transition-all duration-200 transform hover:scale-105 active:scale-95\"\n disabled={loading}\n >\n {t.fillTestAccount}\n </button>\n </div>\n )}\n\n {/* Submit Button */}\n <div className=\"pt-3\">\n <Button type=\"submit\" disabled={loading}>\n {loading ? t.loggingInButton : t.loginButton}\n </Button>\n </div>\n </form>\n </div>\n </Card>\n </div>\n </Container>\n );\n}\n\n"]}
@@ -1,2 +1,31 @@
1
- export { A as AuthResult, B as BaseApiClient, U as UseAuthReturn, b as User, u as useAuth, a as useAuthForm } from '../../index-8VoHap_4.mjs';
2
- import 'react';
1
+ import * as React from 'react';
2
+ import { b as BaseApiClient, U as UseAuthReturn } from '../../types-DmsXCWvm.mjs';
3
+ export { A as AuthResult, a as User } from '../../types-DmsXCWvm.mjs';
4
+ import '../../enums-Dume-V5Y.mjs';
5
+ import 'drizzle-orm/pg-core';
6
+
7
+ declare function useAuth(apiClient: BaseApiClient): UseAuthReturn;
8
+ /**
9
+ * 表单验证 Hook
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const { values, errors, handleChange, handleBlur, validate } = useAuthForm({
14
+ * email: '',
15
+ * password: ''
16
+ * })
17
+ * ```
18
+ */
19
+ declare function useAuthForm<T extends Record<string, any>>(initialValues: T): {
20
+ values: T;
21
+ errors: Partial<Record<keyof T, string>>;
22
+ touched: Partial<Record<keyof T, boolean>>;
23
+ handleChange: (field: keyof T, value: any) => void;
24
+ handleBlur: (field: keyof T) => void;
25
+ validate: (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => boolean;
26
+ reset: () => void;
27
+ setValues: React.Dispatch<React.SetStateAction<T>>;
28
+ setErrors: React.Dispatch<React.SetStateAction<Partial<Record<keyof T, string>>>>;
29
+ };
30
+
31
+ export { BaseApiClient, UseAuthReturn, useAuth, useAuthForm };
@@ -1,2 +1,31 @@
1
- export { A as AuthResult, B as BaseApiClient, U as UseAuthReturn, b as User, u as useAuth, a as useAuthForm } from '../../index-8VoHap_4.js';
2
- import 'react';
1
+ import * as React from 'react';
2
+ import { b as BaseApiClient, U as UseAuthReturn } from '../../types-CroexXnI.js';
3
+ export { A as AuthResult, a as User } from '../../types-CroexXnI.js';
4
+ import '../../enums-Dume-V5Y.js';
5
+ import 'drizzle-orm/pg-core';
6
+
7
+ declare function useAuth(apiClient: BaseApiClient): UseAuthReturn;
8
+ /**
9
+ * 表单验证 Hook
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const { values, errors, handleChange, handleBlur, validate } = useAuthForm({
14
+ * email: '',
15
+ * password: ''
16
+ * })
17
+ * ```
18
+ */
19
+ declare function useAuthForm<T extends Record<string, any>>(initialValues: T): {
20
+ values: T;
21
+ errors: Partial<Record<keyof T, string>>;
22
+ touched: Partial<Record<keyof T, boolean>>;
23
+ handleChange: (field: keyof T, value: any) => void;
24
+ handleBlur: (field: keyof T) => void;
25
+ validate: (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => boolean;
26
+ reset: () => void;
27
+ setValues: React.Dispatch<React.SetStateAction<T>>;
28
+ setErrors: React.Dispatch<React.SetStateAction<Partial<Record<keyof T, string>>>>;
29
+ };
30
+
31
+ export { BaseApiClient, UseAuthReturn, useAuth, useAuthForm };
@@ -2,12 +2,12 @@ export { U as UserRole, u as userRole } from '../enums-Dume-V5Y.mjs';
2
2
  export { Account, NewAccount, NewSession, NewUser, NewVerification, Session, User, Verification, account, accountRelations, session, sessionRelations, user, userRelations, verifications } from './schema/index.mjs';
3
3
  export { A as AuthResult, a as AuthServiceConfig, D as DrizzleAuthService, S as SessionInfo, U as UserInfo, V as VerifyResult } from '../drizzle-auth-service-DZY2F1sv.mjs';
4
4
  export { JwtPayload, generateToken, getTokenFromRequest, hashPassword, verifyJwtToken, verifyPassword } from './services/index.mjs';
5
- export { ApiResponse, BaseRouteConfig, LoginRouteConfig, RegisterRouteConfig, createLoginHandler, createLogoutHandler, createMeHandler, createRegisterHandler } from './routes/index.mjs';
5
+ export { AnalyticsEvent, AnalyticsService, ApiResponse, BaseRouteConfig, LoginRouteConfig, RegisterRouteConfig, createAnalyticsAdapter, createDefaultBaseConfig, createDefaultLoginConfig, createDefaultRegisterConfig, createLoginHandler, createLoginOptionsHandler, createLogoutHandler, createLogoutOptionsHandler, createMeHandler, createMeOptionsHandler, createRegisterHandler, createRegisterOptionsHandler } from './routes/index.mjs';
6
6
  export { AuthLevel, AuthMiddlewareConfig, RouteContext, RouteHandler, createAuthMiddleware } from './middleware/index.mjs';
7
- export { L as LoginFormData, R as RegisterFormData, U as UseAuthReturn, u as useAuth, a as useAuthForm } from '../index-8VoHap_4.mjs';
8
- export { BaseApiClient } from './client/index.mjs';
9
- export { A as API_ROUTES, S as STORAGE_KEYS } from '../types-DW9qar-w.mjs';
10
- export { L as LoginFormState, R as RegisterFormState } from '../types-DT8LVCvE.mjs';
7
+ export { useAuth, useAuthForm } from './hooks/index.mjs';
8
+ export { API_ROUTES, BaseApiClient, STORAGE_KEYS } from './client/index.mjs';
9
+ export { L as LoginFormState, R as RegisterFormState } from '../types-Dt0oqeFM.mjs';
10
+ export { B as BaseUser, L as LoginForm, R as RegisterForm, U as UseAuthReturn } from '../types-DmsXCWvm.mjs';
11
11
  import 'drizzle-orm/pg-core';
12
12
  import 'drizzle-orm';
13
13
  import 'react';
@@ -2,12 +2,12 @@ export { U as UserRole, u as userRole } from '../enums-Dume-V5Y.js';
2
2
  export { Account, NewAccount, NewSession, NewUser, NewVerification, Session, User, Verification, account, accountRelations, session, sessionRelations, user, userRelations, verifications } from './schema/index.js';
3
3
  export { A as AuthResult, a as AuthServiceConfig, D as DrizzleAuthService, S as SessionInfo, U as UserInfo, V as VerifyResult } from '../drizzle-auth-service-Bxlovhv8.js';
4
4
  export { JwtPayload, generateToken, getTokenFromRequest, hashPassword, verifyJwtToken, verifyPassword } from './services/index.js';
5
- export { ApiResponse, BaseRouteConfig, LoginRouteConfig, RegisterRouteConfig, createLoginHandler, createLogoutHandler, createMeHandler, createRegisterHandler } from './routes/index.js';
5
+ export { AnalyticsEvent, AnalyticsService, ApiResponse, BaseRouteConfig, LoginRouteConfig, RegisterRouteConfig, createAnalyticsAdapter, createDefaultBaseConfig, createDefaultLoginConfig, createDefaultRegisterConfig, createLoginHandler, createLoginOptionsHandler, createLogoutHandler, createLogoutOptionsHandler, createMeHandler, createMeOptionsHandler, createRegisterHandler, createRegisterOptionsHandler } from './routes/index.js';
6
6
  export { AuthLevel, AuthMiddlewareConfig, RouteContext, RouteHandler, createAuthMiddleware } from './middleware/index.js';
7
- export { L as LoginFormData, R as RegisterFormData, U as UseAuthReturn, u as useAuth, a as useAuthForm } from '../index-8VoHap_4.js';
8
- export { BaseApiClient } from './client/index.js';
9
- export { A as API_ROUTES, S as STORAGE_KEYS } from '../types-DW9qar-w.js';
10
- export { L as LoginFormState, R as RegisterFormState } from '../types-DAxQ1MeY.js';
7
+ export { useAuth, useAuthForm } from './hooks/index.js';
8
+ export { API_ROUTES, BaseApiClient, STORAGE_KEYS } from './client/index.js';
9
+ export { L as LoginFormState, R as RegisterFormState } from '../types-zK6kDzDQ.js';
10
+ export { B as BaseUser, L as LoginForm, R as RegisterForm, U as UseAuthReturn } from '../types-CroexXnI.js';
11
11
  import 'drizzle-orm/pg-core';
12
12
  import 'drizzle-orm';
13
13
  import 'react';
@@ -1,15 +1,63 @@
1
1
  'use strict';
2
2
 
3
+ var chunk42IJ7HEI_js = require('../chunk-42IJ7HEI.js');
3
4
  var chunkFV3FNHQY_js = require('../chunk-FV3FNHQY.js');
4
5
  var chunkO26VCNS3_js = require('../chunk-O26VCNS3.js');
5
6
  var chunkROEYW4A7_js = require('../chunk-ROEYW4A7.js');
6
- var chunkAPY57REU_js = require('../chunk-APY57REU.js');
7
7
  var chunk6BL3AZGD_js = require('../chunk-6BL3AZGD.js');
8
8
  var chunkSVWQN2LR_js = require('../chunk-SVWQN2LR.js');
9
9
  require('../chunk-DGUM43GV.js');
10
10
 
11
11
 
12
12
 
13
+ Object.defineProperty(exports, "createAnalyticsAdapter", {
14
+ enumerable: true,
15
+ get: function () { return chunk42IJ7HEI_js.createAnalyticsAdapter; }
16
+ });
17
+ Object.defineProperty(exports, "createDefaultBaseConfig", {
18
+ enumerable: true,
19
+ get: function () { return chunk42IJ7HEI_js.createDefaultBaseConfig; }
20
+ });
21
+ Object.defineProperty(exports, "createDefaultLoginConfig", {
22
+ enumerable: true,
23
+ get: function () { return chunk42IJ7HEI_js.createDefaultLoginConfig; }
24
+ });
25
+ Object.defineProperty(exports, "createDefaultRegisterConfig", {
26
+ enumerable: true,
27
+ get: function () { return chunk42IJ7HEI_js.createDefaultRegisterConfig; }
28
+ });
29
+ Object.defineProperty(exports, "createLoginHandler", {
30
+ enumerable: true,
31
+ get: function () { return chunk42IJ7HEI_js.createLoginHandler; }
32
+ });
33
+ Object.defineProperty(exports, "createLoginOptionsHandler", {
34
+ enumerable: true,
35
+ get: function () { return chunk42IJ7HEI_js.createLoginOptionsHandler; }
36
+ });
37
+ Object.defineProperty(exports, "createLogoutHandler", {
38
+ enumerable: true,
39
+ get: function () { return chunk42IJ7HEI_js.createLogoutHandler; }
40
+ });
41
+ Object.defineProperty(exports, "createLogoutOptionsHandler", {
42
+ enumerable: true,
43
+ get: function () { return chunk42IJ7HEI_js.createLogoutOptionsHandler; }
44
+ });
45
+ Object.defineProperty(exports, "createMeHandler", {
46
+ enumerable: true,
47
+ get: function () { return chunk42IJ7HEI_js.createMeHandler; }
48
+ });
49
+ Object.defineProperty(exports, "createMeOptionsHandler", {
50
+ enumerable: true,
51
+ get: function () { return chunk42IJ7HEI_js.createMeOptionsHandler; }
52
+ });
53
+ Object.defineProperty(exports, "createRegisterHandler", {
54
+ enumerable: true,
55
+ get: function () { return chunk42IJ7HEI_js.createRegisterHandler; }
56
+ });
57
+ Object.defineProperty(exports, "createRegisterOptionsHandler", {
58
+ enumerable: true,
59
+ get: function () { return chunk42IJ7HEI_js.createRegisterOptionsHandler; }
60
+ });
13
61
  Object.defineProperty(exports, "createAuthMiddleware", {
14
62
  enumerable: true,
15
63
  get: function () { return chunkFV3FNHQY_js.createAuthMiddleware; }
@@ -34,22 +82,6 @@ Object.defineProperty(exports, "useAuthForm", {
34
82
  enumerable: true,
35
83
  get: function () { return chunkROEYW4A7_js.useAuthForm; }
36
84
  });
37
- Object.defineProperty(exports, "createLoginHandler", {
38
- enumerable: true,
39
- get: function () { return chunkAPY57REU_js.createLoginHandler; }
40
- });
41
- Object.defineProperty(exports, "createLogoutHandler", {
42
- enumerable: true,
43
- get: function () { return chunkAPY57REU_js.createLogoutHandler; }
44
- });
45
- Object.defineProperty(exports, "createMeHandler", {
46
- enumerable: true,
47
- get: function () { return chunkAPY57REU_js.createMeHandler; }
48
- });
49
- Object.defineProperty(exports, "createRegisterHandler", {
50
- enumerable: true,
51
- get: function () { return chunkAPY57REU_js.createRegisterHandler; }
52
- });
53
85
  Object.defineProperty(exports, "DrizzleAuthService", {
54
86
  enumerable: true,
55
87
  get: function () { return chunk6BL3AZGD_js.DrizzleAuthService; }
@@ -1,7 +1,7 @@
1
+ export { createAnalyticsAdapter, createDefaultBaseConfig, createDefaultLoginConfig, createDefaultRegisterConfig, createLoginHandler, createLoginOptionsHandler, createLogoutHandler, createLogoutOptionsHandler, createMeHandler, createMeOptionsHandler, createRegisterHandler, createRegisterOptionsHandler } from '../chunk-IBLB7ARJ.mjs';
1
2
  export { createAuthMiddleware } from '../chunk-6VHWOPRR.mjs';
2
3
  export { API_ROUTES, BaseApiClient, STORAGE_KEYS } from '../chunk-HEMA7SWK.mjs';
3
4
  export { useAuth, useAuthForm } from '../chunk-KGRQNEIR.mjs';
4
- export { createLoginHandler, createLogoutHandler, createMeHandler, createRegisterHandler } from '../chunk-C64RY2OW.mjs';
5
5
  export { DrizzleAuthService, generateToken, getTokenFromRequest, hashPassword, verifyJwtToken, verifyPassword } from '../chunk-U2L6V7KD.mjs';
6
6
  export { account, accountRelations, session, sessionRelations, user, userRelations, userRole, verifications } from '../chunk-AIKEVVDR.mjs';
7
7
  import '../chunk-BJTO5JO5.mjs';