90 lines
4.0 KiB
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>
|