code_runner/cmd/service_front/templates/auth.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>