diff --git a/package.json b/package.json index f4e0d95..8d9033f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.23.0", + "version": "1.23.1", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/app/auth/reset-password/page.tsx b/src/app/auth/reset-password/page.tsx index 744e3f6..7a00f93 100644 --- a/src/app/auth/reset-password/page.tsx +++ b/src/app/auth/reset-password/page.tsx @@ -5,49 +5,53 @@ import React, { useState, useEffect } from 'react'; const ResetPasswordPage = () => { const [token, setToken] = useState(''); const [newPassword, setNewPassword] = useState(''); + const [confirmPassword, setConfirmPassword] = useState(''); const [isLoading, setIsLoading] = useState(false); - const [message, setMessage] = useState(null); const [error, setError] = useState(null); const [showSuccess, setShowSuccess] = useState(false); + const [hasToken, setHasToken] = useState(false); - // Get token from URL query parameter useEffect(() => { const urlParams = new URLSearchParams(window.location.search); const tokenParam = urlParams.get('token'); if (tokenParam) { setToken(tokenParam); + setHasToken(true); } }, []); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - setIsLoading(true); - setMessage(null); setError(null); - + + if (newPassword.length < 6) { + setError('Password must be at least 6 characters'); + return; + } + + if (newPassword !== confirmPassword) { + setError('Passwords do not match'); + return; + } + + setIsLoading(true); + try { - // Simulate API call const response = await fetch('/api/auth/reset-password', { method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, + headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, newPassword }), }); - + const result = await response.json(); - + if (!response.ok) { throw new Error(result.error || 'Failed to reset password'); } - - setMessage('Password reset successfully!'); + setShowSuccess(true); - setToken(''); - setNewPassword(''); } catch (err) { setError(err instanceof Error ? err.message : 'An unknown error occurred'); - console.error('Reset password error:', err); } finally { setIsLoading(false); } @@ -60,7 +64,25 @@ const ResetPasswordPage = () => {

Password Reset Successful!

- Your password has been reset successfully. You can now sign in with your new password. + Your password has been reset successfully. You can now{' '} + sign in{' '} + with your new password. +

+
+ + + ); + } + + if (!hasToken) { + return ( +
+
+
+

Invalid Reset Link

+

+ This reset link is invalid or has expired. Please{' '} + request a new one.

@@ -74,36 +96,19 @@ const ResetPasswordPage = () => {

Weekly To Do List

-

Reset your password

+

Choose a new password

- +
{error && (
{error}
)} - +
- - setToken(e.target.value)} - className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm" - placeholder="Reset Token" - /> -
-
- + { required value={newPassword} onChange={(e) => setNewPassword(e.target.value)} - className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm" + className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm" placeholder="New Password" />
+
+ + setConfirmPassword(e.target.value)} + className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm" + placeholder="Confirm Password" + /> +
@@ -123,15 +141,11 @@ const ResetPasswordPage = () => { disabled={isLoading} className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50" > - {isLoading ? ( - Resetting... - ) : ( - Reset Password - )} + {isLoading ? 'Resetting...' : 'Reset Password'}
- +

@@ -145,4 +159,4 @@ const ResetPasswordPage = () => { ); }; -export default ResetPasswordPage; \ No newline at end of file +export default ResetPasswordPage;