@zhang_libo/resource-hub 1.0.11 → 1.0.12
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.
package/package.json
CHANGED
|
@@ -256,7 +256,13 @@ function AdminCategories() {
|
|
|
256
256
|
)}
|
|
257
257
|
|
|
258
258
|
{/* Create/Edit Modal */}
|
|
259
|
-
<window.Modal
|
|
259
|
+
<window.Modal
|
|
260
|
+
isOpen={showModal}
|
|
261
|
+
onClose={() => setShowModal(false)}
|
|
262
|
+
title={editTarget ? '编辑类别' : '新增类别'}
|
|
263
|
+
width="480px"
|
|
264
|
+
closeOnBackdrop={false}
|
|
265
|
+
>
|
|
260
266
|
<div>
|
|
261
267
|
<div style={{ marginBottom: '16px' }}>
|
|
262
268
|
<label style={modalLabelStyle}>类别名称</label>
|
|
@@ -331,7 +331,13 @@ function AdminUsers() {
|
|
|
331
331
|
)}
|
|
332
332
|
|
|
333
333
|
{/* Create/Edit Modal */}
|
|
334
|
-
<window.Modal
|
|
334
|
+
<window.Modal
|
|
335
|
+
isOpen={showModal}
|
|
336
|
+
onClose={() => setShowModal(false)}
|
|
337
|
+
title={editTarget ? '编辑用户' : '新增用户'}
|
|
338
|
+
width="480px"
|
|
339
|
+
closeOnBackdrop={false}
|
|
340
|
+
>
|
|
335
341
|
<form onSubmit={(e) => { e.preventDefault(); handleSave(); }}>
|
|
336
342
|
{formErrors.general && (
|
|
337
343
|
<div style={{ background: 'color-mix(in srgb, var(--danger) 8%, var(--surface-elevated))', border: '1px solid color-mix(in srgb, var(--danger) 22%, var(--control-border))', borderRadius: '10px', padding: '10px 14px', marginBottom: '14px', fontSize: '13px', color: 'var(--danger)' }}>
|
|
@@ -419,8 +425,13 @@ function AdminUsers() {
|
|
|
419
425
|
</window.Modal>
|
|
420
426
|
|
|
421
427
|
{/* Reset Password Modal */}
|
|
422
|
-
<window.Modal
|
|
423
|
-
|
|
428
|
+
<window.Modal
|
|
429
|
+
isOpen={!!resetTarget}
|
|
430
|
+
onClose={() => { setResetTarget(null); setResetError(''); }}
|
|
431
|
+
title={`重置密码 — ${resetTarget?.displayName || ''}`}
|
|
432
|
+
width="400px"
|
|
433
|
+
closeOnBackdrop={false}
|
|
434
|
+
>
|
|
424
435
|
<div>
|
|
425
436
|
<p style={{ fontSize: '14px', color: 'var(--text-secondary)', marginBottom: '14px' }}>
|
|
426
437
|
系统将自动生成临时密码并发送至用户邮箱,用户可凭临时密码登录后自行修改。
|
|
@@ -1,3 +1,52 @@
|
|
|
1
|
+
function PasswordField({ field, label, showKey, placeholder, autoComplete, value, showPassword, error, onChange, onToggleShow, onKeyDown, disabled }) {
|
|
2
|
+
return (
|
|
3
|
+
<div style={{ marginBottom: '14px' }}>
|
|
4
|
+
<label style={{
|
|
5
|
+
fontSize: '13px', fontWeight: 500, color: 'var(--text-primary)',
|
|
6
|
+
display: 'block', marginBottom: '6px',
|
|
7
|
+
}}>
|
|
8
|
+
{label}
|
|
9
|
+
</label>
|
|
10
|
+
<div style={{ position: 'relative' }}>
|
|
11
|
+
<input
|
|
12
|
+
type={showPassword ? 'text' : 'password'}
|
|
13
|
+
name={field}
|
|
14
|
+
autoComplete={autoComplete}
|
|
15
|
+
value={value}
|
|
16
|
+
placeholder={placeholder}
|
|
17
|
+
onChange={onChange}
|
|
18
|
+
onKeyDown={onKeyDown}
|
|
19
|
+
disabled={disabled}
|
|
20
|
+
style={{
|
|
21
|
+
width: '100%', padding: '8px 40px 8px 12px',
|
|
22
|
+
border: `1px solid ${error ? 'var(--danger)' : 'var(--border)'}`,
|
|
23
|
+
borderRadius: '8px', background: 'var(--bg-secondary)',
|
|
24
|
+
color: 'var(--text-primary)', fontSize: '14px',
|
|
25
|
+
outline: 'none', boxSizing: 'border-box',
|
|
26
|
+
}}
|
|
27
|
+
/>
|
|
28
|
+
<button
|
|
29
|
+
type="button"
|
|
30
|
+
onClick={onToggleShow}
|
|
31
|
+
style={{
|
|
32
|
+
position: 'absolute', right: '10px', top: '50%', transform: 'translateY(-50%)',
|
|
33
|
+
background: 'none', border: 'none', cursor: 'pointer',
|
|
34
|
+
color: 'var(--text-secondary)', display: 'flex', alignItems: 'center',
|
|
35
|
+
}}
|
|
36
|
+
>
|
|
37
|
+
{showPassword ? <lucide.EyeOff size={16} /> : <lucide.Eye size={16} />}
|
|
38
|
+
</button>
|
|
39
|
+
</div>
|
|
40
|
+
{field === 'newPassword' && (
|
|
41
|
+
<window.PasswordStrength password={value} />
|
|
42
|
+
)}
|
|
43
|
+
{error && (
|
|
44
|
+
<div style={{ fontSize: '12px', color: 'var(--danger)', marginTop: '4px' }}>{error}</div>
|
|
45
|
+
)}
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
1
50
|
function ChangePasswordModal({ isOpen, onClose }) {
|
|
2
51
|
const state = window.useAppState();
|
|
3
52
|
const dispatch = window.useAppDispatch();
|
|
@@ -72,52 +121,9 @@ function ChangePasswordModal({ isOpen, onClose }) {
|
|
|
72
121
|
}
|
|
73
122
|
};
|
|
74
123
|
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
fontSize: '13px', fontWeight: 500, color: 'var(--text-primary)',
|
|
79
|
-
display: 'block', marginBottom: '6px',
|
|
80
|
-
}}>
|
|
81
|
-
{label}
|
|
82
|
-
</label>
|
|
83
|
-
<div style={{ position: 'relative' }}>
|
|
84
|
-
<input
|
|
85
|
-
type={showFields[showKey] ? 'text' : 'password'}
|
|
86
|
-
name={field}
|
|
87
|
-
autoComplete={autoComplete}
|
|
88
|
-
value={form[field]}
|
|
89
|
-
placeholder={placeholder}
|
|
90
|
-
onChange={e => setForm(f => ({ ...f, [field]: e.target.value }))}
|
|
91
|
-
onKeyDown={e => { if (e.key === 'Enter') handleSubmit(); }}
|
|
92
|
-
disabled={loading}
|
|
93
|
-
style={{
|
|
94
|
-
width: '100%', padding: '8px 40px 8px 12px',
|
|
95
|
-
border: `1px solid ${errors[field] ? 'var(--danger)' : 'var(--border)'}`,
|
|
96
|
-
borderRadius: '8px', background: 'var(--bg-secondary)',
|
|
97
|
-
color: 'var(--text-primary)', fontSize: '14px',
|
|
98
|
-
outline: 'none', boxSizing: 'border-box',
|
|
99
|
-
}}
|
|
100
|
-
/>
|
|
101
|
-
<button
|
|
102
|
-
type="button"
|
|
103
|
-
onClick={() => setShowFields(s => ({ ...s, [showKey]: !s[showKey] }))}
|
|
104
|
-
style={{
|
|
105
|
-
position: 'absolute', right: '10px', top: '50%', transform: 'translateY(-50%)',
|
|
106
|
-
background: 'none', border: 'none', cursor: 'pointer',
|
|
107
|
-
color: 'var(--text-secondary)', display: 'flex', alignItems: 'center',
|
|
108
|
-
}}
|
|
109
|
-
>
|
|
110
|
-
{showFields[showKey] ? <lucide.EyeOff size={16} /> : <lucide.Eye size={16} />}
|
|
111
|
-
</button>
|
|
112
|
-
</div>
|
|
113
|
-
{field === 'newPassword' && (
|
|
114
|
-
<window.PasswordStrength password={form.newPassword} />
|
|
115
|
-
)}
|
|
116
|
-
{errors[field] && (
|
|
117
|
-
<div style={{ fontSize: '12px', color: 'var(--danger)', marginTop: '4px' }}>{errors[field]}</div>
|
|
118
|
-
)}
|
|
119
|
-
</div>
|
|
120
|
-
);
|
|
124
|
+
const handleFieldChange = (field) => (e) => setForm(f => ({ ...f, [field]: e.target.value }));
|
|
125
|
+
const handleToggleShow = (showKey) => () => setShowFields(s => ({ ...s, [showKey]: !s[showKey] }));
|
|
126
|
+
const handleKeyDown = (e) => { if (e.key === 'Enter') handleSubmit(); };
|
|
121
127
|
|
|
122
128
|
return (
|
|
123
129
|
<window.Modal isOpen={isOpen} onClose={onClose} title="修改密码" width="440px" closeOnBackdrop={false} closeOnEscape>
|
|
@@ -143,6 +149,13 @@ function ChangePasswordModal({ isOpen, onClose }) {
|
|
|
143
149
|
showKey="current"
|
|
144
150
|
placeholder="请输入当前密码"
|
|
145
151
|
autoComplete="current-password"
|
|
152
|
+
value={form.currentPassword}
|
|
153
|
+
showPassword={showFields.current}
|
|
154
|
+
error={errors.currentPassword}
|
|
155
|
+
onChange={handleFieldChange('currentPassword')}
|
|
156
|
+
onToggleShow={handleToggleShow('current')}
|
|
157
|
+
onKeyDown={handleKeyDown}
|
|
158
|
+
disabled={loading}
|
|
146
159
|
/>
|
|
147
160
|
<PasswordField
|
|
148
161
|
field="newPassword"
|
|
@@ -150,6 +163,13 @@ function ChangePasswordModal({ isOpen, onClose }) {
|
|
|
150
163
|
showKey="new"
|
|
151
164
|
placeholder="至少8位,含字母和数字"
|
|
152
165
|
autoComplete="new-password"
|
|
166
|
+
value={form.newPassword}
|
|
167
|
+
showPassword={showFields.new}
|
|
168
|
+
error={errors.newPassword}
|
|
169
|
+
onChange={handleFieldChange('newPassword')}
|
|
170
|
+
onToggleShow={handleToggleShow('new')}
|
|
171
|
+
onKeyDown={handleKeyDown}
|
|
172
|
+
disabled={loading}
|
|
153
173
|
/>
|
|
154
174
|
<PasswordField
|
|
155
175
|
field="confirmPassword"
|
|
@@ -157,6 +177,13 @@ function ChangePasswordModal({ isOpen, onClose }) {
|
|
|
157
177
|
showKey="confirm"
|
|
158
178
|
placeholder="再次输入新密码"
|
|
159
179
|
autoComplete="new-password"
|
|
180
|
+
value={form.confirmPassword}
|
|
181
|
+
showPassword={showFields.confirm}
|
|
182
|
+
error={errors.confirmPassword}
|
|
183
|
+
onChange={handleFieldChange('confirmPassword')}
|
|
184
|
+
onToggleShow={handleToggleShow('confirm')}
|
|
185
|
+
onKeyDown={handleKeyDown}
|
|
186
|
+
disabled={loading}
|
|
160
187
|
/>
|
|
161
188
|
|
|
162
189
|
<div style={{
|