Files
tp/serv_nginx/bbvue/src/views/Register.vue
T
2025-10-16 01:57:19 +05:00

370 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="page">
<div class="register-container">
<h1>👤 Регистрация</h1>
<p>Присоединяйтесь к нашему беговому сообществу</p>
<form @submit.prevent="handleRegister" class="register-form">
<div class="form-row">
<div class="form-group">
<label for="firstName">Имя *</label>
<input id="firstName" v-model="formData.firstName" type="text" class="form-input"
placeholder="Введите ваше имя" required :disabled="loading">
</div>
<div class="form-group">
<label for="lastName">Фамилия *</label>
<input id="lastName" v-model="formData.lastName" type="text" class="form-input"
placeholder="Введите вашу фамилию" required :disabled="loading">
</div>
</div>
<div class="form-group">
<label for="email">Email *</label>
<input id="email" v-model="formData.email" type="email" class="form-input" placeholder="example@mail.ru"
required :disabled="loading">
</div>
<div class="form-group">
<label for="phone">Телефон</label>
<input id="phone" v-model="formData.phone" type="tel" class="form-input" placeholder="+7 (999) 123-45-67"
:disabled="loading">
</div>
<div class="form-row">
<div class="form-group">
<label for="password">Пароль *</label>
<input id="password" v-model="formData.password" type="password" class="form-input"
placeholder="Не менее 6 символов" required minlength="6" :disabled="loading">
</div>
<div class="form-group">
<label for="confirmPassword">Подтверждение пароля *</label>
<input id="confirmPassword" v-model="formData.confirmPassword" type="password" class="form-input"
placeholder="Повторите пароль" required :disabled="loading">
</div>
</div>
<div class="form-group">
<label for="experience">Уровень подготовки</label>
<select id="experience" v-model="formData.experience" class="form-input" :disabled="loading">
<option value="">Выберите уровень</option>
<option value="beginner">Начинающий (0-6 месяцев)</option>
<option value="intermediate">Любитель (6-24 месяцев)</option>
<option value="advanced">Опытный (2+ лет)</option>
<option value="professional">Профессионал</option>
</select>
</div>
<div class="form-group">
<label for="goals">Цели</label>
<select id="goals" v-model="formData.goals" class="form-input" :disabled="loading">
<option value="">Выберите цель</option>
<option value="health">Улучшить здоровье</option>
<option value="weight">Сбросить вес</option>
<option value="first5k">Пробежать первые 5 км</option>
<option value="first10k">Пробежать первые 10 км</option>
<option value="halfMarathon">Подготовиться к полумарафону</option>
<option value="marathon">Подготовиться к марафону</option>
<option value="improve">Улучшить результаты</option>
<option value="social">Общение и компания</option>
</select>
</div>
<div class="form-group checkbox-group">
<label class="checkbox-label">
<input v-model="formData.agreeTerms" type="checkbox" class="checkbox" required :disabled="loading">
<span class="checkmark"></span>
Я соглашаюсь с
<router-link to="/terms" class="link" target="_blank">правилами клуба</router-link> и
<router-link to="/privacy" class="link" target="_blank">политикой конфиденциальности</router-link> *
</label>
</div>
<div class="form-group checkbox-group">
<label class="checkbox-label">
<input v-model="formData.newsletter" type="checkbox" class="checkbox" :disabled="loading">
<span class="checkmark"></span>
Хочу получать новости о тренировках и мероприятиях
</label>
</div>
<button type="submit" class="btn btn-primary" :disabled="!formData.agreeTerms || loading">
{{ loading ? 'Регистрация...' : '🏃 Зарегистрироваться' }}
</button>
<div v-if="error" class="error-message">
{{ error }}
</div>
</form>
<div class="login-link">
<p>Уже есть аккаунт? <router-link to="/login" class="link">Войдите здесь</router-link></p>
</div>
<div class="benefits">
<h3>Что вы получите после регистрации:</h3>
<ul class="benefits-list">
<li> Доступ к расписанию тренировок</li>
<li> Персональный трекер прогресса</li>
<li> Общение с тренером и участниками</li>
<li> Участие в клубных мероприятиях</li>
<li> Скидки на стартовые взносы</li>
</ul>
</div>
</div>
<button class="btn btn-secondary" @click="$router.push('/')"> На главную</button>
</div>
</template>
<script>
import { useAuthStore } from '../stores/auth'
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'Register',
setup() {
const authStore = useAuthStore()
return { authStore }
},
data() {
return {
formData: {
firstName: '',
lastName: '',
email: '',
phone: '',
password: '',
confirmPassword: '',
experience: '',
goals: '',
agreeTerms: false,
newsletter: true
},
showDebugInfo: import.meta.env.DEV // Показывать отладочную информацию только в development
}
},
computed: {
loading() {
return this.authStore.loading
},
error() {
return this.authStore.error
}
},
methods: {
async handleRegister() {
// Валидация
if (this.formData.password !== this.formData.confirmPassword) {
this.authStore.error = 'Пароли не совпадают'
return
}
if (this.formData.password.length < 6) {
this.authStore.error = 'Пароль должен содержать не менее 6 символов'
return
}
if (!this.formData.agreeTerms) {
this.authStore.error = 'Необходимо согласие с правилами клуба'
return
}
// Подготовка данных для API
const registerData = {
email: this.formData.email,
password: this.formData.password,
firstName: this.formData.firstName,
lastName: this.formData.lastName,
phone: this.formData.phone,
experience: this.formData.experience,
goals: this.formData.goals,
newsletter: this.formData.newsletter
}
console.log('Отправка данных регистрации:', { ...registerData, password: '***' })
alert("|" + registerData.email + "|" + registerData.password + "|")
const result = await this.authStore.register(registerData)
alert("register seccess=" + result.success + "| data=" + result.data)
if (result.success) {
// Перенаправляем на страницу профиля после успешной регистрации
this.$router.push('/profile')
} else {
console.error('Ошибка регистрации:', result.error)
}
}
}
}
</script>
<style scoped>
/* Стили остаются без изменений */
.register-container {
max-width: 500px;
margin: 0 auto;
text-align: left;
}
.register-form {
background: white;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
margin: 2rem 0;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
color: #333;
}
.form-input {
width: 100%;
padding: 12px;
border: 2px solid #e1e5e9;
border-radius: 6px;
font-size: 1rem;
transition: border-color 0.3s;
}
.form-input:focus {
outline: none;
border-color: #2e8b57;
}
.form-input:disabled {
background-color: #f5f5f5;
cursor: not-allowed;
}
.checkbox-group {
margin: 1.5rem 0;
}
.checkbox-label {
display: flex;
align-items: flex-start;
cursor: pointer;
font-weight: normal;
}
.checkbox {
margin-right: 10px;
margin-top: 3px;
}
.checkmark {
width: 18px;
height: 18px;
border: 2px solid #ddd;
border-radius: 3px;
margin-right: 10px;
margin-top: 2px;
position: relative;
flex-shrink: 0;
}
.checkbox:checked+.checkmark {
background-color: #2e8b57;
border-color: #2e8b57;
}
.checkbox:checked+.checkmark::after {
content: '✓';
color: white;
position: absolute;
top: -2px;
left: 2px;
font-size: 14px;
}
.btn-primary {
width: 100%;
background-color: #2e8b57;
color: white;
padding: 15px;
font-size: 1.1rem;
margin-top: 1rem;
}
.btn-primary:hover:not(:disabled) {
background-color: #26734a;
}
.btn-primary:disabled {
background-color: #ccc;
cursor: not-allowed;
}
.error-message {
background-color: #fee;
color: #c33;
padding: 12px;
border-radius: 6px;
margin-top: 1rem;
border-left: 4px solid #c33;
}
.login-link {
text-align: center;
margin: 1.5rem 0;
}
.link {
color: #2e8b57;
text-decoration: none;
}
.link:hover {
text-decoration: underline;
}
.benefits {
background-color: #f8fff8;
padding: 1.5rem;
border-radius: 8px;
border-left: 4px solid #2e8b57;
margin: 2rem 0;
}
.benefits h3 {
color: #2e8b57;
margin-bottom: 1rem;
}
.benefits-list {
list-style: none;
padding: 0;
}
.benefits-list li {
padding: 0.3rem 0;
color: #555;
}
/* Адаптивность */
@media (max-width: 600px) {
.form-row {
grid-template-columns: 1fr;
}
.register-form {
padding: 1.5rem;
}
}
</style>