rajesh / index.html
Rajeshdakulla's picture
undefined - Initial Deployment
bb94aea verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Auth Modal with TailwindCSS</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.animate-fade-in {
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.animate-slide-up {
animation: slideUp 0.3s ease-in-out;
}
@keyframes slideUp {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
.input-focus-effect:focus {
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5);
}
.btn-loading {
position: relative;
overflow: hidden;
}
.btn-loading::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
animation: loading 1.5s infinite;
}
@keyframes loading {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
</style>
</head>
<body class="bg-gray-100 min-h-screen flex items-center justify-center">
<div class="text-center">
<h1 class="text-3xl font-bold mb-8 text-gray-800">
Authentication Demo
</h1>
<div class="space-x-2 sm:space-x-4">
<button
id="loginBtn"
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 sm:px-6 sm:py-3 rounded-md font-medium transition-colors"
>
Open Login Modal
</button>
<button
id="signupBtn"
class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 sm:px-6 sm:py-3 rounded-md font-medium transition-colors"
>
Open Signup Modal
</button>
</div>
</div>
<!-- Auth Modal -->
<div id="authModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden animate-fade-in">
<div class="bg-white rounded-lg p-6 sm:p-8 max-w-md w-full mx-4 relative animate-slide-up">
<button
id="closeModal"
class="absolute top-4 right-4 text-gray-500 hover:text-gray-700 text-2xl leading-none"
>
&times;
</button>
<h2 id="modalTitle" class="text-2xl font-bold mb-6 text-center">
Welcome Back
</h2>
<div id="errorMessage" class="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded mb-4 hidden"></div>
<button
id="googleAuthBtn"
class="flex items-center justify-center w-full bg-red-600 hover:bg-red-700 disabled:bg-red-400 text-white py-3 rounded-md mb-4 transition-colors"
>
<i class="fab fa-google mr-2"></i>
Continue with Google
</button>
<div class="relative my-6">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white text-gray-500">OR</span>
</div>
</div>
<div>
<div id="fullNameContainer" class="mb-4 hidden">
<input
type="text"
id="fullName"
placeholder="Full Name"
class="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none input-focus-effect"
/>
</div>
<div class="mb-4">
<input
type="email"
id="email"
placeholder="Email"
class="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none input-focus-effect"
/>
</div>
<div class="mb-6">
<input
type="password"
id="password"
placeholder="Password"
class="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none input-focus-effect"
/>
</div>
<button
id="submitBtn"
class="w-full bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400 text-white py-3 rounded-md transition-colors font-medium btn-loading"
>
Sign In
</button>
</div>
<div class="mt-6 text-center">
<p id="toggleText" class="text-gray-600">
Don't have an account?
<button
id="toggleModeBtn"
class="text-blue-600 hover:text-blue-700 font-medium"
>
Sign up
</button>
</p>
</div>
<div class="mt-4 text-xs text-gray-500 text-center">
<p>Demo: Try 'test@error.com' for signup error, 'wrong' password for login error</p>
</div>
</div>
</div>
<script>
// State management
const state = {
mode: 'login',
email: '',
password: '',
fullName: '',
error: '',
loading: false
};
// DOM elements
const elements = {
authModal: document.getElementById('authModal'),
modalTitle: document.getElementById('modalTitle'),
errorMessage: document.getElementById('errorMessage'),
fullNameContainer: document.getElementById('fullNameContainer'),
fullName: document.getElementById('fullName'),
email: document.getElementById('email'),
password: document.getElementById('password'),
submitBtn: document.getElementById('submitBtn'),
toggleText: document.getElementById('toggleText'),
toggleModeBtn: document.getElementById('toggleModeBtn'),
googleAuthBtn: document.getElementById('googleAuthBtn'),
closeModal: document.getElementById('closeModal'),
loginBtn: document.getElementById('loginBtn'),
signupBtn: document.getElementById('signupBtn')
};
// Event listeners
elements.loginBtn.addEventListener('click', () => openModal('login'));
elements.signupBtn.addEventListener('click', () => openModal('signup'));
elements.closeModal.addEventListener('click', closeModal);
elements.toggleModeBtn.addEventListener('click', toggleMode);
elements.submitBtn.addEventListener('click', handleSubmit);
elements.googleAuthBtn.addEventListener('click', handleGoogleAuth);
// Input change handlers
elements.email.addEventListener('input', (e) => {
state.email = e.target.value;
});
elements.password.addEventListener('input', (e) => {
state.password = e.target.value;
});
elements.fullName.addEventListener('input', (e) => {
state.fullName = e.target.value;
});
// Functions
function openModal(mode) {
state.mode = mode;
resetForm();
updateUI();
elements.authModal.classList.remove('hidden');
document.body.style.overflow = 'hidden';
}
function closeModal() {
elements.authModal.classList.add('hidden');
document.body.style.overflow = 'auto';
}
function toggleMode() {
state.mode = state.mode === 'login' ? 'signup' : 'login';
resetForm();
updateUI();
}
function resetForm() {
state.email = '';
state.password = '';
state.fullName = '';
state.error = '';
state.loading = false;
elements.email.value = '';
elements.password.value = '';
elements.fullName.value = '';
elements.errorMessage.classList.add('hidden');
}
function updateUI() {
// Update title
elements.modalTitle.textContent = state.mode === 'login'
? 'Welcome Back'
: 'Create Account';
// Update submit button text
elements.submitBtn.textContent = state.mode === 'login'
? 'Sign In'
: 'Create Account';
// Toggle full name field
if (state.mode === 'signup') {
elements.fullNameContainer.classList.remove('hidden');
} else {
elements.fullNameContainer.classList.add('hidden');
}
// Update toggle text
elements.toggleText.innerHTML = state.mode === 'login'
? "Don't have an account? "
: "Already have an account? ";
elements.toggleModeBtn.textContent = state.mode === 'login'
? 'Sign up'
: 'Sign in';
}
function setLoading(loading) {
state.loading = loading;
elements.submitBtn.disabled = loading;
elements.googleAuthBtn.disabled = loading;
elements.toggleModeBtn.disabled = loading;
if (loading) {
elements.submitBtn.classList.add('btn-loading');
} else {
elements.submitBtn.classList.remove('btn-loading');
}
}
function showError(message) {
state.error = message;
elements.errorMessage.textContent = message;
elements.errorMessage.classList.remove('hidden');
}
function hideError() {
state.error = '';
elements.errorMessage.classList.add('hidden');
}
// Mock authentication functions
async function mockSignUp() {
// Simulate API call delay
await new Promise(resolve => setTimeout(resolve, 1000));
if (state.email === 'test@error.com') {
return {
data: null,
error: { message: 'Email already exists' }
};
}
return {
data: {
user: {
id: 'user-123',
email: state.email,
user_metadata: {
full_name: state.fullName
}
}
},
error: null
};
}
async function mockSignIn() {
// Simulate API call delay
await new Promise(resolve => setTimeout(resolve, 1000));
if (state.password === 'wrong') {
return {
data: null,
error: { message: 'Invalid credentials' }
};
}
return {
data: {
user: {
id: 'user-123',
email: state.email
}
},
error: null
};
}
async function mockGoogleAuth() {
// Simulate API call delay
await new Promise(resolve => setTimeout(resolve, 1000));
return { error: null };
}
async function mockInsertProfile(user) {
// Simulate API call delay
await new Promise(resolve => setTimeout(resolve, 500));
return { error: null };
}
// Event handlers
async function handleSubmit() {
hideError();
// Basic validation
if (!state.email) {
showError('Email is required');
return;
}
if (!state.password) {
showError('Password is required');
return;
}
if (state.mode === 'signup' && !state.fullName) {
showError('Full name is required');
return;
}
setLoading(true);
try {
if (state.mode === 'login') {
const { data, error } = await mockSignIn();
if (error) {
showError(error.message);
} else {
closeModal();
alert(`Welcome back, ${data.user.email}!`);
}
} else {
// Sign up flow
const { data: user, error: signUpError } = await mockSignUp();
if (signUpError) {
showError(signUpError.message);
return;
}
// Insert profile
const { error: profileError } = await mockInsertProfile(user.user);
if (profileError) {
showError(profileError.message);
} else {
closeModal();
alert(`Account created for ${user.user.email}!`);
}
}
} catch (err) {
showError('An unexpected error occurred');
} finally {
setLoading(false);
}
}
async function handleGoogleAuth() {
hideError();
setLoading(true);
try {
const { error } = await mockGoogleAuth();
if (error) {
showError(error.message);
} else {
// In a real app, this would redirect to Google
alert('Would redirect to Google OAuth in a real app');
}
} catch (err) {
showError('An unexpected error occurred');
} finally {
setLoading(false);
}
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Rajeshdakulla/rajesh" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>