/* SoftSins Authentication Modal */
class AuthModal {
constructor() {
this.overlay = null;
this.modal = null;
this.currentForm = 'login';
this.isLoading = false;
this.createModal();
this.bindEvents();
}
createModal() {
// Create overlay
this.overlay = document.createElement('div');
this.overlay.className = 'auth-modal-overlay';
this.overlay.id = 'authModalOverlay';
// Modal HTML
this.overlay.innerHTML = `
`;
document.body.appendChild(this.overlay);
}
bindEvents() {
// Form submissions
document.getElementById('loginForm').addEventListener('submit', (e) => {
e.preventDefault();
this.handleLogin();
});
document.getElementById('registerForm').addEventListener('submit', (e) => {
e.preventDefault();
this.handleRegister();
});
// Close on overlay click
this.overlay.addEventListener('click', (e) => {
if (e.target === this.overlay) {
this.close();
}
});
// Close on escape key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && this.isOpen()) {
this.close();
}
});
}
open(form = 'login') {
this.switchForm(form);
this.overlay.classList.add('active');
document.body.style.overflow = 'hidden';
// Focus first input
setTimeout(() => {
const firstInput = this.overlay.querySelector(`#${form}Form .auth-form-input`);
if (firstInput) firstInput.focus();
}, 100);
}
close() {
this.overlay.classList.remove('active');
document.body.style.overflow = '';
this.clearForms();
this.hideMessage();
}
isOpen() {
return this.overlay.classList.contains('active');
}
switchForm(formType) {
this.currentForm = formType;
// Update toggle buttons
document.querySelectorAll('.auth-toggle-btn').forEach(btn => btn.classList.remove('active'));
const targetBtn = document.querySelector(`.auth-toggle-btn[onclick*="${formType}"]`);
if (targetBtn) {
targetBtn.classList.add('active');
}
// Update forms
document.querySelectorAll('.auth-form').forEach(form => form.classList.remove('active'));
document.getElementById(`${formType}Form`).classList.add('active');
this.hideMessage();
this.clearErrors();
}
togglePassword(inputId) {
const input = document.getElementById(inputId);
const toggle = input.nextElementSibling;
if (input.type === 'password') {
input.type = 'text';
toggle.textContent = '🙈';
} else {
input.type = 'password';
toggle.textContent = '👁️';
}
}
async handleLogin() {
if (this.isLoading) return;
const email = document.getElementById('loginEmail').value.trim();
const password = document.getElementById('loginPassword').value;
if (!this.validateLogin(email, password)) return;
this.setLoading(true);
this.hideMessage();
try {
const { data, error } = await supabase.auth.signInWithPassword({
email: email,
password: password
});
if (error) throw error;
this.showMessage('Erfolgreich angemeldet! Willkommen zurück.', 'success');
setTimeout(() => {
this.close();
}, 1500);
} catch (error) {
console.error('Login error:', error);
this.showMessage(this.getErrorMessage(error), 'error');
} finally {
this.setLoading(false);
}
}
async handleRegister() {
if (this.isLoading) return;
const email = document.getElementById('registerEmail').value.trim();
const password = document.getElementById('registerPassword').value;
const passwordConfirm = document.getElementById('registerPasswordConfirm').value;
if (!this.validateRegister(email, password, passwordConfirm)) return;
this.setLoading(true);
this.hideMessage();
try {
const { data, error } = await supabase.auth.signUp({
email: email,
password: password,
options: {
emailRedirectTo: `${window.location.origin}/`
}
});
if (error) throw error;
this.showMessage(
'Registrierung erfolgreich! Bitte überprüfe deine E-Mails und bestätige deine Adresse.',
'success'
);
// Switch to login after successful registration
setTimeout(() => {
this.switchForm('login');
}, 3000);
} catch (error) {
console.error('Register error:', error);
this.showMessage(this.getErrorMessage(error), 'error');
} finally {
this.setLoading(false);
}
}
async sendMagicLink() {
const email = document.getElementById('loginEmail').value.trim();
if (!email) {
this.showMessage('Bitte gib deine E-Mail-Adresse ein.', 'error');
document.getElementById('loginEmail').focus();
return;
}
if (!this.isValidEmail(email)) {
this.showMessage('Bitte gib eine gültige E-Mail-Adresse ein.', 'error');
return;
}
try {
const { error } = await supabase.auth.signInWithOtp({
email: email,
options: {
emailRedirectTo: `${window.location.origin}/`
}
});
if (error) throw error;
this.showMessage(
`Magic Link wurde an ${email} gesendet! Überprüfe deine E-Mails.`,
'success'
);
} catch (error) {
console.error('Magic link error:', error);
this.showMessage(this.getErrorMessage(error), 'error');
}
}
async showForgotPassword() {
const email = prompt('Gib deine E-Mail-Adresse ein:');
if (!email) return;
if (!this.isValidEmail(email)) {
this.showMessage('Bitte gib eine gültige E-Mail-Adresse ein.', 'error');
return;
}
try {
const { error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: `${window.location.origin}/`
});
if (error) throw error;
this.showMessage(
`Password-Reset-Link wurde an ${email} gesendet!`,
'success'
);
} catch (error) {
console.error('Password reset error:', error);
this.showMessage(this.getErrorMessage(error), 'error');
}
}
validateLogin(email, password) {
this.clearErrors();
let isValid = true;
if (!email) {
this.showFieldError('loginEmail', 'E-Mail-Adresse ist erforderlich');
isValid = false;
} else if (!this.isValidEmail(email)) {
this.showFieldError('loginEmail', 'Bitte gib eine gültige E-Mail-Adresse ein');
isValid = false;
}
if (!password) {
this.showFieldError('loginPassword', 'Passwort ist erforderlich');
isValid = false;
}
return isValid;
}
validateRegister(email, password, passwordConfirm) {
this.clearErrors();
let isValid = true;
if (!email) {
this.showFieldError('registerEmail', 'E-Mail-Adresse ist erforderlich');
isValid = false;
} else if (!this.isValidEmail(email)) {
this.showFieldError('registerEmail', 'Bitte gib eine gültige E-Mail-Adresse ein');
isValid = false;
}
if (!password) {
this.showFieldError('registerPassword', 'Passwort ist erforderlich');
isValid = false;
} else if (password.length < 6) {
this.showFieldError('registerPassword', 'Passwort muss mindestens 6 Zeichen lang sein');
isValid = false;
}
if (!passwordConfirm) {
this.showFieldError('registerPasswordConfirm', 'Passwort-Bestätigung ist erforderlich');
isValid = false;
} else if (password !== passwordConfirm) {
this.showFieldError('registerPasswordConfirm', 'Passwörter stimmen nicht überein');
isValid = false;
}
return isValid;
}
showFieldError(fieldId, message) {
const field = document.getElementById(fieldId);
const error = document.getElementById(fieldId + 'Error');
field.classList.add('error');
error.textContent = message;
error.classList.add('show');
}
clearErrors() {
document.querySelectorAll('.auth-form-input').forEach(input => {
input.classList.remove('error');
});
document.querySelectorAll('.auth-form-error').forEach(error => {
error.classList.remove('show');
error.textContent = '';
});
}
clearForms() {
document.querySelectorAll('.auth-form input').forEach(input => {
input.value = '';
});
this.clearErrors();
}
setLoading(loading) {
this.isLoading = loading;
const submitBtns = document.querySelectorAll('.auth-submit-btn');
submitBtns.forEach(btn => {
if (loading) {
btn.classList.add('loading');
btn.disabled = true;
} else {
btn.classList.remove('loading');
btn.disabled = false;
}
});
}
showMessage(message, type = 'info') {
const messageEl = document.getElementById('authMessage');
messageEl.textContent = message;
messageEl.className = `auth-message show ${type}`;
}
hideMessage() {
const messageEl = document.getElementById('authMessage');
messageEl.classList.remove('show');
}
isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
getErrorMessage(error) {
const errorMessages = {
'Invalid login credentials': 'Ungültige E-Mail-Adresse oder Passwort',
'Email not confirmed': 'Bitte bestätige deine E-Mail-Adresse',
'User already registered': 'Diese E-Mail-Adresse ist bereits registriert',
'Password is too weak': 'Passwort ist zu schwach',
'Invalid email': 'Ungültige E-Mail-Adresse'
};
return errorMessages[error.message] || error.message || 'Ein unbekannter Fehler ist aufgetreten';
}
}
// Initialize auth modal when DOM is loaded
let authModal;
document.addEventListener('DOMContentLoaded', function() {
authModal = new AuthModal();
// Make globally accessible after initialization
window.authModal = authModal;
});
// Global function to open login modal
function openLoginModal() {
if (window.authModal) {
window.authModal.open('login');
}
}
// Global function to open registration modal
function openRegisterModal() {
if (window.authModal) {
window.authModal.open('register');
}
}