Enhance user communication and improve UI components

- Update CLAUDE.md to mandate informal "Du" form for user communication in all UI text and emails.
- Modify LoginForm and RegisterForm components to reflect informal language in validation messages and placeholders.
- Add secure connection indicators in LoginForm for user awareness.
- Update alert component styles for better visual feedback.
- Introduce experimenta company information document for user reference.
This commit is contained in:
Bastian Masanek
2025-10-31 17:28:07 +01:00
parent c2c706ebcf
commit d9f08bbef2
9 changed files with 599 additions and 32 deletions

View File

@@ -4,13 +4,14 @@
import { z } from 'zod'
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import { AlertCircle, AlertTriangle, Loader2, ShieldCheck, ShieldAlert } from 'lucide-vue-next'
const { login } = useAuth()
// Validation schema
const loginSchema = toTypedSchema(
z.object({
email: z.string().email('Bitte geben Sie eine gültige E-Mail-Adresse ein'),
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'),
})
)
@@ -33,19 +34,30 @@ const onSubmit = handleSubmit(async (values) => {
} 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 versuchen Sie es erneut.'
submitError.value = error.message || 'Anmeldung fehlgeschlagen. Bitte versuche es erneut.'
}
})
// Is the connection secure?
const isSecureConnection = computed(() => {
return window.location.protocol === 'https:'
})
</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="ihre.email@beispiel.de" v-bind="componentField" />
<Input type="email" placeholder="deine.email@beispiel.de" v-bind="componentField" />
</FormControl>
<FormMessage />
</FormItem>
@@ -62,21 +74,21 @@ const onSubmit = handleSubmit(async (values) => {
</FormItem>
</FormField>
<!-- Error Alert -->
<Alert v-if="submitError" class="border-destructive bg-destructive/10 text-white">
<AlertCircle class="h-5 w-5 text-destructive" />
<AlertDescription class="text-white/90">{{ submitError }}</AlertDescription>
</Alert>
<!-- 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>
<!-- Info Text -->
<p class="text-sm text-white/70 text-center">
Anmeldung erfolgt verschlüsselt über unseren Partner Cidaas
<!-- Secure Connection Text -->
<p v-if="!isSecureConnection" class="flex items-center justify-center gap-2 text-sm text-white/70">
<ShieldAlert :size="16" class="flex-shrink-0 text-error" />
<span class="text-error">Die Datenübertragung erfolgt NICHT verschlüsselt</span>
</p>
<p v-else class="flex items-center justify-center gap-2 text-sm text-white/70">
<ShieldCheck :size="16" class="flex-shrink-0 text-success" />
<span class="text-success">Die Datenübertragung erfolgt verschlüsselt</span>
</p>
</form>
</template>

View File

@@ -4,13 +4,14 @@
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 geben Sie eine gültige E-Mail-Adresse ein'),
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')
@@ -51,7 +52,7 @@ const onSubmit = handleSubmit(async (values) => {
if (error.status === 409) {
submitError.value = 'Diese E-Mail-Adresse ist bereits registriert.'
} else {
submitError.value = error.data?.message || 'Registrierung fehlgeschlagen. Bitte versuchen Sie es erneut.'
submitError.value = error.data?.message || 'Registrierung fehlgeschlagen. Bitte versuche es erneut.'
}
}
})
@@ -60,18 +61,18 @@ const onSubmit = handleSubmit(async (values) => {
<template>
<form @submit="onSubmit" class="space-y-5">
<!-- Success Alert -->
<Alert v-if="submitSuccess" class="border-success bg-success/10 text-white">
<CheckCircle class="h-5 w-5 text-success" />
<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 class="text-white/90">
Bitte bestätigen Sie Ihre E-Mail-Adresse über den Link, den wir Ihnen gesendet haben.
<AlertDescription>
Bitte bestätige deine E-Mail-Adresse über den Link, den wir dir gesendet haben.
</AlertDescription>
</Alert>
<!-- Error Alert -->
<Alert v-if="submitError" class="border-destructive bg-destructive/10 text-white">
<AlertCircle class="h-5 w-5 text-destructive" />
<AlertDescription class="text-white/90">{{ submitError }}</AlertDescription>
<Alert v-if="submitError" variant="error">
<AlertCircle class="h-6 w-6" />
<AlertDescription>{{ submitError }}</AlertDescription>
</Alert>
<!-- First Name -->
@@ -105,7 +106,7 @@ const onSubmit = handleSubmit(async (values) => {
<FormItem>
<FormLabel class="text-white/90 text-base font-medium">E-Mail-Adresse</FormLabel>
<FormControl>
<Input type="email" placeholder="ihre.email@beispiel.de" v-bind="componentField" />
<Input type="email" placeholder="deine.email@beispiel.de" v-bind="componentField" />
</FormControl>
<FormMessage />
</FormItem>
@@ -137,7 +138,7 @@ const onSubmit = handleSubmit(async (values) => {
<!-- Terms & Privacy -->
<p class="text-sm text-white/70 text-center">
Mit der Registrierung stimmen Sie unserer
Mit der Registrierung stimmst du unserer
<a href="/datenschutz" class="text-accent font-medium transition-all duration-300 hover:brightness-125">
Datenschutzerklärung
</a>

View File

@@ -6,13 +6,15 @@ export { default as AlertDescription } from './AlertDescription.vue'
export { default as AlertTitle } from './AlertTitle.vue'
export const alertVariants = cva(
'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',
'relative w-full rounded-lg border p-4 flex items-center gap-3 [&>svg]:shrink-0 [&>svg]:text-foreground',
{
variants: {
variant: {
default: 'bg-background text-foreground',
destructive:
'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',
error:
'bg-white/15 border-l-4 border-warning text-white [&>svg]:text-warning',
},
},
defaultVariants: {

View File

@@ -31,7 +31,7 @@ onMounted(() => {
// Error message from OAuth callback
const errorMessage = computed(() => {
if (route.query.error === 'login_failed') {
return 'Login fehlgeschlagen. Bitte versuchen Sie es erneut.'
return 'Login fehlgeschlagen. Bitte versuche es erneut.'
}
return null
})
@@ -51,7 +51,7 @@ definePageMeta({
Willkommen
</h1>
<p class="mt-3 text-lg text-white/80">
Melden Sie sich an oder erstellen Sie ein Konto
Melde dich an oder erstelle ein Konto
</p>
</div>
@@ -79,7 +79,7 @@ definePageMeta({
<CardHeader class="px-0 pt-0">
<CardTitle class="text-2xl font-medium">Anmelden</CardTitle>
<CardDescription class="text-white/70 mt-2">
Melden Sie sich mit Ihrer E-Mail-Adresse an
Melde dich mit deiner E-Mail-Adresse an
</CardDescription>
</CardHeader>
<CardContent class="px-0 pb-0">
@@ -94,7 +94,7 @@ definePageMeta({
<CardHeader class="px-0 pt-0">
<CardTitle class="text-2xl font-medium">Konto erstellen</CardTitle>
<CardDescription class="text-white/70 mt-2">
Erstellen Sie ein neues experimenta-Konto
Erstelle ein neues experimenta-Konto
</CardDescription>
</CardHeader>
<CardContent class="px-0 pb-0">

View File

@@ -435,8 +435,8 @@ const copyCode = async (code: string) => {
<!-- Error Messages -->
<div>
<label class="form-label">Form mit Fehlermeldung</label>
<input type="email" class="form-input border-red-500/50" placeholder="ihre.email@beispiel.de" />
<p class="form-error">Bitte geben Sie eine gültige E-Mail-Adresse ein</p>
<input type="email" class="form-input border-red-500/50" placeholder="deine.email@beispiel.de" />
<p class="form-error">Bitte gib eine gültige E-Mail-Adresse ein</p>
</div>
<!-- Error Message Styles -->