Files
go_nuxt_admin/app/pages/auth/login.vue
Beyhan Oğur 5285a0dd86 first commit
2026-04-26 22:07:47 +03:00

177 lines
6.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="login-area pt-120 pb-120">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-6 col-md-8">
<div class="login-form-wrap shadow-lg p-5 rounded bg-white">
<div class="login-header text-center mb-4">
<h2 class="mb-2">Giriş Yap</h2>
<p>
Hesabınız yok mu?
<NuxtLink to="/auth/register" class="text-primary fw-bold">Kayıt Olun</NuxtLink>
</p>
</div>
<form @submit.prevent="handleLogin">
<div class="mb-3">
<label for="email" class="form-label">E-posta Adresi</label>
<div class="input-group">
<span class="input-group-text"><i class="fas fa-envelope"></i></span>
<input type="email" class="form-control" id="email" v-model="form.email"
placeholder="E-posta adresinizi girin" required>
</div>
<div v-if="errors.email" class="text-danger small mt-1">{{ errors.email }}</div>
</div>
<div class="mb-3">
<label for="password" class="form-label">Şifre</label>
<div class="input-group">
<span class="input-group-text"><i class="fas fa-lock"></i></span>
<input type="password" class="form-control" id="password" v-model="form.password"
placeholder="Şifrenizi girin" required>
</div>
<div v-if="errors.password" class="text-danger small mt-1">{{ errors.password }}</div>
</div>
<div class="d-flex justify-content-between align-items-center mb-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="remember-me">
<label class="form-check-label" for="remember-me">Beni Hatırla</label>
</div>
<a href="#" class="text-muted small">Şifremi Unuttum?</a>
</div>
<!-- Turnstile Component -->
<ClientOnly>
<div class="mb-4 d-flex justify-content-center">
<NuxtTurnstile v-model="turnstileToken" />
</div>
</ClientOnly>
<button type="submit" class="btn btn-primary w-100 py-2" :disabled="loading">
<span v-if="loading" class="spinner-border spinner-border-sm me-2" role="status"
aria-hidden="true"></span>
{{ loading ? 'Giriş Yapılıyor...' : 'Giriş Yap' }}
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { loginSchema, type LoginInput } from '~~/utils/validations';
import Swal from 'sweetalert2';
definePageMeta({
middleware: 'guest-only',
auth: { unauthenticatedOnly: true, navigateAuthenticatedTo: '/' }
});
const { signIn } = useAuth();
const router = useRouter();
// Reactive form state
const form = reactive<LoginInput>({
email: '',
password: ''
});
// Validation errors state
const errors = reactive<Partial<Record<keyof LoginInput, string>>>({});
const loading = ref(false);
const turnstileToken = ref('');
const validate = () => {
const result = loginSchema.safeParse(form);
// Clear previous errors
Object.keys(errors).forEach(key => delete errors[key as keyof LoginInput]);
if (!result.success) {
result.error.errors.forEach(err => {
if (err.path[0]) {
errors[err.path[0] as keyof LoginInput] = err.message;
}
});
return false;
}
return true;
};
const handleLogin = async () => {
if (!validate()) return;
if (!turnstileToken.value) {
Swal.fire({
icon: 'warning',
title: 'Güvenlik Kontrolü',
text: 'Lütfen Turnstile güvenlik kontrolünü tamamlayın.',
timer: 3000,
toast: true,
position: 'top-end',
showConfirmButton: false
});
return;
}
loading.value = true;
try {
const result = await signIn('credentials', {
email: form.email,
password: form.password,
redirect: false,
});
if (result?.error) {
Swal.fire({
icon: 'error',
title: 'Giriş Başarısız',
text: 'E-posta veya şifre hatalı.',
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 3000
});
} else {
Swal.fire({
icon: 'success',
title: 'Giriş Başarılı',
text: 'Yönlendiriliyorsunuz...',
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 1500
});
setTimeout(() => {
router.push('/');
}, 1000);
}
} catch (error) {
console.error(error);
Swal.fire({
icon: 'error',
title: 'Hata',
text: 'Bir şeyler ters gitti, lütfen tekrar deneyin.',
});
} finally {
loading.value = false;
}
};
</script>
<style scoped>
.login-area {
background-color: #f8f9fa;
min-height: 80vh;
display: flex;
align-items: center;
}
.login-form-wrap {
border-top: 5px solid #0d6efd;
}
</style>