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
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>
|
|
|