first commit
This commit is contained in:
177
app/pages/auth/login.vue
Normal file
177
app/pages/auth/login.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<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>
|
||||
222
app/pages/auth/register.vue
Normal file
222
app/pages/auth/register.vue
Normal file
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<div class="register-area pt-120 pb-120">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8 col-md-10">
|
||||
<div class="register-form-wrap shadow-lg p-5 rounded bg-white">
|
||||
<div class="register-header text-center mb-4">
|
||||
<h2 class="mb-2">Hesap Oluşturun</h2>
|
||||
<p>
|
||||
Zaten hesabınız var mı?
|
||||
<NuxtLink to="/auth/login" class="text-primary fw-bold">Giriş Yapın</NuxtLink>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form @submit.prevent="handleRegister">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Kullanıcı Adı</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-user"></i></span>
|
||||
<input type="text" class="form-control" id="username" v-model="form.username"
|
||||
placeholder="Kullanıcı adı seçin" required>
|
||||
</div>
|
||||
<div v-if="errors.username" class="text-danger small mt-1">{{ errors.username }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="first_name" class="form-label">Ad</label>
|
||||
<input type="text" class="form-control" id="first_name" v-model="form.first_name"
|
||||
placeholder="Adınız" required>
|
||||
<div v-if="errors.first_name" class="text-danger small mt-1">{{ errors.first_name }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="last_name" class="form-label">Soyad</label>
|
||||
<input type="text" class="form-control" id="last_name" v-model="form.last_name"
|
||||
placeholder="Soyadınız" required>
|
||||
<div v-if="errors.last_name" class="text-danger small mt-1">{{ errors.last_name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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 adresiniz" required>
|
||||
</div>
|
||||
<div v-if="errors.email" class="text-danger small mt-1">{{ errors.email }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 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="Şifreniz" required>
|
||||
</div>
|
||||
<div v-if="errors.password" class="text-danger small mt-1">{{ errors.password }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="passwordConfirm" class="form-label">Şifre Tekrar</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-lock"></i></span>
|
||||
<input type="password" class="form-control" id="passwordConfirm"
|
||||
v-model="form.passwordConfirm" placeholder="Şifrenizi tekrar girin"
|
||||
required>
|
||||
</div>
|
||||
<div v-if="errors.passwordConfirm" class="text-danger small mt-1">{{
|
||||
errors.passwordConfirm }}</div>
|
||||
</div>
|
||||
</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-success 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 ? 'Kayıt Yapılıyor...' : 'Kayıt Ol' }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { registerSchema, type RegisterInput } from '~~/utils/validations';
|
||||
import Swal from 'sweetalert2';
|
||||
|
||||
definePageMeta({
|
||||
middleware: 'guest-only',
|
||||
auth: { unauthenticatedOnly: true, navigateAuthenticatedTo: '/' }
|
||||
});
|
||||
|
||||
const config = useRuntimeConfig();
|
||||
const router = useRouter();
|
||||
|
||||
const form = reactive<RegisterInput>({
|
||||
username: '',
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
email: '',
|
||||
password: '',
|
||||
passwordConfirm: ''
|
||||
});
|
||||
|
||||
const errors = reactive<Partial<Record<keyof RegisterInput, string>>>({});
|
||||
const loading = ref(false);
|
||||
const turnstileToken = ref('');
|
||||
|
||||
const validate = () => {
|
||||
// Zod validasyonu
|
||||
const result = registerSchema.safeParse(form);
|
||||
|
||||
// Clear previous errors
|
||||
Object.keys(errors).forEach(key => delete errors[key as keyof RegisterInput]);
|
||||
|
||||
if (!result.success) {
|
||||
result.error.errors.forEach(err => {
|
||||
if (err.path[0]) {
|
||||
errors[err.path[0] as keyof RegisterInput] = err.message;
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleRegister = 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 apiUrl = config.public.NUXT_PUBLIC_API_BASE || 'http://127.0.0.1:8080';
|
||||
|
||||
// Backend API çağrısı
|
||||
const response = await fetch(`${apiUrl}/api/v1/auth/register`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username: form.username,
|
||||
first_name: form.first_name,
|
||||
last_name: form.last_name,
|
||||
email: form.email,
|
||||
password: form.password
|
||||
})
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Kayıt Başarılı!',
|
||||
text: data.message || 'Lütfen e-posta adresinizi doğrulayın.',
|
||||
confirmButtonText: 'Giriş Yap'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
router.push('/auth/login');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const errorData = await response.json();
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Kayıt Hatası',
|
||||
text: errorData.message || 'Kayıt işlemi sırasında bir hata oluştu.',
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Hata',
|
||||
text: 'Sunucu ile iletişim hatası.',
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.register-area {
|
||||
background-color: #f8f9fa;
|
||||
min-height: 80vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.register-form-wrap {
|
||||
border-top: 5px solid #198754;
|
||||
}
|
||||
</style>
|
||||
150
app/pages/auth/resend-verify.vue
Normal file
150
app/pages/auth/resend-verify.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div class="resend-verify-area pt-120 pb-120">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-6 col-md-8">
|
||||
<div class="resend-form-wrap shadow-lg p-5 rounded bg-white">
|
||||
<div class="header text-center mb-4">
|
||||
<h2 class="mb-2">Doğrulama E-postası Gönder</h2>
|
||||
<p class="text-muted">
|
||||
E-posta adresinizi girin, doğrulama bağlantısını tekrar gönderelim.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form @submit.prevent="handleResend">
|
||||
<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="email"
|
||||
placeholder="E-posta adresinizi girin" required>
|
||||
</div>
|
||||
<div v-if="error" class="text-danger small mt-1">{{ error }}</div>
|
||||
</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 ? 'Gönderiliyor...' : 'Gönder' }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<NuxtLink to="/auth/login" class="text-decoration-none">
|
||||
<i class="fas fa-arrow-left me-1"></i> Giriş sayfasına dön
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { z } from 'zod'; // Import z directly if not exported from validations, or use from validations if available
|
||||
import Swal from 'sweetalert2';
|
||||
|
||||
definePageMeta({
|
||||
middleware: 'guest-only',
|
||||
auth: { unauthenticatedOnly: true, navigateAuthenticatedTo: '/' }
|
||||
});
|
||||
|
||||
const config = useRuntimeConfig();
|
||||
const email = ref('');
|
||||
const error = ref('');
|
||||
const loading = ref(false);
|
||||
const turnstileToken = ref('');
|
||||
|
||||
const emailSchema = z.string().email({ message: 'Geçerli bir e-posta adresi giriniz' });
|
||||
|
||||
const validate = () => {
|
||||
const result = emailSchema.safeParse(email.value);
|
||||
if (!result.success) {
|
||||
error.value = result.error.errors[0].message;
|
||||
return false;
|
||||
}
|
||||
error.value = '';
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleResend = 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 apiUrl = config.public.NUXT_PUBLIC_API_BASE || 'http://127.0.0.1:8080';
|
||||
|
||||
const response = await fetch(`${apiUrl}/api/v1/auth/resend-verification`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: email.value
|
||||
})
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Başarılı!',
|
||||
text: 'Doğrulama bağlantısı e-posta adresinize gönderildi.',
|
||||
confirmButtonText: 'Tamam'
|
||||
});
|
||||
email.value = ''; // Reset form
|
||||
turnstileToken.value = ''; // Reset token ideally, but might need manual reset
|
||||
} else {
|
||||
const data = await response.json();
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Hata',
|
||||
text: data.message || data.error || 'İşlem başarısız oldu.',
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Hata',
|
||||
text: 'Sunucu ile iletişim hatası.',
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.resend-verify-area {
|
||||
background-color: #f8f9fa;
|
||||
min-height: 80vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.resend-form-wrap {
|
||||
border-top: 5px solid #0d6efd;
|
||||
}
|
||||
</style>
|
||||
114
app/pages/auth/verify.vue
Normal file
114
app/pages/auth/verify.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<div class="verify-area pt-120 pb-120">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-6 col-md-8">
|
||||
<div class="verify-content text-center shadow-lg p-5 rounded bg-white">
|
||||
|
||||
<div v-if="loading" class="text-center py-5">
|
||||
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
|
||||
<span class="visually-hidden">Yükleniyor...</span>
|
||||
</div>
|
||||
<p class="mt-3 text-muted fs-5">E-posta adresiniz doğrulanıyor...</p>
|
||||
</div>
|
||||
|
||||
<div v-else-if="success">
|
||||
<div class="mb-4">
|
||||
<div class="success-icon d-inline-flex align-items-center justify-content-center bg-success text-white rounded-circle"
|
||||
style="width: 80px; height: 80px;">
|
||||
<i class="fas fa-check fa-3x"></i>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="mb-3 text-success">Doğrulama Başarılı!</h3>
|
||||
<p class="text-muted mb-4 fs-5">Hesabınız başarıyla doğrulandı. Artık giriş yapabilirsiniz.
|
||||
</p>
|
||||
<NuxtLink to="/auth/login" class="btn btn-primary btn-lg w-100">
|
||||
Giriş Yap
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<div class="mb-4">
|
||||
<div class="error-icon d-inline-flex align-items-center justify-content-center bg-danger text-white rounded-circle"
|
||||
style="width: 80px; height: 80px;">
|
||||
<i class="fas fa-times fa-3x"></i>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="mb-3 text-danger">Doğrulama Hatası</h3>
|
||||
<p class="text-muted mb-4 fs-5">{{ displayError }}</p>
|
||||
<NuxtLink to="/auth/login" class="btn btn-outline-primary">
|
||||
Giriş sayfasına dön
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const route = useRoute();
|
||||
const config = useRuntimeConfig();
|
||||
|
||||
definePageMeta({
|
||||
middleware: 'guest-only',
|
||||
auth: { unauthenticatedOnly: true, navigateAuthenticatedTo: '/' }
|
||||
});
|
||||
|
||||
const loading = ref(true);
|
||||
const success = ref(false);
|
||||
const errorMessage = ref('');
|
||||
|
||||
const displayError = computed(() => {
|
||||
return errorMessage.value || 'Doğrulama işlemi sırasında bir hata oluştu.';
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const token = route.query.token as string;
|
||||
|
||||
if (!token) {
|
||||
loading.value = false;
|
||||
errorMessage.value = "Geçersiz doğrulama bağlantısı (token eksik).";
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const apiUrl = config.public.NUXT_PUBLIC_API_BASE || 'http://127.0.0.1:8080';
|
||||
|
||||
// Backend API: GET /api/v1/auth/verify-email?token=...
|
||||
const response = await fetch(`${apiUrl}/api/v1/auth/verify-email?token=${token}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'accept': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
success.value = true;
|
||||
} else {
|
||||
const data = await response.json();
|
||||
errorMessage.value = data.message || 'Token geçersiz veya süresi dolmuş.';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Verify error:", error);
|
||||
errorMessage.value = 'Sunucu ile bağlantı kurulamadı.';
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.verify-area {
|
||||
background-color: #f8f9fa;
|
||||
min-height: 80vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.verify-content {
|
||||
border-top: 5px solid #0d6efd;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user