init
This commit is contained in:
212
public/js/auth.js
Normal file
212
public/js/auth.js
Normal file
@@ -0,0 +1,212 @@
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user