Spaces:
Running
Running
| class AuthForm extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| .auth-container { | |
| @apply max-w-md mx-auto p-8 bg-white rounded-lg shadow-md; | |
| } | |
| .auth-tabs { | |
| @apply flex border-b mb-6; | |
| } | |
| .auth-tab { | |
| @apply px-4 py-2 cursor-pointer; | |
| } | |
| .auth-tab.active { | |
| @apply border-b-2 border-blue-500 font-medium; | |
| } | |
| .form-group { | |
| @apply mb-4; | |
| } | |
| label { | |
| @apply block text-sm font-medium text-gray-700 mb-1; | |
| } | |
| input { | |
| @apply w-full px-3 py-2 border border-gray-300 rounded-md; | |
| } | |
| button { | |
| @apply w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700; | |
| } | |
| .error { | |
| @apply text-red-500 text-sm mt-2; | |
| } | |
| </style> | |
| <div class="auth-container"> | |
| <div class="auth-tabs"> | |
| <div class="auth-tab active" data-tab="login">Login</div> | |
| <div class="auth-tab" data-tab="register">Register</div> | |
| </div> | |
| <form id="loginForm"> | |
| <div class="form-group"> | |
| <label>Email</label> | |
| <input type="email" id="loginEmail" required> | |
| </div> | |
| <div class="form-group"> | |
| <label>Password</label> | |
| <input type="password" id="loginPassword" required> | |
| </div> | |
| <div id="loginError" class="error"></div> | |
| <button type="submit">Login</button> | |
| </form> | |
| <form id="registerForm" class="hidden"> | |
| <div class="form-group"> | |
| <label>Name</label> | |
| <input type="text" id="registerName" required> | |
| </div> | |
| <div class="form-group"> | |
| <label>Email</label> | |
| <input type="email" id="registerEmail" required> | |
| </div> | |
| <div class="form-group"> | |
| <label>Password</label> | |
| <input type="password" id="registerPassword" required> | |
| </div> | |
| <div id="registerError" class="error"></div> | |
| <button type="submit">Register</button> | |
| </form> | |
| </div> | |
| `; | |
| // Tab switching | |
| this.shadowRoot.querySelectorAll('.auth-tab').forEach(tab => { | |
| tab.addEventListener('click', () => { | |
| this.shadowRoot.querySelectorAll('.auth-tab').forEach(t => t.classList.remove('active')); | |
| tab.classList.add('active'); | |
| document.getElementById('loginForm').classList.toggle('hidden'); | |
| document.getElementById('registerForm').classList.toggle('hidden'); | |
| }); | |
| }); | |
| // Form submissions | |
| this.shadowRoot.getElementById('loginForm').addEventListener('submit', this.handleLogin.bind(this)); | |
| this.shadowRoot.getElementById('registerForm').addEventListener('submit', this.handleRegister.bind(this)); | |
| } | |
| handleLogin(e) { | |
| e.preventDefault(); | |
| const email = this.shadowRoot.getElementById('loginEmail').value; | |
| const password = this.shadowRoot.getElementById('loginPassword').value; | |
| // In a real app, you would call your authentication API here | |
| if (email && password) { | |
| localStorage.setItem('currentUser', JSON.stringify({ email })); | |
| this.dispatchEvent(new CustomEvent('auth-success')); | |
| } else { | |
| this.shadowRoot.getElementById('loginError').textContent = 'Invalid credentials'; | |
| } | |
| } | |
| handleRegister(e) { | |
| e.preventDefault(); | |
| const name = this.shadowRoot.getElementById('registerName').value; | |
| const email = this.shadowRoot.getElementById('registerEmail').value; | |
| const password = this.shadowRoot.getElementById('registerPassword').value; | |
| // In a real app, you would call your registration API here | |
| if (name && email && password) { | |
| localStorage.setItem('currentUser', JSON.stringify({ email, name })); | |
| this.dispatchEvent(new CustomEvent('auth-success')); | |
| } else { | |
| this.shadowRoot.getElementById('registerError').textContent = 'Please fill all fields'; | |
| } | |
| } | |
| } | |
| customElements.define('auth-form', AuthForm); |