idconvert/frontend/app/components/auth/AuthModal.vue

90 lines
4.0 KiB
Vue

<script setup>
const auth = useAuthStore()
const ui = useUiStore()
const email = ref('')
const password = ref('')
const name = ref('')
const isLogin = computed(() => ui.authModalMode === 'login')
async function handleSubmit() {
if (isLogin.value) {
await auth.login(email.value, password.value)
} else {
await auth.register(email.value, password.value, name.value)
}
if (!auth.error) ui.closeAuthModal()
}
function devLogin(userEmail) {
auth.login(userEmail, 'pass').then(() => {
if (!auth.error) ui.closeAuthModal()
})
}
</script>
<template>
<Teleport to="body">
<div class="fixed inset-0 bg-black/40 flex items-center justify-center z-[100] p-4" @click.self="ui.closeAuthModal()">
<div class="bg-white rounded-xl p-8 w-full max-w-md shadow-xl">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-bold text-gray-900">{{ isLogin ? 'Log in' : 'Create account' }}</h2>
<button @click="ui.closeAuthModal()" class="text-gray-400 hover:text-gray-600 transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div v-if="auth.error" class="bg-red-50 border border-red-200 text-red-700 text-sm rounded-lg px-3 py-2 mb-4">
{{ auth.error }}
</div>
<form @submit.prevent="handleSubmit" class="space-y-4">
<div v-if="!isLogin">
<label class="block text-sm font-medium text-gray-700 mb-1">Name</label>
<input v-model="name" type="text" required placeholder="Your name"
class="w-full border border-gray-200 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-100 focus:border-[#1a56db]" />
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Email</label>
<input v-model="email" type="email" required placeholder="you@example.com"
class="w-full border border-gray-200 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-100 focus:border-[#1a56db]" />
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Password</label>
<input v-model="password" type="password" required placeholder="••••••••"
class="w-full border border-gray-200 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-100 focus:border-[#1a56db]" />
</div>
<BaseButton type="submit" variant="primary" full-width :loading="auth.status === 'loading'">
{{ isLogin ? 'Log in' : 'Create account' }}
</BaseButton>
</form>
<p class="text-sm text-gray-500 text-center mt-4">
<template v-if="isLogin">
No account?
<button @click="ui.openAuthModal('register')" class="text-[#1a56db] hover:underline">Sign up free</button>
</template>
<template v-else>
Already have an account?
<button @click="ui.openAuthModal('login')" class="text-[#1a56db] hover:underline">Log in</button>
</template>
</p>
<!-- Dev shortcuts -->
<div class="mt-6 pt-4 border-t border-gray-100">
<p class="text-xs text-gray-400 mb-2">Dev shortcuts (mock only):</p>
<div class="flex flex-wrap gap-2">
<button @click="devLogin('maya@studio.com')" class="text-xs bg-gray-100 hover:bg-gray-200 px-2.5 py-1 rounded transition-colors">Maya (4 credits)</button>
<button @click="devLogin('richard@firmname.com')" class="text-xs bg-gray-100 hover:bg-gray-200 px-2.5 py-1 rounded transition-colors">Richard (0 credits)</button>
<button @click="devLogin('new@user.com')" class="text-xs bg-gray-100 hover:bg-gray-200 px-2.5 py-1 rounded transition-colors">New user (free unused)</button>
</div>
</div>
</div>
</div>
</Teleport>
</template>