![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/backups/lavocat.quebec/backup-20250730-021618/src/pages/auth/ |
import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import type { NextPage } from 'next';
import Link from 'next/link';
import { Lock } from 'lucide-react';
import LayoutWithSidebar from '../../components/LayoutWithSidebar';
import BackButton from '../../components/BackButton';
const ResetPasswordPage: NextPage = () => {
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [error, setError] = useState('');
const [success, setSuccess] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [isMobile, setIsMobile] = useState(false);
const [language, setLanguage] = useState<'fr' | 'en'>('fr');
const router = useRouter();
const { token } = router.query;
// Mobile detection
useEffect(() => {
const checkMobile = () => {
setIsMobile(window.innerWidth < 768);
};
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}, []);
const handleLanguageToggle = () => {
const newLang = language === 'fr' ? 'en' : 'fr';
setLanguage(newLang);
};
const validateForm = () => {
if (!password.trim()) {
setError('Password is required.');
return false;
}
if (!confirmPassword.trim()) {
setError('Please confirm your password.');
return false;
}
if (password !== confirmPassword) {
setError('Passwords do not match.');
return false;
}
if (password.length < 8) {
setError('Password must be at least 8 characters long.');
return false;
}
return true;
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
setSuccess('');
if (!validateForm()) {
return;
}
if (!token) {
setError('Invalid reset token.');
return;
}
setIsLoading(true);
try {
const response = await fetch('/api/auth/reset-password', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ token, password }),
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || 'Password reset failed.');
}
setSuccess('Password reset successfully! You can now login with your new password.');
// Redirect to login after success
setTimeout(() => {
router.push('/auth/login');
}, 3000);
} catch (err: any) {
console.error('Reset password error:', err);
setError(err.message || 'An unexpected error occurred.');
} finally {
setIsLoading(false);
}
};
return (
<LayoutWithSidebar>
<div className={`min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-50 ${isMobile ? 'py-4 px-4' : 'py-12 px-4 sm:px-6 lg:px-8'}`}>
<div className={`w-full space-y-8 bg-white rounded-xl shadow-lg ${isMobile ? 'max-w-full p-6' : 'max-w-md p-8'}`}>
<BackButton />
<div>
<h2 className={`mt-6 text-center font-extrabold text-gray-900 ${isMobile ? 'text-2xl' : 'text-3xl'}`}>
Reset Password
</h2>
<p className={`mt-2 text-center text-gray-600 ${isMobile ? 'text-sm' : 'text-sm'}`}>
Enter your new password below.
</p>
</div>
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
{error && (
<div className={`bg-red-100 border border-red-400 text-red-700 rounded relative ${isMobile ? 'px-3 py-2 text-sm' : 'px-4 py-3'}`}>
{error}
</div>
)}
{success && (
<div className={`bg-green-100 border border-green-400 text-green-700 rounded relative ${isMobile ? 'px-3 py-2 text-sm' : 'px-4 py-3'}`}>
{success}
</div>
)}
<div className="rounded-md shadow-sm -space-y-px">
<div className={isMobile ? 'mb-4' : ''}>
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
New Password
</label>
<div className="mt-1 relative rounded-md shadow-sm">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Lock className="h-5 w-5 text-gray-400" aria-hidden="true" />
</div>
<input
id="password"
name="password"
type="password"
autoComplete="new-password"
required
value={password}
onChange={(e) => {
setPassword(e.target.value);
setError('');
}}
className={`block w-full pl-10 border border-gray-300 rounded-md focus:outline-none focus:ring-primary focus:border-primary ${isMobile ? 'px-3 py-3 text-base' : 'px-3 py-2 sm:text-sm'}`}
placeholder="Enter your new password"
disabled={isLoading}
/>
</div>
</div>
<div className={isMobile ? 'mb-4' : ''}>
<label htmlFor="confirmPassword" className="block text-sm font-medium text-gray-700">
Confirm Password
</label>
<div className="mt-1 relative rounded-md shadow-sm">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Lock className="h-5 w-5 text-gray-400" aria-hidden="true" />
</div>
<input
id="confirmPassword"
name="confirmPassword"
type="password"
autoComplete="new-password"
required
value={confirmPassword}
onChange={(e) => {
setConfirmPassword(e.target.value);
setError('');
}}
className={`block w-full pl-10 border border-gray-300 rounded-md focus:outline-none focus:ring-primary focus:border-primary ${isMobile ? 'px-3 py-3 text-base' : 'px-3 py-2 sm:text-sm'}`}
placeholder="Confirm your new password"
disabled={isLoading}
/>
</div>
</div>
</div>
<div>
<button
type="submit"
className={`group relative w-full flex justify-center border border-transparent font-medium rounded-md text-white bg-primary hover:bg-primary-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed ${isMobile ? 'py-3 px-4 text-base' : 'py-2 px-4 text-sm'}`}
disabled={isLoading}
>
{isLoading ? 'Resetting...' : 'Reset Password'}
</button>
</div>
<div className="text-center">
<p className={`text-gray-600 ${isMobile ? 'text-sm' : 'text-sm'}`}>
Remember your password?{' '}
<Link href={language === 'en' ? '/en/auth/login' : '/auth/login'} className="font-medium text-primary hover:text-primary-dark">
Sign in
</Link>
</p>
</div>
</form>
</div>
</div>
</LayoutWithSidebar>
);
};
export default ResetPasswordPage;