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.
 
 
 

152 lines
5.0 KiB

<!-- app/components/Auth/RegisterForm.vue -->
<script setup lang="ts">
import { z } from 'zod'
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import { AlertCircle, CheckCircle, Loader2 } from 'lucide-vue-next'
const { register } = useAuth()
// Validation schema
const registerSchema = toTypedSchema(
z.object({
email: z.string().email('Bitte gib eine gültige E-Mail-Adresse ein'),
password: z
.string()
.min(8, 'Das Passwort muss mindestens 8 Zeichen lang sein')
.regex(/[A-Z]/, 'Das Passwort muss mindestens einen Großbuchstaben enthalten')
.regex(/[a-z]/, 'Das Passwort muss mindestens einen Kleinbuchstaben enthalten')
.regex(/[0-9]/, 'Das Passwort muss mindestens eine Zahl enthalten'),
firstName: z.string().min(2, 'Der Vorname muss mindestens 2 Zeichen lang sein'),
lastName: z.string().min(2, 'Der Nachname muss mindestens 2 Zeichen lang sein'),
})
)
// Form state
const { handleSubmit, isSubmitting } = useForm({
validationSchema: registerSchema,
})
// Success/error state
const submitError = ref<string | null>(null)
const submitSuccess = ref(false)
// Form submit handler
const onSubmit = handleSubmit(async (values) => {
submitError.value = null
submitSuccess.value = false
try {
const result = await register(values)
submitSuccess.value = true
// Show success message for 3 seconds, then switch to login tab
setTimeout(() => {
navigateTo('/auth?tab=login')
}, 3000)
} catch (error: any) {
console.error('Registration error:', error)
if (error.status === 409) {
submitError.value = 'Diese E-Mail-Adresse ist bereits registriert.'
} else {
submitError.value = error.data?.message || 'Registrierung fehlgeschlagen. Bitte versuche es erneut.'
}
}
})
</script>
<template>
<form @submit="onSubmit" class="space-y-5">
<!-- Success Alert -->
<Alert v-if="submitSuccess" class="bg-white/15 border-l-4 border-success text-white">
<CheckCircle class="h-6 w-6 text-success" />
<AlertTitle class="text-success font-medium">Registrierung erfolgreich!</AlertTitle>
<AlertDescription>
Bitte bestätige deine E-Mail-Adresse über den Link, den wir dir gesendet haben.
</AlertDescription>
</Alert>
<!-- Error Alert -->
<Alert v-if="submitError" variant="error">
<AlertCircle class="h-6 w-6" />
<AlertDescription>{{ submitError }}</AlertDescription>
</Alert>
<!-- First Name -->
<FormField v-slot="{ componentField }" name="firstName">
<FormItem>
<FormLabel class="text-white/90 text-base font-medium">Vorname</FormLabel>
<FormControl>
<Input
type="text"
placeholder="Max"
v-bind="componentField"
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<!-- Last Name -->
<FormField v-slot="{ componentField }" name="lastName">
<FormItem>
<FormLabel class="text-white/90 text-base font-medium">Nachname</FormLabel>
<FormControl>
<Input type="text" placeholder="Mustermann" v-bind="componentField" />
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<!-- Email -->
<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 -->
<FormField v-slot="{ componentField }" name="password">
<FormItem>
<FormLabel class="text-white/90 text-base font-medium">Passwort</FormLabel>
<FormControl>
<Input
type="password"
placeholder="Mindestens 8 Zeichen"
v-bind="componentField"
/>
</FormControl>
<FormDescription class="text-white/60 text-sm">
Mindestens 8 Zeichen, Groß-/Kleinbuchstaben und eine Zahl
</FormDescription>
<FormMessage />
</FormItem>
</FormField>
<!-- Submit Button -->
<Button type="submit" variant="experimenta" size="experimenta" class="w-full" :disabled="isSubmitting || submitSuccess">
<Loader2 v-if="isSubmitting" class="mr-2 h-5 w-5 animate-spin" />
{{ isSubmitting ? 'Wird registriert...' : 'Konto erstellen' }}
</Button>
<!-- Terms & Privacy -->
<p class="text-sm text-white/70 text-center">
Mit der Registrierung stimmst du unserer
<a href="https://www.experimenta.science/datenschutz/" target="_blank" rel="noopener noreferrer" class="text-accent font-medium transition-all duration-300 hover:brightness-125">
Datenschutzerklärung
</a>
und den
<a href="https://www.experimenta.science/agb/" target="_blank" rel="noopener noreferrer" class="text-accent font-medium transition-all duration-300 hover:brightness-125">
Nutzungsbedingungen
</a>
zu.
</p>
</form>
</template>