2026.06.04 frontend építés közben
This commit is contained in:
624
frontend/src/components/LoginModal.vue
Normal file
624
frontend/src/components/LoginModal.vue
Normal file
@@ -0,0 +1,624 @@
|
||||
<template>
|
||||
<Transition name="slide-fade">
|
||||
<div
|
||||
v-if="visible"
|
||||
class="fixed inset-0 z-[100] flex items-center justify-center px-4"
|
||||
@click.self="$emit('close')"
|
||||
>
|
||||
<!-- Dark Blurred Backdrop -->
|
||||
<div
|
||||
class="absolute inset-0 bg-[#062535]/80 backdrop-blur-sm"
|
||||
@click="$emit('close')"
|
||||
></div>
|
||||
|
||||
<!-- 3D Perspective Container -->
|
||||
<div class="perspective-1000 relative z-10 w-full max-w-md">
|
||||
<!-- Flippable Card Body -->
|
||||
<div
|
||||
class="relative transition-transform duration-700 transform-style-3d"
|
||||
:class="{
|
||||
'rotate-y-180': authMode === 'register',
|
||||
'rotate-x-180': authMode === 'forgot'
|
||||
}"
|
||||
>
|
||||
<!-- ==================== FRONT FACE: LOGIN ==================== -->
|
||||
<form
|
||||
@submit.prevent="handleLogin"
|
||||
class="backface-hidden w-full rounded-2xl border border-[#75A882]/30 bg-[#062535] p-8 shadow-2xl"
|
||||
:class="{ 'pointer-events-none': authMode !== 'login' }"
|
||||
>
|
||||
<!-- Close Button (X) -->
|
||||
<button
|
||||
type="button"
|
||||
@click="$emit('close')"
|
||||
class="absolute right-4 top-4 text-white/60 transition-colors hover:text-white"
|
||||
>
|
||||
<svg
|
||||
class="h-6 w-6"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18" />
|
||||
<line x1="6" y1="6" x2="18" y2="18" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- Title -->
|
||||
<h2 class="mb-8 text-center text-2xl font-bold text-white">
|
||||
Belépés a garázsba
|
||||
</h2>
|
||||
|
||||
<!-- Email Input -->
|
||||
<div class="mb-5">
|
||||
<label for="login-email" class="mb-2 block text-sm font-medium text-white/80">
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
id="login-email"
|
||||
v-model="email"
|
||||
type="email"
|
||||
placeholder="pelda@email.com"
|
||||
autocomplete="email"
|
||||
required
|
||||
class="w-full rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-white placeholder-white/30 backdrop-blur-sm transition-all duration-200 focus:border-[#75A882] focus:outline-none focus:ring-2 focus:ring-[#75A882]/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Password Input -->
|
||||
<div class="mb-6 relative">
|
||||
<label for="login-password" class="mb-2 block text-sm font-medium text-white/80">
|
||||
Jelszó
|
||||
</label>
|
||||
<input
|
||||
id="login-password"
|
||||
v-model="password"
|
||||
:type="showPassword ? 'text' : 'password'"
|
||||
placeholder="••••••••"
|
||||
autocomplete="current-password"
|
||||
required
|
||||
class="w-full rounded-xl border border-white/10 bg-white/5 px-4 py-3 pr-12 text-white placeholder-white/30 backdrop-blur-sm transition-all duration-200 focus:border-[#75A882] focus:outline-none focus:ring-2 focus:ring-[#75A882]/50"
|
||||
/>
|
||||
<!-- Eye icon (hold to show) -->
|
||||
<button
|
||||
type="button"
|
||||
@mousedown="showPassword = true"
|
||||
@mouseup="showPassword = false"
|
||||
@mouseleave="showPassword = false"
|
||||
@touchstart.prevent="showPassword = true"
|
||||
@touchend="showPassword = false"
|
||||
class="absolute right-3 top-[42px] text-white/40 hover:text-white/70 transition-colors cursor-pointer"
|
||||
tabindex="-1"
|
||||
aria-label="Jelszó megtekintése"
|
||||
>
|
||||
<!-- Eye open (password visible) -->
|
||||
<svg
|
||||
v-if="showPassword"
|
||||
class="h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" />
|
||||
<path d="M1 1l22 22" />
|
||||
</svg>
|
||||
<!-- Eye closed (password hidden) -->
|
||||
<svg
|
||||
v-else
|
||||
class="h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Forgot Password Link (right-aligned, always visible) -->
|
||||
<div class="mb-6 text-right">
|
||||
<a
|
||||
href="#"
|
||||
@click.prevent="switchMode('forgot')"
|
||||
class="text-xs text-[#75A882] hover:text-[#D4AF37] transition-colors"
|
||||
>
|
||||
Elfelejtetted a jelszavad?
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Error Message -->
|
||||
<div
|
||||
v-if="authStore.error && authMode === 'login'"
|
||||
class="mb-4 rounded-xl bg-red-500/20 px-4 py-3 text-sm text-red-300"
|
||||
>
|
||||
{{ authStore.error }}
|
||||
</div>
|
||||
|
||||
<!-- Login Button (Premium) -->
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="authStore.isLoading"
|
||||
class="btn-premium w-full px-4 py-3 text-lg"
|
||||
>
|
||||
{{ authStore.isLoading ? 'Kérlek várj...' : 'Belépés' }}
|
||||
</button>
|
||||
|
||||
<!-- Divider -->
|
||||
<div class="my-6 flex items-center gap-3">
|
||||
<span class="flex-1 border-t border-white/10"></span>
|
||||
<span class="text-sm text-white/40">vagy</span>
|
||||
<span class="flex-1 border-t border-white/10"></span>
|
||||
</div>
|
||||
|
||||
<!-- Social Login Placeholders -->
|
||||
<div class="mb-6 grid grid-cols-2 gap-3">
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center justify-center gap-2 rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-sm text-white/50 transition-all duration-200 hover:border-white/20 hover:text-white/80"
|
||||
>
|
||||
<!-- Google Logo Placeholder -->
|
||||
<svg class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z"/>
|
||||
<path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
|
||||
<path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
|
||||
<path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>
|
||||
</svg>
|
||||
Google
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center justify-center gap-2 rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-sm text-white/50 transition-all duration-200 hover:border-white/20 hover:text-white/80"
|
||||
>
|
||||
<!-- Apple Logo Placeholder -->
|
||||
<svg class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"/>
|
||||
</svg>
|
||||
Apple
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Registration Link (Triggers Flip) -->
|
||||
<p class="text-center text-sm text-white/50">
|
||||
Még nincs garázsod?
|
||||
<a
|
||||
href="#"
|
||||
@click.prevent="switchMode('register')"
|
||||
class="font-semibold text-[#D4AF37] transition-colors hover:text-[#D4AF37]/80"
|
||||
>
|
||||
Regisztráció
|
||||
</a>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<!-- ==================== BACK FACE: REGISTER ==================== -->
|
||||
<form
|
||||
v-if="activeBackFace === 'register'"
|
||||
@submit.prevent="handleRegister"
|
||||
class="backface-hidden rotate-y-180 absolute inset-0 w-full rounded-2xl border border-[#75A882]/30 bg-[#062535] p-8 shadow-2xl"
|
||||
>
|
||||
<!-- Close Button (X) -->
|
||||
<button
|
||||
type="button"
|
||||
@click="$emit('close')"
|
||||
class="absolute right-4 top-4 text-white/60 transition-colors hover:text-white"
|
||||
>
|
||||
<svg
|
||||
class="h-6 w-6"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18" />
|
||||
<line x1="6" y1="6" x2="18" y2="18" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- Title -->
|
||||
<h2 class="mb-8 text-center text-2xl font-bold text-white">
|
||||
Új Garázs Nyitása
|
||||
</h2>
|
||||
|
||||
<!-- Last Name Input -->
|
||||
<div class="mb-5">
|
||||
<label for="reg-lastname" class="mb-2 block text-sm font-medium text-white/80">
|
||||
Vezetéknév
|
||||
</label>
|
||||
<input
|
||||
id="reg-lastname"
|
||||
v-model="lastName"
|
||||
type="text"
|
||||
placeholder="Vezetéknév"
|
||||
autocomplete="family-name"
|
||||
required
|
||||
class="w-full rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-white placeholder-white/30 backdrop-blur-sm transition-all duration-200 focus:border-[#75A882] focus:outline-none focus:ring-2 focus:ring-[#75A882]/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- First Name Input -->
|
||||
<div class="mb-5">
|
||||
<label for="reg-firstname" class="mb-2 block text-sm font-medium text-white/80">
|
||||
Keresztnév
|
||||
</label>
|
||||
<input
|
||||
id="reg-firstname"
|
||||
v-model="firstName"
|
||||
type="text"
|
||||
placeholder="Keresztnév"
|
||||
autocomplete="given-name"
|
||||
required
|
||||
class="w-full rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-white placeholder-white/30 backdrop-blur-sm transition-all duration-200 focus:border-[#75A882] focus:outline-none focus:ring-2 focus:ring-[#75A882]/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Email Input -->
|
||||
<div class="mb-5">
|
||||
<label for="reg-email" class="mb-2 block text-sm font-medium text-white/80">
|
||||
E-mail
|
||||
</label>
|
||||
<input
|
||||
id="reg-email"
|
||||
v-model="regEmail"
|
||||
type="email"
|
||||
placeholder="pelda@email.com"
|
||||
autocomplete="email"
|
||||
required
|
||||
class="w-full rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-white placeholder-white/30 backdrop-blur-sm transition-all duration-200 focus:border-[#75A882] focus:outline-none focus:ring-2 focus:ring-[#75A882]/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Password Input -->
|
||||
<div class="mb-6 relative">
|
||||
<label for="reg-password" class="mb-2 block text-sm font-medium text-white/80">
|
||||
Jelszó
|
||||
</label>
|
||||
<input
|
||||
id="reg-password"
|
||||
v-model="regPassword"
|
||||
:type="showRegPassword ? 'text' : 'password'"
|
||||
placeholder="••••••••"
|
||||
autocomplete="new-password"
|
||||
required
|
||||
minlength="8"
|
||||
class="w-full rounded-xl border border-white/10 bg-white/5 px-4 py-3 pr-12 text-white placeholder-white/30 backdrop-blur-sm transition-all duration-200 focus:border-[#75A882] focus:outline-none focus:ring-2 focus:ring-[#75A882]/50"
|
||||
/>
|
||||
<!-- Eye icon (hold to show) -->
|
||||
<button
|
||||
type="button"
|
||||
@mousedown="showRegPassword = true"
|
||||
@mouseup="showRegPassword = false"
|
||||
@mouseleave="showRegPassword = false"
|
||||
@touchstart.prevent="showRegPassword = true"
|
||||
@touchend="showRegPassword = false"
|
||||
class="absolute right-3 top-[42px] text-white/40 hover:text-white/70 transition-colors cursor-pointer"
|
||||
tabindex="-1"
|
||||
aria-label="Jelszó megtekintése"
|
||||
>
|
||||
<!-- Eye open (password visible) -->
|
||||
<svg
|
||||
v-if="showRegPassword"
|
||||
class="h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" />
|
||||
<path d="M1 1l22 22" />
|
||||
</svg>
|
||||
<!-- Eye closed (password hidden) -->
|
||||
<svg
|
||||
v-else
|
||||
class="h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Error Message -->
|
||||
<div
|
||||
v-if="authStore.error && authMode === 'register'"
|
||||
class="mb-4 rounded-xl bg-red-500/20 px-4 py-3 text-sm text-red-300"
|
||||
>
|
||||
{{ authStore.error }}
|
||||
</div>
|
||||
|
||||
<!-- Register Button (Premium) -->
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="authStore.isLoading"
|
||||
class="btn-premium w-full px-4 py-3 text-lg"
|
||||
>
|
||||
{{ authStore.isLoading ? 'Kérlek várj...' : 'Regisztráció' }}
|
||||
</button>
|
||||
|
||||
<!-- Switch back to Login -->
|
||||
<p class="mt-6 text-center text-sm text-white/50">
|
||||
Már van garázsod?
|
||||
<a
|
||||
href="#"
|
||||
@click.prevent="switchMode('login')"
|
||||
class="font-semibold text-[#D4AF37] transition-colors hover:text-[#D4AF37]/80"
|
||||
>
|
||||
Belépés
|
||||
</a>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<!-- ==================== THIRD FACE: FORGOT PASSWORD ==================== -->
|
||||
<form
|
||||
v-if="activeBackFace === 'forgot'"
|
||||
@submit.prevent="handleForgotPassword"
|
||||
class="backface-hidden rotate-x-180 absolute inset-0 w-full rounded-2xl border border-[#75A882]/30 bg-[#062535] p-8 shadow-2xl"
|
||||
>
|
||||
<!-- Close Button (X) -->
|
||||
<button
|
||||
type="button"
|
||||
@click="$emit('close')"
|
||||
class="absolute right-4 top-4 text-white/60 transition-colors hover:text-white"
|
||||
>
|
||||
<svg
|
||||
class="h-6 w-6"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18" />
|
||||
<line x1="6" y1="6" x2="18" y2="18" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- Title -->
|
||||
<h2 class="mb-6 text-center text-2xl font-bold text-white">
|
||||
Új jelszó igénylése
|
||||
</h2>
|
||||
|
||||
<!-- Description -->
|
||||
<p class="mb-6 rounded-xl bg-[#1A6B5A]/20 px-4 py-3 text-center text-sm text-[#5EC4B0]">
|
||||
Add meg az e-mail címed, és küldünk egy biztonsági linket.
|
||||
</p>
|
||||
|
||||
<!-- Email Input -->
|
||||
<div class="mb-6">
|
||||
<label for="forgot-email" class="mb-2 block text-sm font-medium text-white/80">
|
||||
E-mail
|
||||
</label>
|
||||
<input
|
||||
id="forgot-email"
|
||||
v-model="forgotEmail"
|
||||
type="email"
|
||||
placeholder="pelda@email.com"
|
||||
autocomplete="email"
|
||||
required
|
||||
class="w-full rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-white placeholder-white/30 backdrop-blur-sm transition-all duration-200 focus:border-[#75A882] focus:outline-none focus:ring-2 focus:ring-[#75A882]/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Error Message -->
|
||||
<div
|
||||
v-if="authStore.error && authMode === 'forgot'"
|
||||
class="mb-4 rounded-xl bg-red-500/20 px-4 py-3 text-sm text-red-300"
|
||||
>
|
||||
{{ authStore.error }}
|
||||
</div>
|
||||
|
||||
<!-- Send Link Button (Premium) -->
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="authStore.isLoading"
|
||||
class="btn-premium w-full px-4 py-3 text-lg"
|
||||
>
|
||||
{{ authStore.isLoading ? 'Kérlek várj...' : 'Link Küldése' }}
|
||||
</button>
|
||||
|
||||
<!-- Back to Login -->
|
||||
<p class="mt-6 text-center text-sm text-white/50">
|
||||
<a
|
||||
href="#"
|
||||
@click.prevent="switchMode('login')"
|
||||
class="font-semibold text-[#D4AF37] transition-colors hover:text-[#D4AF37]/80"
|
||||
>
|
||||
Vissza a belépéshez
|
||||
</a>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAuthStore } from '../stores/auth'
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
close: []
|
||||
}>()
|
||||
|
||||
const router = useRouter()
|
||||
const authStore = useAuthStore()
|
||||
|
||||
// ── Login form fields ──
|
||||
const email = ref('')
|
||||
const password = ref('')
|
||||
|
||||
// ── Register form fields ──
|
||||
const lastName = ref('')
|
||||
const firstName = ref('')
|
||||
const regEmail = ref('')
|
||||
const regPassword = ref('')
|
||||
|
||||
// ── Forgot password form fields ──
|
||||
const forgotEmail = ref('')
|
||||
|
||||
// ── Password visibility states (hold-to-show) ──
|
||||
const showPassword = ref(false)
|
||||
const showRegPassword = ref(false)
|
||||
|
||||
// ── 3D Flip state machine ──
|
||||
const authMode = ref<'login' | 'register' | 'forgot'>('login')
|
||||
const activeBackFace = ref<'register' | 'forgot'>('register')
|
||||
|
||||
// ── Reset modal state when it closes ──
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (!newVal) {
|
||||
// Reset view to login
|
||||
authMode.value = 'login'
|
||||
activeBackFace.value = 'register'
|
||||
// Clear all form fields
|
||||
email.value = ''
|
||||
password.value = ''
|
||||
lastName.value = ''
|
||||
firstName.value = ''
|
||||
regEmail.value = ''
|
||||
regPassword.value = ''
|
||||
forgotEmail.value = ''
|
||||
// Clear store error
|
||||
authStore.clearError()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// ── Clear store error when switching modes ──
|
||||
watch(authMode, () => {
|
||||
authStore.clearError()
|
||||
})
|
||||
|
||||
function switchMode(mode: 'login' | 'register' | 'forgot') {
|
||||
if (mode !== 'login') {
|
||||
activeBackFace.value = mode
|
||||
}
|
||||
authMode.value = mode
|
||||
}
|
||||
|
||||
// ── Smart Login Logic ──
|
||||
async function handleLogin() {
|
||||
try {
|
||||
await authStore.login(email.value, password.value)
|
||||
|
||||
// After successful login, check KYC status
|
||||
if (authStore.isKycComplete) {
|
||||
router.push('/dashboard')
|
||||
} else {
|
||||
router.push('/complete-kyc')
|
||||
}
|
||||
|
||||
// Close the modal
|
||||
emit('close')
|
||||
} catch {
|
||||
// Error is already set in authStore.error — UI displays it automatically
|
||||
}
|
||||
}
|
||||
|
||||
// ── Register Logic ──
|
||||
async function handleRegister() {
|
||||
try {
|
||||
await authStore.register({
|
||||
email: regEmail.value,
|
||||
password: regPassword.value,
|
||||
first_name: firstName.value,
|
||||
last_name: lastName.value,
|
||||
})
|
||||
|
||||
// Registration successful — flip back to login so user can sign in
|
||||
switchMode('login')
|
||||
// Pre-fill the email field
|
||||
email.value = regEmail.value
|
||||
// Clear register fields
|
||||
lastName.value = ''
|
||||
firstName.value = ''
|
||||
regEmail.value = ''
|
||||
regPassword.value = ''
|
||||
} catch {
|
||||
// Error is already set in authStore.error
|
||||
}
|
||||
}
|
||||
|
||||
// ── Forgot Password Logic ──
|
||||
async function handleForgotPassword() {
|
||||
try {
|
||||
await authStore.forgotPassword(forgotEmail.value)
|
||||
|
||||
// Success — flip back to login
|
||||
switchMode('login')
|
||||
forgotEmail.value = ''
|
||||
} catch {
|
||||
// Error is already set in authStore.error
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Slide-Fade Transition: enters from top-right, fades in — slower & more elegant */
|
||||
.slide-fade-enter-active {
|
||||
transition: all 0.5s cubic-bezier(0.25, 1, 0.5, 1);
|
||||
}
|
||||
.slide-fade-leave-active {
|
||||
transition: all 0.5s cubic-bezier(0.25, 1, 0.5, 1);
|
||||
}
|
||||
.slide-fade-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateX(48px) translateY(-48px) scale(0.95);
|
||||
}
|
||||
.slide-fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(48px) translateY(-48px) scale(0.95);
|
||||
}
|
||||
|
||||
/* 3D Card Flip Utilities */
|
||||
.perspective-1000 {
|
||||
perspective: 1000px;
|
||||
}
|
||||
.transform-style-3d {
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
.backface-hidden {
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
.rotate-y-180 {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
.rotate-x-180 {
|
||||
transform: rotateX(180deg);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user