138 lines
4.0 KiB
Vue
138 lines
4.0 KiB
Vue
<template>
|
|
<div class="min-h-full flex items-center justify-center py-16 px-4 sm:px-6 lg:px-8 bg-gray-50">
|
|
<div class="max-w-md w-full space-y-8">
|
|
<div class="text-center">
|
|
<h2 class="text-3xl font-display font-bold text-gray-900">
|
|
Passwort zurücksetzen
|
|
</h2>
|
|
<p class="mt-2 text-sm text-gray-600">
|
|
Geben Sie Ihre E-Mail-Adresse ein, um Ihr Passwort zurückzusetzen
|
|
</p>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-xl shadow-lg p-8">
|
|
<form
|
|
class="space-y-6"
|
|
@submit.prevent="handleReset"
|
|
>
|
|
<!-- Email -->
|
|
<div>
|
|
<label
|
|
for="email"
|
|
class="block text-sm font-medium text-gray-700 mb-2"
|
|
>
|
|
E-Mail-Adresse
|
|
</label>
|
|
<input
|
|
id="email"
|
|
v-model="email"
|
|
type="email"
|
|
required
|
|
autocomplete="email"
|
|
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-600 focus:border-transparent transition-all"
|
|
:class="{ 'border-red-500': errorMessage }"
|
|
placeholder="ihre-email@example.com"
|
|
>
|
|
</div>
|
|
|
|
<!-- Error Message -->
|
|
<div
|
|
v-if="errorMessage"
|
|
class="bg-red-50 border border-red-200 rounded-lg p-4"
|
|
>
|
|
<p class="text-sm text-red-800 flex items-center">
|
|
<AlertCircle
|
|
:size="18"
|
|
class="mr-2"
|
|
/>
|
|
{{ errorMessage }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Success Message -->
|
|
<div
|
|
v-if="successMessage"
|
|
class="bg-green-50 border border-green-200 rounded-lg p-4"
|
|
>
|
|
<p class="text-sm text-green-800 flex items-center">
|
|
<Check
|
|
:size="18"
|
|
class="mr-2"
|
|
/>
|
|
{{ successMessage }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Submit Button -->
|
|
<button
|
|
type="submit"
|
|
:disabled="isLoading"
|
|
class="w-full px-6 py-3 bg-primary-600 hover:bg-primary-700 disabled:bg-gray-400 text-white font-semibold rounded-lg transition-colors flex items-center justify-center"
|
|
>
|
|
<Loader2
|
|
v-if="isLoading"
|
|
:size="20"
|
|
class="mr-2 animate-spin"
|
|
/>
|
|
<span>{{ isLoading ? 'Wird gesendet...' : 'Passwort zurücksetzen' }}</span>
|
|
</button>
|
|
|
|
<!-- Back to Login -->
|
|
<div class="text-center">
|
|
<NuxtLink
|
|
to="/login"
|
|
class="text-sm text-primary-600 hover:text-primary-700 font-medium"
|
|
>
|
|
Zurück zum Login
|
|
</NuxtLink>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Info Box -->
|
|
<div class="bg-primary-50 border border-primary-100 rounded-lg p-4">
|
|
<p class="text-sm text-primary-800 text-center">
|
|
Sie erhalten eine E-Mail mit einem Link zum Zurücksetzen Ihres Passworts.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from 'vue'
|
|
import { AlertCircle, Check, Loader2 } from 'lucide-vue-next'
|
|
|
|
const email = ref('')
|
|
const isLoading = ref(false)
|
|
const errorMessage = ref('')
|
|
const successMessage = ref('')
|
|
|
|
const handleReset = async () => {
|
|
isLoading.value = true
|
|
errorMessage.value = ''
|
|
successMessage.value = ''
|
|
|
|
try {
|
|
const response = await $fetch('/api/auth/reset-password', {
|
|
method: 'POST',
|
|
body: { email: email.value }
|
|
})
|
|
|
|
if (response.success) {
|
|
successMessage.value = 'Eine E-Mail mit weiteren Anweisungen wurde an Ihre E-Mail-Adresse gesendet.'
|
|
email.value = ''
|
|
}
|
|
} catch (error) {
|
|
errorMessage.value = error.data?.message || 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.'
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
useHead({
|
|
title: 'Passwort vergessen - Harheimer TC',
|
|
})
|
|
</script>
|
|
|