You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.5 KiB
82 lines
2.5 KiB
<!-- app/components/Auth/LoginForm.vue -->
|
|
|
|
<script setup lang="ts">
|
|
import { z } from 'zod'
|
|
import { useForm } from 'vee-validate'
|
|
import { toTypedSchema } from '@vee-validate/zod'
|
|
import { AlertCircle, Loader2 } from 'lucide-vue-next'
|
|
|
|
const { login } = useAuth()
|
|
|
|
// Validation schema
|
|
const loginSchema = toTypedSchema(
|
|
z.object({
|
|
email: z.string().email('Bitte gib eine gültige E-Mail-Adresse ein'),
|
|
password: z.string().min(8, 'Passwort muss mindestens 8 Zeichen lang sein'),
|
|
})
|
|
)
|
|
|
|
// Form state
|
|
const { handleSubmit, isSubmitting, errors } = useForm({
|
|
validationSchema: loginSchema,
|
|
})
|
|
|
|
// Success/error state
|
|
const submitError = ref<string | null>(null)
|
|
|
|
// Form submit handler
|
|
const onSubmit = handleSubmit(async (values) => {
|
|
submitError.value = null
|
|
|
|
try {
|
|
await login(values.email, values.password)
|
|
// Redirect happens in login() function
|
|
} catch (error: any) {
|
|
console.error('Login error:', error)
|
|
// Error message is now directly in error.message (thrown by useAuth composable)
|
|
submitError.value = error.message || 'Anmeldung fehlgeschlagen. Bitte versuche es erneut.'
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<form @submit="onSubmit" class="space-y-6">
|
|
<!-- Error Alert -->
|
|
<Alert v-if="submitError" variant="error">
|
|
<AlertCircle class="h-6 w-6" />
|
|
<AlertDescription>{{ submitError }}</AlertDescription>
|
|
</Alert>
|
|
|
|
<!-- Email Field -->
|
|
<FormField v-slot="{ componentField }" name="email">
|
|
<FormItem>
|
|
<FormLabel class="text-white/90 text-base font-medium">E-Mail-Adresse</FormLabel>
|
|
<FormControl>
|
|
<Input type="email" placeholder="deine.email@beispiel.de" v-bind="componentField" />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
</FormField>
|
|
|
|
<!-- Password Field -->
|
|
<FormField v-slot="{ componentField }" name="password">
|
|
<FormItem>
|
|
<FormLabel class="text-white/90 text-base font-medium">Passwort</FormLabel>
|
|
<FormControl>
|
|
<Input type="password" placeholder="••••••••" v-bind="componentField" />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
</FormField>
|
|
|
|
<!-- Submit Button -->
|
|
<Button type="submit" variant="experimenta" size="experimenta" class="w-full" :disabled="isSubmitting">
|
|
<Loader2 v-if="isSubmitting" class="mr-2 h-5 w-5 animate-spin" />
|
|
{{ isSubmitting ? 'Wird angemeldet...' : 'Anmelden' }}
|
|
</Button>
|
|
|
|
<!-- Secure Connection Indicator -->
|
|
<SecureConnectionIndicator />
|
|
|
|
</form>
|
|
</template>
|
|
|