Enhanced Login Form
Login form with validation states, remember me, and forgot password
<form x-data="{ email: '', password: '', remember: false, loading: false }"
@submit.prevent="loading = true; setTimeout(() => loading = false, 2000)"
class="max-w-md mx-auto bg-white dark:bg-gray-800 rounded-lg shadow p-8">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6">Sign In</h2>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Email</label>
<input type="email" x-model="email" required
class="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 dark:bg-gray-700">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Password</label>
<input type="password" x-model="password" required
class="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 dark:bg-gray-700">
</div>
<div class="flex items-center justify-between mb-6">
<label class="flex items-center">
<input type="checkbox" x-model="remember" class="rounded border-gray-300 text-blue-600 focus:ring-blue-500">
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">Remember me</span>
</label>
<a href="#" class="text-sm text-blue-600 hover:text-blue-500">Forgot password?</a>
</div>
<button type="submit" :disabled="loading"
class="w-full bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700 disabled:opacity-50">
<span x-show="!loading">Sign In</span>
<span x-show="loading">Signing in...</span>
</button>
</form>
Enhanced Register Form
Registration form with password strength indicator and terms checkbox
<form x-data="{
password: '',
confirmPassword: '',
strength: 0,
terms: false,
calculateStrength() {
let score = 0;
if (this.password.length > 8) score++;
if (/[a-z]/.test(this.password) && /[A-Z]/.test(this.password)) score++;
if (/[0-9]/.test(this.password)) score++;
if (/[^a-zA-Z0-9]/.test(this.password)) score++;
this.strength = score;
}
}" class="max-w-md mx-auto bg-white dark:bg-gray-800 rounded-lg shadow p-8">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6">Create Account</h2>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Full Name</label>
<input type="text" class="w-full px-4 py-2 border rounded-lg dark:bg-gray-700">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Email</label>
<input type="email" class="w-full px-4 py-2 border rounded-lg dark:bg-gray-700">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Password</label>
<input type="password" x-model="password" @input="calculateStrength()"
class="w-full px-4 py-2 border rounded-lg dark:bg-gray-700">
<div class="mt-2 flex gap-1">
<div class="h-1 flex-1 rounded" :class="strength >= 1 ? 'bg-red-500' : 'bg-gray-200'"></div>
<div class="h-1 flex-1 rounded" :class="strength >= 2 ? 'bg-yellow-500' : 'bg-gray-200'"></div>
<div class="h-1 flex-1 rounded" :class="strength >= 3 ? 'bg-blue-500' : 'bg-gray-200'"></div>
<div class="h-1 flex-1 rounded" :class="strength >= 4 ? 'bg-green-500' : 'bg-gray-200'"></div>
</div>
</div>
<div class="mb-4">
<label class="flex items-start">
<input type="checkbox" x-model="terms" class="mt-1 rounded">
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">
I agree to the <a href="#" class="text-blue-600">Terms and Conditions</a>
</span>
</label>
</div>
<button type="submit" :disabled="!terms" class="w-full bg-blue-600 text-white py-2 rounded-lg disabled:opacity-50">
Create Account
</button>
</form>
OTP Verification
One-time password verification with resend timer
Verify Your Email
Enter the 6-digit code sent to your email
<div x-data="{
otp: ['', '', '', '', '', ''],
timer: 60,
canResend: false,
startTimer() {
this.timer = 60;
this.canResend = false;
const interval = setInterval(() => {
this.timer--;
if (this.timer === 0) {
this.canResend = true;
clearInterval(interval);
}
}, 1000);
}
}" x-init="startTimer()" class="max-w-md mx-auto bg-white dark:bg-gray-800 rounded-lg shadow p-8">
<h2 class="text-2xl font-bold text-center mb-2">Verify Your Email</h2>
<p class="text-sm text-gray-600 dark:text-gray-400 text-center mb-6">
Enter the 6-digit code sent to your email
</p>
<div class="flex gap-2 justify-center mb-6">
<template x-for="(digit, index) in otp" :key="index">
<input type="text" maxlength="1" x-model="otp[index]"
@input="if ($event.target.value && index < 5) $refs['input' + (index + 1)].focus()"
:x-ref="'input' + index"
class="w-12 h-12 text-center text-lg font-bold border-2 rounded-lg focus:border-blue-500">
</template>
</div>
<button class="w-full bg-blue-600 text-white py-2 rounded-lg mb-4">Verify</button>
<div class="text-center text-sm">
<span class="text-gray-600 dark:text-gray-400">Didn't receive code?</span>
<button @click="startTimer()" :disabled="!canResend"
:class="canResend ? 'text-blue-600' : 'text-gray-400'"
class="ml-1 font-medium">
<span x-show="!canResend" x-text="'Resend in ' + timer + 's'"></span>
<span x-show="canResend">Resend Code</span>
</button>
</div>
</div>
2FA Setup Wizard
Two-factor authentication setup with QR code and backup codes
Scan QR Code
Scan this QR code with your authenticator app
<div x-data="{ step: 1 }" class="max-w-2xl mx-auto bg-white dark:bg-gray-800 rounded-lg shadow p-8">
<div class="mb-8">
<div class="flex items-center justify-between mb-4">
<div class="flex items-center" :class="step >= 1 ? 'text-blue-600' : 'text-gray-400'">
<div class="w-8 h-8 rounded-full flex items-center justify-center"
:class="step >= 1 ? 'bg-blue-600 text-white' : 'bg-gray-300'">1</div>
<span class="ml-2 font-medium">Scan QR Code</span>
</div>
<div class="flex items-center" :class="step >= 2 ? 'text-blue-600' : 'text-gray-400'">
<div class="w-8 h-8 rounded-full flex items-center justify-center"
:class="step >= 2 ? 'bg-blue-600 text-white' : 'bg-gray-300'">2</div>
<span class="ml-2 font-medium">Backup Codes</span>
</div>
</div>
</div>
<div x-show="step === 1">
<h3 class="text-lg font-semibold mb-4">Scan QR Code</h3>
<div class="flex flex-col items-center">
<div class="w-48 h-48 bg-gray-200 dark:bg-gray-700 rounded-lg flex items-center justify-center mb-4">
<span class="text-gray-500">QR Code Here</span>
</div>
<p class="text-sm text-gray-600 dark:text-gray-400 text-center mb-6">
Scan this QR code with your authenticator app
</p>
<button @click="step = 2" class="bg-blue-600 text-white px-6 py-2 rounded-lg">
Continue
</button>
</div>
</div>
<div x-show="step === 2">
<h3 class="text-lg font-semibold mb-4">Save Backup Codes</h3>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
Store these codes safely. Each can only be used once.
</p>
<div class="grid grid-cols-2 gap-2 mb-6">
<div class="p-3 bg-gray-100 dark:bg-gray-700 rounded font-mono text-sm">ABCD-1234</div>
<div class="p-3 bg-gray-100 dark:bg-gray-700 rounded font-mono text-sm">EFGH-5678</div>
<div class="p-3 bg-gray-100 dark:bg-gray-700 rounded font-mono text-sm">IJKL-9012</div>
<div class="p-3 bg-gray-100 dark:bg-gray-700 rounded font-mono text-sm">MNOP-3456</div>
</div>
<button class="w-full bg-blue-600 text-white py-2 rounded-lg">Complete Setup</button>
</div>
</div>
Profile Settings Page
Editable profile form with save states and validation
Profile Settings
<div x-data="{ saving: false, saved: false }" class="max-w-3xl mx-auto bg-white dark:bg-gray-800 rounded-lg shadow p-8">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6">Profile Settings</h2>
<form @submit.prevent="saving = true; setTimeout(() => { saving = false; saved = true; setTimeout(() => saved = false, 3000); }, 1500)">
<div class="grid grid-cols-2 gap-6 mb-6">
<div>
<label class="block text-sm font-medium mb-2">First Name</label>
<input type="text" value="John" class="w-full px-4 py-2 border rounded-lg dark:bg-gray-700">
</div>
<div>
<label class="block text-sm font-medium mb-2">Last Name</label>
<input type="text" value="Doe" class="w-full px-4 py-2 border rounded-lg dark:bg-gray-700">
</div>
</div>
<div class="mb-6">
<label class="block text-sm font-medium mb-2">Email</label>
<input type="email" value="john@example.com" class="w-full px-4 py-2 border rounded-lg dark:bg-gray-700">
</div>
<div class="mb-6">
<label class="block text-sm font-medium mb-2">Bio</label>
<textarea rows="4" class="w-full px-4 py-2 border rounded-lg dark:bg-gray-700"></textarea>
</div>
<div class="flex items-center gap-4">
<button type="submit" :disabled="saving"
class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50">
<span x-show="!saving">Save Changes</span>
<span x-show="saving">Saving...</span>
</button>
<span x-show="saved" class="text-green-600 text-sm">Changes saved successfully!</span>
</div>
</form>
</div>
Password Change Form
Change password with strength meter and validation
Change Password
<div x-data="{
current: '',
newPassword: '',
confirm: '',
strength: 0,
showCurrent: false,
showNew: false,
calculateStrength() {
let score = 0;
if (this.newPassword.length > 8) score++;
if (/[a-z]/.test(this.newPassword) && /[A-Z]/.test(this.newPassword)) score++;
if (/[0-9]/.test(this.newPassword)) score++;
if (/[^a-zA-Z0-9]/.test(this.newPassword)) score++;
this.strength = score;
}
}" class="max-w-md mx-auto bg-white dark:bg-gray-800 rounded-lg shadow p-8">
<h2 class="text-2xl font-bold mb-6">Change Password</h2>
<div class="mb-4">
<label class="block text-sm font-medium mb-2">Current Password</label>
<div class="relative">
<input :type="showCurrent ? 'text' : 'password'" x-model="current"
class="w-full px-4 py-2 border rounded-lg dark:bg-gray-700 pr-10">
<button type="button" @click="showCurrent = !showCurrent" class="absolute right-3 top-3">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path x-show="!showCurrent" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
<path x-show="!showCurrent" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
</svg>
</button>
</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-2">New Password</label>
<input type="password" x-model="newPassword" @input="calculateStrength()"
class="w-full px-4 py-2 border rounded-lg dark:bg-gray-700">
<div class="mt-2 flex gap-1">
<div class="h-1 flex-1 rounded" :class="strength >= 1 ? 'bg-red-500' : 'bg-gray-200'"></div>
<div class="h-1 flex-1 rounded" :class="strength >= 2 ? 'bg-yellow-500' : 'bg-gray-200'"></div>
<div class="h-1 flex-1 rounded" :class="strength >= 3 ? 'bg-blue-500' : 'bg-gray-200'"></div>
<div class="h-1 flex-1 rounded" :class="strength >= 4 ? 'bg-green-500' : 'bg-gray-200'"></div>
</div>
</div>
<div class="mb-6">
<label class="block text-sm font-medium mb-2">Confirm New Password</label>
<input type="password" x-model="confirm" class="w-full px-4 py-2 border rounded-lg dark:bg-gray-700">
<p x-show="confirm && newPassword !== confirm" class="text-xs text-red-500 mt-1">
Passwords do not match
</p>
</div>
<button class="w-full bg-blue-600 text-white py-2 rounded-lg">Update Password</button>
</div>
Active Sessions Management
View and manage active sessions with device info and revoke actions
Active Sessions
Manage devices where you're currently signed in
<div x-data="{
sessions: [
{ id: 1, device: 'Chrome on Windows', location: 'New York, USA', current: true, lastActive: 'Just now' },
{ id: 2, device: 'Safari on iPhone', location: 'San Francisco, USA', current: false, lastActive: '2 hours ago' },
{ id: 3, device: 'Firefox on Ubuntu', location: 'London, UK', current: false, lastActive: '1 day ago' }
],
revokeSession(id) {
this.sessions = this.sessions.filter(s => s.id !== id);
}
}" class="bg-white dark:bg-gray-800 rounded-lg shadow">
<div class="p-6 border-b dark:border-gray-700">
<h3 class="text-lg font-semibold">Active Sessions</h3>
<p class="text-sm text-gray-600 dark:text-gray-400">Manage devices where you're currently signed in</p>
</div>
<div class="divide-y dark:divide-gray-700">
<template x-for="session in sessions" :key="session.id">
<div class="p-6 flex items-center justify-between">
<div class="flex items-center gap-4">
<svg class="w-10 h-10 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
<path d="M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zm0 6a1 1 0 011-1h12a1 1 0 011 1v6a1 1 0 01-1 1H4a1 1 0 01-1-1v-6z"/>
</svg>
<div>
<div class="flex items-center gap-2">
<p class="font-medium" x-text="session.device"></p>
<span x-show="session.current" class="px-2 py-0.5 bg-green-100 text-green-800 text-xs rounded">Current</span>
</div>
<p class="text-sm text-gray-500" x-text="session.location"></p>
<p class="text-xs text-gray-400" x-text="session.lastActive"></p>
</div>
</div>
<button x-show="!session.current" @click="revokeSession(session.id)"
class="text-red-600 hover:text-red-700 text-sm font-medium">
Revoke
</button>
</div>
</template>
</div>
</div>
API Tokens Management
Generate, copy, and revoke API tokens with last used timestamp
API Tokens
Manage your API access tokens
Last used
<div x-data="{
tokens: [
{ id: 1, name: 'Production API', token: 'sk_live_***************', lastUsed: '2 hours ago' },
{ id: 2, name: 'Development API', token: 'sk_test_***************', lastUsed: 'Never' }
],
showModal: false,
newToken: '',
generateToken() {
const token = 'sk_live_' + Math.random().toString(36).substring(2, 15);
this.newToken = token;
this.showModal = true;
},
copyToken(token) {
navigator.clipboard.writeText(token);
alert('Token copied to clipboard!');
}
}" class="bg-white dark:bg-gray-800 rounded-lg shadow">
<div class="p-6 border-b dark:border-gray-700 flex justify-between items-center">
<div>
<h3 class="text-lg font-semibold">API Tokens</h3>
<p class="text-sm text-gray-600 dark:text-gray-400">Manage your API access tokens</p>
</div>
<button @click="generateToken()" class="px-4 py-2 bg-blue-600 text-white rounded-lg">
Generate Token
</button>
</div>
<div class="divide-y dark:divide-gray-700">
<template x-for="token in tokens" :key="token.id">
<div class="p-6 flex items-center justify-between">
<div class="flex-1">
<p class="font-medium" x-text="token.name"></p>
<p class="text-sm text-gray-500 font-mono" x-text="token.token"></p>
<p class="text-xs text-gray-400">Last used <span x-text="token.lastUsed"></span></p>
</div>
<div class="flex gap-2">
<button @click="copyToken(token.token)" class="text-blue-600 text-sm">Copy</button>
<button class="text-red-600 text-sm">Revoke</button>
</div>
</div>
</template>
</div>
<div x-show="showModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div class="bg-white dark:bg-gray-800 rounded-lg p-6 max-w-md">
<h3 class="text-lg font-semibold mb-4">Token Generated</h3>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
Copy this token now. You won't be able to see it again!
</p>
<div class="p-3 bg-gray-100 dark:bg-gray-700 rounded font-mono text-sm mb-4" x-text="newToken"></div>
<div class="flex gap-2">
<button @click="copyToken(newToken)" class="flex-1 bg-blue-600 text-white py-2 rounded">
Copy Token
</button>
<button @click="showModal = false" class="px-4 py-2 border rounded">Close</button>
</div>
</div>
</div>
</div>