import React, { useState, useEffect } from 'react'; import { Link, useSearchParams, useNavigate } from 'react-router-dom'; import { toast } from 'sonner'; import Container from '@/components/Layout/Container'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { KeyRound, ArrowLeft, Eye, EyeOff, CheckCircle, AlertCircle, Loader2 } from 'lucide-react'; export default function ResetPassword() { const [searchParams] = useSearchParams(); const navigate = useNavigate(); const key = searchParams.get('key') || ''; const login = searchParams.get('login') || ''; const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [showPassword, setShowPassword] = useState(false); const [isLoading, setIsLoading] = useState(false); const [isValidating, setIsValidating] = useState(true); const [isValid, setIsValid] = useState(false); const [error, setError] = useState(''); const [isSuccess, setIsSuccess] = useState(false); // Validate the reset key on mount useEffect(() => { const validateKey = async () => { if (!key || !login) { setError('Invalid password reset link. Please request a new one.'); setIsValidating(false); return; } try { const apiRoot = (window as any).woonoowCustomer?.apiRoot || '/wp-json/woonoow/v1'; const nonce = (window as any).woonoowCustomer?.nonce || ''; const response = await fetch(`${apiRoot}/auth/validate-reset-key`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': nonce, }, credentials: 'include', body: JSON.stringify({ key, login }), }); const data = await response.json(); if (response.ok && data.valid) { setIsValid(true); } else { setError(data.message || 'This password reset link has expired or is invalid.'); } } catch (err) { setError('Unable to validate reset link. Please try again later.'); } finally { setIsValidating(false); } }; validateKey(); }, [key, login]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(''); if (password !== confirmPassword) { setError('Passwords do not match'); return; } if (password.length < 8) { setError('Password must be at least 8 characters long'); return; } setIsLoading(true); try { const apiRoot = (window as any).woonoowCustomer?.apiRoot || '/wp-json/woonoow/v1'; const nonce = (window as any).woonoowCustomer?.nonce || ''; const response = await fetch(`${apiRoot}/auth/reset-password`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': nonce, }, credentials: 'include', body: JSON.stringify({ key, login, password }), }); const data = await response.json(); if (response.ok && data.success) { setIsSuccess(true); toast.success('Password reset successfully!'); } else { setError(data.message || 'Failed to reset password. Please try again.'); } } catch (err: any) { setError(err.message || 'An error occurred. Please try again later.'); } finally { setIsLoading(false); } }; // Password strength indicator const getPasswordStrength = (pwd: string) => { if (pwd.length === 0) return { label: '', color: '', width: '0%' }; if (pwd.length < 8) return { label: 'Too short', color: 'bg-red-500', width: '25%' }; let strength = 0; if (pwd.length >= 8) strength++; if (pwd.length >= 12) strength++; if (/[a-z]/.test(pwd) && /[A-Z]/.test(pwd)) strength++; if (/\d/.test(pwd)) strength++; if (/[!@#$%^&*(),.?":{}|<>]/.test(pwd)) strength++; if (strength <= 2) return { label: 'Weak', color: 'bg-orange-500', width: '50%' }; if (strength <= 3) return { label: 'Medium', color: 'bg-yellow-500', width: '75%' }; return { label: 'Strong', color: 'bg-green-500', width: '100%' }; }; const passwordStrength = getPasswordStrength(password); // Loading state if (isValidating) { return ( Validating reset link... ); } // Success state if (isSuccess) { return ( Password Reset! Your password has been successfully updated. You can now log in with your new password. Sign In ); } // Error state (invalid key) if (!isValid && error) { return ( Invalid Reset Link {error} Request New Link ); } // Reset form return ( {/* Back link */} Back to login {/* Header */} Reset Your Password Enter your new password below. {/* Error message */} {error && ( {error} )} {/* Form */} New Password setPassword(e.target.value)} placeholder="Enter new password" required disabled={isLoading} className="pr-10" /> setShowPassword(!showPassword)} className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600" > {showPassword ? : } {password && ( Strength: {passwordStrength.label} )} Confirm Password setConfirmPassword(e.target.value)} placeholder="Confirm new password" required disabled={isLoading} /> {confirmPassword && password !== confirmPassword && ( Passwords do not match )} {isLoading ? 'Resetting...' : 'Reset Password'} {/* Footer */} Remember your password?{' '} Sign in ); }
Validating reset link...
Your password has been successfully updated. You can now log in with your new password.
{error}
Enter your new password below.
Strength: {passwordStrength.label}
Passwords do not match