diff --git a/app/login/page.tsx b/app/login/page.tsx index 4046b89..edfdd1e 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -3,7 +3,7 @@ import { useState } from 'react' import { useRouter } from 'next/navigation' import { loginWithPassword, signUpWithPassword } from '@/lib/auth/client' -import { Brain, Zap, Target, Clock } from 'lucide-react' +import { Brain, Zap, Target, Clock, Eye, EyeOff } from 'lucide-react' import { BentoGrid, BentoCard } from '@/components/ui/bento-grid' import Link from 'next/link' @@ -62,6 +62,8 @@ export default function LoginPage() { const [password, setPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') // Only for signup const [loading, setLoading] = useState(false) + const [showPassword, setShowPassword] = useState(false) + const [showConfirmPassword, setShowConfirmPassword] = useState(false) const [message, setMessage] = useState<{ type: 'success' | 'error' text: string @@ -104,10 +106,10 @@ export default function LoginPage() { } else { // Login Flow await loginWithPassword(email, password) - + setMessage({ type: 'success', - text: 'Ingelogd! Redirect naar EPD...' + text: 'Ingelogd! Je wordt doorgestuurd...' }) // Redirect to EPD @@ -115,7 +117,7 @@ export default function LoginPage() { router.push('/epd/clients') }, 1000) } - } catch (error: any) { + } catch (error: any) { // Check for duplicate email error with auto-login if (error.code === 'user_already_registered' && error.data?.session) { // User was auto-logged in (client-side detection succeeded) @@ -140,6 +142,20 @@ export default function LoginPage() { setConfirmPassword('') }, 2000) } + // Invalid credentials during login - suggest signup + else if (error.code === 'invalid_credentials' && mode === 'login') { + setMessage({ + type: 'error', + text: error.message || 'Email of wachtwoord is onjuist.' + }) + } + // Email not confirmed + else if (error.code === 'email_not_confirmed') { + setMessage({ + type: 'error', + text: error.message || 'Je email is nog niet geverifieerd. Check je inbox.' + }) + } // Generic error handling else { setMessage({ @@ -303,16 +319,30 @@ export default function LoginPage() { > Wachtwoord - setPassword(e.target.value)} - placeholder="••••••••" - required - minLength={8} - className="w-full px-4 py-2.5 border border-slate-300 rounded-lg focus:ring-2 focus:ring-slate-400 focus:border-slate-400" - /> +
+ setPassword(e.target.value)} + placeholder="••••••••" + required + minLength={8} + className="w-full px-4 py-2.5 pr-11 border border-slate-300 rounded-lg focus:ring-2 focus:ring-slate-400 focus:border-slate-400" + /> + +
{mode === 'login' && (
Bevestig Wachtwoord - setConfirmPassword(e.target.value)} - placeholder="••••••••" - required - minLength={8} - className="w-full px-4 py-2.5 border border-slate-300 rounded-lg focus:ring-2 focus:ring-slate-400 focus:border-slate-400" - /> +
+ setConfirmPassword(e.target.value)} + placeholder="••••••••" + required + minLength={8} + className="w-full px-4 py-2.5 pr-11 border border-slate-300 rounded-lg focus:ring-2 focus:ring-slate-400 focus:border-slate-400" + /> + +
)} diff --git a/docs/RELEASE_AUTH_IMPROVEMENTS.md b/docs/RELEASE_AUTH_IMPROVEMENTS.md new file mode 100644 index 0000000..1014e58 --- /dev/null +++ b/docs/RELEASE_AUTH_IMPROVEMENTS.md @@ -0,0 +1,67 @@ +# Release Notes - Verbeterde Authenticatie Flow + +**Datum:** 19 November 2025 +**Versie:** 1.1.0 + +--- + +## 🔐 Authenticatie Verbeteringen + +We hebben de login en registratie ervaring flink verbeterd met duidelijkere feedback en een gebruiksvriendelijkere interface. + +### ✨ Nieuwe Features + +#### 1. **Wachtwoord Zichtbaarheid Toggle** +- Toon/verberg je wachtwoord met een klik op het oog-icoon +- Werkt voor zowel wachtwoord als bevestig wachtwoord velden +- Maakt het makkelijker om typefouten te voorkomen + +#### 2. **Verbeterde Foutmeldingen** +Alle foutmeldingen zijn nu duidelijker en helpen je beter op weg: + +| Situatie | Nieuwe Melding | +|----------|----------------| +| Login met onjuist wachtwoord | "Email of wachtwoord is onjuist. Controleer je gegevens en probeer opnieuw." | +| Registratie met bestaand email | "Dit emailadres is al geregistreerd. Probeer in te loggen." | +| Email niet geverifieerd | "Je email is nog niet geverifieerd. Check je inbox voor de verificatie link." | + +#### 3. **Automatische Account Herkenning** +- Probeer je te registreren met een bestaand email? Je wordt automatisch naar de login modus gestuurd +- Als het systeem detecteert dat je al bent ingelogd met dezelfde credentials, word je direct doorgestuurd + +#### 4. **Wachtwoord Vergeten Flow** +- De "Wachtwoord vergeten?" link werkt nu correct +- Vraag eenvoudig een reset link aan via je email +- Reset links zijn 1 uur geldig + +### 🛠️ Technische Verbeteringen + +- **Duplicate Email Detectie**: Auth hook met fallback mechanisme voorkomt verwarrende situaties +- **Security**: Geen email enumeration - je kunt niet zien welke emails geregistreerd zijn +- **Middleware Fix**: Reset password routes zijn nu correct toegankelijk voor niet-ingelogde gebruikers + +### 🎨 UI/UX Verbeteringen + +- Consistente Nederlandse taalgebruik door de hele flow +- Visuele feedback bij hover op password toggle +- Toegankelijke aria-labels voor screen readers +- Smooth transitions en loading states + +--- + +## 🚀 Voor Ontwikkelaars + +De volgende functies zijn toegevoegd aan `lib/auth/client.ts`: + +- Verbeterde error handling met custom error codes +- `invalid_credentials` error code voor login failures +- `user_already_registered` error code met optionele auto-login data +- `email_not_confirmed` error code voor verificatie issues + +Middleware is uitgebreid met publieke routes: +- `/reset-password` - Wachtwoord reset aanvragen +- `/update-password` - Nieuw wachtwoord instellen + +--- + +**Veel plezier met de verbeterde authenticatie ervaring!** 🎉 diff --git a/lib/auth/client.ts b/lib/auth/client.ts index 2c28e17..019d128 100644 --- a/lib/auth/client.ts +++ b/lib/auth/client.ts @@ -158,7 +158,29 @@ export async function loginWithPassword(email: string, password: string) { password }) - if (error) throw error + if (error) { + // Provide user-friendly error messages + const errorMessage = error.message?.toLowerCase() || '' + + // Invalid login credentials (account doesn't exist OR wrong password) + if (errorMessage.includes('invalid login credentials') || + errorMessage.includes('invalid credentials') || + error.status === 400) { + const friendlyError = new Error('Email of wachtwoord is onjuist. Controleer je gegevens en probeer opnieuw.') + ;(friendlyError as any).code = 'invalid_credentials' + throw friendlyError + } + + // Email not confirmed + if (errorMessage.includes('email not confirmed')) { + const friendlyError = new Error('Je email is nog niet geverifieerd. Check je inbox voor de verificatie link.') + ;(friendlyError as any).code = 'email_not_confirmed' + throw friendlyError + } + + // Generic error fallback + throw error + } return { success: true, diff --git a/middleware.ts b/middleware.ts index fbb1466..63a965d 100644 --- a/middleware.ts +++ b/middleware.ts @@ -46,6 +46,8 @@ export async function middleware(request: NextRequest) { const publicRoutes = [ '/', '/login', + '/reset-password', + '/update-password', '/auth/callback', '/contact', '/api/leads',