200 lines
6 KiB
TypeScript
200 lines
6 KiB
TypeScript
import { useState } from 'react'
|
|
import {
|
|
Dialog,
|
|
DialogTitle,
|
|
DialogContent,
|
|
DialogActions,
|
|
TextField,
|
|
Button,
|
|
Alert,
|
|
Box,
|
|
IconButton,
|
|
InputAdornment,
|
|
CircularProgress,
|
|
} from '@mui/material'
|
|
import { Visibility, VisibilityOff } from '@mui/icons-material'
|
|
import { useAuth } from '../context/AuthContext'
|
|
|
|
interface ChangePasswordDialogProps {
|
|
open: boolean
|
|
onClose: () => void
|
|
}
|
|
|
|
export default function ChangePasswordDialog({ open, onClose }: ChangePasswordDialogProps) {
|
|
const { changePassword } = useAuth()
|
|
|
|
const [currentPassword, setCurrentPassword] = useState('')
|
|
const [newPassword, setNewPassword] = useState('')
|
|
const [confirmPassword, setConfirmPassword] = useState('')
|
|
const [showCurrentPassword, setShowCurrentPassword] = useState(false)
|
|
const [showNewPassword, setShowNewPassword] = useState(false)
|
|
const [showConfirmPassword, setShowConfirmPassword] = useState(false)
|
|
const [isLoading, setIsLoading] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
const [success, setSuccess] = useState(false)
|
|
|
|
const handleClose = () => {
|
|
// Reset form state
|
|
setCurrentPassword('')
|
|
setNewPassword('')
|
|
setConfirmPassword('')
|
|
setShowCurrentPassword(false)
|
|
setShowNewPassword(false)
|
|
setShowConfirmPassword(false)
|
|
setError(null)
|
|
setSuccess(false)
|
|
onClose()
|
|
}
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault()
|
|
setError(null)
|
|
|
|
// Validate passwords
|
|
if (!currentPassword || !newPassword || !confirmPassword) {
|
|
setError('Vul alle velden in')
|
|
return
|
|
}
|
|
|
|
if (newPassword.length < 8) {
|
|
setError('Nieuw wachtwoord moet minimaal 8 tekens bevatten')
|
|
return
|
|
}
|
|
|
|
if (newPassword !== confirmPassword) {
|
|
setError('Nieuwe wachtwoorden komen niet overeen')
|
|
return
|
|
}
|
|
|
|
if (currentPassword === newPassword) {
|
|
setError('Nieuw wachtwoord moet anders zijn dan het huidige wachtwoord')
|
|
return
|
|
}
|
|
|
|
setIsLoading(true)
|
|
|
|
try {
|
|
const result = await changePassword(currentPassword, newPassword)
|
|
|
|
if (result.success) {
|
|
setSuccess(true)
|
|
// Close dialog after showing success message
|
|
setTimeout(() => {
|
|
handleClose()
|
|
}, 1500)
|
|
} else {
|
|
setError(result.error || 'Er is een fout opgetreden')
|
|
}
|
|
} catch {
|
|
setError('Er is een fout opgetreden bij het wijzigen van het wachtwoord')
|
|
} finally {
|
|
setIsLoading(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onClose={handleClose} maxWidth="sm" fullWidth>
|
|
<DialogTitle sx={{ pb: 1 }}>Wachtwoord wijzigen</DialogTitle>
|
|
|
|
<form onSubmit={handleSubmit}>
|
|
<DialogContent>
|
|
{error && (
|
|
<Alert severity="error" sx={{ mb: 2 }}>
|
|
{error}
|
|
</Alert>
|
|
)}
|
|
|
|
{success && (
|
|
<Alert severity="success" sx={{ mb: 2 }}>
|
|
Wachtwoord succesvol gewijzigd
|
|
</Alert>
|
|
)}
|
|
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
<TextField
|
|
label="Huidig wachtwoord"
|
|
type={showCurrentPassword ? 'text' : 'password'}
|
|
value={currentPassword}
|
|
onChange={(e) => setCurrentPassword(e.target.value)}
|
|
disabled={isLoading || success}
|
|
fullWidth
|
|
autoFocus
|
|
InputProps={{
|
|
endAdornment: (
|
|
<InputAdornment position="end">
|
|
<IconButton
|
|
onClick={() => setShowCurrentPassword(!showCurrentPassword)}
|
|
edge="end"
|
|
tabIndex={-1}
|
|
>
|
|
{showCurrentPassword ? <VisibilityOff /> : <Visibility />}
|
|
</IconButton>
|
|
</InputAdornment>
|
|
),
|
|
}}
|
|
/>
|
|
|
|
<TextField
|
|
label="Nieuw wachtwoord"
|
|
type={showNewPassword ? 'text' : 'password'}
|
|
value={newPassword}
|
|
onChange={(e) => setNewPassword(e.target.value)}
|
|
disabled={isLoading || success}
|
|
fullWidth
|
|
helperText="Minimaal 8 tekens"
|
|
InputProps={{
|
|
endAdornment: (
|
|
<InputAdornment position="end">
|
|
<IconButton
|
|
onClick={() => setShowNewPassword(!showNewPassword)}
|
|
edge="end"
|
|
tabIndex={-1}
|
|
>
|
|
{showNewPassword ? <VisibilityOff /> : <Visibility />}
|
|
</IconButton>
|
|
</InputAdornment>
|
|
),
|
|
}}
|
|
/>
|
|
|
|
<TextField
|
|
label="Bevestig nieuw wachtwoord"
|
|
type={showConfirmPassword ? 'text' : 'password'}
|
|
value={confirmPassword}
|
|
onChange={(e) => setConfirmPassword(e.target.value)}
|
|
disabled={isLoading || success}
|
|
fullWidth
|
|
InputProps={{
|
|
endAdornment: (
|
|
<InputAdornment position="end">
|
|
<IconButton
|
|
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
|
|
edge="end"
|
|
tabIndex={-1}
|
|
>
|
|
{showConfirmPassword ? <VisibilityOff /> : <Visibility />}
|
|
</IconButton>
|
|
</InputAdornment>
|
|
),
|
|
}}
|
|
/>
|
|
</Box>
|
|
</DialogContent>
|
|
|
|
<DialogActions sx={{ px: 3, pb: 2 }}>
|
|
<Button onClick={handleClose} disabled={isLoading}>
|
|
Annuleren
|
|
</Button>
|
|
<Button
|
|
type="submit"
|
|
variant="contained"
|
|
disabled={isLoading || success}
|
|
startIcon={isLoading ? <CircularProgress size={20} color="inherit" /> : null}
|
|
>
|
|
{isLoading ? 'Bezig...' : 'Wijzigen'}
|
|
</Button>
|
|
</DialogActions>
|
|
</form>
|
|
</Dialog>
|
|
)
|
|
}
|