fix: 修复管理员邮箱验证逻辑并优化表单样式

修复管理员邮箱验证时不再需要同时检查adminEnabled标志
优化AdminAuthModal的更新逻辑,减少不必要的渲染
统一表单输入框样式,添加cwd-form-input类
调整评论表单的代码格式和退出验证按钮的显示
This commit is contained in:
anghunk
2026-01-20 17:01:31 +08:00
parent 586fd25834
commit 5fdbc5077b
4 changed files with 96 additions and 36 deletions

View File

@@ -8,6 +8,11 @@ export class AdminAuthModal extends Component {
error: '', error: '',
loading: false loading: false
}; };
this.elements = {
input: null,
error: null,
submitBtn: null
};
} }
render() { render() {
@@ -71,14 +76,48 @@ export class AdminAuthModal extends Component {
this.empty(this.container); this.empty(this.container);
this.container.appendChild(overlay); this.container.appendChild(overlay);
// Focus input this.elements.input = overlay.querySelector('input');
const input = overlay.querySelector('input'); this.elements.error = overlay.querySelector('.cwd-error-text');
this.elements.submitBtn = overlay.querySelector('.cwd-btn-primary');
this.update();
const input = this.elements.input;
if (input) setTimeout(() => input.focus(), 50); if (input) setTimeout(() => input.focus(), 50);
} }
setState(newState) { setState(newState) {
this.state = { ...this.state, ...newState }; this.state = { ...this.state, ...newState };
this.render(); this.update();
}
update() {
const { key, error, loading } = this.state;
if (this.elements.input) {
this.elements.input.value = key;
this.elements.input.disabled = loading;
if (error) {
this.elements.input.classList.add('cwd-input-error');
} else {
this.elements.input.classList.remove('cwd-input-error');
}
}
if (this.elements.error) {
if (error) {
this.elements.error.textContent = error;
this.elements.error.style.display = '';
} else {
this.elements.error.textContent = '';
this.elements.error.style.display = 'none';
}
}
if (this.elements.submitBtn) {
this.elements.submitBtn.disabled = loading || !key;
this.elements.submitBtn.textContent = loading ? '验证中...' : '验证';
}
} }
handleSubmit() { handleSubmit() {

View File

@@ -31,8 +31,8 @@ export class CommentForm extends Component {
const { localForm } = this.state; const { localForm } = this.state;
const canSubmit = localForm.name.trim() && localForm.email.trim() && localForm.content.trim(); const canSubmit = localForm.name.trim() && localForm.email.trim() && localForm.content.trim();
const isAdmin = this.props.adminEmail && localForm.email.trim() === this.props.adminEmail; const isAdmin = this.props.adminEmail && localForm.email.trim() === this.props.adminEmail;
const isVerified = isAdmin && auth.hasToken(); const isVerified = isAdmin && auth.hasToken();
const root = this.createElement('form', { const root = this.createElement('form', {
className: 'cwd-comment-form', className: 'cwd-comment-form',
@@ -55,30 +55,31 @@ export class CommentForm extends Component {
// 昵称 // 昵称
this.createFormField('昵称 *', 'text', 'name', localForm.name, formErrors.name), this.createFormField('昵称 *', 'text', 'name', localForm.name, formErrors.name),
// 邮箱 // 邮箱
this.createElement('div', { this.createElement('div', {
className: 'cwd-form-field-wrapper', className: 'cwd-form-field-wrapper',
children: [ children: [
this.createFormField('邮箱 *', 'email', 'email', localForm.email, formErrors.email), this.createFormField('邮箱 *', 'email', 'email', localForm.email, formErrors.email),
isVerified ? this.createElement('div', { isVerified
className: 'cwd-admin-controls', ? this.createElement('div', {
children: [ className: 'cwd-admin-controls',
this.createTextElement('span', '✓ 已验证', 'cwd-admin-verified'), children: [
this.createElement('button', { this.createElement('button', {
className: 'cwd-btn-text', className: 'cwd-btn-text',
text: '退出', text: '退出验证',
attributes: { attributes: {
type: 'button', type: 'button',
title: '清除管理员凭证', title: '清除管理员凭证',
onClick: () => { onClick: () => {
auth.clearToken(); auth.clearToken();
this.render(); this.render();
} },
} },
}) }),
] ],
}) : null })
] : null,
}), ],
}),
// 网址 // 网址
this.createFormField('网址', 'url', 'url', localForm.url, formErrors.url), this.createFormField('网址', 'url', 'url', localForm.url, formErrors.url),
], ],
@@ -248,7 +249,7 @@ export class CommentForm extends Component {
onInput: (e) => this.handleFieldChange(fieldName, e.target.value), onInput: (e) => this.handleFieldChange(fieldName, e.target.value),
onBlur: (e) => { onBlur: (e) => {
if (fieldName === 'email') this.handleEmailBlur(e.target.value); if (fieldName === 'email') this.handleEmailBlur(e.target.value);
} },
}, },
}), }),
...(error ? [this.createTextElement('span', error, 'cwd-error-text')] : []), ...(error ? [this.createTextElement('span', error, 'cwd-error-text')] : []),
@@ -324,7 +325,7 @@ export class CommentForm extends Component {
this.modal.destroy(); this.modal.destroy();
this.modal = null; this.modal = null;
} }
} },
}); });
this.modal.render(); this.modal.render();
} }

View File

@@ -151,7 +151,7 @@ export class CWDComments {
if (serverConfig.avatarPrefix) { if (serverConfig.avatarPrefix) {
this.config.avatarPrefix = serverConfig.avatarPrefix; this.config.avatarPrefix = serverConfig.avatarPrefix;
} }
if (serverConfig.adminEnabled && serverConfig.adminEmail) { if (serverConfig.adminEmail) {
this.config.adminEmail = serverConfig.adminEmail; this.config.adminEmail = serverConfig.adminEmail;
} }
if (serverConfig.adminEnabled && serverConfig.adminBadge) { if (serverConfig.adminEnabled && serverConfig.adminBadge) {

View File

@@ -426,7 +426,7 @@
margin: 0 0 8px; margin: 0 0 8px;
} }
.cwd-comment-content li + li { .cwd-comment-content li+li {
margin-top: 4px; margin-top: 4px;
} }
@@ -737,8 +737,15 @@
} }
@keyframes cwd-modal-in { @keyframes cwd-modal-in {
from { opacity: 0; transform: scale(0.95); } from {
to { opacity: 1; transform: scale(1); } opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
} }
.cwd-modal-title { .cwd-modal-title {
@@ -760,6 +767,19 @@
color: var(--cwd-text-secondary, #6e7781); color: var(--cwd-text-secondary, #6e7781);
} }
.cwd-form-input {
width: 100%;
padding: 8px 12px;
font-size: 14px;
line-height: 1.5;
color: var(--cwd-text, #24292f);
background: var(--cwd-bg-input, #ffffff);
border: 1px solid var(--cwd-border, #d0d7de);
border-radius: var(--cwd-radius, 6px);
transition: border-color 0.2s, box-shadow 0.2s;
font-family: inherit;
}
.cwd-modal-actions { .cwd-modal-actions {
padding: 16px 20px; padding: 16px 20px;
background: var(--cwd-bg-secondary, #f6f8fa); background: var(--cwd-bg-secondary, #f6f8fa);