213 lines
7.0 KiB
JavaScript
213 lines
7.0 KiB
JavaScript
// Authentication Handler
|
|
class Auth {
|
|
constructor() {
|
|
this.user = null;
|
|
this.isAuthenticated = false;
|
|
this.checkAuth();
|
|
}
|
|
|
|
async checkAuth() {
|
|
try {
|
|
const response = await api.getCurrentUser();
|
|
if (response.success) {
|
|
this.user = response.user;
|
|
this.isAuthenticated = true;
|
|
return true;
|
|
}
|
|
} catch (error) {
|
|
this.logout();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
async login(email, password) {
|
|
try {
|
|
const response = await api.login(email, password);
|
|
if (response.success) {
|
|
this.user = response.user;
|
|
this.isAuthenticated = true;
|
|
return { success: true, user: this.user };
|
|
}
|
|
return { success: false, error: response.message };
|
|
} catch (error) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
}
|
|
|
|
async register(name, email, password) {
|
|
try {
|
|
const response = await api.register(name, email, password);
|
|
if (response.success) {
|
|
return { success: true, message: 'Регистрация успешна. Теперь вы можете войти.' };
|
|
}
|
|
return { success: false, error: response.message };
|
|
} catch (error) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
}
|
|
|
|
async logout() {
|
|
try {
|
|
await api.logout();
|
|
} catch (error) {
|
|
console.error('Logout error:', error);
|
|
}
|
|
this.user = null;
|
|
this.isAuthenticated = false;
|
|
window.location.hash = '#login';
|
|
}
|
|
|
|
hasRole(role) {
|
|
return this.user && this.user.role === role;
|
|
}
|
|
|
|
hasPermission(permission) {
|
|
if (!this.user) return false;
|
|
return this.user.permissions && this.user.permissions.includes(permission);
|
|
}
|
|
|
|
getUser() {
|
|
return this.user;
|
|
}
|
|
|
|
isAdmin() {
|
|
return this.user && (this.user.role === 'superadmin' || this.user.role === 'admin');
|
|
}
|
|
|
|
isSuperAdmin() {
|
|
return this.user && this.user.role === 'superadmin';
|
|
}
|
|
}
|
|
|
|
// Global auth instance
|
|
const auth = new Auth();
|
|
|
|
// Login/Register form handler
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// Tab switching
|
|
const authTabBtns = document.querySelectorAll('.auth-tab-btn');
|
|
const authForms = document.querySelectorAll('.auth-form');
|
|
|
|
authTabBtns.forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
const tab = btn.dataset.tab;
|
|
|
|
// Update active tab
|
|
authTabBtns.forEach(b => b.classList.remove('active'));
|
|
btn.classList.add('active');
|
|
|
|
// Show/hide forms
|
|
authForms.forEach(form => form.classList.add('hidden'));
|
|
if (tab === 'login') {
|
|
document.getElementById('loginForm').classList.remove('hidden');
|
|
} else {
|
|
document.getElementById('registerForm').classList.remove('hidden');
|
|
}
|
|
});
|
|
});
|
|
|
|
// Login form
|
|
const loginForm = document.getElementById('loginForm');
|
|
if (loginForm) {
|
|
loginForm.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
|
|
const email = document.getElementById('loginEmail').value;
|
|
const password = document.getElementById('loginPassword').value;
|
|
|
|
const loginText = document.querySelector('.login-text');
|
|
const loginLoader = document.querySelector('.login-loader');
|
|
|
|
loginText.style.display = 'none';
|
|
loginLoader.classList.remove('hidden');
|
|
|
|
const result = await auth.login(email, password);
|
|
|
|
if (result.success) {
|
|
// Redirect to dashboard
|
|
setTimeout(() => {
|
|
window.location.hash = '#dashboard';
|
|
}, 500);
|
|
} else {
|
|
showAuthError(result.error);
|
|
loginText.style.display = 'block';
|
|
loginLoader.classList.add('hidden');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Register form
|
|
const registerForm = document.getElementById('registerForm');
|
|
if (registerForm) {
|
|
registerForm.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
|
|
const name = document.getElementById('registerName').value;
|
|
const email = document.getElementById('registerEmail').value;
|
|
const password = document.getElementById('registerPassword').value;
|
|
const confirmPassword = document.getElementById('registerPasswordConfirm').value;
|
|
|
|
if (password !== confirmPassword) {
|
|
showAuthError('Пароли не совпадают');
|
|
return;
|
|
}
|
|
|
|
const registerText = document.querySelector('.register-text');
|
|
const registerLoader = document.querySelector('.register-loader');
|
|
|
|
registerText.style.display = 'none';
|
|
registerLoader.classList.remove('hidden');
|
|
|
|
const result = await auth.register(name, email, password);
|
|
|
|
if (result.success) {
|
|
showAuthError(result.message, 'success');
|
|
// Clear form and switch to login
|
|
registerForm.reset();
|
|
document.querySelector('[data-tab="login"]').click();
|
|
} else {
|
|
showAuthError(result.error);
|
|
}
|
|
|
|
registerText.style.display = 'block';
|
|
registerLoader.classList.add('hidden');
|
|
});
|
|
}
|
|
});
|
|
|
|
function showAuthError(message, type = 'error') {
|
|
const errorDiv = document.getElementById('authError');
|
|
const errorText = document.getElementById('authErrorText');
|
|
|
|
if (type === 'success') {
|
|
errorDiv.classList.remove('bg-red-50', 'border-red-200', 'text-red-600', 'dark:bg-red-900/20', 'dark:border-red-800', 'dark:text-red-400');
|
|
errorDiv.classList.add('bg-green-50', 'border-green-200', 'text-green-600', 'dark:bg-green-900/20', 'dark:border-green-800', 'dark:text-green-400');
|
|
const icon = errorDiv.querySelector('i');
|
|
if (icon) {
|
|
icon.setAttribute('data-lucide', 'check-circle');
|
|
}
|
|
} else {
|
|
errorDiv.classList.remove('bg-green-50', 'border-green-200', 'text-green-600', 'dark:bg-green-900/20', 'dark:border-green-800', 'dark:text-green-400');
|
|
errorDiv.classList.add('bg-red-50', 'border-red-200', 'text-red-600', 'dark:bg-red-900/20', 'dark:border-red-800', 'dark:text-red-400');
|
|
const icon = errorDiv.querySelector('i');
|
|
if (icon) {
|
|
icon.setAttribute('data-lucide', 'alert-circle');
|
|
}
|
|
}
|
|
|
|
errorText.textContent = message;
|
|
errorDiv.classList.remove('hidden');
|
|
|
|
// Auto-hide success messages
|
|
if (type === 'success') {
|
|
setTimeout(() => {
|
|
errorDiv.classList.add('hidden');
|
|
}, 3000);
|
|
}
|
|
|
|
// Update Lucide icons
|
|
if (typeof lucide !== 'undefined') {
|
|
lucide.createIcons();
|
|
}
|
|
}
|