feat(login-page): replace language select and toggle with custom components

This commit is contained in:
Supra4E8C
2026-03-07 23:26:55 +08:00
Unverified
parent d12dac02c0
commit a4dee2ea82
2 changed files with 32 additions and 50 deletions
+8 -28
View File
@@ -169,22 +169,8 @@
// 语言下拉选择
.languageSelect {
white-space: nowrap;
border: 1px solid var(--border-color);
border-radius: $radius-md;
padding: 10px 12px;
font-size: 14px;
background: var(--bg-primary);
color: var(--text-primary);
cursor: pointer;
height: 40px;
box-sizing: border-box;
&:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba($primary-color, 0.18);
}
min-width: 108px;
flex: 0 0 auto;
}
// 连接信息框
@@ -218,19 +204,13 @@
.toggleAdvanced {
display: flex;
justify-content: flex-start;
align-items: center;
gap: $spacing-xs;
width: 100%;
}
.toggleLabel {
color: var(--text-secondary);
cursor: pointer;
input[type='checkbox'] {
cursor: pointer;
}
label {
cursor: pointer;
font-size: 14px;
}
font-size: 14px;
font-weight: 500;
}
// 错误提示框
+24 -22
View File
@@ -3,6 +3,8 @@ import { Navigate, useNavigate, useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { Select } from '@/components/ui/Select';
import { ToggleSwitch } from '@/components/ui/ToggleSwitch';
import { IconEye, IconEyeOff } from '@/components/ui/icons';
import { useAuthStore, useLanguageStore, useNotificationStore } from '@/stores';
import { detectApiBaseFromLocation, normalizeApiBase } from '@/utils/connection';
@@ -89,9 +91,16 @@ export function LoginPage() {
const [error, setError] = useState('');
const detectedBase = useMemo(() => detectApiBaseFromLocation(), []);
const languageOptions = useMemo(
() =>
LANGUAGE_ORDER.map((lang) => ({
value: lang,
label: t(LANGUAGE_LABEL_KEYS[lang])
})),
[t]
);
const handleLanguageChange = useCallback(
(event: React.ChangeEvent<HTMLSelectElement>) => {
const selectedLanguage = event.target.value;
(selectedLanguage: string) => {
if (!isSupportedLanguage(selectedLanguage)) {
return;
}
@@ -205,19 +214,14 @@ export function LoginPage() {
<div className={styles.loginHeader}>
<div className={styles.titleRow}>
<div className={styles.title}>{t('title.login')}</div>
<select
<Select
className={styles.languageSelect}
value={language}
options={languageOptions}
onChange={handleLanguageChange}
title={t('language.switch')}
aria-label={t('language.switch')}
>
{LANGUAGE_ORDER.map((lang) => (
<option key={lang} value={lang}>
{t(LANGUAGE_LABEL_KEYS[lang])}
</option>
))}
</select>
fullWidth={false}
ariaLabel={t('language.switch')}
/>
</div>
<div className={styles.subtitle}>{t('login.subtitle')}</div>
</div>
@@ -229,13 +233,12 @@ export function LoginPage() {
</div>
<div className={styles.toggleAdvanced}>
<input
id="custom-connection-toggle"
type="checkbox"
<ToggleSwitch
checked={showCustomBase}
onChange={(e) => setShowCustomBase(e.target.checked)}
onChange={setShowCustomBase}
ariaLabel={t('login.custom_connection_label')}
label={<span className={styles.toggleLabel}>{t('login.custom_connection_label')}</span>}
/>
<label htmlFor="custom-connection-toggle">{t('login.custom_connection_label')}</label>
</div>
{showCustomBase && (
@@ -278,13 +281,12 @@ export function LoginPage() {
/>
<div className={styles.toggleAdvanced}>
<input
id="remember-password-toggle"
type="checkbox"
<ToggleSwitch
checked={rememberPassword}
onChange={(e) => setRememberPassword(e.target.checked)}
onChange={setRememberPassword}
ariaLabel={t('login.remember_password_label')}
label={<span className={styles.toggleLabel}>{t('login.remember_password_label')}</span>}
/>
<label htmlFor="remember-password-toggle">{t('login.remember_password_label')}</label>
</div>
<Button fullWidth onClick={handleSubmit} loading={loading}>