257 lines
8.2 KiB
HTML
257 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ru">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Регистрация/Авторизация</title>
|
|
<style>
|
|
html {
|
|
height: 100%;
|
|
}
|
|
body {
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
height: 100%;
|
|
}
|
|
.container {
|
|
margin: auto;
|
|
max-width: 400px;
|
|
background-color: white;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
}
|
|
.tabs {
|
|
display: flex;
|
|
margin-bottom: 20px;
|
|
}
|
|
.tab {
|
|
padding: 10px 20px;
|
|
cursor: pointer;
|
|
background-color: #eee;
|
|
border: none;
|
|
flex: 1;
|
|
text-align: center;
|
|
}
|
|
.tab.active {
|
|
background-color: #3f51b5;
|
|
color: white;
|
|
}
|
|
.form-container {
|
|
display: none;
|
|
}
|
|
.form-container.active {
|
|
display: block;
|
|
}
|
|
input {
|
|
width: 100%;
|
|
padding: 10px;
|
|
margin: 8px 0;
|
|
box-sizing: border-box;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
button {
|
|
background: #3f51b5;
|
|
color: white;
|
|
padding: 12px 20px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
width: 100%;
|
|
font-size: 16px;
|
|
}
|
|
button:hover {
|
|
background-color: #606fc7;
|
|
}
|
|
.message {
|
|
margin-top: 15px;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
display: none;
|
|
}
|
|
.success {
|
|
background-color: #dff0d8;
|
|
color: #3c763d;
|
|
}
|
|
.error {
|
|
background-color: #f2dede;
|
|
color: #a94442;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="tabs">
|
|
<button class="tab active" onclick="openTab('login')">Вход</button>
|
|
<button class="tab" onclick="openTab('register')">Регистрация</button>
|
|
</div>
|
|
|
|
<div id="login-form" class="form-container active">
|
|
<h2>Вход</h2>
|
|
<form id="loginForm">
|
|
<input type="email" id="loginEmail" placeholder="Email" required>
|
|
<input type="password" id="loginPassword" placeholder="Пароль" required>
|
|
<button type="submit">Войти</button>
|
|
</form>
|
|
<div id="loginMessage" class="message"></div>
|
|
</div>
|
|
|
|
<div id="register-form" class="form-container">
|
|
<h2>Регистрация</h2>
|
|
<form id="registerForm">
|
|
<input type="text" id="registerName" placeholder="Имя" required>
|
|
<input type="email" id="registerEmail" placeholder="Email" required>
|
|
<input type="password" id="registerPassword" placeholder="Пароль (минимум 6 символов)" required>
|
|
<button type="submit">Зарегистрироваться</button>
|
|
</form>
|
|
<div id="registerMessage" class="message"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function setCookie(name, value, days) {
|
|
let expires = "";
|
|
if (days) {
|
|
const date = new Date();
|
|
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
|
expires = "; expires=" + date.toUTCString();
|
|
}
|
|
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
|
}
|
|
function getCookie(name) {
|
|
const nameEQ = name + "=";
|
|
const ca = document.cookie.split(';');
|
|
for(let i = 0; i < ca.length; i++) {
|
|
let c = ca[i];
|
|
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
|
|
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function saveAuthData(token, userData) {
|
|
setCookie('jwtToken', token, 7);
|
|
localStorage.setItem('jwtToken', token);
|
|
localStorage.setItem('userData', JSON.stringify(userData));
|
|
}
|
|
|
|
function getToken() {
|
|
const cookieToken = getCookie('jwtToken');
|
|
return cookieToken || localStorage.getItem('jwtToken');
|
|
}
|
|
|
|
function getAuthHeaders() {
|
|
const token = getToken();
|
|
return {
|
|
'Content-Type': 'application/json',
|
|
...(token ? {'Authorization': `Bearer ${token}`} : {})
|
|
};
|
|
}
|
|
|
|
function openTab(tabName) {
|
|
document.querySelectorAll('.form-container').forEach(form => {
|
|
form.classList.remove('active');
|
|
});
|
|
|
|
document.getElementById(tabName + '-form').classList.add('active');
|
|
|
|
document.querySelectorAll('.tab').forEach(tab => {
|
|
tab.classList.remove('active');
|
|
});
|
|
event.currentTarget.classList.add('active');
|
|
}
|
|
|
|
document.getElementById('loginForm').addEventListener('submit', async function(e) {
|
|
e.preventDefault();
|
|
|
|
const email = document.getElementById('loginEmail').value;
|
|
const password = document.getElementById('loginPassword').value;
|
|
const messageElement = document.getElementById('loginMessage');
|
|
|
|
try {
|
|
const response = await fetch('/login', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
email: email,
|
|
password: password
|
|
}),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (response.ok) {
|
|
saveAuthData(data.data.token, data.data.user);
|
|
|
|
showMessage('loginMessage', 'success', 'Успешный вход! Перенаправление...');
|
|
setTimeout(() => {
|
|
window.location.href = '/profile';
|
|
}, 500);
|
|
} else {
|
|
showMessage('loginMessage', 'error', data.error || 'Ошибка входа');
|
|
}
|
|
} catch (error) {
|
|
showMessage('loginMessage', 'error', 'Ошибка сети: ' + error.message);
|
|
}
|
|
});
|
|
|
|
document.getElementById('registerForm').addEventListener('submit', async function(e) {
|
|
e.preventDefault();
|
|
|
|
const name = document.getElementById('registerName').value;
|
|
const email = document.getElementById('registerEmail').value;
|
|
const password = document.getElementById('registerPassword').value;
|
|
|
|
if (password.length < 6) {
|
|
showMessage('registerMessage', 'error', 'Пароль должен содержать минимум 6 символов');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch('/register', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
name: name,
|
|
email: email,
|
|
password: password
|
|
}),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (response.ok) {
|
|
saveAuthData(data.data.token, data.data.user);
|
|
showMessage('registerMessage', 'success', 'Регистрация успешна! Перенаправление...');
|
|
setTimeout(() => {
|
|
window.location.href = '/profile';
|
|
}, 500);
|
|
} else {
|
|
showMessage('registerMessage', 'error', data.error || 'Ошибка регистрации');
|
|
}
|
|
} catch (error) {
|
|
showMessage('registerMessage', 'error', 'Ошибка сети: ' + error.message);
|
|
}
|
|
});
|
|
|
|
function showMessage(elementId, type, message) {
|
|
const element = document.getElementById(elementId);
|
|
element.textContent = message;
|
|
element.className = 'message ' + type;
|
|
element.style.display = 'block';
|
|
|
|
setTimeout(() => {
|
|
element.style.display = 'none';
|
|
}, 5000);
|
|
}
|
|
|
|
</script>
|
|
</body>
|
|
</html> |