core/panel/login.tsx

121 lines
3.4 KiB
TypeScript
Raw Normal View History

2025-05-16 06:23:48 +00:00
/**
* Компонент страницы входа
* @module LoginPage
*/
2025-06-28 10:47:08 +00:00
import { Component, createSignal } from 'solid-js'
2025-05-16 07:30:02 +00:00
import { login } from './auth'
interface LoginPageProps {
onLoginSuccess?: () => void
}
2025-05-16 06:23:48 +00:00
/**
* Компонент страницы входа
*/
2025-05-16 07:30:02 +00:00
const LoginPage: Component<LoginPageProps> = (props) => {
2025-05-16 06:23:48 +00:00
const [email, setEmail] = createSignal('')
const [password, setPassword] = createSignal('')
const [isLoading, setIsLoading] = createSignal(false)
const [error, setError] = createSignal<string | null>(null)
2025-05-19 08:25:41 +00:00
const [formSubmitting, setFormSubmitting] = createSignal(false)
2025-05-16 06:23:48 +00:00
/**
* Обработчик отправки формы входа
* @param e - Событие отправки формы
*/
const handleSubmit = async (e: Event) => {
e.preventDefault()
2025-05-19 08:25:41 +00:00
// Предотвращаем повторную отправку формы
if (formSubmitting()) return
2025-05-16 06:23:48 +00:00
// Очищаем пробелы в email
const cleanEmail = email().trim()
if (!cleanEmail || !password()) {
setError('Пожалуйста, заполните все поля')
return
}
2025-05-19 08:25:41 +00:00
setFormSubmitting(true)
2025-05-16 06:23:48 +00:00
setIsLoading(true)
setError(null)
try {
// Используем функцию login из модуля auth
const loginSuccessful = await login({
email: cleanEmail,
password: password()
})
if (loginSuccessful) {
2025-05-16 07:30:02 +00:00
// Вызываем коллбэк для оповещения родителя об успешном входе
if (props.onLoginSuccess) {
props.onLoginSuccess()
}
2025-05-16 06:23:48 +00:00
} else {
throw new Error('Вход не выполнен')
}
} catch (err) {
console.error('Ошибка при входе:', err)
setError(err instanceof Error ? err.message : 'Неизвестная ошибка')
setIsLoading(false)
2025-05-19 08:25:41 +00:00
} finally {
setFormSubmitting(false)
2025-05-16 06:23:48 +00:00
}
}
return (
<div class="login-page">
<div class="login-container">
2025-05-21 07:35:27 +00:00
<img src="https://testing.dscrs.site/logo.svg" alt="Logo" />
<div class="error-message" style={{ opacity: error() ? 1 : 0 }}>{error()}</div>
2025-05-16 06:23:48 +00:00
2025-05-19 08:25:41 +00:00
<form onSubmit={handleSubmit} method="post">
2025-05-16 06:23:48 +00:00
<div class="form-group">
<input
type="email"
id="email"
2025-05-19 08:25:41 +00:00
name="email"
2025-05-21 07:35:27 +00:00
placeholder="Email"
2025-05-16 06:23:48 +00:00
value={email()}
onInput={(e) => setEmail(e.currentTarget.value)}
disabled={isLoading()}
autocomplete="username"
required
/>
</div>
<div class="form-group">
<input
type="password"
id="password"
2025-05-19 08:25:41 +00:00
name="password"
2025-05-21 07:35:27 +00:00
placeholder="Пароль"
2025-05-16 06:23:48 +00:00
value={password()}
onInput={(e) => setPassword(e.currentTarget.value)}
disabled={isLoading()}
autocomplete="current-password"
required
/>
</div>
2025-05-19 08:25:41 +00:00
<button type="submit" disabled={isLoading() || formSubmitting()}>
{isLoading() ? (
<>
<span class="spinner"></span>
Вход...
</>
) : (
'Войти'
)}
2025-05-16 06:23:48 +00:00
</button>
</form>
</div>
</div>
)
}
export default LoginPage