Skip to content

Commit ec9a5e3

Browse files
许君山许君山
authored andcommitted
style: remove error message block and use input styling for validation feedback
1 parent 68eb3a0 commit ec9a5e3

1 file changed

Lines changed: 39 additions & 9 deletions

File tree

frontend/src/App.vue

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
id="verb"
1818
v-model="form.verb"
1919
type="text"
20-
placeholder="例如:飲む、食べる、nomu、taberu"
20+
:placeholder="error ? error : '例如:飲む、食べる、nomu、taberu'"
21+
:class="{ 'input-error': error, 'input-success': result }"
2122
@keyup.enter="conjugate"
2223
@input="error = ''"
2324
@focus="showSuggestions = true"
@@ -43,7 +44,7 @@
4344
{{ loading ? '处理中...' : '活用' }}
4445
</button>
4546

46-
<div v-if="error" class="error-message">
47+
<div v-if="error" class="error-message" style="display: none;">
4748
{{ error }}
4849
</div>
4950
</div>
@@ -290,12 +291,16 @@ const hideSuggestionsWithDelay = () => {
290291
const conjugate = async () => {
291292
error.value = '';
292293
result.value = null;
293-
aiExplanation.value = null;
294+
aiRawExplanation.value = '';
294295
aiError.value = '';
295296
verificationStatus.value = {};
296297
297-
if (!form.value.verb) {
298+
if (!form.value.verb || !form.value.verb.trim()) {
298299
error.value = '请输入动词';
300+
// 当错误时,让输入框获取焦点
301+
setTimeout(() => {
302+
document.getElementById('verb')?.focus();
303+
}, 50);
299304
return;
300305
}
301306
@@ -312,6 +317,13 @@ const conjugate = async () => {
312317
fetchAiExplanation();
313318
} catch (err) {
314319
error.value = err.response?.data?.error || '请求失败,请检查输入';
320+
// 错误时重置结果状态
321+
result.value = null;
322+
// 错误时让输入框获取焦点,并清空用户的错误输入以便显示 placeholder 的错误提示
323+
form.value.verb = '';
324+
setTimeout(() => {
325+
document.getElementById('verb')?.focus();
326+
}, 50);
315327
} finally {
316328
loading.value = false;
317329
}
@@ -540,13 +552,30 @@ const fetchAiExplanation = async () => {
540552
border: 2px solid #e0e0e0;
541553
border-radius: 8px;
542554
font-size: 1em;
543-
transition: border-color 0.3s;
555+
transition: all 0.3s ease;
544556
}
545557
546558
.form-group input:focus,
547559
.form-group select:focus {
548560
outline: none;
549561
border-color: #667eea;
562+
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
563+
}
564+
565+
.input-error {
566+
background-color: #fff5f5 !important;
567+
border-color: #fc8181 !important;
568+
color: #c53030 !important;
569+
}
570+
571+
.input-error::placeholder {
572+
color: #feb2b2;
573+
}
574+
575+
.input-success {
576+
background-color: #f0fff4 !important;
577+
border-color: #68d391 !important;
578+
color: #2f855a !important;
550579
}
551580
552581
.btn-primary {
@@ -572,12 +601,13 @@ const fetchAiExplanation = async () => {
572601
}
573602
574603
.error-message {
575-
margin-top: 15px;
604+
color: #e53e3e;
605+
background-color: #fff5f5;
606+
border: 1px solid #fed7d7;
576607
padding: 12px;
577-
background: #fee;
578-
color: #c33;
579608
border-radius: 8px;
580-
border-left: 4px solid #c33;
609+
margin-top: 15px;
610+
font-size: 0.9em;
581611
}
582612
583613
.result-card {

0 commit comments

Comments
 (0)