modified: main_dc/yalarba/easySite/easySite/app/composables/useAuth.ts

modified:   main_dc/yalarba/easySite/easySite/app/middleware/auth.ts
modified:   main_dc/yalarba/easySite/easySite/app/pages/auth/login.vue
	modified:   main_dc/yalarba/easySite/easySite/app/pages/auth/register.vue
	new file:   main_dc/yalarba/easySite/easySite/app/pages/plugins/auth.client.ts
	modified:   main_dc/yalarba/easySite/easySite/app/pages/profile/index.vue
	new file:   main_dc/yalarba/easySite/easySite/app/schemas/auth.ts
modified:   main_dc/yalarba/easySite/easySite/app/types/auth.ts
	modified:   main_dc/yalarba/easySite/easySite/package-lock.json
	modified:   main_dc/yalarba/easySite/easySite/package.json
update login register with use vee and firebase
This commit is contained in:
2025-11-14 23:55:02 +05:00
parent e5723490d4
commit 8fee46ce5c
10 changed files with 603 additions and 234 deletions
@@ -6,40 +6,37 @@
<div class="card-header text-center">
<h1 class="auth-title">Вход в систему</h1>
</div>
<div class="card-body">
<form class="auth-form" @submit.prevent="handleSubmit">
<form class="auth-form" @submit="onSubmit">
<div class="form-group">
<label class="form-label">Email</label>
<input
v-model="form.email"
type="email"
class="form-input"
placeholder="your@email.com"
required
>
<input v-model="email" type="email" class="form-input" :class="{ 'error': errors.email }"
placeholder="your@email.com">
<span v-if="errors.email" class="error-message">
{{ errors.email }}
</span>
</div>
<div class="form-group">
<label class="form-label">Пароль</label>
<input
v-model="form.password"
type="password"
class="form-input"
placeholder="Введите пароль"
required
>
<input v-model="password" type="password" class="form-input" :class="{ 'error': errors.password }"
placeholder="Введите пароль">
<span v-if="errors.password" class="error-message">
{{ errors.password }}
</span>
</div>
<button type="submit" class="btn btn-primary auth-button">
Войти
<button type="submit" class="btn btn-primary auth-button" :disabled="isSubmitting || auth.loading.value">
<span v-if="isSubmitting || auth.loading.value">Вход...</span>
<span v-else>Войти</span>
</button>
</form>
</div>
<div class="card-footer text-center">
<p class="auth-footer-text">
Нет аккаунта?
Нет аккаунта?
<NuxtLink to="/auth/register" class="auth-link">
Зарегистрируйтесь
</NuxtLink>
@@ -55,16 +52,38 @@
</template>
<script setup lang="ts">
const form = ref({
email: '',
password: ''
import { useField, useForm } from 'vee-validate'
import { loginSchema } from '~/schemas/auth'
definePageMeta({
middleware: 'auth'
})
const handleSubmit = () => {
// В демо-режиме просто переходим в профиль
alert('Демо-режим: вход выполнен')
navigateTo('/profile')
}
const auth = useAuth()
const { handleSubmit, errors, isSubmitting } = useForm({
validationSchema: loginSchema
})
const { value: email } = useField('email')
const { value: password } = useField('password')
const onSubmit = handleSubmit(async (values) => {
try {
await auth.login(values)
await navigateTo('/profile')
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error('Login error:', error)
if (error.status === 401) {
alert('Неверный email или пароль')
} else if (error.status === 422) {
alert('Неверные данные для входа')
} else {
alert('Произошла ошибка при входе. Попробуйте позже.')
}
}
})
</script>
<style scoped>
@@ -74,7 +93,7 @@ const handleSubmit = () => {
display: flex;
align-items: center;
justify-content: center;
padding: 2rem 1rem;
padding: 1rem;
}
.auth-container {
@@ -86,9 +105,29 @@ const handleSubmit = () => {
width: 100%;
}
.card {
background: white;
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
overflow: hidden;
}
.card-header {
padding: 2rem 2rem 0;
}
.card-body {
padding: 1.5rem 2rem;
}
.card-footer {
padding: 0 2rem 2rem;
}
.auth-title {
font-size: 1.5rem;
font-weight: bold;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 0.5rem;
}
@@ -98,20 +137,69 @@ const handleSubmit = () => {
gap: 1rem;
}
.form-group {
display: flex;
flex-direction: column;
}
.form-label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
color: var(--text-primary);
font-size: 0.875rem;
}
.form-input {
width: 100%;
padding: 0.75rem;
border: 1px solid var(--border-color);
border-radius: 6px;
font-size: 0.875rem;
transition: all 0.2s;
}
.form-input:focus {
outline: none;
border-color: var(--primary-500);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
.form-input.error {
border-color: #dc2626;
box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1);
}
.error-message {
color: #dc2626;
font-size: 0.75rem;
margin-top: 0.25rem;
display: block;
}
.auth-button {
width: 100%;
margin-top: 0.5rem;
padding: 0.75rem;
font-size: 0.875rem;
}
.auth-button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.auth-footer-text {
color: var(--text-secondary);
margin-bottom: 1rem;
font-size: 0.875rem;
}
.auth-link {
color: var(--primary-600);
font-weight: 500;
text-decoration: none;
font-size: 0.875rem;
}
.auth-link:hover {
@@ -121,5 +209,48 @@ const handleSubmit = () => {
.home-link {
display: inline-block;
margin-top: 0.5rem;
font-size: 0.875rem;
}
/* Адаптивность для мобильных устройств */
@media (max-width: 640px) {
.auth-container {
max-width: 100%;
}
.card-header {
padding: 1.5rem 1.5rem 0;
}
.card-body {
padding: 1rem 1.5rem;
}
.card-footer {
padding: 0 1.5rem 1.5rem;
}
.auth-title {
font-size: 1.25rem;
}
}
/* Для очень маленьких экранов */
@media (max-width: 380px) {
.auth-page {
padding: 0.5rem;
}
.card-header {
padding: 1rem 1rem 0;
}
.card-body {
padding: 0.75rem 1rem;
}
.card-footer {
padding: 0 1rem 1rem;
}
}
</style>